diff --git a/CHANGELOG.md b/CHANGELOG.md index 73251534..81c676b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All Notable changes to `League\Uri` will be documented in this file - issue [#91](https://github.com/thephpleague/uri/issues/91) Path modifier must be RFC3986 compliant - issue [#94](https://github.com/thephpleague/uri/issues/91) Improve Query parser encoder +- `Formatter::__invoke` path must be RFC3986 compliant ### Deprecated diff --git a/composer.json b/composer.json index c7bce4fb..1d5781fb 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^1.9", - "phpunit/phpunit" : "^4.0" + "phpunit/phpunit": "^4.0", + "zendframework/zend-diactoros": "^1.3" }, "autoload": { "psr-4": { diff --git a/src/Formatter.php b/src/Formatter.php index a4c5195b..8af6c238 100644 --- a/src/Formatter.php +++ b/src/Formatter.php @@ -288,9 +288,14 @@ protected function formatUri($uri) $scheme .= ':'; } + $path = $uri->getPath(); + if ('' != $uri->getAuthority() && '' != $path && '/' != $path[0]) { + $path = '/'.$path; + } + return $scheme .$this->formatAuthority($uri) - .$uri->getPath() + .$path .$this->formatQuery($uri) .$this->formatFragment($uri) ; diff --git a/test/FormatterTest.php b/test/FormatterTest.php index eecc5cf8..44e41bed 100644 --- a/test/FormatterTest.php +++ b/test/FormatterTest.php @@ -9,6 +9,7 @@ use League\Uri\Schemes\Data as DataUri; use League\Uri\Schemes\Http as HttpUri; use PHPUnit_Framework_TestCase; +use Zend\Diactoros\Uri as DiactorosUri; /** * @group formatter @@ -27,7 +28,7 @@ class FormatterTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->uri = HttpUri::createFromString( + $this->uri = new DiactorosUri( 'http://login:pass@gwóźdź.pl:443/test/query.php?kingkong=toto&foo=bar+baz#doc3' ); $this->formatter = new Formatter(); @@ -38,7 +39,8 @@ public function testFormatHostAscii() $this->assertSame(Formatter::HOST_AS_UNICODE, $this->formatter->getHostEncoding()); $this->formatter->setHostEncoding(Formatter::HOST_AS_ASCII); $this->assertSame(Formatter::HOST_AS_ASCII, $this->formatter->getHostEncoding()); - $this->assertSame('xn--gwd-hna98db.pl', $this->formatter->__invoke($this->uri->host)); + $uri = HttpUri::createFromString($this->uri->__toString()); + $this->assertSame('xn--gwd-hna98db.pl', $this->formatter->__invoke($uri->host)); } /** @@ -59,19 +61,16 @@ public function testInvalidQueryEncoding() public function testFormatWithSimpleString() { - $uri = 'https://login:pass@gwóźdź.pl:443/test/query.php?kingkong=toto&foo=bar+baz#doc3'; - $expected = 'https://login:pass@xn--gwd-hna98db.pl/test/query.php?kingkong=toto&foo=bar+baz#doc3'; - $uri = HttpUri::createFromString($uri); - + $expected = 'http://login:pass@xn--gwd-hna98db.pl:443/test/query.php?kingkong=toto&foo=bar+baz#doc3'; $this->formatter->setQuerySeparator('&'); $this->formatter->setHostEncoding(Formatter::HOST_AS_ASCII); - $this->assertSame($expected, $this->formatter->__invoke($uri)); + $this->assertSame($expected, $this->formatter->__invoke($this->uri)); } public function testFormatWithZeroes() { $expected = 'https://example.com/image.jpeg?0#0'; - $uri = HttpUri::createFromString('https://example.com/image.jpeg?0#0'); + $uri = new DiactorosUri('https://example.com/image.jpeg?0#0'); $this->assertSame($expected, $this->formatter->__invoke($uri)); } @@ -84,7 +83,8 @@ public function testFormatComponent() public function testFormatHostUnicode() { $this->formatter->setHostEncoding(Formatter::HOST_AS_UNICODE); - $this->assertSame('gwóźdź.pl', $this->formatter->__invoke($this->uri->host)); + $uri = HttpUri::createFromString($this->uri->__toString()); + $this->assertSame('gwóźdź.pl', $this->formatter->__invoke($uri->host)); } public function testFormatQueryRFC1738() @@ -92,13 +92,15 @@ public function testFormatQueryRFC1738() $this->assertSame(PHP_QUERY_RFC3986, $this->formatter->getQueryEncoding()); $this->formatter->setQueryEncoding(PHP_QUERY_RFC1738); $this->assertSame(PHP_QUERY_RFC1738, $this->formatter->getQueryEncoding()); - $this->assertSame('kingkong=toto&foo=bar%2Bbaz', $this->formatter->__invoke($this->uri->query)); + $uri = HttpUri::createFromString($this->uri->__toString()); + $this->assertSame('kingkong=toto&foo=bar%2Bbaz', $this->formatter->__invoke($uri->query)); } public function testFormatQueryRFC3986() { $this->formatter->setQueryEncoding(PHP_QUERY_RFC3986); - $this->assertSame('kingkong=toto&foo=bar+baz', $this->formatter->__invoke($this->uri->query)); + $uri = HttpUri::createFromString($this->uri->__toString()); + $this->assertSame('kingkong=toto&foo=bar+baz', $this->formatter->__invoke($uri->query)); } public function testFormatQueryWithSeparator() @@ -106,7 +108,8 @@ public function testFormatQueryWithSeparator() $this->assertSame('&', $this->formatter->getQuerySeparator()); $this->formatter->setQuerySeparator('&'); $this->assertSame('&', $this->formatter->getQuerySeparator()); - $this->assertSame('kingkong=toto&foo=bar+baz', $this->formatter->__invoke($this->uri->query)); + $uri = HttpUri::createFromString($this->uri->__toString()); + $this->assertSame('kingkong=toto&foo=bar+baz', $this->formatter->__invoke($uri->query)); } public function testFormat() @@ -146,7 +149,7 @@ public function testFormatterFailed() public function testFormatterPreservedQuery() { $expected = 'http://example.com'; - $uri = HttpUri::createFromString($expected); + $uri = new DiactorosUri($expected); $this->formatter->preserveQuery(true); $this->assertSame($expected, (string) $uri); $this->assertSame('http://example.com?', $this->formatter->__invoke($uri)); @@ -155,9 +158,15 @@ public function testFormatterPreservedQuery() public function testFormatterPreservedFragment() { $expected = 'http://example.com'; - $uri = HttpUri::createFromString($expected); + $uri = new DiactorosUri($expected); $this->formatter->preserveFragment(true); $this->assertSame($expected, (string) $uri); $this->assertSame('http://example.com#', $this->formatter->__invoke($uri)); } + + public function testValidFormatterRespectRFC3986() + { + $psr7uri = (new DiactorosUri('http://bébé.be'))->withPath('foo/bar'); + $this->assertSame('http://bébé.be/foo/bar', (string) $this->formatter->__invoke($psr7uri)); + } } diff --git a/test/Modifiers/PathModifierTest.php b/test/Modifiers/PathModifierTest.php index f361451d..1bf8d8b2 100644 --- a/test/Modifiers/PathModifierTest.php +++ b/test/Modifiers/PathModifierTest.php @@ -111,9 +111,9 @@ public function testAppendProcess($segment, $key, $append, $prepend, $replace) */ public function testAppendProcessWithRelativePath($uri, $segment, $expected) { - $modifier = new AppendSegment('new-segment'); - $uri = HttpUri::createFromString('http://www.example.com'); - $this->assertSame('http://www.example.com/new-segment', (string) $modifier($uri)); + $modifier = new AppendSegment($segment); + $uri = HttpUri::createFromString($uri); + $this->assertSame($expected, (string) $modifier($uri)); } public function validAppendPathProvider()