subjectRepository = new InMemorySubjectRepository(); $this->clock = new class implements Clock { public function now(): DateTimeImmutable { return new DateTimeImmutable('2026-02-01 10:00:00'); } }; } #[Test] public function itArchivesSubjectSuccessfully(): void { $subject = $this->createAndSaveSubject(); $handler = new ArchiveSubjectHandler($this->subjectRepository, $this->clock); $command = new ArchiveSubjectCommand( subjectId: (string) $subject->id, tenantId: self::TENANT_ID, ); $archivedSubject = $handler($command); self::assertSame(SubjectStatus::ARCHIVED, $archivedSubject->status); self::assertFalse($archivedSubject->estActive()); self::assertNotNull($archivedSubject->deletedAt); } #[Test] public function itPersistsArchivedSubjectInRepository(): void { $subject = $this->createAndSaveSubject(); $handler = new ArchiveSubjectHandler($this->subjectRepository, $this->clock); $command = new ArchiveSubjectCommand( subjectId: (string) $subject->id, tenantId: self::TENANT_ID, ); $handler($command); // Retrieve from repository $retrievedSubject = $this->subjectRepository->get($subject->id); self::assertSame(SubjectStatus::ARCHIVED, $retrievedSubject->status); } #[Test] public function itThrowsExceptionWhenSubjectNotFound(): void { $handler = new ArchiveSubjectHandler($this->subjectRepository, $this->clock); $this->expectException(SubjectNotFoundException::class); $command = new ArchiveSubjectCommand( subjectId: '550e8400-e29b-41d4-a716-446655440099', tenantId: self::TENANT_ID, ); $handler($command); } #[Test] public function itThrowsExceptionWhenSubjectBelongsToDifferentTenant(): void { $subject = $this->createAndSaveSubject(); $handler = new ArchiveSubjectHandler($this->subjectRepository, $this->clock); $this->expectException(SubjectNotFoundException::class); // Try to archive with a different tenant ID $command = new ArchiveSubjectCommand( subjectId: (string) $subject->id, tenantId: self::OTHER_TENANT_ID, ); $handler($command); } #[Test] public function itIsIdempotentWhenArchivingAlreadyArchivedSubject(): void { $subject = $this->createAndSaveSubject(); $handler = new ArchiveSubjectHandler($this->subjectRepository, $this->clock); $command = new ArchiveSubjectCommand( subjectId: (string) $subject->id, tenantId: self::TENANT_ID, ); // Archive twice $handler($command); $archivedAgain = $handler($command); self::assertSame(SubjectStatus::ARCHIVED, $archivedAgain->status); } private function createAndSaveSubject(): Subject { $subject = Subject::creer( tenantId: TenantId::fromString(self::TENANT_ID), schoolId: SchoolId::fromString(self::SCHOOL_ID), name: new SubjectName('Mathématiques'), code: new SubjectCode('MATH'), color: new SubjectColor('#3B82F6'), createdAt: new DateTimeImmutable('2026-01-15 10:00:00'), ); $this->subjectRepository->save($subject); return $subject; } }