VisitsTrackerTest.php 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. declare(strict_types=1);
  3. namespace ShlinkioTest\Shlink\Core\Service;
  4. use Doctrine\ORM\EntityManager;
  5. use Doctrine\ORM\EntityRepository;
  6. use Laminas\Stdlib\ArrayUtils;
  7. use PHPUnit\Framework\Assert;
  8. use PHPUnit\Framework\TestCase;
  9. use Prophecy\Argument;
  10. use Prophecy\Prophecy\ObjectProphecy;
  11. use Psr\EventDispatcher\EventDispatcherInterface;
  12. use Shlinkio\Shlink\Common\Util\DateRange;
  13. use Shlinkio\Shlink\Core\Entity\ShortUrl;
  14. use Shlinkio\Shlink\Core\Entity\Visit;
  15. use Shlinkio\Shlink\Core\EventDispatcher\ShortUrlVisited;
  16. use Shlinkio\Shlink\Core\Model\Visitor;
  17. use Shlinkio\Shlink\Core\Model\VisitsParams;
  18. use Shlinkio\Shlink\Core\Repository\VisitRepository;
  19. use Shlinkio\Shlink\Core\Service\VisitsTracker;
  20. class VisitsTrackerTest extends TestCase
  21. {
  22. private VisitsTracker $visitsTracker;
  23. private ObjectProphecy $em;
  24. private ObjectProphecy $eventDispatcher;
  25. public function setUp(): void
  26. {
  27. $this->em = $this->prophesize(EntityManager::class);
  28. $this->eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
  29. $this->visitsTracker = new VisitsTracker($this->em->reveal(), $this->eventDispatcher->reveal());
  30. }
  31. /** @test */
  32. public function trackPersistsVisit(): void
  33. {
  34. $shortCode = '123ABC';
  35. $repo = $this->prophesize(EntityRepository::class);
  36. $repo->findOneBy(['shortCode' => $shortCode])->willReturn(new ShortUrl(''));
  37. $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal())->shouldBeCalledOnce();
  38. $this->em->persist(Argument::that(fn (Visit $visit) => $visit->setId('1')))->shouldBeCalledOnce();
  39. $this->em->flush()->shouldBeCalledOnce();
  40. $this->visitsTracker->track($shortCode, Visitor::emptyInstance());
  41. $this->eventDispatcher->dispatch(Argument::type(ShortUrlVisited::class))->shouldHaveBeenCalled();
  42. }
  43. /** @test */
  44. public function trackedIpAddressGetsObfuscated(): void
  45. {
  46. $shortCode = '123ABC';
  47. $repo = $this->prophesize(EntityRepository::class);
  48. $repo->findOneBy(['shortCode' => $shortCode])->willReturn(new ShortUrl(''));
  49. $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal())->shouldBeCalledOnce();
  50. $this->em->persist(Argument::any())->will(function ($args) {
  51. /** @var Visit $visit */
  52. $visit = $args[0];
  53. Assert::assertEquals('4.3.2.0', $visit->getRemoteAddr());
  54. $visit->setId('1');
  55. return $visit;
  56. })->shouldBeCalledOnce();
  57. $this->em->flush()->shouldBeCalledOnce();
  58. $this->visitsTracker->track($shortCode, new Visitor('', '', '4.3.2.1'));
  59. $this->eventDispatcher->dispatch(Argument::type(ShortUrlVisited::class))->shouldHaveBeenCalled();
  60. }
  61. /** @test */
  62. public function infoReturnsVisitsForCertainShortCode(): void
  63. {
  64. $shortCode = '123ABC';
  65. $repo = $this->prophesize(EntityRepository::class);
  66. $count = $repo->count(['shortCode' => $shortCode])->willReturn(1);
  67. $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal())->shouldBeCalledOnce();
  68. $list = [
  69. new Visit(new ShortUrl(''), Visitor::emptyInstance()),
  70. new Visit(new ShortUrl(''), Visitor::emptyInstance()),
  71. ];
  72. $repo2 = $this->prophesize(VisitRepository::class);
  73. $repo2->findVisitsByShortCode($shortCode, Argument::type(DateRange::class), 1, 0)->willReturn($list);
  74. $repo2->countVisitsByShortCode($shortCode, Argument::type(DateRange::class))->willReturn(1);
  75. $this->em->getRepository(Visit::class)->willReturn($repo2->reveal())->shouldBeCalledOnce();
  76. $paginator = $this->visitsTracker->info($shortCode, new VisitsParams());
  77. $this->assertEquals($list, ArrayUtils::iteratorToArray($paginator->getCurrentItems()));
  78. $count->shouldHaveBeenCalledOnce();
  79. }
  80. }