Issue #1859684 by dawehner, effulgentsia: Expand routeBuilder unit test.
parent
0d263c64e9
commit
b15aed5760
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace Drupal\Core\Routing;
|
namespace Drupal\Core\Routing;
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
|
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
use Drupal\Core\Database\Connection;
|
use Drupal\Core\Database\Connection;
|
||||||
|
@ -59,10 +58,7 @@ class MatcherDumper implements MatcherDumperInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds additional routes to be dumped.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param Symfony\Component\Routing\RouteCollection $routes
|
|
||||||
* A collection of routes to add to this dumper.
|
|
||||||
*/
|
*/
|
||||||
public function addRoutes(RouteCollection $routes) {
|
public function addRoutes(RouteCollection $routes) {
|
||||||
if (empty($this->routes)) {
|
if (empty($this->routes)) {
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Core\Routing\MatcherDumperInterface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\Routing;
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface as SymfonyMatcherDumperInterface;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extends the symfony matcher dumper interface with a addRoutes method.
|
||||||
|
*/
|
||||||
|
interface MatcherDumperInterface extends SymfonyMatcherDumperInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds additional routes to be dumped.
|
||||||
|
*
|
||||||
|
* @param \Symfony\Component\Routing\RouteCollection $routes
|
||||||
|
* A collection of routes to add to this dumper.
|
||||||
|
*/
|
||||||
|
public function addRoutes(RouteCollection $routes);
|
||||||
|
|
||||||
|
}
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Drupal\Core\Routing;
|
namespace Drupal\Core\Routing;
|
||||||
|
|
||||||
use Drupal\Component\Discovery\YamlDiscovery;
|
use Drupal\Component\Discovery\YamlDiscovery;
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
|
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\Yaml\Parser;
|
use Symfony\Component\Yaml\Parser;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
@ -47,7 +46,14 @@ class RouteBuilder {
|
||||||
protected $dispatcher;
|
protected $dispatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The extension handler for retieving the list of enabled modules.
|
* The yaml discovery used to find all the .routing.yml files.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Component\Discovery\YamlDiscovery
|
||||||
|
*/
|
||||||
|
protected $yamlDiscovery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The module handler.
|
||||||
*
|
*
|
||||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||||
*/
|
*/
|
||||||
|
@ -56,12 +62,14 @@ class RouteBuilder {
|
||||||
/**
|
/**
|
||||||
* Construcs the RouteBuilder using the passed MatcherDumperInterface.
|
* Construcs the RouteBuilder using the passed MatcherDumperInterface.
|
||||||
*
|
*
|
||||||
* @param \Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface $dumper
|
* @param \Drupal\Core\Routing\MatcherDumperInterface $dumper
|
||||||
* The matcher dumper used to store the route information.
|
* The matcher dumper used to store the route information.
|
||||||
* @param \Drupal\Core\Lock\LockBackendInterface $lock
|
* @param \Drupal\Core\Lock\LockBackendInterface $lock
|
||||||
* The lock backend.
|
* The lock backend.
|
||||||
* @param \Symfony\Component\EventDispatcherEventDispatcherInterface
|
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
|
||||||
* The event dispatcher to notify of routes.
|
* The event dispatcher to notify of routes.
|
||||||
|
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||||
|
* The module handler.
|
||||||
*/
|
*/
|
||||||
public function __construct(MatcherDumperInterface $dumper, LockBackendInterface $lock, EventDispatcherInterface $dispatcher, ModuleHandlerInterface $module_handler) {
|
public function __construct(MatcherDumperInterface $dumper, LockBackendInterface $lock, EventDispatcherInterface $dispatcher, ModuleHandlerInterface $module_handler) {
|
||||||
$this->dumper = $dumper;
|
$this->dumper = $dumper;
|
||||||
|
@ -72,6 +80,9 @@ class RouteBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebuilds the route info and dumps to dumper.
|
* Rebuilds the route info and dumps to dumper.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* Returns TRUE if the rebuild succeeds, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
public function rebuild() {
|
public function rebuild() {
|
||||||
if (!$this->lock->acquire('router_rebuild')) {
|
if (!$this->lock->acquire('router_rebuild')) {
|
||||||
|
@ -79,10 +90,10 @@ class RouteBuilder {
|
||||||
// We choose to block here since otherwise the routes might not be
|
// We choose to block here since otherwise the routes might not be
|
||||||
// available, resulting in a 404.
|
// available, resulting in a 404.
|
||||||
$this->lock->wait('router_rebuild');
|
$this->lock->wait('router_rebuild');
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$yaml_discovery = new YamlDiscovery('routing', $this->moduleHandler->getModuleDirectories());
|
$yaml_discovery = $this->getYamlDiscovery();
|
||||||
|
|
||||||
foreach ($yaml_discovery->findAll() as $module => $routes) {
|
foreach ($yaml_discovery->findAll() as $module => $routes) {
|
||||||
$collection = new RouteCollection();
|
$collection = new RouteCollection();
|
||||||
|
@ -111,6 +122,20 @@ class RouteBuilder {
|
||||||
$this->dumper->dump(array('route_set' => 'dynamic_routes'));
|
$this->dumper->dump(array('route_set' => 'dynamic_routes'));
|
||||||
|
|
||||||
$this->lock->release('router_rebuild');
|
$this->lock->release('router_rebuild');
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the YAML discovery for getting all the .routing.yml files.
|
||||||
|
*
|
||||||
|
* @return \Drupal\Component\Discovery\YamlDiscovery
|
||||||
|
* The yaml discovery.
|
||||||
|
*/
|
||||||
|
protected function getYamlDiscovery() {
|
||||||
|
if (!isset($this->yamlDiscovery)) {
|
||||||
|
$this->yamlDiscovery = new YamlDiscovery('routing', $this->moduleHandler->getModuleDirectories());
|
||||||
|
}
|
||||||
|
return $this->yamlDiscovery;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,44 @@ class RoutingFixtures {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a static version of the routes.
|
||||||
|
*/
|
||||||
|
public function staticSampleRouteCollection() {
|
||||||
|
$routes = array();
|
||||||
|
$routes['route_a'] = array(
|
||||||
|
'path' => '/path/one',
|
||||||
|
'requirements' => array(
|
||||||
|
'_method' => 'GET',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$routes['route_b'] = array(
|
||||||
|
'path' => '/path/one',
|
||||||
|
'requirements' => array(
|
||||||
|
'_method' => 'PUT',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$routes['route_c'] = array(
|
||||||
|
'path' => '/path/two',
|
||||||
|
'requirements' => array(
|
||||||
|
'_method' => 'GET',
|
||||||
|
'_format' => 'json'
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$routes['route_d'] = array(
|
||||||
|
'path' => '/path/three',
|
||||||
|
);
|
||||||
|
$routes['route_e'] = array(
|
||||||
|
'path' => '/path/two',
|
||||||
|
'requirements' => array(
|
||||||
|
'_method' => 'GET|HEAD',
|
||||||
|
'_format' => 'html'
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $routes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a standard set of routes for testing.
|
* Returns a standard set of routes for testing.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Tests\Core\Routing\RouteBuilderTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Tests\Core\Routing;
|
||||||
|
|
||||||
|
use Drupal\Component\Discovery\YamlDiscovery;
|
||||||
|
use Drupal\Core\Routing\RouteBuilder;
|
||||||
|
use Drupal\Core\Routing\RouteBuildEvent;
|
||||||
|
use Drupal\Core\Routing\RoutingEvents;
|
||||||
|
use Drupal\system\Tests\Routing\RoutingFixtures;
|
||||||
|
use Drupal\Tests\UnitTestCase;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the route builder.
|
||||||
|
*
|
||||||
|
* @group Drupal
|
||||||
|
* @group Routing
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\Routing\RouteBuilder
|
||||||
|
*/
|
||||||
|
class RouteBuilderTest extends UnitTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual tested route builder.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Routing\RouteBuilder
|
||||||
|
*/
|
||||||
|
protected $routeBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mocked matcher dumper.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Routing\MatcherDumperInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
protected $dumper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mocked lock backend.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
protected $lock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mocked event dispatcher.
|
||||||
|
*
|
||||||
|
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
protected $dispatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mocked yaml discovery.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Component\Discovery\YamlDiscovery|\PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
protected $yamlDiscovery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The module handler.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||||
|
*/
|
||||||
|
protected $moduleHandler;
|
||||||
|
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'Route Builder',
|
||||||
|
'description' => 'Tests the route builder.',
|
||||||
|
'group' => 'Routing',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp() {
|
||||||
|
$this->dumper = $this->getMock('Drupal\Core\Routing\MatcherDumperInterface');
|
||||||
|
$this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
|
||||||
|
$this->dispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||||
|
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
|
||||||
|
$this->yamlDiscovery = $this->getMockBuilder('\Drupal\Component\Discovery\YamlDiscovery')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$this->routeBuilder = new TestRouteBuilder($this->dumper, $this->lock, $this->dispatcher, $this->moduleHandler);
|
||||||
|
$this->routeBuilder->setYamlDiscovery($this->yamlDiscovery);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that the route rebuilding both locks and unlocks.
|
||||||
|
*/
|
||||||
|
public function testRebuildLockingUnlocking() {
|
||||||
|
$this->lock->expects($this->once())
|
||||||
|
->method('acquire')
|
||||||
|
->with('router_rebuild')
|
||||||
|
->will($this->returnValue(TRUE));
|
||||||
|
|
||||||
|
$this->lock->expects($this->once())
|
||||||
|
->method('release')
|
||||||
|
->with('router_rebuild');
|
||||||
|
|
||||||
|
$this->yamlDiscovery->expects($this->any())
|
||||||
|
->method('findAll')
|
||||||
|
->will($this->returnValue(array()));
|
||||||
|
|
||||||
|
$this->assertTrue($this->routeBuilder->rebuild());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests route rebuilding with a blocking lock.
|
||||||
|
*/
|
||||||
|
public function testRebuildBlockingLock() {
|
||||||
|
$this->lock->expects($this->once())
|
||||||
|
->method('acquire')
|
||||||
|
->with('router_rebuild')
|
||||||
|
->will($this->returnValue(FALSE));
|
||||||
|
|
||||||
|
$this->lock->expects($this->once())
|
||||||
|
->method('wait')
|
||||||
|
->with('router_rebuild');
|
||||||
|
|
||||||
|
$this->lock->expects($this->never())
|
||||||
|
->method('release');
|
||||||
|
|
||||||
|
$this->yamlDiscovery->expects($this->never())
|
||||||
|
->method('findAll');
|
||||||
|
|
||||||
|
$this->assertFalse($this->routeBuilder->rebuild());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that provided routes by a module is put into the dumper/dispatcher.
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\Routing\RouteBuilder::rebuild()
|
||||||
|
*/
|
||||||
|
public function testRebuildWithStaticModuleRoutes() {
|
||||||
|
$this->lock->expects($this->once())
|
||||||
|
->method('acquire')
|
||||||
|
->with('router_rebuild')
|
||||||
|
->will($this->returnValue(TRUE));
|
||||||
|
|
||||||
|
$routing_fixtures = new RoutingFixtures();
|
||||||
|
$routes = $routing_fixtures->staticSampleRouteCollection();
|
||||||
|
|
||||||
|
$this->yamlDiscovery->expects($this->once())
|
||||||
|
->method('findAll')
|
||||||
|
->will($this->returnValue(array('test_module' => $routes)));
|
||||||
|
|
||||||
|
// Ensure that the dispatch events for altering are fired.
|
||||||
|
$this->dispatcher->expects($this->at(0))
|
||||||
|
->method('dispatch')
|
||||||
|
->with($this->equalTo(RoutingEvents::ALTER), $this->isInstanceOf('Drupal\Core\Routing\RouteBuildEvent'));
|
||||||
|
|
||||||
|
$empty_collection = new RouteCollection();
|
||||||
|
$route_build_event = new RouteBuildEvent($empty_collection, 'dynamic_routes');
|
||||||
|
|
||||||
|
// Ensure that the dynamic routes events are fired.
|
||||||
|
$this->dispatcher->expects($this->at(1))
|
||||||
|
->method('dispatch')
|
||||||
|
->with(RoutingEvents::DYNAMIC, $route_build_event);
|
||||||
|
|
||||||
|
$this->dispatcher->expects($this->at(2))
|
||||||
|
->method('dispatch')
|
||||||
|
->with(RoutingEvents::ALTER, $route_build_event);
|
||||||
|
|
||||||
|
// Ensure that the routes are set to the dumper and dumped.
|
||||||
|
$this->dumper->expects($this->at(0))
|
||||||
|
->method('addRoutes')
|
||||||
|
->with($routing_fixtures->sampleRouteCollection());
|
||||||
|
$this->dumper->expects($this->at(1))
|
||||||
|
->method('dump')
|
||||||
|
->with(array('route_set' => 'test_module'));
|
||||||
|
$this->dumper->expects($this->at(2))
|
||||||
|
->method('addRoutes')
|
||||||
|
->with($empty_collection);
|
||||||
|
$this->dumper->expects($this->at(3))
|
||||||
|
->method('dump')
|
||||||
|
->with(array('route_set' => 'dynamic_routes'));
|
||||||
|
|
||||||
|
|
||||||
|
$this->assertTrue($this->routeBuilder->rebuild());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the rebuild with some dynamic routes.
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\Routing\RouteBuilder::rebuild()
|
||||||
|
*/
|
||||||
|
public function testRebuildWithDynamicRoutes() {
|
||||||
|
$this->lock->expects($this->once())
|
||||||
|
->method('acquire')
|
||||||
|
->with('router_rebuild')
|
||||||
|
->will($this->returnValue(TRUE));
|
||||||
|
|
||||||
|
$this->yamlDiscovery->expects($this->once())
|
||||||
|
->method('findAll')
|
||||||
|
->will($this->returnValue(array()));
|
||||||
|
|
||||||
|
$route_collection_filled = new RouteCollection();
|
||||||
|
$route_collection_filled->add('test_route', new Route('/test-route'));
|
||||||
|
|
||||||
|
$this->dispatcher->expects($this->at(0))
|
||||||
|
->method('dispatch')
|
||||||
|
->with($this->equalTo(RoutingEvents::DYNAMIC))
|
||||||
|
->will($this->returnCallback(function ($object, RouteBuildEvent $event) {
|
||||||
|
$event->getRouteCollection()->add('test_route', new Route('/test-route'));
|
||||||
|
}));
|
||||||
|
|
||||||
|
$this->dispatcher->expects($this->at(1))
|
||||||
|
->method('dispatch')
|
||||||
|
->with($this->equalTo(RoutingEvents::ALTER));
|
||||||
|
|
||||||
|
$this->dumper->expects($this->once())
|
||||||
|
->method('addRoutes')
|
||||||
|
->with($route_collection_filled);
|
||||||
|
$this->dumper->expects($this->once())
|
||||||
|
->method('dump')
|
||||||
|
->with(array('route_set' => 'dynamic_routes'));
|
||||||
|
|
||||||
|
$this->assertTrue($this->routeBuilder->rebuild());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extends the core route builder with a setter method for the yaml discovery.
|
||||||
|
*/
|
||||||
|
class TestRouteBuilder extends RouteBuilder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the yaml discovery.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Component\Discovery\YamlDiscovery $yaml_discovery
|
||||||
|
* The yaml discovery to set.
|
||||||
|
*/
|
||||||
|
public function setYamlDiscovery(YamlDiscovery $yaml_discovery) {
|
||||||
|
$this->yamlDiscovery = $yaml_discovery;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue