| 1 |
<?php |
| 2 |
namespace GuzzleHttp\Tests\Psr7; |
| 3 |
|
| 4 |
use GuzzleHttp\Psr7\Uri; |
| 5 |
use GuzzleHttp\Psr7\UriNormalizer; |
| 6 |
|
| 7 |
/** |
| 8 |
* @covers GuzzleHttp\Psr7\UriNormalizer |
| 9 |
*/ |
| 10 |
class UriNormalizerTest extends BaseTest |
| 11 |
{ |
| 12 |
public function testCapitalizePercentEncoding() |
| 13 |
{ |
| 14 |
$actualEncoding = 'a%c2%7A%5eb%25%fa%fA%Fa'; |
| 15 |
$expectEncoding = 'a%C2%7A%5Eb%25%FA%FA%FA'; |
| 16 |
$uri = (new Uri())->withPath("/$actualEncoding")->withQuery($actualEncoding); |
| 17 |
|
| 18 |
$this->assertSame("/$actualEncoding?$actualEncoding", (string) $uri, 'Not normalized automatically beforehand'); |
| 19 |
|
| 20 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::CAPITALIZE_PERCENT_ENCODING); |
| 21 |
|
| 22 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 23 |
$this->assertSame("/$expectEncoding?$expectEncoding", (string) $normalizedUri); |
| 24 |
} |
| 25 |
|
| 26 |
/** |
| 27 |
* @dataProvider getUnreservedCharacters |
| 28 |
*/ |
| 29 |
public function testDecodeUnreservedCharacters($char) |
| 30 |
{ |
| 31 |
$percentEncoded = '%'.bin2hex($char); |
| 32 |
// Add encoded reserved characters to test that those are not decoded and include the percent-encoded |
| 33 |
// unreserved character both in lower and upper case to test the decoding is case-insensitive. |
| 34 |
$encodedChars = $percentEncoded.'%2F%5B'.strtoupper($percentEncoded); |
| 35 |
$uri = (new Uri())->withPath("/$encodedChars")->withQuery($encodedChars); |
| 36 |
|
| 37 |
$this->assertSame("/$encodedChars?$encodedChars", (string) $uri, 'Not normalized automatically beforehand'); |
| 38 |
|
| 39 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::DECODE_UNRESERVED_CHARACTERS); |
| 40 |
|
| 41 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 42 |
$this->assertSame("/$char%2F%5B$char?$char%2F%5B$char", (string) $normalizedUri); |
| 43 |
} |
| 44 |
|
| 45 |
public function getUnreservedCharacters() |
| 46 |
{ |
| 47 |
$unreservedChars = array_merge(range('a', 'z'), range('A', 'Z'), range('0', '9'), ['-', '.', '_', '~']); |
| 48 |
|
| 49 |
return array_map(function ($char) { |
| 50 |
return [$char]; |
| 51 |
}, $unreservedChars); |
| 52 |
} |
| 53 |
|
| 54 |
/** |
| 55 |
* @dataProvider getEmptyPathTestCases |
| 56 |
*/ |
| 57 |
public function testConvertEmptyPath($uri, $expected) |
| 58 |
{ |
| 59 |
$normalizedUri = UriNormalizer::normalize(new Uri($uri), UriNormalizer::CONVERT_EMPTY_PATH); |
| 60 |
|
| 61 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 62 |
$this->assertSame($expected, (string) $normalizedUri); |
| 63 |
} |
| 64 |
|
| 65 |
public function getEmptyPathTestCases() |
| 66 |
{ |
| 67 |
return [ |
| 68 |
['http://example.org', 'http://example.org/'], |
| 69 |
['https://example.org', 'https://example.org/'], |
| 70 |
['urn://example.org', 'urn://example.org'], |
| 71 |
]; |
| 72 |
} |
| 73 |
|
| 74 |
public function testRemoveDefaultHost() |
| 75 |
{ |
| 76 |
$uri = new Uri('file://localhost/myfile'); |
| 77 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DEFAULT_HOST); |
| 78 |
|
| 79 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 80 |
$this->assertSame('file:///myfile', (string) $normalizedUri); |
| 81 |
} |
| 82 |
|
| 83 |
public function testRemoveDefaultPort() |
| 84 |
{ |
| 85 |
$uri = $this->getMockBuilder('Psr\Http\Message\UriInterface')->getMock(); |
| 86 |
$uri->expects($this->any())->method('getScheme')->will($this->returnValue('http')); |
| 87 |
$uri->expects($this->any())->method('getPort')->will($this->returnValue(80)); |
| 88 |
$uri->expects($this->once())->method('withPort')->with(null)->will($this->returnValue(new Uri('http://example.org'))); |
| 89 |
|
| 90 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DEFAULT_PORT); |
| 91 |
|
| 92 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 93 |
$this->assertNull($normalizedUri->getPort()); |
| 94 |
} |
| 95 |
|
| 96 |
public function testRemoveDotSegments() |
| 97 |
{ |
| 98 |
$uri = new Uri('http://example.org/../a/b/../c/./d.html'); |
| 99 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS); |
| 100 |
|
| 101 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 102 |
$this->assertSame('http://example.org/a/c/d.html', (string) $normalizedUri); |
| 103 |
} |
| 104 |
|
| 105 |
public function testRemoveDotSegmentsOfAbsolutePathReference() |
| 106 |
{ |
| 107 |
$uri = new Uri('/../a/b/../c/./d.html'); |
| 108 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS); |
| 109 |
|
| 110 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 111 |
$this->assertSame('/a/c/d.html', (string) $normalizedUri); |
| 112 |
} |
| 113 |
|
| 114 |
public function testRemoveDotSegmentsOfRelativePathReference() |
| 115 |
{ |
| 116 |
$uri = new Uri('../c/./d.html'); |
| 117 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DOT_SEGMENTS); |
| 118 |
|
| 119 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 120 |
$this->assertSame('../c/./d.html', (string) $normalizedUri); |
| 121 |
} |
| 122 |
|
| 123 |
public function testRemoveDuplicateSlashes() |
| 124 |
{ |
| 125 |
$uri = new Uri('http://example.org//foo///bar/bam.html'); |
| 126 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::REMOVE_DUPLICATE_SLASHES); |
| 127 |
|
| 128 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 129 |
$this->assertSame('http://example.org/foo/bar/bam.html', (string) $normalizedUri); |
| 130 |
} |
| 131 |
|
| 132 |
public function testSortQueryParameters() |
| 133 |
{ |
| 134 |
$uri = new Uri('?lang=en&article=fred'); |
| 135 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::SORT_QUERY_PARAMETERS); |
| 136 |
|
| 137 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 138 |
$this->assertSame('?article=fred&lang=en', (string) $normalizedUri); |
| 139 |
} |
| 140 |
|
| 141 |
public function testSortQueryParametersWithSameKeys() |
| 142 |
{ |
| 143 |
$uri = new Uri('?a=b&b=c&a=a&a&b=a&b=b&a=d&a=c'); |
| 144 |
$normalizedUri = UriNormalizer::normalize($uri, UriNormalizer::SORT_QUERY_PARAMETERS); |
| 145 |
|
| 146 |
$this->assertInstanceOf('Psr\Http\Message\UriInterface', $normalizedUri); |
| 147 |
$this->assertSame('?a&a=a&a=b&a=c&a=d&b=a&b=b&b=c', (string) $normalizedUri); |
| 148 |
} |
| 149 |
|
| 150 |
/** |
| 151 |
* @dataProvider getEquivalentTestCases |
| 152 |
*/ |
| 153 |
public function testIsEquivalent($uri1, $uri2, $expected) |
| 154 |
{ |
| 155 |
$equivalent = UriNormalizer::isEquivalent(new Uri($uri1), new Uri($uri2)); |
| 156 |
|
| 157 |
$this->assertSame($expected, $equivalent); |
| 158 |
} |
| 159 |
|
| 160 |
public function getEquivalentTestCases() |
| 161 |
{ |
| 162 |
return [ |
| 163 |
['http://example.org', 'http://example.org', true], |
| 164 |
['hTTp://eXaMpLe.org', 'http://example.org', true], |
| 165 |
['http://example.org/path?#', 'http://example.org/path', true], |
| 166 |
['http://example.org:80', 'http://example.org/', true], |
| 167 |
['http://example.org/../a/.././p%61th?%7a=%5e', 'http://example.org/path?z=%5E', true], |
| 168 |
['https://example.org/', 'http://example.org/', false], |
| 169 |
['https://example.org/', '//example.org/', false], |
| 170 |
['//example.org/', '//example.org/', true], |
| 171 |
['file:/myfile', 'file:///myfile', true], |
| 172 |
['file:///myfile', 'file://localhost/myfile', true], |
| 173 |
]; |
| 174 |
} |
| 175 |
} |
| 176 |
|