2 namespace TYPO3\CMS\Core\Tests\Unit\Http
;
5 * This file is part of the TYPO3 CMS project.
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
14 * The TYPO3 project - inspiring people to share!
17 use TYPO3\CMS\Core\Http\Uri
;
20 * Testcase for \TYPO3\CMS\Core\Http\Uri
22 * Adapted from https://github.com/phly/http/
24 class UriTest
extends \TYPO3\CMS\Core\Tests\UnitTestCase
29 public function constructorSetsAllProperties()
31 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
32 $this->assertEquals('https', $uri->getScheme());
33 $this->assertEquals('user:pass', $uri->getUserInfo());
34 $this->assertEquals('local.example.com', $uri->getHost());
35 $this->assertEquals(3001, $uri->getPort());
36 $this->assertEquals('user:pass@local.example.com:3001', $uri->getAuthority());
37 $this->assertEquals('/foo', $uri->getPath());
38 $this->assertEquals('bar=baz', $uri->getQuery());
39 $this->assertEquals('quz', $uri->getFragment());
45 public function canSerializeToString()
47 $url = 'https://user:pass@local.example.com:3001/foo?bar=baz#quz';
49 $this->assertEquals($url, (string) $uri);
55 public function withSchemeReturnsNewInstanceWithNewScheme()
57 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
58 $new = $uri->withScheme('http');
59 $this->assertNotSame($uri, $new);
60 $this->assertEquals('http', $new->getScheme());
61 $this->assertEquals('http://user:pass@local.example.com:3001/foo?bar=baz#quz', (string) $new);
67 public function withUserInfoReturnsNewInstanceWithProvidedUser()
69 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
70 $new = $uri->withUserInfo('matthew');
71 $this->assertNotSame($uri, $new);
72 $this->assertEquals('matthew', $new->getUserInfo());
73 $this->assertEquals('https://matthew@local.example.com:3001/foo?bar=baz#quz', (string) $new);
79 public function withUserInfoReturnsNewInstanceWithProvidedUserAndPassword()
81 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
82 $new = $uri->withUserInfo('matthew', 'zf2');
83 $this->assertNotSame($uri, $new);
84 $this->assertEquals('matthew:zf2', $new->getUserInfo());
85 $this->assertEquals('https://matthew:zf2@local.example.com:3001/foo?bar=baz#quz', (string) $new);
91 public function withHostReturnsNewInstanceWithProvidedHost()
93 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
94 $new = $uri->withHost('framework.zend.com');
95 $this->assertNotSame($uri, $new);
96 $this->assertEquals('framework.zend.com', $new->getHost());
97 $this->assertEquals('https://user:pass@framework.zend.com:3001/foo?bar=baz#quz', (string) $new);
103 public function validPortsDataProvider()
112 * @dataProvider validPortsDataProvider
115 public function withPortReturnsNewInstanceWithProvidedPort($port)
117 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
118 $new = $uri->withPort($port);
119 $this->assertNotSame($uri, $new);
120 $this->assertEquals($port, $new->getPort());
122 sprintf('https://user:pass@local.example.com:%d/foo?bar=baz#quz', $port),
130 public function invalidPortsDataProvider()
136 'string' => ['string'],
138 'object' => [(object) [3000]],
141 'too-big' => [65536],
146 * @dataProvider invalidPortsDataProvider
148 public function withPortRaisesExceptionForInvalidPorts($port)
150 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
151 $this->setExpectedException('InvalidArgumentException', 'Invalid port');
152 $new = $uri->withPort($port);
158 public function withPathReturnsNewInstanceWithProvidedPath()
160 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
161 $new = $uri->withPath('/bar/baz');
162 $this->assertNotSame($uri, $new);
163 $this->assertEquals('/bar/baz', $new->getPath());
164 $this->assertEquals('https://user:pass@local.example.com:3001/bar/baz?bar=baz#quz', (string) $new);
170 public function invalidPathsDataProvider()
176 'array' => [['/bar/baz']],
177 'object' => [(object) ['/bar/baz']],
178 'query' => ['/bar/baz?bat=quz'],
179 'fragment' => ['/bar/baz#bat'],
184 * @dataProvider invalidPathsDataProvider
187 public function withPathRaisesExceptionForInvalidPaths($path)
189 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
190 $this->setExpectedException('InvalidArgumentException', 'Invalid path');
191 $new = $uri->withPath($path);
197 public function withQueryReturnsNewInstanceWithProvidedQuery()
199 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
200 $new = $uri->withQuery('baz=bat');
201 $this->assertNotSame($uri, $new);
202 $this->assertEquals('baz=bat', $new->getQuery());
203 $this->assertEquals('https://user:pass@local.example.com:3001/foo?baz=bat#quz', (string) $new);
209 public function invalidQueryStringsDataProvider()
215 'array' => [['baz=bat']],
216 'object' => [(object) ['baz=bat']],
217 'fragment' => ['baz=bat#quz'],
222 * @dataProvider invalidQueryStringsDataProvider
225 public function withQueryRaisesExceptionForInvalidQueryStrings($query)
227 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
228 $this->setExpectedException('InvalidArgumentException', 'Query string');
229 $new = $uri->withQuery($query);
235 public function withFragmentReturnsNewInstanceWithProvidedFragment()
237 $uri = new Uri('https://user:pass@local.example.com:3001/foo?bar=baz#quz');
238 $new = $uri->withFragment('qat');
239 $this->assertNotSame($uri, $new);
240 $this->assertEquals('qat', $new->getFragment());
241 $this->assertEquals('https://user:pass@local.example.com:3001/foo?bar=baz#qat', (string) $new);
247 public function authorityInfoDataProvider()
250 'host-only' => ['http://foo.com/bar', 'foo.com'],
251 'host-port' => ['http://foo.com:3000/bar', 'foo.com:3000'],
252 'user-host' => ['http://me@foo.com/bar', 'me@foo.com'],
253 'user-host-port' => ['http://me@foo.com:3000/bar', 'me@foo.com:3000'],
258 * @dataProvider authorityInfoDataProvider
261 public function getAuthorityReturnsExpectedValues($url, $expected)
263 $uri = new Uri($url);
264 $this->assertEquals($expected, $uri->getAuthority());
270 public function canEmitOriginFormUrl()
272 $url = '/foo/bar?baz=bat';
273 $uri = new Uri($url);
274 $this->assertEquals($url, (string) $uri);
280 public function settingEmptyPathOnAbsoluteUriReturnsAnEmptyPath()
282 $uri = new Uri('http://example.com/foo');
283 $new = $uri->withPath('');
284 $this->assertEquals('', $new->getPath());
290 public function stringRepresentationOfAbsoluteUriWithNoPathSetsAnEmptyPath()
292 $uri = new Uri('http://example.com');
293 $this->assertEquals('http://example.com', (string) $uri);
299 public function getPathOnOriginFormRemainsAnEmptyPath()
301 $uri = new Uri('?foo=bar');
302 $this->assertEquals('', $uri->getPath());
308 public function stringRepresentationOfOriginFormWithNoPathRetainsEmptyPath()
310 $uri = new Uri('?foo=bar');
311 $this->assertEquals('?foo=bar', (string) $uri);
317 public function invalidConstructorUrisDataProvider()
325 'array' => [['http://example.com/']],
326 'object' => [(object) ['uri' => 'http://example.com/']],
331 * @dataProvider invalidConstructorUrisDataProvider
333 public function constructorRaisesExceptionForNonStringURI($uri)
335 $this->setExpectedException('InvalidArgumentException');
342 public function constructorRaisesExceptionForSeriouslyMalformedURI()
344 $this->setExpectedException('InvalidArgumentException');
345 new Uri('http:///www.php-fig.org/');
351 public function withSchemeStripsOffDelimiter()
353 $uri = new Uri('http://example.com');
354 $new = $uri->withScheme('https://');
355 $this->assertEquals('https', $new->getScheme());
361 public function invalidSchemesDataProvider()
364 'mailto' => ['mailto'],
366 'telnet' => ['telnet'],
373 * @dataProvider invalidSchemesDataProvider
376 public function constructWithUnsupportedSchemeRaisesAnException($scheme)
378 $this->setExpectedException('InvalidArgumentException', 'Unsupported scheme');
379 $uri = new Uri($scheme . '://example.com');
383 * @dataProvider invalidSchemesDataProvider
386 public function withSchemeUsingUnsupportedSchemeRaisesAnException($scheme)
388 $uri = new Uri('http://example.com');
389 $this->setExpectedException('InvalidArgumentException', 'Unsupported scheme');
390 $uri->withScheme($scheme);
396 public function withPathIsNotPrefixedWithSlashIfSetWithoutOne()
398 $uri = new Uri('http://example.com');
399 $new = $uri->withPath('foo/bar');
400 $this->assertEquals('foo/bar', $new->getPath());
406 public function withPathNotSlashPrefixedIsEmittedWithSlashDelimiterWhenUriIsCastToString()
408 $uri = new Uri('http://example.com');
409 $new = $uri->withPath('foo/bar');
410 $this->assertEquals('http://example.com/foo/bar', $new->__toString());
416 public function withQueryStripsQueryPrefixIfPresent()
418 $uri = new Uri('http://example.com');
419 $new = $uri->withQuery('?foo=bar');
420 $this->assertEquals('foo=bar', $new->getQuery());
426 public function withFragmentStripsFragmentPrefixIfPresent()
428 $uri = new Uri('http://example.com');
429 $new = $uri->withFragment('#/foo/bar');
430 $this->assertEquals('/foo/bar', $new->getFragment());
436 public function standardSchemePortCombinationsDataProvider()
439 'http' => ['http', 80],
440 'https' => ['https', 443],
445 * @dataProvider standardSchemePortCombinationsDataProvider
448 public function getAuthorityOmitsPortForStandardSchemePortCombinations($scheme, $port)
451 ->withHost('example.com')
452 ->withScheme($scheme)
454 $this->assertEquals('example.com', $uri->getAuthority());
460 public function getPathIsProperlyEncoded()
462 $uri = (new Uri())->withPath('/foo^bar');
463 $expected = '/foo%5Ebar';
464 $this->assertEquals($expected, $uri->getPath());
470 public function getPathDoesNotBecomeDoubleEncoded()
472 $uri = (new Uri())->withPath('/foo%5Ebar');
473 $expected = '/foo%5Ebar';
474 $this->assertEquals($expected, $uri->getPath());
480 public function queryStringsForEncodingDataProvider()
483 'key-only' => ['k^ey', 'k%5Eey'],
484 'key-value' => ['k^ey=valu`', 'k%5Eey=valu%60'],
485 'array-key-only' => ['key[]', 'key%5B%5D'],
486 'array-key-value' => ['key[]=valu`', 'key%5B%5D=valu%60'],
487 'complex' => ['k^ey&key[]=valu`&f<>=`bar', 'k%5Eey&key%5B%5D=valu%60&f%3C%3E=%60bar'],
492 * @dataProvider queryStringsForEncodingDataProvider
495 public function getQueryIsProperlyEncoded($query, $expected)
497 $uri = (new Uri())->withQuery($query);
498 $this->assertEquals($expected, $uri->getQuery());
502 * @dataProvider queryStringsForEncodingDataProvider
505 public function getQueryIsNotDoubleEncoded($query, $expected)
507 $uri = (new Uri())->withQuery($expected);
508 $this->assertEquals($expected, $uri->getQuery());
514 public function getFragmentIsProperlyEncoded()
516 $uri = (new Uri())->withFragment('/p^th?key^=`bar#b@z');
517 $expected = '/p%5Eth?key%5E=%60bar%23b@z';
518 $this->assertEquals($expected, $uri->getFragment());
524 public function getFragmentIsNotDoubleEncoded()
526 $expected = '/p%5Eth?key%5E=%60bar%23b@z';
527 $uri = (new Uri())->withFragment($expected);
528 $this->assertEquals($expected, $uri->getFragment());