chill-bundles/src/Bundle/ChillMainBundle/Tests/Workflow/SignatureStepStateChangerTest.php

190 lines
8.2 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 testMarkSignatureAsSignedScenarioWhichExpectsTransitionSignatureWithPerson()
{
$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 testMarkSignatureAsSignedScenarioWhichExpectsTransitionSignatureWithUser()
{
$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->futureUserSignature = $signer = new User();
$workflow->apply($entityWorkflow, 'to_signature', ['context' => $dto, 'transitionAt' => $clock->now(),
'byUser' => $user, 'transition' => 'to_signature']);
// get the signature created
$signatures = $entityWorkflow->getCurrentStep()->getSignatures();
// 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(EntityWorkflowSignatureStateEnum::SIGNED, $signatures[0]->getState());
self::assertEquals('post-signature', $entityWorkflow->getStep(), 'the entity workflow step should be post-signature');
self::assertContains($signer, $entityWorkflow->getCurrentStep()->getAllDestUser());
self::assertCount(1, $entityWorkflow->getCurrentStep()->getAllDestUser());
self::assertEquals(1, $signatures[0]->getZoneSignatureIndex());
self::assertNotNull($signatures[0]->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;
}
}