diff -u b/core/lib/Drupal/Core/Menu/ContextualLinkManager.php b/core/lib/Drupal/Core/Menu/ContextualLinkManager.php --- b/core/lib/Drupal/Core/Menu/ContextualLinkManager.php +++ b/core/lib/Drupal/Core/Menu/ContextualLinkManager.php @@ -13,7 +13,6 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Language\LanguageManager; use Drupal\Core\Plugin\DefaultPluginManager; -use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator; use Drupal\Core\Plugin\Discovery\YamlDiscovery; use Drupal\Core\Plugin\Factory\ContainerFactory; @@ -48,6 +47,13 @@ ); /** + * A controller resolver object. + * + * @var \Symfony\Component\HttpKernel\Controller\ControllerResolverInterface + */ + protected $controllerResolver; + + /** * Constructs a new ContextualLinksManager instance. * * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver only in patch2: unchanged: --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Menu/ContextualLinkManagerTest.php @@ -0,0 +1,269 @@ + 'Contextual links manager.', + 'description' => 'Tests the contextual links manager.', + 'group' => 'Menu', + ); + } + + protected function setUp() { + $this->contextualLinkManager = $this + ->getMockBuilder('Drupal\Core\Menu\ContextualLinkManager') + ->disableOriginalConstructor() + ->setMethods(NULL) + ->getMock(); + + $this->controllerResolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface'); + $this->pluginDiscovery = $this->getMock('Drupal\Component\Plugin\Discovery\DiscoveryInterface'); + $this->factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface'); + $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); + + $property = new \ReflectionProperty('Drupal\Core\Menu\ContextualLinkManager', 'controllerResolver'); + $property->setAccessible(TRUE); + $property->setValue($this->contextualLinkManager, $this->controllerResolver); + + $property = new \ReflectionProperty('Drupal\Core\Menu\ContextualLinkManager', 'discovery'); + $property->setAccessible(TRUE); + $property->setValue($this->contextualLinkManager, $this->pluginDiscovery); + + $property = new \ReflectionProperty('Drupal\Core\Menu\ContextualLinkManager', 'factory'); + $property->setAccessible(TRUE); + $property->setValue($this->contextualLinkManager, $this->factory); + + $language_manager = $this->getMockBuilder('Drupal\Core\Language\LanguageManager') + ->disableOriginalConstructor() + ->getMock(); + $language_manager->expects($this->any()) + ->method('getLanguage') + ->will($this->returnValue(new Language(array('id' => 'en')))); + + $this->contextualLinkManager->setCacheBackend($this->cacheBackend, $language_manager, 'contextual_links_plugins'); + } + + /** + * Tests the getContextualLinkPluginsByGroup method. + * + * @see \Drupal\Core\Menu\ContextualLinkManager::getContextualLinkPluginsByGroup() + */ + public function testGetContextualLinkPluginsByGroup() { + $definitions = array( + 'test_plugin1' => array( + 'id' => 'test_plugin1', + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'group' => 'group1', + 'route_name' => 'test_route', + ), + 'test_plugin2' => array( + 'id' => 'test_plugin2', + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'group' => 'group1', + 'route_name' => 'test_route2', + ), + 'test_plugin3' => array( + 'id' => 'test_plugin3', + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'group' => 'group2', + 'route_name' => 'test_router3', + ), + ); + $this->pluginDiscovery->expects($this->once()) + ->method('getDefinitions') + ->will($this->returnValue($definitions)); + + // Test with a non existing group. + $result = $this->contextualLinkManager->getContextualLinkPluginsByGroup('group_non_existing'); + $this->assertEmpty($result); + + $result = $this->contextualLinkManager->getContextualLinkPluginsByGroup('group1'); + $this->assertEquals(array('test_plugin1', 'test_plugin2'), array_keys($result)); + + $result = $this->contextualLinkManager->getContextualLinkPluginsByGroup('group2'); + $this->assertEquals(array('test_plugin3'), array_keys($result)); + } + + /** + * Tests the getContextualLinkPluginsByGroup with a prefilled cache. + */ + public function testGetContextualLinkPluginsByGroupWithCache() { + $definitions = array( + 'test_plugin1' => array( + 'id' => 'test_plugin1', + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'group' => 'group1', + 'route_name' => 'test_route', + ), + 'test_plugin2' => array( + 'id' => 'test_plugin2', + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'group' => 'group1', + 'route_name' => 'test_route2', + ), + ); + + $this->cacheBackend->expects($this->once()) + ->method('get') + ->with('contextual_links_plugins:en:group1') + ->will($this->returnValue((object) array('data' => $definitions))); + + $result = $this->contextualLinkManager->getContextualLinkPluginsByGroup('group1'); + $this->assertEquals($definitions, $result); + } + + /** + * Tests processDefinition() by passing a plugin definition without a route. + * + * @see \Drupal\Core\Menu\ContextualLinkManager::processDefinition() + * + * @expectedException \Drupal\Component\Plugin\Exception\PluginException + */ + public function testProcessDefinitionWithoutRoute() { + $definition = array( + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'group' => 'example', + 'id' => 'test_plugin', + ); + $this->contextualLinkManager->processDefinition($definition, 'test_plugin'); + } + + /** + * Tests processDefinition() by passing a plugin definition without a group. + * + * @see \Drupal\Core\Menu\ContextualLinkManager::processDefinition() + * + * @expectedException \Drupal\Component\Plugin\Exception\PluginException + */ + public function testProcessDefinitionWithoutGroup() { + $definition = array( + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'route_name' => 'example', + 'id' => 'test_plugin', + ); + $this->contextualLinkManager->processDefinition($definition, 'test_plugin'); + } + + + /** + * Tests the getContextualLinksArrayByGroup method. + * + * @see \Drupal\Core\Menu\ContextualLinkManager::getContextualLinksArrayByGroup() + */ + public function testGetContextualLinksArrayByGroup() { + $definitions = array( + 'test_plugin1' => array( + 'id' => 'test_plugin1', + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'title' => 'Plugin 1', + 'weight' => 0, + 'group' => 'group1', + 'route_name' => 'test_route', + 'options' => array(), + ), + 'test_plugin2' => array( + 'id' => 'test_plugin2', + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'title' => 'Plugin 2', + 'weight' => 2, + 'group' => 'group1', + 'route_name' => 'test_route2', + 'options' => array('key' => 'value'), + ), + 'test_plugin3' => array( + 'id' => 'test_plugin3', + 'class' => '\Drupal\Core\Menu\ContextualLinkDefault', + 'title' => 'Plugin 3', + 'weight' => 5, + 'group' => 'group2', + 'route_name' => 'test_router3', + 'options' => array(), + ), + ); + + $this->pluginDiscovery->expects($this->once()) + ->method('getDefinitions') + ->will($this->returnValue($definitions)); + + $map = array(); + foreach ($definitions as $plugin_id => $definition) { + $plugin = $this->getMock('Drupal\Core\Menu\ContextualLinkInterface'); + $plugin->expects($this->any()) + ->method('getRouteName') + ->will($this->returnValue($definition['route_name'])); + $plugin->expects($this->any()) + ->method('getTitle') + ->will($this->returnValue($definition['title'])); + $plugin->expects($this->any()) + ->method('getWeight') + ->will($this->returnValue($definition['weight'])); + $plugin->expects($this->any()) + ->method('getOptions') + ->will($this->returnValue($definition['options'])); + $map[] = array($plugin_id, array(), $plugin); + } + $this->factory->expects($this->any()) + ->method('createInstance') + ->will($this->returnValueMap($map)); + + $result = $this->contextualLinkManager->getContextualLinksArrayByGroup('group1', array('key' => 'value')); + foreach (array('test_plugin1', 'test_plugin2') as $plugin_id) { + $definition = $definitions[$plugin_id]; + $this->assertEquals($definition['weight'], $result[$plugin_id]['weight']); + $this->assertEquals($definition['title'], $result[$plugin_id]['title']); + $this->assertEquals($definition['route_name'], $result[$plugin_id]['route_name']); + } + } + +}