diff --git a/src/Responder/Responder.php b/src/Responder/Responder.php index 39b7cb6..7c42928 100644 --- a/src/Responder/Responder.php +++ b/src/Responder/Responder.php @@ -5,11 +5,27 @@ namespace WellRESTed\Responder; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\StreamInterface; +use WellRESTed\Dispatching\Dispatcher; +use WellRESTed\Dispatching\DispatcherInterface; +use WellRESTed\Responder\Middleware\ContentLengthHandler; +use WellRESTed\Responder\Middleware\HeadHandler; class Responder implements ResponderInterface { + /** @var int */ private $chunkSize = 0; + /** @var DispatcherInterface */ + private $dispatcher; + + public function __construct(DispatcherInterface $dispatcher = null) + { + if ($dispatcher === null) { + $dispatcher = new Dispatcher(); + } + $this->dispatcher = $dispatcher; + } + /** * Outputs a response. * @@ -18,6 +34,9 @@ class Responder implements ResponderInterface */ public function respond(ServerRequestInterface $request, ResponseInterface $response) { + // Prepare the response for output. + $response = $this->prepareResponse($request, $response); + // Status Line header($this->getStatusLine($response)); // Headers @@ -43,6 +62,21 @@ class Responder implements ResponderInterface $this->chunkSize = $chunkSize; } + protected function prepareResponse(ServerRequestInterface $request, ResponseInterface $response) + { + return $this->dispatcher->dispatch( + [ + new ContentLengthHandler(), + new HeadHandler() + ], + $request, + $response, + function ($request, $response) { + return $response; + } + ); + } + private function getStatusLine(ResponseInterface $response) { $protocol = $response->getProtocolVersion(); diff --git a/test/tests/unit/Responder/ResponderTest.php b/test/tests/unit/Responder/ResponderTest.php index 3301373..f9664b2 100644 --- a/test/tests/unit/Responder/ResponderTest.php +++ b/test/tests/unit/Responder/ResponderTest.php @@ -9,7 +9,12 @@ use WellRESTed\Responder\Responder; require_once __DIR__ . "/../../../src/HeaderStack.php"; /** - * @covers WellRESTed\Responder\Responder + * @coversDefaultClass WellRESTed\Responder\Responder + * @uses WellRESTed\Responder\Responder + * @uses WellRESTed\Responder\Middleware\ContentLengthHandler + * @uses WellRESTed\Responder\Middleware\HeadHandler + * @uses WellRESTed\Dispatching\Dispatcher + * @uses WellRESTed\Dispatching\DispatchStack * @group responder */ class ResponderTest extends \PHPUnit_Framework_TestCase @@ -23,15 +28,34 @@ class ResponderTest extends \PHPUnit_Framework_TestCase HeaderStack::reset(); $this->body = $this->prophesize('\Psr\Http\Message\StreamInterface'); $this->body->isReadable()->willReturn(false); + $this->body->getSize()->willReturn(1024); $this->request = $this->prophesize('\Psr\Http\Message\ServerRequestInterface'); + $this->request->getMethod()->willReturn("HEAD"); $this->response = $this->prophesize('\Psr\Http\Message\ResponseInterface'); $this->response->getHeaders()->willReturn([]); + $this->response->hasHeader("Content-length")->willReturn(true); + $this->response->getHeaderLine("Transfer-encoding")->willReturn(""); $this->response->getProtocolVersion()->willReturn("1.1"); $this->response->getStatusCode()->willReturn("200"); $this->response->getReasonPhrase()->willReturn("Ok"); $this->response->getBody()->willReturn($this->body->reveal()); + $this->response->withHeader(Argument::cetera())->willReturn($this->response->reveal()); + $this->response->withBody(Argument::any())->willReturn($this->response->reveal()); } + /** + * @covers ::__construct + */ + public function testCreatesInstance() + { + $responder = new Responder(); + $this->assertNotNull($responder); + } + + /** + * @covers ::respond + * @covers ::getStatusLine + */ public function testSendStatusCodeWithReasonPhrase() { $this->response->getStatusCode()->willReturn("200"); @@ -42,6 +66,10 @@ class ResponderTest extends \PHPUnit_Framework_TestCase $this->assertContains("HTTP/1.1 200 Ok", HeaderStack::getHeaders()); } + /** + * @covers ::respond + * @covers ::getStatusLine + */ public function testSendStatusCodeWithoutReasonPhrase() { $this->response->getStatusCode()->willReturn("999"); @@ -53,6 +81,7 @@ class ResponderTest extends \PHPUnit_Framework_TestCase } /** + * @covers ::respond * @dataProvider headerProvider */ public function testSendsHeaders($header) @@ -76,6 +105,10 @@ class ResponderTest extends \PHPUnit_Framework_TestCase ]; } + /** + * @covers ::respond + * @covers ::outputBody + */ public function testOutputsBody() { $content = "Hello, world!"; @@ -93,6 +126,11 @@ class ResponderTest extends \PHPUnit_Framework_TestCase $this->assertEquals($content, $captured); } + /** + * @covers ::respond + * @covers ::setChunkSize + * @covers ::outputBody + */ public function testOutputsBodyInChunks() { $content = "Hello, world!"; @@ -124,4 +162,38 @@ class ResponderTest extends \PHPUnit_Framework_TestCase $this->assertEquals($content, $captured); } + + /** + * @cover ::prepareResponse + */ + public function testAddContentLengthHeader() + { + $bodySize = 1024; + $this->response->getStatusCode()->willReturn("200"); + $this->response->getReasonPhrase()->willReturn("Ok"); + $this->response->hasHeader("Content-length")->willReturn(false); + $this->body->isReadable()->willReturn(true); + $this->body->__toString()->willReturn(""); + $this->body->getSize()->willReturn($bodySize); + + $responder = new Responder(); + $responder->respond($this->request->reveal(), $this->response->reveal()); + $this->response->withHeader("Content-length", $bodySize)->shouldHaveBeenCalled(); + } + + /** + * @cover ::prepareResponse + */ + public function testReplacesBodyForHeadRequeset() + { + $this->response->getStatusCode()->willReturn("200"); + $this->response->getReasonPhrase()->willReturn("Ok"); + $this->response->hasHeader("Content-length")->willReturn(false); + $this->body->isReadable()->willReturn(true); + $this->body->__toString()->willReturn(""); + + $responder = new Responder(); + $responder->respond($this->request->reveal(), $this->response->reveal()); + $this->response->withBody(Argument::any())->shouldHaveBeenCalled(); + } }