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; } }