1<?php 2 3namespace Drupal\KernelTests\Core\Menu; 4 5use Drupal\Core\Menu\MenuLinkTreeElement; 6use Drupal\Core\Menu\MenuTreeParameters; 7use Drupal\KernelTests\KernelTestBase; 8use Drupal\Tests\Core\Menu\MenuLinkMock; 9 10/** 11 * Tests the menu link tree. 12 * 13 * @group Menu 14 * 15 * @see \Drupal\Core\Menu\MenuLinkTree 16 */ 17class MenuLinkTreeTest extends KernelTestBase { 18 19 /** 20 * The tested menu link tree. 21 * 22 * @var \Drupal\Core\Menu\MenuLinkTree 23 */ 24 protected $linkTree; 25 26 /** 27 * The menu link plugin manager. 28 * 29 * @var \Drupal\Core\Menu\MenuLinkManagerInterface 30 */ 31 protected $menuLinkManager; 32 33 /** 34 * Modules to enable. 35 * 36 * @var array 37 */ 38 protected static $modules = [ 39 'system', 40 'menu_test', 41 'menu_link_content', 42 'field', 43 'link', 44 'user', 45 ]; 46 47 /** 48 * {@inheritdoc} 49 */ 50 protected function setUp(): void { 51 parent::setUp(); 52 $this->installEntitySchema('user'); 53 $this->installEntitySchema('menu_link_content'); 54 55 $this->linkTree = $this->container->get('menu.link_tree'); 56 $this->menuLinkManager = $this->container->get('plugin.manager.menu.link'); 57 } 58 59 /** 60 * Tests deleting all the links in a menu. 61 */ 62 public function testDeleteLinksInMenu() { 63 \Drupal::entityTypeManager()->getStorage('menu')->create(['id' => 'menu1'])->save(); 64 \Drupal::entityTypeManager()->getStorage('menu')->create(['id' => 'menu2'])->save(); 65 66 \Drupal::entityTypeManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content', 'title' => 'Link test'])->save(); 67 \Drupal::entityTypeManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content', 'title' => 'Link test'])->save(); 68 \Drupal::entityTypeManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu2', 'bundle' => 'menu_link_content', 'title' => 'Link test'])->save(); 69 70 $output = $this->linkTree->load('menu1', new MenuTreeParameters()); 71 $this->assertCount(2, $output); 72 $output = $this->linkTree->load('menu2', new MenuTreeParameters()); 73 $this->assertCount(1, $output); 74 75 $this->menuLinkManager->deleteLinksInMenu('menu1'); 76 77 $output = $this->linkTree->load('menu1', new MenuTreeParameters()); 78 $this->assertCount(0, $output); 79 80 $output = $this->linkTree->load('menu2', new MenuTreeParameters()); 81 $this->assertCount(1, $output); 82 } 83 84 /** 85 * Tests creating links with an expected tree structure. 86 */ 87 public function testCreateLinksInMenu() { 88 // This creates a tree with the following structure: 89 // - 1 90 // - 2 91 // - 3 92 // - 4 93 // - 5 94 // - 7 95 // - 6 96 // - 8 97 // With link 6 being the only external link. 98 99 $links = [ 100 1 => MenuLinkMock::create(['id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '']), 101 2 => MenuLinkMock::create(['id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => 'test.example1', 'route_parameters' => ['foo' => 'bar']]), 102 3 => MenuLinkMock::create(['id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'route_parameters' => ['baz' => 'qux']]), 103 4 => MenuLinkMock::create(['id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3']), 104 5 => MenuLinkMock::create(['id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '']), 105 6 => MenuLinkMock::create(['id' => 'test.example6', 'route_name' => '', 'url' => 'https://www.drupal.org/', 'title' => 'barbar', 'parent' => '']), 106 7 => MenuLinkMock::create(['id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => '']), 107 8 => MenuLinkMock::create(['id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '']), 108 ]; 109 foreach ($links as $instance) { 110 $this->menuLinkManager->addDefinition($instance->getPluginId(), $instance->getPluginDefinition()); 111 } 112 $parameters = new MenuTreeParameters(); 113 $tree = $this->linkTree->load('mock', $parameters); 114 115 $count = function (array $tree) { 116 $sum = function ($carry, MenuLinkTreeElement $item) { 117 return $carry + $item->count(); 118 }; 119 return array_reduce($tree, $sum); 120 }; 121 122 $this->assertEquals(8, $count($tree)); 123 $parameters = new MenuTreeParameters(); 124 $parameters->setRoot('test.example2'); 125 $tree = $this->linkTree->load($instance->getMenuName(), $parameters); 126 $top_link = reset($tree); 127 $this->assertCount(1, $top_link->subtree); 128 $child = reset($top_link->subtree); 129 $this->assertEquals($links[3]->getPluginId(), $child->link->getPluginId()); 130 $height = $this->linkTree->getSubtreeHeight('test.example2'); 131 $this->assertEquals(3, $height); 132 } 133 134} 135