3 namespace Drupal\Tests\Core\Path;
5 use Drupal\Core\ParamConverter\ParamNotConvertedException;
6 use Drupal\Core\Path\PathValidator;
7 use Drupal\Tests\UnitTestCase;
8 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
9 use Symfony\Component\HttpFoundation\ParameterBag;
10 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
11 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
12 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
15 * @coversDefaultClass \Drupal\Core\Path\PathValidator
18 class PathValidatorTest extends UnitTestCase {
21 * The mocked access aware router.
23 * @var \Drupal\Core\Routing\AccessAwareRouterInterface|\PHPUnit_Framework_MockObject_MockObject
25 protected $accessAwareRouter;
28 * The mocked access unaware router.
29 * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|\PHPUnit_Framework_MockObject_MockObject
31 protected $accessUnawareRouter;
36 * @var \Drupal\Core\Session\AccountInterface|\PHPUnit_Framework_MockObject_MockObject
43 * @var \Drupal\Core\PathProcessor\InboundPathProcessorInterface|\PHPUnit_Framework_MockObject_MockObject
45 protected $pathProcessor;
48 * The tested path validator.
50 * @var \Drupal\Core\Path\PathValidator
52 protected $pathValidator;
57 protected function setUp() {
60 $this->accessAwareRouter = $this->getMock('Drupal\Core\Routing\AccessAwareRouterInterface');
61 $this->accessUnawareRouter = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface');
62 $this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
63 $this->pathProcessor = $this->getMock('Drupal\Core\PathProcessor\InboundPathProcessorInterface');
64 $this->pathValidator = new PathValidator($this->accessAwareRouter, $this->accessUnawareRouter, $this->account, $this->pathProcessor);
68 * Tests the isValid() method for the frontpage.
72 public function testIsValidWithFrontpage() {
73 $this->accessAwareRouter->expects($this->never())
76 $this->assertTrue($this->pathValidator->isValid('<front>'));
80 * Tests the isValid() method for <none> (used for jumplinks).
84 public function testIsValidWithNone() {
85 $this->accessAwareRouter->expects($this->never())
88 $this->assertTrue($this->pathValidator->isValid('<none>'));
92 * Tests the isValid() method for an external URL.
96 public function testIsValidWithExternalUrl() {
97 $this->accessAwareRouter->expects($this->never())
100 $this->assertTrue($this->pathValidator->isValid('https://www.drupal.org'));
104 * Tests the isValid() method with an invalid external URL.
108 public function testIsValidWithInvalidExternalUrl() {
109 $this->accessAwareRouter->expects($this->never())
112 $this->assertFalse($this->pathValidator->isValid('http://'));
116 * Tests the isValid() method with a 'link to any page' permission.
119 * @covers ::getPathAttributes
121 public function testIsValidWithLinkToAnyPageAccount() {
122 $this->account->expects($this->once())
123 ->method('hasPermission')
124 ->with('link to any page')
126 $this->accessAwareRouter->expects($this->never())
128 $this->accessUnawareRouter->expects($this->once())
131 ->willReturn([RouteObjectInterface::ROUTE_NAME => 'test_route', '_raw_variables' => new ParameterBag(['key' => 'value'])]);
132 $this->pathProcessor->expects($this->once())
133 ->method('processInbound')
134 ->willReturnArgument(0);
136 $this->assertTrue($this->pathValidator->isValid('test-path'));
140 * Tests the isValid() method without the 'link to any page' permission.
144 public function testIsValidWithoutLinkToAnyPageAccount() {
145 $this->account->expects($this->once())
146 ->method('hasPermission')
147 ->with('link to any page')
149 $this->accessUnawareRouter->expects($this->never())
151 $this->accessAwareRouter->expects($this->once())
154 ->willReturn([RouteObjectInterface::ROUTE_NAME => 'test_route', '_raw_variables' => new ParameterBag(['key' => 'value'])]);
155 $this->pathProcessor->expects($this->once())
156 ->method('processInbound')
157 ->willReturnArgument(0);
159 $this->assertTrue($this->pathValidator->isValid('test-path'));
163 * Tests the isValid() method with a path alias.
167 public function testIsValidWithPathAlias() {
168 $this->account->expects($this->once())
169 ->method('hasPermission')
170 ->with('link to any page')
172 $this->accessUnawareRouter->expects($this->never())
174 $this->accessAwareRouter->expects($this->once())
177 ->willReturn([RouteObjectInterface::ROUTE_NAME => 'test_route', '_raw_variables' => new ParameterBag(['key' => 'value'])]);
178 $this->pathProcessor->expects($this->once())
179 ->method('processInbound')
180 ->with('/path-alias', $this->anything())
181 ->willReturn('/test-path');
183 $this->assertTrue($this->pathValidator->isValid('path-alias'));
187 * Tests the isValid() method with a user without access to the path.
190 * @covers ::getPathAttributes
192 public function testIsValidWithAccessDenied() {
193 $this->account->expects($this->once())
194 ->method('hasPermission')
195 ->with('link to any page')
197 $this->accessUnawareRouter->expects($this->never())
199 $this->accessAwareRouter->expects($this->once())
202 ->willThrowException(new AccessDeniedHttpException());
203 $this->pathProcessor->expects($this->once())
204 ->method('processInbound')
205 ->willReturnArgument(0);
207 $this->assertFalse($this->pathValidator->isValid('test-path'));
212 * @covers ::getPathAttributes
214 public function testIsValidWithResourceNotFound() {
215 $this->account->expects($this->once())
216 ->method('hasPermission')
217 ->with('link to any page')
219 $this->accessUnawareRouter->expects($this->never())
221 $this->accessAwareRouter->expects($this->once())
224 ->willThrowException(new ResourceNotFoundException());
225 $this->pathProcessor->expects($this->once())
226 ->method('processInbound')
227 ->willReturnArgument(0);
229 $this->assertFalse($this->pathValidator->isValid('test-path'));
234 * @covers ::getPathAttributes
236 public function testIsValidWithParamNotConverted() {
237 $this->account->expects($this->once())
238 ->method('hasPermission')
239 ->with('link to any page')
241 $this->accessUnawareRouter->expects($this->never())
243 $this->accessAwareRouter->expects($this->once())
246 ->willThrowException(new ParamNotConvertedException());
247 $this->pathProcessor->expects($this->once())
248 ->method('processInbound')
249 ->willReturnArgument(0);
251 $this->assertFalse($this->pathValidator->isValid('test-path'));
256 * @covers ::getPathAttributes
258 public function testIsValidWithMethodNotAllowed() {
259 $this->account->expects($this->once())
260 ->method('hasPermission')
261 ->with('link to any page')
263 $this->accessUnawareRouter->expects($this->never())
265 $this->accessAwareRouter->expects($this->once())
268 ->willThrowException(new MethodNotAllowedException([]));
269 $this->pathProcessor->expects($this->once())
270 ->method('processInbound')
271 ->willReturnArgument(0);
273 $this->assertFalse($this->pathValidator->isValid('test-path'));
277 * Tests the isValid() method with a not working param converting.
281 public function testIsValidWithFailingParameterConverting() {
282 $this->account->expects($this->once())
283 ->method('hasPermission')
284 ->with('link to any page')
286 $this->accessUnawareRouter->expects($this->never())
288 $this->accessAwareRouter->expects($this->once())
290 ->with('/entity-test/1')
291 ->willThrowException(new ParamNotConvertedException());
292 $this->pathProcessor->expects($this->once())
293 ->method('processInbound')
294 ->willReturnArgument(0);
296 $this->assertFalse($this->pathValidator->isValid('entity-test/1'));
300 * Tests the isValid() method with a not existing path.
304 public function testIsValidWithNotExistingPath() {
305 $this->account->expects($this->once())
306 ->method('hasPermission')
307 ->with('link to any page')
309 $this->accessUnawareRouter->expects($this->never())
311 $this->accessAwareRouter->expects($this->once())
313 ->with('/not-existing-path')
314 ->willThrowException(new ResourceNotFoundException());
315 $this->pathProcessor->expects($this->once())
316 ->method('processInbound')
317 ->willReturnArgument(0);
319 $this->assertFalse($this->pathValidator->isValid('not-existing-path'));
323 * Tests the getUrlIfValid() method when there is access.
325 * @covers ::getUrlIfValid
326 * @covers ::getPathAttributes
328 public function testGetUrlIfValidWithAccess() {
329 $this->account->expects($this->exactly(2))
330 ->method('hasPermission')
331 ->with('link to any page')
334 $this->accessAwareRouter->expects($this->exactly(2))
337 ->willReturn([RouteObjectInterface::ROUTE_NAME => 'test_route', '_raw_variables' => new ParameterBag(['key' => 'value'])]);
338 $this->pathProcessor->expects($this->exactly(2))
339 ->method('processInbound')
340 ->willReturnArgument(0);
342 $url = $this->pathValidator->getUrlIfValid('test-path');
343 $this->assertInstanceOf('Drupal\Core\Url', $url);
345 $this->assertEquals('test_route', $url->getRouteName());
346 $this->assertEquals(['key' => 'value'], $url->getRouteParameters());
348 // Test with leading /.
349 $url = $this->pathValidator->getUrlIfValid('/test-path');
350 $this->assertInstanceOf('Drupal\Core\Url', $url);
352 $this->assertEquals('test_route', $url->getRouteName());
353 $this->assertEquals(['key' => 'value'], $url->getRouteParameters());
357 * Tests the getUrlIfValid() method with a query in the path.
359 * @covers ::getUrlIfValid
361 public function testGetUrlIfValidWithQuery() {
362 $this->account->expects($this->once())
363 ->method('hasPermission')
364 ->with('link to any page')
367 $this->accessAwareRouter->expects($this->once())
369 ->with('/test-path?k=bar')
370 ->willReturn([RouteObjectInterface::ROUTE_NAME => 'test_route', '_raw_variables' => new ParameterBag()]);
371 $this->pathProcessor->expects($this->once())
372 ->method('processInbound')
373 ->willReturnArgument(0);
375 $url = $this->pathValidator->getUrlIfValid('test-path?k=bar');
376 $this->assertInstanceOf('Drupal\Core\Url', $url);
378 $this->assertEquals('test_route', $url->getRouteName());
379 $this->assertEquals(['k' => 'bar'], $url->getOptions()['query']);
383 * Tests the getUrlIfValid() method where there is no access.
385 * @covers ::getUrlIfValid
387 public function testGetUrlIfValidWithoutAccess() {
388 $this->account->expects($this->once())
389 ->method('hasPermission')
390 ->with('link to any page')
393 $this->accessAwareRouter->expects($this->once())
396 ->willThrowException(new AccessDeniedHttpException());
398 $this->pathProcessor->expects($this->once())
399 ->method('processInbound')
400 ->willReturnArgument(0);
402 $url = $this->pathValidator->getUrlIfValid('test-path');
403 $this->assertFalse($url);
407 * Tests the getUrlIfValid() method with a front page + query + fragments.
409 * @covers ::getUrlIfValid
411 public function testGetUrlIfValidWithFrontPageAndQueryAndFragments() {
412 $url = $this->pathValidator->getUrlIfValid('<front>?hei=sen#berg');
413 $this->assertEquals('<front>', $url->getRouteName());
414 $this->assertEquals(['hei' => 'sen'], $url->getOptions()['query']);
415 $this->assertEquals('berg', $url->getOptions()['fragment']);
419 * Tests the getUrlIfValidWithoutAccessCheck() method.
421 * @covers ::getUrlIfValidWithoutAccessCheck
422 * @covers ::getPathAttributes
424 public function testGetUrlIfValidWithoutAccessCheck() {
425 $this->account->expects($this->never())
426 ->method('hasPermission')
427 ->with('link to any page');
428 $this->accessAwareRouter->expects($this->never())
430 $this->accessUnawareRouter->expects($this->once())
433 ->willReturn([RouteObjectInterface::ROUTE_NAME => 'test_route', '_raw_variables' => new ParameterBag(['key' => 'value'])]);
434 $this->pathProcessor->expects($this->once())
435 ->method('processInbound')
436 ->willReturnArgument(0);
438 $url = $this->pathValidator->getUrlIfValidWithoutAccessCheck('test-path');
439 $this->assertInstanceOf('Drupal\Core\Url', $url);
441 $this->assertEquals('test_route', $url->getRouteName());
442 $this->assertEquals(['key' => 'value'], $url->getRouteParameters());