From b57816ccedd331cb79b7c6e04b102d949cd09a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Cobucci?= Date: Wed, 18 Dec 2019 20:03:47 +0100 Subject: [PATCH] Merge pull request #25 from chimeraphp/prevent-generated-id-override Prevent generated id override --- src/Handler/CreateAndFetch.php | 2 +- src/Handler/CreateOnly.php | 2 +- tests/Handler/CreateAndFetchTest.php | 68 ++++++++++++++++++++++++---- tests/Handler/CreateOnlyTest.php | 64 ++++++++++++++++++++++---- 4 files changed, 114 insertions(+), 22 deletions(-) diff --git a/src/Handler/CreateAndFetch.php b/src/Handler/CreateAndFetch.php index 48be38e..f3be2b6 100644 --- a/src/Handler/CreateAndFetch.php +++ b/src/Handler/CreateAndFetch.php @@ -74,7 +74,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface { $request = $request->withAttribute( IdentifierGenerator::class, - $this->identifierGenerator->generate() + $request->getAttribute(IdentifierGenerator::class, $this->identifierGenerator->generate()) ); $input = new HttpRequest($request); diff --git a/src/Handler/CreateOnly.php b/src/Handler/CreateOnly.php index e540c6a..da8c162 100644 --- a/src/Handler/CreateOnly.php +++ b/src/Handler/CreateOnly.php @@ -70,7 +70,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface { $request = $request->withAttribute( IdentifierGenerator::class, - $this->identifierGenerator->generate() + $request->getAttribute(IdentifierGenerator::class, $this->identifierGenerator->generate()) ); $this->action->execute(new HttpRequest($request)); diff --git a/tests/Handler/CreateAndFetchTest.php b/tests/Handler/CreateAndFetchTest.php index ceca9ae..fbc6bef 100644 --- a/tests/Handler/CreateAndFetchTest.php +++ b/tests/Handler/CreateAndFetchTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; use Zend\Diactoros\ResponseFactory; use Zend\Diactoros\ServerRequest; @@ -65,15 +66,6 @@ public function createDependencies(): void */ public function handleShouldExecuteTheCommandAndReturnAnEmptyResponse(): void { - $handler = new CreateAndFetch( - new ExecuteCommand($this->bus, $this->creator, 'command'), - new ExecuteQuery($this->bus, $this->creator, 'query'), - new ResponseFactory(), - 'info', - $this->uriGenerator, - $this->idGenerator - ); - $request = new ServerRequest(); $command = (object) ['a' => 'b']; $query = (object) ['c' => 'd']; @@ -96,7 +88,7 @@ public function handleShouldExecuteTheCommandAndReturnAnEmptyResponse(): void ->willReturn('/testing/1'); /** @var ResponseInterface|UnformattedResponse $response */ - $response = $handler->handle($request); + $response = $this->handleRequest($request); self::assertInstanceOf(UnformattedResponse::class, $response); self::assertSame(StatusCodeInterface::STATUS_CREATED, $response->getStatusCode()); @@ -104,4 +96,60 @@ public function handleShouldExecuteTheCommandAndReturnAnEmptyResponse(): void self::assertSame([ExecuteQuery::class => 'query'], $response->getAttributes()); self::assertSame('result', $response->getUnformattedContent()); } + + /** + * @test + * + * @covers ::__construct() + * @covers ::handle() + * @covers ::generateResponse() + * + * @uses \Chimera\Routing\HttpRequest + */ + public function handleShouldPreserveTheRequestGeneratedIdIfAlreadyPresent(): void + { + $request = (new ServerRequest())->withAttribute(IdentifierGenerator::class, 2); + $command = (object) ['a' => 'b']; + $query = (object) ['c' => 'd']; + + $this->creator->expects(self::exactly(2)) + ->method('create') + ->willReturn($command, $query); + + $this->bus->expects(self::exactly(2)) + ->method('handle') + ->withConsecutive([$command], [$query]) + ->willReturn(null, 'result'); + + $this->idGenerator->method('generate') + ->willReturn(1); + + $this->uriGenerator->expects(self::once()) + ->method('generateRelativePath') + ->with($request, 'info') + ->willReturn('/testing/2'); + + /** @var ResponseInterface|UnformattedResponse $response */ + $response = $this->handleRequest($request); + + self::assertInstanceOf(UnformattedResponse::class, $response); + self::assertSame(StatusCodeInterface::STATUS_CREATED, $response->getStatusCode()); + self::assertSame('/testing/2', $response->getHeaderLine('Location')); + self::assertSame([ExecuteQuery::class => 'query'], $response->getAttributes()); + self::assertSame('result', $response->getUnformattedContent()); + } + + private function handleRequest(ServerRequestInterface $request): ResponseInterface + { + $handler = new CreateAndFetch( + new ExecuteCommand($this->bus, $this->creator, 'command'), + new ExecuteQuery($this->bus, $this->creator, 'query'), + new ResponseFactory(), + 'info', + $this->uriGenerator, + $this->idGenerator + ); + + return $handler->handle($request); + } } diff --git a/tests/Handler/CreateOnlyTest.php b/tests/Handler/CreateOnlyTest.php index 47af203..f0ae793 100644 --- a/tests/Handler/CreateOnlyTest.php +++ b/tests/Handler/CreateOnlyTest.php @@ -13,6 +13,8 @@ use Lcobucci\ContentNegotiation\UnformattedResponse; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; use Zend\Diactoros\ResponseFactory; use Zend\Diactoros\ServerRequest; @@ -63,15 +65,6 @@ public function createDependencies(): void */ public function handleShouldExecuteTheCommandAndReturnAnEmptyResponse(): void { - $handler = new CreateOnly( - new ExecuteCommand($this->bus, $this->creator, 'command'), - new ResponseFactory(), - 'info', - $this->uriGenerator, - $this->idGenerator, - StatusCodeInterface::STATUS_CREATED - ); - $request = new ServerRequest(); $command = (object) ['a' => 'b']; @@ -91,10 +84,61 @@ public function handleShouldExecuteTheCommandAndReturnAnEmptyResponse(): void ->with($request->withAttribute(IdentifierGenerator::class, 1), 'info') ->willReturn('/testing/1'); - $response = $handler->handle($request); + $response = $this->handleRequest($request); self::assertNotInstanceOf(UnformattedResponse::class, $response); self::assertSame(StatusCodeInterface::STATUS_CREATED, $response->getStatusCode()); self::assertSame('/testing/1', $response->getHeaderLine('Location')); } + + /** + * @test + * + * @covers ::__construct() + * @covers ::handle() + * @covers ::generateResponse() + * + * @uses \Chimera\Routing\HttpRequest + */ + public function handleShouldPreserveTheRequestGeneratedIdIfAlreadyPresent(): void + { + $request = (new ServerRequest())->withAttribute(IdentifierGenerator::class, 2); + $command = (object) ['a' => 'b']; + + $this->creator->expects(self::once()) + ->method('create') + ->willReturn($command); + + $this->bus->expects(self::once()) + ->method('handle') + ->with($command); + + $this->idGenerator->method('generate') + ->willReturn(1); + + $this->uriGenerator->expects(self::once()) + ->method('generateRelativePath') + ->with($request, 'info') + ->willReturn('/testing/2'); + + $response = $this->handleRequest($request); + + self::assertNotInstanceOf(UnformattedResponse::class, $response); + self::assertSame(StatusCodeInterface::STATUS_CREATED, $response->getStatusCode()); + self::assertSame('/testing/2', $response->getHeaderLine('Location')); + } + + private function handleRequest(ServerRequestInterface $request): ResponseInterface + { + $handler = new CreateOnly( + new ExecuteCommand($this->bus, $this->creator, 'command'), + new ResponseFactory(), + 'info', + $this->uriGenerator, + $this->idGenerator, + StatusCodeInterface::STATUS_CREATED + ); + + return $handler->handle($request); + } }