diff --git a/src/Routing/MethodMap.php b/src/Routing/MethodMap.php index b6b9547..76a230f 100644 --- a/src/Routing/MethodMap.php +++ b/src/Routing/MethodMap.php @@ -23,33 +23,28 @@ class MethodMap implements MethodMapInterface // MethodMapInterface /** - * Register middleware with a method. + * Register a dispatchable (handler or middleware) with a method. * * $method may be: * - A single verb ("GET"), * - A comma-separated list of verbs ("GET,PUT,DELETE") * - "*" to indicate any method. * - * $middleware may be: - * - An instance implementing MiddlewareInterface - * - A string containing the fully qualified class name of a class - * implementing MiddlewareInterface - * - A callable that returns an instance implementing MiddleInterface - * - A callable matching the signature of MiddlewareInterface::dispatch - * @see DispatchedInterface::dispatch + * $dispatchable may be anything a Dispatcher can dispatch. + * @see DispatcherInterface::dispatch * - * $middleware may also be null, in which case any previously set - * middleware for that method or methods will be unset. + * $dispatchable may also be null, in which case any previously set + * handlers and middle for that method or methods will be unset. * * @param string $method - * @param mixed $middleware + * @param mixed $dispatchable */ - public function register($method, $middleware) + public function register($method, $dispatchable) { $methods = explode(",", $method); $methods = array_map("trim", $methods); foreach ($methods as $method) { - $this->map[$method] = $middleware; + $this->map[$method] = $dispatchable; } } @@ -62,8 +57,11 @@ class MethodMap implements MethodMapInterface * @param callable $next * @return ResponseInterface */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next) - { + public function __invoke( + ServerRequestInterface $request, + ResponseInterface $response, + $next + ) { $method = $request->getMethod(); // Dispatch middleware registered with the explicitly matching method. if (isset($this->map[$method])) { @@ -119,8 +117,12 @@ class MethodMap implements MethodMapInterface * @param $next * @return ResponseInterface */ - private function dispatchMiddleware($middleware, ServerRequestInterface $request, ResponseInterface &$response, $next) - { + private function dispatchMiddleware( + $middleware, + ServerRequestInterface $request, + ResponseInterface &$response, + $next + ) { return $this->dispatcher->dispatch($middleware, $request, $response, $next); } } diff --git a/src/Routing/MethodMapInterface.php b/src/Routing/MethodMapInterface.php index 0027a76..2ac0e6a 100644 --- a/src/Routing/MethodMapInterface.php +++ b/src/Routing/MethodMapInterface.php @@ -7,15 +7,12 @@ use Psr\Http\Message\ServerRequestInterface; use WellRESTed\MiddlewareInterface; /** - * Maps HTTP methods to middleware + * Maps HTTP methods to handlers and middleware */ interface MethodMapInterface extends MiddlewareInterface { /** - * Evaluate $request's method and dispatches matching middleware. - * - * Implementations MUST pass $request, $response, and $next to the matching - * middleware. + * Evaluate $request's method and dispatches matching dispatchable. * * @param ServerRequestInterface $request * @param ResponseInterface $response @@ -25,23 +22,18 @@ interface MethodMapInterface extends MiddlewareInterface public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next); /** - * Register middleware with a method. + * Register a dispatchable (handler or middleware) with a method. * * $method may be: * - A single verb ("GET"), * - A comma-separated list of verbs ("GET,PUT,DELETE") * - "*" to indicate any method. * - * $middleware may be: - * - An instance implementing MiddlewareInterface - * - A string containing the fully qualified class name of a class - * implementing MiddlewareInterface - * - A callable that returns an instance implementing MiddleInterface - * - A callable matching the signature of MiddlewareInterface::dispatch + * $dispatchable may be anything a Dispatcher can dispatch. * @see DispatcherInterface::dispatch * * @param string $method - * @param mixed $middleware + * @param mixed $dispatchable */ - public function register($method, $middleware); + public function register($method, $dispatchable); } diff --git a/src/Routing/Route/Route.php b/src/Routing/Route/Route.php index 630f1d6..a641d80 100644 --- a/src/Routing/Route/Route.php +++ b/src/Routing/Route/Route.php @@ -37,6 +37,25 @@ abstract class Route implements RouteInterface return $this->target; } + /** + * Register a dispatchable (handler or middleware) with a method. + * + * $method may be: + * - A single verb ("GET"), + * - A comma-separated list of verbs ("GET,PUT,DELETE") + * - "*" to indicate any method. + * + * $dispatchable may be anything a Dispatcher can dispatch. + * @see DispatcherInterface::dispatch + * + * @param string $method + * @param mixed $dispatchable + */ + public function register($method, $dispatchable) + { + $this->methodMap->register($method, $dispatchable); + } + public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next) { $map = $this->methodMap; diff --git a/src/Routing/Route/RouteInterface.php b/src/Routing/Route/RouteInterface.php index d3ff8f7..3339a1f 100644 --- a/src/Routing/Route/RouteInterface.php +++ b/src/Routing/Route/RouteInterface.php @@ -64,4 +64,20 @@ interface RouteInterface extends MiddlewareInterface * invalid regular expression */ public function matchesRequestTarget($requestTarget); + + /** + * Register a dispatchable (handler or middleware) with a method. + * + * $method may be: + * - A single verb ("GET"), + * - A comma-separated list of verbs ("GET,PUT,DELETE") + * - "*" to indicate any method. + * + * $dispatchable may be anything a Dispatcher can dispatch. + * @see DispatcherInterface::dispatch + * + * @param string $method + * @param mixed $dispatchable + */ + public function register($method, $dispatchable); } diff --git a/test/tests/unit/Routing/Route/RouteTest.php b/test/tests/unit/Routing/Route/RouteTest.php index c3c9a69..1195845 100644 --- a/test/tests/unit/Routing/Route/RouteTest.php +++ b/test/tests/unit/Routing/Route/RouteTest.php @@ -3,53 +3,56 @@ namespace WellRESTed\Test\Unit\Routing\Route; use Prophecy\Argument; +use Psr\Http\Server\RequestHandlerInterface; +use WellRESTed\Message\Response; +use WellRESTed\Message\ServerRequest; +use WellRESTed\Routing\MethodMap; +use WellRESTed\Routing\Route\StaticRoute; use WellRESTed\Test\TestCase; class RouteTest extends TestCase { - public function testCreatesInstance() + const TARGET = '/target'; + + private $methodMap; + private $route; + + public function setUp() { - $methodMap = $this->prophesize('WellRESTed\Routing\MethodMapInterface'); - $route = $this->getMockForAbstractClass( - 'WellRESTed\Routing\Route\Route', - ["/target", $methodMap->reveal()]); - $this->assertNotNull($route); + $this->methodMap = $this->prophesize(MethodMap::class); + $this->methodMap->register(Argument::cetera()) + ->willReturn(); + $this->methodMap->__invoke(Argument::cetera()) + ->willReturn(new Response()); + + $this->route = new StaticRoute( + self::TARGET, $this->methodMap->reveal()); } public function testReturnsTarget() { - $methodMap = $this->prophesize('WellRESTed\Routing\MethodMapInterface'); - $route = $this->getMockForAbstractClass( - 'WellRESTed\Routing\Route\Route', - ["/target", $methodMap->reveal()]); - $this->assertSame("/target", $route->getTarget()); + $this->assertSame(self::TARGET, $this->route->getTarget()); } - public function testReturnsMethodMap() + public function testRegistersDispatchableWithMethodMap() { - $methodMap = $this->prophesize('WellRESTed\Routing\MethodMapInterface'); - $route = $this->getMockForAbstractClass( - 'WellRESTed\Routing\Route\Route', - ["/target", $methodMap->reveal()]); - $this->assertSame($methodMap->reveal(), $route->getMethodMap()); + $handler = $this->prophesize(RequestHandlerInterface::class)->reveal(); + + $this->route->register('GET', $handler); + + $this->methodMap->register('GET', $handler)->shouldHaveBeenCalled(); } public function testDispatchesMethodMap() { - $methodMap = $this->prophesize('WellRESTed\Routing\MethodMapInterface'); - $methodMap->__invoke(Argument::cetera())->willReturn(); - - $route = $this->getMockForAbstractClass( - 'WellRESTed\Routing\Route\Route', - ["/target", $methodMap->reveal()]); - - $request = $this->prophesize('Psr\Http\Message\ServerRequestInterface')->reveal(); - $response = $this->prophesize('Psr\Http\Message\ResponseInterface')->reveal(); - $next = function ($request, $response) { - return $response; + $request = new ServerRequest(); + $response = new Response(); + $next = function ($rqst, $resp) { + return $resp; }; - $route->__invoke($request, $response, $next); - $methodMap->__invoke(Argument::cetera())->shouldHaveBeenCalled(); + $this->route->__invoke($request, $response, $next); + + $this->methodMap->__invoke(Argument::cetera())->shouldHaveBeenCalled(); } }