prophesize(CronJobInterface::class); $jobToExecute->getKey()->willReturn('to-exec'); $jobToExecute->canRun(Argument::type(CronJobExecution::class))->willReturn(true); $jobToExecute->run([])->shouldBeCalled(); $executions = [ ['key' => $jobOld1->getKey(), 'lastStart' => new DateTimeImmutable('yesterday'), 'lastEnd' => new DateTimeImmutable('1 hours ago'), 'lastStatus' => CronJobExecution::SUCCESS], ['key' => $jobOld2->getKey(), 'lastStart' => new DateTimeImmutable('3 days ago'), 'lastEnd' => new DateTimeImmutable('36 hours ago'), 'lastStatus' => CronJobExecution::SUCCESS], // this is the oldest one ['key' => 'to-exec', 'lastStart' => new DateTimeImmutable('1 month ago'), 'lastEnd' => new DateTimeImmutable('10 days ago'), 'lastStatus' => CronJobExecution::SUCCESS], ]; $cronManager = new CronManager( $this->buildCronJobExecutionRepository($executions), $this->buildEntityManager([]), new ArrayObject([$jobOld1, $jobToExecute->reveal(), $jobOld2]), new NullLogger() ); $cronManager->run(); } public function testSelectNewJobFirstAndNewJobIsFirstInList(): void { $jobAlreadyExecuted = new JobCanRun('k'); $jobNeverExecuted = $this->prophesize(CronJobInterface::class); $jobNeverExecuted->getKey()->willReturn('never-executed'); $jobNeverExecuted->run([])->shouldBeCalled(); $jobNeverExecuted->canRun(null)->willReturn(true); $executions = [ ['key' => $jobAlreadyExecuted->getKey(), 'lastStart' => new DateTimeImmutable('yesterday'), 'lastEnd' => new DateTimeImmutable('1 hours ago'), 'lastStatus' => CronJobExecution::SUCCESS], ]; $cronManager = new CronManager( $this->buildCronJobExecutionRepository($executions), $this->buildEntityManager([Argument::type(CronJobExecution::class)]), new ArrayObject([$jobNeverExecuted->reveal(), $jobAlreadyExecuted]), new NullLogger() ); $cronManager->run(); } public function testSelectNewJobFirstAndNewJobIsLastInList(): void { $jobAlreadyExecuted = new JobCanRun('k'); $jobNeverExecuted = $this->prophesize(CronJobInterface::class); $jobNeverExecuted->getKey()->willReturn('never-executed'); $jobNeverExecuted->run([])->shouldBeCalled(); $jobNeverExecuted->canRun(null)->willReturn(true); $executions = [ ['key' => $jobAlreadyExecuted->getKey(), 'lastStart' => new DateTimeImmutable('yesterday'), 'lastEnd' => new DateTimeImmutable('1 hours ago'), 'lastStatus' => CronJobExecution::SUCCESS], ]; $cronManager = new CronManager( $this->buildCronJobExecutionRepository($executions), $this->buildEntityManager([Argument::type(CronJobExecution::class)]), new ArrayObject([$jobAlreadyExecuted, $jobNeverExecuted->reveal()]), new NullLogger() ); $cronManager->run(); } /** * @param array $executions */ private function buildCronJobExecutionRepository(array $executions): CronJobExecutionRepositoryInterface { $repository = $this->prophesize(CronJobExecutionRepositoryInterface::class); $repository->findAll()->willReturn( array_map( static function (array $exec): CronJobExecution { $e = new CronJobExecution($exec['key']); $e->setLastStart($exec['lastStart']); if (array_key_exists('lastEnd', $exec)) { $e->setLastEnd($exec['lastEnd']); } if (array_key_exists('lastStatus', $exec)) { $e->setLastStatus($exec['lastStatus']); } return $e; }, $executions ) ); return $repository->reveal(); } private function buildEntityManager(array $persistArgsShouldBeCalled = []): EntityManagerInterface { $em = $this->prophesize(EntityManagerInterface::class); if ([] === $persistArgsShouldBeCalled) { $em->persist(Argument::any())->shouldNotBeCalled(); } else { foreach ($persistArgsShouldBeCalled as $arg) { $em->persist($arg)->shouldBeCalled(); } $em->flush()->shouldBeCalled(); } // other methods $em->clear()->shouldBeCalled(); $query = $this->prophesize(AbstractQuery::class); $query->setParameters(Argument::type('array'))->willReturn($query->reveal()); $query->execute()->shouldBeCalled(); $em->createQuery(Argument::type('string'))->willReturn($query->reveal()); return $em->reveal(); } } class JobCanRun implements CronJobInterface { private string $key; public function __construct(string $key) { $this->key = $key; } public function canRun(?CronJobExecution $cronJobExecution): bool { return true; } public function getKey(): string { return $this->key; } public function run(array $lastExecutionData): null|array { return null; } } class JobCannotRun implements CronJobInterface { public function canRun(?CronJobExecution $cronJobExecution): bool { return false; } public function getKey(): string { return 'job-b'; } public function run(array $lastExecutionData): null|array { return null; } }