From 932ef94e2ccb36c80fccfec39264d4029fa6ee92 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Sat, 18 May 2024 11:38:33 +0100
Subject: [PATCH] Issue #3445184 by plopesc, matthieuscarset, m4olivei: Fatal
 error when accessing Navigation Blocks on a minimal profile installation
 because of the Shortcut block

(cherry picked from commit e96135b23f9973413504db1573aa56523dc0c0f9)
---
 .../Plugin/Block/NavigationShortcutsBlock.php | 11 ++-
 ...t.php => NavigationShortcutsBlockTest.php} | 88 +++++++++++--------
 2 files changed, 56 insertions(+), 43 deletions(-)
 rename core/modules/navigation/tests/src/Functional/{ShortcutsNavigationBlockTest.php => NavigationShortcutsBlockTest.php} (71%)

diff --git a/core/modules/navigation/src/Plugin/Block/NavigationShortcutsBlock.php b/core/modules/navigation/src/Plugin/Block/NavigationShortcutsBlock.php
index e925d24ec545..07e3ba3baa21 100644
--- a/core/modules/navigation/src/Plugin/Block/NavigationShortcutsBlock.php
+++ b/core/modules/navigation/src/Plugin/Block/NavigationShortcutsBlock.php
@@ -59,12 +59,6 @@ public static function create(ContainerInterface $container, array $configuratio
    * {@inheritdoc}
    */
   protected function blockAccess(AccountInterface $account): AccessResultInterface {
-    // This navigation block requires shortcut module. Once the plugin is moved
-    // to the module, this should not be necessary.
-    if (!$this->moduleHandler->moduleExists('shortcut')) {
-      return AccessResult::forbidden();
-    }
-
     return AccessResult::allowedIfHasPermission($account, 'access shortcuts');
   }
 
@@ -72,6 +66,11 @@ protected function blockAccess(AccountInterface $account): AccessResultInterface
    * {@inheritdoc}
    */
   public function build(): array {
+    // This navigation block requires shortcut module. Once the plugin is moved
+    // to the module, this should not be necessary.
+    if (!$this->moduleHandler->moduleExists('shortcut')) {
+      return [];
+    }
     return [
       'shortcuts' => [
         // @phpstan-ignore-next-line
diff --git a/core/modules/navigation/tests/src/Functional/ShortcutsNavigationBlockTest.php b/core/modules/navigation/tests/src/Functional/NavigationShortcutsBlockTest.php
similarity index 71%
rename from core/modules/navigation/tests/src/Functional/ShortcutsNavigationBlockTest.php
rename to core/modules/navigation/tests/src/Functional/NavigationShortcutsBlockTest.php
index 6ec194ffa786..181483c70f9f 100644
--- a/core/modules/navigation/tests/src/Functional/ShortcutsNavigationBlockTest.php
+++ b/core/modules/navigation/tests/src/Functional/NavigationShortcutsBlockTest.php
@@ -11,11 +11,11 @@
 use Drupal\Tests\system\Functional\Cache\PageCacheTagsTestBase;
 
 /**
- * Tests for \Drupal\navigation\Plugin\Block\ShortcutsNavigationBlock.
+ * Tests for \Drupal\navigation\Plugin\Block\NavigationShortcutsBlock.
  *
  * @group navigation
  */
-class ShortcutsNavigationBlockTest extends PageCacheTagsTestBase {
+class NavigationShortcutsBlockTest extends PageCacheTagsTestBase {
 
   use AssertPageCacheContextsAndTagsTrait;
 
@@ -80,7 +80,7 @@ public function testNavigationBlock() {
     // Verify that users without the 'access shortcuts' permission can't see the
     // shortcuts.
     $this->drupalLogin($this->drupalCreateUser(['access navigation']));
-    $this->assertSession()->linkNotExists('Shortcuts');
+    $this->assertSession()->pageTextNotContains('Shortcuts');
     $this->verifyDynamicPageCache($test_page_url, 'MISS');
     $this->verifyDynamicPageCache($test_page_url, 'HIT');
 
@@ -103,6 +103,7 @@ public function testNavigationBlock() {
       'access shortcuts',
       'administer site configuration',
       'access administration pages',
+      'configure any layout',
     ]);
 
     // Create two different users with the same role to assert that the second
@@ -169,44 +170,57 @@ public function testNavigationBlock() {
     ]);
     $new_shortcut->save();
 
-    // @todo Uncomment once tests are executed against 10.3.x.
     // Assign the new shortcut set to user 2 and confirm that links are changed
     // automatically.
-    // \Drupal::entityTypeManager()
-    // ->getStorage('shortcut_set')
-    // ->assignUser($new_set, $site_configuration_user2);
-    // //    $this->verifyDynamicPageCache($test_page_url, 'HIT');
-    // $this->assertSession()->linkExists('Cron');
-    // $this->assertSession()->linkExists('New Llama');
-    // //    // Confirm that links for user 1 have not been affected.
-    // $this->drupalLogin($site_configuration_user1);
-    // $this->verifyDynamicPageCache($test_page_url, 'HIT');
-    // $this->assertSession()->linkExists('Cron');
-    // $this->assertSession()->linkNotExists('New Llama');
+    \Drupal::entityTypeManager()
+      ->getStorage('shortcut_set')
+      ->assignUser($new_set, $site_configuration_user2);
+    $this->verifyDynamicPageCache($test_page_url, 'HIT');
+    $this->assertSession()->linkExists('Cron');
+    $this->assertSession()->linkExists('New Llama');
+    // Confirm that links for user 1 have not been affected.
+    $this->drupalLogin($site_configuration_user1);
+    $this->verifyDynamicPageCache($test_page_url, 'HIT');
+    $this->assertSession()->linkExists('Cron');
+    $this->assertSession()->linkNotExists('New Llama');
     // Confirm that removing assignment automatically changes the links too.
-    // $this->drupalLogin($site_configuration_user2);
-    // $this->verifyDynamicPageCache($test_page_url, 'HIT');
-    // $this->assertSession()->linkExists('Cron');
-    // $this->assertSession()->linkExists('New Llama');
-    // \Drupal::entityTypeManager()
-    // ->getStorage('shortcut_set')
-    // ->unassignUser($site_configuration_user2);
-    // $this->verifyDynamicPageCache($test_page_url, 'HIT');
-    // $this->assertSession()->linkExists('Cron');
-    // $this->assertSession()->linkNotExists('New Llama');
+    $this->drupalLogin($site_configuration_user2);
+    $this->verifyDynamicPageCache($test_page_url, 'HIT');
+    $this->assertSession()->linkExists('Cron');
+    $this->assertSession()->linkExists('New Llama');
+    \Drupal::entityTypeManager()
+      ->getStorage('shortcut_set')
+      ->unassignUser($site_configuration_user2);
+    $this->verifyDynamicPageCache($test_page_url, 'HIT');
+    $this->assertSession()->linkExists('Cron');
+    $this->assertSession()->linkNotExists('New Llama');
     // Confirm that deleting a shortcut set automatically changes the links too.
-    // \Drupal::entityTypeManager()
-    // ->getStorage('shortcut_set')
-    // ->assignUser($new_set, $site_configuration_user2);
-    // $this->verifyDynamicPageCache($test_page_url, 'HIT');
-    // $this->assertSession()->linkExists('Cron');
-    // $this->assertSession()->linkExists('New Llama');
-    // \Drupal::entityTypeManager()
-    // ->getStorage('shortcut_set')
-    // ->delete([$new_set]);
-    // $this->verifyDynamicPageCache($test_page_url, 'HIT');
-    // $this->assertSession()->linkExists('Cron');
-    // $this->assertSession()->linkNotExists('New Llama');
+    \Drupal::entityTypeManager()
+      ->getStorage('shortcut_set')
+      ->assignUser($new_set, $site_configuration_user2);
+    $this->verifyDynamicPageCache($test_page_url, 'HIT');
+    $this->assertSession()->linkExists('Cron');
+    $this->assertSession()->linkExists('New Llama');
+    \Drupal::entityTypeManager()
+      ->getStorage('shortcut_set')
+      ->delete([$new_set]);
+    $this->verifyDynamicPageCache($test_page_url, 'HIT');
+    $this->assertSession()->linkExists('Cron');
+    $this->assertSession()->linkNotExists('New Llama');
+
+    // Verify that block disappears gracefully when shortcut module is disabled.
+    // Shortcut entities has to be removed first.
+    $link_storage = \Drupal::entityTypeManager()->getStorage('shortcut');
+    $link_storage->delete($link_storage->loadMultiple());
+    \Drupal::service('module_installer')->uninstall(['shortcut']);
+    $this->verifyDynamicPageCache($test_page_url, 'MISS');
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertSession()->pageTextNotContains('Shortcuts');
+
+    // Confirm that Navigation Blocks page is working.
+    // @see https://www.drupal.org/project/drupal/issues/3445184
+    $this->drupalGet('/admin/config/user-interface/navigation-block');
+    $this->assertSession()->statusCodeEquals(200);
   }
 
 }
-- 
GitLab