mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-12 21:34:25 +00:00
Introduce MessageBus to handle post-signature operations asynchronously. This ensures that further steps are executed through dispatched messages, improving system scalability and performance. Implement new handlers and messages for the workflow state transitions.
156 lines
6.5 KiB
PHP
156 lines
6.5 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 Chill\MainBundle\Tests\Workflow;
|
|
|
|
use Chill\MainBundle\Entity\User;
|
|
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
|
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
|
|
use Chill\MainBundle\Workflow\EntityWorkflowMarkingStore;
|
|
use Chill\MainBundle\Workflow\SignatureStepStateChanger;
|
|
use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO;
|
|
use Chill\PersonBundle\Entity\Person;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\Log\NullLogger;
|
|
use Symfony\Component\Clock\MockClock;
|
|
use Symfony\Component\Messenger\MessageBus;
|
|
use Symfony\Component\Workflow\DefinitionBuilder;
|
|
use Symfony\Component\Workflow\Metadata\InMemoryMetadataStore;
|
|
use Symfony\Component\Workflow\Registry;
|
|
use Symfony\Component\Workflow\SupportStrategy\WorkflowSupportStrategyInterface;
|
|
use Symfony\Component\Workflow\Transition;
|
|
use Symfony\Component\Workflow\Workflow;
|
|
use Symfony\Component\Workflow\WorkflowInterface;
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* @coversNothing
|
|
*/
|
|
class SignatureStepStateChangerTest extends TestCase
|
|
{
|
|
public function testMarkSignatureAsSignedScenarioWhichExpectsTransition()
|
|
{
|
|
$entityWorkflow = new EntityWorkflow();
|
|
$entityWorkflow->setWorkflowName('dummy');
|
|
$registry = $this->buildRegistry();
|
|
$workflow = $registry->get($entityWorkflow, 'dummy');
|
|
$clock = new MockClock();
|
|
$user = new User();
|
|
|
|
$messengerBus = new MessageBus([]);
|
|
$changer = new SignatureStepStateChanger($registry, $clock, new NullLogger(), $messengerBus);
|
|
|
|
// move it to signature
|
|
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
|
$dto->futurePersonSignatures = [new Person(), new Person()];
|
|
$workflow->apply($entityWorkflow, 'to_signature', ['context' => $dto, 'transitionAt' => $clock->now(),
|
|
'byUser' => $user, 'transition' => 'to_signature']);
|
|
|
|
// get the signature created
|
|
$signatures = $entityWorkflow->getCurrentStep()->getSignatures();
|
|
|
|
if (2 !== count($signatures)) {
|
|
throw new \LogicException('there should have 2 signatures at this step');
|
|
}
|
|
|
|
// we mark the first signature as signed
|
|
$changer->markSignatureAsSigned($signatures[0], 1);
|
|
// the next step should be done by handling an async message
|
|
$changer->onPostMark($signatures[0]);
|
|
|
|
self::assertEquals('signature', $entityWorkflow->getStep(), 'there should have any change in the entity workflow step');
|
|
self::assertEquals(EntityWorkflowSignatureStateEnum::SIGNED, $signatures[0]->getState());
|
|
self::assertEquals(1, $signatures[0]->getZoneSignatureIndex());
|
|
self::assertNotNull($signatures[0]->getStateDate());
|
|
|
|
|
|
// we mark the second signature as signed
|
|
$changer->markSignatureAsSigned($signatures[1], 2);
|
|
// the next step should be done by handling an async message
|
|
$changer->onPostMark($signatures[1]);
|
|
self::assertEquals(EntityWorkflowSignatureStateEnum::SIGNED, $signatures[1]->getState());
|
|
self::assertEquals('post-signature', $entityWorkflow->getStep(), 'the entity workflow step should be post-signature');
|
|
self::assertContains($user, $entityWorkflow->getCurrentStep()->getAllDestUser());
|
|
self::assertEquals(2, $signatures[1]->getZoneSignatureIndex());
|
|
self::assertNotNull($signatures[1]->getStateDate());
|
|
}
|
|
|
|
public function testMarkSignatureAsSignedScenarioWithoutRequiredMetadata()
|
|
{
|
|
$entityWorkflow = new EntityWorkflow();
|
|
$entityWorkflow->setWorkflowName('dummy');
|
|
$registry = $this->buildRegistry();
|
|
$workflow = $registry->get($entityWorkflow, 'dummy');
|
|
$clock = new MockClock();
|
|
$user = new User();
|
|
$changer = new SignatureStepStateChanger($registry, $clock, new NullLogger(), new MessageBus([]));
|
|
|
|
// move it to signature
|
|
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
|
$dto->futurePersonSignatures = [new Person()];
|
|
$workflow->apply($entityWorkflow, 'to_signature-without-metadata', ['context' => $dto, 'transitionAt' => $clock->now(),
|
|
'byUser' => $user, 'transition' => 'to_signature-without-metadata']);
|
|
|
|
// get the signature created
|
|
$signatures = $entityWorkflow->getCurrentStep()->getSignatures();
|
|
|
|
if (1 !== count($signatures)) {
|
|
throw new \LogicException('there should have 2 signatures at this step');
|
|
}
|
|
|
|
// we mark the first signature as signed
|
|
$changer->markSignatureAsSigned($signatures[0], 1);
|
|
// the next step should be done by handling an async message
|
|
$changer->onPostMark($signatures[0]);
|
|
|
|
self::assertEquals('signature-without-metadata', $entityWorkflow->getStep(), 'there should have any change in the entity workflow step');
|
|
self::assertEquals(EntityWorkflowSignatureStateEnum::SIGNED, $signatures[0]->getState());
|
|
self::assertEquals(1, $signatures[0]->getZoneSignatureIndex());
|
|
self::assertNotNull($signatures[0]->getStateDate());
|
|
}
|
|
|
|
private function buildRegistry(): Registry
|
|
{
|
|
$builder = new DefinitionBuilder();
|
|
$builder
|
|
->setInitialPlaces('initial')
|
|
->addPlaces(['initial', 'signature', 'signature-without-metadata', 'post-signature'])
|
|
->addTransition(new Transition('to_signature', 'initial', 'signature'))
|
|
->addTransition(new Transition('to_signature-without-metadata', 'initial', 'signature-without-metadata'))
|
|
->addTransition(new Transition('to_post-signature', 'signature', 'post-signature'))
|
|
->addTransition(new Transition('to_post-signature_2', 'signature-without-metadata', 'post-signature'))
|
|
;
|
|
|
|
$metadata = new InMemoryMetadataStore(
|
|
[],
|
|
[
|
|
'signature' => ['onSignatureCompleted' => ['transitionName' => 'to_post-signature']],
|
|
]
|
|
);
|
|
$builder->setMetadataStore($metadata);
|
|
|
|
$workflow = new Workflow($builder->build(), new EntityWorkflowMarkingStore(), name: 'dummy');
|
|
$registry = new Registry();
|
|
$registry->addWorkflow(
|
|
$workflow,
|
|
new class () implements WorkflowSupportStrategyInterface {
|
|
public function supports(WorkflowInterface $workflow, object $subject): bool
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
);
|
|
|
|
return $registry;
|
|
}
|
|
}
|