mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-18 16:24:24 +00:00
Add functionality to add single addressee to tickets
This update introduces a new feature allowing end-users to add a single addressee to a ticket without removing the existing ones. This was achieved by adding a new API endpoint and updating the SetAddresseesController to handle the addition of a single addressee. Accompanying tests have also been provided to ensure the new feature works as expected.
This commit is contained in:
parent
b434d38091
commit
fa67835690
@ -115,7 +115,7 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
addresses:
|
addressees:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
oneOf:
|
oneOf:
|
||||||
@ -129,3 +129,35 @@ paths:
|
|||||||
422:
|
422:
|
||||||
description: "UNPROCESSABLE ENTITY"
|
description: "UNPROCESSABLE ENTITY"
|
||||||
|
|
||||||
|
/1.0/ticket/{id}/addressee/add:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- ticket
|
||||||
|
summary: Add an addressee to a ticket, without removing existing ones.
|
||||||
|
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:
|
||||||
|
addressee:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/UserGroupById'
|
||||||
|
- $ref: '#/components/schemas/UserById'
|
||||||
|
|
||||||
|
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: "ACCEPTED"
|
||||||
|
422:
|
||||||
|
description: "UNPROCESSABLE ENTITY"
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
<?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\TicketBundle\Action\Ticket;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Entity\UserGroup;
|
||||||
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a single addressee to the ticket.
|
||||||
|
*
|
||||||
|
* This command is converted into an "SetAddresseesCommand" for handling
|
||||||
|
*/
|
||||||
|
final readonly class AddAddresseeCommand
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
#[Groups(['read'])]
|
||||||
|
public User|UserGroup $addressee
|
||||||
|
) {}
|
||||||
|
}
|
@ -14,6 +14,7 @@ namespace Chill\TicketBundle\Action\Ticket;
|
|||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Entity\UserGroup;
|
use Chill\MainBundle\Entity\UserGroup;
|
||||||
use Chill\MainBundle\Validation\Constraint\UserGroupDoNotExclude;
|
use Chill\MainBundle\Validation\Constraint\UserGroupDoNotExclude;
|
||||||
|
use Chill\TicketBundle\Entity\Ticket;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
use Symfony\Component\Validator\Constraints\GreaterThan;
|
use Symfony\Component\Validator\Constraints\GreaterThan;
|
||||||
|
|
||||||
@ -28,4 +29,12 @@ final readonly class SetAddresseesCommand
|
|||||||
#[Groups(['read'])]
|
#[Groups(['read'])]
|
||||||
public array $addressees
|
public array $addressees
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
public static function fromAddAddresseeCommand(AddAddresseeCommand $command, Ticket $ticket): self
|
||||||
|
{
|
||||||
|
return new self([
|
||||||
|
$command->addressee,
|
||||||
|
...$ticket->getCurrentAddressee(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\TicketBundle\Controller;
|
namespace Chill\TicketBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\TicketBundle\Action\Ticket\AddAddresseeCommand;
|
||||||
use Chill\TicketBundle\Action\Ticket\Handler\SetAddresseesCommandHandler;
|
use Chill\TicketBundle\Action\Ticket\Handler\SetAddresseesCommandHandler;
|
||||||
use Chill\TicketBundle\Action\Ticket\SetAddresseesCommand;
|
use Chill\TicketBundle\Action\Ticket\SetAddresseesCommand;
|
||||||
use Chill\TicketBundle\Entity\Ticket;
|
use Chill\TicketBundle\Entity\Ticket;
|
||||||
@ -28,11 +29,11 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|||||||
final readonly class SetAddresseesController
|
final readonly class SetAddresseesController
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private Security $security,
|
private Security $security,
|
||||||
private EntityManagerInterface $entityManager,
|
private EntityManagerInterface $entityManager,
|
||||||
private SerializerInterface $serializer,
|
private SerializerInterface $serializer,
|
||||||
private SetAddresseesCommandHandler $addressesCommandHandler,
|
private SetAddresseesCommandHandler $addressesCommandHandler,
|
||||||
private ValidatorInterface $validator,
|
private ValidatorInterface $validator,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[Route('/api/1.0/ticket/{id}/addressees/set', methods: ['POST'])]
|
#[Route('/api/1.0/ticket/{id}/addressees/set', methods: ['POST'])]
|
||||||
@ -44,6 +45,23 @@ final readonly class SetAddresseesController
|
|||||||
|
|
||||||
$command = $this->serializer->deserialize($request->getContent(), SetAddresseesCommand::class, 'json', [AbstractNormalizer::GROUPS => ['read']]);
|
$command = $this->serializer->deserialize($request->getContent(), SetAddresseesCommand::class, 'json', [AbstractNormalizer::GROUPS => ['read']]);
|
||||||
|
|
||||||
|
return $this->registerSetAddressees($command, $ticket);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/api/1.0/ticket/{id}/addressee/add', methods: ['POST'])]
|
||||||
|
public function addAddressee(Ticket $ticket, Request $request): Response
|
||||||
|
{
|
||||||
|
if (!$this->security->isGranted('ROLE_USER')) {
|
||||||
|
throw new AccessDeniedHttpException('Only users can add addressees.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$command = $this->serializer->deserialize($request->getContent(), AddAddresseeCommand::class, 'json', [AbstractNormalizer::GROUPS => ['read']]);
|
||||||
|
|
||||||
|
return $this->registerSetAddressees(SetAddresseesCommand::fromAddAddresseeCommand($command, $ticket), $ticket);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function registerSetAddressees(SetAddresseesCommand $command, Ticket $ticket): Response
|
||||||
|
{
|
||||||
if (0 < count($errors = $this->validator->validate($command))) {
|
if (0 < count($errors = $this->validator->validate($command))) {
|
||||||
return new JsonResponse(
|
return new JsonResponse(
|
||||||
$this->serializer->serialize($errors, 'json'),
|
$this->serializer->serialize($errors, 'json'),
|
||||||
|
@ -85,6 +85,70 @@ class SetAddresseesControllerTest extends KernelTestCase
|
|||||||
self::assertGreaterThan(0, count($asArray['violations']));
|
self::assertGreaterThan(0, count($asArray['violations']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getContentDataUnique
|
||||||
|
*/
|
||||||
|
public function testAddAddresseeWithValidData(array $bodyAsArray): void
|
||||||
|
{
|
||||||
|
$controller = $this->buildController(true, true);
|
||||||
|
$request = new Request(content: json_encode(['addressee' => $bodyAsArray], JSON_THROW_ON_ERROR, 512));
|
||||||
|
$ticket = new Ticket();
|
||||||
|
|
||||||
|
$response = $controller->addAddressee($ticket, $request);
|
||||||
|
|
||||||
|
self::assertEquals(200, $response->getStatusCode());
|
||||||
|
|
||||||
|
$asArray = json_decode($response->getContent(), true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
self::assertIsArray($asArray);
|
||||||
|
self::assertArrayHasKey('type', $asArray);
|
||||||
|
self::assertEquals('ticket_ticket', $asArray['type']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \JsonException
|
||||||
|
*
|
||||||
|
* @dataProvider getContentDataUnique
|
||||||
|
*/
|
||||||
|
public function testAddAddresseeWithInvalidData(array $bodyAsArray): void
|
||||||
|
{
|
||||||
|
$controller = $this->buildController(false, false);
|
||||||
|
$request = new Request(content: json_encode(['addressee' => $bodyAsArray], JSON_THROW_ON_ERROR, 512));
|
||||||
|
$ticket = new Ticket();
|
||||||
|
|
||||||
|
$response = $controller->addAddressee($ticket, $request);
|
||||||
|
|
||||||
|
self::assertEquals(422, $response->getStatusCode());
|
||||||
|
|
||||||
|
$asArray = json_decode($response->getContent(), true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
self::assertIsArray($asArray);
|
||||||
|
self::arrayHasKey('violations', $asArray);
|
||||||
|
self::assertGreaterThan(0, count($asArray['violations']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getContentDataUnique(): iterable
|
||||||
|
{
|
||||||
|
$entityManager = self::getContainer()->get(EntityManagerInterface::class);
|
||||||
|
|
||||||
|
$userGroup = $entityManager->createQuery('SELECT ug FROM '.UserGroup::class.' ug ')
|
||||||
|
->setMaxResults(1)->getOneOrNullResult();
|
||||||
|
|
||||||
|
if (null === $userGroup) {
|
||||||
|
throw new \RuntimeException('User group not existing in database');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $entityManager->createQuery('SELECT u FROM '.User::class.' u')
|
||||||
|
->setMaxResults(1)->getOneOrNullResult();
|
||||||
|
|
||||||
|
if (null === $user) {
|
||||||
|
throw new \RuntimeException('User not existing in database');
|
||||||
|
}
|
||||||
|
|
||||||
|
self::ensureKernelShutdown();
|
||||||
|
|
||||||
|
yield [['type' => 'user', 'id' => $user->getId()]];
|
||||||
|
yield [['type' => 'user_group', 'id' => $userGroup->getId()]];
|
||||||
|
}
|
||||||
|
|
||||||
public static function getContentData(): iterable
|
public static function getContentData(): iterable
|
||||||
{
|
{
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user