.../src/Tests/Entity/EntityCacheTagsTestBase.php | 49 +++++++++++++++++----- .../Entity/EntityWithUriCacheTagsTestBase.php | 8 +++- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php index 3bfe637..580cada 100644 --- a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php @@ -303,6 +303,9 @@ public function testReferencedEntity() { $empty_entity_listing_url = Url::fromRoute('entity.entity_test.collection_empty', ['entity_type_id' => $entity_type]); $nonempty_entity_listing_url = Url::fromRoute('entity.entity_test.collection_labels_alphabetically', ['entity_type_id' => $entity_type]); + // The default cache contexts for rendered entities. + $entity_cache_contexts = ['theme', 'user.roles']; + // Cache tags present on every rendered page. $page_cache_tags = Cache::mergeTags( ['rendered'], @@ -352,8 +355,9 @@ public function testReferencedEntity() { // Verify a cache hit, but also the presence of the correct cache tags. $this->verifyPageCache($referencing_entity_url, 'HIT', Cache::mergeTags($referencing_entity_cache_tags, $page_cache_tags)); // Also verify the existence of an entity render cache entry. - $cid = 'entity_view:entity_test:' . $this->referencing_entity->id() . ':full:classy:r.anonymous'; - $redirected_cid = $this->buildRedirectedCid($cid); + $cache_keys = ['entity_view', 'entity_test', $this->referencing_entity->id(), 'full']; + $cid = $this->createCacheId($cache_keys, $entity_cache_contexts); + $redirected_cid = $this->createRedirectedCacheId($cache_keys, $entity_cache_contexts); $this->verifyRenderCache($cid, $referencing_entity_cache_tags, $redirected_cid); $this->pass("Test non-referencing entity.", 'Debug'); @@ -361,7 +365,8 @@ public function testReferencedEntity() { // Verify a cache hit, but also the presence of the correct cache tags. $this->verifyPageCache($non_referencing_entity_url, 'HIT', Cache::mergeTags($non_referencing_entity_cache_tags, $page_cache_tags)); // Also verify the existence of an entity render cache entry. - $cid = 'entity_view:entity_test:' . $this->non_referencing_entity->id() . ':full:classy:r.anonymous'; + $cache_keys = ['entity_view', 'entity_test', $this->non_referencing_entity->id(), 'full']; + $cid = $this->createCacheId($cache_keys, $entity_cache_contexts); $this->verifyRenderCache($cid, $non_referencing_entity_cache_tags); @@ -595,26 +600,50 @@ public function testReferencedEntity() { } /** - * Build the redirected CID, if any. + * Creates a cache ID from a list of cache keys and a set of cache contexts. + * + * @param string[] $keys + * A list of cache keys. + * @param string[] $contexts + * A set of cache contexts. + * + * @return string + * The cache ID string. + */ + protected function createCacheId(array $keys, array $contexts) { + $cid_parts = $keys; + + sort($contexts); + $contexts = \Drupal::service('cache_contexts')->convertTokensToKeys($contexts); + $cid_parts = array_merge($cid_parts, $contexts); + + return implode(':', $cid_parts); + } + + /** + * Creates the redirected cache ID, if any. * * If a subclass overrides ::getAdditionalCacheContextsForEntity(), it can * specify the additional cache contexts by which the given entity must be * varied, because those are the cache contexts that are bubbled from the * field formatters. * - * @param string $cid - * The regular (pre-bubbling) CID. + * @param string[] $keys + * A list of cache keys used for the regular (pre-bubbling) CID. + * @param string[] $contexts + * A set of cache contexts used for the regular (pre-bubbling) CID. * * @return null|string * The redirected (post-bubbling) CID, if any. */ - protected function buildRedirectedCid($cid) { - $redirected_cid = NULL; + protected function createRedirectedCacheId(array $keys, array $contexts) { $additional_cache_contexts = $this->getAdditionalCacheContextsForEntity($this->referencing_entity); if (count($additional_cache_contexts)) { - $redirected_cid = $cid . ':' . implode(':', \Drupal::service('cache_contexts')->convertTokensToKeys($additional_cache_contexts)); + return $this->createCacheId($keys, Cache::mergeContexts($contexts, $additional_cache_contexts)); + } + else { + return NULL; } - return $redirected_cid; } /** diff --git a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php index ae0873c..c72d7d0 100644 --- a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php @@ -30,6 +30,9 @@ public function testEntityUri() { // Selects the view mode that will be used. $view_mode = $this->selectViewMode($entity_type); + // The default cache contexts for rendered entities. + $entity_cache_contexts = ['theme', 'user.roles']; + // Generate the standardized entity cache tags. $cache_tag = $this->entity->getCacheTags(); $view_cache_tag = \Drupal::entityManager()->getViewBuilder($entity_type)->getCacheTags(); @@ -45,8 +48,9 @@ public function testEntityUri() { // Also verify the existence of an entity render cache entry, if this entity // type supports render caching. if (\Drupal::entityManager()->getDefinition($entity_type)->isRenderCacheable()) { - $cid = 'entity_view:' . $entity_type . ':' . $this->entity->id() . ':' . $view_mode . ':classy:r.anonymous'; - $redirected_cid = $this->buildRedirectedCid($cid); + $cache_keys = ['entity_view', $entity_type, $this->entity->id(), $view_mode]; + $cid = $this->createCacheId($cache_keys, $entity_cache_contexts); + $redirected_cid = $this->createRedirectedCacheId($cache_keys, $entity_cache_contexts); $expected_cache_tags = Cache::mergeTags($cache_tag, $view_cache_tag, $this->getAdditionalCacheTagsForEntity($this->entity), array($render_cache_tag)); $this->verifyRenderCache($cid, $expected_cache_tags, $redirected_cid); }