Router responds 404 by default for non-matched routes
This commit is contained in:
parent
36b03b6ca2
commit
0a0d3c3bc9
|
|
@ -6,6 +6,7 @@ use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use WellRESTed\Dispatching\Dispatcher;
|
use WellRESTed\Dispatching\Dispatcher;
|
||||||
use WellRESTed\Dispatching\DispatcherInterface;
|
use WellRESTed\Dispatching\DispatcherInterface;
|
||||||
|
use WellRESTed\Message\Response;
|
||||||
use WellRESTed\Routing\Route\RouteFactory;
|
use WellRESTed\Routing\Route\RouteFactory;
|
||||||
use WellRESTed\Routing\Route\RouteFactoryInterface;
|
use WellRESTed\Routing\Route\RouteFactoryInterface;
|
||||||
use WellRESTed\Routing\Route\RouteInterface;
|
use WellRESTed\Routing\Route\RouteInterface;
|
||||||
|
|
@ -27,7 +28,9 @@ class Router implements RouterInterface
|
||||||
/** @var RouteInterface[] Hash array mapping path prefixes to routes */
|
/** @var RouteInterface[] Hash array mapping path prefixes to routes */
|
||||||
private $patternRoutes;
|
private $patternRoutes;
|
||||||
/** @var mixed[] List array of middleware */
|
/** @var mixed[] List array of middleware */
|
||||||
protected $stack;
|
private $stack;
|
||||||
|
/** @var bool Call the next middleware when no route matches */
|
||||||
|
private $continue = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Router.
|
* Create a new Router.
|
||||||
|
|
@ -91,7 +94,10 @@ class Router implements RouterInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no route exists, delegate to the next middleware.
|
if (!$this->continue) {
|
||||||
|
return $response->withStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
return $next($request, $response);
|
return $next($request, $response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,6 +179,12 @@ class Router implements RouterInterface
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function continue()
|
||||||
|
{
|
||||||
|
$this->continue = true;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance to dispatch middleware.
|
* Return an instance to dispatch middleware.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,6 @@ class Server
|
||||||
private $transmitter;
|
private $transmitter;
|
||||||
/** @var mixed[] List array of middleware */
|
/** @var mixed[] List array of middleware */
|
||||||
private $stack;
|
private $stack;
|
||||||
/** @var ResponseInterface */
|
|
||||||
private $unhandledResponse;
|
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->stack = [];
|
$this->stack = [];
|
||||||
|
|
@ -75,8 +73,8 @@ class Server
|
||||||
|
|
||||||
$response = $this->getResponse();
|
$response = $this->getResponse();
|
||||||
|
|
||||||
$next = function () {
|
$next = function ($rqst, $resp) {
|
||||||
return $this->getUnhandledResponse();
|
return $resp;
|
||||||
};
|
};
|
||||||
|
|
||||||
$dispatcher = $this->getDispatcher();
|
$dispatcher = $this->getDispatcher();
|
||||||
|
|
@ -149,15 +147,6 @@ class Server
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ResponseInterface $response
|
|
||||||
* @return Server
|
|
||||||
*/
|
|
||||||
public function setUnhandledResponse(ResponseInterface $response): Server {
|
|
||||||
$this->unhandledResponse = $response;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
/* Defaults */
|
/* Defaults */
|
||||||
|
|
||||||
|
|
@ -200,12 +189,4 @@ class Server
|
||||||
}
|
}
|
||||||
return $this->transmitter;
|
return $this->transmitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getUnhandledResponse()
|
|
||||||
{
|
|
||||||
if (!$this->unhandledResponse) {
|
|
||||||
$this->unhandledResponse = new Response(404);
|
|
||||||
}
|
|
||||||
return $this->unhandledResponse;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,8 @@ class RoutingTest extends TestCase
|
||||||
->addMiddleware(new HeaderAdderMiddleware(
|
->addMiddleware(new HeaderAdderMiddleware(
|
||||||
'Content-type', 'application/cat'))
|
'Content-type', 'application/cat'))
|
||||||
->register('GET', '/molly', new StringHandler('Molly'))
|
->register('GET', '/molly', new StringHandler('Molly'))
|
||||||
->register('GET', '/oscar', new StringHandler('Oscar'));
|
->register('GET', '/oscar', new StringHandler('Oscar'))
|
||||||
|
->continue();
|
||||||
$this->server->add($catRouter);
|
$this->server->add($catRouter);
|
||||||
|
|
||||||
$dogRouter = $this->server->createRouter()
|
$dogRouter = $this->server->createRouter()
|
||||||
|
|
@ -154,7 +155,8 @@ class RoutingTest extends TestCase
|
||||||
->addMiddleware(new HeaderAdderMiddleware(
|
->addMiddleware(new HeaderAdderMiddleware(
|
||||||
'Content-type', 'application/cat'))
|
'Content-type', 'application/cat'))
|
||||||
->register('GET', '/molly', new StringHandler('Molly'))
|
->register('GET', '/molly', new StringHandler('Molly'))
|
||||||
->register('GET', '/oscar', new StringHandler('Oscar'));
|
->register('GET', '/oscar', new StringHandler('Oscar'))
|
||||||
|
->continue();
|
||||||
$this->server->add($catRouter);
|
$this->server->add($catRouter);
|
||||||
|
|
||||||
$dogRouter = $this->server->createRouter()
|
$dogRouter = $this->server->createRouter()
|
||||||
|
|
|
||||||
|
|
@ -361,9 +361,27 @@ class RouterTest extends TestCase
|
||||||
)->shouldHaveBeenCalled();
|
)->shouldHaveBeenCalled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPropagatesToNextMiddlewareWhenNoRouteMatches()
|
// ------------------------------------------------------------------------
|
||||||
|
// No Match
|
||||||
|
|
||||||
|
public function testWhenNoRouteMatchesByDefaultResponds404()
|
||||||
{
|
{
|
||||||
$this->request = $this->request->withRequestTarget("/no/match");
|
$this->request = $this->request->withRequestTarget("/no/match");
|
||||||
|
$response = $this->router->__invoke($this->request, $this->response, $this->next);
|
||||||
|
$this->assertEquals(404, $response->getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testWhenNoRouteMatchesByDefaultDoesNotPropagatesToNextMiddleware()
|
||||||
|
{
|
||||||
|
$this->request = $this->request->withRequestTarget("/no/match");
|
||||||
|
$this->router->__invoke($this->request, $this->response, $this->next);
|
||||||
|
$this->assertFalse($this->next->called);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testWhenNoRouteMatchesAndContinueModePropagatesToNextMiddleware()
|
||||||
|
{
|
||||||
|
$this->request = $this->request->withRequestTarget("/no/match");
|
||||||
|
$this->router->continue();
|
||||||
$this->router->__invoke($this->request, $this->response, $this->next);
|
$this->router->__invoke($this->request, $this->response, $this->next);
|
||||||
$this->assertTrue($this->next->called);
|
$this->assertTrue($this->next->called);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,36 +182,23 @@ class ServerTest extends TestCase
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// End of Stack
|
// End of Stack
|
||||||
|
|
||||||
public function testResponds404ByDefaultWhenReachingEndOfStack()
|
public function testReturnsLastDoublePassResponseAtEndOfStack()
|
||||||
{
|
{
|
||||||
$this->server->respond();
|
$defaultResponse = new Response(404);
|
||||||
|
|
||||||
$has404StatusCode = function ($response) {
|
$this->server->setResponse($defaultResponse);
|
||||||
return $response->getStatusCode() === 404;
|
|
||||||
};
|
|
||||||
|
|
||||||
$this->transmitter->transmit(
|
$this->server->add(
|
||||||
Argument::any(),
|
function ($rqst, $resp, $next) {
|
||||||
Argument::that($has404StatusCode)
|
return $next($rqst, $resp);
|
||||||
)->shouldHaveBeenCalled();
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
public function testRespondsWithUnhandledResponseWhenReachingEndOfStack()
|
|
||||||
{
|
|
||||||
$unhandledResponse = (new Response(404))
|
|
||||||
->withBody(new Stream("I can't find it!"));
|
|
||||||
|
|
||||||
$this->server->setUnhandledResponse($unhandledResponse);
|
|
||||||
|
|
||||||
$this->server->respond();
|
$this->server->respond();
|
||||||
|
|
||||||
$isExpectedResponse = function ($response) use ($unhandledResponse) {
|
|
||||||
return $response === $unhandledResponse;
|
|
||||||
};
|
|
||||||
|
|
||||||
$this->transmitter->transmit(
|
$this->transmitter->transmit(
|
||||||
Argument::any(),
|
Argument::any(),
|
||||||
Argument::that($isExpectedResponse)
|
$defaultResponse
|
||||||
)->shouldHaveBeenCalled();
|
)->shouldHaveBeenCalled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue