3 namespace Drupal\Tests\Core\Utility;
5 use Drupal\Core\GeneratedUrl;
6 use Drupal\Core\Render\BubbleableMetadata;
7 use Drupal\Core\Utility\UnroutedUrlAssembler;
8 use Drupal\Tests\UnitTestCase;
9 use Symfony\Component\HttpFoundation\Request;
10 use Symfony\Component\HttpFoundation\RequestStack;
13 * @coversDefaultClass \Drupal\Core\Utility\UnroutedUrlAssembler
16 class UnroutedUrlAssemblerTest extends UnitTestCase {
21 * @var \Symfony\Component\HttpFoundation\RequestStack
23 protected $requestStack;
26 * The mocked config factory.
28 * @var \Drupal\Core\Config\ConfigFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
30 protected $configFactory;
33 * The tested unrouted URL assembler.
35 * @var \Drupal\Core\Utility\UnroutedUrlAssembler
37 protected $unroutedUrlAssembler;
40 * The mocked outbound path processor.
42 * @var \Drupal\Core\PathProcessor\OutboundPathProcessorInterface|\PHPUnit_Framework_MockObject_MockObject
44 protected $pathProcessor;
49 protected function setUp() {
52 $this->requestStack = new RequestStack();
53 $this->pathProcessor = $this->getMock('Drupal\Core\PathProcessor\OutboundPathProcessorInterface');
54 $this->unroutedUrlAssembler = new UnroutedUrlAssembler($this->requestStack, $this->pathProcessor);
60 public function testAssembleWithNeitherExternalNorDomainLocalUri() {
61 $this->setExpectedException(\InvalidArgumentException::class);
62 $this->unroutedUrlAssembler->assemble('wrong-url');
68 public function testAssembleWithLeadingSlash() {
69 $this->setExpectedException(\InvalidArgumentException::class);
70 $this->unroutedUrlAssembler->assemble('/drupal.org');
75 * @covers ::buildExternalUrl
77 * @dataProvider providerTestAssembleWithExternalUrl
79 public function testAssembleWithExternalUrl($uri, array $options, $expected) {
80 $this->setupRequestStack(FALSE);
81 $this->assertEquals($expected, $this->unroutedUrlAssembler->assemble($uri, $options));
82 $generated_url = $this->unroutedUrlAssembler->assemble($uri, $options, TRUE);
83 $this->assertEquals($expected, $generated_url->getGeneratedUrl());
84 $this->assertInstanceOf('\Drupal\Core\Render\BubbleableMetadata', $generated_url);
88 * Provides test data for testAssembleWithExternalUrl
90 public function providerTestAssembleWithExternalUrl() {
92 ['http://example.com/test', [], 'http://example.com/test'],
93 ['http://example.com/test', ['fragment' => 'example'], 'http://example.com/test#example'],
94 ['http://example.com/test', ['fragment' => 'example'], 'http://example.com/test#example'],
95 ['http://example.com/test', ['query' => ['foo' => 'bar']], 'http://example.com/test?foo=bar'],
96 ['http://example.com/test', ['https' => TRUE], 'https://example.com/test'],
97 ['https://example.com/test', ['https' => FALSE], 'http://example.com/test'],
98 ['https://example.com/test?foo=1#bar', [], 'https://example.com/test?foo=1#bar'],
99 ['//www.drupal.org', [], '//www.drupal.org'],
105 * @covers::buildLocalUrl
107 * @dataProvider providerTestAssembleWithLocalUri
109 public function testAssembleWithLocalUri($uri, array $options, $subdir, $expected) {
110 $this->setupRequestStack($subdir);
112 $this->assertEquals($expected, $this->unroutedUrlAssembler->assemble($uri, $options));
118 public function providerTestAssembleWithLocalUri() {
120 ['base:example', [], FALSE, '/example'],
121 ['base:example', ['query' => ['foo' => 'bar']], FALSE, '/example?foo=bar'],
122 ['base:example', ['query' => ['foo' => '"bar"']], FALSE, '/example?foo=%22bar%22'],
123 ['base:example', ['query' => ['foo' => '"bar"', 'zoo' => 'baz']], FALSE, '/example?foo=%22bar%22&zoo=baz'],
124 ['base:example', ['fragment' => 'example'], FALSE, '/example#example'],
125 ['base:example', [], TRUE, '/subdir/example'],
126 ['base:example', ['query' => ['foo' => 'bar']], TRUE, '/subdir/example?foo=bar'],
127 ['base:example', ['fragment' => 'example'], TRUE, '/subdir/example#example'],
128 ['base:/drupal.org', [], FALSE, '/drupal.org'],
135 public function testAssembleWithNotEnabledProcessing() {
136 $this->setupRequestStack(FALSE);
137 $this->pathProcessor->expects($this->never())
138 ->method('processOutbound');
139 $result = $this->unroutedUrlAssembler->assemble('base:test-uri', []);
140 $this->assertEquals('/test-uri', $result);
146 public function testAssembleWithEnabledProcessing() {
147 $this->setupRequestStack(FALSE);
148 $this->pathProcessor->expects($this->exactly(2))
149 ->method('processOutbound')
150 ->willReturnCallback(function ($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
151 if ($bubbleable_metadata) {
152 $bubbleable_metadata->setCacheContexts(['some-cache-context']);
154 return 'test-other-uri';
157 $result = $this->unroutedUrlAssembler->assemble('base:test-uri', ['path_processing' => TRUE]);
158 $this->assertEquals('/test-other-uri', $result);
160 $result = $this->unroutedUrlAssembler->assemble('base:test-uri', ['path_processing' => TRUE], TRUE);
161 $expected_generated_url = new GeneratedUrl();
162 $expected_generated_url->setGeneratedUrl('/test-other-uri')
163 ->setCacheContexts(['some-cache-context']);
164 $this->assertEquals($expected_generated_url, $result);
168 * Setups the request stack for a given subdir.
170 * @param string $subdir
173 protected function setupRequestStack($subdir) {
176 // Setup a fake request which looks like a Drupal installed under the
177 // subdir "subdir" on the domain www.example.com.
178 // To reproduce the values install Drupal like that and use a debugger.
180 'SCRIPT_NAME' => '/subdir/index.php',
181 'SCRIPT_FILENAME' => $this->root . '/index.php',
182 'SERVER_NAME' => 'http://www.example.com',
184 $request = Request::create('/subdir/');
187 $request = Request::create('/');
189 $request->server->add($server);
190 $this->requestStack->push($request);