feat: Bloquer la création de devoirs non conformes en mode hard
Les établissements utilisant le mode "Hard" des règles de devoirs empêchent désormais les enseignants de créer des devoirs hors règles. Contrairement au mode "Soft" (avertissement avec possibilité de passer outre), le mode "Hard" est un blocage strict : même acknowledgeWarning ne permet pas de contourner. L'API retourne 422 (au lieu de 409 pour le soft) avec des dates conformes suggérées calculées via le calendrier scolaire (weekends, fériés, vacances exclus). Le frontend affiche un modal de blocage avec les raisons, des dates cliquables, et une validation client inline qui empêche la soumission de dates non conformes.
This commit is contained in:
@@ -158,6 +158,33 @@ final class CreateHomeworkHandlerTest extends TestCase
|
||||
$handler($this->createCommand(acknowledgeWarning: true));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function hardBlockingExceptionCarriesSuggestedDatesAndBloquantFlag(): void
|
||||
{
|
||||
$warning = new RuleWarning(
|
||||
ruleType: 'minimum_delay',
|
||||
message: 'Le devoir doit être créé au moins 7 jours avant.',
|
||||
params: ['days' => 7],
|
||||
);
|
||||
$suggestedDates = ['2026-03-25', '2026-03-26', '2026-03-27'];
|
||||
$rulesResult = new HomeworkRulesCheckResult(
|
||||
warnings: [$warning],
|
||||
bloquant: true,
|
||||
suggestedDates: $suggestedDates,
|
||||
);
|
||||
$handler = $this->createHandler(affecte: true, rulesResult: $rulesResult);
|
||||
|
||||
try {
|
||||
$handler($this->createCommand(acknowledgeWarning: false));
|
||||
self::fail('Expected ReglesDevoirsNonRespecteesException');
|
||||
} catch (ReglesDevoirsNonRespecteesException $e) {
|
||||
self::assertTrue($e->bloquant);
|
||||
self::assertSame($suggestedDates, $e->suggestedDates);
|
||||
self::assertCount(1, $e->warnings);
|
||||
self::assertSame('minimum_delay', $e->warnings[0]['ruleType']);
|
||||
}
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function itCreatesHomeworkWhenSoftRulesViolatedButAcknowledged(): void
|
||||
{
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Scolarite\Application\Port;
|
||||
|
||||
use App\Scolarite\Application\Port\HomeworkRulesCheckResult;
|
||||
use App\Scolarite\Application\Port\RuleWarning;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class HomeworkRulesCheckResultTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function okReturnsValidNonBlockingResult(): void
|
||||
{
|
||||
$result = HomeworkRulesCheckResult::ok();
|
||||
|
||||
self::assertTrue($result->estValide());
|
||||
self::assertFalse($result->estAvertissement());
|
||||
self::assertFalse($result->estBloquant());
|
||||
self::assertEmpty($result->warnings);
|
||||
self::assertEmpty($result->suggestedDates);
|
||||
self::assertFalse($result->bloquant);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function estBloquantReturnsTrueWhenBloquantWithWarnings(): void
|
||||
{
|
||||
$result = new HomeworkRulesCheckResult(
|
||||
warnings: [$this->uneWarning()],
|
||||
bloquant: true,
|
||||
);
|
||||
|
||||
self::assertTrue($result->estBloquant());
|
||||
self::assertFalse($result->estAvertissement());
|
||||
self::assertFalse($result->estValide());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function estAvertissementReturnsTrueWhenNonBloquantWithWarnings(): void
|
||||
{
|
||||
$result = new HomeworkRulesCheckResult(
|
||||
warnings: [$this->uneWarning()],
|
||||
bloquant: false,
|
||||
);
|
||||
|
||||
self::assertTrue($result->estAvertissement());
|
||||
self::assertFalse($result->estBloquant());
|
||||
self::assertFalse($result->estValide());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function estValideReturnsFalseWhenBloquantWithoutWarnings(): void
|
||||
{
|
||||
$result = new HomeworkRulesCheckResult(
|
||||
warnings: [],
|
||||
bloquant: true,
|
||||
);
|
||||
|
||||
self::assertTrue($result->estValide());
|
||||
self::assertFalse($result->estBloquant());
|
||||
self::assertFalse($result->estAvertissement());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function suggestedDatesAreStoredAndAccessible(): void
|
||||
{
|
||||
$dates = ['2026-03-25', '2026-03-26', '2026-03-27'];
|
||||
|
||||
$result = new HomeworkRulesCheckResult(
|
||||
warnings: [$this->uneWarning()],
|
||||
bloquant: true,
|
||||
suggestedDates: $dates,
|
||||
);
|
||||
|
||||
self::assertSame($dates, $result->suggestedDates);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function messagesReturnsWarningMessages(): void
|
||||
{
|
||||
$result = new HomeworkRulesCheckResult(
|
||||
warnings: [
|
||||
new RuleWarning('minimum_delay', 'Au moins 3 jours.', ['days' => 3]),
|
||||
new RuleWarning('no_monday_after', 'Pas après vendredi 12h.', []),
|
||||
],
|
||||
bloquant: false,
|
||||
);
|
||||
|
||||
self::assertSame([
|
||||
'Au moins 3 jours.',
|
||||
'Pas après vendredi 12h.',
|
||||
], $result->messages());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function ruleTypesReturnsWarningRuleTypes(): void
|
||||
{
|
||||
$result = new HomeworkRulesCheckResult(
|
||||
warnings: [
|
||||
new RuleWarning('minimum_delay', 'msg1', []),
|
||||
new RuleWarning('no_monday_after', 'msg2', []),
|
||||
],
|
||||
bloquant: false,
|
||||
);
|
||||
|
||||
self::assertSame(['minimum_delay', 'no_monday_after'], $result->ruleTypes());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function toArrayReturnsStructuredWarnings(): void
|
||||
{
|
||||
$result = new HomeworkRulesCheckResult(
|
||||
warnings: [
|
||||
new RuleWarning('minimum_delay', 'Au moins 3 jours.', ['days' => 3]),
|
||||
],
|
||||
bloquant: true,
|
||||
);
|
||||
|
||||
$expected = [
|
||||
[
|
||||
'ruleType' => 'minimum_delay',
|
||||
'message' => 'Au moins 3 jours.',
|
||||
'params' => ['days' => 3],
|
||||
],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $result->toArray());
|
||||
}
|
||||
|
||||
private function uneWarning(): RuleWarning
|
||||
{
|
||||
return new RuleWarning(
|
||||
ruleType: 'minimum_delay',
|
||||
message: 'Le devoir doit être créé au moins 3 jours avant.',
|
||||
params: ['days' => 3],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user