diff --git a/Routing/EndpointLoader.php b/Routing/EndpointLoader.php index 0b2b690..13007b8 100644 --- a/Routing/EndpointLoader.php +++ b/Routing/EndpointLoader.php @@ -59,7 +59,7 @@ public function load($resource, $type = null) //TODO: go through $requestClass and set requirements \d+ etc based on type $route = new Route( - $endpoint->getPath(), + $this->stripQueryString($endpoint->getPath()), ['_controller' => $controller] ); $route->setMethods([$endpoint->getMethod()]); @@ -77,4 +77,14 @@ public function supports($resource, $type = null) { return 'endpoint_handler' === $type; } + + /** + * Endpoint paths may contain a query string template (e.g. "/v1/cars?ids={ids}") used by API clients + * to build request URIs. Routes are matched against the path info only, so the query string must not + * be part of the route path. + */ + private function stripQueryString(string $path): string + { + return explode('?', $path, 2)[0]; + } } diff --git a/Tests/Routing/EndpointLoaderTest.php b/Tests/Routing/EndpointLoaderTest.php new file mode 100644 index 0000000..5084ff9 --- /dev/null +++ b/Tests/Routing/EndpointLoaderTest.php @@ -0,0 +1,67 @@ +loadRoutes('/v1/items?excludeIds={excludeIds}', 'GET'); + + $route = $routes->get(RequestStub::class); + $this->assertNotNull($route); + $this->assertSame('/v1/items', $route->getPath()); + $this->assertSame(['GET'], $route->getMethods()); + } + + public function testLoadKeepsPathPlaceholders(): void + { + $routes = $this->loadRoutes('/v1/cars/{id}', 'POST'); + + $route = $routes->get(RequestStub::class); + $this->assertNotNull($route); + $this->assertSame('/v1/cars/{id}', $route->getPath()); + $this->assertSame(['POST'], $route->getMethods()); + } + + private function loadRoutes(string $path, string $method): RouteCollection + { + $endpoint = (new Endpoint()) + ->setPath($path) + ->setMethod($method); + + $endpointRegistryProphecy = $this->prophesize(EndpointRegistryInterface::class); + $endpointRegistryProphecy->getEndpoint(Argument::type(RequestStub::class)) + ->willReturn($endpoint); + + $endpointLoader = new EndpointLoader( + $endpointRegistryProphecy->reveal(), + [self::CONTROLLER => RequestStub::class] + ); + + $routes = $endpointLoader->load('.', 'endpoint_handler'); + $this->assertInstanceOf(RouteCollection::class, $routes); + + return $routes; + } +} diff --git a/Tests/Routing/RequestStub.php b/Tests/Routing/RequestStub.php new file mode 100644 index 0000000..faf1326 --- /dev/null +++ b/Tests/Routing/RequestStub.php @@ -0,0 +1,20 @@ +