diff --git a/includes/Menu/Definitions.php b/includes/Menu/Definitions.php index e7ad0abb9..9c370506f 100644 --- a/includes/Menu/Definitions.php +++ b/includes/Menu/Definitions.php @@ -32,7 +32,7 @@ use SpecialPage; use Title; /** - * Set of all know menu items for easier building + * Set of all known menu items for easier building */ final class Definitions { @@ -74,6 +74,24 @@ final class Definitions { $this->userOptionsLookup = $userOptionsLookup; } + /** + * Builds a meny entry. + * + * @param string $name + * @param string $text Entry label + * @param string $url The URL entry points to + * @param string $className Optional HTML classes + * @param string|null $icon defaults to $name if not specified + * @param bool $trackable Whether an entry will track clicks or not. Default is false. + * @throws MWException + * @return SingleMenuEntry + */ + private function buildMenuEntry( $name, $text, $url, $className = '', $icon = null, $trackable = false ) { + $entry = SingleMenuEntry::create( $name, $text, $url, $className, $icon, $trackable ); + + return $entry; + } + /** * Creates a login or logout button with a profile button. * @@ -105,14 +123,16 @@ final class Definitions { public function insertNearbyIfSupported( Group $group ) { // Nearby link (if supported) if ( $this->specialPageFactory->exists( 'Nearby' ) ) { - $group->insert( 'nearby', /* $isJSOnly = */ true ) - ->addComponent( - $this->context->msg( 'mobile-frontend-main-menu-nearby' )->text(), - SpecialPage::getTitleFor( 'Nearby' )->getLocalURL(), - '', - [ 'data-event-name' => 'menu.nearby' ], - 'minerva-mapPin' - ); + $entry = $this->buildMenuEntry( + 'nearby', + $this->context->msg( 'mobile-frontend-main-menu-nearby' )->text(), + SpecialPage::getTitleFor( 'Nearby' )->getLocalURL(), + '', + 'mapPin', + true + ); + // Setting this feature for javascript only + $entry->setJSOnly(); } } @@ -138,16 +158,19 @@ final class Definitions { !$betaEnabled ); - $item = SingleMenuEntry::create( + $entry = $this->buildMenuEntry( 'settings', $this->context->msg( 'mobile-frontend-main-menu-settings' )->text(), SpecialPage::getTitleFor( 'MobileOptions' ) - ->getLocalURL( [ 'returnto' => $returnToTitle ] ) + ->getLocalURL( [ 'returnto' => $returnToTitle ] ), + '', + null, + true ); if ( $jsonly ) { - $item->setJSOnly(); + $entry->setJSOnly(); } - $group->insertEntry( $item ); + $group->insertEntry( $entry ); } /** @@ -156,12 +179,14 @@ final class Definitions { * @throws MWException */ public function insertPreferencesItem( Group $group ) { - $entry = SingleMenuEntry::create( + $entry = $this->buildMenuEntry( 'preferences', $this->context->msg( 'preferences' )->text(), - SpecialPage::getTitleFor( 'Preferences' )->getLocalURL() + SpecialPage::getTitleFor( 'Preferences' )->getLocalURL(), + '', + 'settings', + true ); - $entry->setIcon( 'settings' ); $group->insertEntry( $entry ); } @@ -178,8 +203,8 @@ final class Definitions { if ( !$title ) { return; } - $group->insert( 'about' ) - ->addComponent( $msg->text(), $title->getLocalURL() ); + $entry = $this->buildMenuEntry( 'about', $msg->text(), $title->getLocalURL() ); + $group->insertEntry( $entry ); } /** @@ -196,8 +221,8 @@ final class Definitions { if ( !$title ) { return; } - $group->insert( 'disclaimers' ) - ->addComponent( $msg->text(), $title->getLocalURL() ); + $entry = $this->buildMenuEntry( 'disclaimers', $msg->text(), $title->getLocalURL() ); + $group->insertEntry( $entry ); } /** @@ -206,16 +231,15 @@ final class Definitions { * @throws MWException */ public function insertRecentChanges( Group $group ) { - $title = SpecialPage::getTitleFor( 'Recentchanges' ); - - $group->insert( 'recentchanges' ) - ->addComponent( - $this->context->msg( 'recentchanges' )->escaped(), - $title->getLocalURL(), - '', - [ 'data-event-name' => 'menu.recentchanges' ], - 'minerva-recentChanges' - ); + $entry = $this->buildMenuEntry( + 'recentchanges', + $this->context->msg( 'recentchanges' )->escaped(), + SpecialPage::getTitleFor( 'Recentchanges' )->getLocalURL(), + '', + 'recentChanges', + true + ); + $group->insertEntry( $entry ); } /** @@ -224,13 +248,15 @@ final class Definitions { * @throws MWException */ public function insertSpecialPages( Group $group ) { - $group->insertEntry( - SingleMenuEntry::create( - 'specialPages', - $this->context->msg( 'specialpages' )->text(), - SpecialPage::getTitleFor( 'Specialpages' )->getLocalURL() - ) + $entry = $this->buildMenuEntry( + 'specialPages', + $this->context->msg( 'specialpages' )->text(), + SpecialPage::getTitleFor( 'Specialpages' )->getLocalURL(), + '', + null, + true ); + $group->insertEntry( $entry ); } /** @@ -248,11 +274,15 @@ final class Definitions { if ( !$title ) { return; } - $group->insertEntry( SingleMenuEntry::create( + $entry = $this->buildMenuEntry( 'speechBubbles', $msg->text(), - $title->getLocalURL() - ) ); + $title->getLocalURL(), + '', + null, + true + ); + $group->insertEntry( $entry ); } /** @@ -312,17 +342,14 @@ final class Definitions { $urlMsg->text(), [ 'utm_key' => 'minerva' ] ); - - $group->insert( 'donate' )->addComponent( + $entry = $this->buildMenuEntry( + 'donate', $labelMsg->text(), $url, '', - [ - // for consistency with desktop - 'id' => 'n-sitesupport', - 'data-event-name' => 'menu.donate', - ], - 'minerva-heart' + 'heart', + true ); + $group->insertEntry( $entry ); } } diff --git a/includes/Menu/Entries/MenuEntry.php b/includes/Menu/Entries/MenuEntry.php deleted file mode 100644 index 6279b5cbf..000000000 --- a/includes/Menu/Entries/MenuEntry.php +++ /dev/null @@ -1,97 +0,0 @@ -name = $name; - $this->isJSOnly = $isJSOnly; - $this->components = []; - } - - /** - * @return string - */ - public function getName() { - return $this->name; - } - - /** - * Return the CSS classes applied to the Menu element - * - * @return array - */ - public function getCSSClasses(): array { - $classes = []; - if ( $this->isJSOnly ) { - $classes[] = 'jsonly'; - } - return $classes; - } - - /** - * @return array - */ - public function getComponents(): array { - return $this->components; - } - - /** - * Add a link to the entry. - * - * An entry can have zero or more links. - * - * @param string $label - * @param string $url - * @param string $className Any additional CSS classes that should added to the output, - * separated by spaces - * @param array $attrs Additional data that can be associated with the component - * @param null|string $icon the icon identifier - * - * @return MenuEntry - */ - public function addComponent( $label, $url, $className = '', $attrs = [], $icon = null ) { - $this->components[] = [ - 'text' => $label, - 'href' => $url, - 'class' => $className, - 'icon' => $icon, - ] + $attrs; - return $this; - } -} diff --git a/includes/Menu/Entries/SingleMenuEntry.php b/includes/Menu/Entries/SingleMenuEntry.php index 2afb9ffe2..b18b2bc2a 100644 --- a/includes/Menu/Entries/SingleMenuEntry.php +++ b/includes/Menu/Entries/SingleMenuEntry.php @@ -89,11 +89,14 @@ class SingleMenuEntry implements IMenuEntry { * @param string $url The URL entry points to * @param string $className Optional HTML classes * @param string|null $icon defaults to $name if not specified + * @param bool $trackable Whether an entry will track clicks or not. Default is false. * @return static */ - public static function create( $name, $text, $url, $className = '', $icon = null ) { + public static function create( $name, $text, $url, $className = '', $icon = null, $trackable = false ) { $entry = new static( $name, $text, $url, $className ); - $entry->trackClicks( $name ); + if ( $trackable ) { + $entry->trackClicks( $name ); + } if ( $icon === null ) { $icon = $name; } @@ -140,14 +143,19 @@ class SingleMenuEntry implements IMenuEntry { * @param string $iconPrefix either `wikimedia` or `minerva` * @return $this */ - public function setIcon( $iconName, $iconType = 'before', - $additionalClassNames = '', $iconPrefix = 'minerva' + public function setIcon( $iconName, + $iconType = 'before', + $additionalClassNames = '', + $iconPrefix = 'minerva' ) { if ( $iconType === 'before' ) { $this->attributes['icon'] = $iconPrefix . '-' . $iconName; } else { $this->attributes['class'] .= ' ' . MinervaUI::iconClass( - $iconName, $iconType, $additionalClassNames, $iconPrefix + $iconName, + $iconType, + $additionalClassNames, + $iconPrefix ); } return $this; @@ -179,5 +187,4 @@ class SingleMenuEntry implements IMenuEntry { public function setJSOnly() { $this->isJSOnly = true; } - } diff --git a/includes/Menu/Group.php b/includes/Menu/Group.php index 4282cadd1..14a059050 100644 --- a/includes/Menu/Group.php +++ b/includes/Menu/Group.php @@ -22,7 +22,7 @@ namespace MediaWiki\Minerva\Menu; use DomainException; use MediaWiki\Minerva\Menu\Entries\IMenuEntry; -use MediaWiki\Minerva\Menu\Entries\MenuEntry; +use MediaWiki\Minerva\Menu\Entries\SingleMenuEntry; /** * Model for a menu that can be presented in a skin. @@ -110,21 +110,6 @@ final class Group { $this->entries[] = $entry; } - /** - * Insert an entry into the menu. - * - * @param string $name A unique name identifying the menu entry - * @param bool $isJSOnly Whether the menu entry works without JS - * @throws DomainException When the entry already exists - * @return MenuEntry - */ - public function insert( $name, $isJSOnly = false ) { - $this->throwIfNotUnique( $name ); - $this->entries[] = $entry = new MenuEntry( $name, $isJSOnly ); - - return $entry; - } - /** * Searches for a menu entry by name. * @@ -149,18 +134,24 @@ final class Group { * @param string $targetName The name of the existing entry to insert * the new entry after * @param string $name The name of the new entry + * @param string $text Entry label + * @param string $url The URL entry points to + * @param string $className Optional HTML classes + * @param string|null $icon defaults to $name if not specified + * @param bool $trackable Whether an entry will track clicks or not. Default is false. * @param bool $isJSOnly Whether the entry works without JS * @throws DomainException When the existing entry doesn't exist - * @return MenuEntry */ - public function insertAfter( $targetName, $name, $isJSOnly = false ) { + public function insertAfter( $targetName, $name, $text, $url, + $className = '', $icon = null, $trackable = false, $isJSOnly = false ) { $this->throwIfNotUnique( $name ); $index = $this->search( $targetName ); - $entry = new MenuEntry( $name, $isJSOnly ); + $entry = SingleMenuEntry::create( $name, $text, $url, $className, $icon, $trackable ); + if ( $isJSOnly ) { + $entry->setJSOnly(); + } array_splice( $this->entries, $index + 1, 0, [ $entry ] ); - - return $entry; } /** diff --git a/tests/phpunit/menu/Entries/MenuEntryTest.php b/tests/phpunit/menu/Entries/MenuEntryTest.php deleted file mode 100644 index c084af710..000000000 --- a/tests/phpunit/menu/Entries/MenuEntryTest.php +++ /dev/null @@ -1,27 +0,0 @@ -assertSame( $name, $entry->getName() ); - $this->assertArrayEquals( [ 'jsonly' ], $entry->getCSSClasses() ); - $this->assertSame( [], $entry->getComponents() ); - } -} diff --git a/tests/phpunit/menu/GroupTest.php b/tests/phpunit/menu/GroupTest.php index 0f8b79326..afab77626 100644 --- a/tests/phpunit/menu/GroupTest.php +++ b/tests/phpunit/menu/GroupTest.php @@ -4,6 +4,7 @@ namespace MediaWiki\Minerva\Menu; use DomainException; use MediaWiki\Minerva\Menu\Entries\IMenuEntry; +use MediaWiki\Minerva\Menu\Entries\SingleMenuEntry; use MediaWikiIntegrationTestCase; /** @@ -16,8 +17,8 @@ class GroupTest extends MediaWikiIntegrationTestCase { 'text' => 'Home', 'href' => '/Main_page', 'class' => 'mw-ui-icon mw-ui-icon-before mw-ui-icon-home', - 'data-event-name' => 'home', - 'icon' => null, + 'data-event-name' => 'menu.home', + 'icon' => null ]; /** @var string[] */ @@ -30,188 +31,122 @@ class GroupTest extends MediaWikiIntegrationTestCase { /** * @covers ::getEntries + * @covers ::hasEntries */ public function testItShouldntHaveEntriesByDefault() { $menu = new Group( 'p-test' ); $this->assertEmpty( $menu->getEntries() ); + $this->assertFalse( $menu->hasEntries() ); } /** - * @covers ::insert + * @covers ::insertEntry * @covers ::search * @covers ::getEntries - * @covers \MediaWiki\Minerva\Menu\Entries\MenuEntry::addComponent + * @covers ::hasEntries */ public function testInsertingAnEntry() { $menu = new Group( 'p-test' ); - $menu->insert( 'home' ) - ->addComponent( - $this->homeComponent['text'], - $this->homeComponent['href'], - $this->homeComponent['class'], - [ - 'data-event-name' => $this->homeComponent['data-event-name'] - ] - ); + $entry = SingleMenuEntry::create( + 'home', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'], + $this->homeComponent['icon'], + true + ); + $menu->insertEntry( $entry ); $expectedEntries = [ [ 'name' => 'home', - 'components' => [ $this->homeComponent ], + 'components' => [ + [ + 'text' => $this->homeComponent['text'], + 'href' => $this->homeComponent['href'], + 'class' => 'mw-ui-icon mw-ui-icon-before mw-ui-icon-home menu__item--home', + 'icon' => 'minerva-home', + 'data-event-name' => 'menu.home' + ] + ], ], ]; $this->assertEquals( $expectedEntries, $menu->getEntries() ); + $this->assertTrue( $menu->hasEntries() ); } /** - * @covers ::insert + * @covers ::insertEntry * @covers ::search * @covers ::getEntries - * @covers \MediaWiki\Minerva\Menu\Entries\MenuEntry::addComponent + * @covers ::insertAfter */ public function testInsertingAnEntryAfterAnother() { $menu = new Group( 'p-test' ); - $menu->insert( 'home' ) - ->addComponent( - $this->homeComponent['text'], - $this->homeComponent['href'], - $this->homeComponent['class'], - [ - 'data-event-name' => $this->homeComponent['data-event-name'] - ] - ); - $menu->insert( 'another_home' ) - ->addComponent( - $this->homeComponent['text'], - $this->homeComponent['href'], - $this->homeComponent['class'], - [ - 'data-event-name' => $this->homeComponent['data-event-name'] - ] - ); - $menu->insertAfter( 'home', 'nearby' ) - ->addComponent( - $this->nearbyComponent['text'], - $this->nearbyComponent['href'], - $this->nearbyComponent['class'] - ); + $entryHome = SingleMenuEntry::create( + 'home', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'], + $this->homeComponent['icon'], + true + ); + $menu->insertEntry( $entryHome ); + + $entryOtherHome = SingleMenuEntry::create( + 'another_home', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'], + $this->homeComponent['icon'], + true + ); + $menu->insertEntry( $entryOtherHome ); + $menu->insertAfter( + 'home', + 'nearby', + $this->nearbyComponent['text'], + $this->nearbyComponent['href'], + $this->nearbyComponent['class'], + $this->nearbyComponent['icon'] + ); $expectedEntries = [ [ 'name' => 'home', - 'components' => [ $this->homeComponent ], + 'components' => [ + [ + 'text' => $this->homeComponent['text'], + 'href' => $this->homeComponent['href'], + 'class' => 'mw-ui-icon mw-ui-icon-before mw-ui-icon-home menu__item--home', + 'icon' => 'minerva-home', + 'data-event-name' => 'menu.home' + ] + ], ], [ 'name' => 'nearby', - 'components' => [ $this->nearbyComponent ], + 'components' => [ + [ + 'text' => $this->nearbyComponent['text'], + 'href' => $this->nearbyComponent['href'], + 'class' => 'mw-ui-icon mw-ui-icon-before mw-ui-icon-nearby menu__item--nearby', + 'icon' => 'minerva-nearby' + ] + ], ], [ 'name' => 'another_home', - 'components' => [ $this->homeComponent ], - ], - ]; - - $this->assertEquals( $expectedEntries, $menu->getEntries() ); - } - - /** - * @covers ::insertAfter - * @covers ::search - * @covers \MediaWiki\Minerva\Menu\Entries\MenuEntry::addComponent - */ - public function testInsertAfterWhenTargetEntryDoesntExist() { - $menu = new Group( 'p-test' ); - $this->expectException( DomainException::class ); - $this->expectExceptionMessage( 'The "home" entry doesn\'t exist.' ); - $menu->insertAfter( 'home', 'nearby' ) - ->addComponent( - $this->nearbyComponent['text'], - $this->nearbyComponent['href'], - $this->nearbyComponent['class'] - ); - } - - /** - * @covers ::insertAfter - */ - public function testInsertAfterWithAnEntryWithAnExistingName() { - $menu = new Group( 'p-test' ); - $menu->insert( 'home' ); - $menu->insert( 'car' ); - $this->expectException( DomainException::class ); - $this->expectExceptionMessage( 'The "car" entry already exists.' ); - $menu->insertAfter( 'home', 'car' ); - } - - /** - * @covers ::insert - */ - public function testInsertingAnEntryWithAnExistingName() { - $menu = new Group( 'p-test' ); - $menu->insert( 'home' ); - $this->expectException( DomainException::class ); - $this->expectExceptionMessage( 'The "home" entry already exists.' ); - $menu->insert( 'home' ); - } - - /** - * @covers ::insert - * @covers ::insertAfter - */ - public function testInsertingAnEntryAfterAnotherOne() { - $menu = new Group( 'p-test' ); - $menu->insert( 'first' ); - $menu->insert( 'last' ); - $menu->insertAfter( 'first', 'middle' ); - $items = $menu->getEntries(); - $this->assertCount( 3, $items ); - $this->assertSame( 'first', $items[0]['name'] ); - $this->assertSame( 'middle', $items[1]['name'] ); - $this->assertSame( 'last', $items[2]['name'] ); - } - - /** - * @covers ::insert - * @covers ::getEntries - * @covers \MediaWiki\Minerva\Menu\Entries\MenuEntry::addComponent - */ - public function testinsertingAnEntryWithMultipleComponents() { - $authLoginComponent = [ - 'text' => 'Phuedx (WMF)', - 'href' => '/wiki/User:Phuedx_(WMF)', - 'class' => - 'mw-ui-icon mw-ui-icon-before mw-ui-icon-profile', - 'icon' => null, - ]; - $authLogoutComponent = [ - 'text' => 'Logout', - 'href' => '/wiki/Special:UserLogout', - 'class' => - 'mw-ui-icon mw-ui-icon-element secondary-logout', - 'icon' => null, - ]; - - $menu = new Group( 'p-test' ); - $menu->insert( 'auth' ) - ->addComponent( - $authLoginComponent['text'], - $authLoginComponent['href'], - $authLoginComponent['class'] - ) - ->addComponent( - $authLogoutComponent['text'], - $authLogoutComponent['href'], - $authLogoutComponent['class'] - ); - - $expectedEntries = [ - [ - 'name' => 'auth', 'components' => [ - $authLoginComponent, - $authLogoutComponent + [ + 'text' => $this->homeComponent['text'], + 'href' => $this->homeComponent['href'], + 'class' => 'mw-ui-icon mw-ui-icon-before mw-ui-icon-home menu__item--another_home', + 'icon' => 'minerva-another_home', + 'data-event-name' => 'menu.another_home' + ] ], ], ]; @@ -220,23 +155,132 @@ class GroupTest extends MediaWikiIntegrationTestCase { } /** - * @covers ::insert + * @covers ::insertAfter + * @covers ::search + */ + public function testInsertAfterWhenTargetEntryDoesntExist() { + $menu = new Group( 'p-test' ); + $this->expectException( DomainException::class ); + $this->expectExceptionMessage( 'The "home" entry doesn\'t exist.' ); + $menu->insertAfter( + 'home', + 'nearby', + $this->nearbyComponent['text'], + $this->nearbyComponent['href'], + $this->nearbyComponent['class'], + $this->nearbyComponent['icon'] + ); + } + + /** + * @covers ::insertAfter + */ + public function testInsertAfterWithAnEntryWithAnExistingName() { + $menu = new Group( 'p-test' ); + $entryHome = SingleMenuEntry::create( + 'home', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'] + ); + $menu->insertEntry( $entryHome ); + $entryCar = SingleMenuEntry::create( + 'car', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'] + ); + $menu->insertEntry( $entryCar ); + $this->expectException( DomainException::class ); + $this->expectExceptionMessage( 'The "car" entry already exists.' ); + $menu->insertAfter( + 'home', + 'car', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'] + ); + } + + /** + * @covers ::insertEntry + */ + public function testInsertingAnEntryWithAnExistingName() { + $menu = new Group( 'p-test' ); + $entryHome = SingleMenuEntry::create( + 'home', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'] + ); + $menu->insertEntry( $entryHome ); + $this->expectException( DomainException::class ); + $this->expectExceptionMessage( 'The "home" entry already exists.' ); + $menu->insertEntry( $entryHome ); + } + + /** + * @covers ::insertEntry + * @covers ::insertAfter + */ + public function testInsertingAnEntryAfterAnotherOne() { + $menu = new Group( 'p-test' ); + $entryFirst = SingleMenuEntry::create( + 'first', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'] + ); + $menu->insertEntry( $entryFirst ); + + $entryLast = SingleMenuEntry::create( + 'last', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'] + ); + $menu->insertEntry( $entryLast ); + $menu->insertAfter( + 'first', + 'middle', + $this->nearbyComponent['text'], + $this->nearbyComponent['href'], + $this->nearbyComponent['class'], + $this->nearbyComponent['icon'] + ); + $items = $menu->getEntries(); + $this->assertCount( 3, $items ); + $this->assertSame( 'first', $items[0]['name'] ); + $this->assertSame( 'middle', $items[1]['name'] ); + $this->assertSame( 'last', $items[2]['name'] ); + } + + /** + * @covers ::insertEntry * @covers ::getEntries - * @covers \MediaWiki\Minerva\Menu\Entries\MenuEntry::addComponent */ public function testInsertingAJavascriptOnlyEntry() { $menu = new Group( 'p-test' ); - $menu->insert( 'nearby', $isJSOnly = true ) - ->addComponent( - $this->nearbyComponent['text'], - $this->nearbyComponent['href'], - $this->nearbyComponent['class'] - ); + $entryHome = SingleMenuEntry::create( + 'nearby', + $this->nearbyComponent['text'], + $this->nearbyComponent['href'], + $this->nearbyComponent['class'] + ); + $entryHome->setJSOnly(); + $menu->insertEntry( $entryHome ); $expectedEntries = [ [ 'name' => 'nearby', - 'components' => [ $this->nearbyComponent ], + 'components' => [ + [ + 'text' => $this->nearbyComponent['text'], + 'href' => $this->nearbyComponent['href'], + 'class' => 'mw-ui-icon mw-ui-icon-before mw-ui-icon-nearby menu__item--nearby', + 'icon' => 'minerva-nearby' + ] + ], 'class' => 'jsonly' ], ]; @@ -250,11 +294,13 @@ class GroupTest extends MediaWikiIntegrationTestCase { */ public function testGetEntryByName() { $menu = new Group( 'p-test' ); - $menu->insert( 'home' ) - ->addComponent( - $this->homeComponent['text'], - $this->homeComponent['href'] - ); + $entryHome = SingleMenuEntry::create( + 'home', + $this->homeComponent['text'], + $this->homeComponent['href'], + $this->homeComponent['class'] + ); + $menu->insertEntry( $entryHome ); $this->assertInstanceOf( IMenuEntry::class, $menu->getEntryByName( 'home' ) ); }