You are here

public function BlockTest::testBlockCacheTags in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/block/tests/src/Functional/BlockTest.php \Drupal\Tests\block\Functional\BlockTest::testBlockCacheTags()

Tests that cache tags are properly set and bubbled up to the page cache.

Verify that invalidation of these cache tags works:

  • "block:<block ID>"
  • "block_plugin:<block plugin ID>"

File

core/modules/block/tests/src/Functional/BlockTest.php, line 389

Class

BlockTest
Tests basic block functionality.

Namespace

Drupal\Tests\block\Functional

Code

public function testBlockCacheTags() {

  // The page cache only works for anonymous users.
  $this
    ->drupalLogout();

  // Enable page caching.
  $config = $this
    ->config('system.performance');
  $config
    ->set('cache.page.max_age', 300);
  $config
    ->save();

  // Place the "Powered by Drupal" block.
  $block = $this
    ->drupalPlaceBlock('system_powered_by_block', [
    'id' => 'powered',
  ]);

  // Prime the page cache.
  $this
    ->drupalGet('<front>');
  $this
    ->assertSession()
    ->responseHeaderEquals('X-Drupal-Cache', 'MISS');

  // Verify a cache hit, but also the presence of the correct cache tags in
  // both the page and block caches.
  $this
    ->drupalGet('<front>');
  $this
    ->assertSession()
    ->responseHeaderEquals('X-Drupal-Cache', 'HIT');
  $cid_parts = [
    Url::fromRoute('<front>', [], [
      'absolute' => TRUE,
    ])
      ->toString(),
    '',
  ];
  $cid = implode(':', $cid_parts);
  $cache_entry = \Drupal::cache('page')
    ->get($cid);
  $expected_cache_tags = [
    'config:block_list',
    'block_view',
    'config:block.block.powered',
    'config:user.role.anonymous',
    'http_response',
    'rendered',
  ];
  sort($expected_cache_tags);
  $keys = \Drupal::service('cache_contexts_manager')
    ->convertTokensToKeys([
    'languages:language_interface',
    'theme',
    'user.permissions',
  ])
    ->getKeys();
  $this
    ->assertSame($expected_cache_tags, $cache_entry->tags);
  $cache_entry = \Drupal::cache('render')
    ->get('entity_view:block:powered:' . implode(':', $keys));
  $expected_cache_tags = [
    'block_view',
    'config:block.block.powered',
    'rendered',
  ];
  sort($expected_cache_tags);
  $this
    ->assertSame($expected_cache_tags, $cache_entry->tags);

  // The "Powered by Drupal" block is modified; verify a cache miss.
  $block
    ->setRegion('content');
  $block
    ->save();
  $this
    ->drupalGet('<front>');
  $this
    ->assertSession()
    ->responseHeaderEquals('X-Drupal-Cache', 'MISS');

  // Now we should have a cache hit again.
  $this
    ->drupalGet('<front>');
  $this
    ->assertSession()
    ->responseHeaderEquals('X-Drupal-Cache', 'HIT');

  // Place the "Powered by Drupal" block another time; verify a cache miss.
  $this
    ->drupalPlaceBlock('system_powered_by_block', [
    'id' => 'powered-2',
  ]);
  $this
    ->drupalGet('<front>');
  $this
    ->assertSession()
    ->responseHeaderEquals('X-Drupal-Cache', 'MISS');

  // Verify a cache hit, but also the presence of the correct cache tags.
  $this
    ->drupalGet('<front>');
  $this
    ->assertSession()
    ->responseHeaderEquals('X-Drupal-Cache', 'HIT');
  $cid_parts = [
    Url::fromRoute('<front>', [], [
      'absolute' => TRUE,
    ])
      ->toString(),
    '',
  ];
  $cid = implode(':', $cid_parts);
  $cache_entry = \Drupal::cache('page')
    ->get($cid);
  $expected_cache_tags = [
    'config:block_list',
    'block_view',
    'config:block.block.powered',
    'config:block.block.powered-2',
    'config:user.role.anonymous',
    'http_response',
    'rendered',
  ];
  sort($expected_cache_tags);
  $this
    ->assertEquals($expected_cache_tags, $cache_entry->tags);
  $expected_cache_tags = [
    'block_view',
    'config:block.block.powered',
    'rendered',
  ];
  sort($expected_cache_tags);
  $keys = \Drupal::service('cache_contexts_manager')
    ->convertTokensToKeys([
    'languages:language_interface',
    'theme',
    'user.permissions',
  ])
    ->getKeys();
  $cache_entry = \Drupal::cache('render')
    ->get('entity_view:block:powered:' . implode(':', $keys));
  $this
    ->assertSame($expected_cache_tags, $cache_entry->tags);
  $expected_cache_tags = [
    'block_view',
    'config:block.block.powered-2',
    'rendered',
  ];
  sort($expected_cache_tags);
  $keys = \Drupal::service('cache_contexts_manager')
    ->convertTokensToKeys([
    'languages:language_interface',
    'theme',
    'user.permissions',
  ])
    ->getKeys();
  $cache_entry = \Drupal::cache('render')
    ->get('entity_view:block:powered-2:' . implode(':', $keys));
  $this
    ->assertSame($expected_cache_tags, $cache_entry->tags);

  // Now we should have a cache hit again.
  $this
    ->drupalGet('<front>');
  $this
    ->assertSession()
    ->responseHeaderEquals('X-Drupal-Cache', 'HIT');

  // Delete the "Powered by Drupal" blocks; verify a cache miss.
  $block_storage = \Drupal::entityTypeManager()
    ->getStorage('block');
  $block_storage
    ->load('powered')
    ->delete();
  $block_storage
    ->load('powered-2')
    ->delete();
  $this
    ->drupalGet('<front>');
  $this
    ->assertSession()
    ->responseHeaderEquals('X-Drupal-Cache', 'MISS');
}