diff --git a/app/config/packages/backoffice_menu.yaml b/app/config/packages/backoffice_menu.yaml index 2f03f1fee..d6ab12a2b 100644 --- a/app/config/packages/backoffice_menu.yaml +++ b/app/config/packages/backoffice_menu.yaml @@ -100,6 +100,14 @@ parameters: - admin_site_articles_list - admin_site_articles_add - admin_site_articles_edit + super_apero_infos: + nom: 'Super Apéro' + niveau: 'ROLE_ADMIN' + url: '/admin/super-apero' + extra_routes: + - admin_super_apero_list + - admin_super_apero_add + - admin_super_apero_edit forum: nom: 'Évènements' niveau: 'ROLE_FORUM' diff --git a/app/config/packages/doctrine.yaml b/app/config/packages/doctrine.yaml index cbf1c485a..29b1215fe 100644 --- a/app/config/packages/doctrine.yaml +++ b/app/config/packages/doctrine.yaml @@ -29,6 +29,11 @@ doctrine: is_bundle: false dir: '%kernel.project_dir%/../sources/AppBundle/Site/Entity' prefix: 'AppBundle\Site\Entity' + SuperApero: + type: attribute + is_bundle: false + dir: '%kernel.project_dir%/../sources/AppBundle/SuperApero/Entity' + prefix: 'AppBundle\SuperApero\Entity' when@test: doctrine: diff --git a/app/config/routing/admin.yml b/app/config/routing/admin.yml index ddbe6dd4f..564f82532 100644 --- a/app/config/routing/admin.yml +++ b/app/config/routing/admin.yml @@ -45,6 +45,10 @@ admin_antennes: resource: "admin_antennes.yml" prefix: /antennes +admin_super_apero: + resource: "admin_super_apero.yml" + prefix: /super-apero + admin_members_reporting: path: /members/reporting defaults: {_controller: AppBundle\Controller\MembershipAdmin\ReportingAction} diff --git a/app/config/routing/admin_super_apero.yml b/app/config/routing/admin_super_apero.yml new file mode 100644 index 000000000..7e7a7fda6 --- /dev/null +++ b/app/config/routing/admin_super_apero.yml @@ -0,0 +1,20 @@ +admin_super_apero_list: + path: / + defaults: {_controller: AppBundle\Controller\Admin\SuperApero\ListAction} + +admin_super_apero_add: + path: /add + defaults: {_controller: AppBundle\Controller\Admin\SuperApero\AddAction} + +admin_super_apero_edit: + path: /edit/{id} + defaults: {_controller: AppBundle\Controller\Admin\SuperApero\EditAction} + requirements: + id: '\d+' + +admin_super_apero_delete: + path: /delete/{id} + defaults: {_controller: AppBundle\Controller\Admin\SuperApero\DeleteAction} + methods: [POST] + requirements: + id: '\d+' diff --git a/db/migrations/20260217124904_create_super_apero_tables.php b/db/migrations/20260217124904_create_super_apero_tables.php new file mode 100644 index 000000000..a890e1a9c --- /dev/null +++ b/db/migrations/20260217124904_create_super_apero_tables.php @@ -0,0 +1,26 @@ +table('super_apero') + ->addColumn('date', 'date', ['null' => false]) + ->create(); + + $this->table('super_apero_meetup') + ->addColumn('super_apero_id', 'integer', [ + 'null' => false, + 'signed' => false, + ]) + ->addColumn('antenne', 'string', ['limit' => 255, 'null' => false]) + ->addColumn('meetup_id', 'integer', ['null' => true]) + ->addColumn('description', 'text', ['null' => true]) + ->addForeignKey('super_apero_id', 'super_apero', 'id', ['delete' => 'CASCADE', 'update' => 'NO_ACTION']) + ->create(); + } +} diff --git a/sources/AppBundle/Controller/Admin/SuperApero/AddAction.php b/sources/AppBundle/Controller/Admin/SuperApero/AddAction.php new file mode 100644 index 000000000..15d1bc07e --- /dev/null +++ b/sources/AppBundle/Controller/Admin/SuperApero/AddAction.php @@ -0,0 +1,43 @@ +createForm(SuperAperoType::class, $superApero); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->superAperoRepository->save($superApero); + $this->audit->log('Ajout du Super Apéro ' . $superApero->annee()); + $this->addFlash('notice', 'Le Super Apéro ' . $superApero->annee() . ' a été ajouté'); + + return $this->redirectToRoute('admin_super_apero_list'); + } + + return $this->render('admin/super_apero/form.html.twig', [ + 'form' => $form->createView(), + 'formTitle' => 'Ajouter un Super Apéro', + 'submitLabel' => 'Ajouter', + ]); + } +} diff --git a/sources/AppBundle/Controller/Admin/SuperApero/DeleteAction.php b/sources/AppBundle/Controller/Admin/SuperApero/DeleteAction.php new file mode 100644 index 000000000..bdcbb1cb3 --- /dev/null +++ b/sources/AppBundle/Controller/Admin/SuperApero/DeleteAction.php @@ -0,0 +1,41 @@ +isCsrfTokenValid('super_apero_delete', $request->request->getString('_token'))) { + $this->addFlash('error', 'Token invalide'); + + return $this->redirectToRoute('admin_super_apero_list'); + } + + $superApero = $this->superAperoRepository->find($id); + + if ($superApero === null) { + throw $this->createNotFoundException('Super apéro non trouvé'); + } + + $annee = $superApero->annee(); + $this->superAperoRepository->delete($superApero); + $this->audit->log('Suppression du Super Apéro ' . $annee); + $this->addFlash('notice', 'Le Super Apéro ' . $annee . ' a été supprimé'); + + return $this->redirectToRoute('admin_super_apero_list'); + } +} diff --git a/sources/AppBundle/Controller/Admin/SuperApero/EditAction.php b/sources/AppBundle/Controller/Admin/SuperApero/EditAction.php new file mode 100644 index 000000000..c2836a502 --- /dev/null +++ b/sources/AppBundle/Controller/Admin/SuperApero/EditAction.php @@ -0,0 +1,47 @@ +superAperoRepository->find($id); + + if (!$superApero instanceof SuperApero) { + throw $this->createNotFoundException('Super apéro non trouvé'); + } + + $form = $this->createForm(SuperAperoType::class, $superApero); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->superAperoRepository->save($superApero); + $this->audit->log('Modification du Super Apéro ' . $superApero->annee()); + $this->addFlash('notice', 'Le Super Apéro ' . $superApero->annee() . ' a été modifié'); + + return $this->redirectToRoute('admin_super_apero_list'); + } + + return $this->render('admin/super_apero/form.html.twig', [ + 'form' => $form->createView(), + 'formTitle' => 'Modifier le Super Apéro ' . $superApero->annee(), + 'submitLabel' => 'Modifier', + ]); + } +} diff --git a/sources/AppBundle/Controller/Admin/SuperApero/ListAction.php b/sources/AppBundle/Controller/Admin/SuperApero/ListAction.php new file mode 100644 index 000000000..5c790c91a --- /dev/null +++ b/sources/AppBundle/Controller/Admin/SuperApero/ListAction.php @@ -0,0 +1,30 @@ +clock->now()->format('Y'); + + return $this->render('admin/super_apero/index.html.twig', [ + 'aperos' => $this->superAperoRepository->getAllSortedByYear(), + 'currentYear' => $currentYear, + 'hasSuperAperoForCurrentYear' => $this->superAperoRepository->findOneByYear($currentYear) instanceof SuperApero, + ]); + } +} diff --git a/sources/AppBundle/Controller/Website/Static/SuperAperoAction.php b/sources/AppBundle/Controller/Website/Static/SuperAperoAction.php index 0d30b18f1..798608b87 100644 --- a/sources/AppBundle/Controller/Website/Static/SuperAperoAction.php +++ b/sources/AppBundle/Controller/Website/Static/SuperAperoAction.php @@ -4,56 +4,30 @@ namespace AppBundle\Controller\Website\Static; +use AppBundle\SuperApero\Entity\Repository\SuperAperoRepository; use AppBundle\Twig\ViewRenderer; -use Symfony\Component\DependencyInjection\Attribute\Autowire; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; final readonly class SuperAperoAction { public function __construct( private ViewRenderer $view, - #[Autowire('%super_apero_csv_url%')] - private string $superAperoCsvUrl, + private SuperAperoRepository $superAperoRepository, + private UrlGeneratorInterface $urlGenerator, ) {} public function __invoke(): Response { - return $this->view->render('site/superapero.html.twig', [ - 'aperos' => $this->getAperos($this->superAperoCsvUrl), - ]); - } + $superApero = $this->superAperoRepository->findActive(); - /** - * @return array{code: (string | null), content: (string | null), meetup_id?: (string | null)}[] - */ - protected function getAperos(string $url): array - { - $fp = fopen($url, 'rb'); - if (!$fp) { - throw new \RuntimeException("Error opening spreadsheet"); + if ($superApero === null) { + return new RedirectResponse($this->urlGenerator->generate('home')); } - $aperos = []; - - while (false !== ($row = fgetcsv($fp))) { - if (trim((string) $row[0]) === '') { - continue; - } - - [$code, $meeetupId, $content] = $row; - - $apero = [ - 'code' => mb_strtolower((string) $code), - 'content' => $content, - ]; - - if (strlen(trim((string) $meeetupId)) !== 0) { - $apero['meetup_id'] = $meeetupId; - } - - $aperos[] = $apero; - } - - return $aperos; + return $this->view->render('site/superapero.html.twig', [ + 'superApero' => $superApero, + ]); } } diff --git a/sources/AppBundle/SuperApero/Entity/Repository/SuperAperoRepository.php b/sources/AppBundle/SuperApero/Entity/Repository/SuperAperoRepository.php new file mode 100644 index 000000000..4635e2899 --- /dev/null +++ b/sources/AppBundle/SuperApero/Entity/Repository/SuperAperoRepository.php @@ -0,0 +1,69 @@ + + */ +final class SuperAperoRepository extends EntityRepository +{ + private ClockInterface $clock; + + public function __construct(ManagerRegistry $registry, ClockInterface $clock) + { + parent::__construct($registry, SuperApero::class); + + $this->clock = $clock; + } + + /** + * @return array + */ + public function getAllSortedByYear(): array + { + return $this->createQueryBuilder('s') + ->orderBy('s.date', 'desc') + ->getQuery() + ->execute(); + } + + public function findOneByYear(int $year): ?SuperApero + { + return $this->createQueryBuilder('s') + ->where('s.date >= :yearStart') + ->andWhere('s.date <= :yearEnd') + ->setParameter('yearStart', new DateTimeImmutable($year . '-01-01')) + ->setParameter('yearEnd', new DateTimeImmutable($year . '-12-31')) + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + } + + public function findActive(): ?SuperApero + { + $now = $this->clock->now(); + + return $this->createQueryBuilder('s') + // Le prochain Super Apéro doit être aujourd'hui ou dans le futur + ->where('s.date >= :now') + // Et doit avoir lieu dans l'année courante + ->andWhere('s.date >= :yearStart') + ->andWhere('s.date <= :yearEnd') + // Et doit avoir au moins un meetup associé + ->innerJoin('s.meetups', 'm') + ->setParameter('now', new DateTimeImmutable($now->format('Y-m-d'))) + ->setParameter('yearStart', new DateTimeImmutable($now->format('Y') . '-01-01')) + ->setParameter('yearEnd', new DateTimeImmutable($now->format('Y') . '-12-31')) + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + } +} diff --git a/sources/AppBundle/SuperApero/Entity/SuperApero.php b/sources/AppBundle/SuperApero/Entity/SuperApero.php new file mode 100644 index 000000000..590c59719 --- /dev/null +++ b/sources/AppBundle/SuperApero/Entity/SuperApero.php @@ -0,0 +1,60 @@ +&iterable */ + #[ORM\OneToMany(targetEntity: SuperAperoMeetup::class, mappedBy: 'superApero', cascade: ['persist', 'remove'], orphanRemoval: true, indexBy: 'antenne')] + public Collection $meetups; + + public function __construct() + { + $this->meetups = new ArrayCollection(); + } + + public function annee(): int + { + return (int) $this->date->format('Y'); + } + + public function addMeetup(SuperAperoMeetup $meetup): void + { + if (!$this->meetups->contains($meetup)) { + $this->meetups->add($meetup); + $meetup->superApero = $this; + } + } + + public function removeMeetup(SuperAperoMeetup $meetup): void + { + $this->meetups->removeElement($meetup); + } + + public function isActive(): bool + { + $now = Clock::get()->now(); + + return $this->annee() === (int) $now->format('Y') + && $this->date >= new DateTimeImmutable($now->format('Y-m-d')) + && !$this->meetups->isEmpty(); + } +} diff --git a/sources/AppBundle/SuperApero/Entity/SuperAperoMeetup.php b/sources/AppBundle/SuperApero/Entity/SuperAperoMeetup.php new file mode 100644 index 000000000..074dac3f3 --- /dev/null +++ b/sources/AppBundle/SuperApero/Entity/SuperAperoMeetup.php @@ -0,0 +1,30 @@ +meetupId = $entity->meetupId; + $data->description = $entity->description; + + return $data; + } + + public function hasValues(): bool + { + return $this->meetupId !== null + || trim((string) $this->description) !== ''; + } +} diff --git a/sources/AppBundle/SuperApero/Form/SuperAperoMeetupType.php b/sources/AppBundle/SuperApero/Form/SuperAperoMeetupType.php new file mode 100644 index 000000000..ff3079f9e --- /dev/null +++ b/sources/AppBundle/SuperApero/Form/SuperAperoMeetupType.php @@ -0,0 +1,36 @@ +add('meetupId', IntegerType::class, [ + 'label' => 'ID Meetup', + 'required' => false, + ]) + ->add('description', TextareaType::class, [ + 'label' => 'Description', + 'required' => false, + 'attr' => ['rows' => 4], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => SuperAperoMeetupFormData::class, + ]); + } +} diff --git a/sources/AppBundle/SuperApero/Form/SuperAperoType.php b/sources/AppBundle/SuperApero/Form/SuperAperoType.php new file mode 100644 index 000000000..63b5eaaa4 --- /dev/null +++ b/sources/AppBundle/SuperApero/Form/SuperAperoType.php @@ -0,0 +1,113 @@ +antenneRepository->getAllSortedByLabels(); + + $builder + ->add('date', DateType::class, [ + 'label' => 'Date', + 'widget' => 'single_text', + 'input' => 'datetime_immutable', + 'required' => true, + ]) + ->add($builder->create('meetups', FormType::class, [ + 'mapped' => false, + 'label' => false, + ])); + + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($antennes): void { + /** @var SuperApero $superApero */ + $superApero = $event->getData(); + + $meetupsForm = $event->getForm()->get('meetups'); + foreach ($antennes as $antenne) { + $existing = $superApero->meetups[$antenne->code] ?? null; + + $meetupsForm->add($antenne->code, SuperAperoMeetupType::class, [ + 'label' => $antenne->label, + 'data' => $existing instanceof SuperAperoMeetup + ? SuperAperoMeetupFormData::fromEntity($existing) + : null, + ]); + } + }); + + $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($antennes): void { + /** @var SuperApero $superApero */ + $superApero = $event->getData(); + $form = $event->getForm(); + + if (isset($superApero->date)) { + $year = $superApero->annee(); + $existing = $this->superAperoRepository->findOneByYear($year); + + if ($existing !== null && $existing->id !== $superApero->id) { + $form->get('date')->addError( + new FormError("Un Super Apéro existe déjà pour l'année {$year}."), + ); + } + } + + $meetupsForm = $form->get('meetups'); + + $submittedAntennes = []; + foreach ($antennes as $antenne) { + /** @var SuperAperoMeetupFormData $data */ + $data = $meetupsForm->get($antenne->code)->getData(); + + if ($data->hasValues()) { + $submittedAntennes[] = $antenne->code; + + if (isset($superApero->meetups[$antenne->code])) { + $superApero->meetups[$antenne->code]->meetupId = $data->meetupId; + $superApero->meetups[$antenne->code]->description = $data->description; + } else { + $meetup = new SuperAperoMeetup(); + $meetup->antenne = $antenne->code; + $meetup->meetupId = $data->meetupId; + $meetup->description = $data->description; + $superApero->addMeetup($meetup); + } + } + } + + foreach ($superApero->meetups->toArray() as $meetup) { + if (!\in_array($meetup->antenne, $submittedAntennes, true)) { + $superApero->removeMeetup($meetup); + } + } + }); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => SuperApero::class, + ]); + } +} diff --git a/templates/admin/super_apero/form.html.twig b/templates/admin/super_apero/form.html.twig new file mode 100644 index 000000000..4c29dde3a --- /dev/null +++ b/templates/admin/super_apero/form.html.twig @@ -0,0 +1,72 @@ +{% extends 'admin/base_with_header.html.twig' %} + +{% form_theme form 'form_theme_admin.html.twig' %} + +{% block content %} +

{{ formTitle }}

+ + {{ form_start(form) }} + +
+
+ {{ form_row(form.date) }} +
+ +
+
+
+ +

Antennes

+ +
+

+ Seules les antennes ayant soit un ID meetup, soit une description seront affichées sur le site. +

+
+ + + + + + + + + + + {% for meetup in form.meetups %} + + + + + + {% endfor %} + +
AntenneID MeetupDescription
{{ meetup.vars.label }} +
+ {{ form_widget(meetup.meetupId) }} +
+
+
+ {{ form_widget(meetup.description) }} +
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+ + {{ form_end(form) }} +{% endblock %} diff --git a/templates/admin/super_apero/index.html.twig b/templates/admin/super_apero/index.html.twig new file mode 100644 index 000000000..16bd6950e --- /dev/null +++ b/templates/admin/super_apero/index.html.twig @@ -0,0 +1,78 @@ +{% extends 'admin/base_with_header.html.twig' %} + +{% block content %} +

Liste des Super Apéros

+ + {% if not hasSuperAperoForCurrentYear %} + + {% endif %} + +
+

+ Un Super Apéro devient actif lorsque sa date est dans l'année courante, n'est pas encore passée et qu'au + moins une des antennes a des informations renseignées.
+ Si un Super Apéro est actif, la page du site affichera les informations. Sinon, elle redirige vers la page d'accueil. +

+
+ + + + + + + + + + + + + {% for apero in aperos %} + + + + + + + + {% endfor %} + +
AnnéeDateAntennesÉtat
{{ apero.annee }}{{ apero.date|date('d/m/Y') }} + {% for meetup in apero.meetups %} + {{ office_name(meetup.antenne) }} + {% endfor %} + + {% if apero.isActive %} + Actif + {% else %} + Inactif + {% endif %} + + + + + +
+ + +
+
+{% endblock %} diff --git a/templates/site/superapero.html.twig b/templates/site/superapero.html.twig index d30cdf9fd..d79bb8d66 100644 --- a/templates/site/superapero.html.twig +++ b/templates/site/superapero.html.twig @@ -39,10 +39,10 @@

Des apéros PHP le même jour dans toutes les antennes !

-

Bloquez votre soirée du mercredi 11 mars et rendez-vous dans votre antenne locale pour une soirée de conférences et d'échanges, où toute la communauté PHP sera invitée à lever son verre pour célébrer le langage !

+

Bloquez votre soirée du {{ superApero.date|format_date(pattern='EEEE d MMMM', locale='fr') }} et rendez-vous dans votre antenne locale pour une soirée de conférences et d'échanges, où toute la communauté PHP sera invitée à lever son verre pour célébrer le langage !

- {% for apero in aperos %} + {% for meetup in superApero.meetups %} {% if loop.index is odd %}
{% endif %} @@ -50,19 +50,19 @@
- +
-

{{ office_name(apero.code) }}

+

{{ office_name(meetup.antenne) }}

-
- {{ apero.content|raw }} +
+ {{ meetup.description|raw }}
- {% if apero.meetup_id is defined %} + {% if meetup.meetupId %} {% endif %}
@@ -73,7 +73,7 @@ {% endif %} {% endfor %} - {% if aperos|length is odd %} + {% if superApero.meetups|length is odd %}
{% endif %}
diff --git a/tests/behat/features/Admin/SuperApero/SuperApero.feature b/tests/behat/features/Admin/SuperApero/SuperApero.feature new file mode 100644 index 000000000..5fad5376f --- /dev/null +++ b/tests/behat/features/Admin/SuperApero/SuperApero.feature @@ -0,0 +1,98 @@ +Feature: Gestion des Super Apéro + + @reloadDbWithTestData + Scenario: Ajout d'un Super Apéro + Given the current date is "2025-01-15 10:00:00" + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/" + Then I should see "Liste des Super Apéros" + When I follow "Planifier le Super Apéro 2025" + Then I should see "Ajouter un Super Apéro" + When I fill in "super_apero[date]" with "2025-03-11" + And I fill in "super_apero[meetups][lyon][meetupId]" with "12345" + And I fill in "super_apero[meetups][paris][description]" with "Super Apéro PHP à Paris" + And I fill in "super_apero[meetups][bordeaux][meetupId]" with "67890" + And I fill in "super_apero[meetups][bordeaux][description]" with "Super Apéro PHP à Bordeaux" + And I press "Ajouter" + Then I should see "Le Super Apéro 2025 a été ajouté" + And I should see "2025" + And I should see "11/03/2025" + And I should see "lyon" + And I should see "paris" + And I should see "bordeaux" + And I should see a green label "Actif" + + Scenario: Activation d'un Super Apéro + Given the current date is "2025-03-11 23:59:59" + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/" + Then I should see "Liste des Super Apéros" + And I should see "2025" + And I should see "11/03/2025" + And I should see a green label "Actif" + When the current date is "2025-03-12 00:00:00" + And I am on "/admin/super-apero/" + Then I should see "Liste des Super Apéros" + And I should see "2025" + And I should see "11/03/2025" + And I should see a grey label "Inactif" + + Scenario: Un seul Super Apéro possible par année + Given the current date is "2025-01-15 10:00:00" + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/add" + When I fill in "super_apero[date]" with "2025-09-20" + And I press "Ajouter" + Then I should see "Un Super Apéro existe déjà pour l'année 2025." + + Scenario: Modifier la date d'un Super Apéro + Given the current date is "2025-01-15 10:00:00" + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/" + When I follow "modifier_1" + Then I should see "Modifier le Super Apéro 2025" + When I fill in "super_apero[date]" with "2025-06-15" + And I press "Modifier" + Then I should see "Le Super Apéro 2025 a été modifié" + And I should see "2025" + And I should see "15/06/2025" + + Scenario: Ajouter une ville à un Super Apéro + Given the current date is "2025-01-15 10:00:00" + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/edit/1" + When I fill in "super_apero[meetups][nantes][meetupId]" with "11111" + And I fill in "super_apero[meetups][nantes][description]" with "Super Apéro PHP à Nantes" + And I press "Modifier" + Then I should see "Le Super Apéro 2025 a été modifié" + And I should see "nantes" + + Scenario: Modifier une ville d'un Super Apéro + Given the current date is "2025-01-15 10:00:00" + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/edit/1" + When I fill in "super_apero[meetups][lyon][meetupId]" with "99999" + And I fill in "super_apero[meetups][lyon][description]" with "Super Apéro PHP à Lyon modifié" + And I fill in "super_apero[meetups][paris][description]" with "Super Apéro PHP à Paris modifié" + And I fill in "super_apero[meetups][bordeaux][meetupId]" with "88888" + And I fill in "super_apero[meetups][bordeaux][description]" with "Super Apéro PHP à Bordeaux modifié" + And I press "Modifier" + Then I should see "Le Super Apéro 2025 a été modifié" + + Scenario: Supprimer une ville d'un Super Apéro + Given the current date is "2025-01-15 10:00:00" + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/edit/1" + When I fill in "super_apero[meetups][nantes][meetupId]" with "" + And I fill in "super_apero[meetups][nantes][description]" with "" + And I press "Modifier" + Then I should see "Le Super Apéro 2025 a été modifié" + And I should not see "nantes" + + Scenario: Supprimer un Super Apéro + Given the current date is "2025-01-15 10:00:00" + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/" + When I press "supprimer_1" + Then I should see "Le Super Apéro 2025 a été supprimé" + And I should not see "15/06/2025" diff --git a/tests/behat/features/PublicSite/SuperApero.feature b/tests/behat/features/PublicSite/SuperApero.feature index 87dc22d34..93414aeba 100644 --- a/tests/behat/features/PublicSite/SuperApero.feature +++ b/tests/behat/features/PublicSite/SuperApero.feature @@ -1,9 +1,44 @@ Feature: Site Public - Super Apéro PHP @reloadDbWithTestData - Scenario: On accède à la page Super Apéro PHP + Scenario: Page du Super Apéro désactivée si aucun Super Apéro pour l'année courante + Given I am on "/super-apero" + Then the current URL should match "#/home#" + + @reloadDbWithTestData + Scenario: Page du Super Apéro désactivée si le Super Apéro de l'année est passé + Given the current date is "2025-02-12 00:00:00" + # Ajout d'un Super Apéro + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/" + Then I should see "Liste des Super Apéros" + When I follow "Planifier le Super Apéro 2025" + Then I should see "Ajouter un Super Apéro" + When I fill in "super_apero[date]" with "2025-02-11" + And I fill in "super_apero[meetups][lyon][meetupId]" with "12345" + And I press "Ajouter" + # Affichage de la page du Super Apéro + Given I am on "/super-apero" + Then the current URL should match "#/home#" + + @reloadDbWithTestData + Scenario: Page du Super Apéro active si un Super Apéro est actif dans l'année courante + Given the current date is "2025-03-11 23:59:59" + # Ajout d'un Super Apéro + And I am logged in as admin and on the Administration + And I am on "/admin/super-apero/" + Then I should see "Liste des Super Apéros" + When I follow "Planifier le Super Apéro 2025" + Then I should see "Ajouter un Super Apéro" + When I fill in "super_apero[date]" with "2025-03-11" + And I fill in "super_apero[meetups][lyon][meetupId]" with "12345" + And I fill in "super_apero[meetups][paris][description]" with "Super Apéro PHP à Paris" + And I fill in "super_apero[meetups][bordeaux][meetupId]" with "67890" + And I fill in "super_apero[meetups][bordeaux][description]" with "Super Apéro PHP à Bordeaux" + And I press "Ajouter" + # Affichage de la page du Super Apéro Given I am on "/super-apero" Then the current URL should match "#/association/super-apero$#" And the "#main h1" element should contain "Super-apéro PHP" - And the response should contain "Super Apéro PHP – Édition Spéciale" - And the response should contain "Super Apéro PHP chez WanadevDigital" + And the response should contain "Super Apéro PHP à Paris" + And the response should contain "Super Apéro PHP à Bordeaux"