Les enseignants avaient besoin d'un outil pour créer des devoirs assignés à leurs classes, avec filtrage automatique par matière selon la classe sélectionnée. Le système valide que la date d'échéance tombe un jour ouvrable (lundi-vendredi) et empêche les dates dans le passé. Le domaine modélise le devoir comme un agrégat avec pièces jointes, statut brouillon/publié, et événements métier (création, modification, suppression). Les handlers de notification écoutent ces événements pour les futurs envois aux parents et élèves.
139 lines
4.5 KiB
PHP
139 lines
4.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Unit\Scolarite\Domain\Service;
|
|
|
|
use App\Administration\Domain\Model\SchoolCalendar\CalendarEntry;
|
|
use App\Administration\Domain\Model\SchoolCalendar\CalendarEntryId;
|
|
use App\Administration\Domain\Model\SchoolCalendar\CalendarEntryType;
|
|
use App\Administration\Domain\Model\SchoolCalendar\SchoolCalendar;
|
|
use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
|
|
use App\Scolarite\Domain\Exception\DateEcheanceInvalideException;
|
|
use App\Scolarite\Domain\Service\DueDateValidator;
|
|
use App\Shared\Domain\Tenant\TenantId;
|
|
use DateTimeImmutable;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class DueDateValidatorTest extends TestCase
|
|
{
|
|
private DueDateValidator $validator;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->validator = new DueDateValidator();
|
|
}
|
|
|
|
#[Test]
|
|
public function acceptsValidFutureSchoolDay(): void
|
|
{
|
|
$now = new DateTimeImmutable('2026-03-12 10:00:00'); // Jeudi
|
|
$dueDate = new DateTimeImmutable('2026-03-16'); // Lundi
|
|
$calendar = $this->createEmptyCalendar();
|
|
|
|
$this->validator->valider($dueDate, $now, $calendar);
|
|
|
|
$this->addToAssertionCount(1);
|
|
}
|
|
|
|
#[Test]
|
|
public function rejectsPastDate(): void
|
|
{
|
|
$now = new DateTimeImmutable('2026-03-12 10:00:00');
|
|
$dueDate = new DateTimeImmutable('2026-03-11');
|
|
$calendar = $this->createEmptyCalendar();
|
|
|
|
$this->expectException(DateEcheanceInvalideException::class);
|
|
$this->expectExceptionMessageMatches('/futur/');
|
|
|
|
$this->validator->valider($dueDate, $now, $calendar);
|
|
}
|
|
|
|
#[Test]
|
|
public function rejectsTodayDate(): void
|
|
{
|
|
$now = new DateTimeImmutable('2026-03-12 10:00:00');
|
|
$dueDate = new DateTimeImmutable('2026-03-12');
|
|
$calendar = $this->createEmptyCalendar();
|
|
|
|
$this->expectException(DateEcheanceInvalideException::class);
|
|
$this->expectExceptionMessageMatches('/futur/');
|
|
|
|
$this->validator->valider($dueDate, $now, $calendar);
|
|
}
|
|
|
|
#[Test]
|
|
public function acceptsTomorrowDate(): void
|
|
{
|
|
$now = new DateTimeImmutable('2026-03-12 10:00:00'); // Jeudi
|
|
$dueDate = new DateTimeImmutable('2026-03-13'); // Vendredi
|
|
$calendar = $this->createEmptyCalendar();
|
|
|
|
$this->validator->valider($dueDate, $now, $calendar);
|
|
|
|
$this->addToAssertionCount(1);
|
|
}
|
|
|
|
#[Test]
|
|
public function rejectsWeekendDate(): void
|
|
{
|
|
$now = new DateTimeImmutable('2026-03-12 10:00:00');
|
|
$dueDate = new DateTimeImmutable('2026-03-14'); // Samedi
|
|
$calendar = $this->createEmptyCalendar();
|
|
|
|
$this->expectException(DateEcheanceInvalideException::class);
|
|
$this->expectExceptionMessageMatches('/weekend/');
|
|
|
|
$this->validator->valider($dueDate, $now, $calendar);
|
|
}
|
|
|
|
#[Test]
|
|
public function rejectsHolidayDate(): void
|
|
{
|
|
$now = new DateTimeImmutable('2026-03-12 10:00:00');
|
|
$dueDate = new DateTimeImmutable('2026-04-06'); // Lundi
|
|
$calendar = $this->createCalendarWithVacation(
|
|
new DateTimeImmutable('2026-04-04'),
|
|
new DateTimeImmutable('2026-04-19'),
|
|
'Vacances de printemps',
|
|
);
|
|
|
|
$this->expectException(DateEcheanceInvalideException::class);
|
|
$this->expectExceptionMessageMatches('/Vacances de printemps/');
|
|
|
|
$this->validator->valider($dueDate, $now, $calendar);
|
|
}
|
|
|
|
private function createEmptyCalendar(): SchoolCalendar
|
|
{
|
|
return SchoolCalendar::reconstitute(
|
|
tenantId: TenantId::fromString('550e8400-e29b-41d4-a716-446655440001'),
|
|
academicYearId: AcademicYearId::fromString('550e8400-e29b-41d4-a716-446655440002'),
|
|
zone: null,
|
|
entries: [],
|
|
);
|
|
}
|
|
|
|
private function createCalendarWithVacation(
|
|
DateTimeImmutable $start,
|
|
DateTimeImmutable $end,
|
|
string $label,
|
|
): SchoolCalendar {
|
|
return SchoolCalendar::reconstitute(
|
|
tenantId: TenantId::fromString('550e8400-e29b-41d4-a716-446655440001'),
|
|
academicYearId: AcademicYearId::fromString('550e8400-e29b-41d4-a716-446655440002'),
|
|
zone: null,
|
|
entries: [
|
|
new CalendarEntry(
|
|
id: CalendarEntryId::generate(),
|
|
type: CalendarEntryType::VACATION,
|
|
startDate: $start,
|
|
endDate: $end,
|
|
label: $label,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|