3 namespace Drupal\Tests\menu_link_content\Functional;
5 use Drupal\Component\Utility\SafeMarkup;
6 use Drupal\menu_link_content\Entity\MenuLinkContent;
7 use Drupal\Tests\BrowserTestBase;
8 use Drupal\system\Entity\Menu;
11 * Tests handling of menu links hierarchies.
15 class LinksTest extends BrowserTestBase {
22 public static $modules = ['router_test', 'menu_link_content'];
25 * The menu link plugin manager.
27 * @var \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager
29 protected $menuLinkManager;
34 protected function setUp() {
37 $this->menuLinkManager = \Drupal::service('plugin.manager.menu.link');
41 'label' => 'Test menu',
42 'description' => 'Description text',
47 * Create a simple hierarchy of links.
49 public function createLinkHierarchy($module = 'menu_test') {
50 // First remove all the menu links in the menu.
51 $this->menuLinkManager->deleteLinksInMenu('menu_test');
53 // Then create a simple link hierarchy:
60 'title' => 'Menu link test',
61 'provider' => $module,
62 'menu_name' => 'menu_test',
65 $parent = $base_options + [
66 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent'],
68 $link = MenuLinkContent::create($parent);
70 $links['parent'] = $link->getPluginId();
72 $child_1 = $base_options + [
73 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent/child'],
74 'parent' => $links['parent'],
76 $link = MenuLinkContent::create($child_1);
78 $links['child-1'] = $link->getPluginId();
80 $child_1_1 = $base_options + [
81 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent/child2/child'],
82 'parent' => $links['child-1'],
84 $link = MenuLinkContent::create($child_1_1);
86 $links['child-1-1'] = $link->getPluginId();
88 $child_1_2 = $base_options + [
89 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent/child2/child'],
90 'parent' => $links['child-1'],
92 $link = MenuLinkContent::create($child_1_2);
94 $links['child-1-2'] = $link->getPluginId();
96 $child_2 = $base_options + [
97 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent/child'],
98 'parent' => $links['parent'],
100 $link = MenuLinkContent::create($child_2);
102 $links['child-2'] = $link->getPluginId();
108 * Assert that at set of links is properly parented.
110 public function assertMenuLinkParents($links, $expected_hierarchy) {
111 foreach ($expected_hierarchy as $id => $parent) {
112 /* @var \Drupal\Core\Menu\MenuLinkInterface $menu_link_plugin */
113 $menu_link_plugin = $this->menuLinkManager->createInstance($links[$id]);
114 $expected_parent = isset($links[$parent]) ? $links[$parent] : '';
116 $this->assertEqual($menu_link_plugin->getParent(), $expected_parent, SafeMarkup::format('Menu link %id has parent of %parent, expected %expected_parent.', ['%id' => $id, '%parent' => $menu_link_plugin->getParent(), '%expected_parent' => $expected_parent]));
121 * Assert that a link entity's created timestamp is set.
123 public function testCreateLink() {
125 'menu_name' => 'menu_test',
126 'bundle' => 'menu_link_content',
127 'link' => [['uri' => 'internal:/']],
129 $link = MenuLinkContent::create($options);
131 // Make sure the changed timestamp is set.
132 $this->assertEqual($link->getChangedTime(), REQUEST_TIME, 'Creating a menu link sets the "changed" timestamp.');
134 'title' => 'Test Link',
136 $link->link->options = $options;
137 $link->changed->value = 0;
139 // Make sure the changed timestamp is updated.
140 $this->assertEqual($link->getChangedTime(), REQUEST_TIME, 'Changing a menu link sets "changed" timestamp.');
144 * Test automatic reparenting of menu links.
146 public function testMenuLinkReparenting($module = 'menu_test') {
147 // Check the initial hierarchy.
148 $links = $this->createLinkHierarchy($module);
150 $expected_hierarchy = [
152 'child-1' => 'parent',
153 'child-1-1' => 'child-1',
154 'child-1-2' => 'child-1',
155 'child-2' => 'parent',
157 $this->assertMenuLinkParents($links, $expected_hierarchy);
159 // Start over, and move child-1 under child-2, and check that all the
160 // children of child-1 have been moved too.
161 $links = $this->createLinkHierarchy($module);
162 /* @var \Drupal\Core\Menu\MenuLinkInterface $menu_link_plugin */
163 $this->menuLinkManager->updateDefinition($links['child-1'], ['parent' => $links['child-2']]);
164 // Verify that the entity was updated too.
165 $menu_link_plugin = $this->menuLinkManager->createInstance($links['child-1']);
166 $entity = \Drupal::entityManager()->loadEntityByUuid('menu_link_content', $menu_link_plugin->getDerivativeId());
167 $this->assertEqual($entity->getParentId(), $links['child-2']);
169 $expected_hierarchy = [
171 'child-1' => 'child-2',
172 'child-1-1' => 'child-1',
173 'child-1-2' => 'child-1',
174 'child-2' => 'parent',
176 $this->assertMenuLinkParents($links, $expected_hierarchy);
178 // Start over, and delete child-1, and check that the children of child-1
179 // have been reassigned to the parent.
180 $links = $this->createLinkHierarchy($module);
181 $this->menuLinkManager->removeDefinition($links['child-1']);
183 $expected_hierarchy = [
185 'child-1-1' => 'parent',
186 'child-1-2' => 'parent',
187 'child-2' => 'parent',
189 $this->assertMenuLinkParents($links, $expected_hierarchy);
191 // Try changing the parent at the entity level.
192 $definition = $this->menuLinkManager->getDefinition($links['child-1-2']);
193 $entity = MenuLinkContent::load($definition['metadata']['entity_id']);
194 $entity->parent->value = '';
197 $expected_hierarchy = [
199 'child-1-1' => 'parent',
201 'child-2' => 'parent',
203 $this->assertMenuLinkParents($links, $expected_hierarchy);
205 // @todo Figure out what makes sense to test in terms of automatic
206 // re-parenting. https://www.drupal.org/node/2309531
210 * Tests uninstalling a module providing default links.
212 public function testModuleUninstalledMenuLinks() {
213 \Drupal::service('module_installer')->install(['menu_test']);
214 \Drupal::service('router.builder')->rebuild();
215 \Drupal::service('plugin.manager.menu.link')->rebuild();
216 $menu_links = $this->menuLinkManager->loadLinksByRoute('menu_test.menu_test');
217 $this->assertEqual(count($menu_links), 1);
218 $menu_link = reset($menu_links);
219 $this->assertEqual($menu_link->getPluginId(), 'menu_test');
221 // Uninstall the module and ensure the menu link got removed.
222 \Drupal::service('module_installer')->uninstall(['menu_test']);
223 \Drupal::service('plugin.manager.menu.link')->rebuild();
224 $menu_links = $this->menuLinkManager->loadLinksByRoute('menu_test.menu_test');
225 $this->assertEqual(count($menu_links), 0);