BlockCacheTest.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <?php
  2. namespace Drupal\Tests\block\Functional;
  3. use Drupal\Core\Cache\Cache;
  4. use Drupal\Tests\BrowserTestBase;
  5. /**
  6. * Tests block caching.
  7. *
  8. * @group block
  9. */
  10. class BlockCacheTest extends BrowserTestBase {
  11. /**
  12. * Modules to install.
  13. *
  14. * @var array
  15. */
  16. public static $modules = ['block', 'block_test', 'test_page_test'];
  17. /**
  18. * A user with permission to create and edit books and to administer blocks.
  19. *
  20. * @var object
  21. */
  22. protected $adminUser;
  23. /**
  24. * An authenticated user to test block caching.
  25. *
  26. * @var object
  27. */
  28. protected $normalUser;
  29. /**
  30. * Another authenticated user to test block caching.
  31. *
  32. * @var object
  33. */
  34. protected $normalUserAlt;
  35. /**
  36. * The block used by this test.
  37. *
  38. * @var \Drupal\block\BlockInterface
  39. */
  40. protected $block;
  41. protected function setUp() {
  42. parent::setUp();
  43. // Create an admin user, log in and enable test blocks.
  44. $this->adminUser = $this->drupalCreateUser(['administer blocks', 'access administration pages']);
  45. $this->drupalLogin($this->adminUser);
  46. // Create additional users to test caching modes.
  47. $this->normalUser = $this->drupalCreateUser();
  48. $this->normalUserAlt = $this->drupalCreateUser();
  49. // Sync the roles, since drupalCreateUser() creates separate roles for
  50. // the same permission sets.
  51. $this->normalUserAlt->roles = $this->normalUser->getRoles();
  52. $this->normalUserAlt->save();
  53. // Enable our test block.
  54. $this->block = $this->drupalPlaceBlock('test_cache');
  55. }
  56. /**
  57. * Test "user.roles" cache context.
  58. */
  59. public function testCachePerRole() {
  60. \Drupal::state()->set('block_test.cache_contexts', ['user.roles']);
  61. // Enable our test block. Set some content for it to display.
  62. $current_content = $this->randomMachineName();
  63. \Drupal::state()->set('block_test.content', $current_content);
  64. $this->drupalLogin($this->normalUser);
  65. $this->drupalGet('');
  66. $this->assertText($current_content, 'Block content displays.');
  67. // Change the content, but the cached copy should still be served.
  68. $old_content = $current_content;
  69. $current_content = $this->randomMachineName();
  70. \Drupal::state()->set('block_test.content', $current_content);
  71. $this->drupalGet('');
  72. $this->assertText($old_content, 'Block is served from the cache.');
  73. // Clear the cache and verify that the stale data is no longer there.
  74. Cache::invalidateTags(['block_view']);
  75. $this->drupalGet('');
  76. $this->assertNoText($old_content, 'Block cache clear removes stale cache data.');
  77. $this->assertText($current_content, 'Fresh block content is displayed after clearing the cache.');
  78. // Test whether the cached data is served for the correct users.
  79. $old_content = $current_content;
  80. $current_content = $this->randomMachineName();
  81. \Drupal::state()->set('block_test.content', $current_content);
  82. $this->drupalLogout();
  83. $this->drupalGet('');
  84. $this->assertNoText($old_content, 'Anonymous user does not see content cached per-role for normal user.');
  85. $this->drupalLogin($this->normalUserAlt);
  86. $this->drupalGet('');
  87. $this->assertText($old_content, 'User with the same roles sees per-role cached content.');
  88. $this->drupalLogin($this->adminUser);
  89. $this->drupalGet('');
  90. $this->assertNoText($old_content, 'Admin user does not see content cached per-role for normal user.');
  91. $this->drupalLogin($this->normalUser);
  92. $this->drupalGet('');
  93. $this->assertText($old_content, 'Block is served from the per-role cache.');
  94. }
  95. /**
  96. * Test a cacheable block without any additional cache context.
  97. */
  98. public function testCachePermissions() {
  99. // user.permissions is a required context, so a user with different
  100. // permissions will see a different version of the block.
  101. \Drupal::state()->set('block_test.cache_contexts', []);
  102. $current_content = $this->randomMachineName();
  103. \Drupal::state()->set('block_test.content', $current_content);
  104. $this->drupalGet('');
  105. $this->assertText($current_content, 'Block content displays.');
  106. $old_content = $current_content;
  107. $current_content = $this->randomMachineName();
  108. \Drupal::state()->set('block_test.content', $current_content);
  109. $this->drupalGet('user');
  110. $this->assertText($old_content, 'Block content served from cache.');
  111. $this->drupalLogout();
  112. $this->drupalGet('user');
  113. $this->assertText($current_content, 'Block content not served from cache.');
  114. }
  115. /**
  116. * Test non-cacheable block.
  117. */
  118. public function testNoCache() {
  119. \Drupal::state()->set('block_test.cache_max_age', 0);
  120. $current_content = $this->randomMachineName();
  121. \Drupal::state()->set('block_test.content', $current_content);
  122. // If max_age = 0 has no effect, the next request would be cached.
  123. $this->drupalGet('');
  124. $this->assertText($current_content, 'Block content displays.');
  125. // A cached copy should not be served.
  126. $current_content = $this->randomMachineName();
  127. \Drupal::state()->set('block_test.content', $current_content);
  128. $this->drupalGet('');
  129. $this->assertText($current_content, 'Maximum age of zero prevents blocks from being cached.');
  130. }
  131. /**
  132. * Test "user" cache context.
  133. */
  134. public function testCachePerUser() {
  135. \Drupal::state()->set('block_test.cache_contexts', ['user']);
  136. $current_content = $this->randomMachineName();
  137. \Drupal::state()->set('block_test.content', $current_content);
  138. $this->drupalLogin($this->normalUser);
  139. $this->drupalGet('');
  140. $this->assertText($current_content, 'Block content displays.');
  141. $old_content = $current_content;
  142. $current_content = $this->randomMachineName();
  143. \Drupal::state()->set('block_test.content', $current_content);
  144. $this->drupalGet('');
  145. $this->assertText($old_content, 'Block is served from per-user cache.');
  146. $this->drupalLogin($this->normalUserAlt);
  147. $this->drupalGet('');
  148. $this->assertText($current_content, 'Per-user block cache is not served for other users.');
  149. $this->drupalLogin($this->normalUser);
  150. $this->drupalGet('');
  151. $this->assertText($old_content, 'Per-user block cache is persistent.');
  152. }
  153. /**
  154. * Test "url" cache context.
  155. */
  156. public function testCachePerPage() {
  157. \Drupal::state()->set('block_test.cache_contexts', ['url']);
  158. $current_content = $this->randomMachineName();
  159. \Drupal::state()->set('block_test.content', $current_content);
  160. $this->drupalGet('test-page');
  161. $this->assertText($current_content, 'Block content displays on the test page.');
  162. $old_content = $current_content;
  163. $current_content = $this->randomMachineName();
  164. \Drupal::state()->set('block_test.content', $current_content);
  165. $this->drupalGet('user');
  166. $this->assertResponse(200);
  167. $this->assertNoText($old_content, 'Block content cached for the test page does not show up for the user page.');
  168. $this->drupalGet('test-page');
  169. $this->assertResponse(200);
  170. $this->assertText($old_content, 'Block content cached for the test page.');
  171. }
  172. }