View source
<?php
namespace Drupal\Tests\Core\Routing;
use Drupal\Core\Cache\Cache;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\PathProcessor\PathProcessorAlias;
use Drupal\Core\PathProcessor\PathProcessorManager;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Routing\RequestContext;
use Drupal\Core\Routing\UrlGenerator;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
class UrlGeneratorTest extends UnitTestCase {
protected $generator;
protected $aliasManager;
protected $routeProcessorManager;
protected $requestStack;
protected function setUp() {
$cache_contexts_manager = $this
->getMockBuilder('Drupal\\Core\\Cache\\Context\\CacheContextsManager')
->disableOriginalConstructor()
->getMock();
$cache_contexts_manager
->method('assertValidTokens')
->willReturn(TRUE);
$container = new ContainerBuilder();
$container
->set('cache_contexts_manager', $cache_contexts_manager);
\Drupal::setContainer($container);
$routes = new RouteCollection();
$first_route = new Route('/test/one');
$second_route = new Route('/test/two/{narf}');
$third_route = new Route('/test/two/');
$fourth_route = new Route('/test/four', [], [], [], '', [
'https',
]);
$none_route = new Route('', [], [], [
'_no_path' => TRUE,
]);
$routes
->add('test_1', $first_route);
$routes
->add('test_2', $second_route);
$routes
->add('test_3', $third_route);
$routes
->add('test_4', $fourth_route);
$routes
->add('<none>', $none_route);
$provider = $this
->getMockBuilder('Drupal\\Core\\Routing\\RouteProvider')
->disableOriginalConstructor()
->getMock();
$route_name_return_map = $routes_names_return_map = array();
$return_map_values = array(
[
'route_name' => 'test_1',
'return' => $first_route,
],
[
'route_name' => 'test_2',
'return' => $second_route,
],
[
'route_name' => 'test_3',
'return' => $third_route,
],
[
'route_name' => 'test_4',
'return' => $fourth_route,
],
[
'route_name' => '<none>',
'return' => $none_route,
],
);
foreach ($return_map_values as $values) {
$route_name_return_map[] = array(
$values['route_name'],
$values['return'],
);
$routes_names_return_map[] = array(
array(
$values['route_name'],
),
$values['return'],
);
}
$provider
->expects($this
->any())
->method('getRouteByName')
->will($this
->returnValueMap($route_name_return_map));
$provider
->expects($this
->any())
->method('getRoutesByNames')
->will($this
->returnValueMap($routes_names_return_map));
$alias_manager = $this
->getMockBuilder('Drupal\\Core\\Path\\AliasManager')
->disableOriginalConstructor()
->getMock();
$alias_manager
->expects($this
->any())
->method('getAliasByPath')
->will($this
->returnCallback(array(
$this,
'aliasManagerCallback',
)));
$this->aliasManager = $alias_manager;
$this->requestStack = new RequestStack();
$request = Request::create('/some/path');
$this->requestStack
->push($request);
$context = new RequestContext();
$context
->fromRequestStack($this->requestStack);
$processor = new PathProcessorAlias($this->aliasManager);
$processor_manager = new PathProcessorManager();
$processor_manager
->addOutbound($processor, 1000);
$this->routeProcessorManager = $this
->getMockBuilder('Drupal\\Core\\RouteProcessor\\RouteProcessorManager')
->disableOriginalConstructor()
->getMock();
$generator = new UrlGenerator($provider, $processor_manager, $this->routeProcessorManager, $this->requestStack, [
'http',
'https',
]);
$generator
->setContext($context);
$this->generator = $generator;
}
public function aliasManagerCallback() {
$args = func_get_args();
switch ($args[0]) {
case '/test/one':
return '/hello/world';
case '/test/two/5':
return '/goodbye/cruel/world';
case '/<front>':
return '/';
default:
return $args[0];
}
}
public function testAliasGeneration() {
$url = $this->generator
->generate('test_1');
$this
->assertEquals('/hello/world', $url);
$this->routeProcessorManager
->expects($this
->exactly(3))
->method('processOutbound')
->with($this
->anything());
$this
->assertGenerateFromRoute('test_1', [], [], $url, (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT));
$path = $this->generator
->getPathFromRoute('test_1');
$this
->assertEquals('test/one', $path);
}
public function testGetPathFromRouteWithSubdirectory() {
$this->routeProcessorManager
->expects($this
->once())
->method('processOutbound');
$path = $this->generator
->getPathFromRoute('test_1');
$this
->assertEquals('test/one', $path);
}
public function testAliasGenerationWithParameters() {
$url = $this->generator
->generate('test_2', array(
'narf' => '5',
));
$this
->assertEquals('/goodbye/cruel/world', $url);
$this->routeProcessorManager
->expects($this
->exactly(7))
->method('processOutbound')
->with($this
->anything());
$options = array(
'fragment' => 'top',
);
$this
->assertGenerateFromRoute('test_1', [
'zoo' => 5,
], $options, '/hello/world?zoo=5#top', (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT));
$options = array(
'query' => array(
'page' => '1',
),
'fragment' => 'bottom',
);
$this
->assertGenerateFromRoute('test_2', [
'narf' => 5,
], $options, '/goodbye/cruel/world?page=1#bottom', (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT));
$this
->assertGenerateFromRoute('test_2', [
'narf' => 7,
], $options, '/test/two/7?page=1#bottom', (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT));
$path = $this->generator
->getPathFromRoute('test_2', array(
'narf' => '5',
));
$this
->assertEquals('test/two/5', $path);
}
public function testAliasGenerationWithOptions($route_name, $route_parameters, $options, $expected) {
$this
->assertGenerateFromRoute($route_name, $route_parameters, $options, $expected, (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT));
}
public function providerTestAliasGenerationWithOptions() {
$data = [];
$data[] = [
'test_1',
[
'zoo' => '5',
],
[
'fragment' => 'top',
],
'/hello/world?zoo=5#top',
];
$data[] = [
'test_2',
[
'narf' => '5',
],
[
'query' => [
'page' => '1',
],
'fragment' => 'bottom',
],
'/goodbye/cruel/world?page=1#bottom',
];
$data[] = [
'test_2',
[
'narf' => '7',
],
[
'query' => [
'page' => '1',
],
'fragment' => 'bottom',
],
'/test/two/7?page=1#bottom',
];
$data[] = [
'test_2',
[
'narf' => '7',
],
[
'query' => [
'page' => '1/2',
],
'fragment' => 'bottom',
],
'/test/two/7?page=1/2#bottom',
];
return $data;
}
public function testGetPathFromRouteTrailing() {
$this->routeProcessorManager
->expects($this
->once())
->method('processOutbound');
$path = $this->generator
->getPathFromRoute('test_3');
$this
->assertEquals($path, 'test/two');
}
public function testAbsoluteURLGeneration() {
$url = $this->generator
->generate('test_1', array(), TRUE);
$this
->assertEquals('http://localhost/hello/world', $url);
$this->routeProcessorManager
->expects($this
->exactly(2))
->method('processOutbound')
->with($this
->anything());
$options = array(
'absolute' => TRUE,
'fragment' => 'top',
);
$this
->assertGenerateFromRoute('test_1', [
'zoo' => 5,
], $options, 'http://localhost/hello/world?zoo=5#top', (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT)
->setCacheContexts([
'url.site',
]));
}
public function testBaseURLGeneration() {
$options = array(
'base_url' => 'http://www.example.com:8888',
);
$this
->assertGenerateFromRoute('test_1', [], $options, 'http://www.example.com:8888/hello/world', (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT));
$options = array(
'base_url' => 'http://www.example.com:8888',
'https' => TRUE,
);
$this
->assertGenerateFromRoute('test_1', [], $options, 'https://www.example.com:8888/hello/world', (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT));
$options = array(
'base_url' => 'https://www.example.com:8888',
'https' => FALSE,
);
$this
->assertGenerateFromRoute('test_1', [], $options, 'http://www.example.com:8888/hello/world', (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT));
$this->routeProcessorManager
->expects($this
->exactly(2))
->method('processOutbound')
->with($this
->anything());
$options = array(
'base_url' => 'http://www.example.com:8888',
'fragment' => 'top',
);
$this
->assertGenerateFromRoute('test_1', [
'zoo' => 5,
], $options, 'http://www.example.com:8888/hello/world?zoo=5#top', (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT));
}
public function testUrlGenerationWithHttpsRequirement() {
$url = $this->generator
->generate('test_4', array(), TRUE);
$this
->assertEquals('https://localhost/test/four', $url);
$this->routeProcessorManager
->expects($this
->exactly(2))
->method('processOutbound')
->with($this
->anything());
$options = array(
'absolute' => TRUE,
'https' => TRUE,
);
$this
->assertGenerateFromRoute('test_1', [], $options, 'https://localhost/hello/world', (new BubbleableMetadata())
->setCacheMaxAge(Cache::PERMANENT)
->setCacheContexts([
'url.site',
]));
}
public function testNoPath($options, $expected_url) {
$url = $this->generator
->generateFromRoute('<none>', [], $options);
$this
->assertEquals($expected_url, $url);
}
public function providerTestNoPath() {
return [
[
[],
'',
],
[
[
'query' => [
'foo' => 'bar',
],
],
'?foo=bar',
],
[
[
'query' => [
'foo' => 'bar',
'baz' => '',
],
],
'?foo=bar&baz=',
],
[
[
'fragment' => 'foo',
],
'#foo',
],
[
[
'query' => [
'bar' => 'baz',
],
'fragment' => 'foo',
],
'?bar=baz#foo',
],
[
[
'query' => [
'bar' => 'baz',
'foo' => 'bar',
],
'fragment' => 'foo',
],
'?bar=baz&foo=bar#foo',
],
];
}
protected function assertGenerateFromRoute($route_name, array $route_parameters, array $options, $expected_url, BubbleableMetadata $expected_bubbleable_metadata) {
$url = $this->generator
->generateFromRoute($route_name, $route_parameters, $options);
$this
->assertSame($expected_url, $url);
$generated_url = $this->generator
->generateFromRoute($route_name, $route_parameters, $options, TRUE);
$this
->assertSame($expected_url, $generated_url
->getGeneratedUrl());
$this
->assertEquals($expected_bubbleable_metadata, BubbleableMetadata::createFromObject($generated_url));
}
}