VisitsTrackerTest.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. <?php
  2. declare(strict_types=1);
  3. namespace ShlinkioTest\Shlink\Core\Visit;
  4. use Doctrine\ORM\EntityManager;
  5. use PHPUnit\Framework\TestCase;
  6. use Prophecy\Argument;
  7. use Prophecy\PhpUnit\ProphecyTrait;
  8. use Prophecy\Prophecy\ObjectProphecy;
  9. use Psr\EventDispatcher\EventDispatcherInterface;
  10. use Shlinkio\Shlink\Core\Entity\ShortUrl;
  11. use Shlinkio\Shlink\Core\Entity\Visit;
  12. use Shlinkio\Shlink\Core\EventDispatcher\Event\UrlVisited;
  13. use Shlinkio\Shlink\Core\Model\Visitor;
  14. use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
  15. use Shlinkio\Shlink\Core\Visit\VisitsTracker;
  16. class VisitsTrackerTest extends TestCase
  17. {
  18. use ProphecyTrait;
  19. private VisitsTracker $visitsTracker;
  20. private ObjectProphecy $em;
  21. private ObjectProphecy $eventDispatcher;
  22. private UrlShortenerOptions $options;
  23. public function setUp(): void
  24. {
  25. $this->em = $this->prophesize(EntityManager::class);
  26. $this->eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
  27. $this->options = new UrlShortenerOptions();
  28. $this->visitsTracker = new VisitsTracker($this->em->reveal(), $this->eventDispatcher->reveal(), $this->options);
  29. }
  30. /**
  31. * @test
  32. * @dataProvider provideTrackingMethodNames
  33. */
  34. public function trackPersistsVisitAndDispatchesEvent(string $method, array $args): void
  35. {
  36. $this->em->persist(Argument::that(fn (Visit $visit) => $visit->setId('1')))->shouldBeCalledOnce();
  37. $this->em->flush()->shouldBeCalledOnce();
  38. $this->visitsTracker->{$method}(...$args);
  39. $this->eventDispatcher->dispatch(Argument::type(UrlVisited::class))->shouldHaveBeenCalled();
  40. }
  41. public function provideTrackingMethodNames(): iterable
  42. {
  43. yield 'track' => ['track', [ShortUrl::createEmpty(), Visitor::emptyInstance()]];
  44. yield 'trackInvalidShortUrlVisit' => ['trackInvalidShortUrlVisit', [Visitor::emptyInstance()]];
  45. yield 'trackBaseUrlVisit' => ['trackBaseUrlVisit', [Visitor::emptyInstance()]];
  46. yield 'trackRegularNotFoundVisit' => ['trackRegularNotFoundVisit', [Visitor::emptyInstance()]];
  47. }
  48. /**
  49. * @test
  50. * @dataProvider provideOrphanTrackingMethodNames
  51. */
  52. public function orphanVisitsAreNotTrackedWhenDisabled(string $method): void
  53. {
  54. $this->options->trackOrphanVisits = false;
  55. $this->visitsTracker->{$method}(Visitor::emptyInstance());
  56. $this->eventDispatcher->dispatch(Argument::cetera())->shouldNotHaveBeenCalled();
  57. $this->em->persist(Argument::cetera())->shouldNotHaveBeenCalled();
  58. $this->em->flush()->shouldNotHaveBeenCalled();
  59. }
  60. public function provideOrphanTrackingMethodNames(): iterable
  61. {
  62. yield 'trackInvalidShortUrlVisit' => ['trackInvalidShortUrlVisit'];
  63. yield 'trackBaseUrlVisit' => ['trackBaseUrlVisit'];
  64. yield 'trackRegularNotFoundVisit' => ['trackRegularNotFoundVisit'];
  65. }
  66. }