mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-22 15:43:51 +00:00
[WIP] Refactor AddressReferenceRepository to use interface and add tests for AddressReferenceAggregatedApiController
This commit is contained in:
@@ -11,7 +11,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\MainBundle\Controller;
|
namespace Chill\MainBundle\Controller;
|
||||||
|
|
||||||
use Chill\MainBundle\Repository\AddressReferenceRepository;
|
use Chill\MainBundle\Repository\AddressReferenceRepositoryInterface;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
@@ -23,7 +23,7 @@ final readonly class AddressReferenceAggregatedApiController
|
|||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private Security $security,
|
private Security $security,
|
||||||
private AddressReferenceRepository $addressReferenceRepository,
|
private AddressReferenceRepositoryInterface $addressReferenceRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[Route(path: '/api/1.0/main/address-reference/aggregated/search')]
|
#[Route(path: '/api/1.0/main/address-reference/aggregated/search')]
|
||||||
|
@@ -20,9 +20,8 @@ use Doctrine\ORM\EntityRepository;
|
|||||||
use Doctrine\ORM\NativeQuery;
|
use Doctrine\ORM\NativeQuery;
|
||||||
use Doctrine\ORM\Query\ResultSetMapping;
|
use Doctrine\ORM\Query\ResultSetMapping;
|
||||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
|
||||||
|
|
||||||
final readonly class AddressReferenceRepository implements ObjectRepository
|
final readonly class AddressReferenceRepository implements AddressReferenceRepositoryInterface
|
||||||
{
|
{
|
||||||
private EntityManagerInterface $entityManager;
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
|
@@ -0,0 +1,20 @@
|
|||||||
|
<?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\MainBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\PostalCode;
|
||||||
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
|
interface AddressReferenceRepositoryInterface extends ObjectRepository
|
||||||
|
{
|
||||||
|
public function findAggregatedBySearchString(string $search, PostalCode|int|null $postalCode = null, int $firstResult = 0, int $maxResults = 50): iterable;
|
||||||
|
}
|
@@ -0,0 +1,118 @@
|
|||||||
|
<?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\MainBundle\Tests\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Controller\AddressReferenceAggregatedApiController;
|
||||||
|
use Chill\MainBundle\Repository\AddressReferenceRepositoryInterface;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @covers \Chill\MainBundle\Controller\AddressReferenceAggregatedApiController
|
||||||
|
*/
|
||||||
|
final class AddressReferenceAggregatedApiControllerTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
public function testAccessDeniedWhenNotAuthenticated(): void
|
||||||
|
{
|
||||||
|
$security = $this->prophesize(Security::class);
|
||||||
|
$security->isGranted('IS_AUTHENTICATED')->willReturn(false);
|
||||||
|
|
||||||
|
$repo = $this->prophesize(AddressReferenceRepositoryInterface::class);
|
||||||
|
|
||||||
|
$controller = new AddressReferenceAggregatedApiController($security->reveal(), $repo->reveal());
|
||||||
|
|
||||||
|
$request = new Request(query: ['q' => 'anything']);
|
||||||
|
|
||||||
|
$this->expectException(AccessDeniedHttpException::class);
|
||||||
|
|
||||||
|
$controller->search($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBadRequestWhenQueryIsMissing(): void
|
||||||
|
{
|
||||||
|
$security = $this->prophesize(Security::class);
|
||||||
|
$security->isGranted('IS_AUTHENTICATED')->willReturn(true);
|
||||||
|
|
||||||
|
$repo = $this->prophesize(AddressReferenceRepositoryInterface::class);
|
||||||
|
|
||||||
|
$controller = new AddressReferenceAggregatedApiController($security->reveal(), $repo->reveal());
|
||||||
|
|
||||||
|
$request = new Request();
|
||||||
|
|
||||||
|
$this->expectException(BadRequestHttpException::class);
|
||||||
|
$this->expectExceptionMessage('Parameter "q" is required.');
|
||||||
|
|
||||||
|
$controller->search($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBadRequestWhenQueryIsEmpty(): void
|
||||||
|
{
|
||||||
|
$security = $this->prophesize(Security::class);
|
||||||
|
$security->isGranted('IS_AUTHENTICATED')->willReturn(true);
|
||||||
|
|
||||||
|
$repo = $this->prophesize(AddressReferenceRepositoryInterface::class);
|
||||||
|
|
||||||
|
$controller = new AddressReferenceAggregatedApiController($security->reveal(), $repo->reveal());
|
||||||
|
|
||||||
|
$request = new Request(query: ['q' => ' ']);
|
||||||
|
|
||||||
|
$this->expectException(BadRequestHttpException::class);
|
||||||
|
$this->expectExceptionMessage('Parameter "q" is required and cannot be empty.');
|
||||||
|
|
||||||
|
$controller->search($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSuccessfulSearchReturnsJsonAndCallsRepositoryWithTrimmedQuery(): void
|
||||||
|
{
|
||||||
|
$security = $this->prophesize(Security::class);
|
||||||
|
$security->isGranted('IS_AUTHENTICATED')->willReturn(true);
|
||||||
|
|
||||||
|
$expectedQuery = 'foo';
|
||||||
|
$iterableResult = new \ArrayIterator([
|
||||||
|
[
|
||||||
|
'street' => 'Main Street',
|
||||||
|
'postcode_id' => 123,
|
||||||
|
'code' => '1000',
|
||||||
|
'label' => 'Brussels',
|
||||||
|
'positions' => ['1' => '12', '2' => '14'],
|
||||||
|
'row_number' => 1,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$repo = $this->prophesize(AddressReferenceRepositoryInterface::class);
|
||||||
|
$repo->findAggregatedBySearchString($expectedQuery)->willReturn($iterableResult)->shouldBeCalledOnce();
|
||||||
|
|
||||||
|
$controller = new AddressReferenceAggregatedApiController($security->reveal(), $repo->reveal());
|
||||||
|
|
||||||
|
// Provide spaces around to ensure trimming is applied
|
||||||
|
$request = new Request(query: ['q' => " {$expectedQuery} "]);
|
||||||
|
|
||||||
|
$response = $controller->search($request);
|
||||||
|
|
||||||
|
self::assertSame(200, $response->getStatusCode());
|
||||||
|
$data = json_decode($response->getContent(), true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
self::assertIsArray($data);
|
||||||
|
self::assertCount(1, $data);
|
||||||
|
self::assertSame('Main Street', $data[0]['street']);
|
||||||
|
self::assertSame(123, $data[0]['postcode_id']);
|
||||||
|
self::assertSame('1000', $data[0]['code']);
|
||||||
|
self::assertSame('Brussels', $data[0]['label']);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user