Skip to content
Snippets Groups Projects
Commit e4221aef authored by Pablo López's avatar Pablo López Committed by Cristina Chumillas
Browse files

Issue #3426283: Add NavigationBlockManager tests

parent b2de0262
Branches
Tags
1 merge request!182Issue #3426283: Add NavigationBlockManager tests
Pipeline #119825 passed with warnings
...@@ -31,7 +31,7 @@ navigation.navigation_block.*: ...@@ -31,7 +31,7 @@ navigation.navigation_block.*:
label: 'Plugin' label: 'Plugin'
constraints: constraints:
PluginExists: PluginExists:
manager: plugin.manager.navigation_block_manager manager: plugin.manager.navigation_block
interface: Drupal\navigation\NavigationBlockPluginInterface interface: Drupal\navigation\NavigationBlockPluginInterface
settings: settings:
type: navigation_block.settings.[%parent.plugin] type: navigation_block.settings.[%parent.plugin]
......
...@@ -218,7 +218,7 @@ function navigation_menu_insert(MenuInterface $menu) { ...@@ -218,7 +218,7 @@ function navigation_menu_insert(MenuInterface $menu) {
// @todo This code should be moved to Drupal\system\Entity\Menu::save() once // @todo This code should be moved to Drupal\system\Entity\Menu::save() once
// Navigation lands in core, in a similar way BlockManager cache is // Navigation lands in core, in a similar way BlockManager cache is
// invalidated there. // invalidated there.
\Drupal::service('plugin.manager.navigation_block_manager') \Drupal::service('plugin.manager.navigation_block')
->clearCachedDefinitions(); ->clearCachedDefinitions();
} }
...@@ -229,7 +229,7 @@ function navigation_menu_update(MenuInterface $menu) { ...@@ -229,7 +229,7 @@ function navigation_menu_update(MenuInterface $menu) {
// @todo This code should be moved to Drupal\system\Entity\Menu::save() once // @todo This code should be moved to Drupal\system\Entity\Menu::save() once
// Navigation lands in core, in a similar way BlockManager cache is // Navigation lands in core, in a similar way BlockManager cache is
// invalidated there. // invalidated there.
\Drupal::service('plugin.manager.navigation_block_manager') \Drupal::service('plugin.manager.navigation_block')
->clearCachedDefinitions(); ->clearCachedDefinitions();
} }
...@@ -240,6 +240,6 @@ function navigation_menu_delete(MenuInterface $menu) { ...@@ -240,6 +240,6 @@ function navigation_menu_delete(MenuInterface $menu) {
// @todo This code should be moved to Drupal\system\Entity\Menu::delete() once // @todo This code should be moved to Drupal\system\Entity\Menu::delete() once
// Navigation lands in core, in a similar way BlockManager cache is // Navigation lands in core, in a similar way BlockManager cache is
// invalidated there. // invalidated there.
\Drupal::service('plugin.manager.navigation_block_manager') \Drupal::service('plugin.manager.navigation_block')
->clearCachedDefinitions(); ->clearCachedDefinitions();
} }
services: services:
plugin.manager.navigation_block_manager: plugin.manager.navigation_block:
class: Drupal\navigation\NavigationBlockManager class: Drupal\navigation\NavigationBlockManager
parent: default_plugin_manager parent: default_plugin_manager
arguments: ['@logger.channel.default'] arguments: ['@logger.channel.default']
Drupal\navigation\NavigationBlockManagerInterface: '@plugin.manager.navigation_block_manager' Drupal\navigation\NavigationBlockManagerInterface: '@plugin.manager.navigation_block'
navigation_block.repository: navigation_block.repository:
class: Drupal\navigation\NavigationBlockRepository class: Drupal\navigation\NavigationBlockRepository
...@@ -17,7 +17,7 @@ services: ...@@ -17,7 +17,7 @@ services:
navigation.menu.invalidator: navigation.menu.invalidator:
class: Drupal\navigation\Cache\SystemMenuNavigationBlockCacheTagInvalidator class: Drupal\navigation\Cache\SystemMenuNavigationBlockCacheTagInvalidator
arguments: [ '@plugin.manager.navigation_block_manager', '@entity_type.manager' ] arguments: [ '@plugin.manager.navigation_block', '@entity_type.manager' ]
public: false public: false
tags: tags:
- { name: cache_tags_invalidator } - { name: cache_tags_invalidator }
......
...@@ -70,7 +70,7 @@ class NavigationBlockLibraryController extends ControllerBase { ...@@ -70,7 +70,7 @@ class NavigationBlockLibraryController extends ControllerBase {
*/ */
public static function create(ContainerInterface $container) { public static function create(ContainerInterface $container) {
return new static( return new static(
$container->get('plugin.manager.navigation_block_manager'), $container->get('plugin.manager.navigation_block'),
$container->get('context.repository'), $container->get('context.repository'),
$container->get('current_route_match'), $container->get('current_route_match'),
$container->get('plugin.manager.menu.local_action') $container->get('plugin.manager.menu.local_action')
......
...@@ -149,7 +149,7 @@ class NavigationBlock extends ConfigEntityBase implements NavigationBlockInterfa ...@@ -149,7 +149,7 @@ class NavigationBlock extends ConfigEntityBase implements NavigationBlockInterfa
*/ */
protected function getPluginCollection() { protected function getPluginCollection() {
if (!$this->pluginCollection) { if (!$this->pluginCollection) {
$this->pluginCollection = new NavigationBlockPluginCollection(\Drupal::service('plugin.manager.navigation_block_manager'), $this->plugin, $this->get('settings'), $this->id()); $this->pluginCollection = new NavigationBlockPluginCollection(\Drupal::service('plugin.manager.navigation_block'), $this->plugin, $this->get('settings'), $this->id());
} }
return $this->pluginCollection; return $this->pluginCollection;
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace Drupal\navigation; namespace Drupal\navigation;
use Drupal\Component\Plugin\FallbackPluginManagerInterface;
use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\CategorizingPluginManagerTrait; use Drupal\Core\Plugin\CategorizingPluginManagerTrait;
...@@ -13,7 +14,7 @@ use Psr\Log\LoggerInterface; ...@@ -13,7 +14,7 @@ use Psr\Log\LoggerInterface;
/** /**
* Defines a navigation block manager. * Defines a navigation block manager.
*/ */
class NavigationBlockManager extends DefaultPluginManager implements NavigationBlockManagerInterface { class NavigationBlockManager extends DefaultPluginManager implements NavigationBlockManagerInterface, FallbackPluginManagerInterface {
use CategorizingPluginManagerTrait { use CategorizingPluginManagerTrait {
getSortedDefinitions as traitGetSortedDefinitions; getSortedDefinitions as traitGetSortedDefinitions;
......
<?php
declare(strict_types=1);
namespace Drupal\navigation\Plugin\NavigationBlock;
use Drupal\Core\Block\BlockPluginTrait;
use Drupal\Core\Cache\CacheableDependencyTrait;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\navigation\Attribute\NavigationBlock;
use Drupal\navigation\NavigationBlockPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a fallback plugin for missing navigation block plugins.
*/
#[NavigationBlock(
id: "broken",
admin_label: new TranslatableMarkup("Broken/Missing"),
category: new TranslatableMarkup("Navigation")
)]
class Broken extends PluginBase implements NavigationBlockPluginInterface, ContainerFactoryPluginInterface {
use BlockPluginTrait;
use CacheableDependencyTrait;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected AccountInterface $currentUser;
/**
* Creates a Broken Block instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, AccountInterface $current_user) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_user')
);
}
/**
* {@inheritdoc}
*/
public function build(): array {
$build = [];
if ($this->currentUser->hasPermission('administer blocks')) {
$build += $this->brokenMessage();
}
return $build;
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state):array {
return $this->brokenMessage();
}
/**
* Generate message with debug info as to why the navigation block is broken.
*
* @return array
* Render array containing debug information.
*/
protected function brokenMessage(): array {
$build['message'] = [
'#markup' => $this->t('This navigation block is broken or missing. You may be missing content or you might need to install the original module.'),
];
return $build;
}
}
...@@ -99,7 +99,7 @@ class SystemMenuNavigationBlockTest extends KernelTestBase { ...@@ -99,7 +99,7 @@ class SystemMenuNavigationBlockTest extends KernelTestBase {
$this->menuLinkManager = $this->container->get('plugin.manager.menu.link'); $this->menuLinkManager = $this->container->get('plugin.manager.menu.link');
$this->linkTree = $this->container->get('menu.link_tree'); $this->linkTree = $this->container->get('menu.link_tree');
$this->navigationBlockManager = $this->container->get('plugin.manager.navigation_block_manager'); $this->navigationBlockManager = $this->container->get('plugin.manager.navigation_block');
$routes = new RouteCollection(); $routes = new RouteCollection();
$requirements = ['_access' => 'TRUE']; $requirements = ['_access' => 'TRUE'];
......
<?php
declare(strict_types=1);
namespace Drupal\Tests\navigation\Unit;
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\navigation\NavigationBlockManager;
use Drupal\navigation\NavigationBlockManagerInterface;
use Drupal\navigation\Plugin\NavigationBlock\Broken;
use Drupal\Tests\UnitTestCase;
use Psr\Log\LoggerInterface;
/**
* @coversDefaultClass \Drupal\navigation\NavigationBlockManager
*
* @group navigation
*/
class NavigationBlockManagerTest extends UnitTestCase {
use StringTranslationTrait;
/**
* The block manager under test.
*
* @var \Drupal\navigation\NavigationBlockManagerInterface
*/
protected NavigationBlockManagerInterface $navigationBlockManager;
/**
* The logger.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$container = new ContainerBuilder();
$current_user = $this->prophesize(AccountInterface::class);
$container->set('current_user', $current_user->reveal());
$container->set('string_translation', $this->getStringTranslationStub());
\Drupal::setContainer($container);
$cache_backend = $this->prophesize(CacheBackendInterface::class);
$module_handler = $this->prophesize(ModuleHandlerInterface::class);
$this->logger = $this->prophesize(LoggerInterface::class);
$this->navigationBlockManager = new NavigationBlockManager(new \ArrayObject(), $cache_backend->reveal(), $module_handler->reveal(), $this->logger->reveal());
$this->navigationBlockManager->setStringTranslation($this->getStringTranslationStub());
$discovery = $this->prophesize(DiscoveryInterface::class);
// Specify the 'broken' block, as well as 3 other blocks with admin labels
// that are purposefully not in alphabetical order.
$discovery->getDefinitions()->willReturn([
'broken' => [
'admin_label' => $this->t('Broken/Missing'),
'category' => $this->t('Block'),
'class' => Broken::class,
'provider' => 'core',
],
'block1' => [
'admin_label' => $this->t('Coconut'),
'category' => $this->t('Group 2'),
],
'block2' => [
'admin_label' => $this->t('Apple'),
'category' => $this->t('Group 1'),
],
'block3' => [
'admin_label' => $this->t('Banana'),
'category' => $this->t('Group 2'),
],
]);
// Force the discovery object onto the block manager.
$property = new \ReflectionProperty(NavigationBlockManager::class, 'discovery');
$property->setValue($this->navigationBlockManager, $discovery->reveal());
}
/**
* @covers ::getDefinitions
*/
public function testDefinitions() {
$definitions = $this->navigationBlockManager->getDefinitions();
$this->assertSame(['broken', 'block1', 'block2', 'block3'], array_keys($definitions));
}
/**
* @covers ::getSortedDefinitions
*/
public function testSortedDefinitions() {
$definitions = $this->navigationBlockManager->getSortedDefinitions();
$this->assertSame(['block2', 'block3', 'block1'], array_keys($definitions));
}
/**
* @covers ::getGroupedDefinitions
*/
public function testGroupedDefinitions() {
$definitions = $this->navigationBlockManager->getGroupedDefinitions();
$this->assertSame(['Group 1', 'Group 2'], array_keys($definitions));
$this->assertSame(['block2'], array_keys($definitions['Group 1']));
$this->assertSame(['block3', 'block1'], array_keys($definitions['Group 2']));
}
/**
* @covers ::handlePluginNotFound
*/
public function testHandlePluginNotFound() {
$this->logger->warning('The "%plugin_id" was not found', ['%plugin_id' => 'invalid'])->shouldBeCalled();
$plugin = $this->navigationBlockManager->createInstance('invalid');
$this->assertSame('broken', $plugin->getPluginId());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment