mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-10-01 10:59:45 +00:00
Add test for MyInvitationsController.php
This commit is contained in:
@@ -13,7 +13,7 @@ namespace Chill\CalendarBundle\Controller;
|
|||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Chill\CalendarBundle\Repository\InviteRepository;
|
use Chill\CalendarBundle\Repository\InviteRepository;
|
||||||
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
|
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepositoryInterface;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
@@ -24,7 +24,7 @@ use Symfony\Component\Routing\Annotation\Route;
|
|||||||
|
|
||||||
class MyInvitationsController extends AbstractController
|
class MyInvitationsController extends AbstractController
|
||||||
{
|
{
|
||||||
public function __construct(private readonly InviteRepository $inviteRepository, private readonly PaginatorFactory $paginator, private readonly DocGeneratorTemplateRepository $docGeneratorTemplateRepository) {}
|
public function __construct(private readonly InviteRepository $inviteRepository, private readonly PaginatorFactory $paginator, private readonly DocGeneratorTemplateRepositoryInterface $docGeneratorTemplateRepository) {}
|
||||||
|
|
||||||
#[Route(path: '/{_locale}/calendar/invitations/my', name: 'chill_calendar_invitations_list_my')]
|
#[Route(path: '/{_locale}/calendar/invitations/my', name: 'chill_calendar_invitations_list_my')]
|
||||||
public function myInvitations(Request $request): Response
|
public function myInvitations(Request $request): Response
|
||||||
|
@@ -16,7 +16,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
readonly class InviteRepository implements ObjectRepository
|
class InviteRepository implements ObjectRepository
|
||||||
{
|
{
|
||||||
private EntityRepository $entityRepository;
|
private EntityRepository $entityRepository;
|
||||||
|
|
||||||
|
@@ -0,0 +1,292 @@
|
|||||||
|
<?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\CalendarBundle\Tests\Controller;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Controller\MyInvitationsController;
|
||||||
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
|
use Chill\CalendarBundle\Entity\Invite;
|
||||||
|
use Chill\CalendarBundle\Repository\InviteRepository;
|
||||||
|
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepositoryInterface;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||||
|
use Twig\Environment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class MyInvitationsControllerTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
private MyInvitationsController $controller;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
// Create prophecies for dependencies
|
||||||
|
$inviteRepository = $this->prophesize(InviteRepository::class);
|
||||||
|
$paginatorFactory = $this->prophesize(PaginatorFactory::class);
|
||||||
|
$docGeneratorTemplateRepository = $this->prophesize(DocGeneratorTemplateRepositoryInterface::class);
|
||||||
|
|
||||||
|
// Create controller instance
|
||||||
|
$this->controller = new MyInvitationsController(
|
||||||
|
$inviteRepository->reveal(),
|
||||||
|
$paginatorFactory->reveal(),
|
||||||
|
$docGeneratorTemplateRepository->reveal()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set up necessary services for AbstractController
|
||||||
|
$authorizationChecker = $this->prophesize(AuthorizationCheckerInterface::class);
|
||||||
|
$tokenStorage = $this->prophesize(TokenStorageInterface::class);
|
||||||
|
$twig = $this->prophesize(Environment::class);
|
||||||
|
|
||||||
|
// Use reflection to set the container
|
||||||
|
$reflection = new \ReflectionClass($this->controller);
|
||||||
|
$containerProperty = $reflection->getParentClass()->getProperty('container');
|
||||||
|
$containerProperty->setAccessible(true);
|
||||||
|
|
||||||
|
// Create a mock container
|
||||||
|
$container = $this->prophesize(\Psr\Container\ContainerInterface::class);
|
||||||
|
$container->has('security.authorization_checker')->willReturn(true);
|
||||||
|
$container->get('security.authorization_checker')->willReturn($authorizationChecker->reveal());
|
||||||
|
$container->has('security.token_storage')->willReturn(true);
|
||||||
|
$container->get('security.token_storage')->willReturn($tokenStorage->reveal());
|
||||||
|
$container->has('twig')->willReturn(true);
|
||||||
|
$container->get('twig')->willReturn($twig->reveal());
|
||||||
|
|
||||||
|
$containerProperty->setValue($this->controller, $container->reveal());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMyInvitationsReturnsCorrectAmountOfInvitations(): void
|
||||||
|
{
|
||||||
|
// Create test user
|
||||||
|
$user = new User();
|
||||||
|
$user->setUsername('testuser');
|
||||||
|
|
||||||
|
// Create test invitations
|
||||||
|
$invite1 = new Invite();
|
||||||
|
$invite1->setUser($user);
|
||||||
|
$invite1->setStatus(Invite::PENDING);
|
||||||
|
|
||||||
|
$invite2 = new Invite();
|
||||||
|
$invite2->setUser($user);
|
||||||
|
$invite2->setStatus(Invite::ACCEPTED);
|
||||||
|
|
||||||
|
$invite3 = new Invite();
|
||||||
|
$invite3->setUser($user);
|
||||||
|
$invite3->setStatus(Invite::DECLINED);
|
||||||
|
|
||||||
|
$allInvitations = [$invite1, $invite2, $invite3];
|
||||||
|
$paginatedInvitations = [$invite1, $invite2]; // First page with 2 items per page
|
||||||
|
|
||||||
|
// Set up repository prophecies
|
||||||
|
$inviteRepository = $this->prophesize(InviteRepository::class);
|
||||||
|
$inviteRepository->findBy(['user' => $user])->willReturn($allInvitations);
|
||||||
|
$inviteRepository->findBy(
|
||||||
|
['user' => $user],
|
||||||
|
['createdAt' => 'DESC'],
|
||||||
|
2, // items per page
|
||||||
|
0 // offset
|
||||||
|
)->willReturn($paginatedInvitations);
|
||||||
|
|
||||||
|
// Set up paginator prophecies
|
||||||
|
$paginator = $this->prophesize(PaginatorInterface::class);
|
||||||
|
$paginator->getItemsPerPage()->willReturn(2);
|
||||||
|
$paginator->getCurrentPageFirstItemNumber()->willReturn(0);
|
||||||
|
|
||||||
|
$paginatorFactory = $this->prophesize(PaginatorFactory::class);
|
||||||
|
$paginatorFactory->create(3)->willReturn($paginator->reveal());
|
||||||
|
|
||||||
|
// Set up doc generator repository
|
||||||
|
$docGeneratorTemplateRepository = $this->prophesize(DocGeneratorTemplateRepositoryInterface::class);
|
||||||
|
$docGeneratorTemplateRepository->findByEntity(Calendar::class)->willReturn([]);
|
||||||
|
|
||||||
|
// Create controller with mocked dependencies
|
||||||
|
$controller = new MyInvitationsController(
|
||||||
|
$inviteRepository->reveal(),
|
||||||
|
$paginatorFactory->reveal(),
|
||||||
|
$docGeneratorTemplateRepository->reveal()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set up authorization checker to return true for ROLE_USER
|
||||||
|
$authorizationChecker = $this->prophesize(AuthorizationCheckerInterface::class);
|
||||||
|
$authorizationChecker->isGranted('ROLE_USER', null)->willReturn(true);
|
||||||
|
|
||||||
|
// Set up token storage to return user
|
||||||
|
$token = $this->prophesize(TokenInterface::class);
|
||||||
|
$token->getUser()->willReturn($user);
|
||||||
|
$tokenStorage = $this->prophesize(TokenStorageInterface::class);
|
||||||
|
$tokenStorage->getToken()->willReturn($token->reveal());
|
||||||
|
|
||||||
|
// Set up twig to return a response
|
||||||
|
$twig = $this->prophesize(Environment::class);
|
||||||
|
$twig->render('@ChillCalendar/Invitations/listByUser.html.twig', [
|
||||||
|
'invitations' => $paginatedInvitations,
|
||||||
|
'paginator' => $paginator->reveal(),
|
||||||
|
'templates' => [],
|
||||||
|
])->willReturn('rendered content');
|
||||||
|
|
||||||
|
// Set up container
|
||||||
|
$container = $this->prophesize(\Psr\Container\ContainerInterface::class);
|
||||||
|
$container->has('security.authorization_checker')->willReturn(true);
|
||||||
|
$container->get('security.authorization_checker')->willReturn($authorizationChecker->reveal());
|
||||||
|
$container->has('security.token_storage')->willReturn(true);
|
||||||
|
$container->get('security.token_storage')->willReturn($tokenStorage->reveal());
|
||||||
|
$container->has('twig')->willReturn(true);
|
||||||
|
$container->get('twig')->willReturn($twig->reveal());
|
||||||
|
|
||||||
|
// Use reflection to set the container
|
||||||
|
$reflection = new \ReflectionClass($controller);
|
||||||
|
$containerProperty = $reflection->getParentClass()->getProperty('container');
|
||||||
|
$containerProperty->setAccessible(true);
|
||||||
|
$containerProperty->setValue($controller, $container->reveal());
|
||||||
|
|
||||||
|
// Create request
|
||||||
|
$request = new Request();
|
||||||
|
|
||||||
|
// Execute the action
|
||||||
|
$response = $controller->myInvitations($request);
|
||||||
|
|
||||||
|
// Assert that response is successful
|
||||||
|
self::assertInstanceOf(Response::class, $response);
|
||||||
|
self::assertSame(200, $response->getStatusCode());
|
||||||
|
self::assertSame('rendered content', $response->getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMyInvitationsPageLoads(): void
|
||||||
|
{
|
||||||
|
// Create test user
|
||||||
|
$user = new User();
|
||||||
|
$user->setUsername('testuser');
|
||||||
|
|
||||||
|
// Set up repository prophecies - no invitations
|
||||||
|
$inviteRepository = $this->prophesize(InviteRepository::class);
|
||||||
|
$inviteRepository->findBy(['user' => $user])->willReturn([]);
|
||||||
|
$inviteRepository->findBy(
|
||||||
|
['user' => $user],
|
||||||
|
['createdAt' => 'DESC'],
|
||||||
|
20, // default items per page
|
||||||
|
0 // offset
|
||||||
|
)->willReturn([]);
|
||||||
|
|
||||||
|
// Set up paginator prophecies
|
||||||
|
$paginator = $this->prophesize(PaginatorInterface::class);
|
||||||
|
$paginator->getItemsPerPage()->willReturn(20);
|
||||||
|
$paginator->getCurrentPageFirstItemNumber()->willReturn(0);
|
||||||
|
|
||||||
|
$paginatorFactory = $this->prophesize(PaginatorFactory::class);
|
||||||
|
$paginatorFactory->create(0)->willReturn($paginator->reveal());
|
||||||
|
|
||||||
|
// Set up doc generator repository
|
||||||
|
$docGeneratorTemplateRepository = $this->prophesize(DocGeneratorTemplateRepositoryInterface::class);
|
||||||
|
$docGeneratorTemplateRepository->findByEntity(Calendar::class)->willReturn([]);
|
||||||
|
|
||||||
|
// Create controller with mocked dependencies
|
||||||
|
$controller = new MyInvitationsController(
|
||||||
|
$inviteRepository->reveal(),
|
||||||
|
$paginatorFactory->reveal(),
|
||||||
|
$docGeneratorTemplateRepository->reveal()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set up authorization checker to return true for ROLE_USER
|
||||||
|
$authorizationChecker = $this->prophesize(AuthorizationCheckerInterface::class);
|
||||||
|
$authorizationChecker->isGranted('ROLE_USER', null)->willReturn(true);
|
||||||
|
|
||||||
|
// Set up token storage to return user
|
||||||
|
$token = $this->prophesize(TokenInterface::class);
|
||||||
|
$token->getUser()->willReturn($user);
|
||||||
|
$tokenStorage = $this->prophesize(TokenStorageInterface::class);
|
||||||
|
$tokenStorage->getToken()->willReturn($token->reveal());
|
||||||
|
|
||||||
|
// Set up twig to return a response
|
||||||
|
$twig = $this->prophesize(Environment::class);
|
||||||
|
$twig->render('@ChillCalendar/Invitations/listByUser.html.twig', [
|
||||||
|
'invitations' => [],
|
||||||
|
'paginator' => $paginator->reveal(),
|
||||||
|
'templates' => [],
|
||||||
|
])->willReturn('empty page content');
|
||||||
|
|
||||||
|
// Set up container
|
||||||
|
$container = $this->prophesize(\Psr\Container\ContainerInterface::class);
|
||||||
|
$container->has('security.authorization_checker')->willReturn(true);
|
||||||
|
$container->get('security.authorization_checker')->willReturn($authorizationChecker->reveal());
|
||||||
|
$container->has('security.token_storage')->willReturn(true);
|
||||||
|
$container->get('security.token_storage')->willReturn($tokenStorage->reveal());
|
||||||
|
$container->has('twig')->willReturn(true);
|
||||||
|
$container->get('twig')->willReturn($twig->reveal());
|
||||||
|
|
||||||
|
// Use reflection to set the container
|
||||||
|
$reflection = new \ReflectionClass($controller);
|
||||||
|
$containerProperty = $reflection->getParentClass()->getProperty('container');
|
||||||
|
$containerProperty->setAccessible(true);
|
||||||
|
$containerProperty->setValue($controller, $container->reveal());
|
||||||
|
|
||||||
|
// Create request
|
||||||
|
$request = new Request();
|
||||||
|
|
||||||
|
// Execute the action
|
||||||
|
$response = $controller->myInvitations($request);
|
||||||
|
|
||||||
|
// Assert that page loads successfully
|
||||||
|
self::assertInstanceOf(Response::class, $response);
|
||||||
|
self::assertSame(200, $response->getStatusCode());
|
||||||
|
self::assertSame('empty page content', $response->getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMyInvitationsRequiresAuthentication(): void
|
||||||
|
{
|
||||||
|
// Create controller with minimal dependencies
|
||||||
|
$inviteRepository = $this->prophesize(InviteRepository::class);
|
||||||
|
$paginatorFactory = $this->prophesize(PaginatorFactory::class);
|
||||||
|
$docGeneratorTemplateRepository = $this->prophesize(DocGeneratorTemplateRepositoryInterface::class);
|
||||||
|
|
||||||
|
$controller = new MyInvitationsController(
|
||||||
|
$inviteRepository->reveal(),
|
||||||
|
$paginatorFactory->reveal(),
|
||||||
|
$docGeneratorTemplateRepository->reveal()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set up authorization checker to return false for ROLE_USER
|
||||||
|
$authorizationChecker = $this->prophesize(AuthorizationCheckerInterface::class);
|
||||||
|
$authorizationChecker->isGranted('ROLE_USER')->willReturn(false);
|
||||||
|
$authorizationChecker->isGranted('ROLE_USER', null)->willReturn(false);
|
||||||
|
|
||||||
|
// Set up container
|
||||||
|
$container = $this->prophesize(\Psr\Container\ContainerInterface::class);
|
||||||
|
$container->has('security.authorization_checker')->willReturn(true);
|
||||||
|
$container->get('security.authorization_checker')->willReturn($authorizationChecker->reveal());
|
||||||
|
|
||||||
|
// Use reflection to set the container
|
||||||
|
$reflection = new \ReflectionClass($controller);
|
||||||
|
$containerProperty = $reflection->getParentClass()->getProperty('container');
|
||||||
|
$containerProperty->setAccessible(true);
|
||||||
|
$containerProperty->setValue($controller, $container->reveal());
|
||||||
|
|
||||||
|
// Create request
|
||||||
|
$request = new Request();
|
||||||
|
|
||||||
|
// Expect AccessDeniedException
|
||||||
|
$this->expectException(\Symfony\Component\Security\Core\Exception\AccessDeniedException::class);
|
||||||
|
|
||||||
|
// Execute the action
|
||||||
|
$controller->myInvitations($request);
|
||||||
|
}
|
||||||
|
}
|
@@ -20,4 +20,9 @@ use Doctrine\Persistence\ObjectRepository;
|
|||||||
interface DocGeneratorTemplateRepositoryInterface extends ObjectRepository
|
interface DocGeneratorTemplateRepositoryInterface extends ObjectRepository
|
||||||
{
|
{
|
||||||
public function countByEntity(string $entity): int;
|
public function countByEntity(string $entity): int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|DocGeneratorTemplate[]
|
||||||
|
*/
|
||||||
|
public function findByEntity(string $entity, ?int $start = 0, ?int $limit = 50): array;
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ use Symfony\Component\Routing\RouterInterface;
|
|||||||
/**
|
/**
|
||||||
* Create paginator instances.
|
* Create paginator instances.
|
||||||
*/
|
*/
|
||||||
final readonly class PaginatorFactory implements PaginatorFactoryInterface
|
class PaginatorFactory implements PaginatorFactoryInterface
|
||||||
{
|
{
|
||||||
final public const DEFAULT_CURRENT_PAGE_KEY = 'page';
|
final public const DEFAULT_CURRENT_PAGE_KEY = 'page';
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user