duplicator = new HomeworkDuplicator(); } #[Test] public function itDuplicatesHomeworkForOneTargetClass(): void { $source = $this->createSourceHomework(); $now = new DateTimeImmutable('2026-03-14 10:00:00'); $targetClassId = ClassId::fromString(self::TARGET_CLASS_1); $dueDate = new DateTimeImmutable('2026-04-20'); $duplicates = $this->duplicator->dupliquer($source, [$targetClassId], [$dueDate], $now); self::assertCount(1, $duplicates); $duplicate = $duplicates[0]; self::assertSame($source->title, $duplicate->title); self::assertSame($source->description, $duplicate->description); self::assertTrue($duplicate->classId->equals($targetClassId)); self::assertTrue($duplicate->subjectId->equals($source->subjectId)); self::assertTrue($duplicate->teacherId->equals($source->teacherId)); self::assertTrue($duplicate->tenantId->equals($source->tenantId)); self::assertSame('2026-04-20', $duplicate->dueDate->format('Y-m-d')); } #[Test] public function itDuplicatesHomeworkForMultipleTargetClasses(): void { $source = $this->createSourceHomework(); $now = new DateTimeImmutable('2026-03-14 10:00:00'); $targetClasses = [ ClassId::fromString(self::TARGET_CLASS_1), ClassId::fromString(self::TARGET_CLASS_2), ]; $dueDates = [ new DateTimeImmutable('2026-04-20'), new DateTimeImmutable('2026-04-21'), ]; $duplicates = $this->duplicator->dupliquer($source, $targetClasses, $dueDates, $now); self::assertCount(2, $duplicates); self::assertTrue($duplicates[0]->classId->equals($targetClasses[0])); self::assertTrue($duplicates[1]->classId->equals($targetClasses[1])); self::assertSame('2026-04-20', $duplicates[0]->dueDate->format('Y-m-d')); self::assertSame('2026-04-21', $duplicates[1]->dueDate->format('Y-m-d')); } #[Test] public function itCreatesIndependentCopiesWithUniqueIds(): void { $source = $this->createSourceHomework(); $now = new DateTimeImmutable('2026-03-14 10:00:00'); $targetClasses = [ ClassId::fromString(self::TARGET_CLASS_1), ClassId::fromString(self::TARGET_CLASS_2), ]; $dueDates = [ new DateTimeImmutable('2026-04-20'), new DateTimeImmutable('2026-04-20'), ]; $duplicates = $this->duplicator->dupliquer($source, $targetClasses, $dueDates, $now); self::assertFalse($duplicates[0]->id->equals($source->id)); self::assertFalse($duplicates[1]->id->equals($source->id)); self::assertFalse($duplicates[0]->id->equals($duplicates[1]->id)); } #[Test] public function itRecordsDevoirCreeEventForEachDuplicate(): void { $source = $this->createSourceHomework(); $now = new DateTimeImmutable('2026-03-14 10:00:00'); $targetClasses = [ ClassId::fromString(self::TARGET_CLASS_1), ClassId::fromString(self::TARGET_CLASS_2), ]; $dueDates = [ new DateTimeImmutable('2026-04-20'), new DateTimeImmutable('2026-04-20'), ]; $duplicates = $this->duplicator->dupliquer($source, $targetClasses, $dueDates, $now); foreach ($duplicates as $duplicate) { $events = $duplicate->pullDomainEvents(); self::assertCount(1, $events); } } #[Test] public function itUsesSourceDueDateWhenNoneProvided(): void { $source = $this->createSourceHomework(); $now = new DateTimeImmutable('2026-03-14 10:00:00'); $targetClassId = ClassId::fromString(self::TARGET_CLASS_1); $duplicates = $this->duplicator->dupliquer($source, [$targetClassId], [], $now); self::assertSame($source->dueDate->format('Y-m-d'), $duplicates[0]->dueDate->format('Y-m-d')); } #[Test] public function itPreservesNullDescription(): void { $source = $this->createSourceHomework(description: null); $now = new DateTimeImmutable('2026-03-14 10:00:00'); $targetClassId = ClassId::fromString(self::TARGET_CLASS_1); $duplicates = $this->duplicator->dupliquer($source, [$targetClassId], [], $now); self::assertNull($duplicates[0]->description); } private function createSourceHomework(?string $description = 'Faire les exercices 1 à 10'): Homework { return Homework::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: 'Exercices chapitre 5', description: $description, dueDate: new DateTimeImmutable('2026-04-15'), now: new DateTimeImmutable('2026-03-12 10:00:00'), ); } }