Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/config/config_test.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
imports:
- { resource: config_dev.yml }
- { resource: services_test.yaml }

framework:
test: ~
Expand Down
4 changes: 4 additions & 0 deletions app/config/services_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:
AppBundle\Listener\DetectClockMockingListener:
autowire: true
tags: [ kernel.event_listener ]
28 changes: 8 additions & 20 deletions sources/AppBundle/Listener/DetectClockMockingListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
2 changes: 2 additions & 0 deletions tests/behat/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class FeatureContext implements Context
public function __construct()
{
$this->databaseManager = new DatabaseManager(true);

$this->initTimeContext();
}

#[BeforeScenario]
Expand Down
13 changes: 10 additions & 3 deletions tests/behat/bootstrap/TimeContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<date>[^"]*)"$/')]
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')]
Expand Down
23 changes: 15 additions & 8 deletions tests/behat/features/Admin/SuperApero/SuperApero.feature
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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"
Expand All @@ -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"
Expand All @@ -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"
Expand All @@ -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é"
Expand All @@ -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"
Expand All @@ -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"
46 changes: 46 additions & 0 deletions tests/support/TimeMocker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Afup\Tests\Support;

use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;

final readonly class TimeMocker
{
private const MOCK_DIR_PATH = __DIR__ . '/../../var/cache/test/afup/';
private const MOCK_FILE_PATH = self::MOCK_DIR_PATH . 'current-date-mock';

private Filesystem $filesystem;

public function __construct()
{
$this->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;
}
}
}
Loading