Chris@0: drupalPlaceBlock('system_menu_block:main'); Chris@0: $this->drupalPlaceBlock('page_title_block'); Chris@0: Chris@0: $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); Chris@0: Chris@0: $this->editor = $this->drupalCreateUser([ Chris@0: 'access administration pages', Chris@0: 'administer content types', Chris@0: 'administer menu', Chris@0: 'create page content', Chris@0: 'edit any page content', Chris@0: 'delete any page content', Chris@0: 'create content translations', Chris@0: 'update content translations', Chris@0: 'delete content translations', Chris@0: 'translate any entity', Chris@0: ]); Chris@0: $this->drupalLogin($this->editor); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Test creating, editing, deleting menu links via node form widget. Chris@0: */ Chris@0: public function testMenuNodeFormWidget() { Chris@0: // Verify that cacheability metadata is bubbled from the menu link tree Chris@0: // access checking that is performed when determining the "default parent Chris@0: // item" options in menu_ui_form_node_type_form_alter(). The "log out" link Chris@0: // adds the "user.roles:authenticated" cache context. Chris@0: $this->drupalGet('admin/structure/types/manage/page'); Chris@0: $this->assertCacheContext('user.roles:authenticated'); Chris@0: Chris@0: // Verify that the menu link title has the correct maxlength. Chris@0: $max_length = \Drupal::entityManager()->getBaseFieldDefinitions('menu_link_content')['title']->getSetting('max_length'); Chris@0: $this->drupalGet('node/add/page'); Chris@0: $this->assertPattern('//', 'Menu link title field has correct maxlength in node add form.'); Chris@0: Chris@0: // Disable the default main menu, so that no menus are enabled. Chris@0: $edit = [ Chris@0: 'menu_options[main]' => FALSE, Chris@0: ]; Chris@0: $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); Chris@0: Chris@0: // Verify that no menu settings are displayed and nodes can be created. Chris@0: $this->drupalGet('node/add/page'); Chris@0: $this->assertText(t('Create Basic page')); Chris@0: $this->assertNoText(t('Menu settings')); Chris@0: $node_title = $this->randomMachineName(); Chris@0: $edit = [ Chris@0: 'title[0][value]' => $node_title, Chris@0: 'body[0][value]' => $this->randomString(), Chris@0: ]; Chris@0: $this->drupalPostForm(NULL, $edit, t('Save')); Chris@0: $node = $this->drupalGetNodeByTitle($node_title); Chris@0: $this->assertEqual($node->getTitle(), $edit['title[0][value]']); Chris@0: Chris@0: // Test that we cannot set a menu item from a menu that is not set as Chris@0: // available. Chris@0: $edit = [ Chris@0: 'menu_options[tools]' => 1, Chris@0: 'menu_parent' => 'main:', Chris@0: ]; Chris@0: $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); Chris@0: $this->assertText(t('The selected menu item is not under one of the selected menus.')); Chris@0: $this->assertNoRaw(t('The content type %name has been updated.', ['%name' => 'Basic page'])); Chris@0: Chris@0: // Enable Tools menu as available menu. Chris@0: $edit = [ Chris@0: 'menu_options[main]' => 1, Chris@0: 'menu_options[tools]' => 1, Chris@0: 'menu_parent' => 'main:', Chris@0: ]; Chris@0: $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); Chris@0: $this->assertRaw(t('The content type %name has been updated.', ['%name' => 'Basic page'])); Chris@0: Chris@0: // Test that we can preview a node that will create a menu item. Chris@0: $edit = [ Chris@0: 'title[0][value]' => $node_title, Chris@0: 'menu[enabled]' => 1, Chris@0: 'menu[title]' => 'Test preview', Chris@0: ]; Chris@0: $this->drupalPostForm('node/add/page', $edit, t('Preview')); Chris@0: Chris@0: // Create a node. Chris@0: $node_title = $this->randomMachineName(); Chris@0: $edit = [ Chris@0: 'title[0][value]' => $node_title, Chris@0: 'body[0][value]' => $this->randomString(), Chris@0: ]; Chris@0: $this->drupalPostForm('node/add/page', $edit, t('Save')); Chris@0: $node = $this->drupalGetNodeByTitle($node_title); Chris@0: // Assert that there is no link for the node. Chris@0: $this->drupalGet('test-page'); Chris@0: $this->assertNoLink($node_title); Chris@0: Chris@0: // Edit the node, enable the menu link setting, but skip the link title. Chris@0: $edit = [ Chris@0: 'menu[enabled]' => 1, Chris@0: ]; Chris@0: $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); Chris@0: // Assert that there is no link for the node. Chris@0: $this->drupalGet('test-page'); Chris@0: $this->assertNoLink($node_title); Chris@0: Chris@0: // Make sure the menu links only appear when the node is published. Chris@0: // These buttons just appear for 'administer nodes' users. Chris@0: $admin_user = $this->drupalCreateUser([ Chris@0: 'access administration pages', Chris@0: 'administer content types', Chris@0: 'administer nodes', Chris@0: 'administer menu', Chris@0: 'create page content', Chris@0: 'edit any page content', Chris@0: ]); Chris@0: $this->drupalLogin($admin_user); Chris@0: // Assert that the link does not exist if unpublished. Chris@0: $edit = [ Chris@0: 'menu[enabled]' => 1, Chris@0: 'menu[title]' => $node_title, Chris@0: 'status[value]' => FALSE, Chris@0: ]; Chris@0: $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save'); Chris@0: $this->drupalGet('test-page'); Chris@0: $this->assertNoLink($node_title, 'Found no menu link with the node unpublished'); Chris@0: // Assert that the link exists if published. Chris@0: $edit['status[value]'] = TRUE; Chris@0: $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save'); Chris@0: $this->drupalGet('test-page'); Chris@0: $this->assertLink($node_title, 0, 'Found a menu link with the node published'); Chris@0: Chris@0: // Log back in as normal user. Chris@0: $this->drupalLogin($this->editor); Chris@0: // Edit the node and create a menu link. Chris@0: $edit = [ Chris@0: 'menu[enabled]' => 1, Chris@0: 'menu[title]' => $node_title, Chris@0: 'menu[weight]' => 17, Chris@0: ]; Chris@0: $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); Chris@0: // Assert that the link exists. Chris@0: $this->drupalGet('test-page'); Chris@0: $this->assertLink($node_title); Chris@0: Chris@0: $this->drupalGet('node/' . $node->id() . '/edit'); Chris@0: $this->assertFieldById('edit-menu-weight', 17, 'Menu weight correct in edit form'); Chris@0: $this->assertPattern('//', 'Menu link title field has correct maxlength in node edit form.'); Chris@0: Chris@0: // Disable the menu link, then edit the node--the link should stay disabled. Chris@0: $link_id = menu_ui_get_menu_link_defaults($node)['entity_id']; Chris@0: /** @var \Drupal\menu_link_content\Entity\MenuLinkContent $link */ Chris@0: $link = MenuLinkContent::load($link_id); Chris@0: $link->set('enabled', FALSE); Chris@0: $link->save(); Chris@0: $this->drupalPostForm($node->urlInfo('edit-form'), $edit, t('Save')); Chris@0: $link = MenuLinkContent::load($link_id); Chris@0: $this->assertFalse($link->isEnabled(), 'Saving a node with a disabled menu link keeps the menu link disabled.'); Chris@0: Chris@0: // Edit the node and remove the menu link. Chris@0: $edit = [ Chris@0: 'menu[enabled]' => FALSE, Chris@0: ]; Chris@0: $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); Chris@0: // Assert that there is no link for the node. Chris@0: $this->drupalGet('test-page'); Chris@0: $this->assertNoLink($node_title); Chris@0: Chris@0: // Add a menu link to the Administration menu. Chris@0: $item = MenuLinkContent::create([ Chris@0: 'link' => [['uri' => 'entity:node/' . $node->id()]], Chris@0: 'title' => $this->randomMachineName(16), Chris@0: 'menu_name' => 'admin', Chris@0: ]); Chris@0: $item->save(); Chris@0: Chris@0: // Assert that disabled Administration menu is not shown on the Chris@0: // node/$nid/edit page. Chris@0: $this->drupalGet('node/' . $node->id() . '/edit'); Chris@0: $this->assertText('Provide a menu link', 'Link in not allowed menu not shown in node edit form'); Chris@0: // Assert that the link is still in the Administration menu after save. Chris@0: $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); Chris@0: $link = MenuLinkContent::load($item->id()); Chris@0: $this->assertTrue($link, 'Link in not allowed menu still exists after saving node'); Chris@0: Chris@0: // Move the menu link back to the Tools menu. Chris@0: $item->menu_name->value = 'tools'; Chris@0: $item->save(); Chris@0: // Create a second node. Chris@0: $child_node = $this->drupalCreateNode(['type' => 'article']); Chris@0: // Assign a menu link to the second node, being a child of the first one. Chris@0: $child_item = MenuLinkContent::create([ Chris@0: 'link' => [['uri' => 'entity:node/' . $child_node->id()]], Chris@0: 'title' => $this->randomMachineName(16), Chris@0: 'parent' => $item->getPluginId(), Chris@0: 'menu_name' => $item->getMenuName(), Chris@0: ]); Chris@0: $child_item->save(); Chris@0: // Edit the first node. Chris@0: $this->drupalGet('node/' . $node->id() . '/edit'); Chris@0: // Assert that it is not possible to set the parent of the first node to itself or the second node. Chris@0: $this->assertNoOption('edit-menu-menu-parent', 'tools:' . $item->getPluginId()); Chris@0: $this->assertNoOption('edit-menu-menu-parent', 'tools:' . $child_item->getPluginId()); Chris@0: // Assert that unallowed Administration menu is not available in options. Chris@0: $this->assertNoOption('edit-menu-menu-parent', 'admin:'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Testing correct loading and saving of menu links via node form widget in a multilingual environment. Chris@0: */ Chris@0: public function testMultilingualMenuNodeFormWidget() { Chris@0: // Setup languages. Chris@0: $langcodes = ['de']; Chris@0: foreach ($langcodes as $langcode) { Chris@0: ConfigurableLanguage::createFromLangcode($langcode)->save(); Chris@0: } Chris@0: array_unshift($langcodes, \Drupal::languageManager()->getDefaultLanguage()->getId()); Chris@0: Chris@0: $config = \Drupal::service('config.factory')->getEditable('language.negotiation'); Chris@0: // Ensure path prefix is used to determine the language. Chris@0: $config->set('url.source', 'path_prefix'); Chris@0: // Ensure that there's a path prefix set for english as well. Chris@0: $config->set('url.prefixes.' . $langcodes[0], $langcodes[0]); Chris@0: $config->save(); Chris@0: Chris@0: $this->rebuildContainer(); Chris@0: Chris@0: $languages = []; Chris@0: foreach ($langcodes as $langcode) { Chris@0: $languages[$langcode] = ConfigurableLanguage::load($langcode); Chris@0: } Chris@0: Chris@0: // Use a UI form submission to make the node type and menu link content entity translatable. Chris@0: $this->drupalLogout(); Chris@0: $this->drupalLogin($this->rootUser); Chris@0: $edit = [ Chris@0: 'entity_types[node]' => TRUE, Chris@0: 'entity_types[menu_link_content]' => TRUE, Chris@0: 'settings[node][page][settings][language][language_alterable]' => TRUE, Chris@0: 'settings[node][page][translatable]' => TRUE, Chris@0: 'settings[node][page][fields][title]' => TRUE, Chris@0: 'settings[menu_link_content][menu_link_content][translatable]' => TRUE, Chris@0: ]; Chris@0: $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); Chris@0: Chris@0: // Log out and back in as normal user. Chris@0: $this->drupalLogout(); Chris@0: $this->drupalLogin($this->editor); Chris@0: Chris@0: // Create a node. Chris@0: $node_title = $this->randomMachineName(8); Chris@0: $node = Node::create([ Chris@0: 'type' => 'page', Chris@0: 'title' => $node_title, Chris@0: 'body' => $this->randomMachineName(16), Chris@0: 'uid' => $this->editor->id(), Chris@0: 'status' => 1, Chris@0: 'langcode' => $langcodes[0], Chris@0: ]); Chris@0: $node->save(); Chris@0: Chris@0: // Create translation. Chris@0: $translated_node_title = $this->randomMachineName(8); Chris@0: $node->addTranslation($langcodes[1], ['title' => $translated_node_title, 'body' => $this->randomMachineName(16), 'status' => 1]); Chris@0: $node->save(); Chris@0: Chris@0: // Edit the node and create a menu link. Chris@0: $edit = [ Chris@0: 'menu[enabled]' => 1, Chris@0: 'menu[title]' => $node_title, Chris@0: 'menu[weight]' => 17, Chris@0: ]; Chris@0: $options = ['language' => $languages[$langcodes[0]]]; Chris@0: $url = $node->toUrl('edit-form', $options); Chris@0: $this->drupalPostForm($url, $edit, t('Save') . ' ' . t('(this translation)')); Chris@0: Chris@0: // Edit the node in a different language and translate the menu link. Chris@0: $edit = [ Chris@0: 'menu[enabled]' => 1, Chris@0: 'menu[title]' => $translated_node_title, Chris@0: 'menu[weight]' => 17, Chris@0: ]; Chris@0: $options = ['language' => $languages[$langcodes[1]]]; Chris@0: $url = $node->toUrl('edit-form', $options); Chris@0: $this->drupalPostForm($url, $edit, t('Save') . ' ' . t('(this translation)')); Chris@0: Chris@0: // Assert that the original link exists in the frontend. Chris@0: $this->drupalGet('node/' . $node->id(), ['language' => $languages[$langcodes[0]]]); Chris@0: $this->assertLink($node_title); Chris@0: Chris@0: // Assert that the translated link exists in the frontend. Chris@0: $this->drupalGet('node/' . $node->id(), ['language' => $languages[$langcodes[1]]]); Chris@0: $this->assertLink($translated_node_title); Chris@0: Chris@0: // Revisit the edit page in original language, check the loaded menu item title and save. Chris@0: $options = ['language' => $languages[$langcodes[0]]]; Chris@0: $url = $node->toUrl('edit-form', $options); Chris@0: $this->drupalGet($url); Chris@0: $this->assertFieldById('edit-menu-title', $node_title); Chris@0: $this->drupalPostForm(NULL, [], t('Save') . ' ' . t('(this translation)')); Chris@0: Chris@0: // Revisit the edit page of the translation and check the loaded menu item title. Chris@0: $options = ['language' => $languages[$langcodes[1]]]; Chris@0: $url = $node->toUrl('edit-form', $options); Chris@0: $this->drupalGet($url); Chris@0: $this->assertFieldById('edit-menu-title', $translated_node_title); Chris@0: } Chris@0: Chris@0: }