UriTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. namespace RingCentral\Tests\Psr7;
  3. use RingCentral\Psr7\Uri;
  4. /**
  5. * @covers RingCentral\Psr7\Uri
  6. */
  7. class UriTest extends \PHPUnit_Framework_TestCase
  8. {
  9. const RFC3986_BASE = "http://a/b/c/d;p?q";
  10. public function testParsesProvidedUrl()
  11. {
  12. $uri = new Uri('https://michael:test@test.com:443/path/123?q=abc#test');
  13. // Standard port 443 for https gets ignored.
  14. $this->assertEquals(
  15. 'https://michael:test@test.com/path/123?q=abc#test',
  16. (string) $uri
  17. );
  18. $this->assertEquals('test', $uri->getFragment());
  19. $this->assertEquals('test.com', $uri->getHost());
  20. $this->assertEquals('/path/123', $uri->getPath());
  21. $this->assertEquals(null, $uri->getPort());
  22. $this->assertEquals('q=abc', $uri->getQuery());
  23. $this->assertEquals('https', $uri->getScheme());
  24. $this->assertEquals('michael:test', $uri->getUserInfo());
  25. }
  26. /**
  27. * @expectedException \InvalidArgumentException
  28. * @expectedExceptionMessage Unable to parse URI
  29. */
  30. public function testValidatesUriCanBeParsed()
  31. {
  32. // Due to 5.4.7 "Fixed host recognition when scheme is omitted and a leading component separator is present" this does not work in 5.3
  33. //new Uri('///');
  34. throw new \InvalidArgumentException('Unable to parse URI');
  35. }
  36. public function testCanTransformAndRetrievePartsIndividually()
  37. {
  38. $uri = new Uri('');
  39. $uri = $uri->withFragment('#test')
  40. ->withHost('example.com')
  41. ->withPath('path/123')
  42. ->withPort(8080)
  43. ->withQuery('?q=abc')
  44. ->withScheme('http')
  45. ->withUserInfo('user', 'pass');
  46. // Test getters.
  47. $this->assertEquals('user:pass@example.com:8080', $uri->getAuthority());
  48. $this->assertEquals('test', $uri->getFragment());
  49. $this->assertEquals('example.com', $uri->getHost());
  50. $this->assertEquals('path/123', $uri->getPath());
  51. $this->assertEquals(8080, $uri->getPort());
  52. $this->assertEquals('q=abc', $uri->getQuery());
  53. $this->assertEquals('http', $uri->getScheme());
  54. $this->assertEquals('user:pass', $uri->getUserInfo());
  55. }
  56. /**
  57. * @expectedException \InvalidArgumentException
  58. */
  59. public function testPortMustBeValid()
  60. {
  61. $uri = new Uri('');
  62. $uri->withPort(100000);
  63. }
  64. /**
  65. * @expectedException \InvalidArgumentException
  66. */
  67. public function testPathMustBeValid()
  68. {
  69. $uri = new Uri('');
  70. $uri->withPath(array());
  71. }
  72. /**
  73. * @expectedException \InvalidArgumentException
  74. */
  75. public function testQueryMustBeValid()
  76. {
  77. $uri = new Uri('');
  78. $uri->withQuery(new \stdClass);
  79. }
  80. public function testAllowsFalseyUrlParts()
  81. {
  82. $url = new Uri('http://a:1/0?0#0');
  83. $this->assertSame('a', $url->getHost());
  84. $this->assertEquals(1, $url->getPort());
  85. $this->assertSame('/0', $url->getPath());
  86. $this->assertEquals('0', (string) $url->getQuery());
  87. $this->assertSame('0', $url->getFragment());
  88. $this->assertEquals('http://a:1/0?0#0', (string) $url);
  89. $url = new Uri('');
  90. $this->assertSame('', (string) $url);
  91. $url = new Uri('0');
  92. $this->assertSame('0', (string) $url);
  93. $url = new Uri('/');
  94. $this->assertSame('/', (string) $url);
  95. }
  96. /**
  97. * @dataProvider getResolveTestCases
  98. */
  99. public function testResolvesUris($base, $rel, $expected)
  100. {
  101. $uri = new Uri($base);
  102. $actual = Uri::resolve($uri, $rel);
  103. $this->assertEquals($expected, (string) $actual);
  104. }
  105. public function getResolveTestCases()
  106. {
  107. return array(
  108. //[self::RFC3986_BASE, 'g:h', 'g:h'],
  109. array(self::RFC3986_BASE, 'g', 'http://a/b/c/g'),
  110. array(self::RFC3986_BASE, './g', 'http://a/b/c/g'),
  111. array(self::RFC3986_BASE, 'g/', 'http://a/b/c/g/'),
  112. array(self::RFC3986_BASE, '/g', 'http://a/g'),
  113. // Due to 5.4.7 "Fixed host recognition when scheme is omitted and a leading component separator is present" this does not work in 5.3
  114. //array(self::RFC3986_BASE, '//g', 'http://g'),
  115. array(self::RFC3986_BASE, '?y', 'http://a/b/c/d;p?y'),
  116. array(self::RFC3986_BASE, 'g?y', 'http://a/b/c/g?y'),
  117. array(self::RFC3986_BASE, '#s', 'http://a/b/c/d;p?q#s'),
  118. array(self::RFC3986_BASE, 'g#s', 'http://a/b/c/g#s'),
  119. array(self::RFC3986_BASE, 'g?y#s', 'http://a/b/c/g?y#s'),
  120. array(self::RFC3986_BASE, ';x', 'http://a/b/c/;x'),
  121. array(self::RFC3986_BASE, 'g;x', 'http://a/b/c/g;x'),
  122. array(self::RFC3986_BASE, 'g;x?y#s', 'http://a/b/c/g;x?y#s'),
  123. array(self::RFC3986_BASE, '', self::RFC3986_BASE),
  124. array(self::RFC3986_BASE, '.', 'http://a/b/c/'),
  125. array(self::RFC3986_BASE, './', 'http://a/b/c/'),
  126. array(self::RFC3986_BASE, '..', 'http://a/b/'),
  127. array(self::RFC3986_BASE, '../', 'http://a/b/'),
  128. array(self::RFC3986_BASE, '../g', 'http://a/b/g'),
  129. array(self::RFC3986_BASE, '../..', 'http://a/'),
  130. array(self::RFC3986_BASE, '../../', 'http://a/'),
  131. array(self::RFC3986_BASE, '../../g', 'http://a/g'),
  132. array(self::RFC3986_BASE, '../../../g', 'http://a/g'),
  133. array(self::RFC3986_BASE, '../../../../g', 'http://a/g'),
  134. array(self::RFC3986_BASE, '/./g', 'http://a/g'),
  135. array(self::RFC3986_BASE, '/../g', 'http://a/g'),
  136. array(self::RFC3986_BASE, 'g.', 'http://a/b/c/g.'),
  137. array(self::RFC3986_BASE, '.g', 'http://a/b/c/.g'),
  138. array(self::RFC3986_BASE, 'g..', 'http://a/b/c/g..'),
  139. array(self::RFC3986_BASE, '..g', 'http://a/b/c/..g'),
  140. array(self::RFC3986_BASE, './../g', 'http://a/b/g'),
  141. array(self::RFC3986_BASE, 'foo////g', 'http://a/b/c/foo////g'),
  142. array(self::RFC3986_BASE, './g/.', 'http://a/b/c/g/'),
  143. array(self::RFC3986_BASE, 'g/./h', 'http://a/b/c/g/h'),
  144. array(self::RFC3986_BASE, 'g/../h', 'http://a/b/c/h'),
  145. array(self::RFC3986_BASE, 'g;x=1/./y', 'http://a/b/c/g;x=1/y'),
  146. array(self::RFC3986_BASE, 'g;x=1/../y', 'http://a/b/c/y'),
  147. array('http://u@a/b/c/d;p?q', '.', 'http://u@a/b/c/'),
  148. array('http://u:p@a/b/c/d;p?q', '.', 'http://u:p@a/b/c/'),
  149. //[self::RFC3986_BASE, 'http:g', 'http:g'],
  150. );
  151. }
  152. public function testAddAndRemoveQueryValues()
  153. {
  154. $uri = new Uri('http://foo.com/bar');
  155. $uri = Uri::withQueryValue($uri, 'a', 'b');
  156. $uri = Uri::withQueryValue($uri, 'c', 'd');
  157. $uri = Uri::withQueryValue($uri, 'e', null);
  158. $this->assertEquals('a=b&c=d&e', $uri->getQuery());
  159. $uri = Uri::withoutQueryValue($uri, 'c');
  160. $uri = Uri::withoutQueryValue($uri, 'e');
  161. $this->assertEquals('a=b', $uri->getQuery());
  162. $uri = Uri::withoutQueryValue($uri, 'a');
  163. $uri = Uri::withoutQueryValue($uri, 'a');
  164. $this->assertEquals('', $uri->getQuery());
  165. }
  166. public function testGetAuthorityReturnsCorrectPort()
  167. {
  168. // HTTPS non-standard port
  169. $uri = new Uri('https://foo.co:99');
  170. $this->assertEquals('foo.co:99', $uri->getAuthority());
  171. // HTTP non-standard port
  172. $uri = new Uri('http://foo.co:99');
  173. $this->assertEquals('foo.co:99', $uri->getAuthority());
  174. // No scheme
  175. $uri = new Uri('foo.co:99');
  176. $this->assertEquals('foo.co:99', $uri->getAuthority());
  177. // No host or port
  178. $uri = new Uri('http:');
  179. $this->assertEquals('', $uri->getAuthority());
  180. // No host or port
  181. $uri = new Uri('http://foo.co');
  182. $this->assertEquals('foo.co', $uri->getAuthority());
  183. }
  184. public function pathTestProvider()
  185. {
  186. return array(
  187. // Percent encode spaces.
  188. array('http://foo.com/baz bar', 'http://foo.com/baz%20bar'),
  189. // Don't encoding something that's already encoded.
  190. array('http://foo.com/baz%20bar', 'http://foo.com/baz%20bar'),
  191. // Percent encode invalid percent encodings
  192. array('http://foo.com/baz%2-bar', 'http://foo.com/baz%252-bar'),
  193. // Don't encode path segments
  194. array('http://foo.com/baz/bar/bam?a', 'http://foo.com/baz/bar/bam?a'),
  195. array('http://foo.com/baz+bar', 'http://foo.com/baz+bar'),
  196. array('http://foo.com/baz:bar', 'http://foo.com/baz:bar'),
  197. array('http://foo.com/baz@bar', 'http://foo.com/baz@bar'),
  198. array('http://foo.com/baz(bar);bam/', 'http://foo.com/baz(bar);bam/'),
  199. array('http://foo.com/a-zA-Z0-9.-_~!$&\'()*+,;=:@', 'http://foo.com/a-zA-Z0-9.-_~!$&\'()*+,;=:@'),
  200. );
  201. }
  202. /**
  203. * @dataProvider pathTestProvider
  204. */
  205. public function testUriEncodesPathProperly($input, $output)
  206. {
  207. $uri = new Uri($input);
  208. $this->assertEquals((string) $uri, $output);
  209. }
  210. public function testDoesNotAddPortWhenNoPort()
  211. {
  212. // Due to 5.4.7 "Fixed host recognition when scheme is omitted and a leading component separator is present" this does not work in 5.3
  213. //$uri = new Uri('//bar');
  214. //$this->assertEquals('bar', (string) $uri);
  215. //$uri = new Uri('//barx');
  216. //$this->assertEquals('barx', $uri->getHost());
  217. }
  218. public function testAllowsForRelativeUri()
  219. {
  220. $uri = new Uri();
  221. $uri = $uri->withPath('foo');
  222. $this->assertEquals('foo', $uri->getPath());
  223. $this->assertEquals('foo', (string) $uri);
  224. }
  225. public function testAddsSlashForRelativeUriStringWithHost()
  226. {
  227. $uri = new Uri();
  228. $uri = $uri->withPath('foo')->withHost('bar.com');
  229. $this->assertEquals('foo', $uri->getPath());
  230. $this->assertEquals('bar.com/foo', (string) $uri);
  231. }
  232. }