CommentDefaultFormatterCacheTagsTest.php 5.58 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php

/**
 * @file
 * Contains \Drupal\comment\Tests\CommentDefaultFormatterCacheTagsTest.
 */

namespace Drupal\comment\Tests;

10
use Drupal\Core\Cache\Cache;
11
use Drupal\comment\CommentInterface;
12
use Drupal\system\Tests\Entity\EntityUnitTestBase;
13 14 15
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Session;
16
use Drupal\comment\Entity\Comment;
17
use Drupal\entity_test\Entity\EntityTest;
18 19

/**
20 21 22 23
 * Tests the bubbling up of comment cache tags when using the Comment list
 * formatter on an entity.
 *
 * @group comment
24
 */
25
class CommentDefaultFormatterCacheTagsTest extends EntityUnitTestBase {
26

27 28
  use CommentTestTrait;

29
  /**
30
   * Modules to install.
31 32 33
   *
   * @var array
   */
34
  public static $modules = array('entity_test', 'comment');
35 36 37 38

  /**
   * {@inheritdoc}
   */
39
  protected function setUp() {
40 41
    parent::setUp();

42 43 44 45 46 47 48 49 50 51
    $session = new Session();

    $request = Request::create('/');
    $request->setSession($session);

    /** @var RequestStack $stack */
    $stack = $this->container->get('request_stack');
    $stack->pop();
    $stack->push($request);

52 53 54
    // Set the current user to one that can access comments. Specifically, this
    // user does not have access to the 'administer comments' permission, to
    // ensure only published comments are visible to the end user.
55 56
    $current_user = $this->container->get('current_user');
    $current_user->setAccount($this->createUser(array(), array('access comments')));
57 58

    // Install tables and config needed to render comments.
59
    $this->installSchema('comment', array('comment_entity_statistics'));
60
    $this->installConfig(array('system', 'filter', 'comment'));
61 62 63

    // Comment rendering generates links, so build the router.
    $this->container->get('router.builder')->rebuild();
64 65 66

    // Set up a field, so that the entity that'll be referenced bubbles up a
    // cache tag when rendering it entirely.
67
    $this->addDefaultCommentField('entity_test', 'entity_test');
68 69 70 71 72 73
  }

  /**
   * Tests the bubbling of cache tags.
   */
  public function testCacheTags() {
74 75 76
    /** @var \Drupal\Core\Render\RendererInterface $renderer */
    $renderer = $this->container->get('renderer');

77
    // Create the entity that will be commented upon.
78
    $commented_entity = EntityTest::create(array('name' => $this->randomMachineName()));
79 80 81 82 83 84
    $commented_entity->save();

    // Verify cache tags on the rendered entity before it has comments.
    $build = \Drupal::entityManager()
      ->getViewBuilder('entity_test')
      ->view($commented_entity);
85
    $renderer->renderRoot($build);
86
    $expected_cache_tags = [
87 88
      'entity_test_view',
      'entity_test:'  . $commented_entity->id(),
89 90 91 92 93
      'config:core.entity_form_display.comment.comment.default',
      'config:field.field.comment.comment.comment_body',
      'config:field.field.entity_test.entity_test.comment',
      'config:field.storage.comment.comment_body',
      'config:user.settings',
94
    ];
95
    sort($expected_cache_tags);
96
    $this->assertEqual($build['#cache']['tags'], $expected_cache_tags);
97

98 99 100 101
    // Create a comment on that entity. Comment loading requires that the uid
    // also exists in the {users} table.
    $user = $this->createUser();
    $user->save();
102
    $comment = Comment::create(array(
103 104 105 106 107 108 109 110
      'subject' => 'Llama',
      'comment_body' => array(
        'value' => 'Llamas are cool!',
        'format' => 'plain_text',
      ),
      'entity_id' => $commented_entity->id(),
      'entity_type' => 'entity_test',
      'field_name' => 'comment',
111
      'comment_type' => 'comment',
112
      'status' => CommentInterface::PUBLISHED,
113
      'uid' => $user->id(),
114 115 116 117
    ));
    $comment->save();

    // Load commented entity so comment_count gets computed.
118 119
    // @todo Remove the $reset = TRUE parameter after
    //   https://www.drupal.org/node/597236 lands. It's a temporary work-around.
120 121
    $commented_entity = entity_load('entity_test', $commented_entity->id(), TRUE);

122
    // Verify cache tags on the rendered entity when it has comments.
123 124 125
    $build = \Drupal::entityManager()
      ->getViewBuilder('entity_test')
      ->view($commented_entity);
126
    $renderer->renderRoot($build);
127
    $expected_cache_tags = [
128 129 130 131
      'entity_test_view',
      'entity_test:' . $commented_entity->id(),
      'comment_view',
      'comment:' . $comment->id(),
132
      'config:filter.format.plain_text',
133 134
      'user_view',
      'user:2',
135 136 137 138 139
      'config:core.entity_form_display.comment.comment.default',
      'config:field.field.comment.comment.comment_body',
      'config:field.field.entity_test.entity_test.comment',
      'config:field.storage.comment.comment_body',
      'config:user.settings',
140
    ];
141
    sort($expected_cache_tags);
142
    $this->assertEqual($build['#cache']['tags'], $expected_cache_tags);
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160

    // Build a render array with the entity in a sub-element so that lazy
    // builder elements bubble up outside of the entity and we can check that
    // it got the correct cache max age.
    $build = ['#type' => 'container'];
    $build['entity'] = \Drupal::entityManager()
      ->getViewBuilder('entity_test')
      ->view($commented_entity);
    $renderer->renderRoot($build);

    // The entity itself was cached but the top-level element is max-age 0 due
    // to the bubbled up max age due to the lazy-built comment form.
    $this->assertIdentical(Cache::PERMANENT, $build['entity']['#cache']['max-age']);
    $this->assertIdentical(0, $build['#cache']['max-age'], 'Top level render array has max-age 0');

    // The children (fields) of the entity render array are only built in case
    // of a cache miss.
    $this->assertFalse(isset($build['entity']['comment']), 'Cache hit');
161 162 163
  }

}