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:
|
||||
type: object
|
||||
properties:
|
||||
addresses:
|
||||
addressees:
|
||||
type: array
|
||||
items:
|
||||
oneOf:
|
||||
@ -129,3 +129,35 @@ paths:
|
||||
422:
|
||||
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\UserGroup;
|
||||
use Chill\MainBundle\Validation\Constraint\UserGroupDoNotExclude;
|
||||
use Chill\TicketBundle\Entity\Ticket;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Validator\Constraints\GreaterThan;
|
||||
|
||||
@ -28,4 +29,12 @@ final readonly class SetAddresseesCommand
|
||||
#[Groups(['read'])]
|
||||
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;
|
||||
|
||||
use Chill\TicketBundle\Action\Ticket\AddAddresseeCommand;
|
||||
use Chill\TicketBundle\Action\Ticket\Handler\SetAddresseesCommandHandler;
|
||||
use Chill\TicketBundle\Action\Ticket\SetAddresseesCommand;
|
||||
use Chill\TicketBundle\Entity\Ticket;
|
||||
@ -44,6 +45,23 @@ final readonly class SetAddresseesController
|
||||
|
||||
$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))) {
|
||||
return new JsonResponse(
|
||||
$this->serializer->serialize($errors, 'json'),
|
||||
|
@ -85,6 +85,70 @@ class SetAddresseesControllerTest extends KernelTestCase
|
||||
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
|
||||
{
|
||||
self::bootKernel();
|
||||
|
Loading…
x
Reference in New Issue
Block a user