diff --git a/module/Core/src/Middleware/QrCodeCacheMiddleware.php b/module/Core/src/Middleware/QrCodeCacheMiddleware.php index d0f132bb..67e9bdab 100644 --- a/module/Core/src/Middleware/QrCodeCacheMiddleware.php +++ b/module/Core/src/Middleware/QrCodeCacheMiddleware.php @@ -3,9 +3,11 @@ namespace Shlinkio\Shlink\Core\Middleware; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Doctrine\Common\Cache\Cache; +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 Zend\Stratigility\MiddlewareInterface; +use Zend\Diactoros\Response as DiactResp; class QrCodeCacheMiddleware implements MiddlewareInterface { @@ -26,44 +28,29 @@ class QrCodeCacheMiddleware 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) { $cacheKey = $request->getUri()->getPath(); // If this QR code is already cached, just return it if ($this->cache->contains($cacheKey)) { $qrData = $this->cache->fetch($cacheKey); + $response = new DiactResp(); $response->getBody()->write($qrData['body']); return $response->withHeader('Content-Type', $qrData['content-type']); } // If not, call the next middleware and cache it /** @var Response $resp */ - $resp = $out($request, $response); + $resp = $delegate->process($request); $this->cache->save($cacheKey, [ 'body' => $resp->getBody()->__toString(), 'content-type' => $resp->getHeaderLine('Content-Type'), diff --git a/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php b/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php index 50c2e736..abc1801d 100644 --- a/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php +++ b/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php @@ -4,7 +4,9 @@ namespace ShlinkioTest\Shlink\Core\Middleware; use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\Cache; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; use Shlinkio\Shlink\Core\Middleware\QrCodeCacheMiddleware; +use ShlinkioTest\Shlink\Common\Util\TestUtils; use Zend\Diactoros\Response; use Zend\Diactoros\ServerRequestFactory; use Zend\Diactoros\Uri; @@ -29,18 +31,15 @@ class QrCodeCacheMiddlewareTest extends TestCase /** * @test */ - public function noCachedPathFallbacksToNextMiddleware() + public function noCachedPathFallsBackToNextMiddleware() { - $isCalled = false; - $this->middleware->__invoke( - ServerRequestFactory::fromGlobals(), - new Response(), - function ($req, $resp) use (&$isCalled) { - $isCalled = true; - return $resp; - } - ); - $this->assertTrue($isCalled); + $delegate = TestUtils::createDelegateMock(); + $this->middleware->process(ServerRequestFactory::fromGlobals()->withUri( + new Uri('/foo/bar') + ), $delegate->reveal()); + + $this->assertTrue($this->cache->contains('/foo/bar')); + $delegate->process(Argument::any())->shouldHaveBeenCalledTimes(1); } /** @@ -51,19 +50,17 @@ class QrCodeCacheMiddlewareTest extends TestCase $isCalled = false; $uri = (new Uri())->withPath('/foo'); $this->cache->save('/foo', ['body' => 'the body', 'content-type' => 'image/png']); + $delegate = TestUtils::createDelegateMock(); - $resp = $this->middleware->__invoke( + $resp = $this->middleware->process( ServerRequestFactory::fromGlobals()->withUri($uri), - new Response(), - function ($req, $resp) use (&$isCalled) { - $isCalled = true; - return $resp; - } + $delegate->reveal() ); $this->assertFalse($isCalled); $resp->getBody()->rewind(); $this->assertEquals('the body', $resp->getBody()->getContents()); $this->assertEquals('image/png', $resp->getHeaderLine('Content-Type')); + $delegate->process(Argument::any())->shouldHaveBeenCalledTimes(0); } }