Issue #2396333 by larowlan, effulgentsia, Wim Leers, tim.plunkett: BlockContentBlock ignores cache contexts required by the block_content entity

8.0.x
Nathaniel Catchpole 2015-03-06 16:24:32 +00:00
parent 6ba9484cee
commit 5ad41abb9d
3 changed files with 43 additions and 8 deletions

View File

@ -169,6 +169,10 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
// Collect cache defaults for this entity.
'#cache' => array(
'tags' => Cache::mergeTags($this->getCacheTags(), $entity->getCacheTags()),
'contexts' => [
'theme',
'user.roles',
],
),
);
@ -182,10 +186,6 @@ class EntityViewBuilder extends EntityHandlerBase implements EntityHandlerInterf
$entity->id(),
$view_mode,
),
'contexts' => array(
'theme',
'user.roles',
),
'bin' => $this->cacheBin,
);

View File

@ -7,9 +7,11 @@
namespace Drupal\block_content\Tests;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\system\Tests\Entity\EntityCacheTagsTestBase;
use Symfony\Component\HttpFoundation\Request;
/**
* Tests the Custom Block entity's cache tags.
@ -58,4 +60,37 @@ class BlockContentCacheTagsTest extends EntityCacheTagsTestBase {
return ['config:filter.format.plain_text'];
}
/**
* Tests that the block is cached with the correct contexts and tags.
*/
public function testBlock() {
$block = $this->drupalPlaceBlock('block_content:' . $this->entity->uuid(), ['cache' => []]);
$build = $this->container->get('entity.manager')->getViewBuilder('block')->view($block, 'block');
// Render the block.
// @todo The request stack manipulation won't be necessary once
// https://www.drupal.org/node/2367555 is fixed and the
// corresponding $request->isMethodSafe() checks are removed from
// Drupal\Core\Render\Renderer.
$request_stack = $this->container->get('request_stack');
$request_stack->push(new Request());
$this->container->get('renderer')->render($build);
$request_stack->pop();
// Expected keys, contexts, and tags for the block.
// @see \Drupal\block\BlockViewBuilder::viewMultiple()
$expected_block_cache_keys = ['entity_view', 'block', $block->id()];
$expected_block_cache_contexts = ['language', 'theme'];
$expected_block_cache_tags = Cache::mergeTags(['block_view', 'rendered'], $block->getCacheTags(), $block->getPlugin()->getCacheTags());
// Expected contexts and tags for the BlockContent entity.
// @see \Drupal\Core\Entity\EntityViewBuilder::getBuildDefaults().
$expected_entity_cache_contexts = ['theme', 'user.roles'];
$expected_entity_cache_tags = Cache::mergeTags(['block_content_view'], $this->entity->getCacheTags(), $this->getAdditionalCacheTagsForEntity($this->entity));
// Verify that what was render cached matches the above expectations.
$cid = $this->createCacheId($expected_block_cache_keys, $expected_block_cache_contexts);
$redirected_cid = $this->createCacheId($expected_block_cache_keys, Cache::mergeContexts($expected_block_cache_contexts, $expected_entity_cache_contexts));
$this->verifyRenderCache($cid, Cache::mergeTags($expected_block_cache_tags, $expected_entity_cache_tags), $redirected_cid);
}
}

View File

@ -52,7 +52,7 @@ class EntityViewBuilderTest extends EntityUnitTestBase {
// Test that new entities (before they are saved for the first time) do not
// generate a cache entry.
$build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test, 'full');
$this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == array('tags'), 'The render array element of new (unsaved) entities is not cached, but does have cache tags set.');
$this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == ['tags', 'contexts'], 'The render array element of new (unsaved) entities is not cached, but does have cache tags set.');
// Get a fully built entity view render array.
$entity_test->save();
@ -157,17 +157,17 @@ class EntityViewBuilderTest extends EntityUnitTestBase {
// Test a view mode in default conditions: render caching is enabled for
// the entity type and the view mode.
$build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test, 'full');
$this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == array('tags', 'keys', 'contexts', 'bin') , 'A view mode with render cache enabled has the correct output (cache tags, keys, contexts and bin).');
$this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == ['tags', 'contexts', 'keys', 'bin'] , 'A view mode with render cache enabled has the correct output (cache tags, keys, contexts and bin).');
// Test that a view mode can opt out of render caching.
$build = $this->container->get('entity.manager')->getViewBuilder('entity_test')->view($entity_test, 'test');
$this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == array('tags'), 'A view mode with render cache disabled has the correct output (only cache tags).');
$this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == ['tags', 'contexts'], 'A view mode with render cache disabled has the correct output (only cache tags).');
// Test that an entity type can opt out of render caching completely.
$entity_test_no_cache = $this->createTestEntity('entity_test_label');
$entity_test_no_cache->save();
$build = $this->container->get('entity.manager')->getViewBuilder('entity_test_label')->view($entity_test_no_cache, 'full');
$this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == array('tags'), 'An entity type can opt out of render caching regardless of view mode configuration, but always has cache tags set.');
$this->assertTrue(isset($build['#cache']) && array_keys($build['#cache']) == ['tags', 'contexts'], 'An entity type can opt out of render caching regardless of view mode configuration, but always has cache tags set.');
}
/**