Update Routing integration test

This commit is contained in:
PJ Dietz 2018-06-21 16:53:17 -04:00
parent 9aab0d780e
commit 5e9e7f154b
1 changed files with 167 additions and 145 deletions

View File

@ -4,10 +4,11 @@ namespace WellRESTed\Test\Integration;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use WellRESTed\Message\Response; use WellRESTed\Message\Response;
use WellRESTed\Message\ServerRequest; use WellRESTed\Message\ServerRequest;
use WellRESTed\Message\Stream; use WellRESTed\Message\Stream;
use WellRESTed\MiddlewareInterface;
use WellRESTed\Server; use WellRESTed\Server;
use WellRESTed\Test\TestCase; use WellRESTed\Test\TestCase;
use WellRESTed\Transmission\TransmitterInterface; use WellRESTed\Transmission\TransmitterInterface;
@ -15,188 +16,209 @@ use WellRESTed\Transmission\TransmitterInterface;
/** /**
* @coversNothing * @coversNothing
*/ */
class ServerTest extends TestCase class RoutingTest extends TestCase
{ {
/** @var Server */
private $server;
/** @var TransmitterMock */
private $transmitter;
/** @var ServerRequestInterface */
private $request;
/** @var ResponseInterface */
private $response;
public function setUp()
{
parent::setUp();
$this->server = new Server();
$this->transmitter = new TransmitterMock();
$this->request = new ServerRequest();
$this->response = new Response();
}
private function respond(): ResponseInterface
{
$this->server->respond($this->request, $this->response, $this->transmitter);
return $this->transmitter->response;
}
// -------------------------------------------------------------------------
public function testDispatchesMiddleware() public function testDispatchesMiddleware()
{ {
$server = new Server(); $expectedResponse = (new Response())
$server->add(function ($rqst, $resp, $next) { ->withStatus(200)
$resp = $resp->withStatus(200) ->withBody(new Stream('Hello, world!'));
->withBody(new Stream("Hello, world!"));
return $next($rqst, $resp); $this->server->add(function () use ($expectedResponse) {
return $expectedResponse;
}); });
$request = new ServerRequest(); $actualResponse = $this->respond();
$response = new Response();
$transmitter = new CallableTransmitter(function ($request, $response) { $this->assertSame($expectedResponse, $actualResponse);
$this->assertEquals("Hello, world!", (string) $response->getBody());
});
$server->respond($request, $response, $transmitter);
} }
public function testDispatchesMiddlewareChain() public function testDispatchesMiddlewareChain()
{ {
$server = new Server(); $expectedResponse = (new Response())
$server->add(function ($rqst, $resp, $next) { ->withStatus(200)
return $next($rqst, $resp); ->withBody(new Stream('Hello, world!'));
});
$server->add(function ($rqst, $resp, $next) { $this->server->add(function ($rqst, $resp, $next) {
$resp = $resp->withStatus(200)
->withBody(new Stream("Hello, world!"));
return $next($rqst, $resp); return $next($rqst, $resp);
}); });
$this->server->add(function ($rqst, $resp, $next) {
$request = new ServerRequest();
$response = new Response();
$transmitter = new CallableTransmitter(function ($request, $response) {
$this->assertEquals("Hello, world!", (string) $response->getBody());
});
$server->respond($request, $response, $transmitter);
}
/**
* @dataProvider routeProvider
*/
public function testDispatchesAssortedMiddlewareTypesByPath($requestTarget, $expectedBody)
{
$stringMiddlewareWrapper = function ($string) {
return new StringMiddleware($string);
};
$server = new Server();
$server->add(function ($rqst, $resp, $next) {
return $next($rqst, $resp); return $next($rqst, $resp);
}); });
$server->add($server->createRouter() $this->server->add(function () use ($expectedResponse) {
->register("GET", "/fry", [ return $expectedResponse;
new StringMiddleware("Philip "),
new StringMiddleware("J. "),
new StringMiddleware("Fry")
])
->register("GET", "/leela", new StringMiddleware("Turanga Leela"))
->register("GET", "/bender", __NAMESPACE__ . '\BenderMiddleware')
->register("GET", "/professor", $stringMiddlewareWrapper("Professor Hubert J. Farnsworth"))
->register("GET", "/amy", function ($request, $response, $next) {
$message = "Amy Wong";
$body = $response->getBody();
if ($body->isWritable()) {
$body->write($message);
} else {
$response = $response->withBody(new Stream($message));
}
return $next($request, $response);
})
->register("GET", "/hermes", [
new StringMiddleware("Hermes "),
new StringMiddleware("Conrad", false),
new StringMiddleware(", CPA")
])
->register("GET", "/zoidberg", [
function ($request, $response, $next) {
// Prepend "Doctor " to the dispatched response on the return trip.
$response = $next($request, $response);
$message = "Doctor " . (string) $response->getBody();
return $response->withBody(new Stream($message));
},
new StringMiddleware("John "),
new StringMiddleware("Zoidberg")
])
);
$server->add(function ($rqst, $resp, $next) {
$resp = $resp->withStatus(200);
return $next($rqst, $resp);
}); });
$request = (new ServerRequest())->withRequestTarget($requestTarget); $actualResponse = $this->respond();
$response = new Response();
$transmitter = new CallableTransmitter(function ($request, $response) use ($expectedBody) { $this->assertSame($expectedResponse, $actualResponse);
$this->assertEquals($expectedBody, (string) $response->getBody());
});
$server->respond($request, $response, $transmitter);
} }
public function routeProvider() public function testDispatchesByRoute()
{ {
return [ $router = $this->server->createRouter()
["/fry", "Philip J. Fry"], ->register('GET', '/molly', new StringHandler('Molly'))
["/leela", "Turanga Leela"], ->register('GET', '/oscar', new StringHandler('Oscar'));
["/bender", "Bender Bending Rodriguez"], $this->server->add($router);
["/professor", "Professor Hubert J. Farnsworth"],
["/amy", "Amy Wong"], $this->request = $this->request
["/hermes", "Hermes Conrad"], ->withMethod('GET')
["/zoidberg", "Doctor John Zoidberg"] ->withRequestTarget('/molly');
];
$response = $this->respond();
$this->assertEquals('Molly', (string) $response->getBody());
} }
public function testDispatchesMiddlewareBeforeByRouteHandler()
{
$router = $this->server->createRouter()
->register('GET', '/molly', new StringHandler('Molly'))
->register('GET', '/oscar', new StringHandler('Oscar'));
$this->server->add(new HeaderAdderMiddleware(
'Content-type', 'application/cat'));
$this->server->add($router);
$this->request = $this->request
->withMethod('GET')
->withRequestTarget('/molly');
$response = $this->respond();
$this->assertEquals('Molly', (string) $response->getBody());
$this->assertEquals('application/cat',
$response->getHeaderLine('Content-type'));
}
public function testDispatchesMiddlewareSpecificToRouter()
{
$catRouter = $this->server->createRouter()
->addMiddleware(new HeaderAdderMiddleware(
'Content-type', 'application/cat'))
->register('GET', '/molly', new StringHandler('Molly'))
->register('GET', '/oscar', new StringHandler('Oscar'));
$this->server->add($catRouter);
$dogRouter = $this->server->createRouter()
->addMiddleware(new HeaderAdderMiddleware(
'Content-type', 'application/dog'))
->register('GET', '/bear', new StringHandler('Bear'));
$this->server->add($dogRouter);
$this->request = $this->request
->withMethod('GET')
->withRequestTarget('/bear');
$response = $this->respond();
$this->assertEquals('Bear', (string) $response->getBody());
$this->assertEquals('application/dog',
$response->getHeaderLine('Content-type'));
}
public function testResponds404WhenNoRouteMatched()
{
$catRouter = $this->server->createRouter()
->addMiddleware(new HeaderAdderMiddleware(
'Content-type', 'application/cat'))
->register('GET', '/molly', new StringHandler('Molly'))
->register('GET', '/oscar', new StringHandler('Oscar'));
$this->server->add($catRouter);
$dogRouter = $this->server->createRouter()
->addMiddleware(new HeaderAdderMiddleware(
'Content-type', 'application/dog'))
->register('GET', '/bear', new StringHandler('Bear'));
$this->server->add($dogRouter);
$this->request = $this->request
->withMethod('GET')
->withRequestTarget('/arfus');
$response = $this->respond();
$this->assertEquals(404, $response->getStatusCode());
}
} }
class CallableTransmitter implements TransmitterInterface // -----------------------------------------------------------------------------
class TransmitterMock implements TransmitterInterface
{ {
private $callable; /** @var ResponseInterface */
public $response;
public function __construct($callable) public function transmit(
{ ServerRequestInterface $request,
$this->callable = $callable; ResponseInterface $response
} ) {
$this->response = $response;
public function transmit(ServerRequestInterface $request, ResponseInterface $response)
{
$callable = $this->callable;
$callable($request, $response);
} }
} }
class StringMiddleware implements MiddlewareInterface class StringHandler implements RequestHandlerInterface
{ {
private $string; /** @var string */
private $propagate; private $body;
public function __construct($string, $propagate = true) public function __construct(string $body)
{ {
$this->string = $string; $this->body = $body;
$this->propagate = $propagate;
} }
/** public function handle(ServerRequestInterface $request): ResponseInterface
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @param callable $next
* @return ResponseInterface
*/
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next)
{ {
$body = $response->getBody(); return (new Response(200))
if ($body->isWritable()) { ->withBody(new Stream($this->body));
$body->write($this->string);
} else {
$response = $response->withBody(new Stream($this->string));
}
if ($this->propagate) {
return $next($request, $response);
} else {
return $response;
}
} }
} }
class BenderMiddleware implements MiddlewareInterface class HeaderAdderMiddleware implements MiddlewareInterface
{ {
/** /** @var string */
* @param ServerRequestInterface $request private $name;
* @param ResponseInterface $response /** @var string */
* @param callable $next private $value;
* @return ResponseInterface
*/ public function __construct(string $name, string $value)
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next)
{ {
$message = "Bender Bending Rodriguez"; $this->name = $name;
$body = $response->getBody(); $this->value = $value;
if ($body->isWritable()) { }
$body->write($message);
} else { public function process(
$response = $response->withBody(new Stream($message)); ServerRequestInterface $request,
} RequestHandlerInterface $handler
return $next($request, $response); ): ResponseInterface {
$response = $handler->handle($request);
$response = $response->withHeader($this->name, $this->value);
return $response;
} }
} }