5 * Contains \Drupal\Tests\views\Unit\Plugin\display\PathPluginBaseTest.
8 namespace Drupal\Tests\views\Unit\Plugin\display;
10 use Drupal\Core\DependencyInjection\ContainerBuilder;
11 use Drupal\Tests\UnitTestCase;
12 use Symfony\Component\Routing\Route;
13 use Symfony\Component\Routing\RouteCollection;
16 * @coversDefaultClass \Drupal\views\Plugin\views\display\PathPluginBase
19 class PathPluginBaseTest extends UnitTestCase {
22 * The route provider that should be used.
24 * @var \Drupal\Core\Routing\RouteProviderInterface|\PHPUnit_Framework_MockObject_MockObject
26 protected $routeProvider;
29 * The tested path plugin base.
31 * @var \Drupal\views\Plugin\views\display\PathPluginBase|\PHPUnit_Framework_MockObject_MockObject
33 protected $pathPlugin;
36 * The mocked views access plugin manager.
38 * @var \Drupal\views\Plugin\ViewsPluginManager|\PHPUnit_Framework_MockObject_MockObject
40 protected $accessPluginManager;
43 * The mocked key value storage.
45 * @var \Drupal\Core\State\StateInterface|\PHPUnit_Framework_MockObject_MockObject
52 protected function setUp() {
55 $this->routeProvider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
56 $this->state = $this->getMock('\Drupal\Core\State\StateInterface');
57 $this->pathPlugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase')
58 ->setConstructorArgs([[], 'path_base', [], $this->routeProvider, $this->state])
61 $this->setupContainer();
65 * Setup access plugin manager and config factory in the Drupal class.
67 public function setupContainer() {
68 $this->accessPluginManager = $this->getMockBuilder('\Drupal\views\Plugin\ViewsPluginManager')
69 ->disableOriginalConstructor()
71 $container = new ContainerBuilder();
72 $container->set('plugin.manager.views.access', $this->accessPluginManager);
77 'display_extenders' => [],
81 $container->set('config.factory', $this->getConfigFactoryStub($config));
83 \Drupal::setContainer($container);
87 * Tests the collectRoutes method.
89 * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
91 public function testCollectRoutes() {
92 list($view) = $this->setupViewExecutableAccessPlugin();
95 $display['display_plugin'] = 'page';
96 $display['id'] = 'page_1';
97 $display['display_options'] = [
98 'path' => 'test_route',
100 $this->pathPlugin->initDisplay($view, $display);
102 $collection = new RouteCollection();
103 $result = $this->pathPlugin->collectRoutes($collection);
104 $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result);
106 $route = $collection->get('view.test_id.page_1');
107 $this->assertTrue($route instanceof Route);
108 $this->assertEquals('test_id', $route->getDefault('view_id'));
109 $this->assertEquals('page_1', $route->getDefault('display_id'));
110 $this->assertSame(FALSE, $route->getOption('returns_response'));
111 $this->assertEquals('my views title', $route->getDefault('_title'));
115 * Tests the collectRoutes method with a display returning a response.
117 * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
119 public function testCollectRoutesWithDisplayReturnResponse() {
120 list($view) = $this->setupViewExecutableAccessPlugin();
123 $display['display_plugin'] = 'page';
124 $display['id'] = 'page_1';
125 $display['display_options'] = [
126 'path' => 'test_route',
128 $this->pathPlugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase')
129 ->setConstructorArgs([[], 'path_base', ['returns_response' => TRUE], $this->routeProvider, $this->state])
132 $this->pathPlugin->initDisplay($view, $display);
134 $collection = new RouteCollection();
135 $this->pathPlugin->collectRoutes($collection);
136 $route = $collection->get('view.test_id.page_1');
137 $this->assertSame(TRUE, $route->getOption('returns_response'));
138 $this->assertEquals('my views title', $route->getDefault('_title'));
142 * Tests the collectRoutes method with arguments.
144 * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
146 public function testCollectRoutesWithArguments() {
147 list($view) = $this->setupViewExecutableAccessPlugin();
150 $display['display_plugin'] = 'page';
151 $display['id'] = 'page_1';
152 $display['display_options'] = [
153 'path' => 'test_route/%/example',
155 $this->pathPlugin->initDisplay($view, $display);
157 $collection = new RouteCollection();
158 $result = $this->pathPlugin->collectRoutes($collection);
159 $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result);
161 $route = $collection->get('view.test_id.page_1');
162 $this->assertTrue($route instanceof Route);
163 $this->assertEquals('test_id', $route->getDefault('view_id'));
164 $this->assertEquals('page_1', $route->getDefault('display_id'));
165 $this->assertEquals(['arg_0' => 'arg_0'], $route->getOption('_view_argument_map'));
166 $this->assertEquals('my views title', $route->getDefault('_title'));
170 * Tests the collectRoutes method with arguments not specified in the path.
172 * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
174 public function testCollectRoutesWithArgumentsNotSpecifiedInPath() {
175 list($view) = $this->setupViewExecutableAccessPlugin();
178 $display['display_plugin'] = 'page';
179 $display['id'] = 'page_1';
180 $display['display_options'] = [
181 'path' => 'test_with_arguments',
183 $display['display_options']['arguments'] = [
186 $this->pathPlugin->initDisplay($view, $display);
188 $collection = new RouteCollection();
189 $result = $this->pathPlugin->collectRoutes($collection);
190 $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result);
192 $route = $collection->get('view.test_id.page_1');
193 $this->assertTrue($route instanceof Route);
194 $this->assertEquals('test_id', $route->getDefault('view_id'));
195 $this->assertEquals('page_1', $route->getDefault('display_id'));
196 $this->assertEquals(['arg_0' => 'arg_0'], $route->getOption('_view_argument_map'));
197 $this->assertEquals('my views title', $route->getDefault('_title'));
201 * Tests the collect routes method with an alternative route name in the UI.
203 public function testCollectRoutesWithSpecialRouteName() {
204 list($view) = $this->setupViewExecutableAccessPlugin();
207 $display['display_plugin'] = 'page';
208 $display['id'] = 'page_1';
209 $display['display_options'] = [
210 'path' => 'test_route',
211 'route_name' => 'test_route',
213 $this->pathPlugin->initDisplay($view, $display);
215 $collection = new RouteCollection();
216 $result = $this->pathPlugin->collectRoutes($collection);
217 $this->assertEquals(['test_id.page_1' => 'test_route'], $result);
219 $route = $collection->get('test_route');
220 $this->assertTrue($route instanceof Route);
221 $this->assertEquals('test_id', $route->getDefault('view_id'));
222 $this->assertEquals('page_1', $route->getDefault('display_id'));
223 $this->assertEquals('my views title', $route->getDefault('_title'));
227 * Tests the alter route method.
229 public function testAlterRoute() {
230 $collection = new RouteCollection();
231 $collection->add('test_route', new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']));
232 $route_2 = new Route('test_route/example', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']);
233 $collection->add('test_route_2', $route_2);
235 list($view) = $this->setupViewExecutableAccessPlugin();
238 $display['display_plugin'] = 'page';
239 $display['id'] = 'page_1';
240 $display['display_options'] = [
241 'path' => 'test_route',
243 $this->pathPlugin->initDisplay($view, $display);
245 $view_route_names = $this->pathPlugin->alterRoutes($collection);
246 $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
248 // Ensure that the test_route is overridden.
249 $route = $collection->get('test_route');
250 $this->assertTrue($route instanceof Route);
251 $this->assertEquals('test_id', $route->getDefault('view_id'));
252 $this->assertEquals('page_1', $route->getDefault('display_id'));
253 $this->assertEquals('my views title', $route->getDefault('_title'));
255 // Ensure that the test_route_2 is not overridden.
256 $route = $collection->get('test_route_2');
257 $this->assertTrue($route instanceof Route);
258 $this->assertFalse($route->hasDefault('view_id'));
259 $this->assertFalse($route->hasDefault('display_id'));
260 $this->assertSame($collection->get('test_route_2'), $route_2);
264 * Tests the altering of a REST route.
266 public function testAlterPostRestRoute() {
267 $collection = new RouteCollection();
268 $route = new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']);
269 $route->setMethods(['POST']);
270 $collection->add('test_route', $route);
272 list($view) = $this->setupViewExecutableAccessPlugin();
275 $display['display_plugin'] = 'page';
276 $display['id'] = 'page_1';
277 $display['display_options'] = [
278 'path' => 'test_route',
280 $this->pathPlugin->initDisplay($view, $display);
282 $this->pathPlugin->collectRoutes($collection);
283 $view_route_names = $this->pathPlugin->alterRoutes($collection);
284 $this->assertEquals([], $view_route_names);
286 // Ensure that the test_route is not overridden.
287 $this->assertCount(2, $collection);
288 $route = $collection->get('test_route');
289 $this->assertTrue($route instanceof Route);
290 $this->assertFalse($route->hasDefault('view_id'));
291 $this->assertFalse($route->hasDefault('display_id'));
292 $this->assertSame($collection->get('test_route'), $route);
294 $route = $collection->get('view.test_id.page_1');
295 $this->assertTrue($route instanceof Route);
296 $this->assertEquals('test_id', $route->getDefault('view_id'));
297 $this->assertEquals('page_1', $route->getDefault('display_id'));
298 $this->assertEquals('my views title', $route->getDefault('_title'));
302 * Tests the altering of a REST route.
304 public function testGetRestRoute() {
305 $collection = new RouteCollection();
306 $route = new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']);
307 $route->setMethods(['GET']);
308 $route->setRequirement('_format', 'json');
309 $collection->add('test_route', $route);
311 list($view) = $this->setupViewExecutableAccessPlugin();
314 $display['display_plugin'] = 'page';
315 $display['id'] = 'page_1';
316 $display['display_options'] = [
317 'path' => 'test_route',
319 $this->pathPlugin->initDisplay($view, $display);
321 $this->pathPlugin->collectRoutes($collection);
322 $view_route_names = $this->pathPlugin->alterRoutes($collection);
323 $this->assertEquals([], $view_route_names);
325 // Ensure that the test_route is not overridden.
326 $this->assertCount(2, $collection);
327 $route = $collection->get('test_route');
328 $this->assertTrue($route instanceof Route);
329 $this->assertFalse($route->hasDefault('view_id'));
330 $this->assertFalse($route->hasDefault('display_id'));
331 $this->assertSame($collection->get('test_route'), $route);
333 $route = $collection->get('view.test_id.page_1');
334 $this->assertTrue($route instanceof Route);
335 $this->assertEquals('test_id', $route->getDefault('view_id'));
336 $this->assertEquals('page_1', $route->getDefault('display_id'));
337 $this->assertEquals('my views title', $route->getDefault('_title'));
341 * Tests the alter route method with preexisting title callback.
343 public function testAlterRouteWithAlterCallback() {
344 $collection = new RouteCollection();
345 $collection->add('test_route', new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content', '_title_callback' => '\Drupal\Tests\views\Unit\Plugin\display\TestController::testTitle']));
346 $route_2 = new Route('test_route/example', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']);
347 $collection->add('test_route_2', $route_2);
349 list($view) = $this->setupViewExecutableAccessPlugin();
352 $display['display_plugin'] = 'page';
353 $display['id'] = 'page_1';
354 $display['display_options'] = [
355 'path' => 'test_route',
357 $this->pathPlugin->initDisplay($view, $display);
359 $view_route_names = $this->pathPlugin->alterRoutes($collection);
360 $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
362 // Ensure that the test_route is overridden.
363 $route = $collection->get('test_route');
364 $this->assertTrue($route instanceof Route);
365 $this->assertEquals('test_id', $route->getDefault('view_id'));
366 $this->assertEquals('\Drupal\Tests\views\Unit\Plugin\display\TestController::testTitle', $route->getDefault('_title_callback'));
367 $this->assertEquals('page_1', $route->getDefault('display_id'));
368 $this->assertEquals('my views title', $route->getDefault('_title'));
370 // Ensure that the test_route_2 is not overridden.
371 $route = $collection->get('test_route_2');
372 $this->assertTrue($route instanceof Route);
373 $this->assertFalse($route->hasDefault('view_id'));
374 $this->assertFalse($route->hasDefault('display_id'));
375 $this->assertSame($collection->get('test_route_2'), $route_2);
379 * Tests the collectRoutes method with a path containing named parameters.
381 * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
383 public function testCollectRoutesWithNamedParameters() {
384 /** @var \Drupal\views\ViewExecutable|\PHPUnit_Framework_MockObject_MockObject $view */
385 list($view) = $this->setupViewExecutableAccessPlugin();
387 $view->argument = [];
388 $view->argument['nid'] = $this->getMockBuilder('Drupal\views\Plugin\views\argument\ArgumentPluginBase')
389 ->disableOriginalConstructor()
393 $display['display_plugin'] = 'page';
394 $display['id'] = 'page_1';
395 $display['display_options'] = [
396 'path' => 'test_route/%node/example',
398 $this->pathPlugin->initDisplay($view, $display);
400 $collection = new RouteCollection();
401 $result = $this->pathPlugin->collectRoutes($collection);
402 $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result);
404 $route = $collection->get('view.test_id.page_1');
405 $this->assertTrue($route instanceof Route);
406 $this->assertEquals('/test_route/{node}/example', $route->getPath());
407 $this->assertEquals('test_id', $route->getDefault('view_id'));
408 $this->assertEquals('page_1', $route->getDefault('display_id'));
409 $this->assertEquals('my views title', $route->getDefault('_title'));
410 $this->assertEquals(['arg_0' => 'node'], $route->getOption('_view_argument_map'));
414 * Tests altering routes with parameters in the overridden route.
416 public function testAlterRoutesWithParameters() {
417 $collection = new RouteCollection();
418 $collection->add('test_route', new Route('test_route/{parameter}', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']));
420 list($view) = $this->setupViewExecutableAccessPlugin();
422 // Manually set up an argument handler.
423 $argument = $this->getMockBuilder('Drupal\views\Plugin\views\argument\ArgumentPluginBase')
424 ->disableOriginalConstructor()
426 $view->argument['test_id'] = $argument;
429 $display['display_plugin'] = 'page';
430 $display['id'] = 'page_1';
431 $display['display_options'] = [
432 'path' => 'test_route/%',
434 $this->pathPlugin->initDisplay($view, $display);
436 $view_route_names = $this->pathPlugin->alterRoutes($collection);
437 $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
439 // Ensure that the test_route is overridden.
440 $route = $collection->get('test_route');
441 $this->assertInstanceOf('\Symfony\Component\Routing\Route', $route);
442 $this->assertEquals('test_id', $route->getDefault('view_id'));
443 $this->assertEquals('page_1', $route->getDefault('display_id'));
444 // Ensure that the path did not changed and placeholders are respected.
445 $this->assertEquals('/test_route/{parameter}', $route->getPath());
446 $this->assertEquals(['arg_0' => 'parameter'], $route->getOption('_view_argument_map'));
447 $this->assertEquals('my views title', $route->getDefault('_title'));
451 * Tests altering routes with parameters and upcasting information
453 public function testAlterRoutesWithParametersAndUpcasting() {
454 $collection = new RouteCollection();
455 $collection->add('test_route', new Route('test_route/{parameter}', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content'], [], ['parameters' => ['taxonomy_term' => 'entity:entity_test']]));
457 list($view) = $this->setupViewExecutableAccessPlugin();
459 // Manually set up an argument handler.
460 $argument = $this->getMockBuilder('Drupal\views\Plugin\views\argument\ArgumentPluginBase')
461 ->disableOriginalConstructor()
463 $view->argument['test_id'] = $argument;
466 $display['display_plugin'] = 'page';
467 $display['id'] = 'page_1';
468 $display['display_options'] = [
469 'path' => 'test_route/%',
471 $this->pathPlugin->initDisplay($view, $display);
473 $view_route_names = $this->pathPlugin->alterRoutes($collection);
474 $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
476 // Ensure that the test_route is overridden.
477 $route = $collection->get('test_route');
478 $this->assertInstanceOf('\Symfony\Component\Routing\Route', $route);
479 $this->assertEquals('test_id', $route->getDefault('view_id'));
480 $this->assertEquals('page_1', $route->getDefault('display_id'));
481 $this->assertEquals(['taxonomy_term' => 'entity:entity_test'], $route->getOption('parameters'));
482 // Ensure that the path did not changed and placeholders are respected kk.
483 $this->assertEquals('/test_route/{parameter}', $route->getPath());
484 $this->assertEquals(['arg_0' => 'parameter'], $route->getOption('_view_argument_map'));
485 $this->assertEquals('my views title', $route->getDefault('_title'));
489 * Tests altering routes with optional parameters in the overridden route.
491 public function testAlterRoutesWithOptionalParameters() {
492 $collection = new RouteCollection();
493 $collection->add('test_route', new Route('test_route/{parameter}', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']));
495 list($view) = $this->setupViewExecutableAccessPlugin();
498 $display['display_plugin'] = 'page';
499 $display['id'] = 'page_1';
500 $display['display_options'] = [
501 'path' => 'test_route/%',
503 $display['display_options']['arguments'] = [
507 $this->pathPlugin->initDisplay($view, $display);
509 $view_route_names = $this->pathPlugin->alterRoutes($collection);
510 $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
512 // Ensure that the test_route is overridden.
513 $route = $collection->get('test_route');
514 $this->assertInstanceOf('\Symfony\Component\Routing\Route', $route);
515 $this->assertEquals('test_id', $route->getDefault('view_id'));
516 $this->assertEquals('page_1', $route->getDefault('display_id'));
517 // Ensure that the path did not changed and placeholders are respected.
518 $this->assertEquals('/test_route/{parameter}/{arg_1}', $route->getPath());
519 $this->assertEquals(['arg_0' => 'parameter'], $route->getOption('_view_argument_map'));
520 $this->assertEquals('my views title', $route->getDefault('_title'));
524 * Tests the getRouteName method.
526 public function testGetRouteName() {
527 list($view) = $this->setupViewExecutableAccessPlugin();
530 $display['display_plugin'] = 'page';
531 $display['id'] = 'page_1';
532 $display['display_options'] = [
533 'path' => 'test_route',
535 $this->pathPlugin->initDisplay($view, $display);
536 $route_name = $this->pathPlugin->getRouteName();
537 // Ensure that the expected routename is returned.
538 $this->assertEquals('view.test_id.page_1', $route_name);
542 * Returns some mocked view entity, view executable, and access plugin.
544 protected function setupViewExecutableAccessPlugin() {
545 $view_entity = $this->getMockBuilder('Drupal\views\Entity\View')
546 ->disableOriginalConstructor()
548 $view_entity->expects($this->any())
550 ->will($this->returnValue('test_id'));
552 $view = $this->getMockBuilder('Drupal\views\ViewExecutable')
553 ->disableOriginalConstructor()
555 $view->expects($this->any())
557 ->willReturn('my views title');
559 $view->storage = $view_entity;
561 // Skip views options caching.
562 $view->editing = TRUE;
564 $access_plugin = $this->getMockBuilder('Drupal\views\Plugin\views\access\AccessPluginBase')
565 ->disableOriginalConstructor()
566 ->getMockForAbstractClass();
567 $this->accessPluginManager->expects($this->any())
568 ->method('createInstance')
569 ->will($this->returnValue($access_plugin));
571 return [$view, $view_entity, $access_plugin];
577 * A page controller for use by tests in this file.
579 class TestController {
582 * A page title callback.
587 public function testTitle() {