Add notification to user groups on workflow transition

Implemented NotificationToUserGroupsOnTransition to send group emails upon workflow completion. Also updated NotificationOnTransition to prevent double notifications and created a unit test for the new functionality.
This commit is contained in:
2024-10-18 19:25:03 +02:00
parent 29fa086fde
commit 91a4b45607
4 changed files with 247 additions and 2 deletions

View File

@@ -0,0 +1,141 @@
<?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\EventSubscriber;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserGroup;
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
use Chill\MainBundle\Workflow\EntityWorkflowMarkingStore;
use Chill\MainBundle\Workflow\EventSubscriber\NotificationToUserGroupsOnTransition;
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\BodyRendererInterface;
use Symfony\Component\Mime\RawMessage;
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;
use Twig\Environment;
/**
* @internal
*
* @coversNothing
*/
class NotificationToUserGroupsOnTransitionTest extends KernelTestCase
{
use ProphecyTrait;
private Environment $twig;
private BodyRendererInterface $bodyRenderer;
protected function setUp(): void
{
self::bootKernel();
$this->twig = self::getContainer()->get('twig');
$this->bodyRenderer = self::getContainer()->get(BodyRendererInterface::class);
}
public function testOnCompletedSendNotificationToUserGroupWithEmailAddress(): void
{
$entityWorkflow = new EntityWorkflow();
$reflection = new \ReflectionClass($entityWorkflow);
$idProperty = $reflection->getProperty('id');
$idProperty->setValue($entityWorkflow, 1);
$entityWorkflow->setWorkflowName('dummy');
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
$dto->futureDestUsers = [$ug = new UserGroup()];
$ug->setEmail('test@email.com')->setLabel(['fr' => 'test group']);
$mailer = $this->prophesize(MailerInterface::class);
$sendMethod = $mailer->send(Argument::that(function (RawMessage $message): bool {
if (!$message instanceof TemplatedEmail) {
return false;
}
$this->bodyRenderer->render($message);
return 'test@email.com' === $message->getTo()[0]->getAddress();
}));
$sendMethod->shouldBeCalledOnce();
$metadataExtractor = $this->prophesize(MetadataExtractor::class);
$metadataExtractor->buildArrayPresentationForWorkflow(Argument::type(Workflow::class))->willReturn(['name' => 'dummy', 'text' => 'Dummy Workflow']);
$metadataExtractor->buildArrayPresentationForPlace($entityWorkflow)->willReturn(['name' => 'to_one', 'text' => 'Dummy Place']);
$registry = $this->buildRegistryWithEventSubscriber($mailer->reveal(), $metadataExtractor->reveal());
$workflow = $registry->get($entityWorkflow, 'dummy');
$workflow->apply($entityWorkflow, 'to_one', ['context' => $dto, 'transition' => 'to_one', 'transitionAt' => new \DateTimeImmutable(), 'byUser' => new User()]);
}
public function testOnCompletedSendNotificationToUserGroupWithoutAnyEmailAddress(): void
{
$entityWorkflow = new EntityWorkflow();
$reflection = new \ReflectionClass($entityWorkflow);
$idProperty = $reflection->getProperty('id');
$idProperty->setValue($entityWorkflow, 1);
$entityWorkflow->setWorkflowName('dummy');
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
$dto->futureDestUsers = [$ug = new UserGroup()];
$mailer = $this->prophesize(MailerInterface::class);
$mailer->send(Argument::any())->shouldNotBeCalled();
$metadataExtractor = $this->prophesize(MetadataExtractor::class);
$metadataExtractor->buildArrayPresentationForWorkflow(Argument::type(Workflow::class))->willReturn(['name' => 'dummy', 'text' => 'Dummy Workflow']);
$metadataExtractor->buildArrayPresentationForPlace($entityWorkflow)->willReturn(['name' => 'to_one', 'text' => 'Dummy Place']);
$registry = $this->buildRegistryWithEventSubscriber($mailer->reveal(), $metadataExtractor->reveal());
$workflow = $registry->get($entityWorkflow, 'dummy');
$workflow->apply($entityWorkflow, 'to_one', ['context' => $dto, 'transition' => 'to_one', 'transitionAt' => new \DateTimeImmutable(), 'byUser' => new User()]);
}
public function buildRegistryWithEventSubscriber(MailerInterface $mailer, MetadataExtractor $metadataExtractor): Registry
{
$builder = new DefinitionBuilder();
$builder
->setInitialPlaces('initial')
->addPlaces(['initial', 'to_one'])
->addTransition(new Transition('to_one', 'initial', 'to_one'));
$metadata = new InMemoryMetadataStore(
['label' => ['fr' => 'dummy workflow']],
);
$builder->setMetadataStore($metadata);
$workflow = new Workflow($builder->build(), new EntityWorkflowMarkingStore(), $eventDispatcher = new EventDispatcher(), 'dummy');
$registry = new Registry();
$registry->addWorkflow($workflow, new class () implements WorkflowSupportStrategyInterface {
public function supports(WorkflowInterface $workflow, object $subject): bool
{
return true;
}
});
$notificationEventSubscriber = new NotificationToUserGroupsOnTransition($this->twig, $metadataExtractor, $registry, $mailer);
$eventDispatcher->addSubscriber($notificationEventSubscriber);
return $registry;
}
}