From 85065c9330d3ceab399af7a44d8e6ce8a2c77d64 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 24 Nov 2024 14:05:33 +0100 Subject: [PATCH] Test behavior to track redirect URL --- module/Core/src/Visit/Model/Visitor.php | 1 + module/Core/test/Action/PixelActionTest.php | 13 +++++++--- .../Core/test/Action/RedirectActionTest.php | 12 +++++++--- .../NotFoundTrackerMiddlewareTest.php | 24 +++++++++++++++---- .../ExtraPathRedirectMiddlewareTest.php | 7 +++++- 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/module/Core/src/Visit/Model/Visitor.php b/module/Core/src/Visit/Model/Visitor.php index 53504d75..cab834e6 100644 --- a/module/Core/src/Visit/Model/Visitor.php +++ b/module/Core/src/Visit/Model/Visitor.php @@ -12,6 +12,7 @@ use function Shlinkio\Shlink\Core\geolocationFromRequest; use function Shlinkio\Shlink\Core\ipAddressFromRequest; use function Shlinkio\Shlink\Core\isCrawler; use function substr; + use const Shlinkio\Shlink\REDIRECT_URL_REQUEST_ATTRIBUTE; final readonly class Visitor diff --git a/module/Core/test/Action/PixelActionTest.php b/module/Core/test/Action/PixelActionTest.php index d6f2566a..e78df177 100644 --- a/module/Core/test/Action/PixelActionTest.php +++ b/module/Core/test/Action/PixelActionTest.php @@ -16,6 +16,8 @@ use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface; use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface; +use const Shlinkio\Shlink\REDIRECT_URL_REQUEST_ATTRIBUTE; + class PixelActionTest extends TestCase { private PixelAction $action; @@ -34,12 +36,17 @@ class PixelActionTest extends TestCase public function imageIsReturned(): void { $shortCode = 'abc123'; + $shortUrl = ShortUrl::withLongUrl('http://domain.com/foo/bar'); + $request = (new ServerRequest())->withAttribute('shortCode', $shortCode); + $this->urlResolver->expects($this->once())->method('resolveEnabledShortUrl')->with( ShortUrlIdentifier::fromShortCodeAndDomain($shortCode, ''), - )->willReturn(ShortUrl::withLongUrl('http://domain.com/foo/bar')); - $this->requestTracker->expects($this->once())->method('trackIfApplicable')->withAnyParameters(); + )->willReturn($shortUrl); + $this->requestTracker->expects($this->once())->method('trackIfApplicable')->with( + $shortUrl, + $request->withAttribute(REDIRECT_URL_REQUEST_ATTRIBUTE, null), + ); - $request = (new ServerRequest())->withAttribute('shortCode', $shortCode); $response = $this->action->process($request, $this->createMock(RequestHandlerInterface::class)); self::assertInstanceOf(PixelResponse::class, $response); diff --git a/module/Core/test/Action/RedirectActionTest.php b/module/Core/test/Action/RedirectActionTest.php index 2364371c..fa4a561d 100644 --- a/module/Core/test/Action/RedirectActionTest.php +++ b/module/Core/test/Action/RedirectActionTest.php @@ -19,6 +19,8 @@ use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface; use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface; use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface; +use const Shlinkio\Shlink\REDIRECT_URL_REQUEST_ATTRIBUTE; + class RedirectActionTest extends TestCase { private const LONG_URL = 'https://domain.com/foo/bar?some=thing'; @@ -50,16 +52,20 @@ class RedirectActionTest extends TestCase { $shortCode = 'abc123'; $shortUrl = ShortUrl::withLongUrl(self::LONG_URL); + $expectedResp = new Response\RedirectResponse(self::LONG_URL); + $request = (new ServerRequest())->withAttribute('shortCode', $shortCode); + $this->urlResolver->expects($this->once())->method('resolveEnabledShortUrl')->with( ShortUrlIdentifier::fromShortCodeAndDomain($shortCode, ''), )->willReturn($shortUrl); - $this->requestTracker->expects($this->once())->method('trackIfApplicable'); - $expectedResp = new Response\RedirectResponse(self::LONG_URL); + $this->requestTracker->expects($this->once())->method('trackIfApplicable')->with( + $shortUrl, + $request->withAttribute(REDIRECT_URL_REQUEST_ATTRIBUTE, self::LONG_URL), + ); $this->redirectRespHelper->expects($this->once())->method('buildRedirectResponse')->with( self::LONG_URL, )->willReturn($expectedResp); - $request = (new ServerRequest())->withAttribute('shortCode', $shortCode); $response = $this->action->process($request, $this->createMock(RequestHandlerInterface::class)); self::assertSame($expectedResp, $response); diff --git a/module/Core/test/ErrorHandler/NotFoundTrackerMiddlewareTest.php b/module/Core/test/ErrorHandler/NotFoundTrackerMiddlewareTest.php index 4558197b..9df12a6d 100644 --- a/module/Core/test/ErrorHandler/NotFoundTrackerMiddlewareTest.php +++ b/module/Core/test/ErrorHandler/NotFoundTrackerMiddlewareTest.php @@ -4,7 +4,9 @@ declare(strict_types=1); namespace ShlinkioTest\Shlink\Core\ErrorHandler; +use Laminas\Diactoros\Response; use Laminas\Diactoros\ServerRequestFactory; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -14,6 +16,8 @@ use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; use Shlinkio\Shlink\Core\ErrorHandler\NotFoundTrackerMiddleware; use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface; +use const Shlinkio\Shlink\REDIRECT_URL_REQUEST_ATTRIBUTE; + class NotFoundTrackerMiddlewareTest extends TestCase { private NotFoundTrackerMiddleware $middleware; @@ -33,12 +37,22 @@ class NotFoundTrackerMiddlewareTest extends TestCase ); } - #[Test] - public function delegatesIntoRequestTracker(): void + #[Test, DataProvider('provideResponses')] + public function delegatesIntoRequestTracker(Response $resp, string|null $expectedRedirectUrl): void { - $this->handler->expects($this->once())->method('handle')->with($this->request); - $this->requestTracker->expects($this->once())->method('trackNotFoundIfApplicable')->with($this->request); + $this->handler->expects($this->once())->method('handle')->with($this->request)->willReturn($resp); + $this->requestTracker->expects($this->once())->method('trackNotFoundIfApplicable')->with( + $this->request->withAttribute(REDIRECT_URL_REQUEST_ATTRIBUTE, $expectedRedirectUrl), + ); - $this->middleware->process($this->request, $this->handler); + $result = $this->middleware->process($this->request, $this->handler); + + self::assertSame($resp, $result); + } + + public static function provideResponses(): iterable + { + yield 'no location response' => [new Response(), null]; + yield 'location response' => [new Response\RedirectResponse('the_location'), 'the_location']; } } diff --git a/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php b/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php index 85168020..84ceb790 100644 --- a/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php +++ b/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php @@ -30,6 +30,8 @@ use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface; use function Laminas\Stratigility\middleware; use function str_starts_with; +use const Shlinkio\Shlink\REDIRECT_URL_REQUEST_ATTRIBUTE; + class ExtraPathRedirectMiddlewareTest extends TestCase { private MockObject & ShortUrlResolverInterface $resolver; @@ -159,7 +161,10 @@ class ExtraPathRedirectMiddlewareTest extends TestCase $this->redirectResponseHelper->expects($this->once())->method('buildRedirectResponse')->with( 'the_built_long_url', )->willReturn(new RedirectResponse('')); - $this->requestTracker->expects($this->once())->method('trackIfApplicable')->with($shortUrl, $request); + $this->requestTracker->expects($this->once())->method('trackIfApplicable')->with( + $shortUrl, + $request->withAttribute(REDIRECT_URL_REQUEST_ATTRIBUTE, 'the_built_long_url'), + ); $this->middleware($options)->process($request, $this->handler); }