repository = new InMemoryParentInvitationRepository(); $this->userRepository = new InMemoryUserRepository(); $this->studentId = (string) UserId::generate(); $student = User::reconstitute( id: UserId::fromString($this->studentId), email: null, roles: [Role::ELEVE], tenantId: TenantId::fromString(self::TENANT_ID), schoolName: 'Test School', statut: StatutCompte::INSCRIT, dateNaissance: null, createdAt: new DateTimeImmutable('2026-01-01'), hashedPassword: null, activatedAt: null, consentementParental: null, firstName: 'Camille', lastName: 'Test', ); $this->userRepository->save($student); $clock = new class implements Clock { public function now(): DateTimeImmutable { return new DateTimeImmutable('2026-02-07 10:00:00'); } }; $this->handler = new SendParentInvitationHandler( $this->repository, $this->userRepository, new InvitationCodeGenerator(), $clock, ); } #[Test] public function itCreatesAndSendsInvitation(): void { $createdBy = (string) UserId::generate(); $invitation = ($this->handler)(new SendParentInvitationCommand( tenantId: self::TENANT_ID, studentId: $this->studentId, parentEmail: 'parent@example.com', createdBy: $createdBy, )); self::assertSame(InvitationStatus::SENT, $invitation->status); self::assertSame('parent@example.com', (string) $invitation->parentEmail); self::assertSame($this->studentId, (string) $invitation->studentId); self::assertNotNull($invitation->sentAt); } #[Test] public function itPersistsTheInvitation(): void { $createdBy = (string) UserId::generate(); $invitation = ($this->handler)(new SendParentInvitationCommand( tenantId: self::TENANT_ID, studentId: $this->studentId, parentEmail: 'parent@example.com', createdBy: $createdBy, )); $found = $this->repository->findById($invitation->id, TenantId::fromString(self::TENANT_ID)); self::assertNotNull($found); self::assertSame((string) $invitation->id, (string) $found->id); } #[Test] public function itRecordsInvitationSentEvent(): void { $createdBy = (string) UserId::generate(); $invitation = ($this->handler)(new SendParentInvitationCommand( tenantId: self::TENANT_ID, studentId: $this->studentId, parentEmail: 'parent@example.com', createdBy: $createdBy, )); $events = $invitation->pullDomainEvents(); self::assertCount(1, $events); self::assertInstanceOf(InvitationParentEnvoyee::class, $events[0]); } }