Files
Classeo/backend/tests/Unit/Scolarite/Application/Command/DeleteEvaluation/DeleteEvaluationHandlerTest.php
Mathias STRASSER 93baeb1eaa
Some checks failed
CI / Backend Tests (push) Has been cancelled
CI / Frontend Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Naming Conventions (push) Has been cancelled
CI / Build Check (push) Has been cancelled
feat: Permettre à l'enseignant de créer et gérer ses évaluations
Les enseignants avaient besoin de définir les critères de notation
(barème, coefficient) avant de pouvoir saisir des notes. Sans cette
brique, le module Notes & Évaluations (Epic 6) ne pouvait pas démarrer.

L'évaluation est un agrégat du bounded context Scolarité avec deux
Value Objects (GradeScale 1-100, Coefficient 0.1-10). Le barème est
verrouillé dès qu'une note existe pour éviter les incohérences.
Un port EvaluationGradesChecker (stub pour l'instant) sera branché
sur le repository de notes dans la story 6.2.
2026-03-23 23:56:37 +01:00

137 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Unit\Scolarite\Application\Command\DeleteEvaluation;
use App\Administration\Domain\Model\SchoolClass\ClassId;
use App\Administration\Domain\Model\Subject\SubjectId;
use App\Administration\Domain\Model\User\UserId;
use App\Scolarite\Application\Command\DeleteEvaluation\DeleteEvaluationCommand;
use App\Scolarite\Application\Command\DeleteEvaluation\DeleteEvaluationHandler;
use App\Scolarite\Domain\Exception\EvaluationDejaSupprimeeException;
use App\Scolarite\Domain\Exception\EvaluationNotFoundException;
use App\Scolarite\Domain\Exception\NonProprietaireDeLEvaluationException;
use App\Scolarite\Domain\Model\Evaluation\Coefficient;
use App\Scolarite\Domain\Model\Evaluation\Evaluation;
use App\Scolarite\Domain\Model\Evaluation\EvaluationStatus;
use App\Scolarite\Domain\Model\Evaluation\GradeScale;
use App\Scolarite\Infrastructure\Persistence\InMemory\InMemoryEvaluationRepository;
use App\Shared\Domain\Clock;
use App\Shared\Domain\Tenant\TenantId;
use DateTimeImmutable;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
final class DeleteEvaluationHandlerTest extends TestCase
{
private const string TENANT_ID = '550e8400-e29b-41d4-a716-446655440001';
private const string CLASS_ID = '550e8400-e29b-41d4-a716-446655440020';
private const string SUBJECT_ID = '550e8400-e29b-41d4-a716-446655440030';
private const string TEACHER_ID = '550e8400-e29b-41d4-a716-446655440010';
private const string OTHER_TEACHER_ID = '550e8400-e29b-41d4-a716-446655440099';
private InMemoryEvaluationRepository $evaluationRepository;
private Clock $clock;
protected function setUp(): void
{
$this->evaluationRepository = new InMemoryEvaluationRepository();
$this->clock = new class implements Clock {
public function now(): DateTimeImmutable
{
return new DateTimeImmutable('2026-03-14 08:00:00');
}
};
}
#[Test]
public function itSoftDeletesEvaluation(): void
{
$evaluation = $this->createAndSaveEvaluation();
$handler = $this->createHandler();
$result = $handler(new DeleteEvaluationCommand(
tenantId: self::TENANT_ID,
evaluationId: (string) $evaluation->id,
teacherId: self::TEACHER_ID,
));
self::assertSame(EvaluationStatus::DELETED, $result->status);
}
#[Test]
public function itThrowsWhenTeacherIsNotOwner(): void
{
$evaluation = $this->createAndSaveEvaluation();
$handler = $this->createHandler();
$this->expectException(NonProprietaireDeLEvaluationException::class);
$handler(new DeleteEvaluationCommand(
tenantId: self::TENANT_ID,
evaluationId: (string) $evaluation->id,
teacherId: self::OTHER_TEACHER_ID,
));
}
#[Test]
public function itThrowsWhenEvaluationNotFound(): void
{
$handler = $this->createHandler();
$this->expectException(EvaluationNotFoundException::class);
$handler(new DeleteEvaluationCommand(
tenantId: self::TENANT_ID,
evaluationId: '550e8400-e29b-41d4-a716-446655449999',
teacherId: self::TEACHER_ID,
));
}
#[Test]
public function itThrowsWhenAlreadyDeleted(): void
{
$evaluation = $this->createAndSaveEvaluation();
$evaluation->supprimer(new DateTimeImmutable('2026-03-13'));
$this->evaluationRepository->save($evaluation);
$handler = $this->createHandler();
$this->expectException(EvaluationDejaSupprimeeException::class);
$handler(new DeleteEvaluationCommand(
tenantId: self::TENANT_ID,
evaluationId: (string) $evaluation->id,
teacherId: self::TEACHER_ID,
));
}
private function createHandler(): DeleteEvaluationHandler
{
return new DeleteEvaluationHandler(
$this->evaluationRepository,
$this->clock,
);
}
private function createAndSaveEvaluation(): Evaluation
{
$evaluation = Evaluation::creer(
tenantId: TenantId::fromString(self::TENANT_ID),
classId: ClassId::fromString(self::CLASS_ID),
subjectId: SubjectId::fromString(self::SUBJECT_ID),
teacherId: UserId::fromString(self::TEACHER_ID),
title: 'Contrôle chapitre 5',
description: 'Évaluation sur les fonctions',
evaluationDate: new DateTimeImmutable('2026-04-15'),
gradeScale: new GradeScale(20),
coefficient: new Coefficient(1.0),
now: new DateTimeImmutable('2026-03-12 10:00:00'),
);
$this->evaluationRepository->save($evaluation);
return $evaluation;
}
}