diff --git a/app/config/config_test.yml b/app/config/config_test.yml index 4b9d091a6..73feec2da 100644 --- a/app/config/config_test.yml +++ b/app/config/config_test.yml @@ -1,5 +1,6 @@ imports: - { resource: config_dev.yml } + - { resource: services_test.yaml } framework: test: ~ diff --git a/app/config/services_test.yaml b/app/config/services_test.yaml new file mode 100644 index 000000000..e4b53ca9d --- /dev/null +++ b/app/config/services_test.yaml @@ -0,0 +1,4 @@ +services: + AppBundle\Listener\DetectClockMockingListener: + autowire: true + tags: [ kernel.event_listener ] diff --git a/sources/AppBundle/Listener/DetectClockMockingListener.php b/sources/AppBundle/Listener/DetectClockMockingListener.php index e379de2f7..715719714 100644 --- a/sources/AppBundle/Listener/DetectClockMockingListener.php +++ b/sources/AppBundle/Listener/DetectClockMockingListener.php @@ -4,44 +4,32 @@ namespace AppBundle\Listener; +use Afup\Tests\Support\TimeMocker; use Symfony\Component\Clock\Clock; use Symfony\Component\Clock\MockClock; use Symfony\Component\DependencyInjection\Attribute\Autowire; -use Symfony\Component\EventDispatcher\Attribute\AsEventListener; use Symfony\Component\HttpKernel\Event\RequestEvent; -#[AsEventListener] -final class DetectClockMockingListener +final readonly class DetectClockMockingListener { - public const HEADER = 'X-Test-Mock-Clock'; - public function __construct( #[Autowire('%kernel.environment%')] - private readonly string $env, + private string $env, ) {} public function __invoke(RequestEvent $event): void { if ($this->env !== 'test') { + // Le listener est configuré manuellement uniquement dans l'env de test. + // Mais on ne sait jamais alors, alors on vérifie ici au cas où. return; } - if (!$event->isMainRequest()) { - return; - } - - $request = $event->getRequest(); - - if (!$request->headers->has(self::HEADER)) { - return; - } - - $headerValue = $request->headers->get(self::HEADER); - - if ($headerValue === null || $headerValue === '') { + $currentDateMock = (new TimeMocker())->getCurrentDateMock(); + if ($currentDateMock === null) { return; } - Clock::set(new MockClock($headerValue)); + Clock::set(new MockClock($currentDateMock)); } } diff --git a/tests/behat/bootstrap/FeatureContext.php b/tests/behat/bootstrap/FeatureContext.php index 538379e51..c32497a0e 100644 --- a/tests/behat/bootstrap/FeatureContext.php +++ b/tests/behat/bootstrap/FeatureContext.php @@ -30,6 +30,8 @@ class FeatureContext implements Context public function __construct() { $this->databaseManager = new DatabaseManager(true); + + $this->initTimeContext(); } #[BeforeScenario] diff --git a/tests/behat/bootstrap/TimeContext.php b/tests/behat/bootstrap/TimeContext.php index 4fc8f64d0..339f4af27 100644 --- a/tests/behat/bootstrap/TimeContext.php +++ b/tests/behat/bootstrap/TimeContext.php @@ -4,7 +4,7 @@ namespace Afup\Tests\Behat\Bootstrap; -use AppBundle\Listener\DetectClockMockingListener; +use Afup\Tests\Support\TimeMocker; use Behat\Hook\BeforeScenario; use Behat\Step\Given; use Behat\Step\Then; @@ -13,16 +13,23 @@ trait TimeContext { + private TimeMocker $timeMocker; + + private function initTimeContext(): void + { + $this->timeMocker = new TimeMocker(); + } + #[BeforeScenario] public function clearTestClock(): void { - $this->minkContext->getSession()->getDriver()->setRequestHeader(DetectClockMockingListener::HEADER, ''); + $this->timeMocker->clearCurrentDateMock(); } #[Given('/^the current date is "(?P[^"]*)"$/')] public function theCurrentDateIs(string $date): void { - $this->minkContext->getSession()->getDriver()->setRequestHeader(DetectClockMockingListener::HEADER, $date); + $this->timeMocker->setCurrentDateMock($date); } #[Then('the response should contain date :arg1')] diff --git a/tests/behat/features/Admin/SuperApero/SuperApero.feature b/tests/behat/features/Admin/SuperApero/SuperApero.feature index 5fad5376f..470ef9c47 100644 --- a/tests/behat/features/Admin/SuperApero/SuperApero.feature +++ b/tests/behat/features/Admin/SuperApero/SuperApero.feature @@ -4,7 +4,7 @@ Feature: Gestion des Super Apéro 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/" + And I follow "Super Apéro" 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" @@ -25,13 +25,13 @@ Feature: Gestion des Super Apéro 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/" + And I follow "Super Apéro" 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/" + And I follow "Super Apéro" Then I should see "Liste des Super Apéros" And I should see "2025" And I should see "11/03/2025" @@ -40,6 +40,10 @@ Feature: Gestion des Super Apéro 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 follow "Super Apéro" + Then I should not see "Planifier le Super Apéro" + Then I should not see "Planifier le Super Apéro 2025" + # Url en dur car le bouton n'est pas affiché si un super apéro existe déjà pour l'année courante And I am on "/admin/super-apero/add" When I fill in "super_apero[date]" with "2025-09-20" And I press "Ajouter" @@ -48,7 +52,7 @@ Feature: Gestion des Super Apéro 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/" + And I follow "Super Apéro" 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" @@ -60,7 +64,8 @@ Feature: Gestion des Super Apéro 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" + And I follow "Super Apéro" + When I follow "modifier_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" @@ -70,7 +75,8 @@ Feature: Gestion des Super Apéro 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" + And I follow "Super Apéro" + When I follow "modifier_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é" @@ -82,7 +88,8 @@ Feature: Gestion des Super Apéro 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" + And I follow "Super Apéro" + When I follow "modifier_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" @@ -92,7 +99,7 @@ Feature: Gestion des Super Apéro 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/" + And I follow "Super Apéro" 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/support/TimeMocker.php b/tests/support/TimeMocker.php new file mode 100644 index 000000000..f03a38359 --- /dev/null +++ b/tests/support/TimeMocker.php @@ -0,0 +1,46 @@ +filesystem = new Filesystem(); + } + + public function setCurrentDateMock(string $dateString): void + { + $this->filesystem->mkdir(self::MOCK_DIR_PATH); + $this->filesystem->dumpFile(self::MOCK_FILE_PATH, $dateString); + } + + public function clearCurrentDateMock(): void + { + try { + $this->filesystem->remove(self::MOCK_FILE_PATH); + } catch (IOException) { + // Il y a une exception aussi si le fichier n'existe pas + // mais ce n'est pas important à propager. + } + } + + public function getCurrentDateMock(): ?\DateTimeImmutable + { + try { + return new \DateTimeImmutable($this->filesystem->readFile(self::MOCK_FILE_PATH)); + } catch (IOException) { + return null; + } + } +}