Issue #1859684 by dawehner, effulgentsia: Expand routeBuilder unit test.

8.0.x
Nathaniel Catchpole 2013-11-06 19:58:22 +00:00
parent 0d263c64e9
commit b15aed5760
5 changed files with 339 additions and 11 deletions

View File

@ -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)) {

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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.
*

View File

@ -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;
}
}