chill-bundles/src/Bundle/ChillMainBundle/Tests/Services/Workflow/CancelStaleWorkflowCronJobTest.php
2024-09-09 10:40:42 +02:00

114 lines
3.8 KiB
PHP

<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Services\Workflow;
use Chill\MainBundle\Entity\CronJobExecution;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
use Chill\MainBundle\Service\Workflow\CancelStaleWorkflow;
use Chill\MainBundle\Service\Workflow\CancelStaleWorkflowCronJob;
use Doctrine\DBAL\Connection;
use PHPUnit\Framework\MockObject\Exception;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Clock\MockClock;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
/**
* @internal
*
* @coversNothing
*/
class CancelStaleWorkflowCronJobTest extends KernelTestCase
{
protected function setUp(): void
{
self::bootKernel();
$this->connection = self::getContainer()->get(Connection::class);
}
/**
* @dataProvider buildTestCanRunData
*
* @throws \Exception
*/
public function testCanRun(?CronJobExecution $cronJobExecution, bool $expected): void
{
$clock = new MockClock(new \DateTimeImmutable('2024-01-01 00:00:00', new \DateTimeZone('+00:00')));
$logger = $this->createMock(LoggerInterface::class);
$cronJob = new CancelStaleWorkflowCronJob($this->createMock(EntityWorkflowRepository::class), $clock, $this->buildMessageBus(), $logger);
self::assertEquals($expected, $cronJob->canRun($cronJobExecution));
}
/**
* @throws \DateMalformedStringException
* @throws \DateInvalidTimeZoneException
* @throws Exception
*/
public function testRun(): void
{
$clock = new MockClock((new \DateTimeImmutable('now', new \DateTimeZone('+00:00')))->add(new \DateInterval('P120D')));
$workflowRepository = $this->createMock(EntityWorkflowRepository::class);
$logger = $this->createMock(LoggerInterface::class);
$workflowRepository->method('findWorkflowsWithoutFinalStepAndOlderThan')->willReturn([1, 2, 3]);
$messageBus = $this->buildMessageBus(true);
$cronJob = new CancelStaleWorkflowCronJob($workflowRepository, $clock, $messageBus, $logger);
$results = $cronJob->run([]);
// Assert the result has the last canceled workflow ID
self::assertArrayHasKey('last-canceled-workflow-id', $results);
self::assertEquals(3, $results['last-canceled-workflow-id']);
}
/**
* @throws \Exception
*/
public static function buildTestCanRunData(): iterable
{
yield [
(new CronJobExecution('last-canceled-workflow-id'))->setLastEnd(new \DateTimeImmutable('2023-12-31 00:00:00', new \DateTimeZone('+00:00'))),
true,
];
yield [
(new CronJobExecution('last-canceled-workflow-id'))->setLastEnd(new \DateTimeImmutable('2023-12-30 23:59:59', new \DateTimeZone('+00:00'))),
true,
];
yield [
(new CronJobExecution('last-canceled-workflow-id'))->setLastEnd(new \DateTimeImmutable('2023-12-31 00:00:01', new \DateTimeZone('+00:00'))),
false,
];
}
private function buildMessageBus(bool $expectDispatchAtLeastOnce = false): MessageBusInterface
{
$messageBus = $this->createMock(MessageBusInterface::class);
$methodDispatch = match ($expectDispatchAtLeastOnce) {
true => $messageBus->expects($this->atLeastOnce())->method('dispatch')->with($this->isInstanceOf(CancelStaleWorkflow::class)),
false => $messageBus->method('dispatch'),
};
$methodDispatch->willReturnCallback(function (CancelStaleWorkflow $message) {
return new Envelope($message);
});
return $messageBus;
}
}