diff --git a/test/tests/unit/Routing/RouterTest.php b/test/tests/unit/Routing/RouterTest.php index ec53416..b8a48f7 100644 --- a/test/tests/unit/Routing/RouterTest.php +++ b/test/tests/unit/Routing/RouterTest.php @@ -3,12 +3,15 @@ namespace WellRESTed\Test\Unit\Routing; use Prophecy\Argument; +use WellRESTed\Dispatching\Dispatcher; +use WellRESTed\Message\Response; +use WellRESTed\Message\ServerRequest; use WellRESTed\Routing\Route\RouteInterface; use WellRESTed\Routing\Router; +use WellRESTed\Test\NextMock; /** - * @coversDefaultClass WellRESTed\Routing\Router - * @uses WellRESTed\Routing\Router + * @covers WellRESTed\Routing\Router * @group routing */ class RouterTest extends \PHPUnit_Framework_TestCase @@ -39,21 +42,9 @@ class RouterTest extends \PHPUnit_Framework_TestCase $this->factory = $this->prophesize('WellRESTed\Routing\Route\RouteFactory'); $this->factory->create(Argument::any())->willReturn($this->route->reveal()); - $this->request = $this->prophesize('Psr\Http\Message\ServerRequestInterface'); - $this->request->withAttribute(Argument::cetera())->willReturn($this->request->reveal()); - - $this->response = $this->prophesize('Psr\Http\Message\ResponseInterface'); - $this->next = function ($request, $response) { - return $response; - }; - - $this->dispatcher = $this->prophesize('WellRESTed\Dispatching\DispatcherInterface'); - $this->dispatcher->dispatch(Argument::cetera())->will( - function ($args) { - list($middleware, $request, $response, $next) = $args; - return $middleware->dispatch($request, $response, $next); - } - ); + $this->request = new ServerRequest(); + $this->response = new Response(); + $this->next = new NextMock(); $this->router = $this->getMockBuilder('WellRESTed\Routing\Router') ->setMethods(["getRouteFactory"]) @@ -62,41 +53,27 @@ class RouterTest extends \PHPUnit_Framework_TestCase $this->router->expects($this->any()) ->method("getRouteFactory") ->will($this->returnValue($this->factory->reveal())); - $this->router->__construct($this->dispatcher->reveal()); + $this->router->__construct(new Dispatcher()); } // ------------------------------------------------------------------------ // Construction - /** - * @covers ::__construct - * @covers ::getRouteFactory - * @uses WellRESTed\Routing\Route\RouteFactory - */ public function testCreatesInstance() { - $router = new Router($this->dispatcher->reveal()); + $router = new Router(new Dispatcher()); $this->assertNotNull($router); } // ------------------------------------------------------------------------ // Populating - /** - * @covers ::register - * @covers ::getRouteForTarget - * @covers ::registerRouteForTarget - */ public function testCreatesRouteForTarget() { $this->router->register("GET", "/", "middleware"); $this->factory->create("/")->shouldHaveBeenCalled(); } - /** - * @covers ::register - * @covers ::getRouteForTarget - */ public function testDoesNotRecreateRouteForExistingTarget() { $this->router->register("GET", "/", "middleware"); @@ -104,9 +81,6 @@ class RouterTest extends \PHPUnit_Framework_TestCase $this->factory->create("/")->shouldHaveBeenCalledTimes(1); } - /** - * @covers ::register - */ public function testPassesMethodAndMiddlewareToMethodMap() { $this->router->register("GET", "/", "middleware"); @@ -116,65 +90,50 @@ class RouterTest extends \PHPUnit_Framework_TestCase // ------------------------------------------------------------------------ // Dispatching - /** - * @covers ::__invoke - * @covers ::getStaticRoute - * @covers ::registerRouteForTarget - */ public function testDispatchesStaticRoute() { $target = "/"; + $this->request = $this->request->withRequestTarget($target); - $this->request->getRequestTarget()->willReturn($target); $this->route->getTarget()->willReturn($target); $this->route->getType()->willReturn(RouteInterface::TYPE_STATIC); $this->router->register("GET", $target, "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); - $this->route->__invoke($this->request->reveal(), $this->response->reveal(), $this->next)->shouldHaveBeenCalled(); + $this->route->__invoke($this->request, $this->response, $this->next)->shouldHaveBeenCalled(); } - /** - * @covers ::__invoke - * @covers ::getPrefixRoute - * @covers ::registerRouteForTarget - */ public function testDispatchesPrefixRoute() { $target = "/animals/cats/*"; - $this->request->getRequestTarget()->willReturn("/animals/cats/molly"); + $this->request = $this->request->withRequestTarget("/animals/cats/molly"); + $this->route->getTarget()->willReturn($target); $this->route->getType()->willReturn(RouteInterface::TYPE_PREFIX); $this->router->register("GET", $target, "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); - $this->route->__invoke($this->request->reveal(), $this->response->reveal(), $this->next)->shouldHaveBeenCalled(); + $this->route->__invoke($this->request, $this->response, $this->next)->shouldHaveBeenCalled(); } - /** - * @covers ::__invoke - * @covers ::registerRouteForTarget - */ public function testDispatchesPatternRoute() { $target = "/"; + $this->request = $this->request->withRequestTarget($target); - $this->request->getRequestTarget()->willReturn($target); $this->route->getTarget()->willReturn($target); $this->route->getType()->willReturn(RouteInterface::TYPE_PATTERN); $this->route->matchesRequestTarget(Argument::cetera())->willReturn(true); $this->router->register("GET", $target, "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); - $this->route->__invoke($this->request->reveal(), $this->response->reveal(), $this->next)->shouldHaveBeenCalled(); + $this->route->__invoke($this->request, $this->response, $this->next)->shouldHaveBeenCalled(); } - /** - * @coversNothing - */ + /** @coversNothing */ public function testDispatchesStaticRouteBeforePrefixRoute() { $staticRoute = $this->prophesize('WellRESTed\Routing\Route\RouteInterface'); @@ -189,21 +148,18 @@ class RouterTest extends \PHPUnit_Framework_TestCase $prefixRoute->getType()->willReturn(RouteInterface::TYPE_PREFIX); $prefixRoute->__invoke(Argument::cetera())->willReturn(); - $this->request->getRequestTarget()->willReturn("/cats/"); + $this->request = $this->request->withRequestTarget("/cats/"); $this->factory->create("/cats/")->willReturn($staticRoute->reveal()); $this->factory->create("/cats/*")->willReturn($prefixRoute->reveal()); $this->router->register("GET", "/cats/", "middleware"); $this->router->register("GET", "/cats/*", "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); - $staticRoute->__invoke($this->request->reveal(), $this->response->reveal(), $this->next)->shouldHaveBeenCalled(); + $staticRoute->__invoke($this->request, $this->response, $this->next)->shouldHaveBeenCalled(); } - /** - * @covers ::getPrefixRoute - */ public function testDispatchesLongestMatchingPrefixRoute() { // Note: The longest route is also good for 2 points in Settlers of Catan. @@ -220,21 +176,18 @@ class RouterTest extends \PHPUnit_Framework_TestCase $longRoute->getType()->willReturn(RouteInterface::TYPE_PREFIX); $longRoute->__invoke(Argument::cetera())->willReturn(); - $this->request->getRequestTarget()->willReturn("/animals/cats/molly"); + $this->request = $this->request->withRequestTarget("/animals/cats/molly"); $this->factory->create("/animals/*")->willReturn($shortRoute->reveal()); $this->factory->create("/animals/cats/*")->willReturn($longRoute->reveal()); $this->router->register("GET", "/animals/*", "middleware"); $this->router->register("GET", "/animals/cats/*", "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); - $longRoute->__invoke($this->request->reveal(), $this->response->reveal(), $this->next)->shouldHaveBeenCalled(); + $longRoute->__invoke($this->request, $this->response, $this->next)->shouldHaveBeenCalled(); } - /** - * @coversNothing - */ public function testDispatchesPrefixRouteBeforePatternRoute() { $prefixRoute = $this->prophesize('WellRESTed\Routing\Route\RouteInterface'); @@ -249,21 +202,18 @@ class RouterTest extends \PHPUnit_Framework_TestCase $patternRoute->getType()->willReturn(RouteInterface::TYPE_PATTERN); $patternRoute->__invoke(Argument::cetera())->willReturn(); - $this->request->getRequestTarget()->willReturn("/cats/"); + $this->request = $this->request->withRequestTarget("/cats/"); $this->factory->create("/cats/*")->willReturn($prefixRoute->reveal()); $this->factory->create("/cats/{id}")->willReturn($patternRoute->reveal()); $this->router->register("GET", "/cats/*", "middleware"); $this->router->register("GET", "/cats/{id}", "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); - $prefixRoute->__invoke($this->request->reveal(), $this->response->reveal(), $this->next)->shouldHaveBeenCalled(); + $prefixRoute->__invoke($this->request, $this->response, $this->next)->shouldHaveBeenCalled(); } - /** - * @coversNothing - */ public function testDispatchesFirstMatchingPatternRoute() { $patternRoute1 = $this->prophesize('WellRESTed\Routing\Route\RouteInterface'); @@ -282,21 +232,18 @@ class RouterTest extends \PHPUnit_Framework_TestCase $patternRoute2->matchesRequestTarget(Argument::any())->willReturn(true); $patternRoute2->__invoke(Argument::cetera())->willReturn(); - $this->request->getRequestTarget()->willReturn("/cats/molly"); + $this->request = $this->request->withRequestTarget("/cats/molly"); $this->factory->create("/cats/{id}")->willReturn($patternRoute1->reveal()); $this->factory->create("/cats/{name}")->willReturn($patternRoute2->reveal()); $this->router->register("GET", "/cats/{id}", "middleware"); $this->router->register("GET", "/cats/{name}", "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); - $patternRoute1->__invoke($this->request->reveal(), $this->response->reveal(), $this->next)->shouldHaveBeenCalled(); + $patternRoute1->__invoke($this->request, $this->response, $this->next)->shouldHaveBeenCalled(); } - /** - * @coversNothing - */ public function testStopsTestingPatternsAfterFirstSuccessfulMatch() { $patternRoute1 = $this->prophesize('WellRESTed\Routing\Route\RouteInterface'); @@ -315,33 +262,30 @@ class RouterTest extends \PHPUnit_Framework_TestCase $patternRoute2->matchesRequestTarget(Argument::any())->willReturn(true); $patternRoute2->__invoke(Argument::cetera())->willReturn(); - $this->request->getRequestTarget()->willReturn("/cats/molly"); + $this->request = $this->request->withRequestTarget("/cats/molly"); $this->factory->create("/cats/{id}")->willReturn($patternRoute1->reveal()); $this->factory->create("/cats/{name}")->willReturn($patternRoute2->reveal()); $this->router->register("GET", "/cats/{id}", "middleware"); $this->router->register("GET", "/cats/{name}", "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); $patternRoute2->matchesRequestTarget(Argument::any())->shouldNotHaveBeenCalled(); } - /** - * @covers ::__invoke - * @covers ::registerRouteForTarget - */ public function testMatchesPathAgainstRouteWithoutQuery() { $target = "/my/path?cat=molly&dog=bear"; - $this->request->getRequestTarget()->willReturn($target); + $this->request = $this->request->withRequestTarget($target); + $this->route->getTarget()->willReturn($target); $this->route->getType()->willReturn(RouteInterface::TYPE_PATTERN); $this->route->matchesRequestTarget(Argument::cetera())->willReturn(true); $this->router->register("GET", $target, "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); $this->route->matchesRequestTarget("/my/path")->shouldHaveBeenCalled(); } @@ -349,31 +293,33 @@ class RouterTest extends \PHPUnit_Framework_TestCase // ------------------------------------------------------------------------ // Path Variables - /** - * @covers ::__invoke - * @dataProvider pathVariableProvider - */ + /** @dataProvider pathVariableProvider */ public function testSetPathVariablesAttributeIndividually($name, $value) { - $attributeName = "pathVariables"; - $target = "/"; $variables = [ "id" => "1024", "name" => "Molly" ]; - $this->request->getRequestTarget()->willReturn($target); + $this->request = $this->request->withRequestTarget($target); + $this->route->getTarget()->willReturn($target); $this->route->getType()->willReturn(RouteInterface::TYPE_PATTERN); $this->route->matchesRequestTarget(Argument::cetera())->willReturn(true); $this->route->getPathVariables()->willReturn($variables); - $this->router->__construct($this->dispatcher->reveal()); $this->router->register("GET", $target, "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); - $this->request->withAttribute($name, $value)->shouldHaveBeenCalled(); + $isRequestWithExpectedAttribute = function ($request) use ($name, $value) { + return $request->getAttribute($name) === $value; + }; + + $this->route->__invoke( + Argument::that($isRequestWithExpectedAttribute), + Argument::cetera() + )->shouldHaveBeenCalled(); } public function pathVariableProvider() @@ -384,9 +330,6 @@ class RouterTest extends \PHPUnit_Framework_TestCase ]; } - /** - * @covers ::__invoke - */ public function testSetPathVariablesAttributeAsArray() { $attributeName = "pathVariables"; @@ -397,52 +340,42 @@ class RouterTest extends \PHPUnit_Framework_TestCase "name" => "Molly" ]; - $this->request->getRequestTarget()->willReturn($target); + $this->request = $this->request->withRequestTarget($target); + $this->route->getTarget()->willReturn($target); $this->route->getType()->willReturn(RouteInterface::TYPE_PATTERN); $this->route->matchesRequestTarget(Argument::cetera())->willReturn(true); $this->route->getPathVariables()->willReturn($variables); - $this->router->__construct($this->dispatcher->reveal(), $attributeName); + $this->router->__construct(new Dispatcher(), $attributeName); $this->router->register("GET", $target, "middleware"); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); + $this->router->__invoke($this->request, $this->response, $this->next); - $this->request->withAttribute("pathVariables", $variables)->shouldHaveBeenCalled(); + $isRequestWithExpectedAttribute = function ($request) use ($attributeName, $variables) { + return $request->getAttribute($attributeName) === $variables; + }; + + $this->route->__invoke( + Argument::that($isRequestWithExpectedAttribute), + Argument::cetera() + )->shouldHaveBeenCalled(); } // ------------------------------------------------------------------------ // No Matching Routes - /** - * @covers ::__invoke - * @covers ::getStaticRoute - * @covers ::getPrefixRoute - */ public function testResponds404WhenNoRouteMatches() { - $this->request->getRequestTarget()->willReturn("/no/match"); - $this->response->withStatus(Argument::any())->willReturn($this->response->reveal()); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $this->next); - $this->response->withStatus(404)->shouldHaveBeenCalled(); + $this->request = $this->request->withRequestTarget("/no/match"); + $response = $this->router->__invoke($this->request, $this->response, $this->next); + $this->assertEquals(404, $response->getStatusCode()); } - /** - * @covers ::__invoke - * @covers ::getStaticRoute - * @covers ::getPrefixRoute - */ public function testStopsPropagatingWhenNoRouteMatches() { - $calledNext = false; - $next = function ($request, $response) use (&$calledNext) { - $calledNext = true; - return $response; - }; - - $this->request->getRequestTarget()->willReturn("/no/match"); - $this->response->withStatus(Argument::any())->willReturn($this->response->reveal()); - $this->router->__invoke($this->request->reveal(), $this->response->reveal(), $next); - $this->assertFalse($calledNext); + $this->request = $this->request->withRequestTarget("/no/match"); + $this->router->__invoke($this->request, $this->response, $this->next); + $this->assertFalse($this->next->called); } public function testRegisterIsFluid()