From ce47614ab24a2fde7d322facb4a857a90e2a0749 Mon Sep 17 00:00:00 2001 From: butschster Date: Tue, 15 Aug 2023 17:25:43 +0400 Subject: [PATCH] Fixes incorrect Concatenation of Route Pattern with Prefix in Route Group See #962 --- src/Router/src/UriHandler.php | 6 +++++- src/Router/tests/RouteGroupTest.php | 32 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Router/src/UriHandler.php b/src/Router/src/UriHandler.php index 1dc0e4883..982fabca7 100644 --- a/src/Router/src/UriHandler.php +++ b/src/Router/src/UriHandler.php @@ -269,7 +269,11 @@ private function compile(): void $options = []; $replaces = []; - $pattern = \rtrim(\ltrim($this->getPrefix() . '/' . $this->pattern, ':/'), '/'); + + $prefix = \rtrim($this->getPrefix(), '/ '); + $pattern = \ltrim($this->pattern, '/ '); + $pattern = $prefix . '/' . $pattern; + $pattern = \rtrim(\ltrim($pattern, ':/'), '/'); // correct [/ first occurrence] if (\str_starts_with($pattern, '[/')) { diff --git a/src/Router/tests/RouteGroupTest.php b/src/Router/tests/RouteGroupTest.php index 456709843..c0e8679ac 100644 --- a/src/Router/tests/RouteGroupTest.php +++ b/src/Router/tests/RouteGroupTest.php @@ -5,6 +5,7 @@ namespace Spiral\Tests\Router; use Nyholm\Psr7\Factory\Psr17Factory; +use Nyholm\Psr7\ServerRequest; use PHPUnit\Framework\Attributes\DataProvider; use Psr\Http\Message\UriFactoryInterface; use Spiral\Core\Container; @@ -19,6 +20,7 @@ final class RouteGroupTest extends BaseTestCase { + protected function setUp(): void { parent::setUp(); @@ -134,6 +136,36 @@ public function testWithNamePrefix(): void $this->assertFalse($group->hasRoute('name')); } + #[DataProvider('routePrefixDataProvider')] + public function testWithPrefix(string $prefix, string $pattern): void + { + $route = new Route($pattern, new Action('controller', 'method')); + $group = new RouteGroup(); + $group->setPrefix($prefix); + $group->addRoute('name', $route->withVerbs('GET')); + $group->register($this->router, $this->container); + + $route = $this->router->getRoute('name'); + $this->assertNotNull( + $route->match(new ServerRequest('GET', '/api/blog')) + ); + + $this->assertSame('/api/blog', (string) $route->uri()); + } + + public static function routePrefixDataProvider(): iterable + { + yield ['/api/', '/blog']; + yield ['/api', '/blog']; + yield ['/api', 'blog']; + yield ['api/', '/blog']; + yield ['api', '/blog']; + yield ['api', 'blog']; + yield ['api/', '/blog/']; + yield ['api', '/blog/']; + yield ['api', 'blog/']; + } + /** * @throws \ReflectionException */