From 6ef8c1e2694119d0ead3a95cd0efd5a7e79cd7e5 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Tue, 12 Mar 2024 12:06:48 +0000 Subject: [PATCH] Issue #3426624 by plopesc, smustgrave: Shortcuts Block does not include the necessary cache tags --- .../src/Plugin/Block/ShortcutsBlock.php | 7 +- .../shortcut/src/ShortcutLazyBuilders.php | 7 +- .../src/Functional/ShortcutCacheTagsTest.php | 120 ++++++++++++++++++ 3 files changed, 131 insertions(+), 3 deletions(-) diff --git a/core/modules/shortcut/src/Plugin/Block/ShortcutsBlock.php b/core/modules/shortcut/src/Plugin/Block/ShortcutsBlock.php index f11f836b4369..3e63178e1628 100644 --- a/core/modules/shortcut/src/Plugin/Block/ShortcutsBlock.php +++ b/core/modules/shortcut/src/Plugin/Block/ShortcutsBlock.php @@ -23,7 +23,12 @@ class ShortcutsBlock extends BlockBase { */ public function build() { return [ - shortcut_renderable_links(shortcut_current_displayed_set()), + '#lazy_builder' => ['shortcut.lazy_builders:lazyLinks', [FALSE]], + '#create_placeholder' => TRUE, + '#cache' => [ + 'keys' => ['shortcut_set_block_links'], + 'contexts' => ['user'], + ], ]; } diff --git a/core/modules/shortcut/src/ShortcutLazyBuilders.php b/core/modules/shortcut/src/ShortcutLazyBuilders.php index e2672104c59f..caf0be9b3e10 100644 --- a/core/modules/shortcut/src/ShortcutLazyBuilders.php +++ b/core/modules/shortcut/src/ShortcutLazyBuilders.php @@ -38,16 +38,19 @@ public static function trustedCallbacks() { /** * #lazy_builder callback; builds shortcut toolbar links. * + * @param bool $show_configure_link + * Boolean to indicate whether to include the configure link or not. + * * @return array * A renderable array of shortcut links. */ - public function lazyLinks() { + public function lazyLinks(bool $show_configure_link = TRUE) { $shortcut_set = shortcut_current_displayed_set(); $links = shortcut_renderable_links(); $configure_link = NULL; - if (shortcut_set_edit_access($shortcut_set)->isAllowed()) { + if ($show_configure_link && shortcut_set_edit_access($shortcut_set)->isAllowed()) { $configure_link = [ '#type' => 'link', '#title' => t('Edit shortcuts'), diff --git a/core/modules/shortcut/tests/src/Functional/ShortcutCacheTagsTest.php b/core/modules/shortcut/tests/src/Functional/ShortcutCacheTagsTest.php index 10e4923dfab4..1a4ff76de090 100644 --- a/core/modules/shortcut/tests/src/Functional/ShortcutCacheTagsTest.php +++ b/core/modules/shortcut/tests/src/Functional/ShortcutCacheTagsTest.php @@ -205,4 +205,124 @@ public function testToolbar() { $this->assertSession()->linkNotExists('Alpaca'); } + /** + * Tests visibility and cacheability of shortcuts in the block. + */ + public function testBlock(): void { + $this->drupalPlaceBlock('page_title_block', ['id' => 'title']); + $this->drupalPlaceBlock('shortcuts', [ + 'id' => 'shortcuts', + 'label' => 'Shortcuts Block', + ]); + + $test_page_url = Url::fromRoute('test_page_test.test_page'); + $this->verifyPageCache($test_page_url, 'MISS'); + $this->verifyPageCache($test_page_url, 'HIT'); + + // Ensure that without enabling the shortcuts-in-page-title-link feature + // in the theme, the shortcut_list cache tag is not added to the page. + $this->drupalLogin($this->rootUser); + $this->drupalGet('admin/config/system/cron'); + $expected_cache_tags = [ + 'CACHE_MISS_IF_UNCACHEABLE_HTTP_METHOD:form', + 'block_view', + 'config:block.block.shortcuts', + 'config:block.block.title', + 'config:block_list', + 'config:shortcut.set.default', + 'config:system.menu.admin', + 'config:system.theme', + 'rendered', + ]; + $this->assertCacheTags($expected_cache_tags); + + \Drupal::configFactory() + ->getEditable('stark.settings') + ->set('third_party_settings.shortcut.module_link', TRUE) + ->save(TRUE); + + // Add cron to the default shortcut set, now the shortcut list cache tag + // is expected. + $this->drupalGet('admin/config/system/cron'); + $this->clickLink('Add to Default shortcuts'); + $expected_cache_tags[] = 'config:shortcut_set_list'; + $this->assertCacheTags($expected_cache_tags); + + // Verify that users without the 'access shortcuts' permission can't see the + // shortcuts. + $this->drupalLogin($this->drupalCreateUser()); + $this->assertSession()->pageTextNotContains('Shortcuts Block'); + $this->verifyDynamicPageCache($test_page_url, 'MISS'); + $this->verifyDynamicPageCache($test_page_url, 'HIT'); + + // Verify that users without the 'administer site configuration' permission + // can't see the cron shortcut but can see the block. + $this->drupalLogin($this->drupalCreateUser([ + 'access shortcuts', + ])); + $this->verifyDynamicPageCache($test_page_url, 'MISS'); + $this->verifyDynamicPageCache($test_page_url, 'HIT'); + $this->assertSession()->pageTextContains('Shortcuts Block'); + $this->assertSession()->linkNotExists('Cron'); + + // Create a role with access to shortcuts as well as the necessary + // permissions to see specific shortcuts. + $site_configuration_role = $this->drupalCreateRole([ + 'access shortcuts', + 'administer site configuration', + 'access administration pages', + ]); + + // Create two different users with the same role to assert that the second + // user has a cache hit despite the user cache context, as + // the returned cache contexts include those from lazy-builder content. + $site_configuration_user1 = $this->drupalCreateUser(); + $site_configuration_user1->addRole($site_configuration_role); + $site_configuration_user1->save(); + $site_configuration_user2 = $this->drupalCreateUser(); + $site_configuration_user2->addRole($site_configuration_role); + $site_configuration_user2->save(); + + $this->drupalLogin($site_configuration_user1); + $this->verifyDynamicPageCache($test_page_url, 'MISS'); + $this->verifyDynamicPageCache($test_page_url, 'HIT'); + $this->assertCacheContexts(['user', 'url.query_args:_wrapper_format']); + $this->assertSession()->pageTextContains('Shortcuts Block'); + $this->assertSession()->linkExists('Cron'); + + $this->drupalLogin($site_configuration_user2); + $this->verifyDynamicPageCache($test_page_url, 'HIT'); + $this->assertCacheContexts(['user', 'url.query_args:_wrapper_format']); + $this->assertSession()->pageTextContains('Shortcuts Block'); + $this->assertSession()->linkExists('Cron'); + + // Add another shortcut. + $shortcut = Shortcut::create([ + 'shortcut_set' => 'default', + 'title' => 'Llama', + 'weight' => 0, + 'link' => [['uri' => 'internal:/admin/config']], + ]); + $shortcut->save(); + + // The shortcuts are displayed in a lazy builder, so the page is still a + // cache HIT but shows the new shortcut immediately. + $this->verifyDynamicPageCache($test_page_url, 'HIT'); + $this->assertSession()->linkExists('Cron'); + $this->assertSession()->linkExists('Llama'); + + // Update the shortcut title and assert that it is updated. + $shortcut->set('title', 'Alpaca'); + $shortcut->save(); + $this->verifyDynamicPageCache($test_page_url, 'HIT'); + $this->assertSession()->linkExists('Cron'); + $this->assertSession()->linkExists('Alpaca'); + + // Delete the shortcut and assert that the link is gone. + $shortcut->delete(); + $this->verifyDynamicPageCache($test_page_url, 'HIT'); + $this->assertSession()->linkExists('Cron'); + $this->assertSession()->linkNotExists('Alpaca'); + } + } -- GitLab