PluginProbe
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more / 2.5.4
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more v2.5.4
3.7.2 3.7.1 3.7.0 3.6.0 3.6.1 3.5.2 trunk 2.0 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.6.0 2.6.1 All 73 releases
stockpack / vendor / guzzlehttp / psr7 / tests / UriTest.php

UriTest.php in StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more 2.5.4, at vendor/guzzlehttp/psr7/tests/UriTest.php

705 lines 25.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace GuzzleHttp\Tests\Psr7;
3
4 use GuzzleHttp\Psr7\Uri;
5
6 /**
7 * @covers GuzzleHttp\Psr7\Uri
8 */
9 class UriTest extends BaseTest
10 {
11 public function testParsesProvidedUri()
12 {
13 $uri = new Uri('https://user:[email protected]:8080/path/123?q=abc#test');
14
15 $this->assertSame('https', $uri->getScheme());
16 $this->assertSame('user:[email protected]:8080', $uri->getAuthority());
17 $this->assertSame('user:pass', $uri->getUserInfo());
18 $this->assertSame('example.com', $uri->getHost());
19 $this->assertSame(8080, $uri->getPort());
20 $this->assertSame('/path/123', $uri->getPath());
21 $this->assertSame('q=abc', $uri->getQuery());
22 $this->assertSame('test', $uri->getFragment());
23 $this->assertSame('https://user:[email protected]:8080/path/123?q=abc#test', (string) $uri);
24 }
25
26 public function testCanTransformAndRetrievePartsIndividually()
27 {
28 $uri = (new Uri())
29 ->withScheme('https')
30 ->withUserInfo('user', 'pass')
31 ->withHost('example.com')
32 ->withPort(8080)
33 ->withPath('/path/123')
34 ->withQuery('q=abc')
35 ->withFragment('test');
36
37 $this->assertSame('https', $uri->getScheme());
38 $this->assertSame('user:[email protected]:8080', $uri->getAuthority());
39 $this->assertSame('user:pass', $uri->getUserInfo());
40 $this->assertSame('example.com', $uri->getHost());
41 $this->assertSame(8080, $uri->getPort());
42 $this->assertSame('/path/123', $uri->getPath());
43 $this->assertSame('q=abc', $uri->getQuery());
44 $this->assertSame('test', $uri->getFragment());
45 $this->assertSame('https://user:[email protected]:8080/path/123?q=abc#test', (string) $uri);
46 }
47
48 /**
49 * @dataProvider getValidUris
50 */
51 public function testValidUrisStayValid($input)
52 {
53 $uri = new Uri($input);
54
55 $this->assertSame($input, (string) $uri);
56 }
57
58 /**
59 * @dataProvider getValidUris
60 */
61 public function testFromParts($input)
62 {
63 $uri = Uri::fromParts(parse_url($input));
64
65 $this->assertSame($input, (string) $uri);
66 }
67
68 public function getValidUris()
69 {
70 return [
71 ['urn:path-rootless'],
72 ['urn:path:with:colon'],
73 ['urn:/path-absolute'],
74 ['urn:/'],
75 // only scheme with empty path
76 ['urn:'],
77 // only path
78 ['/'],
79 ['relative/'],
80 ['0'],
81 // same document reference
82 [''],
83 // network path without scheme
84 ['//example.org'],
85 ['//example.org/'],
86 ['//example.org?q#h'],
87 // only query
88 ['?q'],
89 ['?q=abc&foo=bar'],
90 // only fragment
91 ['#fragment'],
92 // dot segments are not removed automatically
93 ['./foo/../bar'],
94 ];
95 }
96
97 /**
98 * @expectedException \InvalidArgumentException
99 * @expectedExceptionMessage Unable to parse URI
100 * @dataProvider getInvalidUris
101 */
102 public function testInvalidUrisThrowException($invalidUri)
103 {
104 new Uri($invalidUri);
105 }
106
107 public function getInvalidUris()
108 {
109 return [
110 // parse_url() requires the host component which makes sense for http(s)
111 // but not when the scheme is not known or different. So '//' or '///' is
112 // currently invalid as well but should not according to RFC 3986.
113 ['http://'],
114 ['urn://host:with:colon'], // host cannot contain ":"
115 ];
116 }
117
118 /**
119 * @expectedException \InvalidArgumentException
120 * @expectedExceptionMessage Invalid port: 100000. Must be between 0 and 65535
121 */
122 public function testPortMustBeValid()
123 {
124 (new Uri())->withPort(100000);
125 }
126
127 /**
128 * @expectedException \InvalidArgumentException
129 * @expectedExceptionMessage Invalid port: -1. Must be between 0 and 65535
130 */
131 public function testWithPortCannotBeNegative()
132 {
133 (new Uri())->withPort(-1);
134 }
135
136 /**
137 * @expectedException \InvalidArgumentException
138 * @expectedExceptionMessage Unable to parse URI
139 */
140 public function testParseUriPortCannotBeZero()
141 {
142 new Uri('//example.com:0');
143 }
144
145 /**
146 * @expectedException \InvalidArgumentException
147 */
148 public function testSchemeMustHaveCorrectType()
149 {
150 (new Uri())->withScheme([]);
151 }
152
153 /**
154 * @expectedException \InvalidArgumentException
155 */
156 public function testHostMustHaveCorrectType()
157 {
158 (new Uri())->withHost([]);
159 }
160
161 /**
162 * @expectedException \InvalidArgumentException
163 */
164 public function testPathMustHaveCorrectType()
165 {
166 (new Uri())->withPath([]);
167 }
168
169 /**
170 * @expectedException \InvalidArgumentException
171 */
172 public function testQueryMustHaveCorrectType()
173 {
174 (new Uri())->withQuery([]);
175 }
176
177 /**
178 * @expectedException \InvalidArgumentException
179 */
180 public function testFragmentMustHaveCorrectType()
181 {
182 (new Uri())->withFragment([]);
183 }
184
185 public function testCanParseFalseyUriParts()
186 {
187 $uri = new Uri('0://0:0@0/0?0#0');
188
189 $this->assertSame('0', $uri->getScheme());
190 $this->assertSame('0:0@0', $uri->getAuthority());
191 $this->assertSame('0:0', $uri->getUserInfo());
192 $this->assertSame('0', $uri->getHost());
193 $this->assertSame('/0', $uri->getPath());
194 $this->assertSame('0', $uri->getQuery());
195 $this->assertSame('0', $uri->getFragment());
196 $this->assertSame('0://0:0@0/0?0#0', (string) $uri);
197 }
198
199 public function testCanConstructFalseyUriParts()
200 {
201 $uri = (new Uri())
202 ->withScheme('0')
203 ->withUserInfo('0', '0')
204 ->withHost('0')
205 ->withPath('/0')
206 ->withQuery('0')
207 ->withFragment('0');
208
209 $this->assertSame('0', $uri->getScheme());
210 $this->assertSame('0:0@0', $uri->getAuthority());
211 $this->assertSame('0:0', $uri->getUserInfo());
212 $this->assertSame('0', $uri->getHost());
213 $this->assertSame('/0', $uri->getPath());
214 $this->assertSame('0', $uri->getQuery());
215 $this->assertSame('0', $uri->getFragment());
216 $this->assertSame('0://0:0@0/0?0#0', (string) $uri);
217 }
218
219 /**
220 * @dataProvider getPortTestCases
221 */
222 public function testIsDefaultPort($scheme, $port, $isDefaultPort)
223 {
224 $uri = $this->getMockBuilder('Psr\Http\Message\UriInterface')->getMock();
225 $uri->expects($this->any())->method('getScheme')->will($this->returnValue($scheme));
226 $uri->expects($this->any())->method('getPort')->will($this->returnValue($port));
227
228 $this->assertSame($isDefaultPort, Uri::isDefaultPort($uri));
229 }
230
231 public function getPortTestCases()
232 {
233 return [
234 ['http', null, true],
235 ['http', 80, true],
236 ['http', 8080, false],
237 ['https', null, true],
238 ['https', 443, true],
239 ['https', 444, false],
240 ['ftp', 21, true],
241 ['gopher', 70, true],
242 ['nntp', 119, true],
243 ['news', 119, true],
244 ['telnet', 23, true],
245 ['tn3270', 23, true],
246 ['imap', 143, true],
247 ['pop', 110, true],
248 ['ldap', 389, true],
249 ];
250 }
251
252 public function testIsAbsolute()
253 {
254 $this->assertTrue(Uri::isAbsolute(new Uri('http://example.org')));
255 $this->assertFalse(Uri::isAbsolute(new Uri('//example.org')));
256 $this->assertFalse(Uri::isAbsolute(new Uri('/abs-path')));
257 $this->assertFalse(Uri::isAbsolute(new Uri('rel-path')));
258 }
259
260 public function testIsNetworkPathReference()
261 {
262 $this->assertFalse(Uri::isNetworkPathReference(new Uri('http://example.org')));
263 $this->assertTrue(Uri::isNetworkPathReference(new Uri('//example.org')));
264 $this->assertFalse(Uri::isNetworkPathReference(new Uri('/abs-path')));
265 $this->assertFalse(Uri::isNetworkPathReference(new Uri('rel-path')));
266 }
267
268 public function testIsAbsolutePathReference()
269 {
270 $this->assertFalse(Uri::isAbsolutePathReference(new Uri('http://example.org')));
271 $this->assertFalse(Uri::isAbsolutePathReference(new Uri('//example.org')));
272 $this->assertTrue(Uri::isAbsolutePathReference(new Uri('/abs-path')));
273 $this->assertTrue(Uri::isAbsolutePathReference(new Uri('/')));
274 $this->assertFalse(Uri::isAbsolutePathReference(new Uri('rel-path')));
275 }
276
277 public function testIsRelativePathReference()
278 {
279 $this->assertFalse(Uri::isRelativePathReference(new Uri('http://example.org')));
280 $this->assertFalse(Uri::isRelativePathReference(new Uri('//example.org')));
281 $this->assertFalse(Uri::isRelativePathReference(new Uri('/abs-path')));
282 $this->assertTrue(Uri::isRelativePathReference(new Uri('rel-path')));
283 $this->assertTrue(Uri::isRelativePathReference(new Uri('')));
284 }
285
286 public function testIsSameDocumentReference()
287 {
288 $this->assertFalse(Uri::isSameDocumentReference(new Uri('http://example.org')));
289 $this->assertFalse(Uri::isSameDocumentReference(new Uri('//example.org')));
290 $this->assertFalse(Uri::isSameDocumentReference(new Uri('/abs-path')));
291 $this->assertFalse(Uri::isSameDocumentReference(new Uri('rel-path')));
292 $this->assertFalse(Uri::isSameDocumentReference(new Uri('?query')));
293 $this->assertTrue(Uri::isSameDocumentReference(new Uri('')));
294 $this->assertTrue(Uri::isSameDocumentReference(new Uri('#fragment')));
295
296 $baseUri = new Uri('http://example.org/path?foo=bar');
297
298 $this->assertTrue(Uri::isSameDocumentReference(new Uri('#fragment'), $baseUri));
299 $this->assertTrue(Uri::isSameDocumentReference(new Uri('?foo=bar#fragment'), $baseUri));
300 $this->assertTrue(Uri::isSameDocumentReference(new Uri('/path?foo=bar#fragment'), $baseUri));
301 $this->assertTrue(Uri::isSameDocumentReference(new Uri('path?foo=bar#fragment'), $baseUri));
302 $this->assertTrue(Uri::isSameDocumentReference(new Uri('//example.org/path?foo=bar#fragment'), $baseUri));
303 $this->assertTrue(Uri::isSameDocumentReference(new Uri('http://example.org/path?foo=bar#fragment'), $baseUri));
304
305 $this->assertFalse(Uri::isSameDocumentReference(new Uri('https://example.org/path?foo=bar'), $baseUri));
306 $this->assertFalse(Uri::isSameDocumentReference(new Uri('http://example.com/path?foo=bar'), $baseUri));
307 $this->assertFalse(Uri::isSameDocumentReference(new Uri('http://example.org/'), $baseUri));
308 $this->assertFalse(Uri::isSameDocumentReference(new Uri('http://example.org'), $baseUri));
309
310 $this->assertFalse(Uri::isSameDocumentReference(new Uri('urn:/path'), new Uri('urn://example.com/path')));
311 }
312
313 public function testAddAndRemoveQueryValues()
314 {
315 $uri = new Uri();
316 $uri = Uri::withQueryValue($uri, 'a', 'b');
317 $uri = Uri::withQueryValue($uri, 'c', 'd');
318 $uri = Uri::withQueryValue($uri, 'e', null);
319 $this->assertSame('a=b&c=d&e', $uri->getQuery());
320
321 $uri = Uri::withoutQueryValue($uri, 'c');
322 $this->assertSame('a=b&e', $uri->getQuery());
323 $uri = Uri::withoutQueryValue($uri, 'e');
324 $this->assertSame('a=b', $uri->getQuery());
325 $uri = Uri::withoutQueryValue($uri, 'a');
326 $this->assertSame('', $uri->getQuery());
327 }
328
329 public function testNumericQueryValue()
330 {
331 $uri = Uri::withQueryValue(new Uri(), 'version', 1);
332 $this->assertSame('version=1', $uri->getQuery());
333 }
334
335 public function testWithQueryValues()
336 {
337 $uri = new Uri();
338 $uri = Uri::withQueryValues($uri, [
339 'key1' => 'value1',
340 'key2' => 'value2'
341 ]);
342
343 $this->assertSame('key1=value1&key2=value2', $uri->getQuery());
344 }
345
346 public function testWithQueryValuesReplacesSameKeys()
347 {
348 $uri = new Uri();
349
350 $uri = Uri::withQueryValues($uri, [
351 'key1' => 'value1',
352 'key2' => 'value2'
353 ]);
354
355 $uri = Uri::withQueryValues($uri, [
356 'key2' => 'newvalue'
357 ]);
358
359 $this->assertSame('key1=value1&key2=newvalue', $uri->getQuery());
360 }
361
362 public function testWithQueryValueReplacesSameKeys()
363 {
364 $uri = new Uri();
365 $uri = Uri::withQueryValue($uri, 'a', 'b');
366 $uri = Uri::withQueryValue($uri, 'c', 'd');
367 $uri = Uri::withQueryValue($uri, 'a', 'e');
368 $this->assertSame('c=d&a=e', $uri->getQuery());
369 }
370
371 public function testWithoutQueryValueRemovesAllSameKeys()
372 {
373 $uri = (new Uri())->withQuery('a=b&c=d&a=e');
374 $uri = Uri::withoutQueryValue($uri, 'a');
375 $this->assertSame('c=d', $uri->getQuery());
376 }
377
378 public function testRemoveNonExistingQueryValue()
379 {
380 $uri = new Uri();
381 $uri = Uri::withQueryValue($uri, 'a', 'b');
382 $uri = Uri::withoutQueryValue($uri, 'c');
383 $this->assertSame('a=b', $uri->getQuery());
384 }
385
386 public function testWithQueryValueHandlesEncoding()
387 {
388 $uri = new Uri();
389 $uri = Uri::withQueryValue($uri, 'E=mc^2', 'ein&stein');
390 $this->assertSame('E%3Dmc%5E2=ein%26stein', $uri->getQuery(), 'Decoded key/value get encoded');
391
392 $uri = new Uri();
393 $uri = Uri::withQueryValue($uri, 'E%3Dmc%5e2', 'ein%26stein');
394 $this->assertSame('E%3Dmc%5e2=ein%26stein', $uri->getQuery(), 'Encoded key/value do not get double-encoded');
395 }
396
397 public function testWithoutQueryValueHandlesEncoding()
398 {
399 // It also tests that the case of the percent-encoding does not matter,
400 // i.e. both lowercase "%3d" and uppercase "%5E" can be removed.
401 $uri = (new Uri())->withQuery('E%3dmc%5E2=einstein&foo=bar');
402 $uri = Uri::withoutQueryValue($uri, 'E=mc^2');
403 $this->assertSame('foo=bar', $uri->getQuery(), 'Handles key in decoded form');
404
405 $uri = (new Uri())->withQuery('E%3dmc%5E2=einstein&foo=bar');
406 $uri = Uri::withoutQueryValue($uri, 'E%3Dmc%5e2');
407 $this->assertSame('foo=bar', $uri->getQuery(), 'Handles key in encoded form');
408 }
409
410 public function testSchemeIsNormalizedToLowercase()
411 {
412 $uri = new Uri('HTTP://example.com');
413
414 $this->assertSame('http', $uri->getScheme());
415 $this->assertSame('http://example.com', (string) $uri);
416
417 $uri = (new Uri('//example.com'))->withScheme('HTTP');
418
419 $this->assertSame('http', $uri->getScheme());
420 $this->assertSame('http://example.com', (string) $uri);
421 }
422
423 public function testHostIsNormalizedToLowercase()
424 {
425 $uri = new Uri('//eXaMpLe.CoM');
426
427 $this->assertSame('example.com', $uri->getHost());
428 $this->assertSame('//example.com', (string) $uri);
429
430 $uri = (new Uri())->withHost('eXaMpLe.CoM');
431
432 $this->assertSame('example.com', $uri->getHost());
433 $this->assertSame('//example.com', (string) $uri);
434 }
435
436 public function testPortIsNullIfStandardPortForScheme()
437 {
438 // HTTPS standard port
439 $uri = new Uri('https://example.com:443');
440 $this->assertNull($uri->getPort());
441 $this->assertSame('example.com', $uri->getAuthority());
442
443 $uri = (new Uri('https://example.com'))->withPort(443);
444 $this->assertNull($uri->getPort());
445 $this->assertSame('example.com', $uri->getAuthority());
446
447 // HTTP standard port
448 $uri = new Uri('http://example.com:80');
449 $this->assertNull($uri->getPort());
450 $this->assertSame('example.com', $uri->getAuthority());
451
452 $uri = (new Uri('http://example.com'))->withPort(80);
453 $this->assertNull($uri->getPort());
454 $this->assertSame('example.com', $uri->getAuthority());
455 }
456
457 public function testPortIsReturnedIfSchemeUnknown()
458 {
459 $uri = (new Uri('//example.com'))->withPort(80);
460
461 $this->assertSame(80, $uri->getPort());
462 $this->assertSame('example.com:80', $uri->getAuthority());
463 }
464
465 public function testStandardPortIsNullIfSchemeChanges()
466 {
467 $uri = new Uri('http://example.com:443');
468 $this->assertSame('http', $uri->getScheme());
469 $this->assertSame(443, $uri->getPort());
470
471 $uri = $uri->withScheme('https');
472 $this->assertNull($uri->getPort());
473 }
474
475 public function testPortPassedAsStringIsCastedToInt()
476 {
477 $uri = (new Uri('//example.com'))->withPort('8080');
478
479 $this->assertSame(8080, $uri->getPort(), 'Port is returned as integer');
480 $this->assertSame('example.com:8080', $uri->getAuthority());
481 }
482
483 public function testPortCanBeRemoved()
484 {
485 $uri = (new Uri('http://example.com:8080'))->withPort(null);
486
487 $this->assertNull($uri->getPort());
488 $this->assertSame('http://example.com', (string) $uri);
489 }
490
491 /**
492 * In RFC 8986 the host is optional and the authority can only
493 * consist of the user info and port.
494 */
495 public function testAuthorityWithUserInfoOrPortButWithoutHost()
496 {
497 $uri = (new Uri())->withUserInfo('user', 'pass');
498
499 $this->assertSame('user:pass', $uri->getUserInfo());
500 $this->assertSame('user:pass@', $uri->getAuthority());
501
502 $uri = $uri->withPort(8080);
503 $this->assertSame(8080, $uri->getPort());
504 $this->assertSame('user:pass@:8080', $uri->getAuthority());
505 $this->assertSame('//user:pass@:8080', (string) $uri);
506
507 $uri = $uri->withUserInfo('');
508 $this->assertSame(':8080', $uri->getAuthority());
509 }
510
511 public function testHostInHttpUriDefaultsToLocalhost()
512 {
513 $uri = (new Uri())->withScheme('http');
514
515 $this->assertSame('localhost', $uri->getHost());
516 $this->assertSame('localhost', $uri->getAuthority());
517 $this->assertSame('http://localhost', (string) $uri);
518 }
519
520 public function testHostInHttpsUriDefaultsToLocalhost()
521 {
522 $uri = (new Uri())->withScheme('https');
523
524 $this->assertSame('localhost', $uri->getHost());
525 $this->assertSame('localhost', $uri->getAuthority());
526 $this->assertSame('https://localhost', (string) $uri);
527 }
528
529 public function testFileSchemeWithEmptyHostReconstruction()
530 {
531 $uri = new Uri('file:///tmp/filename.ext');
532
533 $this->assertSame('', $uri->getHost());
534 $this->assertSame('', $uri->getAuthority());
535 $this->assertSame('file:///tmp/filename.ext', (string) $uri);
536 }
537
538 public function uriComponentsEncodingProvider()
539 {
540 $unreserved = 'a-zA-Z0-9.-_~!$&\'()*+,;=:@';
541
542 return [
543 // Percent encode spaces
544 ['/pa th?q=va lue#frag ment', '/pa%20th', 'q=va%20lue', 'frag%20ment', '/pa%20th?q=va%20lue#frag%20ment'],
545 // Percent encode multibyte
546 ['/€?€#€', '/%E2%82%AC', '%E2%82%AC', '%E2%82%AC', '/%E2%82%AC?%E2%82%AC#%E2%82%AC'],
547 // Don't encode something that's already encoded
548 ['/pa%20th?q=va%20lue#frag%20ment', '/pa%20th', 'q=va%20lue', 'frag%20ment', '/pa%20th?q=va%20lue#frag%20ment'],
549 // Percent encode invalid percent encodings
550 ['/pa%2-th?q=va%2-lue#frag%2-ment', '/pa%252-th', 'q=va%252-lue', 'frag%252-ment', '/pa%252-th?q=va%252-lue#frag%252-ment'],
551 // Don't encode path segments
552 ['/pa/th//two?q=va/lue#frag/ment', '/pa/th//two', 'q=va/lue', 'frag/ment', '/pa/th//two?q=va/lue#frag/ment'],
553 // Don't encode unreserved chars or sub-delimiters
554 ["/$unreserved?$unreserved#$unreserved", "/$unreserved", $unreserved, $unreserved, "/$unreserved?$unreserved#$unreserved"],
555 // Encoded unreserved chars are not decoded
556 ['/p%61th?q=v%61lue#fr%61gment', '/p%61th', 'q=v%61lue', 'fr%61gment', '/p%61th?q=v%61lue#fr%61gment'],
557 ];
558 }
559
560 /**
561 * @dataProvider uriComponentsEncodingProvider
562 */
563 public function testUriComponentsGetEncodedProperly($input, $path, $query, $fragment, $output)
564 {
565 $uri = new Uri($input);
566 $this->assertSame($path, $uri->getPath());
567 $this->assertSame($query, $uri->getQuery());
568 $this->assertSame($fragment, $uri->getFragment());
569 $this->assertSame($output, (string) $uri);
570 }
571
572 public function testWithPathEncodesProperly()
573 {
574 $uri = (new Uri())->withPath('/baz?#€/b%61r');
575 // Query and fragment delimiters and multibyte chars are encoded.
576 $this->assertSame('/baz%3F%23%E2%82%AC/b%61r', $uri->getPath());
577 $this->assertSame('/baz%3F%23%E2%82%AC/b%61r', (string) $uri);
578 }
579
580 public function testWithQueryEncodesProperly()
581 {
582 $uri = (new Uri())->withQuery('?=#&€=/&b%61r');
583 // A query starting with a "?" is valid and must not be magically removed. Otherwise it would be impossible to
584 // construct such an URI. Also the "?" and "/" does not need to be encoded in the query.
585 $this->assertSame('?=%23&%E2%82%AC=/&b%61r', $uri->getQuery());
586 $this->assertSame('??=%23&%E2%82%AC=/&b%61r', (string) $uri);
587 }
588
589 public function testWithFragmentEncodesProperly()
590 {
591 $uri = (new Uri())->withFragment('#€?/b%61r');
592 // A fragment starting with a "#" is valid and must not be magically removed. Otherwise it would be impossible to
593 // construct such an URI. Also the "?" and "/" does not need to be encoded in the fragment.
594 $this->assertSame('%23%E2%82%AC?/b%61r', $uri->getFragment());
595 $this->assertSame('#%23%E2%82%AC?/b%61r', (string) $uri);
596 }
597
598 public function testAllowsForRelativeUri()
599 {
600 $uri = (new Uri)->withPath('foo');
601 $this->assertSame('foo', $uri->getPath());
602 $this->assertSame('foo', (string) $uri);
603 }
604
605 public function testRelativePathAndAuhorityIsAutomagicallyFixed()
606 {
607 // concatenating a relative path with a host doesn't work: "//example.comfoo" would be wrong
608 $uri = (new Uri)->withPath('foo')->withHost('example.com');
609 $this->assertSame('/foo', $uri->getPath());
610 $this->assertSame('//example.com/foo', (string) $uri);
611 }
612
613 /**
614 * @expectedException \InvalidArgumentException
615 * @expectedExceptionMessage The path of a URI without an authority must not start with two slashes "//"
616 */
617 public function testPathStartingWithTwoSlashesAndNoAuthorityIsInvalid()
618 {
619 // URI "//foo" would be interpreted as network reference and thus change the original path to the host
620 (new Uri)->withPath('//foo');
621 }
622
623 public function testPathStartingWithTwoSlashes()
624 {
625 $uri = new Uri('http://example.org//path-not-host.com');
626 $this->assertSame('//path-not-host.com', $uri->getPath());
627
628 $uri = $uri->withScheme('');
629 $this->assertSame('//example.org//path-not-host.com', (string) $uri); // This is still valid
630 $this->expectException('\InvalidArgumentException');
631 $uri->withHost(''); // Now it becomes invalid
632 }
633
634 /**
635 * @expectedException \InvalidArgumentException
636 * @expectedExceptionMessage A relative URI must not have a path beginning with a segment containing a colon
637 */
638 public function testRelativeUriWithPathBeginngWithColonSegmentIsInvalid()
639 {
640 (new Uri)->withPath('mailto:foo');
641 }
642
643 public function testRelativeUriWithPathHavingColonSegment()
644 {
645 $uri = (new Uri('urn:/mailto:foo'))->withScheme('');
646 $this->assertSame('/mailto:foo', $uri->getPath());
647
648 $this->expectException('\InvalidArgumentException');
649 (new Uri('urn:mailto:foo'))->withScheme('');
650 }
651
652 public function testDefaultReturnValuesOfGetters()
653 {
654 $uri = new Uri();
655
656 $this->assertSame('', $uri->getScheme());
657 $this->assertSame('', $uri->getAuthority());
658 $this->assertSame('', $uri->getUserInfo());
659 $this->assertSame('', $uri->getHost());
660 $this->assertNull($uri->getPort());
661 $this->assertSame('', $uri->getPath());
662 $this->assertSame('', $uri->getQuery());
663 $this->assertSame('', $uri->getFragment());
664 }
665
666 public function testImmutability()
667 {
668 $uri = new Uri();
669
670 $this->assertNotSame($uri, $uri->withScheme('https'));
671 $this->assertNotSame($uri, $uri->withUserInfo('user', 'pass'));
672 $this->assertNotSame($uri, $uri->withHost('example.com'));
673 $this->assertNotSame($uri, $uri->withPort(8080));
674 $this->assertNotSame($uri, $uri->withPath('/path/123'));
675 $this->assertNotSame($uri, $uri->withQuery('q=abc'));
676 $this->assertNotSame($uri, $uri->withFragment('test'));
677 }
678
679 public function testExtendingClassesInstantiates()
680 {
681 // The non-standard port triggers a cascade of private methods which
682 // should not use late static binding to access private static members.
683 // If they do, this will fatal.
684 $this->assertInstanceOf(
685 'GuzzleHttp\Tests\Psr7\ExtendedUriTest',
686 new ExtendedUriTest('http://h:9/')
687 );
688 }
689
690 public function testSpecialCharsOfUserInfo()
691 {
692 // The `userInfo` must always be URL-encoded.
693 $uri = (new Uri)->withUserInfo('[email protected]', 'pass#word');
694 $this->assertSame('foo%40bar.com:pass%23word', $uri->getUserInfo());
695
696 // The `userInfo` can already be URL-encoded: it should not be encoded twice.
697 $uri = (new Uri)->withUserInfo('foo%40bar.com', 'pass%23word');
698 $this->assertSame('foo%40bar.com:pass%23word', $uri->getUserInfo());
699 }
700 }
701
702 class ExtendedUriTest extends Uri
703 {
704 }
705