diff --git a/src/Bundle/ChillTicketBundle/chill.api.specs.yaml b/src/Bundle/ChillTicketBundle/chill.api.specs.yaml index 199b056a2..65aec91da 100644 --- a/src/Bundle/ChillTicketBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillTicketBundle/chill.api.specs.yaml @@ -135,6 +135,25 @@ paths: **Warning**: This silently remove the filters "byCurrentState" and "byCreatedBefore". schema: type: string + - name: byAddressee + in: query + description: the id of the addressee to search for. The search is also performed against user groups. + required: false + style: form + explode: false + schema: + type: array + items: + type: integer + format: integer + minimum: 1 + - name: byAddresseeToMe + in: query + description: filter tickets assigned to the current authenticated users + required: false + allowEmptyValue: true + schema: + type: string responses: 200: description: OK diff --git a/src/Bundle/ChillTicketBundle/src/Controller/TicketListApiController.php b/src/Bundle/ChillTicketBundle/src/Controller/TicketListApiController.php index 606967cbc..a181faf82 100644 --- a/src/Bundle/ChillTicketBundle/src/Controller/TicketListApiController.php +++ b/src/Bundle/ChillTicketBundle/src/Controller/TicketListApiController.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\TicketBundle\Controller; use Chill\MainBundle\Pagination\PaginatorFactoryInterface; +use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Security\Authorization\PersonVoter; @@ -42,6 +43,7 @@ final readonly class TicketListApiController private MotiveRepository $motiveRepository, private ClockInterface $clock, ParameterBagInterface $parameterBag, + private UserRepositoryInterface $userRepository, ) { $this->expectedTimeResponseDelay = new \DateInterval($parameterBag->get('chill_ticket')['ticket']['response_time_exceeded_delay']); } @@ -56,8 +58,8 @@ final readonly class TicketListApiController $params = []; if ($request->query->has('byPerson')) { - $params = explode(',', $request->query->get('byPerson')); - foreach ($params as $id) { + $personIds = explode(',', $request->query->get('byPerson')); + foreach ($personIds as $id) { $params['byPerson'][] = $person = $this->personRepository->find($id); if (!$this->security->isGranted(PersonVoter::SEE, $person)) { @@ -89,8 +91,8 @@ final readonly class TicketListApiController } if ($request->query->has('byMotives')) { - $params = explode(',', $request->query->get('byMotives')); - foreach ($params as $id) { + $motivesIds = explode(',', $request->query->get('byMotives')); + foreach ($motivesIds as $id) { if (!is_numeric($id) || 0 === ((int) $id)) { throw new BadRequestHttpException('Only numbers are allowed in by motives parameter'); } @@ -132,6 +134,24 @@ final readonly class TicketListApiController unset($params['byCreatedAfter']); } + if ($request->query->has('byAddresseeToMe')) { + $params['byAddressee'][] = $this->security->getUser(); + } + + if ($request->query->has('byAddressee')) { + $userIds = explode(',', $request->query->get('byAddressee')); + foreach ($userIds as $id) { + if (!is_numeric($id) || 0 === ((int) $id)) { + throw new BadRequestHttpException('Only numbers are allowed in by addressee parameter'); + } + + $params['byAddressee'][] = $user = $this->userRepository->find($id); + if (null === $user) { + throw new BadRequestHttpException('User not found'); + } + } + } + $nb = $this->ticketRepository->countTickets($params); $paginator = $this->paginatorFactory->create($nb); diff --git a/src/Bundle/ChillTicketBundle/src/Repository/TicketACLAwareRepository.php b/src/Bundle/ChillTicketBundle/src/Repository/TicketACLAwareRepository.php index 02122b9fe..eb2da9b6e 100644 --- a/src/Bundle/ChillTicketBundle/src/Repository/TicketACLAwareRepository.php +++ b/src/Bundle/ChillTicketBundle/src/Repository/TicketACLAwareRepository.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\TicketBundle\Repository; +use Chill\TicketBundle\Entity\AddresseeHistory; use Chill\TicketBundle\Entity\EmergencyStatusHistory; use Chill\TicketBundle\Entity\MotiveHistory; use Chill\TicketBundle\Entity\PersonHistory; @@ -131,6 +132,40 @@ final readonly class TicketACLAwareRepository implements TicketACLAwareRepositor $qb->setParameter('opening_after', $params['byCreatedBefore']); } + if (array_key_exists('byAddressee', $params)) { + $orx = $qb->expr()->orX(); + foreach ($params['byAddressee'] as $addressee) { + $orx->add( + $qb->expr()->exists(sprintf( + 'SELECT 1 FROM %s tp_addressee_%d WHERE tp_addressee_%d.ticket = t + AND tp_addressee_%d.endDate IS NULL AND tp_addressee_%d.addresseeUser = :addressee_%d', + AddresseeHistory::class, + ++$i, + $i, + $i, + $i, + $addresseeParam = $i, + )) + ); + $orx->add( + $qb->expr()->exists(sprintf( + 'SELECT 1 FROM %s tp_addressee_%d JOIN tp_addressee_%d.addresseeGroup group_%d WHERE tp_addressee_%d.ticket = t + AND tp_addressee_%d.endDate IS NULL AND :addressee_%d MEMBER OF group_%d.users', + AddresseeHistory::class, + ++$i, + $i, + $i, + $i, + $i, + $addresseeParam, + $i, + )) + ); + $qb->setParameter(sprintf('addressee_%d', $addresseeParam), $addressee); + } + $qb->andWhere($orx); + } + return $qb; } } diff --git a/src/Bundle/ChillTicketBundle/src/Repository/TicketACLAwareRepositoryInterface.php b/src/Bundle/ChillTicketBundle/src/Repository/TicketACLAwareRepositoryInterface.php index 474bd7a8d..59527fb73 100644 --- a/src/Bundle/ChillTicketBundle/src/Repository/TicketACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillTicketBundle/src/Repository/TicketACLAwareRepositoryInterface.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\TicketBundle\Repository; +use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\Person; use Chill\TicketBundle\Entity\EmergencyStatusEnum; use Chill\TicketBundle\Entity\Motive; @@ -20,7 +21,7 @@ use Chill\TicketBundle\Entity\Ticket; /** * Repository to find tickets, taking care of permissions. * - * @phpstan-type TicketACLAwareRepositoryParam array{byPerson?: list, byCurrentState?: list, byCurrentStateEmergency?: list, byMotives?: list, byCreatedBefore?: \DateTimeImmutable, byCreatedAfter?: \DateTimeImmutable} + * @phpstan-type TicketACLAwareRepositoryParam array{byPerson?: list, byCurrentState?: list, byCurrentStateEmergency?: list, byMotives?: list, byCreatedBefore?: \DateTimeImmutable, byCreatedAfter?: \DateTimeImmutable, byAddressee?: list} */ interface TicketACLAwareRepositoryInterface { diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByAddresseeTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByAddresseeTest.php new file mode 100644 index 000000000..0508bdfa6 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByAddresseeTest.php @@ -0,0 +1,302 @@ +prophesize(Security::class); + $security->isGranted('ROLE_USER')->willReturn(true); + + $user = new User(); + + $userRepository = $this->prophesize(UserRepositoryInterface::class); + $userRepository->find(1)->willReturn($user); + + $ticketRepository = $this->prophesize(TicketACLAwareRepositoryInterface::class); + $tickets = [new Ticket(), new Ticket()]; + $ticketRepository->countTickets( + Argument::that(fn ($params) => isset($params['byAddressee']) && in_array($user, $params['byAddressee'])) + ) + ->shouldBeCalled() + ->willReturn(2); + $ticketRepository->findTickets( + Argument::that(fn ($params) => isset($params['byAddressee']) && in_array($user, $params['byAddressee'])), + 0, + 10 + )->shouldBeCalled()->willReturn($tickets); + + $paginator = $this->prophesize(PaginatorInterface::class); + $paginator->getCurrentPageFirstItemNumber()->willReturn(0); + $paginator->getItemsPerPage()->willReturn(10); + + $paginatorFactory = $this->prophesize(PaginatorFactoryInterface::class); + $paginatorFactory->create(2)->willReturn($paginator->reveal()); + + $serializer = $this->prophesize(SerializerInterface::class); + $serializer->serialize( + Argument::that(fn (Collection $collection) => $collection->getItems() === $tickets), + 'json', + ['groups' => 'read:simple'] + )->willReturn('{"items":[{},{}],"pagination":{}}'); + + $personRepository = $this->prophesize(PersonRepository::class); + $motiveRepository = $this->prophesize(MotiveRepository::class); + + // Create controller + $controller = new TicketListApiController( + $security->reveal(), + $ticketRepository->reveal(), + $paginatorFactory->reveal(), + $serializer->reveal(), + $personRepository->reveal(), + $motiveRepository->reveal(), + new MockClock(), + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() + ); + + // Create request with byAddressee filter + $request = new Request( + query: ['byAddressee' => '1'] + ); + + // Call controller method + $response = $controller->listTicket($request); + + // Assert response + $this->assertInstanceOf(JsonResponse::class, $response); + $this->assertEquals('{"items":[{},{}],"pagination":{}}', $response->getContent()); + } + + public function testListTicketWithMultipleByAddresseeFilter(): void + { + // Mock dependencies + $security = $this->prophesize(Security::class); + $security->isGranted('ROLE_USER')->willReturn(true); + + $user1 = new User(); + $user2 = new User(); + + $userRepository = $this->prophesize(UserRepositoryInterface::class); + $userRepository->find(1)->willReturn($user1); + $userRepository->find(2)->willReturn($user2); + + $ticketRepository = $this->prophesize(TicketACLAwareRepositoryInterface::class); + $tickets = [new Ticket(), new Ticket()]; + $ticketRepository->countTickets( + Argument::that(fn ($params) => isset($params['byAddressee']) + && in_array($user1, $params['byAddressee']) + && in_array($user2, $params['byAddressee'])) + ) + ->shouldBeCalled() + ->willReturn(2); + $ticketRepository->findTickets( + Argument::that(fn ($params) => isset($params['byAddressee']) + && in_array($user1, $params['byAddressee']) + && in_array($user2, $params['byAddressee'])), + 0, + 10 + )->shouldBeCalled()->willReturn($tickets); + + $paginator = $this->prophesize(PaginatorInterface::class); + $paginator->getCurrentPageFirstItemNumber()->willReturn(0); + $paginator->getItemsPerPage()->willReturn(10); + + $paginatorFactory = $this->prophesize(PaginatorFactoryInterface::class); + $paginatorFactory->create(2)->willReturn($paginator->reveal()); + + $serializer = $this->prophesize(SerializerInterface::class); + $serializer->serialize( + Argument::that(fn (Collection $collection) => $collection->getItems() === $tickets), + 'json', + ['groups' => 'read:simple'] + )->willReturn('{"items":[{},{}],"pagination":{}}'); + + $personRepository = $this->prophesize(PersonRepository::class); + $motiveRepository = $this->prophesize(MotiveRepository::class); + + // Create controller + $controller = new TicketListApiController( + $security->reveal(), + $ticketRepository->reveal(), + $paginatorFactory->reveal(), + $serializer->reveal(), + $personRepository->reveal(), + $motiveRepository->reveal(), + new MockClock(), + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() + ); + + // Create request with multiple byAddressee filter + $request = new Request( + query: ['byAddressee' => '1,2'] + ); + + // Call controller method + $response = $controller->listTicket($request); + + // Assert response + $this->assertInstanceOf(JsonResponse::class, $response); + $this->assertEquals('{"items":[{},{}],"pagination":{}}', $response->getContent()); + } + + public function testListTicketWithByAddresseeFilterUserNotFound(): void + { + self::expectException(BadRequestHttpException::class); + self::expectExceptionMessage('User not found'); + + // Mock dependencies + $security = $this->prophesize(Security::class); + $security->isGranted('ROLE_USER')->willReturn(true); + + $user1 = new User(); + + $userRepository = $this->prophesize(UserRepositoryInterface::class); + $userRepository->find(1)->willReturn($user1); + $userRepository->find(2)->willReturn(null); // User not found + + $ticketRepository = $this->prophesize(TicketACLAwareRepositoryInterface::class); + $paginatorFactory = $this->prophesize(PaginatorFactoryInterface::class); + $serializer = $this->prophesize(SerializerInterface::class); + $personRepository = $this->prophesize(PersonRepository::class); + $motiveRepository = $this->prophesize(MotiveRepository::class); + + // Create controller + $controller = new TicketListApiController( + $security->reveal(), + $ticketRepository->reveal(), + $paginatorFactory->reveal(), + $serializer->reveal(), + $personRepository->reveal(), + $motiveRepository->reveal(), + new MockClock(), + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() + ); + + // Create request with byAddressee filter with non-existent user + $request = new Request( + query: ['byAddressee' => '1,2'] + ); + + // Call controller method - should throw exception + $controller->listTicket($request); + } + + public function testListTicketWithByAddresseeAndByAddresseeToMeFilters(): void + { + // Mock dependencies + $currentUser = new User(); + $user1 = new User(); + + $security = $this->prophesize(Security::class); + $security->isGranted('ROLE_USER')->willReturn(true); + $security->getUser()->willReturn($currentUser); + + $userRepository = $this->prophesize(UserRepositoryInterface::class); + $userRepository->find(1)->willReturn($user1); + + $ticketRepository = $this->prophesize(TicketACLAwareRepositoryInterface::class); + $tickets = [new Ticket(), new Ticket()]; + $ticketRepository->countTickets( + Argument::that(fn ($params) => isset($params['byAddressee']) + && in_array($currentUser, $params['byAddressee']) + && in_array($user1, $params['byAddressee'])) + ) + ->shouldBeCalled() + ->willReturn(2); + $ticketRepository->findTickets( + Argument::that(fn ($params) => isset($params['byAddressee']) + && in_array($currentUser, $params['byAddressee']) + && in_array($user1, $params['byAddressee'])), + 0, + 10 + )->shouldBeCalled()->willReturn($tickets); + + $paginator = $this->prophesize(PaginatorInterface::class); + $paginator->getCurrentPageFirstItemNumber()->willReturn(0); + $paginator->getItemsPerPage()->willReturn(10); + + $paginatorFactory = $this->prophesize(PaginatorFactoryInterface::class); + $paginatorFactory->create(2)->willReturn($paginator->reveal()); + + $serializer = $this->prophesize(SerializerInterface::class); + $serializer->serialize( + Argument::that(fn (Collection $collection) => $collection->getItems() === $tickets), + 'json', + ['groups' => 'read:simple'] + )->willReturn('{"items":[{},{}],"pagination":{}}'); + + $personRepository = $this->prophesize(PersonRepository::class); + $motiveRepository = $this->prophesize(MotiveRepository::class); + + // Create controller + $controller = new TicketListApiController( + $security->reveal(), + $ticketRepository->reveal(), + $paginatorFactory->reveal(), + $serializer->reveal(), + $personRepository->reveal(), + $motiveRepository->reveal(), + new MockClock(), + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() + ); + + // Create request with both byAddressee and byAddresseeToMe filters + $request = new Request( + query: [ + 'byAddressee' => '1', + 'byAddresseeToMe' => '', + ] + ); + + // Call controller method + $response = $controller->listTicket($request); + + // Assert response + $this->assertInstanceOf(JsonResponse::class, $response); + $this->assertEquals('{"items":[{},{}],"pagination":{}}', $response->getContent()); + } +} diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByAddresseeToMeTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByAddresseeToMeTest.php new file mode 100644 index 000000000..f9d5738e7 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByAddresseeToMeTest.php @@ -0,0 +1,108 @@ +prophesize(Security::class); + $security->isGranted('ROLE_USER')->willReturn(true); + $security->getUser()->willReturn($user); + + $ticketRepository = $this->prophesize(TicketACLAwareRepositoryInterface::class); + $tickets = [new Ticket(), new Ticket()]; + $ticketRepository->countTickets( + Argument::that(fn ($params) => isset($params['byAddressee']) && in_array($user, $params['byAddressee'])) + ) + ->shouldBeCalled() + ->willReturn(2); + $ticketRepository->findTickets( + Argument::that(fn ($params) => isset($params['byAddressee']) && in_array($user, $params['byAddressee'])), + 0, + 10 + )->shouldBeCalled()->willReturn($tickets); + + $paginator = $this->prophesize(PaginatorInterface::class); + $paginator->getCurrentPageFirstItemNumber()->willReturn(0); + $paginator->getItemsPerPage()->willReturn(10); + + $paginatorFactory = $this->prophesize(PaginatorFactoryInterface::class); + $paginatorFactory->create(2)->willReturn($paginator->reveal()); + + $serializer = $this->prophesize(SerializerInterface::class); + $serializer->serialize( + Argument::that(fn (Collection $collection) => $collection->getItems() === $tickets), + 'json', + ['groups' => 'read:simple'] + )->willReturn('{"items":[{},{}],"pagination":{}}'); + + $personRepository = $this->prophesize(PersonRepository::class); + $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); + + // Create controller + $controller = new TicketListApiController( + $security->reveal(), + $ticketRepository->reveal(), + $paginatorFactory->reveal(), + $serializer->reveal(), + $personRepository->reveal(), + $motiveRepository->reveal(), + new MockClock(), + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() + ); + + // Create request with byAddresseeToMe filter + $request = new Request( + query: ['byAddresseeToMe' => ''] + ); + + // Call controller method + $response = $controller->listTicket($request); + + // Assert response + $this->assertInstanceOf(JsonResponse::class, $response); + $this->assertEquals('{"items":[{},{}],"pagination":{}}', $response->getContent()); + } +} diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByCreatedAfterTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByCreatedAfterTest.php index 2b03910e4..72eabd43d 100644 --- a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByCreatedAfterTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByCreatedAfterTest.php @@ -13,6 +13,7 @@ namespace Chill\TicketBundle\Tests\Controller; use Chill\MainBundle\Pagination\PaginatorFactoryInterface; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Repository\PersonRepository; use Chill\TicketBundle\Controller\TicketListApiController; @@ -84,6 +85,7 @@ final class TicketListApiControllerByCreatedAfterTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -94,7 +96,8 @@ final class TicketListApiControllerByCreatedAfterTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with byCreatedAfter filter in RFC3339 format @@ -155,6 +158,7 @@ final class TicketListApiControllerByCreatedAfterTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -165,7 +169,8 @@ final class TicketListApiControllerByCreatedAfterTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with byCreatedAfter filter in RFC3339_EXTENDED format @@ -195,6 +200,7 @@ final class TicketListApiControllerByCreatedAfterTest extends TestCase $serializer = $this->prophesize(SerializerInterface::class); $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -205,7 +211,8 @@ final class TicketListApiControllerByCreatedAfterTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with byCreatedAfter filter in invalid format diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByCreatedBeforeTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByCreatedBeforeTest.php index c4fb42ddd..55fa1911d 100644 --- a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByCreatedBeforeTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByCreatedBeforeTest.php @@ -13,6 +13,7 @@ namespace Chill\TicketBundle\Tests\Controller; use Chill\MainBundle\Pagination\PaginatorFactoryInterface; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Repository\PersonRepository; use Chill\TicketBundle\Controller\TicketListApiController; @@ -84,6 +85,7 @@ final class TicketListApiControllerByCreatedBeforeTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -94,7 +96,8 @@ final class TicketListApiControllerByCreatedBeforeTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with byCreatedAfter filter in RFC3339 format @@ -155,6 +158,7 @@ final class TicketListApiControllerByCreatedBeforeTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -165,7 +169,8 @@ final class TicketListApiControllerByCreatedBeforeTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with byCreatedAfter filter in RFC3339_EXTENDED format @@ -195,6 +200,7 @@ final class TicketListApiControllerByCreatedBeforeTest extends TestCase $serializer = $this->prophesize(SerializerInterface::class); $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -205,7 +211,8 @@ final class TicketListApiControllerByCreatedBeforeTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with byCreatedAfter filter in invalid format diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByResponseTimeExceededTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByResponseTimeExceededTest.php index 7768591ea..9c5f386e2 100644 --- a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByResponseTimeExceededTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerByResponseTimeExceededTest.php @@ -13,6 +13,7 @@ namespace Chill\TicketBundle\Tests\Controller; use Chill\MainBundle\Pagination\PaginatorFactoryInterface; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Repository\PersonRepository; use Chill\TicketBundle\Controller\TicketListApiController; @@ -94,6 +95,7 @@ final class TicketListApiControllerByResponseTimeExceededTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -104,7 +106,8 @@ final class TicketListApiControllerByResponseTimeExceededTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), $mockClock, - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with byResponseTimeExceeded parameter only @@ -176,6 +179,7 @@ final class TicketListApiControllerByResponseTimeExceededTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -186,7 +190,8 @@ final class TicketListApiControllerByResponseTimeExceededTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), $mockClock, - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with both byCreatedAfter and byResponseTimeExceeded parameters diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerCurrentStateEmergencyTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerCurrentStateEmergencyTest.php index 79388a4a0..8f39db1ff 100644 --- a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerCurrentStateEmergencyTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerCurrentStateEmergencyTest.php @@ -13,6 +13,7 @@ namespace Chill\TicketBundle\Tests\Controller; use Chill\MainBundle\Pagination\PaginatorFactoryInterface; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Repository\PersonRepository; use Chill\TicketBundle\Controller\TicketListApiController; @@ -74,6 +75,7 @@ final class TicketListApiControllerCurrentStateEmergencyTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -84,7 +86,8 @@ final class TicketListApiControllerCurrentStateEmergencyTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with emergency filter @@ -113,6 +116,7 @@ final class TicketListApiControllerCurrentStateEmergencyTest extends TestCase $serializer = $this->prophesize(SerializerInterface::class); $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -123,7 +127,8 @@ final class TicketListApiControllerCurrentStateEmergencyTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with invalid emergency filter diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerCurrentStateTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerCurrentStateTest.php index 0a8653094..f54258af2 100644 --- a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerCurrentStateTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerCurrentStateTest.php @@ -13,6 +13,7 @@ namespace Chill\TicketBundle\Tests\Controller; use Chill\MainBundle\Pagination\PaginatorFactoryInterface; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Repository\PersonRepository; use Chill\TicketBundle\Controller\TicketListApiController; @@ -74,6 +75,7 @@ final class TicketListApiControllerCurrentStateTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -84,7 +86,8 @@ final class TicketListApiControllerCurrentStateTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with person filter @@ -113,6 +116,7 @@ final class TicketListApiControllerCurrentStateTest extends TestCase $serializer = $this->prophesize(SerializerInterface::class); $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -123,7 +127,8 @@ final class TicketListApiControllerCurrentStateTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with person filter diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerMotivesTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerMotivesTest.php index b77f7d4f5..9369ab7a7 100644 --- a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerMotivesTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerMotivesTest.php @@ -13,6 +13,7 @@ namespace Chill\TicketBundle\Tests\Controller; use Chill\MainBundle\Pagination\PaginatorFactoryInterface; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Repository\PersonRepository; use Chill\TicketBundle\Controller\TicketListApiController; @@ -79,6 +80,7 @@ final class TicketListApiControllerMotivesTest extends TestCase $motiveRepository = $this->prophesize(MotiveRepository::class); $motiveRepository->find(1)->willReturn($motive1); $motiveRepository->find(2)->willReturn($motive2); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -89,7 +91,8 @@ final class TicketListApiControllerMotivesTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with multiple motives filter @@ -142,6 +145,7 @@ final class TicketListApiControllerMotivesTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); $motiveRepository->find(1)->willReturn($motive); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -152,7 +156,8 @@ final class TicketListApiControllerMotivesTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with single motive filter @@ -183,6 +188,7 @@ final class TicketListApiControllerMotivesTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); $motiveRepository->find(999)->willReturn(null); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -193,7 +199,8 @@ final class TicketListApiControllerMotivesTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with non-existent motive @@ -219,6 +226,7 @@ final class TicketListApiControllerMotivesTest extends TestCase $serializer = $this->prophesize(SerializerInterface::class); $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -229,7 +237,8 @@ final class TicketListApiControllerMotivesTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with non-integer motive parameter diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerTest.php index 5a9ec3b3d..76e5e6998 100644 --- a/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Controller/TicketListApiControllerTest.php @@ -13,6 +13,7 @@ namespace Chill\TicketBundle\Tests\Controller; use Chill\MainBundle\Pagination\PaginatorFactoryInterface; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Repository\PersonRepository; @@ -68,6 +69,7 @@ final class TicketListApiControllerTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -78,7 +80,8 @@ final class TicketListApiControllerTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request @@ -127,6 +130,7 @@ final class TicketListApiControllerTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $personRepository->find(123)->willReturn($person); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -137,7 +141,8 @@ final class TicketListApiControllerTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with person filter @@ -164,6 +169,7 @@ final class TicketListApiControllerTest extends TestCase $serializer = $this->prophesize(SerializerInterface::class); $personRepository = $this->prophesize(PersonRepository::class); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -174,7 +180,8 @@ final class TicketListApiControllerTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request @@ -204,6 +211,7 @@ final class TicketListApiControllerTest extends TestCase $personRepository = $this->prophesize(PersonRepository::class); $personRepository->find(123)->willReturn($person); $motiveRepository = $this->prophesize(MotiveRepository::class); + $userRepository = $this->prophesize(UserRepositoryInterface::class); // Create controller $controller = new TicketListApiController( @@ -214,7 +222,8 @@ final class TicketListApiControllerTest extends TestCase $personRepository->reveal(), $motiveRepository->reveal(), new MockClock(), - new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]) + new ParameterBag(['chill_ticket' => ['ticket' => ['response_time_exceeded_delay' => 'PT12H']]]), + $userRepository->reveal() ); // Create request with person filter diff --git a/src/Bundle/ChillTicketBundle/tests/Repository/TicketACLAwareRepositoryTest.php b/src/Bundle/ChillTicketBundle/tests/Repository/TicketACLAwareRepositoryTest.php index 5156f7de5..ef81f5058 100644 --- a/src/Bundle/ChillTicketBundle/tests/Repository/TicketACLAwareRepositoryTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Repository/TicketACLAwareRepositoryTest.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\TicketBundle\Tests\Repository; +use Chill\MainBundle\Entity\User; use Chill\PersonBundle\DataFixtures\Helper\RandomPersonHelperTrait; use Chill\TicketBundle\Entity\EmergencyStatusEnum; use Chill\TicketBundle\Entity\Motive; @@ -123,4 +124,19 @@ class TicketACLAwareRepositoryTest extends KernelTestCase self::assertIsArray($actual); } + + public function testFindByAddressee(): void + { + $users = $this->entityManager->createQuery('SELECT u FROM '.User::class.' u') + ->setMaxResults(2) + ->getResult(); + + if ([] === $users) { + throw new \UnexpectedValueException('No users found'); + } + + $actual = $this->repository->findTickets(['byAddressee' => $users]); + + self::assertIsArray($actual); + } }