tenantId = TenantId::generate(); $this->schoolId = SchoolId::generate(); $this->academicYearId = AcademicYearId::generate(); } #[Test] public function itConfiguresGradingMode(): void { $config = SchoolGradingConfiguration::configurer( tenantId: $this->tenantId, schoolId: $this->schoolId, academicYearId: $this->academicYearId, mode: GradingMode::NUMERIC_20, hasExistingGrades: false, configuredAt: new DateTimeImmutable('2026-02-01'), ); self::assertSame(GradingMode::NUMERIC_20, $config->gradingConfiguration->mode); self::assertSame($this->tenantId, $config->tenantId); self::assertSame($this->schoolId, $config->schoolId); self::assertSame($this->academicYearId, $config->academicYearId); } #[Test] public function itEmitsEventOnCreation(): void { $config = SchoolGradingConfiguration::configurer( tenantId: $this->tenantId, schoolId: $this->schoolId, academicYearId: $this->academicYearId, mode: GradingMode::COMPETENCIES, hasExistingGrades: false, configuredAt: new DateTimeImmutable('2026-02-01'), ); $events = $config->pullDomainEvents(); self::assertCount(1, $events); } #[Test] public function itChangesGradingModeWhenNoGradesExist(): void { $config = SchoolGradingConfiguration::configurer( tenantId: $this->tenantId, schoolId: $this->schoolId, academicYearId: $this->academicYearId, mode: GradingMode::NUMERIC_20, hasExistingGrades: false, configuredAt: new DateTimeImmutable('2026-02-01'), ); $config->pullDomainEvents(); $config->changerMode( nouveauMode: GradingMode::COMPETENCIES, hasExistingGrades: false, at: new DateTimeImmutable('2026-02-02'), ); self::assertSame(GradingMode::COMPETENCIES, $config->gradingConfiguration->mode); $events = $config->pullDomainEvents(); self::assertCount(1, $events); } #[Test] public function itBlocksChangeWhenGradesExist(): void { $config = SchoolGradingConfiguration::configurer( tenantId: $this->tenantId, schoolId: $this->schoolId, academicYearId: $this->academicYearId, mode: GradingMode::NUMERIC_20, hasExistingGrades: false, configuredAt: new DateTimeImmutable('2026-02-01'), ); $this->expectException(CannotChangeGradingModeWithExistingGradesException::class); $config->changerMode( nouveauMode: GradingMode::COMPETENCIES, hasExistingGrades: true, at: new DateTimeImmutable('2026-02-02'), ); } #[Test] public function itDoesNotEmitEventWhenModeIsUnchanged(): void { $config = SchoolGradingConfiguration::configurer( tenantId: $this->tenantId, schoolId: $this->schoolId, academicYearId: $this->academicYearId, mode: GradingMode::NUMERIC_20, hasExistingGrades: false, configuredAt: new DateTimeImmutable('2026-02-01'), ); $config->pullDomainEvents(); $config->changerMode( nouveauMode: GradingMode::NUMERIC_20, hasExistingGrades: false, at: new DateTimeImmutable('2026-02-02'), ); self::assertEmpty($config->pullDomainEvents()); } #[Test] public function itReconstitutesFromStorage(): void { $id = SchoolGradingConfiguration::generateId(); $config = SchoolGradingConfiguration::reconstitute( id: $id, tenantId: $this->tenantId, schoolId: $this->schoolId, academicYearId: $this->academicYearId, gradingConfiguration: new GradingConfiguration(GradingMode::LETTERS), configuredAt: new DateTimeImmutable('2026-02-01'), updatedAt: new DateTimeImmutable('2026-02-02'), ); self::assertSame(GradingMode::LETTERS, $config->gradingConfiguration->mode); self::assertEmpty($config->pullDomainEvents()); } #[Test] public function itBlocksInitialNonDefaultModeWhenGradesExist(): void { $this->expectException(CannotChangeGradingModeWithExistingGradesException::class); SchoolGradingConfiguration::configurer( tenantId: $this->tenantId, schoolId: $this->schoolId, academicYearId: $this->academicYearId, mode: GradingMode::COMPETENCIES, hasExistingGrades: true, configuredAt: new DateTimeImmutable('2026-02-01'), ); } #[Test] public function itAllowsInitialDefaultModeWhenGradesExist(): void { $config = SchoolGradingConfiguration::configurer( tenantId: $this->tenantId, schoolId: $this->schoolId, academicYearId: $this->academicYearId, mode: GradingMode::NUMERIC_20, hasExistingGrades: true, configuredAt: new DateTimeImmutable('2026-02-01'), ); self::assertSame(GradingMode::NUMERIC_20, $config->gradingConfiguration->mode); } #[Test] public function defaultModeIsNumeric20(): void { self::assertSame(GradingMode::NUMERIC_20, SchoolGradingConfiguration::DEFAULT_MODE); } }