|
|
|
@@ -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);
|
|
|
|
|
}
|
|
|
|
|
}
|