userRepository = new InMemoryUserRepository(); $this->clock = new class implements Clock { public function now(): DateTimeImmutable { return new DateTimeImmutable('2026-02-18 10:00:00'); } }; $this->handler = new UpdateImageRightsHandler($this->userRepository, $this->clock); } #[Test] public function updatesImageRightsToAuthorized(): void { $student = $this->createAndSaveStudent(); $command = new UpdateImageRightsCommand( studentId: (string) $student->id, status: 'authorized', modifiedBy: self::MODIFIER_ID, tenantId: self::TENANT_ID, ); $user = ($this->handler)($command); self::assertSame(ImageRightsStatus::AUTHORIZED, $user->imageRightsStatus); } #[Test] public function updatesImageRightsToRefused(): void { $student = $this->createAndSaveStudent(); $command = new UpdateImageRightsCommand( studentId: (string) $student->id, status: 'refused', modifiedBy: self::MODIFIER_ID, tenantId: self::TENANT_ID, ); $user = ($this->handler)($command); self::assertSame(ImageRightsStatus::REFUSED, $user->imageRightsStatus); } #[Test] public function recordsDroitImageModifieEvent(): void { $student = $this->createAndSaveStudent(); $student->pullDomainEvents(); $command = new UpdateImageRightsCommand( studentId: (string) $student->id, status: 'authorized', modifiedBy: self::MODIFIER_ID, tenantId: self::TENANT_ID, ); $user = ($this->handler)($command); $events = $user->pullDomainEvents(); self::assertCount(1, $events); self::assertInstanceOf(DroitImageModifie::class, $events[0]); } #[Test] public function throwsWhenStudentNotFound(): void { $this->expectException(UserNotFoundException::class); $command = new UpdateImageRightsCommand( studentId: '550e8400-e29b-41d4-a716-446655440000', status: 'authorized', modifiedBy: self::MODIFIER_ID, tenantId: self::TENANT_ID, ); ($this->handler)($command); } #[Test] public function throwsWhenTenantMismatch(): void { $student = $this->createAndSaveStudent(); $this->expectException(UserNotFoundException::class); $command = new UpdateImageRightsCommand( studentId: (string) $student->id, status: 'authorized', modifiedBy: self::MODIFIER_ID, tenantId: '550e8400-e29b-41d4-a716-446655440099', ); ($this->handler)($command); } #[Test] public function throwsWhenUserIsNotStudent(): void { $admin = User::creer( email: new Email('admin@example.com'), role: Role::ADMIN, tenantId: TenantId::fromString(self::TENANT_ID), schoolName: 'École Alpha', dateNaissance: null, createdAt: new DateTimeImmutable('2026-01-15 10:00:00'), ); $this->userRepository->save($admin); $this->expectException(UserNotFoundException::class); $command = new UpdateImageRightsCommand( studentId: (string) $admin->id, status: 'authorized', modifiedBy: self::MODIFIER_ID, tenantId: self::TENANT_ID, ); ($this->handler)($command); } #[Test] public function savesUserAfterUpdate(): void { $student = $this->createAndSaveStudent(); $command = new UpdateImageRightsCommand( studentId: (string) $student->id, status: 'refused', modifiedBy: self::MODIFIER_ID, tenantId: self::TENANT_ID, ); ($this->handler)($command); $saved = $this->userRepository->get($student->id); self::assertSame(ImageRightsStatus::REFUSED, $saved->imageRightsStatus); } private function createAndSaveStudent(): User { $student = User::creer( email: new Email('eleve@example.com'), role: Role::ELEVE, tenantId: TenantId::fromString(self::TENANT_ID), schoolName: 'École Alpha', dateNaissance: new DateTimeImmutable('2012-06-15'), createdAt: new DateTimeImmutable('2026-01-15 10:00:00'), ); $this->userRepository->save($student); return $student; } }