View source
<?php
namespace Drupal\Tests\Core\Routing;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Discovery\YamlDiscovery;
use Drupal\Core\Routing\RouteBuilder;
use Drupal\Core\Routing\RouteBuildEvent;
use Drupal\Core\Routing\RouteCompiler;
use Drupal\Core\Routing\RoutingEvents;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
class RouteBuilderTest extends UnitTestCase {
protected $routeBuilder;
protected $dumper;
protected $lock;
protected $dispatcher;
protected $yamlDiscovery;
protected $moduleHandler;
protected $controllerResolver;
protected $checkProvider;
protected function setUp() {
$this->dumper = $this
->createMock('Drupal\\Core\\Routing\\MatcherDumperInterface');
$this->lock = $this
->createMock('Drupal\\Core\\Lock\\LockBackendInterface');
$this->dispatcher = $this
->createMock('\\Symfony\\Component\\EventDispatcher\\EventDispatcherInterface');
$this->moduleHandler = $this
->createMock('Drupal\\Core\\Extension\\ModuleHandlerInterface');
$this->controllerResolver = $this
->createMock('Drupal\\Core\\Controller\\ControllerResolverInterface');
$this->yamlDiscovery = $this
->getMockBuilder('\\Drupal\\Core\\Discovery\\YamlDiscovery')
->disableOriginalConstructor()
->getMock();
$this->checkProvider = $this
->createMock('\\Drupal\\Core\\Access\\CheckProviderInterface');
$this->routeBuilder = new TestRouteBuilder($this->dumper, $this->lock, $this->dispatcher, $this->moduleHandler, $this->controllerResolver, $this->checkProvider);
$this->routeBuilder
->setYamlDiscovery($this->yamlDiscovery);
}
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([]));
$this
->assertTrue($this->routeBuilder
->rebuild());
}
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());
}
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([
'test_module' => $routes,
]));
$route_collection = $routing_fixtures
->sampleRouteCollection();
foreach ($route_collection
->all() as $route) {
$route
->setOption('compiler_class', RouteCompiler::class);
}
$route_build_event = new RouteBuildEvent($route_collection);
$this->dispatcher
->expects($this
->at(0))
->method('dispatch')
->with(RoutingEvents::DYNAMIC, $route_build_event);
$this->dispatcher
->expects($this
->at(1))
->method('dispatch')
->with(RoutingEvents::ALTER, $route_build_event);
$this->checkProvider
->expects($this
->once())
->method('setChecks')
->with($route_collection);
$this->dumper
->expects($this
->at(0))
->method('addRoutes')
->with($route_collection);
$this->dumper
->expects($this
->at(1))
->method('dump')
->with();
$this
->assertTrue($this->routeBuilder
->rebuild());
}
public function testRebuildWithProviderBasedRoutes() {
$this->lock
->expects($this
->once())
->method('acquire')
->with('router_rebuild')
->will($this
->returnValue(TRUE));
$this->yamlDiscovery
->expects($this
->once())
->method('findAll')
->will($this
->returnValue([
'test_module' => [
'route_callbacks' => [
'\\Drupal\\Tests\\Core\\Routing\\TestRouteSubscriber::routesFromArray',
'test_module.route_service:routesFromCollection',
],
],
]));
$container = new ContainerBuilder();
$container
->set('test_module.route_service', new TestRouteSubscriber());
$this->controllerResolver
->expects($this
->any())
->method('getControllerFromDefinition')
->will($this
->returnCallback(function ($controller) use ($container) {
$count = substr_count($controller, ':');
if ($count == 1) {
list($service, $method) = explode(':', $controller, 2);
$object = $container
->get($service);
}
else {
list($class, $method) = explode('::', $controller, 2);
$object = new $class();
}
return [
$object,
$method,
];
}));
$route_collection_filled = new RouteCollection();
$route_collection_filled
->add('test_route.1', new Route('/test-route/1'));
$route_collection_filled
->add('test_route.2', new Route('/test-route/2'));
$route_build_event = new RouteBuildEvent($route_collection_filled);
$this->dispatcher
->expects($this
->at(0))
->method('dispatch')
->with(RoutingEvents::DYNAMIC, $route_build_event);
$this->dispatcher
->expects($this
->at(1))
->method('dispatch')
->with(RoutingEvents::ALTER, $route_build_event);
$this->checkProvider
->expects($this
->once())
->method('setChecks')
->with($route_collection_filled);
$this->dumper
->expects($this
->at(0))
->method('addRoutes')
->with($route_collection_filled);
$this->dumper
->expects($this
->at(1))
->method('dump');
$this
->assertTrue($this->routeBuilder
->rebuild());
}
public function testRebuildIfNeeded() {
$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([]));
$this->routeBuilder
->setRebuildNeeded();
$this
->assertTrue($this->routeBuilder
->rebuildIfNeeded());
$this
->assertFalse($this->routeBuilder
->rebuildIfNeeded());
}
public function testRebuildWithOverriddenRouteClass() {
$this->lock
->expects($this
->once())
->method('acquire')
->with('router_rebuild')
->will($this
->returnValue(TRUE));
$this->yamlDiscovery
->expects($this
->once())
->method('findAll')
->will($this
->returnValue([
'test_module' => [
'test_route.override' => [
'path' => '/test_route_override',
'options' => [
'compiler_class' => 'Class\\Does\\Not\\Exist',
],
],
'test_route' => [
'path' => '/test_route',
],
],
]));
$container = new ContainerBuilder();
$container
->set('test_module.route_service', new TestRouteSubscriber());
$route_collection_filled = new RouteCollection();
$route_collection_filled
->add('test_route.override', new Route('/test_route_override', [], [], [
'compiler_class' => 'Class\\Does\\Not\\Exist',
]));
$route_collection_filled
->add('test_route', new Route('/test_route', [], [], [
'compiler_class' => RouteCompiler::class,
]));
$route_build_event = new RouteBuildEvent($route_collection_filled);
$this->dispatcher
->expects($this
->at(0))
->method('dispatch')
->with(RoutingEvents::DYNAMIC, $route_build_event);
$this
->assertTrue($this->routeBuilder
->rebuild());
}
}
class TestRouteBuilder extends RouteBuilder {
protected $yamlDiscovery;
public function setYamlDiscovery(YamlDiscovery $yaml_discovery) {
$this->yamlDiscovery = $yaml_discovery;
}
protected function getRouteDefinitions() {
return $this->yamlDiscovery
->findAll();
}
}
class TestRouteSubscriber {
public function routesFromArray() {
return [
'test_route.1' => new Route('/test-route/1'),
];
}
public function routesFromCollection() {
$collection = new RouteCollection();
$collection
->add('test_route.2', new Route('/test-route/2'));
return $collection;
}
}