diff --git a/src/Bundle/ChillMainBundle/Service/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJob.php b/src/Bundle/ChillMainBundle/Service/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJob.php index eaa134ea4..b09a4db5c 100644 --- a/src/Bundle/ChillMainBundle/Service/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJob.php +++ b/src/Bundle/ChillMainBundle/Service/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJob.php @@ -16,12 +16,15 @@ use Chill\MainBundle\Entity\CronJobExecution; use DateInterval; use DateTimeImmutable; use Doctrine\DBAL\Connection; +use Symfony\Component\Clock\ClockInterface; use UnexpectedValueException; -class RefreshAddressToGeographicalUnitMaterializedViewCronJob implements CronJobInterface +final readonly class RefreshAddressToGeographicalUnitMaterializedViewCronJob implements CronJobInterface { - public function __construct(private readonly Connection $connection) - { + public function __construct( + private Connection $connection, + private ClockInterface $clock, + ) { } public function canRun(?CronJobExecution $cronJobExecution): bool @@ -34,7 +37,7 @@ class RefreshAddressToGeographicalUnitMaterializedViewCronJob implements CronJob throw new UnexpectedValueException(); } - $now = new DateTimeImmutable('now'); + $now = $this->clock->now(); return $cronJobExecution->getLastStart() < $now->sub(new DateInterval('P1D')) // introduce a random component to ensure a roll when multiple instances are hosted on same machines diff --git a/src/Bundle/ChillMainBundle/Tests/Services/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJobTest.php b/src/Bundle/ChillMainBundle/Tests/Services/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJobTest.php index f2a7bcd47..2c4e6f428 100644 --- a/src/Bundle/ChillMainBundle/Tests/Services/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJobTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Services/AddressGeographicalUnit/RefreshAddressToGeographicalUnitMaterializedViewCronJobTest.php @@ -14,7 +14,9 @@ namespace Chill\MainBundle\Tests\Services\AddressGeographicalUnit; use Chill\MainBundle\Entity\CronJobExecution; use DateTimeImmutable; use Doctrine\DBAL\Connection; +use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use Symfony\Component\Clock\MockClock; /** * @internal @@ -22,68 +24,50 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; */ final class RefreshAddressToGeographicalUnitMaterializedViewCronJobTest extends KernelTestCase { - private Connection $connection; - - protected function setUp(): void - { - parent::bootKernel(); - $this->connection = self::$container->get(Connection::class); - } + use ProphecyTrait; public function testCanRun(): void { // As the can run is executed one of ten, this should be executed at least one after // 10 + 5 executions $job = new \Chill\MainBundle\Service\AddressGeographicalUnit\RefreshAddressToGeographicalUnitMaterializedViewCronJob( - $this->connection + $this->prophesize(Connection::class)->reveal(), + new MockClock(new DateTimeImmutable('2023-07-01T00:00:00')) ); - $lastExecution = new CronJobExecution($job->getKey()); - $lastExecution->setLastStart(new DateTimeImmutable('2 days ago')); + $hoursAgo23 = new CronJobExecution($job->getKey()); + $hoursAgo23->setLastStart(new DateTimeImmutable('2023-06-30T01:00:00')); + $hoursAgo25 = new CronJobExecution($job->getKey()); + $hoursAgo25->setLastStart(new DateTimeImmutable('2023-06-29T23:00:00')); - $executedForFirstTime = 0; - $executedAfterPreviousExecution = 0; + $executedForFirstTime = $executedAfter23 = $executedAfter25 = 0; - for ($round = 0; 20 > $round; ++$round) { + for ($round = 0; 30 > $round; ++$round) { if ($job->canRun(null)) { ++$executedForFirstTime; } - if ($job->canRun($lastExecution)) { - ++$executedAfterPreviousExecution; + if ($job->canRun($hoursAgo23)) { + ++$executedAfter23; + } + + if ($job->canRun($hoursAgo25)) { + ++$executedAfter25; } } $this->assertGreaterThan(0, $executedForFirstTime); - $this->assertGreaterThan(0, $executedAfterPreviousExecution); - } - - public function testCanRunShouldReturnFalse(): void - { - // As the can run is executed one of ten, this should be executed at least one after - // 10 + 5 executions - $job = new \Chill\MainBundle\Service\AddressGeographicalUnit\RefreshAddressToGeographicalUnitMaterializedViewCronJob( - $this->connection - ); - - $lastExecution = new CronJobExecution($job->getKey()); - $lastExecution->setLastStart(new DateTimeImmutable('2 hours ago')); - - $executedAfterPreviousExecution = 0; - - for ($round = 0; 20 > $round; ++$round) { - if ($job->canRun($lastExecution)) { - ++$executedAfterPreviousExecution; - } - } - - $this->assertEquals(0, $executedAfterPreviousExecution); + $this->assertEquals(0, $executedAfter23); + $this->assertGreaterThan(0, $executedAfter25); } public function testFullRun(): void { + self::bootKernel(); + $job = new \Chill\MainBundle\Service\AddressGeographicalUnit\RefreshAddressToGeographicalUnitMaterializedViewCronJob( - $this->connection + self::$container->get(Connection::class), + new MockClock() ); $lastExecution = new CronJobExecution($job->getKey());