entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); $this->viewStorage = $this->getMockBuilder('Drupal\Core\Config\Entity\ConfigEntityStorage') ->disableOriginalConstructor() ->getMock(); $this->entityManager->expects($this->any()) ->method('getStorage') ->with('view') ->will($this->returnValue($this->viewStorage)); $this->state = $this->getMock('\Drupal\Core\State\StateInterface'); $this->routeSubscriber = new TestRouteSubscriber($this->entityManager, $this->state); } /** * @covers ::routeRebuildFinished */ public function testRouteRebuildFinished() { list($display_1, $display_2) = $this->setupMocks(); $display_1->expects($this->once()) ->method('collectRoutes') ->will($this->returnValue(['test_id.page_1' => 'views.test_id.page_1'])); $display_2->expects($this->once()) ->method('collectRoutes') ->will($this->returnValue(['test_id.page_2' => 'views.test_id.page_2'])); $this->routeSubscriber->routes(); $this->state->expects($this->once()) ->method('set') ->with('views.view_route_names', ['test_id.page_1' => 'views.test_id.page_1', 'test_id.page_2' => 'views.test_id.page_2']); $this->routeSubscriber->routeRebuildFinished(); } /** * Tests the onAlterRoutes method. * * @see \Drupal\views\EventSubscriber\RouteSubscriber::onAlterRoutes() */ public function testOnAlterRoutes() { $collection = new RouteCollection(); // The first route will be overridden later. $collection->add('test_route', new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController'])); $route_2 = new Route('test_route/example', ['_controller' => 'Drupal\Tests\Core\Controller\TestController']); $collection->add('test_route_2', $route_2); $route_event = new RouteBuildEvent($collection, 'views'); list($display_1, $display_2) = $this->setupMocks(); // The page_1 display overrides an existing route, so the dynamicRoutes // should only call the second display. $display_1->expects($this->once()) ->method('collectRoutes') ->willReturnCallback(function () use ($collection) { $collection->add('views.test_id.page_1', new Route('test_route', ['_controller' => 'Drupal\views\Routing\ViewPageController'])); return ['test_id.page_1' => 'views.test_id.page_1']; }); $display_1->expects($this->once()) ->method('alterRoutes') ->willReturn(['test_id.page_1' => 'test_route']); $display_2->expects($this->once()) ->method('collectRoutes') ->willReturnCallback(function () use ($collection) { $collection->add('views.test_id.page_2', new Route('test_route', ['_controller' => 'Drupal\views\Routing\ViewPageController'])); return ['test_id.page_2' => 'views.test_id.page_2']; }); $display_2->expects($this->once()) ->method('alterRoutes') ->willReturn([]); // Ensure that even both the collectRoutes() and alterRoutes() methods // are called on the displays, we ensure that the route first defined by // views is dropped. $this->routeSubscriber->routes(); $this->assertNull($this->routeSubscriber->onAlterRoutes($route_event)); $this->state->expects($this->once()) ->method('set') ->with('views.view_route_names', ['test_id.page_1' => 'test_route', 'test_id.page_2' => 'views.test_id.page_2']); $collection = $route_event->getRouteCollection(); $this->assertEquals(['test_route', 'test_route_2', 'views.test_id.page_2'], array_keys($collection->all())); $this->routeSubscriber->routeRebuildFinished(); } /** * Sets up mocks of Views objects needed for testing. * * @return \Drupal\views\Plugin\views\display\DisplayRouterInterface[]|\PHPUnit_Framework_MockObject_MockObject[] * An array of two mocked view displays. */ protected function setupMocks() { $executable = $this->getMockBuilder('Drupal\views\ViewExecutable') ->disableOriginalConstructor() ->getMock(); $view = $this->getMockBuilder('Drupal\views\Entity\View') ->disableOriginalConstructor() ->getMock(); $this->viewStorage->expects($this->any()) ->method('load') ->will($this->returnValue($view)); $view->expects($this->any()) ->method('getExecutable') ->will($this->returnValue($executable)); $view->expects($this->any()) ->method('id') ->will($this->returnValue('test_id')); $executable->storage = $view; $executable->expects($this->any()) ->method('setDisplay') ->will($this->returnValueMap([ ['page_1', TRUE], ['page_2', TRUE], ['page_3', FALSE], ])); // Ensure that only the first two displays are actually called. $display_1 = $this->getMock('Drupal\views\Plugin\views\display\DisplayRouterInterface'); $display_2 = $this->getMock('Drupal\views\Plugin\views\display\DisplayRouterInterface'); $display_collection = $this->getMockBuilder('Drupal\views\DisplayPluginCollection') ->disableOriginalConstructor() ->getMock(); $display_collection->expects($this->any()) ->method('get') ->will($this->returnValueMap([ ['page_1', $display_1], ['page_2', $display_2], ])); $executable->displayHandlers = $display_collection; $this->routeSubscriber->applicableViews = []; $this->routeSubscriber->applicableViews[] = ['test_id', 'page_1']; $this->routeSubscriber->applicableViews[] = ['test_id', 'page_2']; $this->routeSubscriber->applicableViews[] = ['test_id', 'page_3']; return [$display_1, $display_2]; } } /** * Provides a test route subscriber. */ class TestRouteSubscriber extends RouteSubscriber { /** * The applicable views. * * @var array */ public $applicableViews; /** * {@inheritdoc} */ protected function getApplicableViews() { return $this->applicableViews; } }