From 5278d7668cb4bb7b0d999ed61a93f958f8289a2b Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 8 Feb 2021 22:44:58 +0100 Subject: [PATCH] Added orphan visits count to visits stats endpoint --- docs/swagger/definitions/VisitStats.json | 8 ++++++-- docs/swagger/paths/v2_visits.json | 3 ++- module/Core/src/Visit/Model/VisitsStats.php | 5 ++++- module/Core/src/Visit/VisitsStatsHelper.php | 8 ++------ module/Core/test/Visit/VisitsStatsHelperTest.php | 6 ++++-- module/Rest/test-api/Action/GlobalVisitsTest.php | 2 ++ module/Rest/test-api/Fixtures/VisitsFixture.php | 8 ++++++++ module/Rest/test/Action/Visit/GlobalVisitsActionTest.php | 2 +- 8 files changed, 29 insertions(+), 13 deletions(-) diff --git a/docs/swagger/definitions/VisitStats.json b/docs/swagger/definitions/VisitStats.json index 5f439c9b..2a97f597 100644 --- a/docs/swagger/definitions/VisitStats.json +++ b/docs/swagger/definitions/VisitStats.json @@ -1,10 +1,14 @@ { "type": "object", - "required": ["visitsCount"], + "required": ["visitsCount", "orphanVisitsCount"], "properties": { "visitsCount": { "type": "number", - "description": "The total amount of visits received." + "description": "The total amount of visits received on any short URL." + }, + "orphanVisitsCount": { + "type": "number", + "description": "The total amount of visits that could not be matched to a short URL (visits to the base URL, an invalid short URL or any other kind of 404)." } } } diff --git a/docs/swagger/paths/v2_visits.json b/docs/swagger/paths/v2_visits.json index 089223b3..3c712b1f 100644 --- a/docs/swagger/paths/v2_visits.json +++ b/docs/swagger/paths/v2_visits.json @@ -34,7 +34,8 @@ "examples": { "application/json": { "visits": { - "visitsCount": 1569874 + "visitsCount": 1569874, + "orphanVisitsCount": 71345 } } } diff --git a/module/Core/src/Visit/Model/VisitsStats.php b/module/Core/src/Visit/Model/VisitsStats.php index ac5083c7..982f03c4 100644 --- a/module/Core/src/Visit/Model/VisitsStats.php +++ b/module/Core/src/Visit/Model/VisitsStats.php @@ -9,16 +9,19 @@ use JsonSerializable; final class VisitsStats implements JsonSerializable { private int $visitsCount; + private int $orphanVisitsCount; - public function __construct(int $visitsCount) + public function __construct(int $visitsCount, int $orphanVisitsCount) { $this->visitsCount = $visitsCount; + $this->orphanVisitsCount = $orphanVisitsCount; } public function jsonSerialize(): array { return [ 'visitsCount' => $this->visitsCount, + 'orphanVisitsCount' => $this->orphanVisitsCount, ]; } } diff --git a/module/Core/src/Visit/VisitsStatsHelper.php b/module/Core/src/Visit/VisitsStatsHelper.php index 7c4efd23..0cb58897 100644 --- a/module/Core/src/Visit/VisitsStatsHelper.php +++ b/module/Core/src/Visit/VisitsStatsHelper.php @@ -32,15 +32,11 @@ class VisitsStatsHelper implements VisitsStatsHelperInterface } public function getVisitsStats(?ApiKey $apiKey = null): VisitsStats - { - return new VisitsStats($this->getVisitsCount($apiKey)); - } - - private function getVisitsCount(?ApiKey $apiKey): int { /** @var VisitRepository $visitsRepo */ $visitsRepo = $this->em->getRepository(Visit::class); - return $visitsRepo->countVisits($apiKey); + + return new VisitsStats($visitsRepo->countVisits($apiKey), $visitsRepo->countOrphanVisits()); } /** diff --git a/module/Core/test/Visit/VisitsStatsHelperTest.php b/module/Core/test/Visit/VisitsStatsHelperTest.php index 20a39316..6fefd1d0 100644 --- a/module/Core/test/Visit/VisitsStatsHelperTest.php +++ b/module/Core/test/Visit/VisitsStatsHelperTest.php @@ -51,13 +51,15 @@ class VisitsStatsHelperTest extends TestCase public function returnsExpectedVisitsStats(int $expectedCount): void { $repo = $this->prophesize(VisitRepository::class); - $count = $repo->countVisits(null)->willReturn($expectedCount); + $count = $repo->countVisits(null)->willReturn($expectedCount * 3); + $countOrphan = $repo->countOrphanVisits()->willReturn($expectedCount); $getRepo = $this->em->getRepository(Visit::class)->willReturn($repo->reveal()); $stats = $this->helper->getVisitsStats(); - self::assertEquals(new VisitsStats($expectedCount), $stats); + self::assertEquals(new VisitsStats($expectedCount * 3, $expectedCount), $stats); $count->shouldHaveBeenCalledOnce(); + $countOrphan->shouldHaveBeenCalledOnce(); $getRepo->shouldHaveBeenCalledOnce(); } diff --git a/module/Rest/test-api/Action/GlobalVisitsTest.php b/module/Rest/test-api/Action/GlobalVisitsTest.php index 99e05918..1b71f976 100644 --- a/module/Rest/test-api/Action/GlobalVisitsTest.php +++ b/module/Rest/test-api/Action/GlobalVisitsTest.php @@ -19,7 +19,9 @@ class GlobalVisitsTest extends ApiTestCase self::assertArrayHasKey('visits', $payload); self::assertArrayHasKey('visitsCount', $payload['visits']); + self::assertArrayHasKey('orphanVisitsCount', $payload['visits']); self::assertEquals($expectedVisits, $payload['visits']['visitsCount']); + self::assertEquals(3, $payload['visits']['orphanVisitsCount']); } public function provideApiKeys(): iterable diff --git a/module/Rest/test-api/Fixtures/VisitsFixture.php b/module/Rest/test-api/Fixtures/VisitsFixture.php index 1e3b3a5c..9fb53ac1 100644 --- a/module/Rest/test-api/Fixtures/VisitsFixture.php +++ b/module/Rest/test-api/Fixtures/VisitsFixture.php @@ -47,6 +47,14 @@ class VisitsFixture extends AbstractFixture implements DependentFixtureInterface Visit::forValidShortUrl($ghiShortUrl, new Visitor('shlink-tests-agent', 'https://app.shlink.io', '', '')), ); + $manager->persist(Visit::forBasePath(new Visitor('shlink-tests-agent', 'https://doma.in', '1.2.3.4', ''))); + $manager->persist( + Visit::forRegularNotFound(new Visitor('shlink-tests-agent', 'https://doma.in/foo/bar', '1.2.3.4', '')), + ); + $manager->persist( + Visit::forInvalidShortUrl(new Visitor('shlink-tests-agent', 'https://doma.in/foo', '1.2.3.4', '')), + ); + $manager->flush(); } } diff --git a/module/Rest/test/Action/Visit/GlobalVisitsActionTest.php b/module/Rest/test/Action/Visit/GlobalVisitsActionTest.php index 6e3ab1e4..d53cb20d 100644 --- a/module/Rest/test/Action/Visit/GlobalVisitsActionTest.php +++ b/module/Rest/test/Action/Visit/GlobalVisitsActionTest.php @@ -31,7 +31,7 @@ class GlobalVisitsActionTest extends TestCase public function statsAreReturnedFromHelper(): void { $apiKey = new ApiKey(); - $stats = new VisitsStats(5); + $stats = new VisitsStats(5, 3); $getStats = $this->helper->getVisitsStats($apiKey)->willReturn($stats); /** @var JsonResponse $resp */