diff --git a/core/modules/menu_ui/src/Tests/MenuLanguageTest.php b/core/modules/menu_ui/tests/src/Functional/MenuLanguageTest.php similarity index 99% rename from core/modules/menu_ui/src/Tests/MenuLanguageTest.php rename to core/modules/menu_ui/tests/src/Functional/MenuLanguageTest.php index 4c48f05..efdf3a9 100644 --- a/core/modules/menu_ui/src/Tests/MenuLanguageTest.php +++ b/core/modules/menu_ui/tests/src/Functional/MenuLanguageTest.php @@ -1,6 +1,6 @@ drupalGet('admin/structure/types/manage/page'); - $this->assertCacheContext('user.roles:authenticated'); + $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Contexts', 'user.roles:authenticated'); // Verify that the menu link title has the correct maxlength. $max_length = \Drupal::entityManager()->getBaseFieldDefinitions('menu_link_content')['title']->getSetting('max_length'); diff --git a/core/modules/menu_ui/src/Tests/MenuTest.php b/core/modules/menu_ui/tests/src/Functional/MenuTest.php similarity index 93% rename from core/modules/menu_ui/src/Tests/MenuTest.php rename to core/modules/menu_ui/tests/src/Functional/MenuTest.php index dde9502..af9caa1 100644 --- a/core/modules/menu_ui/src/Tests/MenuTest.php +++ b/core/modules/menu_ui/tests/src/Functional/MenuTest.php @@ -1,10 +1,11 @@ drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLinkPartialName('Place block'); + $this->clickLink('Place block'); $this->assertText($label); // Enable the block. @@ -531,7 +532,7 @@ public function testSystemMenuRename() { // Make sure menu shows up with new name in block addition. $default_theme = $this->config('system.theme')->get('default'); $this->drupalget('admin/structure/block/list/' . $default_theme); - $this->clickLinkPartialName('Place block'); + $this->clickLink('Place block'); $this->assertText($edit['label']); } @@ -557,30 +558,7 @@ public function testUnpublishedNodeMenuItem() { $this->assertNoText($item->getTitle(), "Menu link pointing to unpublished node is only visible to users with 'bypass node access' permission"); // The cache contexts associated with the (in)accessible menu links are // bubbled. See DefaultMenuLinkTreeManipulators::menuLinkCheckAccess(). - $this->assertCacheContext('user.permissions'); - } - - /** - * Tests the contextual links on a menu block. - */ - public function testBlockContextualLinks() { - $this->drupalLogin($this->drupalCreateUser(['administer menu', 'access contextual links', 'administer blocks'])); - $custom_menu = $this->addCustomMenu(); - $this->addMenuLink('', '/', $custom_menu->id()); - $block = $this->drupalPlaceBlock('system_menu_block:' . $custom_menu->id(), ['label' => 'Custom menu', 'provider' => 'system']); - $this->drupalGet('test-page'); - - $id = 'block:block=' . $block->id() . ':langcode=en|menu:menu=' . $custom_menu->id() . ':langcode=en'; - // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder() - $this->assertRaw('
', format_string('Contextual link placeholder with id @id exists.', ['@id' => $id])); - - // Get server-rendered contextual links. - // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:renderContextualLinks() - $post = ['ids[0]' => $id]; - $response = $this->drupalPost('contextual/render', 'application/json', $post, ['query' => ['destination' => 'test-page']]); - $this->assertResponse(200); - $json = Json::decode($response); - $this->assertIdentical($json[$id], ''); + $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Contexts', 'user.permissions'); } /** @@ -860,24 +838,6 @@ public function enableMenuLink(MenuLinkContent $item) { } /** - * Tests if administrative users other than user 1 can access the menu parents - * AJAX callback. - */ - public function testMenuParentsJsAccess() { - $admin = $this->drupalCreateUser(['administer menu']); - $this->drupalLogin($admin); - // Just check access to the callback overall, the POST data is irrelevant. - $this->drupalGetAjax('admin/structure/menu/parents'); - $this->assertResponse(200); - - // Do standard user tests. - // Log in the user. - $this->drupalLogin($this->authenticatedUser); - $this->drupalGetAjax('admin/structure/menu/parents'); - $this->assertResponse(403); - } - - /** * Returns standard menu link. * * @return \Drupal\Core\Menu\MenuLinkInterface diff --git a/core/modules/menu_ui/src/Tests/MenuWebTestBase.php b/core/modules/menu_ui/tests/src/Functional/MenuWebTestBase.php similarity index 94% rename from core/modules/menu_ui/src/Tests/MenuWebTestBase.php rename to core/modules/menu_ui/tests/src/Functional/MenuWebTestBase.php index e0ee98f..b8dfb24 100644 --- a/core/modules/menu_ui/src/Tests/MenuWebTestBase.php +++ b/core/modules/menu_ui/tests/src/Functional/MenuWebTestBase.php @@ -1,13 +1,13 @@ drupalPlaceBlock('page_title_block'); + + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + } + + /** + * Creates a custom menu. + * + * @return \Drupal\system\Entity\Menu + * The custom menu that has been created. + */ + public function addCustomMenu() { + // Try adding a menu using a menu_name that is too long. + $this->drupalGet('admin/structure/menu/add'); + $menu_name = substr(hash('sha256', $this->randomMachineName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI + 1); + $label = $this->randomMachineName(16); + $edit = [ + 'id' => $menu_name, + 'description' => '', + 'label' => $label, + ]; + $this->drupalPostForm('admin/structure/menu/add', $edit, t('Save')); + + // Verify that using a menu_name that is too long results in a validation + // message. + $this->assertRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', [ + '@name' => t('Menu name'), + '%max' => MENU_MAX_MENU_NAME_LENGTH_UI, + '%length' => Unicode::strlen($menu_name), + ])); + + // Change the menu_name so it no longer exceeds the maximum length. + $menu_name = substr(hash('sha256', $this->randomMachineName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI); + $edit['id'] = $menu_name; + $this->drupalPostForm('admin/structure/menu/add', $edit, t('Save')); + + // Verify that no validation error is given for menu_name length. + $this->assertNoRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', [ + '@name' => t('Menu name'), + '%max' => MENU_MAX_MENU_NAME_LENGTH_UI, + '%length' => Unicode::strlen($menu_name), + ])); + // Verify that the confirmation message is displayed. + $this->assertRaw(t('Menu %label has been added.', ['%label' => $label])); + $this->drupalGet('admin/structure/menu'); + $this->assertText($label, 'Menu created'); + + // Confirm that the custom menu block is available. + $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); + $this->clickLink('Place block'); + $this->assertText($label); + + // Enable the block. + $block = $this->drupalPlaceBlock('system_menu_block:' . $menu_name); + $this->blockPlacements[$menu_name] = $block->id(); + return Menu::load($menu_name); + } + + /** + * Tests the contextual links on a menu block. + */ + public function testBlockContextualLinks() { + $this->drupalLogin($this->drupalCreateUser(['administer menu', 'access contextual links', 'administer blocks'])); + $custom_menu = $this->addCustomMenu(); + $this->addMenuLink('', '/', $custom_menu->id()); + $block = $this->drupalPlaceBlock('system_menu_block:' . $custom_menu->id(), ['label' => 'Custom menu', 'provider' => 'system']); + $this->drupalGet('test-page'); + + $id = 'block:block=' . $block->id() . ':langcode=en|menu:menu=' . $custom_menu->id() . ':langcode=en'; + // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder() + $this->assertRaw('
', format_string('Contextual link placeholder with id @id exists.', ['@id' => $id])); + + // Get server-rendered contextual links. + // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:renderContextualLinks() + $post = ['ids[0]' => $id]; + $client = \Drupal::httpClient(); + $url = $this->buildUrl('contextual/render', ['query' => ['destination' => 'test-page']]); + $response = $client->post($url, [ + 'form_params' => $post, + 'headers' => [ + 'Accept' => 'application/json', + ], + ]); + $this->assertEquals(200, $response->getStatusCode()); + $json = Json::decode((string) $response); + $this->assertIdentical($json[$id], ''); + } + + /** + * Adds a menu link using the UI. + * + * @param string $parent + * Optional parent menu link id. + * @param string $path + * The path to enter on the form. Defaults to the front page. + * @param string $menu_name + * Menu name. Defaults to 'tools'. + * @param bool $expanded + * Whether or not this menu link is expanded. Setting this to TRUE should + * test whether it works when we do the authenticatedUser tests. Defaults + * to FALSE. + * @param string $weight + * Menu weight. Defaults to 0. + * + * @return \Drupal\menu_link_content\Entity\MenuLinkContent + * A menu link entity. + */ + public function addMenuLink($parent = '', $path = '/', $menu_name = 'tools', $expanded = FALSE, $weight = '0') { + // View add menu link page. + $this->drupalGet("admin/structure/menu/manage/$menu_name/add"); + $this->assertResponse(200); + + $title = '!link_' . $this->randomMachineName(16); + $edit = [ + 'link[0][uri]' => $path, + 'title[0][value]' => $title, + 'description[0][value]' => '', + 'enabled[value]' => 1, + 'expanded[value]' => $expanded, + 'menu_parent' => $menu_name . ':' . $parent, + 'weight[0][value]' => $weight, + ]; + + // Add menu link. + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertResponse(200); + $this->assertText('The menu link has been saved.'); + + $menu_links = entity_load_multiple_by_properties('menu_link_content', ['title' => $title]); + + $menu_link = reset($menu_links); + $this->assertTrue($menu_link, 'Menu link was found in database.'); + $this->assertMenuLink($menu_link->getPluginId(), ['menu_name' => $menu_name, 'children' => [], 'parent' => $parent]); + + return $menu_link; + } + + /** + * Tests if administrative users other than user 1 can access the menu parents + * AJAX callback. + */ + public function testMenuParentsJsAccess() { + $admin = $this->drupalCreateUser(['administer menu']); + $this->drupalLogin($admin); + // Just check access to the callback overall, the POST data is irrelevant. + $this->drupalGet('admin/structure/menu/parents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']], ['X-Requested-With: XMLHttpRequest']); + $this->assertResponse(200); + + // Do standard user tests. + // Log in the user. + $this->drupalLogin($this->authenticatedUser); + $this->drupalGet('admin/structure/menu/parents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']], ['X-Requested-With: XMLHttpRequest']); + $this->assertResponse(403); + } + +} diff --git a/core/modules/menu_ui/tests/src/FunctionalJavascript/MenuWebTestBase.php b/core/modules/menu_ui/tests/src/FunctionalJavascript/MenuWebTestBase.php new file mode 100644 index 0000000..cd84d44 --- /dev/null +++ b/core/modules/menu_ui/tests/src/FunctionalJavascript/MenuWebTestBase.php @@ -0,0 +1,77 @@ +resetDefinitions(); + // Reset the static load cache. + \Drupal::entityManager()->getStorage('menu_link_content')->resetCache(); + $definition = $menu_link_manager->getDefinition($menu_plugin_id); + + $entity = NULL; + + // Pull the path from the menu link content. + if (strpos($menu_plugin_id, 'menu_link_content') === 0) { + list(, $uuid) = explode(':', $menu_plugin_id, 2); + /** @var \Drupal\menu_link_content\Entity\MenuLinkContent $entity */ + $entity = \Drupal::entityManager()->loadEntityByUuid('menu_link_content', $uuid); + } + + if (isset($expected_item['children'])) { + $child_ids = array_values($menu_link_manager->getChildIds($menu_plugin_id)); + sort($expected_item['children']); + if ($child_ids) { + sort($child_ids); + } + $this->assertEqual($expected_item['children'], $child_ids); + unset($expected_item['children']); + } + + if (isset($expected_item['parents'])) { + $parent_ids = array_values($menu_link_manager->getParentIds($menu_plugin_id)); + $this->assertEqual($expected_item['parents'], $parent_ids); + unset($expected_item['parents']); + } + + if (isset($expected_item['langcode']) && $entity) { + $this->assertEqual($entity->langcode->value, $expected_item['langcode']); + unset($expected_item['langcode']); + } + + if (isset($expected_item['enabled']) && $entity) { + $this->assertEqual($entity->enabled->value, $expected_item['enabled']); + unset($expected_item['enabled']); + } + + foreach ($expected_item as $key => $value) { + $this->assertTrue(isset($definition[$key])); + $this->assertEqual($definition[$key], $value); + } + } + +}