Security update for Core, with self-updated composer
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Utility / UnroutedUrlAssemblerTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Utility;
4
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;
11
12 /**
13  * @coversDefaultClass \Drupal\Core\Utility\UnroutedUrlAssembler
14  * @group Utility
15  */
16 class UnroutedUrlAssemblerTest extends UnitTestCase {
17
18   /**
19    * The request stack.
20    *
21    * @var \Symfony\Component\HttpFoundation\RequestStack
22    */
23   protected $requestStack;
24
25   /**
26    * The mocked config factory.
27    *
28    * @var \Drupal\Core\Config\ConfigFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
29    */
30   protected $configFactory;
31
32   /**
33    * The tested unrouted URL assembler.
34    *
35    * @var \Drupal\Core\Utility\UnroutedUrlAssembler
36    */
37   protected $unroutedUrlAssembler;
38
39   /**
40    * The mocked outbound path processor.
41    *
42    * @var \Drupal\Core\PathProcessor\OutboundPathProcessorInterface|\PHPUnit_Framework_MockObject_MockObject
43    */
44   protected $pathProcessor;
45
46   /**
47    * {@inheritdoc}
48    */
49   protected function setUp() {
50     parent::setUp();
51
52     $this->requestStack = new RequestStack();
53     $this->pathProcessor = $this->getMock('Drupal\Core\PathProcessor\OutboundPathProcessorInterface');
54     $this->unroutedUrlAssembler = new UnroutedUrlAssembler($this->requestStack, $this->pathProcessor);
55   }
56
57   /**
58    * @covers ::assemble
59    */
60   public function testAssembleWithNeitherExternalNorDomainLocalUri() {
61     $this->setExpectedException(\InvalidArgumentException::class);
62     $this->unroutedUrlAssembler->assemble('wrong-url');
63   }
64
65   /**
66    * @covers ::assemble
67    */
68   public function testAssembleWithLeadingSlash() {
69     $this->setExpectedException(\InvalidArgumentException::class);
70     $this->unroutedUrlAssembler->assemble('/drupal.org');
71   }
72
73   /**
74    * @covers ::assemble
75    * @covers ::buildExternalUrl
76    *
77    * @dataProvider providerTestAssembleWithExternalUrl
78    */
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);
85   }
86
87   /**
88    * Provides test data for testAssembleWithExternalUrl
89    */
90   public function providerTestAssembleWithExternalUrl() {
91     return [
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'],
100     ];
101   }
102
103   /**
104    * @covers ::assemble
105    * @covers::buildLocalUrl
106    *
107    * @dataProvider providerTestAssembleWithLocalUri
108    */
109   public function testAssembleWithLocalUri($uri, array $options, $subdir, $expected) {
110     $this->setupRequestStack($subdir);
111
112     $this->assertEquals($expected, $this->unroutedUrlAssembler->assemble($uri, $options));
113   }
114
115   /**
116    * @return array
117    */
118   public function providerTestAssembleWithLocalUri() {
119     return [
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'],
129     ];
130   }
131
132   /**
133    * @covers ::assemble
134    */
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);
141   }
142
143   /**
144    * @covers ::assemble
145    */
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']);
153         }
154         return 'test-other-uri';
155       });
156
157     $result = $this->unroutedUrlAssembler->assemble('base:test-uri', ['path_processing' => TRUE]);
158     $this->assertEquals('/test-other-uri', $result);
159
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);
165   }
166
167   /**
168    * Setups the request stack for a given subdir.
169    *
170    * @param string $subdir
171    *   The wanted subdir.
172    */
173   protected function setupRequestStack($subdir) {
174     $server = [];
175     if ($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.
179       $server = [
180         'SCRIPT_NAME' => '/subdir/index.php',
181         'SCRIPT_FILENAME' => $this->root . '/index.php',
182         'SERVER_NAME' => 'http://www.example.com',
183       ];
184       $request = Request::create('/subdir/');
185     }
186     else {
187       $request = Request::create('/');
188     }
189     $request->server->add($server);
190     $this->requestStack->push($request);
191   }
192
193 }