You are here

public function MenuUiTest::doMenuTests in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/menu_ui/tests/src/Functional/MenuUiTest.php \Drupal\Tests\menu_ui\Functional\MenuUiTest::doMenuTests()
  2. 9 core/modules/menu_ui/tests/src/Functional/MenuUiTest.php \Drupal\Tests\menu_ui\Functional\MenuUiTest::doMenuTests()

Tests menu functionality.

File

core/modules/menu_ui/tests/src/Functional/MenuUiTest.php, line 296

Class

MenuUiTest
Add a custom menu, add menu links to the custom menu and Tools menu, check their data, and delete them using the UI.

Namespace

Drupal\Tests\menu_ui\Functional

Code

public function doMenuTests() {

  // Add a link to the tools menu first, to test cacheability metadata of the
  // destination query string.
  $this
    ->drupalGet('admin/structure/menu/manage/tools');
  $this
    ->clickLink('Add link');
  $link_title = $this
    ->randomString();
  $this
    ->submitForm([
    'link[0][uri]' => '/',
    'title[0][value]' => $link_title,
  ], 'Save');
  $this
    ->assertSession()
    ->linkExists($link_title);
  $this
    ->assertSession()
    ->addressEquals('admin/structure/menu/manage/tools');

  // Test adding a menu link direct from the menus listing page.
  $this
    ->drupalGet('admin/structure/menu');

  // Click the "Add link" operation in the Tools row.
  $links = $this
    ->xpath('//*/td[contains(text(),:menu_label)]/following::a[normalize-space()=:link_label]', [
    ':menu_label' => 'Tools',
    ':link_label' => 'Add link',
  ]);
  $links[0]
    ->click();
  $this
    ->assertMatchesRegularExpression('#admin/structure/menu/manage/tools/add\\?destination=(/[^/]*)*/admin/structure/menu/manage/tools$#', $this
    ->getSession()
    ->getCurrentUrl());
  $link_title = $this
    ->randomString();
  $this
    ->submitForm([
    'link[0][uri]' => '/',
    'title[0][value]' => $link_title,
  ], 'Save');
  $this
    ->assertSession()
    ->linkExists($link_title);
  $this
    ->assertSession()
    ->addressEquals('admin/structure/menu/manage/tools');
  $menu_name = $this->menu
    ->id();

  // Access the menu via the overview form to ensure it does not add a
  // destination that breaks the user interface.
  $this
    ->drupalGet('admin/structure/menu');

  // Select the edit menu link for our menu.
  $links = $this
    ->xpath('//*/td[contains(text(),:menu_label)]/following::a[normalize-space()=:link_label]', [
    ':menu_label' => (string) $this->menu
      ->label(),
    ':link_label' => 'Edit menu',
  ]);
  $links[0]
    ->click();

  // Test the 'Add link' local action.
  $this
    ->clickLink('Add link');
  $link_title = $this
    ->randomString();
  $this
    ->submitForm([
    'link[0][uri]' => '/',
    'title[0][value]' => $link_title,
  ], 'Save');
  $this
    ->assertSession()
    ->addressEquals(Url::fromRoute('entity.menu.edit_form', [
    'menu' => $menu_name,
  ]));

  // Test the 'Edit' operation.
  $this
    ->clickLink('Edit');
  $this
    ->assertSession()
    ->fieldValueEquals('title[0][value]', $link_title);
  $link_title = $this
    ->randomString();
  $this
    ->submitForm([
    'title[0][value]' => $link_title,
  ], 'Save');
  $this
    ->assertSession()
    ->addressEquals(Url::fromRoute('entity.menu.edit_form', [
    'menu' => $menu_name,
  ]));

  // Test the 'Delete' operation.
  $this
    ->clickLink('Delete');
  $this
    ->assertSession()
    ->pageTextContains("Are you sure you want to delete the custom menu link {$link_title}?");
  $this
    ->submitForm([], 'Delete');
  $this
    ->assertSession()
    ->addressEquals(Url::fromRoute('entity.menu.edit_form', [
    'menu' => $menu_name,
  ]));

  // Clear the cache to ensure that recent caches aren't preventing us from
  // seeing a broken add link.
  $this
    ->resetAll();
  $this
    ->drupalGet('admin/structure/menu');

  // Select the edit menu link for our menu.
  $links = $this
    ->xpath('//*/td[contains(text(),:menu_label)]/following::a[normalize-space()=:link_label]', [
    ':menu_label' => (string) $this->menu
      ->label(),
    ':link_label' => 'Edit menu',
  ]);
  $links[0]
    ->click();

  // Test the 'Add link' local action.
  $this
    ->clickLink('Add link');
  $link_title = $this
    ->randomString();
  $this
    ->submitForm([
    'link[0][uri]' => '/',
    'title[0][value]' => $link_title,
  ], 'Save');
  $this
    ->assertSession()
    ->linkExists($link_title);
  $this
    ->assertSession()
    ->addressEquals(Url::fromRoute('entity.menu.edit_form', [
    'menu' => $menu_name,
  ]));

  // Add nodes to use as links for menu links.
  $node1 = $this
    ->drupalCreateNode([
    'type' => 'article',
  ]);
  $node2 = $this
    ->drupalCreateNode([
    'type' => 'article',
  ]);
  $node3 = $this
    ->drupalCreateNode([
    'type' => 'article',
  ]);
  $node4 = $this
    ->drupalCreateNode([
    'type' => 'article',
  ]);

  // Create a node with an alias.
  $node5 = $this
    ->drupalCreateNode([
    'type' => 'article',
    'path' => [
      'alias' => '/node5',
    ],
  ]);

  // Verify add link button.
  $this
    ->drupalGet('admin/structure/menu');
  $this
    ->assertSession()
    ->linkByHrefExists('admin/structure/menu/manage/' . $menu_name . '/add', 0, "The add menu link button URL is correct");

  // Verify form defaults.
  $this
    ->doMenuLinkFormDefaultsTest();

  // Add menu links.
  $item1 = $this
    ->addMenuLink('', '/node/' . $node1
    ->id(), $menu_name, TRUE);
  $item2 = $this
    ->addMenuLink($item1
    ->getPluginId(), '/node/' . $node2
    ->id(), $menu_name, FALSE);
  $item3 = $this
    ->addMenuLink($item2
    ->getPluginId(), '/node/' . $node3
    ->id(), $menu_name);

  // Hierarchy
  // <$menu_name>
  // - item1
  // -- item2
  // --- item3
  $this
    ->assertMenuLink([
    'children' => [
      $item2
        ->getPluginId(),
      $item3
        ->getPluginId(),
    ],
    'parents' => [
      $item1
        ->getPluginId(),
    ],
    // We assert the language code here to make sure that the language
    // selection element degrades gracefully without the Language module.
    'langcode' => 'en',
  ], $item1
    ->getPluginId());
  $this
    ->assertMenuLink([
    'children' => [
      $item3
        ->getPluginId(),
    ],
    'parents' => [
      $item2
        ->getPluginId(),
      $item1
        ->getPluginId(),
    ],
    // See above.
    'langcode' => 'en',
  ], $item2
    ->getPluginId());
  $this
    ->assertMenuLink([
    'children' => [],
    'parents' => [
      $item3
        ->getPluginId(),
      $item2
        ->getPluginId(),
      $item1
        ->getPluginId(),
    ],
    // See above.
    'langcode' => 'en',
  ], $item3
    ->getPluginId());

  // Verify menu links.
  $this
    ->verifyMenuLink($item1, $node1);
  $this
    ->verifyMenuLink($item2, $node2, $item1, $node1);
  $this
    ->verifyMenuLink($item3, $node3, $item2, $node2);

  // Add more menu links.
  $item4 = $this
    ->addMenuLink('', '/node/' . $node4
    ->id(), $menu_name);
  $item5 = $this
    ->addMenuLink($item4
    ->getPluginId(), '/node/' . $node5
    ->id(), $menu_name);

  // Create a menu link pointing to an alias.
  $item6 = $this
    ->addMenuLink($item4
    ->getPluginId(), '/node5', $menu_name, TRUE, '0');

  // Hierarchy
  // <$menu_name>
  // - item1
  // -- item2
  // --- item3
  // - item4
  // -- item5
  // -- item6
  $this
    ->assertMenuLink([
    'children' => [
      $item5
        ->getPluginId(),
      $item6
        ->getPluginId(),
    ],
    'parents' => [
      $item4
        ->getPluginId(),
    ],
    // See above.
    'langcode' => 'en',
  ], $item4
    ->getPluginId());
  $this
    ->assertMenuLink([
    'children' => [],
    'parents' => [
      $item5
        ->getPluginId(),
      $item4
        ->getPluginId(),
    ],
    'langcode' => 'en',
  ], $item5
    ->getPluginId());
  $this
    ->assertMenuLink([
    'children' => [],
    'parents' => [
      $item6
        ->getPluginId(),
      $item4
        ->getPluginId(),
    ],
    'route_name' => 'entity.node.canonical',
    'route_parameters' => [
      'node' => $node5
        ->id(),
    ],
    'url' => '',
    // See above.
    'langcode' => 'en',
  ], $item6
    ->getPluginId());

  // Modify menu links.
  $this
    ->modifyMenuLink($item1);
  $this
    ->modifyMenuLink($item2);

  // Toggle menu links.
  $this
    ->toggleMenuLink($item1);
  $this
    ->toggleMenuLink($item2);

  // Move link and verify that descendants are updated.
  $this
    ->moveMenuLink($item2, $item5
    ->getPluginId(), $menu_name);

  // Hierarchy
  // <$menu_name>
  // - item1
  // - item4
  // -- item5
  // --- item2
  // ---- item3
  // -- item6
  $this
    ->assertMenuLink([
    'children' => [],
    'parents' => [
      $item1
        ->getPluginId(),
    ],
    // See above.
    'langcode' => 'en',
  ], $item1
    ->getPluginId());
  $this
    ->assertMenuLink([
    'children' => [
      $item5
        ->getPluginId(),
      $item6
        ->getPluginId(),
      $item2
        ->getPluginId(),
      $item3
        ->getPluginId(),
    ],
    'parents' => [
      $item4
        ->getPluginId(),
    ],
    // See above.
    'langcode' => 'en',
  ], $item4
    ->getPluginId());
  $this
    ->assertMenuLink([
    'children' => [
      $item2
        ->getPluginId(),
      $item3
        ->getPluginId(),
    ],
    'parents' => [
      $item5
        ->getPluginId(),
      $item4
        ->getPluginId(),
    ],
    // See above.
    'langcode' => 'en',
  ], $item5
    ->getPluginId());
  $this
    ->assertMenuLink([
    'children' => [
      $item3
        ->getPluginId(),
    ],
    'parents' => [
      $item2
        ->getPluginId(),
      $item5
        ->getPluginId(),
      $item4
        ->getPluginId(),
    ],
    // See above.
    'langcode' => 'en',
  ], $item2
    ->getPluginId());
  $this
    ->assertMenuLink([
    'children' => [],
    'parents' => [
      $item3
        ->getPluginId(),
      $item2
        ->getPluginId(),
      $item5
        ->getPluginId(),
      $item4
        ->getPluginId(),
    ],
    // See above.
    'langcode' => 'en',
  ], $item3
    ->getPluginId());

  // Add 102 menu links with increasing weights, then make sure the last-added
  // item's weight doesn't get changed because of the old hardcoded delta=50.
  $items = [];
  for ($i = -50; $i <= 51; $i++) {
    $items[$i] = $this
      ->addMenuLink('', '/node/' . $node1
      ->id(), $menu_name, TRUE, strval($i));
  }
  $this
    ->assertMenuLink([
    'weight' => '51',
  ], $items[51]
    ->getPluginId());

  // Disable a link and then re-enable the link via the overview form.
  $this
    ->disableMenuLink($item1);
  $edit = [];
  $edit['links[menu_plugin_id:' . $item1
    ->getPluginId() . '][enabled]'] = TRUE;
  $this
    ->drupalGet('admin/structure/menu/manage/' . $item1
    ->getMenuName());
  $this
    ->submitForm($edit, 'Save');

  // Mark item2, item4 and item5 as expanded.
  // This is done in order to show them on the frontpage.
  $item2->expanded->value = 1;
  $item2
    ->save();
  $item4->expanded->value = 1;
  $item4
    ->save();
  $item5->expanded->value = 1;
  $item5
    ->save();

  // Verify in the database.
  $this
    ->assertMenuLink([
    'enabled' => 1,
  ], $item1
    ->getPluginId());

  // Add an external link.
  $item7 = $this
    ->addMenuLink('', 'https://www.drupal.org', $menu_name);
  $this
    ->assertMenuLink([
    'url' => 'https://www.drupal.org',
  ], $item7
    ->getPluginId());

  // Add <front> menu item.
  $item8 = $this
    ->addMenuLink('', '/', $menu_name);
  $this
    ->assertMenuLink([
    'route_name' => '<front>',
  ], $item8
    ->getPluginId());
  $this
    ->drupalGet('');
  $this
    ->assertSession()
    ->statusCodeEquals(200);

  // Make sure we get routed correctly.
  $this
    ->clickLink($item8
    ->getTitle());
  $this
    ->assertSession()
    ->statusCodeEquals(200);

  // Check invalid menu link parents.
  $this
    ->checkInvalidParentMenuLinks();

  // Save menu links for later tests.
  $this->items[] = $item1;
  $this->items[] = $item2;
}