diff --git a/src/Bundle/ChillMainBundle/Tests/Workflow/EventSubscriber/EntityWorkflowGuardSendExternalIfNoPublicViewTest.php b/src/Bundle/ChillMainBundle/Tests/Workflow/EventSubscriber/EntityWorkflowGuardSendExternalIfNoPublicViewTest.php new file mode 100644 index 000000000..823c47725 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Tests/Workflow/EventSubscriber/EntityWorkflowGuardSendExternalIfNoPublicViewTest.php @@ -0,0 +1,106 @@ +setWorkflowName('dummy'); + + $handler = $this->createMock(EntityWorkflowHandlerInterface::class); + $handler->method('supports')->willReturn(true); + + $registry = $this->buildRegistry($handler); + + $workflow = $registry->get($entityWorkflow, $entityWorkflow->getWorkflowName()); + + self::assertFalse($workflow->can($entityWorkflow, 'to_send_external')); + self::assertTrue($workflow->can($entityWorkflow, 'to_other')); + } + + public function testGuardSendExternalIfNoStoredObjectWithStoredObject() + { + $entityWorkflow = new EntityWorkflow(); + $entityWorkflow->setWorkflowName('dummy'); + + $handler = $this->createMockForIntersectionOfInterfaces( + [EntityWorkflowHandlerInterface::class, EntityWorkflowWithPublicViewInterface::class] + ); + $handler->method('supports')->willReturn(true); + + $registry = $this->buildRegistry($handler); + + $workflow = $registry->get($entityWorkflow, $entityWorkflow->getWorkflowName()); + + self::assertTrue($workflow->can($entityWorkflow, 'to_send_external')); + self::assertTrue($workflow->can($entityWorkflow, 'to_other')); + } + + private function buildRegistry(EntityWorkflowHandlerInterface $handler): Registry + { + $builder = new DefinitionBuilder(); + + $builder->addPlace('initial'); + $builder->addPlace('send_external'); + $builder->addPlace('other'); + $builder->addTransition(new Transition('to_send_external', 'initial', 'send_external')); + $builder->addTransition(new Transition('to_other', 'initial', 'other')); + $builder->setMetadataStore( + new InMemoryMetadataStore( + placesMetadata: [ + 'send_external' => [ + 'isSentExternal' => true, + ], + ] + ) + ); + $definition = $builder->build(); + $workflow = new Workflow($definition, new EntityWorkflowMarkingStore(), $eventDispatcher = new EventDispatcher(), 'dummy'); + $registry = new Registry(); + $registry->addWorkflow($workflow, new class () implements WorkflowSupportStrategyInterface { + public function supports(\Symfony\Component\Workflow\WorkflowInterface $workflow, object $subject): bool + { + return true; + } + }); + + $eventSubscriber = new EntityWorkflowGuardSendExternalIfNoPublicView( + $registry, + new EntityWorkflowManager([$handler], $registry) + ); + $eventDispatcher->addSubscriber($eventSubscriber); + + return $registry; + } +} diff --git a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/EntityWorkflowGuardSendExternalIfNoPublicView.php b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/EntityWorkflowGuardSendExternalIfNoPublicView.php new file mode 100644 index 000000000..558d7b0ab --- /dev/null +++ b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/EntityWorkflowGuardSendExternalIfNoPublicView.php @@ -0,0 +1,57 @@ + [ + ['guardSendExternalIfNoStoredObject', 0], + ]]; + } + + public function guardSendExternalIfNoStoredObject(GuardEvent $event) + { + $entityWorkflow = $event->getSubject(); + if (!$entityWorkflow instanceof EntityWorkflow) { + return; + } + + $workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName()); + + foreach ($event->getTransition()->getTos() as $to) { + $metadata = $workflow->getMetadataStore()->getPlaceMetadata($to); + if (true === ($metadata['isSentExternal'] ?? false) + && !$this->entityWorkflowManager->getHandler($entityWorkflow) instanceof EntityWorkflowWithPublicViewInterface) { + $event->addTransitionBlocker( + new TransitionBlocker( + 'No document associated with this entityWorkflow, not able to send external', + 'a95e57d8-9136-11ef-a208-43b111cfc66d' + ) + ); + + return; + } + } + } +}