From 18b12ab1e6062300893e462167404a9c01b0504a Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 14 Apr 2020 20:57:25 +0200 Subject: [PATCH] Updated NotifyVisitToMercure to send both an update for all short URLs and one specific short URL --- .../EventDispatcher/NotifyVisitToMercure.php | 1 + .../src/Mercure/MercureUpdatesGenerator.php | 23 ++++++++++++++++--- .../MercureUpdatesGeneratorInterface.php | 2 ++ .../NotifyVisitToMercureTest.php | 16 +++++++++---- .../Mercure/MercureUpdatesGeneratorTest.php | 20 ++++++++++++---- 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/module/Core/src/EventDispatcher/NotifyVisitToMercure.php b/module/Core/src/EventDispatcher/NotifyVisitToMercure.php index 69527413..af6dd33f 100644 --- a/module/Core/src/EventDispatcher/NotifyVisitToMercure.php +++ b/module/Core/src/EventDispatcher/NotifyVisitToMercure.php @@ -44,6 +44,7 @@ class NotifyVisitToMercure } try { + ($this->publisher)($this->updatesGenerator->newShortUrlVisitUpdate($visit)); ($this->publisher)($this->updatesGenerator->newVisitUpdate($visit)); } catch (Throwable $e) { $this->logger->debug('Error while trying to notify mercure hub with new visit. {e}', [ diff --git a/module/Core/src/Mercure/MercureUpdatesGenerator.php b/module/Core/src/Mercure/MercureUpdatesGenerator.php index 47d4b7be..513b8e50 100644 --- a/module/Core/src/Mercure/MercureUpdatesGenerator.php +++ b/module/Core/src/Mercure/MercureUpdatesGenerator.php @@ -9,6 +9,7 @@ use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer; use Symfony\Component\Mercure\Update; use function json_encode; +use function sprintf; use const JSON_THROW_ON_ERROR; @@ -25,9 +26,25 @@ final class MercureUpdatesGenerator implements MercureUpdatesGeneratorInterface public function newVisitUpdate(Visit $visit): Update { - return new Update(self::NEW_VISIT_TOPIC, json_encode([ + return new Update(self::NEW_VISIT_TOPIC, $this->serialize([ 'shortUrl' => $this->transformer->transform($visit->getShortUrl()), - 'visit' => $visit->jsonSerialize(), - ], JSON_THROW_ON_ERROR)); + 'visit' => $visit, + ])); + } + + public function newShortUrlVisitUpdate(Visit $visit): Update + { + $shortUrl = $visit->getShortUrl(); + $topic = sprintf('%s/%s', self::NEW_VISIT_TOPIC, $shortUrl->getShortCode()); + + return new Update($topic, $this->serialize([ + 'shortUrl' => $this->transformer->transform($visit->getShortUrl()), + 'visit' => $visit, + ])); + } + + private function serialize(array $data): string + { + return json_encode($data, JSON_THROW_ON_ERROR); } } diff --git a/module/Core/src/Mercure/MercureUpdatesGeneratorInterface.php b/module/Core/src/Mercure/MercureUpdatesGeneratorInterface.php index af539803..d433d9ad 100644 --- a/module/Core/src/Mercure/MercureUpdatesGeneratorInterface.php +++ b/module/Core/src/Mercure/MercureUpdatesGeneratorInterface.php @@ -10,4 +10,6 @@ use Symfony\Component\Mercure\Update; interface MercureUpdatesGeneratorInterface { public function newVisitUpdate(Visit $visit): Update; + + public function newShortUrlVisitUpdate(Visit $visit): Update; } diff --git a/module/Core/test/EventDispatcher/NotifyVisitToMercureTest.php b/module/Core/test/EventDispatcher/NotifyVisitToMercureTest.php index 07f8bd1c..fce53344 100644 --- a/module/Core/test/EventDispatcher/NotifyVisitToMercureTest.php +++ b/module/Core/test/EventDispatcher/NotifyVisitToMercureTest.php @@ -43,7 +43,7 @@ class NotifyVisitToMercureTest extends TestCase } /** @test */ - public function notificationIsNotSentWhenVisitCannotBeFound(): void + public function notificationsAreNotSentWhenVisitCannotBeFound(): void { $visitId = '123'; $findVisit = $this->em->find(Visit::class, $visitId)->willReturn(null); @@ -52,6 +52,9 @@ class NotifyVisitToMercureTest extends TestCase ['visitId' => $visitId], ); $logDebug = $this->logger->debug(Argument::cetera()); + $buildNewShortUrlVisitUpdate = $this->updatesGenerator->newShortUrlVisitUpdate( + Argument::type(Visit::class), + )->willReturn(new Update('', '')); $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate(Argument::type(Visit::class))->willReturn( new Update('', ''), ); @@ -62,12 +65,13 @@ class NotifyVisitToMercureTest extends TestCase $findVisit->shouldHaveBeenCalledOnce(); $logWarning->shouldHaveBeenCalledOnce(); $logDebug->shouldNotHaveBeenCalled(); + $buildNewShortUrlVisitUpdate->shouldNotHaveBeenCalled(); $buildNewVisitUpdate->shouldNotHaveBeenCalled(); $publish->shouldNotHaveBeenCalled(); } /** @test */ - public function notificationIsSentWhenVisitIsFound(): void + public function notificationsAreSentWhenVisitIsFound(): void { $visitId = '123'; $visit = new Visit(new ShortUrl(''), Visitor::emptyInstance()); @@ -76,6 +80,7 @@ class NotifyVisitToMercureTest extends TestCase $findVisit = $this->em->find(Visit::class, $visitId)->willReturn($visit); $logWarning = $this->logger->warning(Argument::cetera()); $logDebug = $this->logger->debug(Argument::cetera()); + $buildNewShortUrlVisitUpdate = $this->updatesGenerator->newShortUrlVisitUpdate($visit)->willReturn($update); $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate($visit)->willReturn($update); $publish = $this->publisher->__invoke($update); @@ -84,8 +89,9 @@ class NotifyVisitToMercureTest extends TestCase $findVisit->shouldHaveBeenCalledOnce(); $logWarning->shouldNotHaveBeenCalled(); $logDebug->shouldNotHaveBeenCalled(); + $buildNewShortUrlVisitUpdate->shouldHaveBeenCalledOnce(); $buildNewVisitUpdate->shouldHaveBeenCalledOnce(); - $publish->shouldHaveBeenCalledOnce(); + $publish->shouldHaveBeenCalledTimes(2); } /** @test */ @@ -101,6 +107,7 @@ class NotifyVisitToMercureTest extends TestCase $logDebug = $this->logger->debug('Error while trying to notify mercure hub with new visit. {e}', [ 'e' => $e, ]); + $buildNewShortUrlVisitUpdate = $this->updatesGenerator->newShortUrlVisitUpdate($visit)->willReturn($update); $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate($visit)->willReturn($update); $publish = $this->publisher->__invoke($update)->willThrow($e); @@ -109,7 +116,8 @@ class NotifyVisitToMercureTest extends TestCase $findVisit->shouldHaveBeenCalledOnce(); $logWarning->shouldNotHaveBeenCalled(); $logDebug->shouldHaveBeenCalledOnce(); - $buildNewVisitUpdate->shouldHaveBeenCalledOnce(); + $buildNewShortUrlVisitUpdate->shouldHaveBeenCalledOnce(); + $buildNewVisitUpdate->shouldNotHaveBeenCalled(); $publish->shouldHaveBeenCalledOnce(); } } diff --git a/module/Core/test/Mercure/MercureUpdatesGeneratorTest.php b/module/Core/test/Mercure/MercureUpdatesGeneratorTest.php index 361d3b2f..f72cd82d 100644 --- a/module/Core/test/Mercure/MercureUpdatesGeneratorTest.php +++ b/module/Core/test/Mercure/MercureUpdatesGeneratorTest.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\Mercure\MercureUpdatesGenerator; +use Shlinkio\Shlink\Core\Model\ShortUrlMeta; use Shlinkio\Shlink\Core\Model\Visitor; use function Shlinkio\Shlink\Common\json_decode; @@ -21,15 +22,18 @@ class MercureUpdatesGeneratorTest extends TestCase $this->generator = new MercureUpdatesGenerator([]); } - /** @test */ - public function visitIsProperlySerializedIntoUpdate(): void + /** + * @test + * @dataProvider provideMethod + */ + public function visitIsProperlySerializedIntoUpdate(string $method, string $expectedTopic): void { - $shortUrl = new ShortUrl(''); + $shortUrl = new ShortUrl('', ShortUrlMeta::fromRawData(['customSlug' => 'foo'])); $visit = new Visit($shortUrl, Visitor::emptyInstance()); - $update = $this->generator->newVisitUpdate($visit); + $update = $this->generator->{$method}($visit); - $this->assertEquals(['https://shlink.io/new_visit'], $update->getTopics()); + $this->assertEquals([$expectedTopic], $update->getTopics()); $this->assertEquals([ 'shortUrl' => [ 'shortCode' => $shortUrl->getShortCode(), @@ -53,4 +57,10 @@ class MercureUpdatesGeneratorTest extends TestCase ], ], json_decode($update->getData())); } + + public function provideMethod(): iterable + { + yield 'newVisitUpdate' => ['newVisitUpdate', 'https://shlink.io/new_visit']; + yield 'newShortUrlVisitUpdate' => ['newShortUrlVisitUpdate', 'https://shlink.io/new_visit/foo']; + } }