diff --git a/lib/Router.php b/lib/Router.php index 5d94037..0e9e4e2 100644 --- a/lib/Router.php +++ b/lib/Router.php @@ -151,7 +151,7 @@ public function do(InternalRequest $ireq) { * @return self */ public function use($action) { - if (is_callable($action) || $action instanceof Middleware || $action instanceof Bootable) { + if (!(is_callable($action) || $action instanceof Middleware || $action instanceof Bootable)) { throw new \InvalidArgumentException( __METHOD__ . " requires a callable action or Middleware instance" ); diff --git a/lib/StandardRequest.php b/lib/StandardRequest.php index a11ca71..7225f03 100644 --- a/lib/StandardRequest.php +++ b/lib/StandardRequest.php @@ -85,10 +85,6 @@ public function getQueryVars(): array { public function getCookie(string $name) { $ireq = $this->internalRequest; - if (!isset($ireq->cookies)) { - $ireq->generateCookies(); - } - return $ireq->cookies[$name] ?? null; } diff --git a/test/ClientTest.php b/test/ClientTest.php index 7fdacaf..7ec390e 100644 --- a/test/ClientTest.php +++ b/test/ClientTest.php @@ -46,6 +46,7 @@ function testTrivialHttpRequest() { $this->assertEquals("/uri", explode("?", $req->getUri())[0]); $this->assertEquals(["foo" => "bar", "baz" => ["1", "2", "qux" => "3"]], $req->getQueryVars()); $this->assertEquals(["header"], $req->getHeaderArray("custom")); + $this->assertEquals("value", $req->getCookie("test")); $res->setCookie("cookie", "with value"); $res->setHeader("custom", "header"); @@ -57,6 +58,7 @@ function testTrivialHttpRequest() { }); $cookies = new \Amp\Artax\Cookie\ArrayCookieJar; + $cookies->store(new \Amp\Artax\Cookie\Cookie("test", "value", null, "/", "localhost")); $client = new Client($cookies); $client->setOption(Client::OP_CRYPTO, ["allow_self_signed" => true, "peer_name" => "localhost", "crypto_method" => STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT]); $port = parse_url($address, PHP_URL_PORT); diff --git a/test/RouterTest.php b/test/RouterTest.php index fc86d69..74cb829 100644 --- a/test/RouterTest.php +++ b/test/RouterTest.php @@ -38,18 +38,20 @@ function setOption(string $opt, $val) { return $this->options->$opt = $val; } function mockResponse($state = Response::NONE) { return new class($state) implements Response { private $state; + public $headers = []; + public $status = 200; public function __construct($state) { $this->state = $state; } - function setStatus(int $code): Response { return $this; } + function setStatus(int $code): Response { $this->status = $code; return $this; } function setReason(string $phrase): Response { return $this; } - function addHeader(string $field, string $value): Response { return $this; } - function setHeader(string $field, string $value): Response { return $this; } + function addHeader(string $field, string $value): Response { $this->headers[strtolower($field)] = $value; return $this; } + function setHeader(string $field, string $value): Response { $this->headers[strtolower($field)] = $value; return $this; } function setCookie(string $field, string $value, array $flags = []): Response { return $this; } function send(string $body) { $this->state = self::ENDED; } function stream(string $partialBodyChunk): Promise { return new Success; } function flush() { } function end(string $finalBodyChunk = null) { } function push(string $url, array $headers = null): Response { return $this; } - function state(): int { return 42; } + function state(): int { return $this->state; } }; } @@ -85,6 +87,50 @@ function testUpdateFailsIfStartedWithoutAnyRoutes() { $this->assertSame($i, 1); } + function testUseCanonicalRedirector() { + $router = new Router; + $router->route("GET", "/{name}/{age}/?", function($req, $res) { $res->send("OK"); }); + $router->prefix("/mediocre-dev"); + $router = (new Router)->use($router); + $mock = $this->mockServer(Server::STARTING); + $router->update($mock); + + $ireq = new InternalRequest; + $request = new StandardRequest($ireq); + $ireq->locals = []; + $ireq->method = "GET"; + $ireq->uri = $ireq->uriPath = "/mediocre-dev/bob/19/"; + $response = $this->mockResponse(); + + $this->assertFalse($router->do($ireq)->valid()); + $multiAction = $router($request, $response); + + if ($multiAction) { + wait(resolve($multiAction)); + } + + $this->assertEquals(\Aerys\HTTP_STATUS["FOUND"], $response->status); + $this->assertEquals("/mediocre-dev/bob/19", $response->headers["location"]); + $this->assertSame(["name" => "bob", "age" => "19"], $ireq->locals["aerys.routeArgs"]); + + $ireq = new InternalRequest; + $request = new StandardRequest($ireq); + $ireq->locals = []; + $ireq->method = "GET"; + $ireq->uriPath = "/mediocre-dev/bob/19"; + $response = $this->mockResponse(); + + $this->assertFalse($router->do($ireq)->valid()); + $multiAction = $router($request, $response); + + if ($multiAction) { + wait(resolve($multiAction)); + } + + $this->assertEquals(\Aerys\Response::ENDED, $response->state()); + $this->assertEquals(\Aerys\HTTP_STATUS["OK"], $response->status); + } + function testMultiActionRouteInvokesEachCallableUntilResponseIsStarted() { $i = 0; $foo = function() use (&$i) { $i++; };