Upgraded drupal core with security updates
[yaffs-website] / web / core / modules / views / tests / src / Unit / Plugin / display / PathPluginBaseTest.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Tests\views\Unit\Plugin\display\PathPluginBaseTest.
6  */
7
8 namespace Drupal\Tests\views\Unit\Plugin\display;
9
10 use Drupal\Core\DependencyInjection\ContainerBuilder;
11 use Drupal\Tests\UnitTestCase;
12 use Symfony\Component\Routing\Route;
13 use Symfony\Component\Routing\RouteCollection;
14
15 /**
16  * @coversDefaultClass \Drupal\views\Plugin\views\display\PathPluginBase
17  * @group views
18  */
19 class PathPluginBaseTest extends UnitTestCase {
20
21   /**
22    * The route provider that should be used.
23    *
24    * @var \Drupal\Core\Routing\RouteProviderInterface|\PHPUnit_Framework_MockObject_MockObject
25    */
26   protected $routeProvider;
27
28   /**
29    * The tested path plugin base.
30    *
31    * @var \Drupal\views\Plugin\views\display\PathPluginBase|\PHPUnit_Framework_MockObject_MockObject
32    */
33   protected $pathPlugin;
34
35   /**
36    * The mocked views access plugin manager.
37    *
38    * @var \Drupal\views\Plugin\ViewsPluginManager|\PHPUnit_Framework_MockObject_MockObject
39    */
40   protected $accessPluginManager;
41
42   /**
43    * The mocked key value storage.
44    *
45    * @var \Drupal\Core\State\StateInterface|\PHPUnit_Framework_MockObject_MockObject
46    */
47   protected $state;
48
49   /**
50    * {@inheritdoc}
51    */
52   protected function setUp() {
53     parent::setUp();
54
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])
59       ->setMethods(NULL)
60       ->getMock();
61     $this->setupContainer();
62   }
63
64   /**
65    * Setup access plugin manager and config factory in the Drupal class.
66    */
67   public function setupContainer() {
68     $this->accessPluginManager = $this->getMockBuilder('\Drupal\views\Plugin\ViewsPluginManager')
69       ->disableOriginalConstructor()
70       ->getMock();
71     $container = new ContainerBuilder();
72     $container->set('plugin.manager.views.access', $this->accessPluginManager);
73
74     $config = [
75       'views.settings' => [
76         'skip_cache' => TRUE,
77         'display_extenders' => [],
78       ],
79     ];
80
81     $container->set('config.factory', $this->getConfigFactoryStub($config));
82
83     \Drupal::setContainer($container);
84   }
85
86   /**
87    * Tests the collectRoutes method.
88    *
89    * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
90    */
91   public function testCollectRoutes() {
92     list($view) = $this->setupViewExecutableAccessPlugin();
93
94     $display = [];
95     $display['display_plugin'] = 'page';
96     $display['id'] = 'page_1';
97     $display['display_options'] = [
98       'path' => 'test_route',
99     ];
100     $this->pathPlugin->initDisplay($view, $display);
101
102     $collection = new RouteCollection();
103     $result = $this->pathPlugin->collectRoutes($collection);
104     $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result);
105
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'));
112   }
113
114   /**
115    * Tests the collectRoutes method with a display returning a response.
116    *
117    * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
118    */
119   public function testCollectRoutesWithDisplayReturnResponse() {
120     list($view) = $this->setupViewExecutableAccessPlugin();
121
122     $display = [];
123     $display['display_plugin'] = 'page';
124     $display['id'] = 'page_1';
125     $display['display_options'] = [
126       'path' => 'test_route',
127     ];
128     $this->pathPlugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase')
129       ->setConstructorArgs([[], 'path_base', ['returns_response' => TRUE], $this->routeProvider, $this->state])
130       ->setMethods(NULL)
131       ->getMock();
132     $this->pathPlugin->initDisplay($view, $display);
133
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'));
139   }
140
141   /**
142    * Tests the collectRoutes method with arguments.
143    *
144    * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
145    */
146   public function testCollectRoutesWithArguments() {
147     list($view) = $this->setupViewExecutableAccessPlugin();
148
149     $display = [];
150     $display['display_plugin'] = 'page';
151     $display['id'] = 'page_1';
152     $display['display_options'] = [
153       'path' => 'test_route/%/example',
154     ];
155     $this->pathPlugin->initDisplay($view, $display);
156
157     $collection = new RouteCollection();
158     $result = $this->pathPlugin->collectRoutes($collection);
159     $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result);
160
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'));
167   }
168
169   /**
170    * Tests the collectRoutes method with arguments not specified in the path.
171    *
172    * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
173    */
174   public function testCollectRoutesWithArgumentsNotSpecifiedInPath() {
175     list($view) = $this->setupViewExecutableAccessPlugin();
176
177     $display = [];
178     $display['display_plugin'] = 'page';
179     $display['id'] = 'page_1';
180     $display['display_options'] = [
181       'path' => 'test_with_arguments',
182     ];
183     $display['display_options']['arguments'] = [
184       'test_id' => [],
185     ];
186     $this->pathPlugin->initDisplay($view, $display);
187
188     $collection = new RouteCollection();
189     $result = $this->pathPlugin->collectRoutes($collection);
190     $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result);
191
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'));
198   }
199
200   /**
201    * Tests the collect routes method with an alternative route name in the UI.
202    */
203   public function testCollectRoutesWithSpecialRouteName() {
204     list($view) = $this->setupViewExecutableAccessPlugin();
205
206     $display = [];
207     $display['display_plugin'] = 'page';
208     $display['id'] = 'page_1';
209     $display['display_options'] = [
210       'path' => 'test_route',
211       'route_name' => 'test_route',
212     ];
213     $this->pathPlugin->initDisplay($view, $display);
214
215     $collection = new RouteCollection();
216     $result = $this->pathPlugin->collectRoutes($collection);
217     $this->assertEquals(['test_id.page_1' => 'test_route'], $result);
218
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'));
224   }
225
226   /**
227    * Tests the alter route method.
228    */
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);
234
235     list($view) = $this->setupViewExecutableAccessPlugin();
236
237     $display = [];
238     $display['display_plugin'] = 'page';
239     $display['id'] = 'page_1';
240     $display['display_options'] = [
241       'path' => 'test_route',
242     ];
243     $this->pathPlugin->initDisplay($view, $display);
244
245     $view_route_names = $this->pathPlugin->alterRoutes($collection);
246     $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
247
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'));
254
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);
261   }
262
263   /**
264    * Tests the altering of a REST route.
265    */
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);
271
272     list($view) = $this->setupViewExecutableAccessPlugin();
273
274     $display = [];
275     $display['display_plugin'] = 'page';
276     $display['id'] = 'page_1';
277     $display['display_options'] = [
278       'path' => 'test_route',
279     ];
280     $this->pathPlugin->initDisplay($view, $display);
281
282     $this->pathPlugin->collectRoutes($collection);
283     $view_route_names = $this->pathPlugin->alterRoutes($collection);
284     $this->assertEquals([], $view_route_names);
285
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);
293
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'));
299   }
300
301   /**
302    * Tests the altering of a REST route.
303    */
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);
310
311     list($view) = $this->setupViewExecutableAccessPlugin();
312
313     $display = [];
314     $display['display_plugin'] = 'page';
315     $display['id'] = 'page_1';
316     $display['display_options'] = [
317       'path' => 'test_route',
318     ];
319     $this->pathPlugin->initDisplay($view, $display);
320
321     $this->pathPlugin->collectRoutes($collection);
322     $view_route_names = $this->pathPlugin->alterRoutes($collection);
323     $this->assertEquals([], $view_route_names);
324
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);
332
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'));
338   }
339
340   /**
341    * Tests the alter route method with preexisting title callback.
342    */
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);
348
349     list($view) = $this->setupViewExecutableAccessPlugin();
350
351     $display = [];
352     $display['display_plugin'] = 'page';
353     $display['id'] = 'page_1';
354     $display['display_options'] = [
355       'path' => 'test_route',
356     ];
357     $this->pathPlugin->initDisplay($view, $display);
358
359     $view_route_names = $this->pathPlugin->alterRoutes($collection);
360     $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
361
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'));
369
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);
376   }
377
378   /**
379    * Tests the collectRoutes method with a path containing named parameters.
380    *
381    * @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
382    */
383   public function testCollectRoutesWithNamedParameters() {
384     /** @var \Drupal\views\ViewExecutable|\PHPUnit_Framework_MockObject_MockObject $view */
385     list($view) = $this->setupViewExecutableAccessPlugin();
386
387     $view->argument = [];
388     $view->argument['nid'] = $this->getMockBuilder('Drupal\views\Plugin\views\argument\ArgumentPluginBase')
389       ->disableOriginalConstructor()
390       ->getMock();
391
392     $display = [];
393     $display['display_plugin'] = 'page';
394     $display['id'] = 'page_1';
395     $display['display_options'] = [
396       'path' => 'test_route/%node/example',
397     ];
398     $this->pathPlugin->initDisplay($view, $display);
399
400     $collection = new RouteCollection();
401     $result = $this->pathPlugin->collectRoutes($collection);
402     $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result);
403
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'));
411   }
412
413   /**
414    * Tests altering routes with parameters in the overridden route.
415    */
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']));
419
420     list($view) = $this->setupViewExecutableAccessPlugin();
421
422     // Manually set up an argument handler.
423     $argument = $this->getMockBuilder('Drupal\views\Plugin\views\argument\ArgumentPluginBase')
424       ->disableOriginalConstructor()
425       ->getMock();
426     $view->argument['test_id'] = $argument;
427
428     $display = [];
429     $display['display_plugin'] = 'page';
430     $display['id'] = 'page_1';
431     $display['display_options'] = [
432       'path' => 'test_route/%',
433     ];
434     $this->pathPlugin->initDisplay($view, $display);
435
436     $view_route_names = $this->pathPlugin->alterRoutes($collection);
437     $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
438
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'));
448   }
449
450   /**
451    * Tests altering routes with parameters and upcasting information
452    */
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']]));
456
457     list($view) = $this->setupViewExecutableAccessPlugin();
458
459     // Manually set up an argument handler.
460     $argument = $this->getMockBuilder('Drupal\views\Plugin\views\argument\ArgumentPluginBase')
461       ->disableOriginalConstructor()
462       ->getMock();
463     $view->argument['test_id'] = $argument;
464
465     $display = [];
466     $display['display_plugin'] = 'page';
467     $display['id'] = 'page_1';
468     $display['display_options'] = [
469       'path' => 'test_route/%',
470     ];
471     $this->pathPlugin->initDisplay($view, $display);
472
473     $view_route_names = $this->pathPlugin->alterRoutes($collection);
474     $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
475
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'));
486   }
487
488   /**
489    * Tests altering routes with optional parameters in the overridden route.
490    */
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']));
494
495     list($view) = $this->setupViewExecutableAccessPlugin();
496
497     $display = [];
498     $display['display_plugin'] = 'page';
499     $display['id'] = 'page_1';
500     $display['display_options'] = [
501       'path' => 'test_route/%',
502     ];
503     $display['display_options']['arguments'] = [
504       'test_id' => [],
505       'test_id2' => [],
506     ];
507     $this->pathPlugin->initDisplay($view, $display);
508
509     $view_route_names = $this->pathPlugin->alterRoutes($collection);
510     $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names);
511
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'));
521   }
522
523   /**
524    * Tests the getRouteName method.
525    */
526   public function testGetRouteName() {
527     list($view) = $this->setupViewExecutableAccessPlugin();
528
529     $display = [];
530     $display['display_plugin'] = 'page';
531     $display['id'] = 'page_1';
532     $display['display_options'] = [
533       'path' => 'test_route',
534     ];
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);
539   }
540
541   /**
542    * Returns some mocked view entity, view executable, and access plugin.
543    */
544   protected function setupViewExecutableAccessPlugin() {
545     $view_entity = $this->getMockBuilder('Drupal\views\Entity\View')
546       ->disableOriginalConstructor()
547       ->getMock();
548     $view_entity->expects($this->any())
549       ->method('id')
550       ->will($this->returnValue('test_id'));
551
552     $view = $this->getMockBuilder('Drupal\views\ViewExecutable')
553       ->disableOriginalConstructor()
554       ->getMock();
555     $view->expects($this->any())
556       ->method('getTitle')
557       ->willReturn('my views title');
558
559     $view->storage = $view_entity;
560
561     // Skip views options caching.
562     $view->editing = TRUE;
563
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));
570
571     return [$view, $view_entity, $access_plugin];
572   }
573
574 }
575
576 /**
577  * A page controller for use by tests in this file.
578  */
579 class TestController {
580
581   /**
582    * A page title callback.
583    *
584    * @return string
585    *   The page title.
586    */
587   public function testTitle() {
588     return 'Test title';
589   }
590
591 }