evaluationRepository = new InMemoryEvaluationRepository(); $this->clock = new class implements Clock { public function now(): DateTimeImmutable { return new DateTimeImmutable('2026-03-13 14:00:00'); } }; } #[Test] public function itUpdatesEvaluationSuccessfully(): void { $evaluation = $this->createAndSaveEvaluation(); $handler = $this->createHandler(hasGrades: false); $command = new UpdateEvaluationCommand( tenantId: self::TENANT_ID, evaluationId: (string) $evaluation->id, teacherId: self::TEACHER_ID, title: 'Titre modifié', description: 'Nouvelle description', evaluationDate: '2026-04-20', coefficient: 2.0, ); $updated = $handler($command); self::assertSame('Titre modifié', $updated->title); self::assertSame('Nouvelle description', $updated->description); self::assertSame(2.0, $updated->coefficient->value); } #[Test] public function itAllowsGradeScaleChangeWhenNoGrades(): void { $evaluation = $this->createAndSaveEvaluation(); $handler = $this->createHandler(hasGrades: false); $command = new UpdateEvaluationCommand( tenantId: self::TENANT_ID, evaluationId: (string) $evaluation->id, teacherId: self::TEACHER_ID, title: $evaluation->title, description: $evaluation->description, evaluationDate: '2026-04-15', gradeScale: 10, ); $updated = $handler($command); self::assertSame(10, $updated->gradeScale->maxValue); } #[Test] public function itBlocksGradeScaleChangeWhenGradesExist(): void { $evaluation = $this->createAndSaveEvaluation(); $handler = $this->createHandler(hasGrades: true); $this->expectException(BaremeNonModifiableException::class); $handler(new UpdateEvaluationCommand( tenantId: self::TENANT_ID, evaluationId: (string) $evaluation->id, teacherId: self::TEACHER_ID, title: $evaluation->title, description: $evaluation->description, evaluationDate: '2026-04-15', gradeScale: 10, )); } #[Test] public function itThrowsWhenTeacherIsNotOwner(): void { $evaluation = $this->createAndSaveEvaluation(); $handler = $this->createHandler(hasGrades: false); $this->expectException(NonProprietaireDeLEvaluationException::class); $handler(new UpdateEvaluationCommand( tenantId: self::TENANT_ID, evaluationId: (string) $evaluation->id, teacherId: self::OTHER_TEACHER_ID, title: 'Titre', description: null, evaluationDate: '2026-04-15', )); } #[Test] public function itThrowsWhenEvaluationNotFound(): void { $handler = $this->createHandler(hasGrades: false); $this->expectException(EvaluationNotFoundException::class); $handler(new UpdateEvaluationCommand( tenantId: self::TENANT_ID, evaluationId: '550e8400-e29b-41d4-a716-446655449999', teacherId: self::TEACHER_ID, title: 'Titre', description: null, evaluationDate: '2026-04-15', )); } #[Test] public function itThrowsWhenEvaluationIsDeleted(): void { $evaluation = $this->createAndSaveEvaluation(); $evaluation->supprimer(new DateTimeImmutable('2026-03-13')); $this->evaluationRepository->save($evaluation); $handler = $this->createHandler(hasGrades: false); $this->expectException(EvaluationDejaSupprimeeException::class); $handler(new UpdateEvaluationCommand( tenantId: self::TENANT_ID, evaluationId: (string) $evaluation->id, teacherId: self::TEACHER_ID, title: 'Titre', description: null, evaluationDate: '2026-04-15', )); } private function createHandler(bool $hasGrades): UpdateEvaluationHandler { $gradesChecker = new class($hasGrades) implements EvaluationGradesChecker { public function __construct(private readonly bool $hasGrades) { } public function hasGrades(EvaluationId $evaluationId, TenantId $tenantId): bool { return $this->hasGrades; } }; return new UpdateEvaluationHandler( $this->evaluationRepository, $gradesChecker, $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; } }