.../modules/node/src/Tests/Views/FrontPageTest.php | 47 +++++++++++++++++++--- .../src/Tests/PageCacheTagsIntegrationTest.php | 18 +++++++-- .../rest/src/Tests/Views/StyleSerializerTest.php | 23 +++++++---- .../src/Tests/Entity/EntityCacheTagsTestBase.php | 17 +++++++- .../Entity/EntityWithUriCacheTagsTestBase.php | 8 ++-- .../src/Plugin/views/display/DisplayPluginBase.php | 2 +- .../views/src/Tests/RenderCacheIntegrationTest.php | 36 ++++++++++++----- 7 files changed, 117 insertions(+), 34 deletions(-) diff --git a/core/modules/node/src/Tests/Views/FrontPageTest.php b/core/modules/node/src/Tests/Views/FrontPageTest.php index ba8438f..0ff6669 100644 --- a/core/modules/node/src/Tests/Views/FrontPageTest.php +++ b/core/modules/node/src/Tests/Views/FrontPageTest.php @@ -237,6 +237,8 @@ public function testCacheTagsWithCachePluginTime() { * Whether to check Views' result & output caches. */ protected function doTestFrontPageViewCacheTags($do_assert_views_caches) { + $required_cache_contexts = $this->container->getParameter('renderer.config')['required_cache_contexts']; + $view = Views::getView('frontpage'); $view->setDisplay('page_1'); @@ -263,14 +265,18 @@ protected function doTestFrontPageViewCacheTags($do_assert_views_caches) { $render_cache_tags = Cache::mergeTags($empty_node_listing_cache_tags, $cache_context_tags); $render_cache_tags = Cache::mergeTags($render_cache_tags, ['config:system.site']); + // Cache redirect for the render cached view's display. + $redirect_tags = ['render_cache_redirect:' . hash('sha1', serialize([['view', 'frontpage', 'display', 'page_1'], Cache::mergeContexts($required_cache_contexts, ['url.query_args', 'user.node_grants:view']), 'render']))]; $this->assertViewsCacheTags( $view, $empty_node_listing_cache_tags, $do_assert_views_caches, - $render_cache_tags + Cache::mergeTags($render_cache_tags, $redirect_tags) ); + $expected_tags = Cache::mergeTags($empty_node_listing_cache_tags, $cache_context_tags); $expected_tags = Cache::mergeTags($expected_tags, ['rendered', 'config:user.role.anonymous', 'config:system.site']); + $expected_tags = Cache::mergeTags($expected_tags, ['render_cache_redirect:' . hash('sha1', serialize([['view', 'frontpage', 'display', 'page_1'], $required_cache_contexts, 'render']))]); $this->assertPageCacheContextsAndTags( Url::fromRoute('view.frontpage.page_1'), $cache_contexts, @@ -327,21 +333,52 @@ protected function doTestFrontPageViewCacheTags($do_assert_views_caches) { ); $view->setDisplay('page_1'); $view->setCurrentPage(0); + $node_teaser_redirect_tags = [ + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '6', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '7', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '8', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '9', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '10', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '11', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '12', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '13', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '14', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '15', 'teaser'], $required_cache_contexts, 'render'])), + ]; + $redirect_tags = Cache::mergeTags( + ['render_cache_redirect:' . hash('sha1', serialize([['view', 'frontpage', 'display', 'page_1', 'page:0'], Cache::mergeContexts($required_cache_contexts, ['url.query_args', 'user.node_grants:view']), 'render']))], + $node_teaser_redirect_tags + ); $this->assertViewsCacheTags( $view, $first_page_result_cache_tags, $do_assert_views_caches, - $first_page_output_cache_tags + Cache::mergeTags($first_page_output_cache_tags, $redirect_tags) + ); + $redirect_tags = Cache::mergeTags( + ['render_cache_redirect:' . hash('sha1', serialize([['view', 'frontpage', 'display', 'page_1'], $required_cache_contexts, 'render']))], + $node_teaser_redirect_tags ); $this->assertPageCacheContextsAndTags( Url::fromRoute('view.frontpage.page_1'), $cache_contexts, - Cache::mergeTags($first_page_output_cache_tags, ['rendered', 'config:user.role.anonymous']) + Cache::mergeTags($first_page_output_cache_tags, Cache::mergeTags(['rendered', 'config:user.role.anonymous'], $redirect_tags)) ); // Second page. $this->pass('Second page'); - $this->assertPageCacheContextsAndTags(Url::fromRoute('view.frontpage.page_1', [], ['query' => ['page' => 1]]), $cache_contexts, [ + $node_teaser_redirect_tags = [ + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '1', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '2', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '3', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '4', 'teaser'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '5', 'teaser'], $required_cache_contexts, 'render'])), + ]; + $redirect_tags = Cache::mergeTags( + ['render_cache_redirect:' . hash('sha1', serialize([['view', 'frontpage', 'display', 'page_1'], $required_cache_contexts, 'render']))], + $node_teaser_redirect_tags + ); + $this->assertPageCacheContextsAndTags(Url::fromRoute('view.frontpage.page_1', [], ['query' => ['page' => 1]]), $cache_contexts, Cache::mergeTags([ // The cache tags for the listed nodes. 'node:1', 'node:2', @@ -359,7 +396,7 @@ protected function doTestFrontPageViewCacheTags($do_assert_views_caches) { // FinishResponseSubscriber adds this cache tag to responses that have the // 'user.permissions' cache context for anonymous users. 'config:user.role.anonymous', - ]); + ], $redirect_tags)); // Let's update a node title on the first page and ensure that the page // cache entry invalidates. diff --git a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php index c471cea..2239198 100644 --- a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php +++ b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php @@ -7,6 +7,7 @@ namespace Drupal\page_cache\Tests; +use Drupal\Core\Cache\Cache; use Drupal\Core\Language\LanguageInterface; use Drupal\simpletest\WebTestBase; use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait; @@ -62,6 +63,7 @@ function testPageCacheTags() { // Place a block, but only make it visible on full node page 2. $block = $this->drupalPlaceBlock('views_block:comments_recent-block_1', array( + 'id' => 'recent-comments', 'visibility' => array( 'request_path' => array( 'pages' => '/node/' . $node_2->id(), @@ -69,12 +71,15 @@ function testPageCacheTags() { ), )); - $cache_contexts = [ + $required_cache_contexts = [ 'languages:' . LanguageInterface::TYPE_INTERFACE, - 'route', 'theme', - 'timezone', 'user.permissions', + ]; + + $cache_contexts = [ + 'route', + 'timezone', // The user login block access depends on whether the current user is // logged in or not. 'user.roles:anonymous', @@ -87,7 +92,7 @@ function testPageCacheTags() { ]; // Full node page 1. - $this->assertPageCacheContextsAndTags($node_1->urlInfo(), $cache_contexts, array( + $this->assertPageCacheContextsAndTags($node_1->urlInfo(), Cache::mergeContexts($required_cache_contexts, $cache_contexts), array( 'rendered', 'block_view', 'config:block_list', @@ -112,6 +117,8 @@ function testPageCacheTags() { 'config:system.menu.footer', 'config:system.menu.main', 'config:system.site', + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '1', 'full'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'block', 'bartik_account_menu'], Cache::mergeContexts($required_cache_contexts, ['route.menu_active_trails:account']), 'render'])), // FinishResponseSubscriber adds this cache tag to responses that have the // 'user.permissions' cache context for anonymous users. 'config:user.role.anonymous', @@ -149,6 +156,9 @@ function testPageCacheTags() { 'comment_list', 'node_list', 'config:views.view.comments_recent', + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'node', '2', 'full'], $required_cache_contexts, 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'block', 'bartik_account_menu'], Cache::mergeContexts($required_cache_contexts, ['route.menu_active_trails:account']), 'render'])), + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'block', 'recent-comments'], $required_cache_contexts, 'render'])), // FinishResponseSubscriber adds this cache tag to responses that have the // 'user.permissions' cache context for anonymous users. 'config:user.role.anonymous', diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php index a0f482a..2819d4a 100644 --- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php +++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php @@ -74,6 +74,8 @@ protected function setUp() { * Checks the behavior of the Serializer callback paths and row plugins. */ public function testSerializerResponses() { + $required_cache_contexts = $this->container->getParameter('renderer.config')['required_cache_contexts']; + // Test the serialize callback. $view = Views::getView('test_serializer_display_field'); $view->initDisplay(); @@ -81,7 +83,8 @@ public function testSerializerResponses() { $actual_json = $this->drupalGetWithFormat('test/serialize/field', 'json'); $this->assertResponse(200); - $this->assertCacheTags($view->getCacheTags()); + $redirect_cache_tag = 'render_cache_redirect:' . hash('sha1', serialize([['view', 'test_serializer_display_field', 'display', 'rest_export_1'], $required_cache_contexts, 'render'])); + $this->assertCacheTags(Cache::mergeTags($view->getCacheTags(), [$redirect_cache_tag])); $this->assertCacheContexts(['languages:language_interface', 'theme', 'request_format']); // @todo Due to https://www.drupal.org/node/2352009 we can't yet test the // propagation of cache max-age. @@ -138,13 +141,14 @@ public function testSerializerResponses() { foreach ($entities as $entity) { $expected_cache_tags = Cache::mergeTags($expected_cache_tags, $entity->getCacheTags()); } - $this->assertCacheTags($expected_cache_tags); + $redirect_cache_tag = 'render_cache_redirect:' . hash('sha1', serialize([['view', 'test_serializer_display_entity', 'display', 'rest_export_1'], $required_cache_contexts, 'render'])); + $this->assertCacheTags(Cache::mergeTags($expected_cache_tags, [$redirect_cache_tag])); $this->assertCacheContexts(['languages:language_interface', 'theme', 'entity_test_view_grants', 'request_format']); $expected = $serializer->serialize($entities, 'hal_json'); $actual_json = $this->drupalGetWithFormat('test/serialize/entity', 'hal_json'); $this->assertIdentical($actual_json, $expected, 'The expected HAL output was found.'); - $this->assertCacheTags($expected_cache_tags); + $this->assertCacheTags(Cache::mergeTags($expected_cache_tags, [$redirect_cache_tag])); // Change the default format to xml. $view->setDisplay('rest_export_1'); @@ -217,9 +221,11 @@ public function testRestRenderCaching() { $original = DisplayPluginBase::buildBasicRenderable('test_serializer_display_entity', 'rest_export_1'); + $required_cache_contexts = $this->container->getParameter('renderer.config')['required_cache_contexts']; + // Ensure that there is no corresponding render cache item yet. $original['#cache'] += ['contexts' => []]; - $original['#cache']['contexts'] = Cache::mergeContexts($original['#cache']['contexts'], $this->container->getParameter('renderer.config')['required_cache_contexts']); + $original['#cache']['contexts'] = Cache::mergeContexts($original['#cache']['contexts'], $required_cache_contexts); $cache_tags = [ 'config:views.view.test_serializer_display_entity', @@ -250,14 +256,15 @@ public function testRestRenderCaching() { $this->addRequestWithFormat('json'); $this->assertHeader('content-type', 'application/json'); $this->assertCacheContexts($cache_contexts); - $this->assertCacheTags($cache_tags); + $redirect_cache_tag = 'render_cache_redirect:' . hash('sha1', serialize([['view', 'test_serializer_display_entity', 'display', 'rest_export_1'], $required_cache_contexts, 'render'])); + $this->assertCacheTags(Cache::mergeTags($cache_tags, [$redirect_cache_tag])); $this->assertTrue($render_cache->get($original)); $result_xml = $this->drupalGetWithFormat('test/serialize/entity', 'xml'); $this->addRequestWithFormat('xml'); $this->assertHeader('content-type', 'text/xml; charset=UTF-8'); $this->assertCacheContexts($cache_contexts); - $this->assertCacheTags($cache_tags); + $this->assertCacheTags(Cache::mergeTags($cache_tags, [$redirect_cache_tag])); $this->assertTrue($render_cache->get($original)); // Ensure that the XML output is different from the JSON one. @@ -269,7 +276,7 @@ public function testRestRenderCaching() { $this->assertHeader('content-type', 'application/json'); $this->assertEqual($result2, $result1); $this->assertCacheContexts($cache_contexts); - $this->assertCacheTags($cache_tags); + $this->assertCacheTags(Cache::mergeTags($cache_tags, [$redirect_cache_tag])); $this->assertTrue($render_cache->get($original)); // Create a new entity and ensure that the cache tags are taken over. @@ -285,7 +292,7 @@ public function testRestRenderCaching() { unset($cache_tags[array_search('entity_test:1', $cache_tags)]); $this->assertCacheContexts($cache_contexts); - $this->assertCacheTags($cache_tags); + $this->assertCacheTags(Cache::mergeTags($cache_tags, [$redirect_cache_tag])); $this->assertTrue($render_cache->get($original)); } diff --git a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php index 5c3aacf..0ad7cf4 100644 --- a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php @@ -379,6 +379,20 @@ public function testReferencedEntity() { $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $this->getAdditionalCacheTagsForEntityListing($this->entity)); $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $page_cache_tags); + // Generate the expected redirect cache tags. + $access_cache_contexts = $this->getAccessCacheContextsForEntity($this->entity); + $additional_cache_contexts = $this->getAdditionalCacheContextsForEntity($this->referencingEntity); + $expected_redirect_cache_tags = []; + if (count($access_cache_contexts) || count($additional_cache_contexts)) { + $expected_redirect_cache_tags = [ + // The redirect cache tag for the referencing entity. + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', 'entity_test', $this->referencingEntity->id(),'full'], $entity_cache_contexts, 'render'])), + // The redirect cache tag for the referenced entity. + 'render_cache_redirect:' . hash('sha1', serialize([['entity_view', $this->entity->getEntityTypeId(), $this->entity->id(), 'full'], $entity_cache_contexts, 'render'])), + ]; + $page_cache_tags_referencing_entity = Cache::mergeTags($page_cache_tags_referencing_entity, $expected_redirect_cache_tags); + } + $this->pass("Test referencing entity.", 'Debug'); $this->verifyPageCache($referencing_entity_url, 'MISS'); @@ -390,8 +404,6 @@ public function testReferencedEntity() { // Also verify the existence of an entity render cache entry. $cache_keys = ['entity_view', 'entity_test', $this->referencingEntity->id(), 'full']; $cid = $this->createCacheId($cache_keys, $entity_cache_contexts); - $access_cache_contexts = $this->getAccessCacheContextsForEntity($this->entity); - $additional_cache_contexts = $this->getAdditionalCacheContextsForEntity($this->referencingEntity); $redirected_cid = NULL; if (count($access_cache_contexts) || count($additional_cache_contexts)) { $cache_contexts = Cache::mergeContexts($entity_cache_contexts, $additional_cache_contexts); @@ -399,6 +411,7 @@ public function testReferencedEntity() { $redirected_cid = $this->createCacheId($cache_keys, $cache_contexts); $context_metadata = \Drupal::service('cache_contexts_manager')->convertTokensToKeys($cache_contexts); $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $context_metadata->getCacheTags()); + $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $expected_redirect_cache_tags); } $this->verifyRenderCache($cid, $referencing_entity_cache_tags, $redirected_cid); diff --git a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php index d5aa9dc..c54fa8b 100644 --- a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php @@ -51,14 +51,16 @@ public function testEntityUri() { if (\Drupal::entityManager()->getDefinition($entity_type)->isRenderCacheable()) { $cache_keys = ['entity_view', $entity_type, $this->entity->id(), $view_mode]; $cid = $this->createCacheId($cache_keys, $entity_cache_contexts); + $expected_cache_tags = Cache::mergeTags($cache_tag, $view_cache_tag); + $expected_cache_tags = Cache::mergeTags($expected_cache_tags, $this->getAdditionalCacheTagsForEntity($this->entity)); + $expected_cache_tags = Cache::mergeTags($expected_cache_tags, array($render_cache_tag)); $redirected_cid = NULL; $additional_cache_contexts = $this->getAdditionalCacheContextsForEntity($this->entity); if (count($additional_cache_contexts)) { $redirected_cid = $this->createCacheId($cache_keys, Cache::mergeContexts($entity_cache_contexts, $additional_cache_contexts)); + $render_cache_redirect_cache_tag = 'render_cache_redirect:' . hash('sha1', serialize([$cache_keys, $entity_cache_contexts, 'render'])); + $expected_cache_tags = Cache::mergeTags($expected_cache_tags, [$render_cache_redirect_cache_tag]); } - $expected_cache_tags = Cache::mergeTags($cache_tag, $view_cache_tag); - $expected_cache_tags = Cache::mergeTags($expected_cache_tags, $this->getAdditionalCacheTagsForEntity($this->entity)); - $expected_cache_tags = Cache::mergeTags($expected_cache_tags, array($render_cache_tag)); $this->verifyRenderCache($cid, $expected_cache_tags, $redirected_cid); } diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index f9ae57a..dd73c1b 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -2332,7 +2332,7 @@ public function buildRenderable(array $args = [], $cache = TRUE) { $this->view->element['#cache'] += ['keys' => []]; // Places like \Drupal\views\ViewExecutable::setCurrentPage() set up an // additional cache context. - $this->view->element['#cache']['keys'] = array_merge(['views', 'display', $this->view->element['#name'], $this->view->element['#display_id']], $this->view->element['#cache']['keys']); + $this->view->element['#cache']['keys'] = array_merge(['view', $this->view->element['#name'], 'display', $this->view->element['#display_id']], $this->view->element['#cache']['keys']); $this->applyDisplayCachablityMetadata($this->view->element); } diff --git a/core/modules/views/src/Tests/RenderCacheIntegrationTest.php b/core/modules/views/src/Tests/RenderCacheIntegrationTest.php index 76a9857..fed359b 100644 --- a/core/modules/views/src/Tests/RenderCacheIntegrationTest.php +++ b/core/modules/views/src/Tests/RenderCacheIntegrationTest.php @@ -93,15 +93,19 @@ public function testFieldBasedViewCacheTagsWithCachePluginTime() { * Whether to check Views' result & output caches. */ protected function assertCacheTagsForFieldBasedView($do_assert_views_caches) { + $required_cache_contexts = $this->container->getParameter('renderer.config')['required_cache_contexts']; + $this->pass('Checking cache tags for field-based view.'); $view = Views::getview('entity_test_fields'); + $cache_plugin = $view->getDisplay()->getOption('cache')['type']; // Empty result (no entities yet). $this->pass('Test without entities'); $base_tags = ['config:views.view.entity_test_fields', 'entity_test_list']; $this->assertViewsCacheTags($view, $base_tags, $do_assert_views_caches, $base_tags); - $this->assertViewsCacheTagsFromStaticRenderArray($view, $base_tags, $do_assert_views_caches); - + // Cache redirect for the view's fields. + $redirect_tags = ($cache_plugin === 'none') ? [] : ['render_cache_redirect:' . hash('sha1', serialize([['view', 'entity_test_fields', 'display', 'default'], $required_cache_contexts, 'render']))]; + $this->assertViewsCacheTagsFromStaticRenderArray($view, Cache::mergeTags($base_tags, $redirect_tags), $do_assert_views_caches); // Non-empty result (1 entity). /** @var \Drupal\Core\Entity\EntityInterface[] $entities */ @@ -111,8 +115,7 @@ protected function assertCacheTagsForFieldBasedView($do_assert_views_caches) { $this->pass('Test with entities'); $tags_with_entity = Cache::mergeTags($base_tags, $entities[0]->getCacheTags()); $this->assertViewsCacheTags($view, $tags_with_entity, $do_assert_views_caches, $tags_with_entity); - $this->assertViewsCacheTagsFromStaticRenderArray($view, $tags_with_entity, $do_assert_views_caches); - + $this->assertViewsCacheTagsFromStaticRenderArray($view, Cache::mergeTags($tags_with_entity, $redirect_tags), $do_assert_views_caches); // Paged result (more entities than the items-per-page limit). for ($i = 0; $i < 5; $i++) { @@ -130,7 +133,7 @@ protected function assertCacheTagsForFieldBasedView($do_assert_views_caches) { $tags_page_1 = Cache::mergeTags($tags_page_1, $entities[4]->getCacheTags()); $tags_page_1 = Cache::mergeTags($tags_page_1, $entities[5]->getCacheTags()); $this->assertViewsCacheTags($view, $tags_page_1, $do_assert_views_caches, $tags_page_1); - $this->assertViewsCacheTagsFromStaticRenderArray($view, $tags_page_1, $do_assert_views_caches); + $this->assertViewsCacheTagsFromStaticRenderArray($view, Cache::mergeTags($tags_page_1, $redirect_tags), $do_assert_views_caches); $view->destroy(); // Page 2. $this->pass('Page 2'); @@ -160,7 +163,7 @@ protected function assertCacheTagsForFieldBasedView($do_assert_views_caches) { $entities[1]->name->value = $random_name = $this->randomMachineName(); $entities[1]->save(); $build = $this->assertViewsCacheTags($view, $tags_page_1, $do_assert_views_caches, $tags_page_1); - $this->assertViewsCacheTagsFromStaticRenderArray($view, $tags_page_1, $do_assert_views_caches); + $this->assertViewsCacheTagsFromStaticRenderArray($view, Cache::mergeTags($tags_page_1, $redirect_tags), $do_assert_views_caches); $this->assertTrue(strpos($build['#markup'], $random_name) !== FALSE); $view->destroy(); @@ -186,13 +189,19 @@ protected function assertCacheTagsForFieldBasedView($do_assert_views_caches) { $single_entity_assertions($build, $entities[0]); $view->setArguments([$entities[0]->id()]); - $build = $this->assertViewsCacheTagsFromStaticRenderArray($view, $tags_argument, $do_assert_views_caches); + // Because an argument is set, the render array's cache keys change, which + // means a different redirect is used. + $redirect_tags = ($cache_plugin === 'none') ? [] : ['render_cache_redirect:' . hash('sha1', serialize([['view', 'entity_test_fields', 'display', 'default', 'args', '1'], $required_cache_contexts, 'render']))]; + $build = $this->assertViewsCacheTagsFromStaticRenderArray($view, Cache::mergeTags($tags_argument, $redirect_tags), $do_assert_views_caches); $single_entity_assertions($build, $entities[0]); // Set a different argument and ensure that the result is different. $tags2_argument = Cache::mergeTags($base_tags, $entities[1]->getCacheTags()); + // Because a different argument is set, the render array's cache keys change + // again, which means again different redirect is used. + $redirect_tags = ($cache_plugin === 'none') ? [] : ['render_cache_redirect:' . hash('sha1', serialize([['view', 'entity_test_fields', 'display', 'default', 'args', '2'], $required_cache_contexts, 'render']))]; $view->setArguments([$entities[1]->id()]); - $build = $this->assertViewsCacheTagsFromStaticRenderArray($view, $tags2_argument, $do_assert_views_caches); + $build = $this->assertViewsCacheTagsFromStaticRenderArray($view, Cache::mergeTags($tags2_argument, $redirect_tags), $do_assert_views_caches); $single_entity_assertions($build, $entities[1]); $view->destroy(); @@ -245,13 +254,18 @@ public function testEntityBasedViewCacheTagsWithCachePluginTime() { * Tests cache tags on output & result cache items for an entity-based view. */ protected function assertCacheTagsForEntityBasedView($do_assert_views_caches) { + $required_cache_contexts = $this->container->getParameter('renderer.config')['required_cache_contexts']; + $this->pass('Checking cache tags for entity-based view.'); $view = Views::getview('entity_test_row'); + $cache_plugin = $view->getDisplay()->getOption('cache')['type']; // Empty result (no entities yet). $base_tags = $base_render_tags = ['config:views.view.entity_test_row', 'entity_test_list']; $this->assertViewsCacheTags($view, $base_tags, $do_assert_views_caches, $base_tags); - $this->assertViewsCacheTagsFromStaticRenderArray($view, $base_tags, $do_assert_views_caches); + // Cache redirect for the view's rows. + $redirect_tags = ($cache_plugin === 'none') ? [] : ['render_cache_redirect:' . hash('sha1', serialize([['view', 'entity_test_row', 'display', 'default'], $required_cache_contexts, 'render']))]; + $this->assertViewsCacheTagsFromStaticRenderArray($view, Cache::mergeTags($base_tags, $redirect_tags), $do_assert_views_caches); // Non-empty result (1 entity). $entities[] = $entity = EntityTest::create(); @@ -261,7 +275,7 @@ protected function assertCacheTagsForEntityBasedView($do_assert_views_caches) { $render_tags_with_entity = Cache::mergeTags($base_render_tags, $entities[0]->getCacheTags()); $render_tags_with_entity = Cache::mergeTags($render_tags_with_entity, ['entity_test_view']); $this->assertViewsCacheTags($view, $result_tags_with_entity, $do_assert_views_caches, $render_tags_with_entity); - $this->assertViewsCacheTagsFromStaticRenderArray($view, $render_tags_with_entity, $do_assert_views_caches); + $this->assertViewsCacheTagsFromStaticRenderArray($view, Cache::mergeTags($render_tags_with_entity, $redirect_tags), $do_assert_views_caches); // Paged result (more entities than the items-per-page limit). @@ -278,7 +292,7 @@ protected function assertCacheTagsForEntityBasedView($do_assert_views_caches) { $render_tags_page_1 = Cache::mergeTags($base_render_tags, $new_entities_cache_tags); $render_tags_page_1 = Cache::mergeTags($render_tags_page_1, ['entity_test_view']); $this->assertViewsCacheTags($view, $result_tags_page_1, $do_assert_views_caches, $render_tags_page_1); - $this->assertViewsCacheTagsFromStaticRenderArray($view, $render_tags_page_1, $do_assert_views_caches); + $this->assertViewsCacheTagsFromStaticRenderArray($view, Cache::mergeTags($render_tags_page_1, $redirect_tags), $do_assert_views_caches); } /**