createMock(StoredObjectVersionRepository::class); $clock = new MockClock(new \DateTimeImmutable('2024-01-01 00:00:00', new \DateTimeZone('+00:00'))); $cronJob = new RemoveOldVersionCronJob($clock, $this->buildMessageBus(), $repository); self::assertEquals($expected, $cronJob->canRun($cronJobExecution)); } public static function buildTestCanRunData(): iterable { yield [ (new CronJobExecution('last-deleted-stored-object-version-id'))->setLastEnd(new \DateTimeImmutable('2023-12-31 00:00:00', new \DateTimeZone('+00:00'))), true, ]; yield [ (new CronJobExecution('last-deleted-stored-object-version-id'))->setLastEnd(new \DateTimeImmutable('2023-12-30 23:59:59', new \DateTimeZone('+00:00'))), true, ]; yield [ (new CronJobExecution('last-deleted-stored-object-version-id'))->setLastEnd(new \DateTimeImmutable('2023-12-31 00:00:01', new \DateTimeZone('+00:00'))), false, ]; yield [ null, true, ]; } public function testRun(): void { // we create a clock in the future. This led us a chance to having stored object to delete $clock = new MockClock(new \DateTimeImmutable('2024-01-01 00:00:00', new \DateTimeZone('+00:00'))); $repository = $this->createMock(StoredObjectVersionRepository::class); $repository->expects($this->once()) ->method('findIdsByVersionsOlderThanDateAndNotLastVersionAndNotPointInTime') ->with(new \DateTime('2023-10-03 00:00:00', new \DateTimeZone('+00:00'))) ->willReturnCallback(function ($arg) { yield 1; yield 3; yield 2; }) ; $cronJob = new RemoveOldVersionCronJob($clock, $this->buildMessageBus(true), $repository); $results = $cronJob->run([]); self::assertArrayHasKey('last-deleted-stored-object-version-id', $results); self::assertIsInt($results['last-deleted-stored-object-version-id']); } private function buildMessageBus(bool $expectDistpatchAtLeastOnce = false): MessageBusInterface { $messageBus = $this->createMock(MessageBusInterface::class); $methodDispatch = match ($expectDistpatchAtLeastOnce) { true => $messageBus->expects($this->atLeastOnce())->method('dispatch')->with($this->isInstanceOf(RemoveOldVersionMessage::class)), false => $messageBus->method('dispatch'), }; $methodDispatch->willReturnCallback(fn (RemoveOldVersionMessage $message) => new Envelope($message)); return $messageBus; } }