diff --git a/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerDelegatorTest.php b/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerDelegatorTest.php index b826802b..7123aa29 100644 --- a/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerDelegatorTest.php +++ b/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerDelegatorTest.php @@ -4,23 +4,20 @@ declare(strict_types=1); namespace ShlinkioTest\Shlink\Core\EventDispatcher; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Psr\Container\ContainerInterface; use Shlinkio\Shlink\Common\Doctrine\ReopeningEntityManagerInterface; use Shlinkio\Shlink\Core\EventDispatcher\CloseDbConnectionEventListenerDelegator; class CloseDbConnectionEventListenerDelegatorTest extends TestCase { - use ProphecyTrait; - private CloseDbConnectionEventListenerDelegator $delegator; - private ObjectProphecy $container; + private MockObject $container; protected function setUp(): void { - $this->container = $this->prophesize(ContainerInterface::class); + $this->container = $this->createMock(ContainerInterface::class); $this->delegator = new CloseDbConnectionEventListenerDelegator(); } @@ -35,12 +32,12 @@ class CloseDbConnectionEventListenerDelegatorTest extends TestCase }; }; - $em = $this->prophesize(ReopeningEntityManagerInterface::class); - $getEm = $this->container->get('em')->willReturn($em->reveal()); + $this->container->expects($this->once())->method('get')->with($this->equalTo('em'))->willReturn( + $this->createMock(ReopeningEntityManagerInterface::class), + ); - ($this->delegator)($this->container->reveal(), '', $callback); + ($this->delegator)($this->container, '', $callback); self::assertTrue($callbackInvoked); - $getEm->shouldHaveBeenCalledOnce(); } } diff --git a/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerTest.php b/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerTest.php index 7c4d74c8..76b433e1 100644 --- a/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerTest.php +++ b/module/Core/test/EventDispatcher/CloseDbConnectionEventListenerTest.php @@ -5,9 +5,8 @@ declare(strict_types=1); namespace ShlinkioTest\Shlink\Core\EventDispatcher; use Doctrine\DBAL\Connection; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use RuntimeException; use Shlinkio\Shlink\Common\Doctrine\ReopeningEntityManagerInterface; use Shlinkio\Shlink\Core\EventDispatcher\CloseDbConnectionEventListener; @@ -16,13 +15,11 @@ use Throwable; class CloseDbConnectionEventListenerTest extends TestCase { - use ProphecyTrait; - - private ObjectProphecy $em; + private MockObject $em; protected function setUp(): void { - $this->em = $this->prophesize(ReopeningEntityManagerInterface::class); + $this->em = $this->createMock(ReopeningEntityManagerInterface::class); } /** @@ -31,16 +28,14 @@ class CloseDbConnectionEventListenerTest extends TestCase */ public function connectionIsOpenedBeforeAndClosedAfter(callable $wrapped, bool &$wrappedWasCalled): void { - $conn = $this->prophesize(Connection::class); - $close = $conn->close()->will(function (): void { - }); - $getConn = $this->em->getConnection()->willReturn($conn->reveal()); - $close = $this->em->close()->will(function (): void { - }); - $open = $this->em->open()->will(function (): void { - }); + $conn = $this->createMock(Connection::class); + $conn->expects($this->once())->method('close'); - $eventListener = new CloseDbConnectionEventListener($this->em->reveal(), $wrapped); + $this->em->expects($this->once())->method('getConnection')->willReturn($conn); + $this->em->expects($this->once())->method('close'); + $this->em->expects($this->once())->method('open'); + + $eventListener = new CloseDbConnectionEventListener($this->em, $wrapped); try { ($eventListener)(new stdClass()); @@ -49,25 +44,21 @@ class CloseDbConnectionEventListenerTest extends TestCase } self::assertTrue($wrappedWasCalled); - $close->shouldHaveBeenCalledOnce(); - $getConn->shouldHaveBeenCalledOnce(); - $close->shouldHaveBeenCalledOnce(); - $open->shouldHaveBeenCalledOnce(); } public function provideWrapped(): iterable { - yield 'does not throw exception' => (function (): array { + yield 'does not throw exception' => (static function (): array { $wrappedWasCalled = false; - $wrapped = function () use (&$wrappedWasCalled): void { + $wrapped = static function () use (&$wrappedWasCalled): void { $wrappedWasCalled = true; }; return [$wrapped, &$wrappedWasCalled]; })(); - yield 'throws exception' => (function (): array { + yield 'throws exception' => (static function (): array { $wrappedWasCalled = false; - $wrapped = function () use (&$wrappedWasCalled): void { + $wrapped = static function () use (&$wrappedWasCalled): void { $wrappedWasCalled = true; throw new RuntimeException('Some error'); }; diff --git a/module/Core/test/EventDispatcher/LocateUnlocatedVisitsTest.php b/module/Core/test/EventDispatcher/LocateUnlocatedVisitsTest.php index 5eb97592..b3063374 100644 --- a/module/Core/test/EventDispatcher/LocateUnlocatedVisitsTest.php +++ b/module/Core/test/EventDispatcher/LocateUnlocatedVisitsTest.php @@ -4,9 +4,8 @@ declare(strict_types=1); namespace ShlinkioTest\Shlink\Core\EventDispatcher; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Shlinkio\Shlink\Core\EventDispatcher\Event\GeoLiteDbCreated; use Shlinkio\Shlink\Core\EventDispatcher\LocateUnlocatedVisits; use Shlinkio\Shlink\Core\Visit\Entity\Visit; @@ -17,25 +16,23 @@ use Shlinkio\Shlink\IpGeolocation\Model\Location; class LocateUnlocatedVisitsTest extends TestCase { - use ProphecyTrait; - private LocateUnlocatedVisits $listener; - private ObjectProphecy $locator; - private ObjectProphecy $visitToLocation; + private MockObject $locator; + private MockObject $visitToLocation; protected function setUp(): void { - $this->locator = $this->prophesize(VisitLocatorInterface::class); - $this->visitToLocation = $this->prophesize(VisitToLocationHelperInterface::class); + $this->locator = $this->createMock(VisitLocatorInterface::class); + $this->visitToLocation = $this->createMock(VisitToLocationHelperInterface::class); - $this->listener = new LocateUnlocatedVisits($this->locator->reveal(), $this->visitToLocation->reveal()); + $this->listener = new LocateUnlocatedVisits($this->locator, $this->visitToLocation); } /** @test */ public function locatorIsCalledWhenInvoked(): void { + $this->locator->expects($this->once())->method('locateUnlocatedVisits')->with($this->equalTo($this->listener)); ($this->listener)(new GeoLiteDbCreated()); - $this->locator->locateUnlocatedVisits($this->listener)->shouldHaveBeenCalledOnce(); } /** @test */ @@ -44,11 +41,12 @@ class LocateUnlocatedVisitsTest extends TestCase $visit = Visit::forBasePath(Visitor::emptyInstance()); $location = Location::emptyInstance(); - $resolve = $this->visitToLocation->resolveVisitLocation($visit)->willReturn($location); + $this->visitToLocation->expects($this->once())->method('resolveVisitLocation')->with( + $this->equalTo($visit), + )->willReturn($location); $result = $this->listener->geolocateVisit($visit); self::assertSame($location, $result); - $resolve->shouldHaveBeenCalledOnce(); } } diff --git a/module/Core/test/EventDispatcher/LocateVisitTest.php b/module/Core/test/EventDispatcher/LocateVisitTest.php index 068df028..b90b5b7f 100644 --- a/module/Core/test/EventDispatcher/LocateVisitTest.php +++ b/module/Core/test/EventDispatcher/LocateVisitTest.php @@ -6,10 +6,8 @@ namespace ShlinkioTest\Shlink\Core\EventDispatcher; use Doctrine\ORM\EntityManagerInterface; use OutOfRangeException; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Common\Util\IpAddress; @@ -27,31 +25,27 @@ use Shlinkio\Shlink\IpGeolocation\Resolver\IpLocationResolverInterface; class LocateVisitTest extends TestCase { - use ProphecyTrait; - private LocateVisit $locateVisit; - private ObjectProphecy $ipLocationResolver; - private ObjectProphecy $em; - private ObjectProphecy $logger; - private ObjectProphecy $dbUpdater; - private ObjectProphecy $eventDispatcher; + private MockObject $ipLocationResolver; + private MockObject $em; + private MockObject $logger; + private MockObject $eventDispatcher; + private MockObject $dbUpdater; protected function setUp(): void { - $this->ipLocationResolver = $this->prophesize(IpLocationResolverInterface::class); - $this->em = $this->prophesize(EntityManagerInterface::class); - $this->logger = $this->prophesize(LoggerInterface::class); - $this->eventDispatcher = $this->prophesize(EventDispatcherInterface::class); - - $this->dbUpdater = $this->prophesize(DbUpdaterInterface::class); - $this->dbUpdater->databaseFileExists()->willReturn(true); + $this->ipLocationResolver = $this->createMock(IpLocationResolverInterface::class); + $this->em = $this->createMock(EntityManagerInterface::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class); + $this->dbUpdater = $this->createMock(DbUpdaterInterface::class); $this->locateVisit = new LocateVisit( - $this->ipLocationResolver->reveal(), - $this->em->reveal(), - $this->logger->reveal(), - $this->dbUpdater->reveal(), - $this->eventDispatcher->reveal(), + $this->ipLocationResolver, + $this->em, + $this->logger, + $this->dbUpdater, + $this->eventDispatcher, ); } @@ -59,97 +53,91 @@ class LocateVisitTest extends TestCase public function invalidVisitLogsWarning(): void { $event = new UrlVisited('123'); - $findVisit = $this->em->find(Visit::class, '123')->willReturn(null); - $logWarning = $this->logger->warning('Tried to locate visit with id "{visitId}", but it does not exist.', [ - 'visitId' => 123, - ]); - $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void { - }); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo('123'), + )->willReturn(null); + $this->em->expects($this->never())->method('flush'); + $this->logger->expects($this->once())->method('warning')->with( + $this->equalTo('Tried to locate visit with id "{visitId}", but it does not exist.'), + $this->equalTo(['visitId' => 123]), + ); + $this->eventDispatcher->expects($this->never())->method('dispatch')->with( + $this->equalTo(new VisitLocated('123')), + ); + $this->ipLocationResolver->expects($this->never())->method('resolveIpLocation'); ($this->locateVisit)($event); - - $findVisit->shouldHaveBeenCalledOnce(); - $this->em->flush()->shouldNotHaveBeenCalled(); - $this->ipLocationResolver->resolveIpLocation(Argument::cetera())->shouldNotHaveBeenCalled(); - $logWarning->shouldHaveBeenCalled(); - $dispatch->shouldNotHaveBeenCalled(); } /** @test */ public function nonExistingGeoLiteDbLogsWarning(): void { $event = new UrlVisited('123'); - $findVisit = $this->em->find(Visit::class, '123')->willReturn( - Visit::forValidShortUrl(ShortUrl::createEmpty(), new Visitor('', '', '1.2.3.4', '')), + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo('123'), + )->willReturn(Visit::forValidShortUrl(ShortUrl::createEmpty(), new Visitor('', '', '1.2.3.4', ''))); + $this->em->expects($this->never())->method('flush'); + $this->dbUpdater->expects($this->once())->method('databaseFileExists')->withAnyParameters()->willReturn(false); + $this->logger->expects($this->once())->method('warning')->with( + $this->equalTo('Tried to locate visit with id "{visitId}", but a GeoLite2 db was not found.'), + $this->equalTo(['visitId' => 123]), ); - $dbExists = $this->dbUpdater->databaseFileExists()->willReturn(false); - $logWarning = $this->logger->warning( - 'Tried to locate visit with id "{visitId}", but a GeoLite2 db was not found.', - ['visitId' => 123], + $this->eventDispatcher->expects($this->once())->method('dispatch')->with( + $this->equalTo(new VisitLocated('123')), ); - $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void { - }); + $this->ipLocationResolver->expects($this->never())->method('resolveIpLocation'); ($this->locateVisit)($event); - - $findVisit->shouldHaveBeenCalledOnce(); - $dbExists->shouldHaveBeenCalledOnce(); - $this->em->flush()->shouldNotHaveBeenCalled(); - $this->ipLocationResolver->resolveIpLocation(Argument::cetera())->shouldNotHaveBeenCalled(); - $logWarning->shouldHaveBeenCalled(); - $dispatch->shouldHaveBeenCalledOnce(); } /** @test */ public function invalidAddressLogsWarning(): void { $event = new UrlVisited('123'); - $findVisit = $this->em->find(Visit::class, '123')->willReturn( - Visit::forValidShortUrl(ShortUrl::createEmpty(), new Visitor('', '', '1.2.3.4', '')), + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo('123'), + )->willReturn(Visit::forValidShortUrl(ShortUrl::createEmpty(), new Visitor('', '', '1.2.3.4', ''))); + $this->em->expects($this->never())->method('flush'); + $this->dbUpdater->expects($this->once())->method('databaseFileExists')->withAnyParameters()->willReturn(true); + $this->ipLocationResolver->expects( + $this->once(), + )->method('resolveIpLocation')->withAnyParameters()->willThrowException(WrongIpException::fromIpAddress('')); + $this->logger->expects($this->once())->method('warning')->with( + $this->equalTo('Tried to locate visit with id "{visitId}", but its address seems to be wrong. {e}'), + $this->isType('array'), ); - $resolveLocation = $this->ipLocationResolver->resolveIpLocation(Argument::cetera())->willThrow( - WrongIpException::class, + $this->eventDispatcher->expects($this->once())->method('dispatch')->with( + $this->equalTo(new VisitLocated('123')), ); - $logWarning = $this->logger->warning( - 'Tried to locate visit with id "{visitId}", but its address seems to be wrong. {e}', - Argument::type('array'), - ); - $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void { - }); ($this->locateVisit)($event); - - $findVisit->shouldHaveBeenCalledOnce(); - $resolveLocation->shouldHaveBeenCalledOnce(); - $logWarning->shouldHaveBeenCalled(); - $this->em->flush()->shouldNotHaveBeenCalled(); - $dispatch->shouldHaveBeenCalledOnce(); } /** @test */ public function unhandledExceptionLogsError(): void { $event = new UrlVisited('123'); - $findVisit = $this->em->find(Visit::class, '123')->willReturn( - Visit::forValidShortUrl(ShortUrl::createEmpty(), new Visitor('', '', '1.2.3.4', '')), + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo('123'), + )->willReturn(Visit::forValidShortUrl(ShortUrl::createEmpty(), new Visitor('', '', '1.2.3.4', ''))); + $this->em->expects($this->never())->method('flush'); + $this->dbUpdater->expects($this->once())->method('databaseFileExists')->withAnyParameters()->willReturn(true); + $this->ipLocationResolver->expects( + $this->once(), + )->method('resolveIpLocation')->withAnyParameters()->willThrowException(new OutOfRangeException()); + $this->logger->expects($this->once())->method('error')->with( + $this->equalTo('An unexpected error occurred while trying to locate visit with id "{visitId}". {e}'), + $this->isType('array'), ); - $resolveLocation = $this->ipLocationResolver->resolveIpLocation(Argument::cetera())->willThrow( - OutOfRangeException::class, + $this->eventDispatcher->expects($this->once())->method('dispatch')->with( + $this->equalTo(new VisitLocated('123')), ); - $logError = $this->logger->error( - 'An unexpected error occurred while trying to locate visit with id "{visitId}". {e}', - Argument::type('array'), - ); - $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void { - }); ($this->locateVisit)($event); - - $findVisit->shouldHaveBeenCalledOnce(); - $resolveLocation->shouldHaveBeenCalledOnce(); - $logError->shouldHaveBeenCalled(); - $this->em->flush()->shouldNotHaveBeenCalled(); - $dispatch->shouldHaveBeenCalledOnce(); } /** @@ -159,21 +147,22 @@ class LocateVisitTest extends TestCase public function nonLocatableVisitsResolveToEmptyLocations(Visit $visit): void { $event = new UrlVisited('123'); - $findVisit = $this->em->find(Visit::class, '123')->willReturn($visit); - $flush = $this->em->flush()->will(function (): void { - }); - $resolveIp = $this->ipLocationResolver->resolveIpLocation(Argument::any()); - $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void { - }); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo('123'), + )->willReturn($visit); + $this->em->expects($this->once())->method('flush'); + $this->dbUpdater->expects($this->once())->method('databaseFileExists')->withAnyParameters()->willReturn(true); + $this->ipLocationResolver->expects($this->never())->method('resolveIpLocation'); + + $this->eventDispatcher->expects($this->once())->method('dispatch')->with( + $this->equalTo(new VisitLocated('123')), + ); + $this->logger->expects($this->never())->method('warning'); ($this->locateVisit)($event); self::assertEquals($visit->getVisitLocation(), VisitLocation::fromGeolocation(Location::emptyInstance())); - $findVisit->shouldHaveBeenCalledOnce(); - $flush->shouldHaveBeenCalledOnce(); - $resolveIp->shouldNotHaveBeenCalled(); - $this->logger->warning(Argument::cetera())->shouldNotHaveBeenCalled(); - $dispatch->shouldHaveBeenCalledOnce(); } public function provideNonLocatableVisits(): iterable @@ -195,21 +184,24 @@ class LocateVisitTest extends TestCase $location = new Location('', '', '', '', 0.0, 0.0, ''); $event = UrlVisited::withOriginalIpAddress('123', $originalIpAddress); - $findVisit = $this->em->find(Visit::class, '123')->willReturn($visit); - $flush = $this->em->flush()->will(function (): void { - }); - $resolveIp = $this->ipLocationResolver->resolveIpLocation($ipAddr)->willReturn($location); - $dispatch = $this->eventDispatcher->dispatch(new VisitLocated('123'))->will(function (): void { - }); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo('123'), + )->willReturn($visit); + $this->em->expects($this->once())->method('flush'); + $this->dbUpdater->expects($this->once())->method('databaseFileExists')->withAnyParameters()->willReturn(true); + $this->ipLocationResolver->expects($this->once())->method('resolveIpLocation')->with( + $this->equalTo($ipAddr), + )->willReturn($location); + + $this->eventDispatcher->expects($this->once())->method('dispatch')->with( + $this->equalTo(new VisitLocated('123')), + ); + $this->logger->expects($this->never())->method('warning'); ($this->locateVisit)($event); self::assertEquals($visit->getVisitLocation(), VisitLocation::fromGeolocation($location)); - $findVisit->shouldHaveBeenCalledOnce(); - $flush->shouldHaveBeenCalledOnce(); - $resolveIp->shouldHaveBeenCalledOnce(); - $this->logger->warning(Argument::cetera())->shouldNotHaveBeenCalled(); - $dispatch->shouldHaveBeenCalledOnce(); } public function provideIpAddresses(): iterable diff --git a/module/Core/test/EventDispatcher/Mercure/NotifyNewShortUrlToMercureTest.php b/module/Core/test/EventDispatcher/Mercure/NotifyNewShortUrlToMercureTest.php index 8e15a3e0..6ae76f8c 100644 --- a/module/Core/test/EventDispatcher/Mercure/NotifyNewShortUrlToMercureTest.php +++ b/module/Core/test/EventDispatcher/Mercure/NotifyNewShortUrlToMercureTest.php @@ -6,10 +6,8 @@ namespace ShlinkioTest\Shlink\Core\EventDispatcher\Mercure; use Doctrine\ORM\EntityManagerInterface; use Exception; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface; use Shlinkio\Shlink\Common\UpdatePublishing\Update; @@ -20,44 +18,43 @@ use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; class NotifyNewShortUrlToMercureTest extends TestCase { - use ProphecyTrait; - private NotifyNewShortUrlToMercure $listener; - private ObjectProphecy $helper; - private ObjectProphecy $updatesGenerator; - private ObjectProphecy $em; - private ObjectProphecy $logger; + private MockObject $helper; + private MockObject $updatesGenerator; + private MockObject $em; + private MockObject $logger; protected function setUp(): void { - $this->helper = $this->prophesize(PublishingHelperInterface::class); - $this->updatesGenerator = $this->prophesize(PublishingUpdatesGeneratorInterface::class); - $this->em = $this->prophesize(EntityManagerInterface::class); - $this->logger = $this->prophesize(LoggerInterface::class); + $this->helper = $this->createMock(PublishingHelperInterface::class); + $this->updatesGenerator = $this->createMock(PublishingUpdatesGeneratorInterface::class); + $this->em = $this->createMock(EntityManagerInterface::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->listener = new NotifyNewShortUrlToMercure( - $this->helper->reveal(), - $this->updatesGenerator->reveal(), - $this->em->reveal(), - $this->logger->reveal(), + $this->helper, + $this->updatesGenerator, + $this->em, + $this->logger, ); } /** @test */ public function messageIsLoggedWhenShortUrlIsNotFound(): void { - $find = $this->em->find(ShortUrl::class, '123')->willReturn(null); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(ShortUrl::class), + $this->equalTo('123'), + )->willReturn(null); + $this->helper->expects($this->never())->method('publishUpdate'); + $this->updatesGenerator->expects($this->never())->method('newShortUrlUpdate'); + $this->logger->expects($this->once())->method('warning')->with( + $this->equalTo('Tried to notify {name} for new short URL with id "{shortUrlId}", but it does not exist.'), + $this->equalTo(['shortUrlId' => '123', 'name' => 'Mercure']), + ); + $this->logger->expects($this->never())->method('debug'); ($this->listener)(new ShortUrlCreated('123')); - - $find->shouldHaveBeenCalledOnce(); - $this->logger->warning( - 'Tried to notify {name} for new short URL with id "{shortUrlId}", but it does not exist.', - ['shortUrlId' => '123', 'name' => 'Mercure'], - )->shouldHaveBeenCalledOnce(); - $this->helper->publishUpdate(Argument::cetera())->shouldNotHaveBeenCalled(); - $this->updatesGenerator->newShortUrlUpdate(Argument::cetera())->shouldNotHaveBeenCalled(); - $this->logger->debug(Argument::cetera())->shouldNotHaveBeenCalled(); } /** @test */ @@ -66,16 +63,18 @@ class NotifyNewShortUrlToMercureTest extends TestCase $shortUrl = ShortUrl::withLongUrl(''); $update = Update::forTopicAndPayload('', []); - $find = $this->em->find(ShortUrl::class, '123')->willReturn($shortUrl); - $newUpdate = $this->updatesGenerator->newShortUrlUpdate($shortUrl)->willReturn($update); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(ShortUrl::class), + $this->equalTo('123'), + )->willReturn($shortUrl); + $this->updatesGenerator->expects($this->once())->method('newShortUrlUpdate')->with( + $this->equalTo($shortUrl), + )->willReturn($update); + $this->helper->expects($this->once())->method('publishUpdate')->with($this->equalTo($update)); + $this->logger->expects($this->never())->method('warning'); + $this->logger->expects($this->never())->method('debug'); ($this->listener)(new ShortUrlCreated('123')); - - $find->shouldHaveBeenCalledOnce(); - $newUpdate->shouldHaveBeenCalledOnce(); - $this->helper->publishUpdate($update)->shouldHaveBeenCalledOnce(); - $this->logger->warning(Argument::cetera())->shouldNotHaveBeenCalled(); - $this->logger->debug(Argument::cetera())->shouldNotHaveBeenCalled(); } /** @test */ @@ -85,19 +84,22 @@ class NotifyNewShortUrlToMercureTest extends TestCase $update = Update::forTopicAndPayload('', []); $e = new Exception('Error'); - $find = $this->em->find(ShortUrl::class, '123')->willReturn($shortUrl); - $newUpdate = $this->updatesGenerator->newShortUrlUpdate($shortUrl)->willReturn($update); - $publish = $this->helper->publishUpdate($update)->willThrow($e); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(ShortUrl::class), + $this->equalTo('123'), + )->willReturn($shortUrl); + $this->updatesGenerator->expects($this->once())->method('newShortUrlUpdate')->with( + $this->equalTo($shortUrl), + )->willReturn($update); + $this->helper->expects($this->once())->method('publishUpdate')->with( + $this->equalTo($update), + )->willThrowException($e); + $this->logger->expects($this->never())->method('warning'); + $this->logger->expects($this->once())->method('debug')->with( + $this->equalTo('Error while trying to notify {name} with new short URL. {e}'), + $this->equalTo(['e' => $e, 'name' => 'Mercure']), + ); ($this->listener)(new ShortUrlCreated('123')); - - $find->shouldHaveBeenCalledOnce(); - $newUpdate->shouldHaveBeenCalledOnce(); - $publish->shouldHaveBeenCalledOnce(); - $this->logger->warning(Argument::cetera())->shouldNotHaveBeenCalled(); - $this->logger->debug( - 'Error while trying to notify {name} with new short URL. {e}', - ['e' => $e, 'name' => 'Mercure'], - )->shouldHaveBeenCalledOnce(); } } diff --git a/module/Core/test/EventDispatcher/Mercure/NotifyVisitToMercureTest.php b/module/Core/test/EventDispatcher/Mercure/NotifyVisitToMercureTest.php index 726e272c..193adac3 100644 --- a/module/Core/test/EventDispatcher/Mercure/NotifyVisitToMercureTest.php +++ b/module/Core/test/EventDispatcher/Mercure/NotifyVisitToMercureTest.php @@ -5,10 +5,8 @@ declare(strict_types=1); namespace ShlinkioTest\Shlink\Core\EventDispatcher\Mercure; use Doctrine\ORM\EntityManagerInterface; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Psr\Log\LoggerInterface; use RuntimeException; use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface; @@ -23,55 +21,41 @@ use Shlinkio\Shlink\Core\Visit\Model\VisitType; class NotifyVisitToMercureTest extends TestCase { - use ProphecyTrait; - private NotifyVisitToMercure $listener; - private ObjectProphecy $helper; - private ObjectProphecy $updatesGenerator; - private ObjectProphecy $em; - private ObjectProphecy $logger; + private MockObject $helper; + private MockObject $updatesGenerator; + private MockObject $em; + private MockObject $logger; protected function setUp(): void { - $this->helper = $this->prophesize(PublishingHelperInterface::class); - $this->updatesGenerator = $this->prophesize(PublishingUpdatesGeneratorInterface::class); - $this->em = $this->prophesize(EntityManagerInterface::class); - $this->logger = $this->prophesize(LoggerInterface::class); + $this->helper = $this->createMock(PublishingHelperInterface::class); + $this->updatesGenerator = $this->createMock(PublishingUpdatesGeneratorInterface::class); + $this->em = $this->createMock(EntityManagerInterface::class); + $this->logger = $this->createMock(LoggerInterface::class); - $this->listener = new NotifyVisitToMercure( - $this->helper->reveal(), - $this->updatesGenerator->reveal(), - $this->em->reveal(), - $this->logger->reveal(), - ); + $this->listener = new NotifyVisitToMercure($this->helper, $this->updatesGenerator, $this->em, $this->logger); } /** @test */ public function notificationsAreNotSentWhenVisitCannotBeFound(): void { $visitId = '123'; - $findVisit = $this->em->find(Visit::class, $visitId)->willReturn(null); - $logWarning = $this->logger->warning( - 'Tried to notify {name} for visit with id "{visitId}", but it does not exist.', - ['visitId' => $visitId, 'name' => 'Mercure'], + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo($visitId), + )->willReturn(null); + $this->logger->expects($this->once())->method('warning')->with( + $this->equalTo('Tried to notify {name} for visit with id "{visitId}", but it does not exist.'), + $this->equalTo(['visitId' => $visitId, 'name' => 'Mercure']), ); - $logDebug = $this->logger->debug(Argument::cetera()); - $buildNewShortUrlVisitUpdate = $this->updatesGenerator->newShortUrlVisitUpdate( - Argument::type(Visit::class), - ); - $buildNewOrphanVisitUpdate = $this->updatesGenerator->newOrphanVisitUpdate(Argument::type(Visit::class)); - $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate(Argument::type(Visit::class)); - $publish = $this->helper->publishUpdate(Argument::type(Update::class)); + $this->logger->expects($this->never())->method('debug'); + $this->updatesGenerator->expects($this->never())->method('newShortUrlVisitUpdate'); + $this->updatesGenerator->expects($this->never())->method('newOrphanVisitUpdate'); + $this->updatesGenerator->expects($this->never())->method('newVisitUpdate'); + $this->helper->expects($this->never())->method('publishUpdate'); ($this->listener)(new VisitLocated($visitId)); - - $findVisit->shouldHaveBeenCalledOnce(); - $logWarning->shouldHaveBeenCalledOnce(); - $logDebug->shouldNotHaveBeenCalled(); - $buildNewShortUrlVisitUpdate->shouldNotHaveBeenCalled(); - $buildNewVisitUpdate->shouldNotHaveBeenCalled(); - $buildNewOrphanVisitUpdate->shouldNotHaveBeenCalled(); - $publish->shouldNotHaveBeenCalled(); } /** @test */ @@ -81,23 +65,22 @@ class NotifyVisitToMercureTest extends TestCase $visit = Visit::forValidShortUrl(ShortUrl::createEmpty(), Visitor::emptyInstance()); $update = Update::forTopicAndPayload('', []); - $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); - $buildNewOrphanVisitUpdate = $this->updatesGenerator->newOrphanVisitUpdate($visit)->willReturn($update); - $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate($visit)->willReturn($update); - $publish = $this->helper->publishUpdate($update); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo($visitId), + )->willReturn($visit); + $this->logger->expects($this->never())->method('warning'); + $this->logger->expects($this->never())->method('debug'); + $this->updatesGenerator->expects($this->once())->method('newShortUrlVisitUpdate')->with( + $this->equalTo($visit), + )->willReturn($update); + $this->updatesGenerator->expects($this->never())->method('newOrphanVisitUpdate'); + $this->updatesGenerator->expects($this->once())->method('newVisitUpdate')->with( + $this->equalTo($visit), + )->willReturn($update); + $this->helper->expects($this->exactly(2))->method('publishUpdate')->with($this->equalTo($update)); ($this->listener)(new VisitLocated($visitId)); - - $findVisit->shouldHaveBeenCalledOnce(); - $logWarning->shouldNotHaveBeenCalled(); - $logDebug->shouldNotHaveBeenCalled(); - $buildNewShortUrlVisitUpdate->shouldHaveBeenCalledOnce(); - $buildNewVisitUpdate->shouldHaveBeenCalledOnce(); - $buildNewOrphanVisitUpdate->shouldNotHaveBeenCalled(); - $publish->shouldHaveBeenCalledTimes(2); } /** @test */ @@ -108,26 +91,27 @@ class NotifyVisitToMercureTest extends TestCase $update = Update::forTopicAndPayload('', []); $e = new RuntimeException('Error'); - $findVisit = $this->em->find(Visit::class, $visitId)->willReturn($visit); - $logWarning = $this->logger->warning(Argument::cetera()); - $logDebug = $this->logger->debug('Error while trying to notify {name} with new visit. {e}', [ - 'e' => $e, - 'name' => 'Mercure', - ]); - $buildNewShortUrlVisitUpdate = $this->updatesGenerator->newShortUrlVisitUpdate($visit)->willReturn($update); - $buildNewOrphanVisitUpdate = $this->updatesGenerator->newOrphanVisitUpdate($visit)->willReturn($update); - $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate($visit)->willReturn($update); - $publish = $this->helper->publishUpdate($update)->willThrow($e); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo($visitId), + )->willReturn($visit); + $this->logger->expects($this->never())->method('warning'); + $this->logger->expects($this->once())->method('debug')->with( + $this->equalTo('Error while trying to notify {name} with new visit. {e}'), + $this->equalTo(['e' => $e, 'name' => 'Mercure']), + ); + $this->updatesGenerator->expects($this->once())->method('newShortUrlVisitUpdate')->with( + $this->equalTo($visit), + )->willReturn($update); + $this->updatesGenerator->expects($this->never())->method('newOrphanVisitUpdate'); + $this->updatesGenerator->expects($this->once())->method('newVisitUpdate')->with( + $this->equalTo($visit), + )->willReturn($update); + $this->helper->expects($this->once())->method('publishUpdate')->with( + $this->equalTo($update), + )->willThrowException($e); ($this->listener)(new VisitLocated($visitId)); - - $findVisit->shouldHaveBeenCalledOnce(); - $logWarning->shouldNotHaveBeenCalled(); - $logDebug->shouldHaveBeenCalledOnce(); - $buildNewShortUrlVisitUpdate->shouldHaveBeenCalledOnce(); - $buildNewVisitUpdate->shouldHaveBeenCalledOnce(); - $buildNewOrphanVisitUpdate->shouldNotHaveBeenCalled(); - $publish->shouldHaveBeenCalledOnce(); } /** @@ -139,23 +123,20 @@ class NotifyVisitToMercureTest extends TestCase $visitId = '123'; $update = Update::forTopicAndPayload('', []); - $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); - $buildNewOrphanVisitUpdate = $this->updatesGenerator->newOrphanVisitUpdate($visit)->willReturn($update); - $buildNewVisitUpdate = $this->updatesGenerator->newVisitUpdate($visit)->willReturn($update); - $publish = $this->helper->publishUpdate($update); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo($visitId), + )->willReturn($visit); + $this->logger->expects($this->never())->method('warning'); + $this->logger->expects($this->never())->method('debug'); + $this->updatesGenerator->expects($this->never())->method('newShortUrlVisitUpdate'); + $this->updatesGenerator->expects($this->once())->method('newOrphanVisitUpdate')->with( + $this->equalTo($visit), + )->willReturn($update); + $this->updatesGenerator->expects($this->never())->method('newVisitUpdate'); + $this->helper->expects($this->once())->method('publishUpdate')->with($this->equalTo($update)); ($this->listener)(new VisitLocated($visitId)); - - $findVisit->shouldHaveBeenCalledOnce(); - $logWarning->shouldNotHaveBeenCalled(); - $logDebug->shouldNotHaveBeenCalled(); - $buildNewShortUrlVisitUpdate->shouldNotHaveBeenCalled(); - $buildNewVisitUpdate->shouldNotHaveBeenCalled(); - $buildNewOrphanVisitUpdate->shouldHaveBeenCalledOnce(); - $publish->shouldHaveBeenCalledOnce(); } public function provideOrphanVisits(): iterable diff --git a/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php b/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php index 2751dbfd..5148748a 100644 --- a/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php +++ b/module/Core/test/EventDispatcher/NotifyVisitToWebHooksTest.php @@ -12,10 +12,8 @@ use GuzzleHttp\Promise\FulfilledPromise; use GuzzleHttp\Promise\RejectedPromise; use GuzzleHttp\RequestOptions; use PHPUnit\Framework\Assert; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated; use Shlinkio\Shlink\Core\EventDispatcher\NotifyVisitToWebHooks; @@ -32,66 +30,52 @@ use function Functional\contains; class NotifyVisitToWebHooksTest extends TestCase { - use ProphecyTrait; - - private ObjectProphecy $httpClient; - private ObjectProphecy $em; - private ObjectProphecy $logger; + private MockObject $httpClient; + private MockObject $em; + private MockObject $logger; protected function setUp(): void { - $this->httpClient = $this->prophesize(ClientInterface::class); - $this->em = $this->prophesize(EntityManagerInterface::class); - $this->logger = $this->prophesize(LoggerInterface::class); + $this->httpClient = $this->createMock(ClientInterface::class); + $this->em = $this->createMock(EntityManagerInterface::class); + $this->logger = $this->createMock(LoggerInterface::class); } /** @test */ public function emptyWebhooksMakeNoFurtherActions(): void { - $find = $this->em->find(Visit::class, '1')->willReturn(null); + $this->em->expects($this->never())->method('find'); $this->createListener([])(new VisitLocated('1')); - - $find->shouldNotHaveBeenCalled(); } /** @test */ public function invalidVisitDoesNotPerformAnyRequest(): void { - $find = $this->em->find(Visit::class, '1')->willReturn(null); - $requestAsync = $this->httpClient->requestAsync( - RequestMethodInterface::METHOD_POST, - Argument::type('string'), - Argument::type('array'), - )->willReturn(new FulfilledPromise('')); - $logWarning = $this->logger->warning( - 'Tried to notify webhooks for visit with id "{visitId}", but it does not exist.', - ['visitId' => '1'], + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo('1'), + )->willReturn(null); + $this->httpClient->expects($this->never())->method('requestAsync'); + $this->logger->expects($this->once())->method('warning')->with( + $this->equalTo('Tried to notify webhooks for visit with id "{visitId}", but it does not exist.'), + $this->equalTo(['visitId' => '1']), ); $this->createListener(['foo', 'bar'])(new VisitLocated('1')); - - $find->shouldHaveBeenCalledOnce(); - $logWarning->shouldHaveBeenCalledOnce(); - $requestAsync->shouldNotHaveBeenCalled(); } /** @test */ public function orphanVisitDoesNotPerformAnyRequestWhenDisabled(): void { - $find = $this->em->find(Visit::class, '1')->willReturn(Visit::forBasePath(Visitor::emptyInstance())); - $requestAsync = $this->httpClient->requestAsync( - RequestMethodInterface::METHOD_POST, - Argument::type('string'), - Argument::type('array'), - )->willReturn(new FulfilledPromise('')); - $logWarning = $this->logger->warning(Argument::cetera()); + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo('1'), + )->willReturn(Visit::forBasePath(Visitor::emptyInstance())); + $this->httpClient->expects($this->never())->method('requestAsync'); + $this->logger->expects($this->never())->method('warning'); $this->createListener(['foo', 'bar'], false)(new VisitLocated('1')); - - $find->shouldHaveBeenCalledOnce(); - $logWarning->shouldNotHaveBeenCalled(); - $requestAsync->shouldNotHaveBeenCalled(); } /** @@ -103,16 +87,19 @@ class NotifyVisitToWebHooksTest extends TestCase $webhooks = ['foo', 'invalid', 'bar', 'baz']; $invalidWebhooks = ['invalid', 'baz']; - $find = $this->em->find(Visit::class, '1')->willReturn($visit); - $requestAsync = $this->httpClient->requestAsync( - RequestMethodInterface::METHOD_POST, - Argument::type('string'), - Argument::that(function (array $requestOptions) use ($expectedResponseKeys) { + $this->em->expects($this->once())->method('find')->with( + $this->equalTo(Visit::class), + $this->equalTo('1'), + )->willReturn($visit); + $this->httpClient->expects($this->exactly(count($webhooks)))->method('requestAsync')->with( + $this->equalTo(RequestMethodInterface::METHOD_POST), + $this->istype('string'), + $this->callback(function (array $requestOptions) use ($expectedResponseKeys) { Assert::assertArrayHasKey(RequestOptions::HEADERS, $requestOptions); Assert::assertArrayHasKey(RequestOptions::JSON, $requestOptions); Assert::assertArrayHasKey(RequestOptions::TIMEOUT, $requestOptions); - Assert::assertEquals($requestOptions[RequestOptions::TIMEOUT], 10); - Assert::assertEquals($requestOptions[RequestOptions::HEADERS], ['User-Agent' => 'Shlink:v1.2.3']); + Assert::assertEquals(10, $requestOptions[RequestOptions::TIMEOUT]); + Assert::assertEquals(['User-Agent' => 'Shlink:v1.2.3'], $requestOptions[RequestOptions::HEADERS]); $json = $requestOptions[RequestOptions::JSON]; Assert::assertCount(count($expectedResponseKeys), $json); @@ -120,30 +107,24 @@ class NotifyVisitToWebHooksTest extends TestCase Assert::assertArrayHasKey($key, $json); } - return $requestOptions; + return true; }), - )->will(function (array $args) use ($invalidWebhooks) { - [, $webhook] = $args; + )->willReturnCallback(function ($_, $webhook) use ($invalidWebhooks) { $shouldReject = contains($invalidWebhooks, $webhook); - return $shouldReject ? new RejectedPromise(new Exception('')) : new FulfilledPromise(''); }); - $logWarning = $this->logger->warning( - 'Failed to notify visit with id "{visitId}" to webhook "{webhook}". {e}', - Argument::that(function (array $extra) { + $this->logger->expects($this->exactly(count($invalidWebhooks)))->method('warning')->with( + $this->equalTo('Failed to notify visit with id "{visitId}" to webhook "{webhook}". {e}'), + $this->callback(function (array $extra): bool { Assert::assertArrayHasKey('webhook', $extra); Assert::assertArrayHasKey('visitId', $extra); Assert::assertArrayHasKey('e', $extra); - return $extra; + return true; }), ); $this->createListener($webhooks)(new VisitLocated('1')); - - $find->shouldHaveBeenCalledOnce(); - $requestAsync->shouldHaveBeenCalledTimes(count($webhooks)); - $logWarning->shouldHaveBeenCalledTimes(count($invalidWebhooks)); } public function provideVisits(): iterable @@ -158,9 +139,9 @@ class NotifyVisitToWebHooksTest extends TestCase private function createListener(array $webhooks, bool $notifyOrphanVisits = true): NotifyVisitToWebHooks { return new NotifyVisitToWebHooks( - $this->httpClient->reveal(), - $this->em->reveal(), - $this->logger->reveal(), + $this->httpClient, + $this->em, + $this->logger, new WebhookOptions( ['webhooks' => $webhooks, 'notify_orphan_visits_to_webhooks' => $notifyOrphanVisits], ), diff --git a/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php b/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php index 9ce20801..93cde57c 100644 --- a/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php +++ b/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php @@ -4,10 +4,8 @@ declare(strict_types=1); namespace ShlinkioTest\Shlink\Core\EventDispatcher; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Log\LoggerInterface; use RuntimeException; @@ -20,24 +18,18 @@ use function Functional\map; class UpdateGeoLiteDbTest extends TestCase { - use ProphecyTrait; - private UpdateGeoLiteDb $listener; - private ObjectProphecy $dbUpdater; - private ObjectProphecy $logger; - private ObjectProphecy $eventDispatcher; + private MockObject $dbUpdater; + private MockObject $logger; + private MockObject $eventDispatcher; protected function setUp(): void { - $this->dbUpdater = $this->prophesize(GeolocationDbUpdaterInterface::class); - $this->logger = $this->prophesize(LoggerInterface::class); - $this->eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $this->dbUpdater = $this->createMock(GeolocationDbUpdaterInterface::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class); - $this->listener = new UpdateGeoLiteDb( - $this->dbUpdater->reveal(), - $this->logger->reveal(), - $this->eventDispatcher->reveal(), - ); + $this->listener = new UpdateGeoLiteDb($this->dbUpdater, $this->logger, $this->eventDispatcher); } /** @test */ @@ -45,15 +37,15 @@ class UpdateGeoLiteDbTest extends TestCase { $e = new RuntimeException(); - $checkDbUpdate = $this->dbUpdater->checkDbUpdate(Argument::cetera())->willThrow($e); - $logError = $this->logger->error('GeoLite2 database download failed. {e}', ['e' => $e]); + $this->dbUpdater->expects($this->once())->method('checkDbUpdate')->withAnyParameters()->willThrowException($e); + $this->logger->expects($this->once())->method('error')->with( + $this->equalTo('GeoLite2 database download failed. {e}'), + $this->equalTo(['e' => $e]), + ); + $this->logger->expects($this->never())->method('notice'); + $this->eventDispatcher->expects($this->never())->method('dispatch'); ($this->listener)(); - - $checkDbUpdate->shouldHaveBeenCalledOnce(); - $logError->shouldHaveBeenCalledOnce(); - $this->logger->notice(Argument::cetera())->shouldNotHaveBeenCalled(); - $this->eventDispatcher->dispatch(Argument::cetera())->shouldNotHaveBeenCalled(); } /** @@ -62,22 +54,17 @@ class UpdateGeoLiteDbTest extends TestCase */ public function noticeMessageIsPrintedWhenFirstCallbackIsInvoked(bool $oldDbExists, string $expectedMessage): void { - $checkDbUpdate = $this->dbUpdater->checkDbUpdate(Argument::cetera())->will( - function (array $args) use ($oldDbExists): GeolocationResult { - [$firstCallback] = $args; + $this->dbUpdater->expects($this->once())->method('checkDbUpdate')->withAnyParameters()->willReturnCallback( + function (callable $firstCallback) use ($oldDbExists): GeolocationResult { $firstCallback($oldDbExists); - return GeolocationResult::DB_IS_UP_TO_DATE; }, ); - $logNotice = $this->logger->notice($expectedMessage); + $this->logger->expects($this->once())->method('notice')->with($this->equalTo($expectedMessage)); + $this->logger->expects($this->never())->method('error'); + $this->eventDispatcher->expects($this->never())->method('dispatch'); ($this->listener)(); - - $checkDbUpdate->shouldHaveBeenCalledOnce(); - $logNotice->shouldHaveBeenCalledOnce(); - $this->logger->error(Argument::cetera())->shouldNotHaveBeenCalled(); - $this->eventDispatcher->dispatch(Argument::cetera())->shouldNotHaveBeenCalled(); } public function provideFlags(): iterable @@ -96,10 +83,8 @@ class UpdateGeoLiteDbTest extends TestCase bool $oldDbExists, ?string $expectedMessage, ): void { - $checkDbUpdate = $this->dbUpdater->checkDbUpdate(Argument::cetera())->will( - function (array $args) use ($total, $downloaded, $oldDbExists): GeolocationResult { - [, $secondCallback] = $args; - + $this->dbUpdater->expects($this->once())->method('checkDbUpdate')->withAnyParameters()->willReturnCallback( + function ($_, callable $secondCallback) use ($total, $downloaded, $oldDbExists): GeolocationResult { // Invoke several times to ensure the log is printed only once $secondCallback($total, $downloaded, $oldDbExists); $secondCallback($total, $downloaded, $oldDbExists); @@ -108,18 +93,12 @@ class UpdateGeoLiteDbTest extends TestCase return GeolocationResult::DB_UPDATED; }, ); - $logNotice = $this->logger->notice($expectedMessage ?? Argument::cetera()); + $logNoticeExpectation = $expectedMessage !== null ? $this->once() : $this->never(); + $this->logger->expects($logNoticeExpectation)->method('notice')->with($this->equalTo($expectedMessage)); + $this->logger->expects($this->never())->method('error'); + $this->eventDispatcher->expects($this->never())->method('dispatch'); ($this->listener)(); - - if ($expectedMessage !== null) { - $logNotice->shouldHaveBeenCalledOnce(); - } else { - $logNotice->shouldNotHaveBeenCalled(); - } - $checkDbUpdate->shouldHaveBeenCalledOnce(); - $this->logger->error(Argument::cetera())->shouldNotHaveBeenCalled(); - $this->eventDispatcher->dispatch(Argument::cetera())->shouldNotHaveBeenCalled(); } public function provideDownloaded(): iterable @@ -142,12 +121,12 @@ class UpdateGeoLiteDbTest extends TestCase GeolocationResult $result, int $expectedDispatches, ): void { - $checkDbUpdate = $this->dbUpdater->checkDbUpdate(Argument::cetera())->willReturn($result); + $this->dbUpdater->expects($this->once())->method('checkDbUpdate')->withAnyParameters()->willReturn($result); + $this->eventDispatcher->expects($this->exactly($expectedDispatches))->method('dispatch')->with( + $this->equalTo(new GeoLiteDbCreated()), + ); ($this->listener)(); - - $checkDbUpdate->shouldHaveBeenCalledOnce(); - $this->eventDispatcher->dispatch(new GeoLiteDbCreated())->shouldHaveBeenCalledTimes($expectedDispatches); } public function provideGeolocationResults(): iterable