Loading src/MenuBasedBreadcrumbBuilder.php +6 −30 Original line number Diff line number Diff line Loading @@ -68,11 +68,7 @@ class MenuBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { } /** * Prepends a link to the front page as the first link if not already present. * * This method is only concerned with checking if the first link refers to the * front page. Even if a link to the front page exists further in the link * sequence, a front page link may still be added. * Prepend a link to the front page (if desired). * * @param array $links * The breadcrumb link sequence, passed by reference. Loading @@ -80,33 +76,13 @@ class MenuBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { * @return \Drupal\Core\Cache\CacheableMetadata * Additional cacheable metadata accrued by this method. */ protected function addMissingFrontLink(array &$links): CacheableMetadata { $cacheability = new CacheableMetadata(); protected function addFrontLink(array &$links): CacheableMetadata { $config = $this->config(); $cacheability = new CacheableMetadata(); $cacheability->addCacheableDependency($config); if (empty($config->get('prepend_front'))) { return $cacheability; } // Attempt to retrieve the front page path from the site's settings. $site_config = $this->configFactory->get('system.site'); $page_front = $site_config->get('page.front'); $internal_path = FALSE; // The front page must always be a routed URL. If there are no breadcrumb // links, or if the first breadcrumb link is unrouted, then a front page // link should always be prepended to the link sequence. if (!empty($links) && reset($links)->getUrl()->isRouted()) { $internal_path = reset($links)->getUrl()->getInternalPath(); $internal_path = rtrim('/' . $internal_path, '/'); // The result of the path test is only affected by updates to the // configured front page path for routed URLs. $cacheability->addCacheableDependency($site_config); } if ($internal_path !== $page_front) { if (!empty($config->get('prepend_front'))) { array_unshift($links, Link::createFromRoute($this->t('Home'), '<front>')); } Loading Loading @@ -153,8 +129,8 @@ class MenuBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { } } // Prepend a link to the front page if one is not already present. $breadcrumb->addCacheableDependency($this->addMissingFrontLink($links)); // Prepend a link to the front page (if desired). $breadcrumb->addCacheableDependency($this->addFrontLink($links)); $breadcrumb->setLinks($links); return $breadcrumb; Loading tests/src/Functional/AssertBreadcrumbTrait.php 0 → 100644 +103 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\crouton\Functional; use Drupal\Core\Url; /** * Provides functional test assertions for breadcrumbs. * * Copyright (C) 2022 Library Solutions, LLC (et al.). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ trait AssertBreadcrumbTrait { /** * Assert that certain breadcrumb links appear. * * The expected 'href' values will be processed prior to assertion. * * @param \Drupal\Core\Url|string|null $goto * A page to load. The current page will be tested if NULL. * @param array $expected * A sequence of associative arrays with an 'href' key whose value is the * expected breadcrumb link path and a 'text' key whose value is the * expected breadcrumb link text (not sanitized). * * @see ::processLink() * For more information about the processing of 'href' values. */ protected function assertBreadcrumbLinks($goto, array $expected) { if (isset($goto)) { $this->drupalGet($goto); } $expected = array_map([$this, 'processBreadcrumbLink'], $expected); $this->assertSame($expected, array_filter($expected), 'Expected breadcrumb links are valid'); $this->assertSame($expected, $this->getBreadcrumbLinks()); } /** * Fetch all breadcrumb links on the current page. * * @return array * A sequence of associative arrays with an 'href' key whose value is the * breadcrumb link path and a 'text' key whose value is the breadcrumb link * text (not sanitized). */ protected function getBreadcrumbLinks() { $results = []; foreach ($this->xpath('//nav[@aria-labelledby="system-breadcrumb"]//ol/li/a') as $element) { $results[] = [ 'href' => $element->getAttribute('href'), 'text' => $element->getText(), ]; } return $results; } /** * Process the supplied link for a breadcrumb assertion. * * The supplied 'href' value will be processed; an empty href will be replaced * with the front page URL, and any href not prefixed with a forward slash * will be prepended with the appropriate Drupal base prefix. * * @param array $link * An associative array with an 'href' key whose value is the expected * breadcrumb link path and a 'text' key whose value is the expected * breadcrumb link text (not sanitized). * * @return array * The input link with a processed value for the 'href' key on success, or * NULL if the link is invalid. */ protected function processBreadcrumbLink(array $link): ?array { $href = $link['href'] ?? FALSE; $text = $link['text'] ?? NULL; if (is_string($text) && is_string($href ?? '')) { if ($href == '') { $href = Url::fromRoute('<front>')->toString(); } elseif (substr($href, 0, 1) !== '/') { $href = Url::fromUri('base:' . $href)->toString(); } return [ 'href' => $href, 'text' => $text, ]; } return NULL; } } tests/src/Functional/AssertBreadcrumbTraitFunctionalTest.php 0 → 100644 +101 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\crouton\Functional; use Drupal\Tests\BrowserTestBase; /** * Functional tests for AssertBreadcrumbTrait. * * Copyright (C) 2022 Library Solutions, LLC (et al.). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * @coversDefaultClass \Drupal\Tests\crouton\Functional\AssertBreadcrumbTrait * @group crouton */ class AssertBreadcrumbTraitFunctionalTest extends BrowserTestBase { use AssertBreadcrumbTrait; /** * {@inheritdoc} */ protected $defaultTheme = 'stark'; /** * {@inheritdoc} */ protected static $modules = [ 'block', ]; /** * Data provider for ::testGetBreadcrumbLinks(). */ public function providerTestGetBreadcrumbLinks() { return [ 'performance configuration, without breadcrumb block' => [ FALSE, [ 'access administration pages', ], 'admin/config/development/performance', [], ], 'performance configuration, with breadcrumb block' => [ TRUE, [ 'access administration pages', ], 'admin/config/development/performance', [ [ 'href' => '', 'text' => 'Home', ], [ 'href' => 'admin', 'text' => 'Administration', ], [ 'href' => 'admin/config', 'text' => 'Configuration', ], [ 'href' => 'admin/config/development', 'text' => 'Development', ], ], ], ]; } /** * Test breadcrumb retrieval for the current page. * * @dataProvider providerTestGetBreadcrumbLinks * * @covers ::getBreadcrumbLinks */ public function testGetBreadcrumbLinks(bool $place_breadcrumb_block, array $user_permissions, string $page, array $expected) { if ($place_breadcrumb_block) { $this->drupalPlaceBlock('system_breadcrumb_block'); } if (!empty($user_permissions)) { $this->drupalLogin($this->drupalCreateUser($user_permissions)); } $this->drupalGet($page); $expected = array_map([$this, 'processBreadcrumbLink'], $expected); $this->assertSame($expected, array_filter($expected), 'Expected breadcrumb links are valid'); $this->assertSame($expected, $this->getBreadcrumbLinks()); } } tests/src/Functional/MenuBasedBreadcrumbBuilderFunctionalTest.php +102 −78 Original line number Diff line number Diff line Loading @@ -2,11 +2,9 @@ namespace Drupal\Tests\crouton\Functional; use Drupal\node\Entity\Node; use Drupal\menu_link_content\Entity\MenuLinkContent; use Drupal\Tests\BrowserTestBase; use Drupal\Tests\system\Functional\Menu\AssertBreadcrumbTrait; use Drupal\menu_link_content\MenuLinkContentInterface; /** * Functional tests for the menu-based breadcrumb builder. Loading Loading @@ -41,100 +39,126 @@ class MenuBasedBreadcrumbBuilderFunctionalTest extends BrowserTestBase { ]; /** * Data provider for ::testBreadcrumbPrepend(). */ public function providerTestBreadcrumbPrepend() { return [ 'matching' => [TRUE], 'not matching' => [FALSE], ]; } /** * Test that menu-based breadcrumbs are displayed. * {@inheritdoc} */ public function testBreadcrumbs() { $expected = []; public function setUp(): void { parent::setUp(); $config_factory = \Drupal::configFactory(); $this->drupalPlaceBlock('system_breadcrumb_block'); $crouton_settings = $config_factory->getEditable('crouton.settings'); $crouton_settings = \Drupal::configFactory()->getEditable('crouton.settings'); $crouton_settings->set('menu_name', 'main'); $crouton_settings->save(); } $content_type = $this->drupalCreateContentType(); /** * Create a menu link to some arbitrary content. * * @param \Drupal\menu_link_content\MenuLinkContentInterface|null $parent * An optional parent menu link. * * @return \Drupal\menu_link_content\MenuLinkContentInterface * The resulting menu link. */ protected function createMenuLink(?MenuLinkContentInterface $parent = NULL) { $entity_type_manager = \Drupal::entityTypeManager(); $node_storage = $entity_type_manager->getStorage('node'); /** @var \Drupal\node\NodeInterface */ $node = $node_storage->create([ 'title' => $this->randomMachineName(), 'type' => $this->drupalCreateContentType()->id(), ]); for ($i = 1; $i <= 3; ++$i) { ($node = Node::create([ 'title' => "Test {$i}", 'type' => $content_type->id(), ]))->save(); $node->save(); ($link = MenuLinkContent::create([ $menu_link_content_storage = $entity_type_manager->getStorage('menu_link_content'); /** @var \Drupal\menu_link_content\MenuLinkContentInterface */ $link = $menu_link_content_storage->create([ 'title' => $node->label(), 'parent' => isset($link) ? $link->getPluginId() : NULL, 'parent' => isset($parent) ? $parent->getPluginId() : NULL, 'provider' => 'menu_link_content', 'menu_name' => 'main', 'link' => [ 'uri' => "internal:/{$node->toUrl()->getInternalPath()}", ], ]))->save(); $expected[$node->toUrl()->getInternalPath()] = $node->label(); } ]); array_pop($expected); $link->save(); $this->drupalPlaceBlock('system_breadcrumb_block'); $this->assertBreadcrumb($node->toUrl(), $expected); return $link; } /** * Test the prepend of the front page to the breadcrumb trail. * Get the expected breadcrumb for the provided link. * * @dataProvider providerTestBreadcrumbPrepend * @param \Drupal\menu_link_content\MenuLinkContentInterface $link * The link for which to get the expected breadcrumb. * * @covers ::addMissingFrontLink * @return array * An associative array with an 'href' key whose value is the menu link path * and a 'text' key whose value is the menu link text (not sanitized). */ public function testBreadcrumbPrepend(bool $matching) { $expected = !$matching ? ['' => 'Home'] : []; protected function getExpectedBreadcrumbForLink(MenuLinkContentInterface $link): array { return [ 'href' => $link->getUrlObject()->getInternalPath(), 'text' => $link->getTitle(), ]; } $config_factory = \Drupal::configFactory(); /** * Data provider for ::testBreadcrumbs(). */ public function providerTestBreadcrumbs() { return [ 'no append current, no prepend front' => [ FALSE, FALSE, ], 'no append current, prepend front' => [ FALSE, TRUE, ], 'append current, no prepend front' => [ TRUE, FALSE, ], 'append current, prepend front' => [ TRUE, TRUE, ], ]; } $crouton_settings = $config_factory->getEditable('crouton.settings'); $crouton_settings->set('menu_name', 'main'); $crouton_settings->set('prepend_front', TRUE); /** * Test that menu-based breadcrumbs work as expected. * * @dataProvider providerTestBreadcrumbs */ public function testBreadcrumbs(bool $append_current, bool $prepend_front) { $crouton_settings = \Drupal::configFactory()->getEditable('crouton.settings'); $crouton_settings->set('append_current', $append_current); $crouton_settings->set('prepend_front', $prepend_front); $crouton_settings->save(); $content_type = $this->drupalCreateContentType(); for ($i = 1; $i <= 3; ++$i) { ($node = Node::create([ 'title' => "Test {$i}", 'type' => $content_type->id(), ]))->save(); ($link = MenuLinkContent::create([ 'title' => $node->label(), 'parent' => isset($link) ? $link->getPluginId() : NULL, 'provider' => 'menu_link_content', 'menu_name' => 'main', 'link' => [ 'uri' => "internal:/{$node->toUrl()->getInternalPath()}", ], ]))->save(); $expected = []; $expected[$node->toUrl()->getInternalPath()] = $node->label(); if ($prepend_front) { $expected[] = [ 'href' => '', 'text' => 'Home', ]; } array_pop($expected); $expected[] = $this->getExpectedBreadcrumbForLink($link = $this->createMenuLink()); $expected[] = $this->getExpectedBreadcrumbForLink($link = $this->createMenuLink($link)); $system_site = $config_factory->getEditable('system.site'); $system_site->set('page.front', $matching ? '/' . key($expected) : '/node'); $system_site->save(); $link = $this->createMenuLink($link); if ($append_current) { $expected[] = $this->getExpectedBreadcrumbForLink($link); } $this->drupalPlaceBlock('system_breadcrumb_block'); $this->assertBreadcrumb($node->toUrl(), $expected); $this->assertBreadcrumbLinks($link->getUrlObject(), $expected); } } Loading
src/MenuBasedBreadcrumbBuilder.php +6 −30 Original line number Diff line number Diff line Loading @@ -68,11 +68,7 @@ class MenuBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { } /** * Prepends a link to the front page as the first link if not already present. * * This method is only concerned with checking if the first link refers to the * front page. Even if a link to the front page exists further in the link * sequence, a front page link may still be added. * Prepend a link to the front page (if desired). * * @param array $links * The breadcrumb link sequence, passed by reference. Loading @@ -80,33 +76,13 @@ class MenuBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { * @return \Drupal\Core\Cache\CacheableMetadata * Additional cacheable metadata accrued by this method. */ protected function addMissingFrontLink(array &$links): CacheableMetadata { $cacheability = new CacheableMetadata(); protected function addFrontLink(array &$links): CacheableMetadata { $config = $this->config(); $cacheability = new CacheableMetadata(); $cacheability->addCacheableDependency($config); if (empty($config->get('prepend_front'))) { return $cacheability; } // Attempt to retrieve the front page path from the site's settings. $site_config = $this->configFactory->get('system.site'); $page_front = $site_config->get('page.front'); $internal_path = FALSE; // The front page must always be a routed URL. If there are no breadcrumb // links, or if the first breadcrumb link is unrouted, then a front page // link should always be prepended to the link sequence. if (!empty($links) && reset($links)->getUrl()->isRouted()) { $internal_path = reset($links)->getUrl()->getInternalPath(); $internal_path = rtrim('/' . $internal_path, '/'); // The result of the path test is only affected by updates to the // configured front page path for routed URLs. $cacheability->addCacheableDependency($site_config); } if ($internal_path !== $page_front) { if (!empty($config->get('prepend_front'))) { array_unshift($links, Link::createFromRoute($this->t('Home'), '<front>')); } Loading Loading @@ -153,8 +129,8 @@ class MenuBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { } } // Prepend a link to the front page if one is not already present. $breadcrumb->addCacheableDependency($this->addMissingFrontLink($links)); // Prepend a link to the front page (if desired). $breadcrumb->addCacheableDependency($this->addFrontLink($links)); $breadcrumb->setLinks($links); return $breadcrumb; Loading
tests/src/Functional/AssertBreadcrumbTrait.php 0 → 100644 +103 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\crouton\Functional; use Drupal\Core\Url; /** * Provides functional test assertions for breadcrumbs. * * Copyright (C) 2022 Library Solutions, LLC (et al.). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ trait AssertBreadcrumbTrait { /** * Assert that certain breadcrumb links appear. * * The expected 'href' values will be processed prior to assertion. * * @param \Drupal\Core\Url|string|null $goto * A page to load. The current page will be tested if NULL. * @param array $expected * A sequence of associative arrays with an 'href' key whose value is the * expected breadcrumb link path and a 'text' key whose value is the * expected breadcrumb link text (not sanitized). * * @see ::processLink() * For more information about the processing of 'href' values. */ protected function assertBreadcrumbLinks($goto, array $expected) { if (isset($goto)) { $this->drupalGet($goto); } $expected = array_map([$this, 'processBreadcrumbLink'], $expected); $this->assertSame($expected, array_filter($expected), 'Expected breadcrumb links are valid'); $this->assertSame($expected, $this->getBreadcrumbLinks()); } /** * Fetch all breadcrumb links on the current page. * * @return array * A sequence of associative arrays with an 'href' key whose value is the * breadcrumb link path and a 'text' key whose value is the breadcrumb link * text (not sanitized). */ protected function getBreadcrumbLinks() { $results = []; foreach ($this->xpath('//nav[@aria-labelledby="system-breadcrumb"]//ol/li/a') as $element) { $results[] = [ 'href' => $element->getAttribute('href'), 'text' => $element->getText(), ]; } return $results; } /** * Process the supplied link for a breadcrumb assertion. * * The supplied 'href' value will be processed; an empty href will be replaced * with the front page URL, and any href not prefixed with a forward slash * will be prepended with the appropriate Drupal base prefix. * * @param array $link * An associative array with an 'href' key whose value is the expected * breadcrumb link path and a 'text' key whose value is the expected * breadcrumb link text (not sanitized). * * @return array * The input link with a processed value for the 'href' key on success, or * NULL if the link is invalid. */ protected function processBreadcrumbLink(array $link): ?array { $href = $link['href'] ?? FALSE; $text = $link['text'] ?? NULL; if (is_string($text) && is_string($href ?? '')) { if ($href == '') { $href = Url::fromRoute('<front>')->toString(); } elseif (substr($href, 0, 1) !== '/') { $href = Url::fromUri('base:' . $href)->toString(); } return [ 'href' => $href, 'text' => $text, ]; } return NULL; } }
tests/src/Functional/AssertBreadcrumbTraitFunctionalTest.php 0 → 100644 +101 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\crouton\Functional; use Drupal\Tests\BrowserTestBase; /** * Functional tests for AssertBreadcrumbTrait. * * Copyright (C) 2022 Library Solutions, LLC (et al.). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * @coversDefaultClass \Drupal\Tests\crouton\Functional\AssertBreadcrumbTrait * @group crouton */ class AssertBreadcrumbTraitFunctionalTest extends BrowserTestBase { use AssertBreadcrumbTrait; /** * {@inheritdoc} */ protected $defaultTheme = 'stark'; /** * {@inheritdoc} */ protected static $modules = [ 'block', ]; /** * Data provider for ::testGetBreadcrumbLinks(). */ public function providerTestGetBreadcrumbLinks() { return [ 'performance configuration, without breadcrumb block' => [ FALSE, [ 'access administration pages', ], 'admin/config/development/performance', [], ], 'performance configuration, with breadcrumb block' => [ TRUE, [ 'access administration pages', ], 'admin/config/development/performance', [ [ 'href' => '', 'text' => 'Home', ], [ 'href' => 'admin', 'text' => 'Administration', ], [ 'href' => 'admin/config', 'text' => 'Configuration', ], [ 'href' => 'admin/config/development', 'text' => 'Development', ], ], ], ]; } /** * Test breadcrumb retrieval for the current page. * * @dataProvider providerTestGetBreadcrumbLinks * * @covers ::getBreadcrumbLinks */ public function testGetBreadcrumbLinks(bool $place_breadcrumb_block, array $user_permissions, string $page, array $expected) { if ($place_breadcrumb_block) { $this->drupalPlaceBlock('system_breadcrumb_block'); } if (!empty($user_permissions)) { $this->drupalLogin($this->drupalCreateUser($user_permissions)); } $this->drupalGet($page); $expected = array_map([$this, 'processBreadcrumbLink'], $expected); $this->assertSame($expected, array_filter($expected), 'Expected breadcrumb links are valid'); $this->assertSame($expected, $this->getBreadcrumbLinks()); } }
tests/src/Functional/MenuBasedBreadcrumbBuilderFunctionalTest.php +102 −78 Original line number Diff line number Diff line Loading @@ -2,11 +2,9 @@ namespace Drupal\Tests\crouton\Functional; use Drupal\node\Entity\Node; use Drupal\menu_link_content\Entity\MenuLinkContent; use Drupal\Tests\BrowserTestBase; use Drupal\Tests\system\Functional\Menu\AssertBreadcrumbTrait; use Drupal\menu_link_content\MenuLinkContentInterface; /** * Functional tests for the menu-based breadcrumb builder. Loading Loading @@ -41,100 +39,126 @@ class MenuBasedBreadcrumbBuilderFunctionalTest extends BrowserTestBase { ]; /** * Data provider for ::testBreadcrumbPrepend(). */ public function providerTestBreadcrumbPrepend() { return [ 'matching' => [TRUE], 'not matching' => [FALSE], ]; } /** * Test that menu-based breadcrumbs are displayed. * {@inheritdoc} */ public function testBreadcrumbs() { $expected = []; public function setUp(): void { parent::setUp(); $config_factory = \Drupal::configFactory(); $this->drupalPlaceBlock('system_breadcrumb_block'); $crouton_settings = $config_factory->getEditable('crouton.settings'); $crouton_settings = \Drupal::configFactory()->getEditable('crouton.settings'); $crouton_settings->set('menu_name', 'main'); $crouton_settings->save(); } $content_type = $this->drupalCreateContentType(); /** * Create a menu link to some arbitrary content. * * @param \Drupal\menu_link_content\MenuLinkContentInterface|null $parent * An optional parent menu link. * * @return \Drupal\menu_link_content\MenuLinkContentInterface * The resulting menu link. */ protected function createMenuLink(?MenuLinkContentInterface $parent = NULL) { $entity_type_manager = \Drupal::entityTypeManager(); $node_storage = $entity_type_manager->getStorage('node'); /** @var \Drupal\node\NodeInterface */ $node = $node_storage->create([ 'title' => $this->randomMachineName(), 'type' => $this->drupalCreateContentType()->id(), ]); for ($i = 1; $i <= 3; ++$i) { ($node = Node::create([ 'title' => "Test {$i}", 'type' => $content_type->id(), ]))->save(); $node->save(); ($link = MenuLinkContent::create([ $menu_link_content_storage = $entity_type_manager->getStorage('menu_link_content'); /** @var \Drupal\menu_link_content\MenuLinkContentInterface */ $link = $menu_link_content_storage->create([ 'title' => $node->label(), 'parent' => isset($link) ? $link->getPluginId() : NULL, 'parent' => isset($parent) ? $parent->getPluginId() : NULL, 'provider' => 'menu_link_content', 'menu_name' => 'main', 'link' => [ 'uri' => "internal:/{$node->toUrl()->getInternalPath()}", ], ]))->save(); $expected[$node->toUrl()->getInternalPath()] = $node->label(); } ]); array_pop($expected); $link->save(); $this->drupalPlaceBlock('system_breadcrumb_block'); $this->assertBreadcrumb($node->toUrl(), $expected); return $link; } /** * Test the prepend of the front page to the breadcrumb trail. * Get the expected breadcrumb for the provided link. * * @dataProvider providerTestBreadcrumbPrepend * @param \Drupal\menu_link_content\MenuLinkContentInterface $link * The link for which to get the expected breadcrumb. * * @covers ::addMissingFrontLink * @return array * An associative array with an 'href' key whose value is the menu link path * and a 'text' key whose value is the menu link text (not sanitized). */ public function testBreadcrumbPrepend(bool $matching) { $expected = !$matching ? ['' => 'Home'] : []; protected function getExpectedBreadcrumbForLink(MenuLinkContentInterface $link): array { return [ 'href' => $link->getUrlObject()->getInternalPath(), 'text' => $link->getTitle(), ]; } $config_factory = \Drupal::configFactory(); /** * Data provider for ::testBreadcrumbs(). */ public function providerTestBreadcrumbs() { return [ 'no append current, no prepend front' => [ FALSE, FALSE, ], 'no append current, prepend front' => [ FALSE, TRUE, ], 'append current, no prepend front' => [ TRUE, FALSE, ], 'append current, prepend front' => [ TRUE, TRUE, ], ]; } $crouton_settings = $config_factory->getEditable('crouton.settings'); $crouton_settings->set('menu_name', 'main'); $crouton_settings->set('prepend_front', TRUE); /** * Test that menu-based breadcrumbs work as expected. * * @dataProvider providerTestBreadcrumbs */ public function testBreadcrumbs(bool $append_current, bool $prepend_front) { $crouton_settings = \Drupal::configFactory()->getEditable('crouton.settings'); $crouton_settings->set('append_current', $append_current); $crouton_settings->set('prepend_front', $prepend_front); $crouton_settings->save(); $content_type = $this->drupalCreateContentType(); for ($i = 1; $i <= 3; ++$i) { ($node = Node::create([ 'title' => "Test {$i}", 'type' => $content_type->id(), ]))->save(); ($link = MenuLinkContent::create([ 'title' => $node->label(), 'parent' => isset($link) ? $link->getPluginId() : NULL, 'provider' => 'menu_link_content', 'menu_name' => 'main', 'link' => [ 'uri' => "internal:/{$node->toUrl()->getInternalPath()}", ], ]))->save(); $expected = []; $expected[$node->toUrl()->getInternalPath()] = $node->label(); if ($prepend_front) { $expected[] = [ 'href' => '', 'text' => 'Home', ]; } array_pop($expected); $expected[] = $this->getExpectedBreadcrumbForLink($link = $this->createMenuLink()); $expected[] = $this->getExpectedBreadcrumbForLink($link = $this->createMenuLink($link)); $system_site = $config_factory->getEditable('system.site'); $system_site->set('page.front', $matching ? '/' . key($expected) : '/node'); $system_site->save(); $link = $this->createMenuLink($link); if ($append_current) { $expected[] = $this->getExpectedBreadcrumbForLink($link); } $this->drupalPlaceBlock('system_breadcrumb_block'); $this->assertBreadcrumb($node->toUrl(), $expected); $this->assertBreadcrumbLinks($link->getUrlObject(), $expected); } }