diff --git a/module/Core/src/Action/PreviewAction.php b/module/Core/src/Action/PreviewAction.php index f2145e1b..291225be 100644 --- a/module/Core/src/Action/PreviewAction.php +++ b/module/Core/src/Action/PreviewAction.php @@ -2,16 +2,16 @@ namespace Shlinkio\Shlink\Core\Action; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; +use Interop\Http\ServerMiddleware\DelegateInterface; +use Interop\Http\ServerMiddleware\MiddlewareInterface; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; -use Shlinkio\Shlink\Common\Exception\PreviewGenerationException; use Shlinkio\Shlink\Common\Service\PreviewGenerator; use Shlinkio\Shlink\Common\Service\PreviewGeneratorInterface; use Shlinkio\Shlink\Common\Util\ResponseUtilsTrait; use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException; use Shlinkio\Shlink\Core\Service\UrlShortener; use Shlinkio\Shlink\Core\Service\UrlShortenerInterface; -use Zend\Stratigility\MiddlewareInterface; class PreviewAction implements MiddlewareInterface { @@ -40,44 +40,28 @@ class PreviewAction implements MiddlewareInterface } /** - * Process an incoming request and/or response. - * - * Accepts a server-side request and a response instance, and does - * something with them. - * - * If the response is not complete and/or further processing would not - * interfere with the work done in the middleware, or if the middleware - * wants to delegate to another process, it can use the `$out` callable - * if present. - * - * If the middleware does not return a value, execution of the current - * request is considered complete, and the response instance provided will - * be considered the response to return. - * - * Alternately, the middleware may return a response instance. - * - * Often, middleware will `return $out();`, with the assumption that a - * later middleware will return a response. + * Process an incoming server request and return a response, optionally delegating + * to the next middleware component to create the response. * * @param Request $request - * @param Response $response - * @param null|callable $out - * @return null|Response + * @param DelegateInterface $delegate + * + * @return Response */ - public function __invoke(Request $request, Response $response, callable $out = null) + public function process(Request $request, DelegateInterface $delegate) { $shortCode = $request->getAttribute('shortCode'); try { $url = $this->urlShortener->shortCodeToUrl($shortCode); if (! isset($url)) { - return $out($request, $response->withStatus(404), 'Not found'); + return $delegate->process($request); } $imagePath = $this->previewGenerator->generatePreview($url); return $this->generateImageResponse($imagePath); } catch (InvalidShortCodeException $e) { - return $out($request, $response->withStatus(404), 'Not found'); + return $delegate->process($request); } } } diff --git a/module/Core/test/Action/PreviewActionTest.php b/module/Core/test/Action/PreviewActionTest.php index 8ef2883a..a5e57d2d 100644 --- a/module/Core/test/Action/PreviewActionTest.php +++ b/module/Core/test/Action/PreviewActionTest.php @@ -2,12 +2,14 @@ namespace ShlinkioTest\Shlink\Core\Action; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; use Prophecy\Prophecy\ObjectProphecy; use Shlinkio\Shlink\Common\Exception\PreviewGenerationException; use Shlinkio\Shlink\Common\Service\PreviewGenerator; use Shlinkio\Shlink\Core\Action\PreviewAction; use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException; use Shlinkio\Shlink\Core\Service\UrlShortener; +use ShlinkioTest\Shlink\Common\Util\TestUtils; use Zend\Diactoros\Response; use Zend\Diactoros\ServerRequestFactory; @@ -36,20 +38,18 @@ class PreviewActionTest extends TestCase /** * @test */ - public function invalidShortCodeFallbacksToNextMiddlewareWithStatusNotFound() + public function invalidShortCodeFallsBackToNextMiddleware() { $shortCode = 'abc123'; $this->urlShortener->shortCodeToUrl($shortCode)->willReturn(null)->shouldBeCalledTimes(1); + $delegate = TestUtils::createDelegateMock(); - $resp = $this->action->__invoke( + $this->action->process( ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode), - new Response(), - function ($req, $resp) { - return $resp; - } + $delegate->reveal() ); - $this->assertEquals(404, $resp->getStatusCode()); + $delegate->process(Argument::cetera())->shouldHaveBeenCalledTimes(1); } /** @@ -63,9 +63,9 @@ class PreviewActionTest extends TestCase $this->urlShortener->shortCodeToUrl($shortCode)->willReturn($url)->shouldBeCalledTimes(1); $this->previewGenerator->generatePreview($url)->willReturn($path)->shouldBeCalledTimes(1); - $resp = $this->action->__invoke( + $resp = $this->action->process( ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode), - new Response() + TestUtils::createDelegateMock()->reveal() ); $this->assertEquals(filesize($path), $resp->getHeaderLine('Content-length')); @@ -75,20 +75,18 @@ class PreviewActionTest extends TestCase /** * @test */ - public function invalidShortcodeExceptionReturnsNotFound() + public function invalidShortcodeExceptionFallsBackToNextMiddleware() { $shortCode = 'abc123'; $this->urlShortener->shortCodeToUrl($shortCode)->willThrow(InvalidShortCodeException::class) ->shouldBeCalledTimes(1); + $delegate = TestUtils::createDelegateMock(); - $resp = $this->action->__invoke( + $this->action->process( ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode), - new Response(), - function ($req, $resp) { - return $resp; - } + $delegate->reveal() ); - $this->assertEquals(404, $resp->getStatusCode()); + $delegate->process(Argument::any())->shouldHaveBeenCalledTimes(1); } }