diff --git a/src/Bundle/ChillMainBundle/Controller/UserGroupApiController.php b/src/Bundle/ChillMainBundle/Controller/UserGroupApiController.php new file mode 100644 index 000000000..602b84ec5 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/UserGroupApiController.php @@ -0,0 +1,16 @@ +getRepository(User::class)->findOneBy(['username' => 'center a_social']); + $centerBSocial = $manager->getRepository(User::class)->findOneBy(['username' => 'center b_social']); + $multiCenter = $manager->getRepository(User::class)->findOneBy(['username' => 'multi_center']); + $administrativeA = $manager->getRepository(User::class)->findOneBy(['username' => 'center a_administrative']); + $administrativeB = $manager->getRepository(User::class)->findOneBy(['username' => 'center b_administrative']); + + $level1 = $this->generateLevelGroup('Niveau 1', '#eec84aff', '#000000ff', 'level'); + $level1->addUser($centerASocial)->addUser($centerBSocial); + $manager->persist($level1); + + $level2 = $this->generateLevelGroup('Niveau 2', ' #e2793dff', '#000000ff', 'level'); + $level2->addUser($multiCenter); + $manager->persist($level2); + + $level3 = $this->generateLevelGroup('Niveau 3', ' #df4949ff', '#000000ff', 'level'); + $level3->addUser($multiCenter); + $manager->persist($level3); + + $tss = $this->generateLevelGroup('Travailleur sociaux', '#43b29dff', '#000000ff', ''); + $tss->addUser($multiCenter)->addUser($centerASocial)->addUser($centerBSocial); + $manager->persist($tss); + $admins = $this->generateLevelGroup('Administratif', '#334d5cff', '#000000ff', ''); + $admins->addUser($administrativeA)->addUser($administrativeB); + $manager->persist($admins); + + $manager->flush(); + } + + private function generateLevelGroup(string $title, string $backgroundColor, string $foregroundColor, string $excludeKey): UserGroup + { + $userGroup = new UserGroup(); + + return $userGroup + ->setLabel(['fr' => $title]) + ->setBackgroundColor($backgroundColor) + ->setForegroundColor($foregroundColor) + ->setExcludeKey($excludeKey) + ; + } +} diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index 4dde2076c..3170cadee 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -24,6 +24,7 @@ use Chill\MainBundle\Controller\LocationTypeController; use Chill\MainBundle\Controller\NewsItemController; use Chill\MainBundle\Controller\RegroupmentController; use Chill\MainBundle\Controller\UserController; +use Chill\MainBundle\Controller\UserGroupApiController; use Chill\MainBundle\Controller\UserJobApiController; use Chill\MainBundle\Controller\UserJobController; use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface; @@ -59,6 +60,7 @@ use Chill\MainBundle\Entity\LocationType; use Chill\MainBundle\Entity\NewsItem; use Chill\MainBundle\Entity\Regroupment; use Chill\MainBundle\Entity\User; +use Chill\MainBundle\Entity\UserGroup; use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Form\CenterType; use Chill\MainBundle\Form\CivilityType; @@ -803,6 +805,21 @@ class ChillMainExtension extends Extension implements ], ], ], + [ + 'class' => UserGroup::class, + 'controller' => UserGroupApiController::class, + 'name' => 'user-group', + 'base_path' => '/api/1.0/main/user-group', + 'base_role' => 'ROLE_USER', + 'actions' => [ + '_index' => [ + 'methods' => [ + Request::METHOD_GET => true, + Request::METHOD_HEAD => true, + ], + ], + ], + ], ], ]); } diff --git a/src/Bundle/ChillMainBundle/Entity/UserGroup.php b/src/Bundle/ChillMainBundle/Entity/UserGroup.php index 3bd9870a6..470a21a70 100644 --- a/src/Bundle/ChillMainBundle/Entity/UserGroup.php +++ b/src/Bundle/ChillMainBundle/Entity/UserGroup.php @@ -14,17 +14,21 @@ namespace Chill\MainBundle\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Serializer\Annotation as Serializer; #[ORM\Entity] #[ORM\Table(name: 'chill_main_user_group')] +#[Serializer\DiscriminatorMap(typeProperty: 'type', mapping: ['user_group' => UserGroup::class])] class UserGroup { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER, nullable: false)] + #[Serializer\Groups(['read'])] private ?int $id = null; #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON, nullable: false, options: ['default' => '[]'])] + #[Serializer\Groups(['read'])] private array $label = []; /** @@ -34,6 +38,24 @@ class UserGroup #[ORM\JoinTable(name: 'chill_main_user_group_user')] private Collection $users; + #[ORM\Column(type: 'text', nullable: false, options: ['default' => '#ffffffff'])] + #[Serializer\Groups(['read'])] + private string $backgroundColor = '#ffffffff'; + + #[ORM\Column(type: 'text', nullable: false, options: ['default' => '#000000ff'])] + #[Serializer\Groups(['read'])] + private string $foregroundColor = '#000000ff'; + + /** + * Groups with same exclude key are mutually exclusive: adding one in a many-to-one relationship + * will exclude others. + * + * An empty string means "no exclusion" + */ + #[ORM\Column(type: 'text', nullable: false, options: ['default' => ''])] + #[Serializer\Groups(['read'])] + private string $excludeKey = ''; + public function __construct() { $this->users = new ArrayCollection(); @@ -71,4 +93,47 @@ class UserGroup { return $this->users; } + + public function getForegroundColor(): string + { + return $this->foregroundColor; + } + + public function getExcludeKey(): string + { + return $this->excludeKey; + } + + public function getBackgroundColor(): string + { + return $this->backgroundColor; + } + + public function setForegroundColor(string $foregroundColor): self + { + $this->foregroundColor = $foregroundColor; + + return $this; + } + + public function setBackgroundColor(string $backgroundColor): self + { + $this->backgroundColor = $backgroundColor; + + return $this; + } + + public function setExcludeKey(string $excludeKey): self + { + $this->excludeKey = $excludeKey; + + return $this; + } + + public function setLabel(array $label): self + { + $this->label = $label; + + return $this; + } } diff --git a/src/Bundle/ChillMainBundle/Resources/public/types.ts b/src/Bundle/ChillMainBundle/Resources/public/types.ts index 2e33b8248..840a0e939 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/types.ts +++ b/src/Bundle/ChillMainBundle/Resources/public/types.ts @@ -42,6 +42,15 @@ export interface User { // todo: mainCenter; mainJob; etc.. } +export interface UserGroup { + type: "chill_main_user_group", + id: number, + label: TranslatableString, + backgroundColor: string, + foregroundColor: string, + excludeKey: string, +} + export interface UserAssociatedInterface { type: "user"; id: number; diff --git a/src/Bundle/ChillMainBundle/Tests/Validation/Validator/UserGroupDoNotExcludeTest.php b/src/Bundle/ChillMainBundle/Tests/Validation/Validator/UserGroupDoNotExcludeTest.php new file mode 100644 index 000000000..d6d1c9887 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Tests/Validation/Validator/UserGroupDoNotExcludeTest.php @@ -0,0 +1,91 @@ +validator->validate([], new \Chill\MainBundle\Validation\Constraint\UserGroupDoNotExclude()); + + $this->assertNoViolation(); + } + + public function testMixedUserGroupAndUsersIsValid(): void + { + $this->validator->validate( + [new User(), new UserGroup()], + new \Chill\MainBundle\Validation\Constraint\UserGroupDoNotExclude() + ); + + $this->assertNoViolation(); + } + + public function testDifferentExcludeKeysIsValid(): void + { + $this->validator->validate( + [(new UserGroup())->setExcludeKey('A'), (new UserGroup())->setExcludeKey('B')], + new \Chill\MainBundle\Validation\Constraint\UserGroupDoNotExclude() + ); + + $this->assertNoViolation(); + } + + public function testMultipleGroupsWithEmptyExcludeKeyIsValid(): void + { + $this->validator->validate( + [(new UserGroup())->setExcludeKey(''), (new UserGroup())->setExcludeKey('')], + new \Chill\MainBundle\Validation\Constraint\UserGroupDoNotExclude() + ); + + $this->assertNoViolation(); + } + + public function testSameExclusionKeyWillRaiseError(): void + { + $this->validator->validate( + [ + (new UserGroup())->setExcludeKey('A')->setLabel(['fr' => 'Group 1']), + (new UserGroup())->setExcludeKey('A')->setLabel(['fr' => 'Group 2']), + ], + new \Chill\MainBundle\Validation\Constraint\UserGroupDoNotExclude() + ); + + $this->buildViolation('The groups {{ excluded_groups }} do exclude themselves. Please choose one between them') + ->setParameter('excluded_groups', 'Group 1, Group 2') + ->setCode('e16c8226-0090-11ef-8560-f7239594db09') + ->assertRaised(); + } +} diff --git a/src/Bundle/ChillMainBundle/Validation/Constraint/UserGroupDoNotExclude.php b/src/Bundle/ChillMainBundle/Validation/Constraint/UserGroupDoNotExclude.php new file mode 100644 index 000000000..5ec688e5b --- /dev/null +++ b/src/Bundle/ChillMainBundle/Validation/Constraint/UserGroupDoNotExclude.php @@ -0,0 +1,31 @@ +getExcludeKey()][] = $gr; + } + } + + foreach ($groups as $excludeKey => $groupByKey) { + if ('' === $excludeKey) { + continue; + } + + if (1 < count($groupByKey)) { + $excludedGroups = implode( + ', ', + array_map( + fn (UserGroup $group) => $this->translatableStringHelper->localize($group->getLabel()), + $groupByKey + ) + ); + + $this->context + ->buildViolation($constraint->message) + ->setCode($constraint->code) + ->setParameters(['excluded_groups' => $excludedGroups]) + ->addViolation(); + } + } + } +} diff --git a/src/Bundle/ChillMainBundle/chill.api.specs.yaml b/src/Bundle/ChillMainBundle/chill.api.specs.yaml index f37ee723d..fec36312d 100644 --- a/src/Bundle/ChillMainBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillMainBundle/chill.api.specs.yaml @@ -908,3 +908,19 @@ paths: $ref: '#/components/schemas/NewsItem' 403: description: "Unauthorized" + /1.0/main/user-group.json: + get: + tags: + - user-group + summary: Return a list of users-groups + responses: + 200: + description: "ok" + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/NewsItem' + 403: + description: "Unauthorized" diff --git a/src/Bundle/ChillMainBundle/migrations/Version20240422091752.php b/src/Bundle/ChillMainBundle/migrations/Version20240422091752.php new file mode 100644 index 000000000..960b3cc79 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20240422091752.php @@ -0,0 +1,41 @@ +addSql('ALTER TABLE chill_main_user_group ADD backgroundColor TEXT DEFAULT \'#ffffffff\' NOT NULL'); + $this->addSql('ALTER TABLE chill_main_user_group ADD foregroundColor TEXT DEFAULT \'#000000ff\' NOT NULL'); + $this->addSql('ALTER TABLE chill_main_user_group ADD excludeKey TEXT DEFAULT \'\' NOT NULL'); + $this->addSql('ALTER INDEX idx_1e07f044d2112630 RENAME TO IDX_738BC82BD2112630'); + $this->addSql('ALTER INDEX idx_1e07f044a76ed395 RENAME TO IDX_738BC82BA76ED395'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_main_user_group DROP backgroundColor'); + $this->addSql('ALTER TABLE chill_main_user_group DROP foregroundColor'); + $this->addSql('ALTER TABLE chill_main_user_group DROP excludeKey'); + $this->addSql('ALTER INDEX idx_738bc82bd2112630 RENAME TO idx_1e07f044d2112630'); + $this->addSql('ALTER INDEX idx_738bc82ba76ed395 RENAME TO idx_1e07f044a76ed395'); + } +} diff --git a/src/Bundle/ChillTicketBundle/chill.api.specs.yaml b/src/Bundle/ChillTicketBundle/chill.api.specs.yaml index ce53732ff..86049cc24 100644 --- a/src/Bundle/ChillTicketBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillTicketBundle/chill.api.specs.yaml @@ -64,3 +64,32 @@ paths: description: "ACCEPTED" 422: description: "UNPROCESSABLE ENTITY" + + /1.0/ticket/{id}/comment/add: + post: + tags: + - ticket + summary: Add a comment to an existing ticket + parameters: + - name: id + in: path + required: true + description: The ticket id + schema: + type: integer + format: integer + minimum: 1 + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + content: + type: string + responses: + 201: + description: "ACCEPTED" + 422: + description: "UNPROCESSABLE ENTITY" diff --git a/src/Bundle/ChillTicketBundle/src/Action/Ticket/AddCommentCommand.php b/src/Bundle/ChillTicketBundle/src/Action/Ticket/AddCommentCommand.php new file mode 100644 index 000000000..1c009cfc8 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Action/Ticket/AddCommentCommand.php @@ -0,0 +1,25 @@ +content, $ticket); + + $this->entityManager->persist($comment); + } +} diff --git a/src/Bundle/ChillTicketBundle/src/Controller/AddCommentController.php b/src/Bundle/ChillTicketBundle/src/Controller/AddCommentController.php new file mode 100644 index 000000000..157e69698 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Controller/AddCommentController.php @@ -0,0 +1,68 @@ +security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException('Only user can add ticket comments.'); + } + + $command = $this->serializer->deserialize($request->getContent(), AddCommentCommand::class, 'json', ['groups' => 'write']); + + $errors = $this->validator->validate($command); + + if (count($errors) > 0) { + return new JsonResponse( + $this->serializer->serialize($errors, 'json'), + Response::HTTP_UNPROCESSABLE_ENTITY, + [], + true + ); + } + + $this->addCommentCommandHandler->handle($ticket, $command); + + $this->entityManager->flush(); + + return new JsonResponse( + $this->serializer->serialize($ticket, 'json', ['groups' => 'read']), + Response::HTTP_CREATED, + [], + true + ); + } +} diff --git a/src/Bundle/ChillTicketBundle/src/Controller/ReplaceMotiveController.php b/src/Bundle/ChillTicketBundle/src/Controller/ReplaceMotiveController.php index d6f1acf94..8af2773e8 100644 --- a/src/Bundle/ChillTicketBundle/src/Controller/ReplaceMotiveController.php +++ b/src/Bundle/ChillTicketBundle/src/Controller/ReplaceMotiveController.php @@ -59,6 +59,11 @@ final readonly class ReplaceMotiveController $this->entityManager->flush(); - return new JsonResponse(null, Response::HTTP_CREATED); + return new JsonResponse( + $this->serializer->serialize($ticket, 'json', ['groups' => 'read']), + Response::HTTP_CREATED, + [], + true + ); } } diff --git a/src/Bundle/ChillTicketBundle/src/Entity/Comment.php b/src/Bundle/ChillTicketBundle/src/Entity/Comment.php index d62e6d8b4..8e11ff489 100644 --- a/src/Bundle/ChillTicketBundle/src/Entity/Comment.php +++ b/src/Bundle/ChillTicketBundle/src/Entity/Comment.php @@ -17,9 +17,11 @@ use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait; use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping\JoinColumn; +use Symfony\Component\Serializer\Annotation as Serializer; #[ORM\Entity()] #[ORM\Table(name: 'comment', schema: 'chill_ticket')] +#[Serializer\DiscriminatorMap(typeProperty: 'type', mapping: ['ticket_comment' => Comment::class])] class Comment implements TrackCreationInterface, TrackUpdateInterface { use TrackCreationTrait; @@ -28,15 +30,19 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface #[ORM\Id] #[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER, nullable: false)] #[ORM\GeneratedValue(strategy: 'AUTO')] + #[Serializer\Groups(['read'])] private ?int $id = null; public function __construct( + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: false, options: ['default' => ''])] + #[Serializer\Groups(['read'])] + private string $content, #[ORM\ManyToOne(targetEntity: Ticket::class, inversedBy: 'comments')] #[JoinColumn(nullable: false)] private Ticket $ticket, - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: false, options: ['default' => ''])] - private string $content = '' - ) {} + ) { + $ticket->addComment($this); + } public function getId(): ?int { diff --git a/src/Bundle/ChillTicketBundle/src/Entity/Ticket.php b/src/Bundle/ChillTicketBundle/src/Entity/Ticket.php index de369379b..cd49d7377 100644 --- a/src/Bundle/ChillTicketBundle/src/Entity/Ticket.php +++ b/src/Bundle/ChillTicketBundle/src/Entity/Ticket.php @@ -104,16 +104,27 @@ class Ticket implements TrackCreationInterface, TrackUpdateInterface ->getValues(); } + /** + * @internal use @see{Comment::__construct} instead + */ + public function addComment(Comment $comment): void + { + $this->comments->add($comment); + } + /** * Add a PersonHistory. * - * This method should not be used, use @see{PersonHistory::__construct()} insted. + * @internal use @see{PersonHistory::__construct} instead */ public function addPersonHistory(PersonHistory $personHistory): void { $this->personHistories->add($personHistory); } + /** + * @internal use @see{MotiveHistory::__construct} instead + */ public function addMotiveHistory(MotiveHistory $motiveHistory): void { $this->motiveHistories->add($motiveHistory); diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/types.ts b/src/Bundle/ChillTicketBundle/src/Resources/public/types.ts index b0c6a37df..2df53da99 100644 --- a/src/Bundle/ChillTicketBundle/src/Resources/public/types.ts +++ b/src/Bundle/ChillTicketBundle/src/Resources/public/types.ts @@ -36,10 +36,21 @@ interface MotiveHistory { createdAt: DateTime|null, } +interface Comment { + type: "ticket_comment", + id: number, + content: string, + createdBy: User|null, + createdAt: DateTime|null, + updatedBy: User|null, + updatedAt: DateTime|null, +} + interface AddPersonEvent extends TicketHistory<"add_person", PersonHistory> {}; +interface AddCommentEvent extends TicketHistory<"add_comment", Comment> {}; interface SetMotiveEvent extends TicketHistory<"set_motive", MotiveHistory> {}; -type TicketHistoryLine = AddPersonEvent | SetMotiveEvent; +type TicketHistoryLine = AddPersonEvent | AddCommentEvent | SetMotiveEvent; export interface Ticket { type: "ticket_ticket" diff --git a/src/Bundle/ChillTicketBundle/src/Serializer/Normalizer/TicketNormalizer.php b/src/Bundle/ChillTicketBundle/src/Serializer/Normalizer/TicketNormalizer.php index c69ac5a7f..c68ab34ef 100644 --- a/src/Bundle/ChillTicketBundle/src/Serializer/Normalizer/TicketNormalizer.php +++ b/src/Bundle/ChillTicketBundle/src/Serializer/Normalizer/TicketNormalizer.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\TicketBundle\Serializer\Normalizer; +use Chill\TicketBundle\Entity\Comment; use Chill\TicketBundle\Entity\MotiveHistory; use Chill\TicketBundle\Entity\PersonHistory; use Chill\TicketBundle\Entity\Ticket; @@ -69,6 +70,15 @@ final class TicketNormalizer implements NormalizerInterface, NormalizerAwareInte ], $ticket->getPersonHistories()->toArray(), ), + ...array_map( + fn (Comment $comment) => [ + 'event_type' => 'add_comment', + 'at' => $comment->getCreatedAt(), + 'by' => $comment->getCreatedBy(), + 'data' => $comment, + ], + $ticket->getComments()->toArray(), + ), ]; usort( diff --git a/src/Bundle/ChillTicketBundle/tests/Action/Ticket/Handler/AddCommentCommandHandlerTest.php b/src/Bundle/ChillTicketBundle/tests/Action/Ticket/Handler/AddCommentCommandHandlerTest.php new file mode 100644 index 000000000..5ff18b436 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/tests/Action/Ticket/Handler/AddCommentCommandHandlerTest.php @@ -0,0 +1,52 @@ +buildCommand(); + + $ticket = new Ticket(); + $command = new AddCommentCommand(content: 'test'); + + $handler->handle($ticket, $command); + + self::assertCount(1, $ticket->getComments()); + self::assertEquals('test', $ticket->getComments()[0]->getContent()); + } + + private function buildCommand(): AddCommentCommandHandler + { + $entityManager = $this->prophesize(EntityManagerInterface::class); + $entityManager->persist(Argument::type(Comment::class))->shouldBeCalled(); + + return new AddCommentCommandHandler($entityManager->reveal()); + } +} diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/AddCommentControllerTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/AddCommentControllerTest.php new file mode 100644 index 000000000..2826c360d --- /dev/null +++ b/src/Bundle/ChillTicketBundle/tests/Controller/AddCommentControllerTest.php @@ -0,0 +1,104 @@ +validator = self::getContainer()->get(ValidatorInterface::class); + $this->serializer = self::getContainer()->get(SerializerInterface::class); + } + + public function testAddComment(): void + { + $controller = $this->buildController(willFlush: true); + + $ticket = new Ticket(); + $request = new Request(content: <<<'JSON' + {"content": "test"} + JSON); + + $response = $controller->__invoke($ticket, $request); + + self::assertEquals(201, $response->getStatusCode()); + } + + public function testAddCommentWithBlankContent(): void + { + $controller = $this->buildController(willFlush: false); + + $ticket = new Ticket(); + $request = new Request(content: <<<'JSON' + {"content": ""} + JSON); + + $response = $controller->__invoke($ticket, $request); + + self::assertEquals(422, $response->getStatusCode()); + + $request = new Request(content: <<<'JSON' + {"content": null} + JSON); + + $response = $controller->__invoke($ticket, $request); + + self::assertEquals(422, $response->getStatusCode()); + } + + private function buildController(bool $willFlush): AddCommentController + { + $security = $this->prophesize(Security::class); + $security->isGranted('ROLE_USER')->willReturn(true); + + $entityManager = $this->prophesize(EntityManagerInterface::class); + + if ($willFlush) { + $entityManager->persist(Argument::type(Comment::class))->shouldBeCalled(); + $entityManager->flush()->shouldBeCalled(); + } + + $commandHandler = new AddCommentCommandHandler($entityManager->reveal()); + + return new AddCommentController( + $security->reveal(), + $this->serializer, + $this->validator, + $commandHandler, + $entityManager->reveal(), + ); + } +} diff --git a/src/Bundle/ChillTicketBundle/tests/Serializer/Normalizer/TicketNormalizerTest.php b/src/Bundle/ChillTicketBundle/tests/Serializer/Normalizer/TicketNormalizerTest.php index e876341cd..447bebfbf 100644 --- a/src/Bundle/ChillTicketBundle/tests/Serializer/Normalizer/TicketNormalizerTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Serializer/Normalizer/TicketNormalizerTest.php @@ -11,7 +11,9 @@ declare(strict_types=1); namespace Chill\TicketBundle\Tests\Serializer\Normalizer; +use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\Person; +use Chill\TicketBundle\Entity\Comment; use Chill\TicketBundle\Entity\Motive; use Chill\TicketBundle\Entity\MotiveHistory; use Chill\TicketBundle\Entity\PersonHistory; @@ -93,11 +95,20 @@ class TicketNormalizerTest extends KernelTestCase // datetime $normalizer->normalize(Argument::type(\DateTimeImmutable::class), 'json', Argument::type('array')) ->will(function ($args) { return $args[0]->getTimestamp(); }); + // user + $normalizer->normalize(Argument::type(User::class), 'json', Argument::type('array')) + ->willReturn(['user']); + // motive $normalizer->normalize(Argument::type(Motive::class), 'json', Argument::type('array'))->willReturn(['type' => 'motive', 'id' => 0]); + // person history $normalizer->normalize(Argument::type(PersonHistory::class), 'json', Argument::type('array')) ->willReturn(['personHistory']); + // motive history $normalizer->normalize(Argument::type(MotiveHistory::class), 'json', Argument::type('array')) ->willReturn(['motiveHistory']); + $normalizer->normalize(Argument::type(Comment::class), 'json', Argument::type('array')) + ->willReturn(['comment']); + // null values $normalizer->normalize(null, 'json', Argument::type('array'))->willReturn(null); $ticketNormalizer = new TicketNormalizer(); @@ -109,6 +120,7 @@ class TicketNormalizerTest extends KernelTestCase public static function provideTickets(): iterable { yield [ + // this a nearly empty ticket new Ticket(), [ 'type' => 'ticket_ticket', @@ -122,10 +134,14 @@ class TicketNormalizerTest extends KernelTestCase ], ]; + // ticket with more features $ticket = new Ticket(); $ticket->setExternalRef('2134'); $personHistory = new PersonHistory(new Person(), $ticket, new \DateTimeImmutable('2024-04-01T12:00:00')); $ticketHistory = new MotiveHistory(new Motive(), $ticket, new \DateTimeImmutable('2024-04-01T12:02:00')); + $comment = new Comment('blabla test', $ticket); + $comment->setCreatedAt(new \DateTimeImmutable('2024-04-01T12:04:00')); + $comment->setCreatedBy(new User()); yield [ $ticket, @@ -137,7 +153,7 @@ class TicketNormalizerTest extends KernelTestCase 'currentAddressees' => [], 'currentInputs' => [], 'currentMotive' => ['type' => 'motive', 'id' => 0], - 'history' => [['event_type' => 'add_person'], ['event_type' => 'set_motive']], + 'history' => [['event_type' => 'add_person'], ['event_type' => 'set_motive'], ['event_type' => 'add_comment']], ], ]; }