More updates to stop using dev or alpha or beta versions.
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Routing / RouteBuilderTest.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Tests\Core\Routing\RouteBuilderTest.
6  */
7
8 namespace Drupal\Tests\Core\Routing;
9
10 use Drupal\Core\DependencyInjection\ContainerBuilder;
11 use Drupal\Core\Discovery\YamlDiscovery;
12 use Drupal\Core\Routing\RouteBuilder;
13 use Drupal\Core\Routing\RouteBuildEvent;
14 use Drupal\Core\Routing\RoutingEvents;
15 use Drupal\Tests\UnitTestCase;
16 use Symfony\Component\Routing\Route;
17 use Symfony\Component\Routing\RouteCollection;
18
19 /**
20  * @coversDefaultClass \Drupal\Core\Routing\RouteBuilder
21  * @group Routing
22  */
23 class RouteBuilderTest extends UnitTestCase {
24
25   /**
26    * The actual tested route builder.
27    *
28    * @var \Drupal\Core\Routing\RouteBuilder
29    */
30   protected $routeBuilder;
31
32   /**
33    * The mocked matcher dumper.
34    *
35    * @var \Drupal\Core\Routing\MatcherDumperInterface|\PHPUnit_Framework_MockObject_MockObject
36    */
37   protected $dumper;
38
39   /**
40    * The mocked lock backend.
41    *
42    * @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit_Framework_MockObject_MockObject
43    */
44   protected $lock;
45
46   /**
47    * The mocked event dispatcher.
48    *
49    * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject
50    */
51   protected $dispatcher;
52
53   /**
54    * The mocked YAML discovery.
55    *
56    * @var \Drupal\Core\Discovery\YamlDiscovery|\PHPUnit_Framework_MockObject_MockObject
57    */
58   protected $yamlDiscovery;
59
60   /**
61    * The module handler.
62    *
63    * @var \Drupal\Core\Extension\ModuleHandlerInterface
64    */
65   protected $moduleHandler;
66
67   /**
68    * The controller resolver.
69    *
70    * @var \Drupal\Core\Controller\ControllerResolverInterface|\PHPUnit_Framework_MockObject_MockObject
71    */
72   protected $controllerResolver;
73
74   /**
75    * @var \Drupal\Core\Access\CheckProviderInterface|\PHPUnit_Framework_MockObject_MockObject
76    */
77   protected $checkProvider;
78
79   protected function setUp() {
80     $this->dumper = $this->getMock('Drupal\Core\Routing\MatcherDumperInterface');
81     $this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
82     $this->dispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
83     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
84     $this->controllerResolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface');
85     $this->yamlDiscovery = $this->getMockBuilder('\Drupal\Core\Discovery\YamlDiscovery')
86       ->disableOriginalConstructor()
87       ->getMock();
88     $this->checkProvider = $this->getMock('\Drupal\Core\Access\CheckProviderInterface');
89
90     $this->routeBuilder = new TestRouteBuilder($this->dumper, $this->lock, $this->dispatcher, $this->moduleHandler, $this->controllerResolver, $this->checkProvider);
91     $this->routeBuilder->setYamlDiscovery($this->yamlDiscovery);
92   }
93
94   /**
95    * Tests that the route rebuilding both locks and unlocks.
96    */
97   public function testRebuildLockingUnlocking() {
98     $this->lock->expects($this->once())
99       ->method('acquire')
100       ->with('router_rebuild')
101       ->will($this->returnValue(TRUE));
102
103     $this->lock->expects($this->once())
104       ->method('release')
105       ->with('router_rebuild');
106
107     $this->yamlDiscovery->expects($this->any())
108       ->method('findAll')
109       ->will($this->returnValue([]));
110
111     $this->assertTrue($this->routeBuilder->rebuild());
112   }
113
114   /**
115    * Tests route rebuilding with a blocking lock.
116    */
117   public function testRebuildBlockingLock() {
118     $this->lock->expects($this->once())
119       ->method('acquire')
120       ->with('router_rebuild')
121       ->will($this->returnValue(FALSE));
122
123     $this->lock->expects($this->once())
124       ->method('wait')
125       ->with('router_rebuild');
126
127     $this->lock->expects($this->never())
128       ->method('release');
129
130     $this->yamlDiscovery->expects($this->never())
131       ->method('findAll');
132
133     $this->assertFalse($this->routeBuilder->rebuild());
134   }
135
136   /**
137    * Tests that provided routes by a module is put into the dumper/dispatcher.
138    *
139    * @see \Drupal\Core\Routing\RouteBuilder::rebuild()
140    */
141   public function testRebuildWithStaticModuleRoutes() {
142     $this->lock->expects($this->once())
143       ->method('acquire')
144       ->with('router_rebuild')
145       ->will($this->returnValue(TRUE));
146
147     $routing_fixtures = new RoutingFixtures();
148     $routes = $routing_fixtures->staticSampleRouteCollection();
149
150     $this->yamlDiscovery->expects($this->once())
151       ->method('findAll')
152       ->will($this->returnValue(['test_module' => $routes]));
153
154     $route_collection = $routing_fixtures->sampleRouteCollection();
155     $route_build_event = new RouteBuildEvent($route_collection);
156
157     // Ensure that the alter routes events are fired.
158     $this->dispatcher->expects($this->at(0))
159       ->method('dispatch')
160       ->with(RoutingEvents::DYNAMIC, $route_build_event);
161
162     $this->dispatcher->expects($this->at(1))
163       ->method('dispatch')
164       ->with(RoutingEvents::ALTER, $route_build_event);
165
166     // Ensure that access checks are set.
167     $this->checkProvider->expects($this->once())
168       ->method('setChecks')
169       ->with($route_collection);
170
171     // Ensure that the routes are set to the dumper and dumped.
172     $this->dumper->expects($this->at(0))
173       ->method('addRoutes')
174       ->with($route_collection);
175     $this->dumper->expects($this->at(1))
176       ->method('dump')
177       ->with();
178
179     $this->assertTrue($this->routeBuilder->rebuild());
180   }
181
182   /**
183    * Tests the rebuild with routes provided by a callback.
184    *
185    * @see \Drupal\Core\Routing\RouteBuilder::rebuild()
186    */
187   public function testRebuildWithProviderBasedRoutes() {
188     $this->lock->expects($this->once())
189       ->method('acquire')
190       ->with('router_rebuild')
191       ->will($this->returnValue(TRUE));
192
193     $this->yamlDiscovery->expects($this->once())
194       ->method('findAll')
195       ->will($this->returnValue([
196         'test_module' => [
197           'route_callbacks' => [
198             '\Drupal\Tests\Core\Routing\TestRouteSubscriber::routesFromArray',
199             'test_module.route_service:routesFromCollection',
200           ],
201         ],
202       ]));
203
204     $container = new ContainerBuilder();
205     $container->set('test_module.route_service', new TestRouteSubscriber());
206     $this->controllerResolver->expects($this->any())
207       ->method('getControllerFromDefinition')
208       ->will($this->returnCallback(function ($controller) use ($container) {
209         $count = substr_count($controller, ':');
210         if ($count == 1) {
211           list($service, $method) = explode(':', $controller, 2);
212           $object = $container->get($service);
213         }
214         else {
215           list($class, $method) = explode('::', $controller, 2);
216           $object = new $class();
217         }
218         return [$object, $method];
219       }));
220
221     $route_collection_filled = new RouteCollection();
222     $route_collection_filled->add('test_route.1', new Route('/test-route/1'));
223     $route_collection_filled->add('test_route.2', new Route('/test-route/2'));
224
225     $route_build_event = new RouteBuildEvent($route_collection_filled);
226
227     // Ensure that the alter routes events are fired.
228     $this->dispatcher->expects($this->at(0))
229       ->method('dispatch')
230       ->with(RoutingEvents::DYNAMIC, $route_build_event);
231
232     $this->dispatcher->expects($this->at(1))
233       ->method('dispatch')
234       ->with(RoutingEvents::ALTER, $route_build_event);
235
236     // Ensure that access checks are set.
237     $this->checkProvider->expects($this->once())
238       ->method('setChecks')
239       ->with($route_collection_filled);
240
241     // Ensure that the routes are set to the dumper and dumped.
242     $this->dumper->expects($this->at(0))
243       ->method('addRoutes')
244       ->with($route_collection_filled);
245     $this->dumper->expects($this->at(1))
246       ->method('dump');
247
248     $this->assertTrue($this->routeBuilder->rebuild());
249   }
250
251   /**
252    * Tests \Drupal\Core\Routing\RouteBuilder::rebuildIfNeeded() method.
253    */
254   public function testRebuildIfNeeded() {
255     $this->lock->expects($this->once())
256       ->method('acquire')
257       ->with('router_rebuild')
258       ->will($this->returnValue(TRUE));
259
260     $this->lock->expects($this->once())
261       ->method('release')
262       ->with('router_rebuild');
263
264     $this->yamlDiscovery->expects($this->any())
265       ->method('findAll')
266       ->will($this->returnValue([]));
267
268     $this->routeBuilder->setRebuildNeeded();
269
270     // This will trigger a successful rebuild.
271     $this->assertTrue($this->routeBuilder->rebuildIfNeeded());
272
273     // This will not trigger a rebuild.
274     $this->assertFalse($this->routeBuilder->rebuildIfNeeded());
275   }
276
277 }
278
279 /**
280  * Extends the core route builder with a setter method for the YAML discovery.
281  */
282 class TestRouteBuilder extends RouteBuilder {
283
284   /**
285    * The mocked YAML discovery.
286    *
287    * @var \Drupal\Core\Discovery\YamlDiscovery|\PHPUnit_Framework_MockObject_MockObject
288    */
289   protected $yamlDiscovery;
290
291   /**
292    * Sets the YAML discovery.
293    *
294    * @param \Drupal\Core\Discovery\YamlDiscovery $yaml_discovery
295    *   The YAML discovery to set.
296    */
297   public function setYamlDiscovery(YamlDiscovery $yaml_discovery) {
298     $this->yamlDiscovery = $yaml_discovery;
299   }
300
301   /**
302    * {@inheritdoc}
303    */
304   protected function getRouteDefinitions() {
305     return $this->yamlDiscovery->findAll();
306   }
307
308 }
309
310 /**
311  * Provides a callback for route definition.
312  */
313 class TestRouteSubscriber {
314   public function routesFromArray() {
315     return [
316       'test_route.1' => new Route('/test-route/1'),
317     ];
318   }
319   public function routesFromCollection() {
320     $collection = new RouteCollection();
321     $collection->add('test_route.2', new Route('/test-route/2'));
322     return $collection;
323   }
324
325 }