core/lib/Drupal/Core/Access/AccessResult.php | 2 +- .../contact/src/Tests/ContactPersonalTest.php | 6 +++-- .../modules/node/src/Tests/Views/FrontPageTest.php | 6 ++--- core/modules/simpletest/src/WebTestBase.php | 13 +++++++++- .../Tests/Cache/PageCacheTagsIntegrationTest.php | 4 +-- core/modules/views/src/Tests/GlossaryTest.php | 2 +- .../Drupal/Tests/Core/Access/AccessResultTest.php | 29 ++++++++++++++++++++-- 7 files changed, 50 insertions(+), 12 deletions(-) diff --git a/core/lib/Drupal/Core/Access/AccessResult.php b/core/lib/Drupal/Core/Access/AccessResult.php index 98d7947..1ef2a40 100644 --- a/core/lib/Drupal/Core/Access/AccessResult.php +++ b/core/lib/Drupal/Core/Access/AccessResult.php @@ -346,7 +346,7 @@ public function cachePerRole() { // will change! To invalidate accordingly, we need this cache tag. // This will be handled automatically once // https://www.drupal.org/node/2428703 lands. - ->addCacheTags(['config:user_role_list']); + ->addCacheTags(Cache::buildTags('config:user.role', \Drupal::currentUser()->getRoles(), '.')); return $this; } diff --git a/core/modules/contact/src/Tests/ContactPersonalTest.php b/core/modules/contact/src/Tests/ContactPersonalTest.php index 78bcc3f..42b9b6a 100644 --- a/core/modules/contact/src/Tests/ContactPersonalTest.php +++ b/core/modules/contact/src/Tests/ContactPersonalTest.php @@ -152,13 +152,15 @@ function testPersonalContactAccess() { // Test that anonymous users can access admin user's contact form. $this->drupalGet('user/' . $this->adminUser->id() . '/contact'); $this->assertResponse(200); - $this->assertCacheTag('config:user_role_list'); + $this->assertCacheContext('user.roles'); + $this->assertCacheTag('config:user.role.anonymous'); // Revoke the personal contact permission for the anonymous user. user_role_revoke_permissions(RoleInterface::ANONYMOUS_ID, array('access user contact forms')); $this->drupalGet('user/' . $this->contactUser->id() . '/contact'); $this->assertResponse(403); - $this->assertCacheTag('config:user_role_list'); + $this->assertCacheContext('user.roles'); + $this->assertCacheTag('config:user.role.anonymous'); $this->drupalGet('user/' . $this->adminUser->id() . '/contact'); $this->assertResponse(403); diff --git a/core/modules/node/src/Tests/Views/FrontPageTest.php b/core/modules/node/src/Tests/Views/FrontPageTest.php index 0a5e8d6..9e14395 100644 --- a/core/modules/node/src/Tests/Views/FrontPageTest.php +++ b/core/modules/node/src/Tests/Views/FrontPageTest.php @@ -257,7 +257,7 @@ protected function assertFrontPageViewCacheTags($do_assert_views_caches) { $this->assertPageCacheContextsAndTags( Url::fromRoute('view.frontpage.page_1'), $cache_contexts, - Cache::mergeTags($empty_node_listing_cache_tags, ['config:user_role_list', 'rendered']) + Cache::mergeTags($empty_node_listing_cache_tags, ['config:user.role.anonymous', 'rendered']) ); // Create some nodes on the frontpage view. Add more than 10 nodes in order @@ -317,7 +317,7 @@ protected function assertFrontPageViewCacheTags($do_assert_views_caches) { $this->assertPageCacheContextsAndTags( Url::fromRoute('view.frontpage.page_1'), $cache_contexts, - Cache::mergeTags($first_page_output_cache_tags, ['config:user_role_list', 'rendered']) + Cache::mergeTags($first_page_output_cache_tags, ['config:user.role.anonymous', 'rendered']) ); // Second page. @@ -329,7 +329,7 @@ protected function assertFrontPageViewCacheTags($do_assert_views_caches) { 'node:4', 'node:5', // The rest. - 'config:user_role_list', + 'config:user.role.anonymous', 'config:filter.format.plain_text', 'config:views.view.frontpage', 'node_list', diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index 63cf76a..f939af3 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -2740,6 +2740,17 @@ protected function buildUrl($path, array $options = array()) { } /** + * Asserts whether an expected cache context was present in the last response. + * + * @param string $expected_cache_context + * The expected cache context. + */ + protected function assertCacheContext($expected_cache_context) { + $cache_contexts = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Contexts')); + $this->assertTrue(in_array($expected_cache_context, $cache_contexts), "'" . $expected_cache_context . "' is present in the X-Drupal-Cache-Contexts header."); + } + + /** * Asserts whether an expected cache tag was present in the last response. * * @param string $expected_cache_tag @@ -2747,7 +2758,7 @@ protected function buildUrl($path, array $options = array()) { */ protected function assertCacheTag($expected_cache_tag) { $cache_tags = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Tags')); - $this->assertTrue(in_array($expected_cache_tag, $cache_tags)); + $this->assertTrue(in_array($expected_cache_tag, $cache_tags), "'" . $expected_cache_tag . "' is present in the X-Drupal-Cache-Tags header."); } } diff --git a/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php b/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php index 05801e8..aa84eed 100644 --- a/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php +++ b/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php @@ -101,7 +101,7 @@ function testPageCacheTags() { 'config:system.menu.footer', 'config:system.menu.main', 'config:system.site', - 'config:user_role_list', + 'config:user.role.anonymous', )); // Full node page 2. @@ -131,7 +131,7 @@ function testPageCacheTags() { 'comment_list', 'node_list', 'config:views.view.comments_recent', - 'config:user_role_list', + 'config:user.role.anonymous', )); } diff --git a/core/modules/views/src/Tests/GlossaryTest.php b/core/modules/views/src/Tests/GlossaryTest.php index 612d08c..b78225d 100644 --- a/core/modules/views/src/Tests/GlossaryTest.php +++ b/core/modules/views/src/Tests/GlossaryTest.php @@ -88,7 +88,7 @@ public function testGlossaryView() { // Verify cache tags. $this->enablePageCaching(); $this->assertPageCacheContextsAndTags(Url::fromRoute('view.glossary.page_1'), ['languages', 'url', 'user'], [ - 'config:user_role_list', + 'config:user.role.anonymous', 'config:views.view.glossary', 'node:' . $nodes_by_char['a'][0]->id(), 'node:' . $nodes_by_char['a'][1]->id(), 'node:' . $nodes_by_char['a'][2]->id(), 'node_list', diff --git a/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php b/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php index 92d22c5..1c1a44f 100644 --- a/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php +++ b/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php @@ -13,6 +13,7 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableInterface; use Drupal\Tests\UnitTestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; /** * @coversDefaultClass \Drupal\Core\Access\AccessResult @@ -30,6 +31,23 @@ protected function assertDefaultCacheability(AccessResult $access) { } /** + * Mocks the current user service, so that ::cachePerRole() can work. + * + * @see ::cachePerRole + * + * @todo remove this when https://www.drupal.org/node/2428703 lands. + */ + protected function mockCurrentUserService() { + $container = new ContainerBuilder(); + $current_user = $this->getMock('\Drupal\Core\Session\AccountProxyInterface'); + $current_user->expects($this->any()) + ->method('getRoles') + ->willReturn(['authenticated', 'llama_herder']); + $container->set('current_user', $current_user); + \Drupal::setContainer($container); + } + + /** * Tests the construction of an AccessResult object. * * @covers ::__construct @@ -325,6 +343,8 @@ public function testCacheMaxAge() { * @covers ::allowedIfHasPermission */ public function testCacheContexts() { + $this->mockCurrentUserService(); + $verify = function (AccessResult $access, array $contexts, array $tags = []) { $this->assertFalse($access->isAllowed()); $this->assertFalse($access->isForbidden()); @@ -357,7 +377,7 @@ public function testCacheContexts() { // ::cachePerRole() convenience method. $contexts = array('user.roles'); - $tags = ['config:user_role_list']; + $tags = ['config:user.role.authenticated', 'config:user.role.llama_herder']; $a = AccessResult::neutral()->addCacheContexts($contexts)->addCacheTags($tags); $verify($a, $contexts, $tags); $b = AccessResult::neutral()->cachePerRole(); @@ -468,13 +488,15 @@ public function testCacheTags() { * @covers ::inheritCacheability */ public function testInheritCacheability() { + $this->mockCurrentUserService(); + // andIf(); 1st has defaults, 2nd has custom tags, contexts and max-age. $access = AccessResult::allowed(); $other = AccessResult::allowed()->setCacheMaxAge(1500)->cachePerRole()->addCacheTags(['node:20011988']); $this->assertTrue($access->inheritCacheability($other) instanceof AccessResult); $this->assertTrue($access->isCacheable()); $this->assertSame(['user.roles'], $access->getCacheContexts()); - $this->assertSame(['config:user_role_list', 'node:20011988'], $access->getCacheTags()); + $this->assertSame(['config:user.role.authenticated', 'config:user.role.llama_herder', 'node:20011988'], $access->getCacheTags()); $this->assertSame('default', $access->getCacheBin()); $this->assertSame(1500, $access->getCacheMaxAge()); @@ -825,6 +847,8 @@ public function testAndOrCacheabilityPropagation(AccessResultInterface $first, $ * @dataProvider providerTestAllowedIfHasPermissions */ public function testAllowIfHasPermissions($permissions, $conjunction, $expected_access) { + $this->mockCurrentUserService(); + $account = $this->getMock('\Drupal\Core\Session\AccountInterface'); $account->expects($this->any()) ->method('hasPermission') @@ -843,6 +867,7 @@ public function testAllowIfHasPermissions($permissions, $conjunction, $expected_ * @return array */ public function providerTestAllowedIfHasPermissions() { + $this->mockCurrentUserService(); return [ [[], 'AND', AccessResult::allowedIf(FALSE)->cachePerRole()], [[], 'OR', AccessResult::allowedIf(FALSE)->cachePerRole()],