Issue #1859684 by dawehner, effulgentsia: Expand routeBuilder unit test.
parent
0d263c64e9
commit
b15aed5760
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\Core\Routing;
|
||||
|
||||
use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
|
@ -59,10 +58,7 @@ class MatcherDumper implements MatcherDumperInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds additional routes to be dumped.
|
||||
*
|
||||
* @param Symfony\Component\Routing\RouteCollection $routes
|
||||
* A collection of routes to add to this dumper.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addRoutes(RouteCollection $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;
|
||||
|
||||
use Drupal\Component\Discovery\YamlDiscovery;
|
||||
use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
@ -47,7 +46,14 @@ class RouteBuilder {
|
|||
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
|
||||
*/
|
||||
|
@ -56,12 +62,14 @@ class RouteBuilder {
|
|||
/**
|
||||
* 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.
|
||||
* @param \Drupal\Core\Lock\LockBackendInterface $lock
|
||||
* The lock backend.
|
||||
* @param \Symfony\Component\EventDispatcherEventDispatcherInterface
|
||||
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
|
||||
* 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) {
|
||||
$this->dumper = $dumper;
|
||||
|
@ -72,6 +80,9 @@ class RouteBuilder {
|
|||
|
||||
/**
|
||||
* Rebuilds the route info and dumps to dumper.
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE if the rebuild succeeds, FALSE otherwise.
|
||||
*/
|
||||
public function 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
|
||||
// available, resulting in a 404.
|
||||
$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) {
|
||||
$collection = new RouteCollection();
|
||||
|
@ -111,6 +122,20 @@ class RouteBuilder {
|
|||
$this->dumper->dump(array('route_set' => 'dynamic_routes'));
|
||||
|
||||
$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.
|
||||
*
|
||||
|
|
|
@ -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