mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Feature: Change accompanying period info step in a cronjob
This commit is contained in:
parent
97b7ff2e43
commit
722f053f06
@ -34,6 +34,7 @@
|
||||
"sensio/framework-extra-bundle": "^5.5",
|
||||
"spomky-labs/base64url": "^2.0",
|
||||
"symfony/browser-kit": "^4.4",
|
||||
"symfony/clock": "^6.2",
|
||||
"symfony/css-selector": "^4.4",
|
||||
"symfony/expression-language": "^4.4",
|
||||
"symfony/form": "^4.4",
|
||||
|
@ -1,6 +1,9 @@
|
||||
parameters:
|
||||
# cl_chill_main.example.class: Chill\MainBundle\Example
|
||||
|
||||
imports:
|
||||
- ./services/clock.yaml
|
||||
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
|
4
src/Bundle/ChillMainBundle/config/services/clock.yaml
Normal file
4
src/Bundle/ChillMainBundle/config/services/clock.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
# temporary, waiting for symfony 6.0 to load clock
|
||||
services:
|
||||
Symfony\Component\Clock\NativeClock: ~
|
||||
Symfony\Component\Clock\ClockInterface: '@Symfony\Component\Clock\NativeClock'
|
@ -0,0 +1,46 @@
|
||||
<?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 Chill\PersonBundle\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\MainBundle\Cron\CronJobInterface;
|
||||
use Chill\MainBundle\Entity\CronJobExecution;
|
||||
use Symfony\Component\Clock\ClockInterface;
|
||||
|
||||
readonly class AccompanyingPeriodStepChangeCronjob implements CronJobInterface
|
||||
{
|
||||
public function __construct(
|
||||
private ClockInterface $clock,
|
||||
private AccompanyingPeriodStepChangeRequestor $requestor,
|
||||
) {
|
||||
}
|
||||
|
||||
public function canRun(?CronJobExecution $cronJobExecution): bool
|
||||
{
|
||||
$now = $this->clock->now();
|
||||
|
||||
if ($now->sub(new \DateInterval('P1D')) < $cronJobExecution->getLastStart()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array((int) $now->format('H'), [1, 2, 3, 4, 5, 6], true);
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return 'accompanying-period-step-change';
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
($this->requestor)();
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?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 Chill\PersonBundle\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
||||
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
|
||||
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
|
||||
|
||||
#[AsMessageHandler]
|
||||
class AccompanyingPeriodStepChangeMessageHandler implements MessageHandlerInterface
|
||||
{
|
||||
private const LOG_PREFIX = '[accompanying period step change message handler] ';
|
||||
|
||||
public function __construct(
|
||||
private AccompanyingPeriodRepository $accompanyingPeriodRepository,
|
||||
private AccompanyingPeriodStepChanger $changer,
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(AccompanyingPeriodStepChangeRequestMessage $message): void
|
||||
{
|
||||
if (null === $period = $this->accompanyingPeriodRepository->find($message->getPeriodId())) {
|
||||
throw new \RuntimeException(self::LOG_PREFIX . 'Could not find period with this id: '. $message->getPeriodId());
|
||||
}
|
||||
|
||||
($this->changer)($period, $message->getTransition());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<?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 Chill\PersonBundle\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
/**
|
||||
* Message which will request a change in the step of accompanying period
|
||||
*/
|
||||
class AccompanyingPeriodStepChangeRequestMessage
|
||||
{
|
||||
private int $periodId;
|
||||
|
||||
public function __construct(
|
||||
AccompanyingPeriod|int $period,
|
||||
private string $transition,
|
||||
) {
|
||||
if (is_int($period)) {
|
||||
$this->periodId = $period;
|
||||
} else {
|
||||
if (null !== $id = $period->getId()) {
|
||||
$this->periodId = $id;
|
||||
}
|
||||
|
||||
throw new \LogicException("This AccompanyingPeriod does not have and id yet");
|
||||
}
|
||||
}
|
||||
|
||||
public function getPeriodId(): int
|
||||
{
|
||||
return $this->periodId;
|
||||
}
|
||||
|
||||
public function getTransition(): string
|
||||
{
|
||||
return $this->transition;
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
<?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 Chill\PersonBundle\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodInfoRepositoryInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
|
||||
/**
|
||||
* Gather all the accompanying period which needs a change in step
|
||||
*/
|
||||
class AccompanyingPeriodStepChangeRequestor
|
||||
{
|
||||
private \DateInterval $intervalForShortInactive;
|
||||
|
||||
private \DateInterval $intervalForLongInactive;
|
||||
|
||||
private bool $isMarkInactive;
|
||||
|
||||
public function __construct(
|
||||
private AccompanyingPeriodInfoRepositoryInterface $accompanyingPeriodInfoRepository,
|
||||
private LoggerInterface $logger,
|
||||
private MessageBusInterface $messageBus,
|
||||
ParameterBagInterface $parameterBag,
|
||||
) {
|
||||
$config = $parameterBag->get('chill_person')['accompanying_period_lifecycle_delays'];
|
||||
$this->isMarkInactive = $config['mark_inactive'];
|
||||
$this->intervalForShortInactive = new \DateInterval($config['mark_inactive_short_after']);
|
||||
$this->intervalForLongInactive = new \DateInterval($config['mark_inactive_long_after']);
|
||||
}
|
||||
|
||||
public function __invoke(): void
|
||||
{
|
||||
if (!$this->isMarkInactive) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the oldest ones first
|
||||
foreach (
|
||||
$olders = $this->accompanyingPeriodInfoRepository->findAccompanyingPeriodIdInactiveAfter(
|
||||
$this->intervalForLongInactive,
|
||||
[AccompanyingPeriod::STEP_CONFIRMED, AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT]
|
||||
) as $accompanyingPeriodId
|
||||
) {
|
||||
$this->logger->debug('request mark period as inactive_short', ['period' => $accompanyingPeriodId]);
|
||||
$this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_inactive_long'));
|
||||
}
|
||||
|
||||
// the newest
|
||||
foreach (
|
||||
$this->accompanyingPeriodInfoRepository->findAccompanyingPeriodIdInactiveAfter(
|
||||
$this->intervalForShortInactive,
|
||||
[AccompanyingPeriod::STEP_CONFIRMED]
|
||||
) as $accompanyingPeriodId
|
||||
) {
|
||||
if (in_array($accompanyingPeriodId, $olders, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->logger->debug('request mark period as inactive_long', ['period' => $accompanyingPeriodId]);
|
||||
$this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_inactive_short'));
|
||||
}
|
||||
|
||||
// a new event has been created => remove inactive long, or short
|
||||
foreach (
|
||||
$this->accompanyingPeriodInfoRepository->findAccompanyingPeriodIdActiveSince(
|
||||
$this->intervalForShortInactive,
|
||||
[AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT, AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG]
|
||||
) as $accompanyingPeriodId
|
||||
) {
|
||||
$this->logger->debug('request mark period as active', ['period' => $accompanyingPeriodId]);
|
||||
$this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_active'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?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 Chill\PersonBundle\AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Workflow\Registry;
|
||||
|
||||
/**
|
||||
* Change the step of an accompanying period
|
||||
*
|
||||
* This should be invoked through scripts (not in the in context of an http request, or an
|
||||
* action from a user).
|
||||
*/
|
||||
class AccompanyingPeriodStepChanger
|
||||
{
|
||||
private const LOG_PREFIX = '[AccompanyingPeriodStepChanger] ';
|
||||
|
||||
public function __construct(
|
||||
private EntityManagerInterface $entityManager,
|
||||
private LoggerInterface $logger,
|
||||
private Registry $workflowRegistry,
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(AccompanyingPeriod $period, string $transition, ?string $workflowName = null): void
|
||||
{
|
||||
$workflow = $this->workflowRegistry->get($period, $workflowName);
|
||||
|
||||
if (!$workflow->can($period, $transition)) {
|
||||
$this->logger->info(self::LOG_PREFIX . 'not able to apply the transition on period', [
|
||||
'period_id' => $period->getId(),
|
||||
'transition' => $transition
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$workflow->apply($period, $transition);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->logger->info(self::LOG_PREFIX . 'could apply a transition', [
|
||||
'period_id' => $period->getId(),
|
||||
'transition' => $transition
|
||||
]);
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ use Chill\MainBundle\DependencyInjection\MissingBundleException;
|
||||
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
||||
use Chill\PersonBundle\Controller\HouseholdCompositionTypeApiController;
|
||||
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodCommentVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodResourceVoter;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
@ -1010,18 +1011,42 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
],
|
||||
'initial_marking' => 'DRAFT',
|
||||
'places' => [
|
||||
'DRAFT',
|
||||
'CONFIRMED',
|
||||
'CLOSED',
|
||||
AccompanyingPeriod::STEP_DRAFT,
|
||||
AccompanyingPeriod::STEP_CONFIRMED,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
AccompanyingPeriod::STEP_CLOSED,
|
||||
],
|
||||
'transitions' => [
|
||||
'confirm' => [
|
||||
'from' => 'DRAFT',
|
||||
'to' => 'CONFIRMED',
|
||||
'from' => AccompanyingPeriod::STEP_DRAFT,
|
||||
'to' => AccompanyingPeriod::STEP_CONFIRMED,
|
||||
],
|
||||
'mark_inactive_short' => [
|
||||
'from' => AccompanyingPeriod::STEP_CONFIRMED,
|
||||
'to' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
],
|
||||
'mark_inactive_long' => [
|
||||
'from' => [
|
||||
AccompanyingPeriod::STEP_CONFIRMED,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT
|
||||
],
|
||||
'to' => AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
],
|
||||
'mark_active' => [
|
||||
'from' => [
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
],
|
||||
'to' => AccompanyingPeriod::STEP_CONFIRMED
|
||||
],
|
||||
'close' => [
|
||||
'from' => 'CONFIRMED',
|
||||
'to' => 'CLOSED',
|
||||
'from' => [
|
||||
AccompanyingPeriod::STEP_CONFIRMED,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||
],
|
||||
'to' => AccompanyingPeriod::STEP_CLOSED,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
@ -128,6 +128,15 @@ class Configuration implements ConfigurationInterface
|
||||
->info('Can we have more than one simultaneous accompanying period in the same time. Default false.')
|
||||
->defaultValue(false)
|
||||
->end()
|
||||
->arrayNode('accompanying_period_lifecycle_delays')
|
||||
->addDefaultsIfNotSet()
|
||||
->info('Delays before marking an accompanying period as inactive')
|
||||
->children()
|
||||
->booleanNode('mark_inactive')->defaultTrue()->end()
|
||||
->scalarNode('mark_inactive_short_after')->defaultValue('P6M')->end()
|
||||
->scalarNode('mark_inactive_long_after')->defaultValue('P2Y')->end()
|
||||
->end()
|
||||
->end() // end of 'accompanying_period_lifecycle_delays
|
||||
->end() // children of 'root', parent = root
|
||||
;
|
||||
|
||||
|
@ -116,7 +116,16 @@ class AccompanyingPeriod implements
|
||||
* confirmed, but no activity (Activity, AccompanyingPeriod, ...)
|
||||
* has been associated, or updated, within this accompanying period.
|
||||
*/
|
||||
public const STEP_CONFIRMED_INACTIVE = 'CONFIRMED_INACTIVE';
|
||||
public const STEP_CONFIRMED_INACTIVE_SHORT = 'CONFIRMED_INACTIVE_SHORT';
|
||||
|
||||
/**
|
||||
* Mark an accompanying period as confirmed, but inactive
|
||||
*
|
||||
* this means that the accompanying period **is**
|
||||
* confirmed, but no activity (Activity, AccompanyingPeriod, ...)
|
||||
* has been associated, or updated, within this accompanying period.
|
||||
*/
|
||||
public const STEP_CONFIRMED_INACTIVE_LONG = 'CONFIRMED_INACTIVE_LONG';
|
||||
|
||||
/**
|
||||
* Mark an accompanying period as "draft".
|
||||
|
@ -0,0 +1,93 @@
|
||||
<?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 Chill\PersonBundle\Repository\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodInfo;
|
||||
use DateInterval;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use LogicException;
|
||||
use Symfony\Component\Clock\ClockInterface;
|
||||
|
||||
readonly class AccompanyingPeriodInfoRepository implements AccompanyingPeriodInfoRepositoryInterface
|
||||
{
|
||||
private EntityRepository $entityRepository;
|
||||
|
||||
public function __construct(
|
||||
private ClockInterface $clock,
|
||||
private EntityManagerInterface $em,
|
||||
) {
|
||||
$this->entityRepository = $em->getRepository($this->getClassName());
|
||||
}
|
||||
|
||||
public function findAccompanyingPeriodIdInactiveAfter(DateInterval $interval, array $statuses = []): array
|
||||
{
|
||||
$query = $this->em->createQuery();
|
||||
$baseDql = 'SELECT DISTINCT IDENTITY(ai.accompanyingPeriod) FROM '.AccompanyingPeriodInfo::class.' ai JOIN ai.accompanyingPeriod a WHERE NOT EXISTS
|
||||
(SELECT 1 FROM ' . AccompanyingPeriodInfo::class . ' aiz WHERE aiz.infoDate > :after AND IDENTITY(aiz.accompanyingPeriod) = IDENTITY(ai.accompanyingPeriod))';
|
||||
|
||||
if ([] !== $statuses) {
|
||||
$dql = $baseDql . ' AND a.step IN (:statuses)';
|
||||
$query->setParameter('statuses', $statuses);
|
||||
} else {
|
||||
$dql = $baseDql;
|
||||
}
|
||||
|
||||
return $query->setDQL($dql)
|
||||
->setParameter('after', $this->clock->now()->sub($interval))
|
||||
->getSingleColumnResult();
|
||||
}
|
||||
|
||||
public function findAccompanyingPeriodIdActiveSince(DateInterval $interval, array $statuses = []): array
|
||||
{
|
||||
$query = $this->em->createQuery();
|
||||
$baseDql = 'SELECT DISTINCT IDENTITY(ai.accompanyingPeriod) FROM ' . AccompanyingPeriodInfo::class . ' ai
|
||||
JOIN ai.accompanyingPeriod a WHERE ai.infoDate > :after';
|
||||
|
||||
if ([] !== $statuses) {
|
||||
$dql = $baseDql . ' AND a.step IN (:statuses)';
|
||||
$query->setParameter('statuses', $statuses);
|
||||
} else {
|
||||
$dql = $baseDql;
|
||||
}
|
||||
|
||||
return $query->setDQL($dql)
|
||||
->setParameter('after', $this->clock->now()->sub($interval))
|
||||
->getSingleColumnResult();
|
||||
}
|
||||
|
||||
public function find($id): ?AccompanyingPeriodInfo
|
||||
{
|
||||
throw new LogicException("Calling an accompanying period info by his id does not make sense");
|
||||
}
|
||||
|
||||
public function findAll(): array
|
||||
{
|
||||
return $this->entityRepository->findAll();
|
||||
}
|
||||
|
||||
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
|
||||
{
|
||||
return $this->entityRepository->findBy($criteria, $orderBy, $limit, $offset);
|
||||
}
|
||||
|
||||
public function findOneBy(array $criteria): ?AccompanyingPeriodInfo
|
||||
{
|
||||
return $this->entityRepository->findOneBy($criteria);
|
||||
}
|
||||
|
||||
public function getClassName(): string
|
||||
{
|
||||
return AccompanyingPeriodInfo::class;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?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 Chill\PersonBundle\Repository\AccompanyingPeriod;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodInfo;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
/**
|
||||
* @template-extends ObjectRepository<AccompanyingPeriodInfo>
|
||||
*/
|
||||
interface AccompanyingPeriodInfoRepositoryInterface extends ObjectRepository
|
||||
{
|
||||
/**
|
||||
* Return a list of id for inactive accompanying periods
|
||||
*
|
||||
* @param \DateInterval $interval
|
||||
* @param list<AccompanyingPeriod::STEP_*> $statuses
|
||||
* @return list<int>
|
||||
*/
|
||||
public function findAccompanyingPeriodIdInactiveAfter(\DateInterval $interval, array $statuses = []): array;
|
||||
|
||||
/**
|
||||
* @param \DateInterval $interval
|
||||
* @param list<AccompanyingPeriod::STEP_*> $statuses
|
||||
* @return list<int>
|
||||
*/
|
||||
public function findAccompanyingPeriodIdActiveSince(\DateInterval $interval, array $statuses = []): array;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
<?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 AccompanyingPeriod\Lifecycle;
|
||||
|
||||
use Chill\MainBundle\Entity\CronJobExecution;
|
||||
use Chill\PersonBundle\AccompanyingPeriod\Lifecycle\AccompanyingPeriodStepChangeCronjob;
|
||||
use Chill\PersonBundle\AccompanyingPeriod\Lifecycle\AccompanyingPeriodStepChangeRequestor;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Component\Clock\MockClock;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class AccompanyingPeriodStepChangeCronjobTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
/**
|
||||
* @dataProvider provideRunTimes
|
||||
*/
|
||||
public function testCanRun(string $datetime, \DateTimeImmutable $lastExecutionStart, bool $canRun): void
|
||||
{
|
||||
$requestor = $this->prophesize(AccompanyingPeriodStepChangeRequestor::class);
|
||||
$clock = new MockClock($datetime);
|
||||
|
||||
$cronJob = new AccompanyingPeriodStepChangeCronjob($clock, $requestor->reveal());
|
||||
$cronJobExecution = (new CronJobExecution($cronJob->getKey()))->setLastStart($lastExecutionStart);
|
||||
|
||||
$this->assertEquals($canRun, $cronJob->canRun($cronJobExecution));
|
||||
}
|
||||
|
||||
public function provideRunTimes(): iterable
|
||||
{
|
||||
// can run, during the night
|
||||
yield ['2023-01-15T01:00:00+02:00', new \DateTimeImmutable('2023-01-14T00:00:00+02:00'), true];
|
||||
|
||||
// can not run, not during the night
|
||||
yield ['2023-01-15T10:00:00+02:00', new \DateTimeImmutable('2023-01-14T00:00:00+02:00'), false];
|
||||
|
||||
// can not run: not enough elapsed time
|
||||
yield ['2023-01-15T01:00:00+02:00', new \DateTimeImmutable('2023-01-15T00:30:00+02:00'), false];
|
||||
}
|
||||
|
||||
}
|
@ -25,6 +25,11 @@ services:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
Chill\PersonBundle\AccompanyingPeriod\Lifecycle\:
|
||||
resource: './../../AccompanyingPeriod/Lifecycle'
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
Chill\PersonBundle\AccompanyingPeriod\Events\UserRefEventSubscriber:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
Loading…
x
Reference in New Issue
Block a user