Skip to content

Commit

Permalink
add workflow test #3619
Browse files Browse the repository at this point in the history
  • Loading branch information
sfinx13 committed Feb 4, 2025
1 parent 70c9c74 commit d163a5c
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/Event/AffectationClosedEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Event;

use App\Entity\Affectation;
use App\Entity\User;

class AffectationClosedEvent
{
public const string NAME = 'affectation.closed';

public function __construct(
private readonly Affectation $affectation,
private readonly User $user,
private readonly ?string $message = null,
) {
}

public function getAffectation(): Affectation
{
return $this->affectation;
}

public function getUser(): User
{
return $this->user;
}

public function getMessage(): ?string
{
return $this->message;
}
}
79 changes: 79 additions & 0 deletions src/EventSubscriber/AffectationClosedSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace App\EventSubscriber;

use App\Entity\Partner;
use App\Entity\Signalement;
use App\Entity\Suivi;
use App\Event\AffectationClosedEvent;
use App\Manager\SignalementManager;
use App\Manager\SuiviManager;
use App\Repository\SignalementRepository;
use App\Service\Mailer\NotificationMail;
use App\Service\Mailer\NotificationMailerRegistry;
use App\Service\Mailer\NotificationMailerType;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

readonly class AffectationClosedSubscriber implements EventSubscriberInterface
{
public function __construct(
private NotificationMailerRegistry $notificationMailerRegistry,
private SignalementManager $signalementManager,
private SuiviManager $suiviManager,
) {
}

public static function getSubscribedEvents(): array
{
return [
AffectationClosedEvent::NAME => 'onAffectationClosed',
];
}

public function onAffectationClosed(AffectationClosedEvent $event): void
{
$user = $event->getUser();
$affectation = $event->getAffectation();
$signalement = $affectation->getSignalement();
$params['subject'] = $affectation->getPartner()->getNom();
$params['motif_cloture'] = $affectation->getMotifCloture();
$params['motif_suivi'] = $event->getMessage();
$suivi = $this->suiviManager->createSuivi(
signalement: $signalement,
description: SuiviManager::buildDescriptionClotureSignalement($params),
type: Suivi::TYPE_PARTNER,
user: $user,
);

$signalement->addSuivi($suivi);
$this->sendMailToPartner(
signalement: $signalement,
partnerToExclude: $user->getPartnerInTerritoryOrFirstOne($signalement->getTerritory())
);

$this->signalementManager->save($signalement);
}

private function sendMailToPartner(Signalement $signalement, ?Partner $partnerToExclude = null): void
{
/** @var SignalementRepository $signalementRepository */
$signalementRepository = $this->signalementManager->getRepository();
$sendTo = $signalementRepository->findUsersPartnerEmailAffectedToSignalement(
$signalement->getId(),
$partnerToExclude
);

if (empty($sendTo)) {
return;
}

$this->notificationMailerRegistry->send(
new NotificationMail(
type: NotificationMailerType::TYPE_SIGNALEMENT_CLOSED_TO_PARTNER,
to: $sendTo,
territory: $signalement->getTerritory(),
signalement: $signalement,
)
);
}
}
35 changes: 35 additions & 0 deletions src/Exception/Suivi/UsagerNotificationRequiredException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace App\Exception\Suivi;

class UsagerNotificationRequiredException extends \Exception
{
private mixed $value;

private array $errors;

public function __construct(
mixed $value = null,
string $message = 'Vous voulez réouvrir pour le partenaire, un suivi de réouverture va être crée. Vous devez indiquer si vous souhaitez notifier l\'usager.',
int $code = 0, ?\Throwable $previous = null,
) {
$this->value = $value;
$this->errors = [
[
'property' => 'notifyUsager',
'message' => 'Veuillez renseigner la valeur true ou false.',
],
];
parent::__construct($message, $code, $previous);
}

public function getValue(): mixed
{
return $this->value;
}

public function getErrors(): array
{
return $this->errors;
}
}
135 changes: 135 additions & 0 deletions tests/Functional/Controller/Api/AffectationUpdateControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

namespace App\Tests\Functional\Controller\Api;

use App\Entity\Affectation;
use App\Entity\Enum\AffectationStatus;
use App\Repository\SignalementRepository;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\Collection;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class AffectationUpdateControllerTest extends WebTestCase
{
/**
* @dataProvider provideValidTransitionData
*/
public function testValidWorkflow(string $signalementUuid, array $payload, string $statut, int $mailSent): void
{
$client = static::createClient();
$user = self::getContainer()->get(UserRepository::class)->findOneBy([
'email' => '[email protected]',
]);

$signalementRepository = self::getContainer()->get(SignalementRepository::class);
$signalement = $signalementRepository->findOneBy(['uuid' => $signalementUuid]);
/** @var Collection $affectations */
$affectations = $signalement->getAffectations();

/** @var Affectation $affectation */
$affectation = $affectations->filter(function (Affectation $affectation) {
return 'Partenaire 13-01' === $affectation->getPartner()->getNom();
})->current();

$client->loginUser($user, 'api');
$client->request(
method: 'PATCH',
uri: '/api/affectations/'.$affectation->getUuid(),
server: ['CONTENT_TYPE' => 'application/json'],
content: json_encode($payload)
);

$this->assertResponseIsSuccessful();
$this->assertEquals($statut, AffectationStatus::mapNewStatus($affectation->getStatut())->value);
$this->assertEmailCount($mailSent);
}

/** @dataProvider provideUnvalidTransitionData */
public function testInvalidWorkflow(string $signalementUuid, array $payload): void
{
$client = static::createClient();
$user = self::getContainer()->get(UserRepository::class)->findOneBy([
'email' => '[email protected]',
]);

$signalementRepository = self::getContainer()->get(SignalementRepository::class);
$signalement = $signalementRepository->findOneBy(['uuid' => $signalementUuid]);
/** @var Collection $affectations */
$affectations = $signalement->getAffectations();

/** @var Affectation $affectation */
$affectation = $affectations->filter(function (Affectation $affectation) {
return 'Partenaire 13-01' === $affectation->getPartner()->getNom();
})->current();

$client->loginUser($user, 'api');
$client->request(
method: 'PATCH',
uri: '/api/affectations/'.$affectation->getUuid(),
server: ['CONTENT_TYPE' => 'application/json'],
content: json_encode($payload)
);

$response = json_decode($client->getResponse()->getContent(), true);
$this->assertEquals(403, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('Cette transition n\'est pas valide', $response['message']);
}

public function provideValidTransitionData(): \Generator
{
yield 'NOUVEAU ==> EN_COURS' => [
'00000000-0000-0000-2022-000000000001',
[
'statut' => 'EN_COURS',
],
'EN_COURS',
0,
];
yield 'EN_COURS ==> FERME' => [
'00000000-0000-0000-2022-000000000006',
[
'statut' => 'FERME',
'motifCloture' => 'REFUS_DE_VISITE',
'message' => 'lorem ipsum dolor sit amet',
],
'FERME',
1,
];

yield 'FERME ==> NOUVEAU' => [
'00000000-0000-0000-2023-000000000013',
[
'statut' => 'NOUVEAU',
'notifyUsager' => true,
],
'NOUVEAU',
2,
];
}

public function provideUnvalidTransitionData(): \Generator
{
yield 'NOUVEAU ==> FERME' => [
'00000000-0000-0000-2022-000000000001',
[
'statut' => 'FERME',
'motifCloture' => 'RELOGEMENT_OCCUPANT',
'message' => 'Hello world buddy!!!!',
],
];
yield 'EN_COURS ==> NOUVEAU' => [
'00000000-0000-0000-2022-000000000006',
[
'statut' => 'NOUVEAU',
'notifyUsager' => true,
],
];

yield 'FERME ==> EN_COURS' => [
'00000000-0000-0000-2023-000000000013',
[
'statut' => 'EN_COURS',
],
];
}
}

0 comments on commit d163a5c

Please sign in to comment.