mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Create a page which list events
This commit is contained in:
parent
d8bf6a195f
commit
e902b6d409
@ -251,7 +251,7 @@ final class EventController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$form = $this->formFactoryInterface
|
$form = $this->formFactoryInterface
|
||||||
->createNamedBuilder(null, FormType::class, null, [
|
->createNamedBuilder('', FormType::class, null, [
|
||||||
'csrf_protection' => false,
|
'csrf_protection' => false,
|
||||||
])
|
])
|
||||||
->setMethod('GET')
|
->setMethod('GET')
|
||||||
@ -354,7 +354,7 @@ final class EventController extends AbstractController
|
|||||||
{
|
{
|
||||||
/** @var \Symfony\Component\Form\FormBuilderInterface $builder */
|
/** @var \Symfony\Component\Form\FormBuilderInterface $builder */
|
||||||
$builder = $this
|
$builder = $this
|
||||||
->get('form.factory')
|
->formFactoryInterface
|
||||||
->createNamedBuilder(
|
->createNamedBuilder(
|
||||||
null,
|
null,
|
||||||
FormType::class,
|
FormType::class,
|
||||||
|
112
src/Bundle/ChillEventBundle/Controller/EventListController.php
Normal file
112
src/Bundle/ChillEventBundle/Controller/EventListController.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?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\EventBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\EventBundle\Entity\Event;
|
||||||
|
use Chill\EventBundle\Entity\EventType;
|
||||||
|
use Chill\EventBundle\Repository\EventACLAwareRepositoryInterface;
|
||||||
|
use Chill\EventBundle\Repository\EventTypeRepository;
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorFactoryInterface;
|
||||||
|
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
||||||
|
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactory;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||||
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
use Twig\Environment;
|
||||||
|
|
||||||
|
final readonly class EventListController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private Environment $environment,
|
||||||
|
private EventACLAwareRepositoryInterface $eventACLAwareRepository,
|
||||||
|
private EventTypeRepository $eventTypeRepository,
|
||||||
|
private FilterOrderHelperFactory $filterOrderHelperFactory,
|
||||||
|
private FormFactoryInterface $formFactory,
|
||||||
|
private PaginatorFactoryInterface $paginatorFactory,
|
||||||
|
private TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
|
private UrlGeneratorInterface $urlGenerator,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("{_locale}/event/event/list", name="chill_event_event_list")
|
||||||
|
*/
|
||||||
|
public function __invoke(): Response
|
||||||
|
{
|
||||||
|
$filter = $this->buildFilterOrder();
|
||||||
|
$filterData = [
|
||||||
|
'q' => (string) $filter->getQueryString(),
|
||||||
|
'dates' => $filter->getDateRangeData('dates'),
|
||||||
|
'event_types' => $filter->getEntityChoiceData('event_types'),
|
||||||
|
];
|
||||||
|
$total = $this->eventACLAwareRepository->countAllViewable($filterData);
|
||||||
|
$pagination = $this->paginatorFactory->create($total);
|
||||||
|
$events = $this->eventACLAwareRepository->findAllViewable($filterData, $pagination->getCurrentPageFirstItemNumber(), $pagination->getItemsPerPage());
|
||||||
|
$eventForms = [];
|
||||||
|
foreach ($events as $event) {
|
||||||
|
$eventForms[$event->getId()] = $this->createAddParticipationByPersonForm($event)->createView();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response($this->environment->render(
|
||||||
|
'@ChillEvent/Event/page_list.html.twig',
|
||||||
|
[
|
||||||
|
'events' => $events,
|
||||||
|
'pagination' => $pagination,
|
||||||
|
'eventForms' => $eventForms,
|
||||||
|
'filter' => $filter,
|
||||||
|
]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildFilterOrder(): FilterOrderHelper
|
||||||
|
{
|
||||||
|
$types = $this->eventTypeRepository->findAllActive();
|
||||||
|
|
||||||
|
$builder = $this->filterOrderHelperFactory->create(__METHOD__);
|
||||||
|
$builder
|
||||||
|
->addDateRange('dates', 'event.filter.event_dates')
|
||||||
|
->addSearchBox(['name'])
|
||||||
|
->addEntityChoice('event_types', 'event.filter.event_types', EventType::class, $types, [
|
||||||
|
'choice_label' => fn (EventType $e) => $this->translatableStringHelper->localize($e->getName()),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $builder->build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createAddParticipationByPersonForm(Event $event): FormInterface
|
||||||
|
{
|
||||||
|
$builder = $this->formFactory
|
||||||
|
->createNamedBuilder(
|
||||||
|
'',
|
||||||
|
FormType::class,
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
'method' => 'GET',
|
||||||
|
'action' => $this->urlGenerator->generate('chill_event_participation_new'),
|
||||||
|
'csrf_protection' => false,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$builder->add('person_id', PickPersonDynamicType::class, ['as_id' => true, 'multiple' => false]);
|
||||||
|
|
||||||
|
$builder->add('event_id', HiddenType::class, [
|
||||||
|
'data' => $event->getId(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $builder->getForm();
|
||||||
|
}
|
||||||
|
}
|
@ -36,7 +36,6 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface
|
|||||||
$loader->load('services/authorization.yaml');
|
$loader->load('services/authorization.yaml');
|
||||||
$loader->load('services/fixtures.yaml');
|
$loader->load('services/fixtures.yaml');
|
||||||
$loader->load('services/forms.yaml');
|
$loader->load('services/forms.yaml');
|
||||||
$loader->load('services/menu.yaml');
|
|
||||||
$loader->load('services/repositories.yaml');
|
$loader->load('services/repositories.yaml');
|
||||||
$loader->load('services/search.yaml');
|
$loader->load('services/search.yaml');
|
||||||
$loader->load('services/timeline.yaml');
|
$loader->load('services/timeline.yaml');
|
||||||
|
@ -114,7 +114,7 @@ final class PickEventType extends AbstractType
|
|||||||
} else {
|
} else {
|
||||||
$centers = $this->authorizationHelper->getReachableCenters(
|
$centers = $this->authorizationHelper->getReachableCenters(
|
||||||
$user,
|
$user,
|
||||||
(string) $options['role']->getRole()
|
$options['role']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
45
src/Bundle/ChillEventBundle/Menu/SectionMenuBuilder.php
Normal file
45
src/Bundle/ChillEventBundle/Menu/SectionMenuBuilder.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?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\EventBundle\Menu;
|
||||||
|
|
||||||
|
use Chill\EventBundle\Security\Authorization\EventVoter;
|
||||||
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
final readonly class SectionMenuBuilder implements LocalMenuBuilderInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private Security $security,
|
||||||
|
private TranslatorInterface $translator,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
||||||
|
{
|
||||||
|
if ($this->security->isGranted(EventVoter::SEE)) {
|
||||||
|
$menu->addChild(
|
||||||
|
$this->translator->trans('Events'),
|
||||||
|
[
|
||||||
|
'route' => 'chill_event_event_list',
|
||||||
|
]
|
||||||
|
)->setExtras([
|
||||||
|
'order' => 250,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMenuIds(): array
|
||||||
|
{
|
||||||
|
return ['section'];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
<?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\EventBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\EventBundle\Entity\Event;
|
||||||
|
use Chill\EventBundle\Entity\Participation;
|
||||||
|
use Chill\EventBundle\Security\Authorization\EventVoter;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\ORM\NonUniqueResultException;
|
||||||
|
use Doctrine\ORM\NoResultException;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
final readonly class EventACLAwareRepository implements EventACLAwareRepositoryInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser,
|
||||||
|
private EntityManagerInterface $entityManager,
|
||||||
|
private Security $security,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws NonUniqueResultException
|
||||||
|
* @throws NoResultException
|
||||||
|
*/
|
||||||
|
public function countAllViewable(array $filters): int
|
||||||
|
{
|
||||||
|
if (!$this->security->getUser() instanceof User) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb = $this->buildQueryByAllViewable($filters);
|
||||||
|
$this->addFilters($filters, $qb);
|
||||||
|
|
||||||
|
$qb->select('COUNT(event.id)');
|
||||||
|
|
||||||
|
return $qb->getQuery()->getSingleScalarResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findAllViewable(array $filters, int $offset = 0, int $limit = 50): array
|
||||||
|
{
|
||||||
|
if (!$this->security->getUser() instanceof User) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb = $this->buildQueryByAllViewable($filters)->select('event');
|
||||||
|
$this->addFilters($filters, $qb);
|
||||||
|
|
||||||
|
$qb->setFirstResult($offset)->setMaxResults($limit);
|
||||||
|
|
||||||
|
$qb->addOrderBy('event.date', 'DESC');
|
||||||
|
|
||||||
|
return $qb->getQuery()->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addFilters(array $filters, QueryBuilder $qb): void
|
||||||
|
{
|
||||||
|
if (($filters['q'] ?? '') !== '') {
|
||||||
|
$qb->andWhere('event.name LIKE :content');
|
||||||
|
$qb->setParameter('content', '%'.$filters['q'].'%');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('dates', $filters)) {
|
||||||
|
$dates = $filters['dates'];
|
||||||
|
if (null !== ($dates['from'] ?? null)) {
|
||||||
|
$qb->andWhere('event.date >= :date_from');
|
||||||
|
$qb->setParameter('date_from', $dates['from']);
|
||||||
|
}
|
||||||
|
if (null !== ($dates['to'] ?? null)) {
|
||||||
|
$qb->andWhere('event.date <= :date_to');
|
||||||
|
$qb->setParameter('date_to', $dates['to']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < count($filters['event_types'] ?? [])) {
|
||||||
|
$qb->andWhere('event.type IN (:event_types)');
|
||||||
|
$qb->setParameter('event_types', $filters['event_types']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildQueryByAllViewable(array $filters): QueryBuilder
|
||||||
|
{
|
||||||
|
$qb = $this->entityManager->createQueryBuilder();
|
||||||
|
$qb->from(Event::class, 'event');
|
||||||
|
|
||||||
|
$aclConditions = $qb->expr()->orX();
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
foreach ($this->authorizationHelperForCurrentUser->getReachableCenters(EventVoter::SEE) as $center) {
|
||||||
|
foreach ($this->authorizationHelperForCurrentUser->getReachableScopes(EventVoter::SEE, $center) as $scopes) {
|
||||||
|
$aclConditions->add(
|
||||||
|
$qb->expr()->andX(
|
||||||
|
'event.circle IN (:scopes_'.$i.')',
|
||||||
|
$qb->expr()->orX(
|
||||||
|
'event.center = :center_'.$i,
|
||||||
|
$qb->expr()->exists(
|
||||||
|
'SELECT 1 FROM '.Participation::class.' participation_'.$i.' JOIN participation_'.$i.'.event event_'.$i.
|
||||||
|
' JOIN '.Person\PersonCenterHistory::class.' person_center_history_'.$i.
|
||||||
|
' WITH IDENTITY(person_center_history_'.$i.'.person) = IDENTITY(participation_'.$i.'.person) '.
|
||||||
|
' AND event_'.$i.'.date <= person_center_history_'.$i.'.startDate AND (person_center_history_'.$i.'.endDate IS NULL OR person_center_history_'.$i.'.endDate > event_'.$i.'.date) '.
|
||||||
|
' WHERE participation_'.$i.'.event = event'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$qb->setParameter('scopes_'.$i, $scopes);
|
||||||
|
$qb->setParameter('center_'.$i, $center);
|
||||||
|
|
||||||
|
++$i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 === $i) {
|
||||||
|
$aclConditions->add('FALSE = TRUE');
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->orX(
|
||||||
|
'event.createdBy = :user',
|
||||||
|
$aclConditions
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$qb->setParameter('user', $this->security->getUser());
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
<?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\EventBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\EventBundle\Entity\Event;
|
||||||
|
use Chill\EventBundle\Entity\EventType;
|
||||||
|
|
||||||
|
interface EventACLAwareRepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array{q?: string, dates?: array{from?: \DateTimeImmutable|null, to?: \DateTimeImmutable|null}, event_types?: list<EventType>} $filters
|
||||||
|
*/
|
||||||
|
public function countAllViewable(array $filters): int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array{q?: string, dates?: array{from?: \DateTimeImmutable|null, to?: \DateTimeImmutable|null}, event_types?: list<EventType>} $filters
|
||||||
|
*
|
||||||
|
* @return list<Event>
|
||||||
|
*/
|
||||||
|
public function findAllViewable(array $filters, int $offset = 0, int $limit = 50): array;
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
<?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\EventBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\EventBundle\Entity\EventType;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<EventType>
|
||||||
|
*/
|
||||||
|
final class EventTypeRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
ManagerRegistry $registry,
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
private readonly TranslatorInterface $translator
|
||||||
|
) {
|
||||||
|
parent::__construct($registry, EventType::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<EventType>
|
||||||
|
*/
|
||||||
|
public function findAllActive(): array
|
||||||
|
{
|
||||||
|
$dql = 'SELECT et FROM '.EventType::class.' et WHERE et.active = TRUE ORDER BY JSON_EXTRACT(et.name, :lang)';
|
||||||
|
|
||||||
|
return $this->entityManager->createQuery($dql)
|
||||||
|
->setParameter('lang', $this->translator->getLocale())
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
{% extends '@ChillEvent/layout.html.twig' %}
|
||||||
|
|
||||||
|
{% block title 'Events'|trans %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
{{ parent() }}
|
||||||
|
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{{ parent() }}
|
||||||
|
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ block('title') }}</h1>
|
||||||
|
|
||||||
|
{{ filter|chill_render_filter_order_helper }}
|
||||||
|
|
||||||
|
{# {% if is_granted('CHILL_EVENT_CREATE') %} #}
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li><a class="btn btn-create" href="{{ chill_path_add_return_path('chill_event__event_new_pickcenter') }}">{{ 'Add an event'|trans }}</a></li>
|
||||||
|
</ul>
|
||||||
|
{# {% endif %} #}
|
||||||
|
{% if events|length > 0 %}
|
||||||
|
<div class="flex-table">
|
||||||
|
{% for e in events %}
|
||||||
|
<div class="item-bloc">
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item-col">
|
||||||
|
<div class="denomination h2">
|
||||||
|
{{ e.name }}
|
||||||
|
</div>
|
||||||
|
<p>{{ e.type.name|localize_translatable_string }}</p>
|
||||||
|
{% if e.moderator is not null %}
|
||||||
|
<p>{{ 'Moderator'|trans }}: {{ e.moderator|chill_entity_render_box }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="item-col">
|
||||||
|
<div class="container" style="text-align: right;">
|
||||||
|
<p>{{ e.date|format_datetime('medium', 'medium') }}</p>
|
||||||
|
<p>{{ 'count participations to this event'|trans({'count': e.participations|length}) }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if e.participations|length > 0 %}
|
||||||
|
<div class="item-row separator">
|
||||||
|
<strong>{{ 'Participations'|trans }} : </strong>
|
||||||
|
{% for part in e.participations|slice(0, 20) %}
|
||||||
|
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||||
|
targetEntity: { name: 'person', id: part.person.id },
|
||||||
|
action: 'show',
|
||||||
|
displayBadge: true,
|
||||||
|
buttonText: part.person|chill_entity_render_string,
|
||||||
|
isDead: part.person.deathdate is not null
|
||||||
|
} %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if e.participations|length > 20 %}
|
||||||
|
{{ 'events.and_other_count_participants'|trans({'count': e.participations|length - 20}) }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{#
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item-col">
|
||||||
|
{{ form_start(eventForms[e.id]) }}
|
||||||
|
{{ form_widget(eventForms[e.id].person_id) }}
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li><button type="submit" class="btn btn-create"></button></li>
|
||||||
|
</ul>
|
||||||
|
{{ form_end(eventForms[e.id]) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
#}
|
||||||
|
<div class="item-row separator">
|
||||||
|
<div class="item-col item-meta">
|
||||||
|
</div>
|
||||||
|
<div class="item-col">
|
||||||
|
<ul class="record_actions">
|
||||||
|
{% if is_granted('CHILL_EVENT_UPDATE', e) %}
|
||||||
|
<li><a href="{{ chill_path_add_return_path('chill_event__event_delete', {'event_id': e.id}) }}" class="btn btn-delete"></a></li>
|
||||||
|
{% endif %}
|
||||||
|
{% if is_granted('CHILL_EVENT_UPDATE', e) %}
|
||||||
|
<li><a href="{{ chill_path_add_return_path('chill_event__event_edit', {'event_id': e.id}) }}" class="btn btn-edit"></a></li>
|
||||||
|
{% endif %}
|
||||||
|
<li><a href="{{ chill_path_add_return_path('chill_event__event_show', {'event_id': e.id}) }}" class="btn btn-show"></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ chill_pagination(pagination) }}
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -0,0 +1,42 @@
|
|||||||
|
<?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\EventBundle\Tests\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
|
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
use Twig\Environment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
class EventListControllerTest extends WebTestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
use PrepareClientTrait;
|
||||||
|
|
||||||
|
private readonly PaginatorFactory $paginatorFactory;
|
||||||
|
private readonly Environment $environment;
|
||||||
|
|
||||||
|
protected function setUp(): void {}
|
||||||
|
|
||||||
|
public function testList(): void
|
||||||
|
{
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
|
||||||
|
$client->request('GET', '/fr/event/event/list');
|
||||||
|
self::assertResponseIsSuccessful();
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,11 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\EventBundle\Tests\Controller;
|
namespace Chill\EventBundle\Tests\Controller;
|
||||||
|
|
||||||
|
use Chill\EventBundle\Entity\Event;
|
||||||
|
use Chill\EventBundle\Repository\EventRepository;
|
||||||
|
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||||
|
use Chill\PersonBundle\DataFixtures\Helper\PersonRandomHelper;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
@ -23,15 +28,12 @@ use function count;
|
|||||||
*/
|
*/
|
||||||
final class ParticipationControllerTest extends WebTestCase
|
final class ParticipationControllerTest extends WebTestCase
|
||||||
{
|
{
|
||||||
/**
|
use PersonRandomHelper;
|
||||||
* @var \Symfony\Component\BrowserKit\AbstractBrowser
|
use PrepareClientTrait;
|
||||||
*/
|
|
||||||
protected $client;
|
|
||||||
|
|
||||||
/**
|
private EntityManagerInterface $em;
|
||||||
* @var \Doctrine\ORM\EntityManagerInterface
|
|
||||||
*/
|
private EventRepository $eventRepository;
|
||||||
protected $em;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep a cache for each person id given by the function getRandomPerson.
|
* Keep a cache for each person id given by the function getRandomPerson.
|
||||||
@ -44,23 +46,21 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
*/
|
*/
|
||||||
private array $personsIdsCache = [];
|
private array $personsIdsCache = [];
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function prepareDI(): void
|
||||||
{
|
{
|
||||||
self::bootKernel();
|
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
$this->eventRepository = self::$container->get(EventRepository::class);
|
||||||
$this->client = self::createClient([], [
|
|
||||||
'PHP_AUTH_USER' => 'center a_social',
|
|
||||||
'PHP_AUTH_PW' => 'password',
|
|
||||||
'HTTP_ACCEPT_LANGUAGE' => 'fr_FR',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$container = self::$kernel->getContainer();
|
|
||||||
|
|
||||||
$this->em = $container->get('doctrine.orm.entity_manager');
|
|
||||||
|
|
||||||
$this->personsIdsCache = [];
|
$this->personsIdsCache = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
parent::tearDown();
|
||||||
|
|
||||||
|
self::ensureKernelShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method test participation creation with wrong parameters.
|
* This method test participation creation with wrong parameters.
|
||||||
*
|
*
|
||||||
@ -68,11 +68,13 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
*/
|
*/
|
||||||
public function testCreateActionWrongParameters()
|
public function testCreateActionWrongParameters()
|
||||||
{
|
{
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
$this->prepareDI();
|
||||||
$event = $this->getRandomEvent();
|
$event = $this->getRandomEvent();
|
||||||
$person = $this->getRandomPerson();
|
$person = $this->getRandomPerson($this->em);
|
||||||
|
|
||||||
// missing person_id or persons_ids
|
// missing person_id or persons_ids
|
||||||
$this->client->request(
|
$client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/create',
|
'/fr/event/participation/create',
|
||||||
[
|
[
|
||||||
@ -81,33 +83,33 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
400,
|
400,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'Test that /fr/event/participation/create fail if '
|
'Test that /fr/event/participation/create fail if '
|
||||||
.'both person_id and persons_ids are missing'
|
.'both person_id and persons_ids are missing'
|
||||||
);
|
);
|
||||||
|
|
||||||
// having both person_id and persons_ids
|
// having both person_id and persons_ids
|
||||||
$this->client->request(
|
$client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/create',
|
'/fr/event/participation/create',
|
||||||
[
|
[
|
||||||
'event_id' => $event->getId(),
|
'event_id' => $event->getId(),
|
||||||
'persons_ids' => implode(',', [
|
'persons_ids' => implode(',', [
|
||||||
$this->getRandomPerson()->getId(),
|
$this->getRandomPerson($this->em)->getId(),
|
||||||
$this->getRandomPerson()->getId(),
|
$this->getRandomPerson($this->em)->getId(),
|
||||||
]),
|
]),
|
||||||
'person_id' => $person->getId(),
|
'person_id' => $person->getId(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
400,
|
400,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'test that /fr/event/participation/create fail if both person_id and '
|
'test that /fr/event/participation/create fail if both person_id and '
|
||||||
.'persons_ids are set'
|
.'persons_ids are set'
|
||||||
);
|
);
|
||||||
|
|
||||||
// missing event_id
|
// missing event_id
|
||||||
$this->client->request(
|
$client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/create',
|
'/fr/event/participation/create',
|
||||||
[
|
[
|
||||||
@ -116,12 +118,12 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
400,
|
400,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'Test that /fr/event/participation/create fails if event_id is missing'
|
'Test that /fr/event/participation/create fails if event_id is missing'
|
||||||
);
|
);
|
||||||
|
|
||||||
// persons_ids with wrong content
|
// persons_ids with wrong content
|
||||||
$this->client->request(
|
$client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/create',
|
'/fr/event/participation/create',
|
||||||
[
|
[
|
||||||
@ -131,42 +133,47 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
400,
|
400,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'Test that /fr/event/participation/create fails if persons_ids has wrong content'
|
'Test that /fr/event/participation/create fails if persons_ids has wrong content'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEditMultipleAction()
|
public function testEditMultipleAction()
|
||||||
{
|
{
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
$this->prepareDI();
|
||||||
|
|
||||||
/** @var \Chill\EventBundle\Entity\Event $event */
|
/** @var \Chill\EventBundle\Entity\Event $event */
|
||||||
$event = $this->getRandomEventWithMultipleParticipations();
|
$event = $this->getRandomEventWithMultipleParticipations();
|
||||||
|
|
||||||
$crawler = $this->client->request('GET', '/fr/event/participation/'.$event->getId().
|
$crawler = $client->request('GET', '/fr/event/participation/'.$event->getId().
|
||||||
'/edit_multiple');
|
'/edit_multiple');
|
||||||
|
|
||||||
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
|
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||||
|
|
||||||
$button = $crawler->selectButton('Mettre à jour');
|
$button = $crawler->selectButton('Mettre à jour');
|
||||||
$this->assertEquals(1, $button->count(), "test the form with button 'mettre à jour' exists ");
|
$this->assertEquals(1, $button->count(), "test the form with button 'mettre à jour' exists ");
|
||||||
|
|
||||||
$this->client->submit($button->form(), [
|
$client->submit($button->form(), [
|
||||||
'form[participations][0][role]' => $event->getType()->getRoles()->first()->getId(),
|
'form[participations][0][role]' => $event->getType()->getRoles()->first()->getId(),
|
||||||
'form[participations][0][status]' => $event->getType()->getStatuses()->first()->getId(),
|
'form[participations][0][status]' => $event->getType()->getStatuses()->first()->getId(),
|
||||||
'form[participations][1][role]' => $event->getType()->getRoles()->last()->getId(),
|
'form[participations][1][role]' => $event->getType()->getRoles()->last()->getId(),
|
||||||
'form[participations][1][status]' => $event->getType()->getStatuses()->last()->getId(),
|
'form[participations][1][status]' => $event->getType()->getStatuses()->last()->getId(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($this->client->getResponse()
|
$this->assertTrue($client->getResponse()
|
||||||
->isRedirect('/fr/event/event/'.$event->getId().'/show'));
|
->isRedirect('/fr/event/event/'.$event->getId().'/show'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNewActionWrongParameters()
|
public function testNewActionWrongParameters()
|
||||||
{
|
{
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
$this->prepareDI();
|
||||||
$event = $this->getRandomEvent();
|
$event = $this->getRandomEvent();
|
||||||
$person = $this->getRandomPerson();
|
$person = $this->getRandomPerson($this->em);
|
||||||
|
|
||||||
// missing person_id or persons_ids
|
// missing person_id or persons_ids
|
||||||
$this->client->request(
|
$client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/new',
|
'/fr/event/participation/new',
|
||||||
[
|
[
|
||||||
@ -175,33 +182,33 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
400,
|
400,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'Test that /fr/event/participation/new fail if '
|
'Test that /fr/event/participation/new fail if '
|
||||||
.'both person_id and persons_ids are missing'
|
.'both person_id and persons_ids are missing'
|
||||||
);
|
);
|
||||||
|
|
||||||
// having both person_id and persons_ids
|
// having both person_id and persons_ids
|
||||||
$this->client->request(
|
$client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/new',
|
'/fr/event/participation/new',
|
||||||
[
|
[
|
||||||
'event_id' => $event->getId(),
|
'event_id' => $event->getId(),
|
||||||
'persons_ids' => implode(',', [
|
'persons_ids' => implode(',', [
|
||||||
$this->getRandomPerson()->getId(),
|
$this->getRandomPerson($this->em)->getId(),
|
||||||
$this->getRandomPerson()->getId(),
|
$this->getRandomPerson($this->em)->getId(),
|
||||||
]),
|
]),
|
||||||
'person_id' => $person->getId(),
|
'person_id' => $person->getId(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
400,
|
400,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'test that /fr/event/participation/new fail if both person_id and '
|
'test that /fr/event/participation/new fail if both person_id and '
|
||||||
.'persons_ids are set'
|
.'persons_ids are set'
|
||||||
);
|
);
|
||||||
|
|
||||||
// missing event_id
|
// missing event_id
|
||||||
$this->client->request(
|
$client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/new',
|
'/fr/event/participation/new',
|
||||||
[
|
[
|
||||||
@ -210,12 +217,12 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
400,
|
400,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'Test that /fr/event/participation/new fails if event_id is missing'
|
'Test that /fr/event/participation/new fails if event_id is missing'
|
||||||
);
|
);
|
||||||
|
|
||||||
// persons_ids with wrong content
|
// persons_ids with wrong content
|
||||||
$this->client->request(
|
$client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/new',
|
'/fr/event/participation/new',
|
||||||
[
|
[
|
||||||
@ -225,13 +232,15 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
400,
|
400,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'Test that /fr/event/participation/new fails if persons_ids has wrong content'
|
'Test that /fr/event/participation/new fails if persons_ids has wrong content'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNewMultipleAction()
|
public function testNewMultipleAction()
|
||||||
{
|
{
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
$this->prepareDI();
|
||||||
$event = $this->getRandomEvent();
|
$event = $this->getRandomEvent();
|
||||||
// record the number of participation for the event (used later in this test)
|
// record the number of participation for the event (used later in this test)
|
||||||
$nbParticipations = $event->getParticipations()->count();
|
$nbParticipations = $event->getParticipations()->count();
|
||||||
@ -244,10 +253,10 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
->toArray()
|
->toArray()
|
||||||
);
|
);
|
||||||
// get some random people
|
// get some random people
|
||||||
$person1 = $this->getRandomPerson();
|
$person1 = $this->getRandomPerson($this->em);
|
||||||
$person2 = $this->getRandomPerson();
|
$person2 = $this->getRandomPerson($this->em);
|
||||||
|
|
||||||
$crawler = $this->client->request(
|
$crawler = $client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/new',
|
'/fr/event/participation/new',
|
||||||
[
|
[
|
||||||
@ -258,7 +267,7 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
200,
|
200,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'test that /fr/event/participation/new is successful'
|
'test that /fr/event/participation/new is successful'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -266,7 +275,7 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
|
|
||||||
$this->assertNotNull($button, "test the form with button 'Créer' exists");
|
$this->assertNotNull($button, "test the form with button 'Créer' exists");
|
||||||
|
|
||||||
$this->client->submit($button->form(), [
|
$client->submit($button->form(), [
|
||||||
'form' => [
|
'form' => [
|
||||||
'participations' => [
|
'participations' => [
|
||||||
0 => [
|
0 => [
|
||||||
@ -281,8 +290,8 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($this->client->getResponse()->isRedirect());
|
$this->assertTrue($client->getResponse()->isRedirect());
|
||||||
$crawler = $this->client->followRedirect();
|
$crawler = $client->followRedirect();
|
||||||
|
|
||||||
$span1 = $crawler->filter('table td span.entity-person a:contains("'
|
$span1 = $crawler->filter('table td span.entity-person a:contains("'
|
||||||
.$person1->getFirstName().'"):contains("'.$person1->getLastname().'")');
|
.$person1->getFirstName().'"):contains("'.$person1->getLastname().'")');
|
||||||
@ -300,13 +309,15 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
|
|
||||||
public function testNewMultipleWithAllPeopleParticipating()
|
public function testNewMultipleWithAllPeopleParticipating()
|
||||||
{
|
{
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
$this->prepareDI();
|
||||||
$event = $this->getRandomEventWithMultipleParticipations();
|
$event = $this->getRandomEventWithMultipleParticipations();
|
||||||
|
|
||||||
$persons_id = implode(',', $event->getParticipations()->map(
|
$persons_id = implode(',', $event->getParticipations()->map(
|
||||||
static fn ($p) => $p->getPerson()->getId()
|
static fn ($p) => $p->getPerson()->getId()
|
||||||
)->toArray());
|
)->toArray());
|
||||||
|
|
||||||
$crawler = $this->client->request(
|
$crawler = $client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/new',
|
'/fr/event/participation/new',
|
||||||
[
|
[
|
||||||
@ -317,13 +328,15 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
302,
|
302,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'test that /fr/event/participation/new is redirecting'
|
'test that /fr/event/participation/new is redirecting'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNewMultipleWithSomePeopleParticipating()
|
public function testNewMultipleWithSomePeopleParticipating()
|
||||||
{
|
{
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
$this->prepareDI();
|
||||||
$event = $this->getRandomEventWithMultipleParticipations();
|
$event = $this->getRandomEventWithMultipleParticipations();
|
||||||
// record the number of participation for the event (used later in this test)
|
// record the number of participation for the event (used later in this test)
|
||||||
$nbParticipations = $event->getParticipations()->count();
|
$nbParticipations = $event->getParticipations()->count();
|
||||||
@ -335,12 +348,12 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
$this->personsIdsCache = array_merge($this->personsIdsCache, $persons_id);
|
$this->personsIdsCache = array_merge($this->personsIdsCache, $persons_id);
|
||||||
|
|
||||||
// get a random person
|
// get a random person
|
||||||
$newPerson = $this->getRandomPerson();
|
$newPerson = $this->getRandomPerson($this->em);
|
||||||
|
|
||||||
// build the `persons_ids` parameter
|
// build the `persons_ids` parameter
|
||||||
$persons_ids_string = implode(',', [...$persons_id, $newPerson->getId()]);
|
$persons_ids_string = implode(',', [...$persons_id, $newPerson->getId()]);
|
||||||
|
|
||||||
$crawler = $this->client->request(
|
$crawler = $client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/new',
|
'/fr/event/participation/new',
|
||||||
[
|
[
|
||||||
@ -351,7 +364,7 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
200,
|
200,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'test that /fr/event/participation/new is successful'
|
'test that /fr/event/participation/new is successful'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -377,12 +390,12 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
$this->assertNotNull($button, "test the form with button 'Créer' exists");
|
$this->assertNotNull($button, "test the form with button 'Créer' exists");
|
||||||
|
|
||||||
// submit the form
|
// submit the form
|
||||||
$this->client->submit($button->form(), [
|
$client->submit($button->form(), [
|
||||||
'participation[role]' => $event->getType()->getRoles()->first()->getId(),
|
'participation[role]' => $event->getType()->getRoles()->first()->getId(),
|
||||||
'participation[status]' => $event->getType()->getStatuses()->first()->getId(),
|
'participation[status]' => $event->getType()->getStatuses()->first()->getId(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($this->client->getResponse()->isRedirect());
|
$this->assertTrue($client->getResponse()->isRedirect());
|
||||||
|
|
||||||
// reload the event and test there is a new participation
|
// reload the event and test there is a new participation
|
||||||
$event = $this->em->getRepository(\Chill\EventBundle\Entity\Event::class)
|
$event = $this->em->getRepository(\Chill\EventBundle\Entity\Event::class)
|
||||||
@ -398,12 +411,14 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
|
|
||||||
public function testNewSingleAction()
|
public function testNewSingleAction()
|
||||||
{
|
{
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
$this->prepareDI();
|
||||||
$event = $this->getRandomEvent();
|
$event = $this->getRandomEvent();
|
||||||
// record the number of participation for the event
|
// record the number of participation for the event
|
||||||
$nbParticipations = $event->getParticipations()->count();
|
$nbParticipations = $event->getParticipations()->count();
|
||||||
$person = $this->getRandomPerson();
|
$person = $this->getRandomPerson($this->em);
|
||||||
|
|
||||||
$crawler = $this->client->request(
|
$crawler = $client->request(
|
||||||
'GET',
|
'GET',
|
||||||
'/fr/event/participation/new',
|
'/fr/event/participation/new',
|
||||||
[
|
[
|
||||||
@ -414,7 +429,7 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
200,
|
200,
|
||||||
$this->client->getResponse()->getStatusCode(),
|
$client->getResponse()->getStatusCode(),
|
||||||
'test that /fr/event/participation/new is successful'
|
'test that /fr/event/participation/new is successful'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -422,13 +437,13 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
|
|
||||||
$this->assertNotNull($button, "test the form with button 'Créer' exists");
|
$this->assertNotNull($button, "test the form with button 'Créer' exists");
|
||||||
|
|
||||||
$this->client->submit($button->form(), [
|
$client->submit($button->form(), [
|
||||||
'participation[role]' => $event->getType()->getRoles()->first()->getId(),
|
'participation[role]' => $event->getType()->getRoles()->first()->getId(),
|
||||||
'participation[status]' => $event->getType()->getStatuses()->first()->getId(),
|
'participation[status]' => $event->getType()->getStatuses()->first()->getId(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($this->client->getResponse()->isRedirect());
|
$this->assertTrue($client->getResponse()->isRedirect());
|
||||||
$crawler = $this->client->followRedirect();
|
$crawler = $client->followRedirect();
|
||||||
|
|
||||||
$span = $crawler->filter('table td span.entity-person a:contains("'
|
$span = $crawler->filter('table td span.entity-person a:contains("'
|
||||||
.$person->getFirstName().'"):contains("'.$person->getLastname().'")');
|
.$person->getFirstName().'"):contains("'.$person->getLastname().'")');
|
||||||
@ -442,23 +457,17 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
$this->assertEquals($nbParticipations + 1, $event->getParticipations()->count());
|
$this->assertEquals($nbParticipations + 1, $event->getParticipations()->count());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function getRandomEvent(string $centerName = 'Center A', string $circleName = 'social'): Event
|
||||||
* @return \Chill\EventBundle\Entity\Event
|
|
||||||
*/
|
|
||||||
protected function getRandomEvent(mixed $centerName = 'Center A', mixed $circleName = 'social')
|
|
||||||
{
|
{
|
||||||
$center = $this->em->getRepository(\Chill\MainBundle\Entity\Center::class)
|
$dql = 'FROM '.Event::class.' e JOIN e.center center JOIN e.circle scope WHERE center.name LIKE :cname AND JSON_EXTRACT(scope.name, \'fr\') LIKE :sname';
|
||||||
->findByName($centerName);
|
|
||||||
|
|
||||||
$circles = $this->em->getRepository(\Chill\MainBundle\Entity\Scope::class)
|
$ids = $this->em->createQuery(
|
||||||
->findAll();
|
'SELECT DISTINCT e.id '.$dql
|
||||||
array_filter($circles, static fn ($circle) => \in_array($circleName, $circle->getName(), true));
|
)
|
||||||
$circle = $circles[0];
|
->setParameters(['cname' => $centerName, 'sname' => $circleName])
|
||||||
|
->getResult();
|
||||||
|
|
||||||
$events = $this->em->getRepository(\Chill\EventBundle\Entity\Event::class)
|
return $this->eventRepository->find($ids[array_rand($ids)]['id']);
|
||||||
->findBy(['center' => $center, 'circle' => $circle]);
|
|
||||||
|
|
||||||
return $events[array_rand($events)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -479,35 +488,4 @@ final class ParticipationControllerTest extends WebTestCase
|
|||||||
$event :
|
$event :
|
||||||
$this->getRandomEventWithMultipleParticipations($centerName, $circleName);
|
$this->getRandomEventWithMultipleParticipations($centerName, $circleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a person randomly.
|
|
||||||
*
|
|
||||||
* This function does not give the same person twice
|
|
||||||
* for each test.
|
|
||||||
*
|
|
||||||
* You may ask to ignore some people by adding their id to the property
|
|
||||||
* `$this->personsIdsCache`
|
|
||||||
*
|
|
||||||
* @param string $centerName
|
|
||||||
*
|
|
||||||
* @return \Chill\PersonBundle\Entity\Person
|
|
||||||
*/
|
|
||||||
protected function getRandomPerson($centerName = 'Center A')
|
|
||||||
{
|
|
||||||
$center = $this->em->getRepository(\Chill\MainBundle\Entity\Center::class)
|
|
||||||
->findByName($centerName);
|
|
||||||
|
|
||||||
$persons = $this->em->getRepository(\Chill\PersonBundle\Entity\Person::class)
|
|
||||||
->findBy(['center' => $center]);
|
|
||||||
|
|
||||||
$person = $persons[array_rand($persons)];
|
|
||||||
|
|
||||||
if (\in_array($person->getId(), $this->personsIdsCache, true)) {
|
|
||||||
return $this->getRandomPerson($centerName); // we try another time
|
|
||||||
}
|
|
||||||
$this->personsIdsCache[] = $person->getId();
|
|
||||||
|
|
||||||
return $person;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
<?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\EventBundle\Tests\Repository;
|
||||||
|
|
||||||
|
use Chill\EventBundle\Repository\EventACLAwareRepository;
|
||||||
|
use Chill\EventBundle\Security\Authorization\EventVoter;
|
||||||
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Chill\MainBundle\Entity\Scope;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
class EventACLAwareRepositoryTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider generateFilters
|
||||||
|
*
|
||||||
|
* @throws \Doctrine\ORM\NoResultException
|
||||||
|
* @throws \Doctrine\ORM\NonUniqueResultException
|
||||||
|
*/
|
||||||
|
public function testCountAllViewable(array $filters): void
|
||||||
|
{
|
||||||
|
$repository = $this->buildEventACLAwareRepository();
|
||||||
|
|
||||||
|
$this->assertGreaterThanOrEqual(0, $repository->countAllViewable($filters));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider generateFilters
|
||||||
|
*/
|
||||||
|
public function testFindAllViewable(array $filters): void
|
||||||
|
{
|
||||||
|
$repository = $this->buildEventACLAwareRepository();
|
||||||
|
|
||||||
|
$this->assertIsArray($repository->findAllViewable($filters));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateFilters(): iterable
|
||||||
|
{
|
||||||
|
yield [[]];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildEventACLAwareRepository(): EventACLAwareRepository
|
||||||
|
{
|
||||||
|
$em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
$user = $em->createQuery('SELECT u FROM '.User::class.' u')
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult()
|
||||||
|
;
|
||||||
|
|
||||||
|
$scopes = $em->createQuery('SELECT s FROM '.Scope::class.' s')
|
||||||
|
->setMaxResults(3)
|
||||||
|
->getResult();
|
||||||
|
|
||||||
|
$centers = $em->createQuery('SELECT c FROM '.Center::class.' c')
|
||||||
|
->setMaxResults(3)
|
||||||
|
->getResult();
|
||||||
|
|
||||||
|
$security = $this->prophesize(Security::class);
|
||||||
|
$security->getUser()->willReturn($user);
|
||||||
|
|
||||||
|
$authorizationHelper = $this->prophesize(AuthorizationHelperForCurrentUserInterface::class);
|
||||||
|
$authorizationHelper->getReachableCenters(EventVoter::SEE)->willReturn($centers);
|
||||||
|
$authorizationHelper->getReachableScopes(EventVoter::SEE, Argument::type(Center::class))->willReturn($scopes);
|
||||||
|
|
||||||
|
return new EventACLAwareRepository(
|
||||||
|
$authorizationHelper->reveal(),
|
||||||
|
$em,
|
||||||
|
$security->reveal()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
services:
|
|
||||||
Chill\EventBundle\Menu\PersonMenuBuilder:
|
|
||||||
arguments:
|
|
||||||
$authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface'
|
|
||||||
$translator: '@Symfony\Contracts\Translation\TranslatorInterface'
|
|
||||||
tags:
|
|
||||||
- { name: 'chill.menu_builder' }
|
|
@ -11,3 +11,11 @@ count participations to this event: >-
|
|||||||
one {Un participant à l'événement}
|
one {Un participant à l'événement}
|
||||||
other {# participants à l'événement}
|
other {# participants à l'événement}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
events:
|
||||||
|
and_other_count_participants: >-
|
||||||
|
{ count, plural,
|
||||||
|
=0 {Aucun autre participant}
|
||||||
|
one {et un autre participant}
|
||||||
|
other {et # autres participants}
|
||||||
|
}
|
@ -107,3 +107,8 @@ csv: csv
|
|||||||
Create a new role: Créer un nouveau rôle
|
Create a new role: Créer un nouveau rôle
|
||||||
Create a new type: Créer un nouveau type
|
Create a new type: Créer un nouveau type
|
||||||
Create a new status: Créer un nouveau statut
|
Create a new status: Créer un nouveau statut
|
||||||
|
|
||||||
|
event:
|
||||||
|
filter:
|
||||||
|
event_types: Par types d'événement
|
||||||
|
event_dates: Par date d'événement
|
||||||
|
@ -20,9 +20,9 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|||||||
class DummyPaginator implements PaginatorFactoryInterface
|
class DummyPaginator implements PaginatorFactoryInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private UrlGeneratorInterface $urlGenerator,
|
private readonly UrlGeneratorInterface $urlGenerator,
|
||||||
private string $route,
|
private readonly string $route,
|
||||||
private array $routeParameters = []
|
private readonly array $routeParameters = []
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public function create(int $totalItems, string $route = null, array $routeParameters = null): PaginatorInterface
|
public function create(int $totalItems, string $route = null, array $routeParameters = null): PaginatorInterface
|
||||||
|
Loading…
x
Reference in New Issue
Block a user