324 lines
11 KiB
PHP
324 lines
11 KiB
PHP
<?php
|
|
|
|
namespace pjdietz\WellRESTed\Test;
|
|
|
|
use pjdietz\WellRESTed\Exceptions\HttpExceptions\HttpException;
|
|
use pjdietz\WellRESTed\Router;
|
|
use pjdietz\WellRESTed\Routes\TemplateRoute;
|
|
use Prophecy\Argument;
|
|
|
|
/**
|
|
* @covers pjdietz\WellRESTed\Router
|
|
*/
|
|
class RouterTest extends \PHPUnit_Framework_TestCase
|
|
{
|
|
private $handler;
|
|
private $request;
|
|
private $response;
|
|
private $route;
|
|
|
|
public function setUp()
|
|
{
|
|
$this->request = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\RequestInterface");
|
|
$this->request->getPath()->willReturn("/");
|
|
$this->request->getMethod()->willReturn("GET");
|
|
$this->response = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\ResponseInterface");
|
|
$this->route = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface");
|
|
$this->handler = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface");
|
|
}
|
|
|
|
public function testAddsSingleRoute()
|
|
{
|
|
$this->request->getPath()->willReturn("/cats/");
|
|
$this->handler->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$router = new Router();
|
|
$router->add("/cats/", $this->handler->reveal());
|
|
$response = $router->getResponse($this->request->reveal());
|
|
$this->assertNotNull($response);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider pathProvider
|
|
*/
|
|
public function testAddsMultpleRoutes($path, $exptectedSuccess)
|
|
{
|
|
$this->request->getPath()->willReturn($path);
|
|
$this->handler->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$router = new Router();
|
|
$router->add(
|
|
["/cats/", $this->handler->reveal()],
|
|
["/cats/*", $this->handler->reveal()],
|
|
["/dogs/{name}", $this->handler->reveal(), TemplateRoute::RE_ALPHA],
|
|
["~/hamsters/[a-z]+~", $this->handler->reveal()]
|
|
);
|
|
$response = $router->getResponse($this->request->reveal());
|
|
$this->assertEquals($exptectedSuccess, !is_null($response));
|
|
}
|
|
|
|
public function pathProvider()
|
|
{
|
|
return [
|
|
["/cats/", true],
|
|
["/cats/molly", true],
|
|
["/dogs/bear", true],
|
|
["/hamsters/fizzgig", true],
|
|
["/dogs/", false],
|
|
["/birds/", false],
|
|
["/hamsters/23", false]
|
|
];
|
|
}
|
|
|
|
public function testAddsSingleRouteInstance()
|
|
{
|
|
$router = new Router();
|
|
$router->addRoute($this->route->reveal());
|
|
$router->getResponse($this->request->reveal());
|
|
$this->route->getResponse(Argument::cetera())->shouldHaveBeenCalled();
|
|
}
|
|
|
|
public function testAddsMultipleRouteInstances()
|
|
{
|
|
$router = new Router();
|
|
$router->addRoutes([$this->route->reveal()]);
|
|
$router->getResponse($this->request->reveal());
|
|
$this->route->getResponse(Argument::cetera())->shouldHaveBeenCalled();
|
|
}
|
|
|
|
public function testPropagatesArgumentsToRouteTable()
|
|
{
|
|
$this->route->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
$this->request->getPath()->willReturn("/cats/");
|
|
$args = ["cat" => "molly"];
|
|
|
|
$router = new Router();
|
|
$router->addRoute($this->route->reveal());
|
|
$router->getResponse($this->request->reveal(), $args);
|
|
|
|
$this->route->getResponse($this->request->reveal(), $args)->shouldHaveBeenCalled();
|
|
}
|
|
|
|
public function testRespondsWithErrorResponseForHttpException()
|
|
{
|
|
$this->route->getResponse(Argument::cetera())->willThrow(new HttpException());
|
|
|
|
$router = new Router();
|
|
$router->addRoute($this->route->reveal());
|
|
$response = $router->getResponse($this->request->reveal());
|
|
$this->assertEquals(500, $response->getStatusCode());
|
|
}
|
|
|
|
public function testDispatchesErrorHandlerForStatusCode()
|
|
{
|
|
$this->response->getStatusCode()->willReturn(403);
|
|
$this->route->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$errorHandler = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface");
|
|
$errorHandler->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$router = new Router();
|
|
$router->addRoute($this->route->reveal());
|
|
$router->setErrorHandlers([403 => $errorHandler->reveal()]);
|
|
$router->getResponse($this->request->reveal());
|
|
|
|
$errorHandler->getResponse(Argument::cetera())->shouldHaveBeenCalled();
|
|
}
|
|
|
|
public function testDispatchesErrorHandlerWithOriginalRequest()
|
|
{
|
|
$this->request->getPath()->willReturn("/");
|
|
$this->response->getStatusCode()->willReturn(403);
|
|
$this->route->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$errorHandler = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface");
|
|
$errorHandler->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$request = $this->request->reveal();
|
|
|
|
$router = new Router();
|
|
$router->addRoute($this->route->reveal());
|
|
$router->setErrorHandlers([403 => $errorHandler->reveal()]);
|
|
$router->getResponse($request);
|
|
|
|
$errorHandler->getResponse(
|
|
Argument::that(
|
|
function ($arg) use ($request) {
|
|
return $arg === $request;
|
|
}
|
|
),
|
|
Argument::any()
|
|
)->shouldHaveBeenCalled();
|
|
}
|
|
|
|
public function testDispatchesErrorHandlerWithOriginalArguments()
|
|
{
|
|
$this->request->getPath()->willReturn("/");
|
|
$this->response->getStatusCode()->willReturn(403);
|
|
$response = $this->response->reveal();
|
|
$this->route->getResponse(Argument::cetera())->willReturn($response);
|
|
|
|
$errorHandler = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface");
|
|
$errorHandler->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$arguments = [
|
|
"cat" => "Molly",
|
|
"dog" => "Bear"
|
|
];
|
|
|
|
$router = new Router();
|
|
$router->addRoute($this->route->reveal());
|
|
$router->setErrorHandlers([403 => $errorHandler->reveal()]);
|
|
$router->getResponse($this->request->reveal(), $arguments);
|
|
|
|
$errorHandler->getResponse(
|
|
Argument::any(),
|
|
Argument::that(
|
|
function ($args) use ($arguments) {
|
|
return count(array_diff_assoc($arguments, $args)) === 0;
|
|
}
|
|
)
|
|
)->shouldHaveBeenCalled();
|
|
}
|
|
|
|
public function testDispatchesErrorHandlerWithPreviousResponse()
|
|
{
|
|
$this->request->getPath()->willReturn("/");
|
|
$this->response->getStatusCode()->willReturn(403);
|
|
$response = $this->response->reveal();
|
|
$this->route->getResponse(Argument::cetera())->willReturn($response);
|
|
|
|
$errorHandler = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface");
|
|
$errorHandler->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$router = new Router();
|
|
$router->addRoute($this->route->reveal());
|
|
$router->setErrorHandlers([403 => $errorHandler->reveal()]);
|
|
$router->getResponse($this->request->reveal());
|
|
|
|
$errorHandler->getResponse(
|
|
Argument::any(),
|
|
Argument::that(
|
|
function ($arg) use ($response) {
|
|
return isset($arg["response"]) && $arg["response"] === $response;
|
|
}
|
|
)
|
|
)->shouldHaveBeenCalled();
|
|
}
|
|
|
|
public function testDispatchesErrorCallable()
|
|
{
|
|
$this->request->getPath()->willReturn("/");
|
|
$this->response->getStatusCode()->willReturn(403);
|
|
$this->route->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$errorResponse = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\ResponseInterface");
|
|
$errorResponse->respond()->willReturn();
|
|
|
|
$errorCallable = function () use ($errorResponse) {
|
|
return $errorResponse->reveal();
|
|
};
|
|
|
|
$router = new Router();
|
|
$router->addRoute($this->route->reveal());
|
|
$router->setErrorHandlers([403 => $errorCallable]);
|
|
$result = $router->getResponse($this->request->reveal());
|
|
|
|
$this->assertSame($errorResponse->reveal(), $result);
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
* @preserveGlobalState disabled
|
|
*/
|
|
public function testRoutesServerRequest()
|
|
{
|
|
$_SERVER["REQUEST_URI"] = "/cats/";
|
|
$_SERVER["HTTP_HOST"] = "localhost";
|
|
$_SERVER["REQUEST_METHOD"] = "GET";
|
|
|
|
$this->response->getStatusCode()->willReturn(200);
|
|
$this->response->respond()->willReturn();
|
|
|
|
$this->route->willImplement("\\pjdietz\\WellRESTed\\Interfaces\\Routes\\StaticRouteInterface");
|
|
$this->route->getPaths()->willReturn(["/cats/"]);
|
|
$this->route->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$router = new Router();
|
|
$router->addRoute($this->route->reveal());
|
|
|
|
ob_start();
|
|
$router->respond();
|
|
ob_end_clean();
|
|
|
|
$this->response->respond()->shouldHaveBeenCalled();
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
* @preserveGlobalState disabled
|
|
*/
|
|
public function testRoutesStaticRequestToNoRouteResponse()
|
|
{
|
|
$_SERVER["REQUEST_URI"] = "/cats/";
|
|
$_SERVER["HTTP_HOST"] = "localhost";
|
|
$_SERVER["REQUEST_METHOD"] = "GET";
|
|
|
|
$router = new Router();
|
|
|
|
ob_start();
|
|
$router->respond();
|
|
$captured = ob_get_contents();
|
|
ob_end_clean();
|
|
|
|
$this->assertEquals("No resource at /cats/", $captured);
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
* @preserveGlobalState disabled
|
|
*/
|
|
public function testRoutesStaticRequestTo404ErrorHandler()
|
|
{
|
|
$_SERVER["REQUEST_URI"] = "/cats/";
|
|
$_SERVER["HTTP_HOST"] = "localhost";
|
|
$_SERVER["REQUEST_METHOD"] = "GET";
|
|
|
|
$errorHandler = $this->prophesize("\\pjdietz\\WellRESTed\\Interfaces\\HandlerInterface");
|
|
$errorHandler->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
|
|
$router = new Router();
|
|
$router->setErrorHandler(404, $errorHandler->reveal());
|
|
|
|
ob_start();
|
|
$router->respond();
|
|
ob_end_clean();
|
|
|
|
$errorHandler->getResponse(Argument::cetera())->shouldHaveBeenCalled();
|
|
}
|
|
|
|
public function testDeprecatedSetsStaticRoute()
|
|
{
|
|
$this->handler->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
$this->request->getPath()->willReturn("/cats/");
|
|
|
|
$router = new Router();
|
|
@$router->setStaticRoute(["/cats/"], $this->handler->reveal());
|
|
$router->getResponse($this->request->reveal());
|
|
|
|
$this->handler->getResponse(Argument::cetera())->shouldHaveBeenCalled();
|
|
}
|
|
|
|
public function testDeprecatedSetsPrefixRoute()
|
|
{
|
|
$this->handler->getResponse(Argument::cetera())->willReturn($this->response->reveal());
|
|
$this->request->getPath()->willReturn("/cats/molly");
|
|
|
|
$router = new Router();
|
|
@$router->setPrefixRoute(["/cats/"], $this->handler->reveal());
|
|
$router->getResponse($this->request->reveal());
|
|
|
|
$this->handler->getResponse(Argument::cetera())->shouldHaveBeenCalled();
|
|
}
|
|
}
|