From d3b1abc151a46e3e641596a0b6a6bbb5c2948a69 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Tue, 12 May 2026 21:24:45 +0400 Subject: [PATCH] [#511] Fix RouteBuilder post-group modifier chaining context --- src/Router/RouteBuilder.php | 6 +-- tests/Unit/Router/RouteBuilderTest.php | 54 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/Router/RouteBuilder.php b/src/Router/RouteBuilder.php index 3a44cd34..cb1631c7 100644 --- a/src/Router/RouteBuilder.php +++ b/src/Router/RouteBuilder.php @@ -85,6 +85,7 @@ public function build(array $moduleRouteClosures, array $moduleConfigs): RouteCo $this->currentModule = null; $this->currentPrefix = null; $this->currentRoute = null; + $this->lastGroupRoutes = null; } return $this->collection; @@ -160,6 +161,7 @@ public function group(string $name, callable $callback): self throw RouteException::nestedGroups(); } + $this->lastGroupRoutes = null; $this->currentGroupName = $name; $this->inGroup = true; $this->groupRoutes = []; @@ -210,7 +212,6 @@ public function middlewares(array $middlewares): self $route->addMiddlewares($middlewares); } - $this->lastGroupRoutes = null; return $this; } @@ -263,7 +264,6 @@ public function cacheable(bool $enabled, ?int $ttl = null): self $route->cache($enabled, $ttl); } - $this->lastGroupRoutes = null; return $this; } @@ -295,7 +295,6 @@ public function rateLimit(int $limit, int $interval): self $route->rateLimit($limit, $interval); } - $this->lastGroupRoutes = null; return $this; } @@ -323,6 +322,7 @@ private function addRoute( throw RouteException::noHttpMethods(); } + $this->lastGroupRoutes = null; $pattern = $this->resolvePath($path); if ($handler instanceof Closure) { diff --git a/tests/Unit/Router/RouteBuilderTest.php b/tests/Unit/Router/RouteBuilderTest.php index f94807a7..012a4a8e 100644 --- a/tests/Unit/Router/RouteBuilderTest.php +++ b/tests/Unit/Router/RouteBuilderTest.php @@ -611,4 +611,58 @@ public function testRouteBuilderGroupedRoutesAreRegisteredIndividually(): void $this->assertSame('g', $routes->all()[0]->getGroup()); $this->assertSame('g', $routes->all()[1]->getGroup()); } + + public function testRouteBuilderPostGroupMiddlewaresThenRateLimitCanBeChained(): void + { + $routes = (new RouteBuilder())->build([ + 'Web' => function (RouteBuilder $route): void { + $route->group('g', function (RouteBuilder $route): void { + $route->get('a', 'AController', 'a'); + $route->get('b', 'BController', 'b'); + })->middlewares(['Auth'])->rateLimit(10, 60); + }, + ], []); + + foreach ($routes->all() as $route) { + $this->assertSame(['Auth'], $route->getMiddlewares()); + $this->assertSame(['limit' => 10, 'interval' => 60], $route->getRateLimit()); + } + } + + public function testRouteBuilderPostGroupRateLimitThenMiddlewaresCanBeChained(): void + { + $routes = (new RouteBuilder())->build([ + 'Web' => function (RouteBuilder $route): void { + $route->group('g', function (RouteBuilder $route): void { + $route->get('a', 'AController', 'a'); + $route->get('b', 'BController', 'b'); + })->rateLimit(20, 30)->middlewares(['Auth']); + }, + ], []); + + foreach ($routes->all() as $route) { + $this->assertSame(['Auth'], $route->getMiddlewares()); + $this->assertSame(['limit' => 20, 'interval' => 30], $route->getRateLimit()); + } + } + + public function testRouteBuilderPostGroupCacheableAndOtherModifiersCanBeChained(): void + { + $routes = (new RouteBuilder())->build([ + 'Web' => function (RouteBuilder $route): void { + $route->group('g', function (RouteBuilder $route): void { + $route->get('a', 'AController', 'a'); + $route->get('b', 'BController', 'b'); + })->cacheable(true, 120)->rateLimit(50, 60)->middlewares(['Auth']); + }, + ], []); + + foreach ($routes->all() as $route) { + $cache = $route->getCache(); + $this->assertSame(true, $cache['enabled']); + $this->assertSame(120, $cache['ttl']); + $this->assertSame(['limit' => 50, 'interval' => 60], $route->getRateLimit()); + $this->assertSame(['Auth'], $route->getMiddlewares()); + } + } }