createUser(['ROLE_DOCTOR']), 'دکتر رویداد'); $this->em->persist($doctor); $this->em->flush(); return $doctor; } private function latest(string $name): ?DomainEventLog { return $this->em->getRepository(DomainEventLog::class) ->findOneBy(['name' => $name], ['id' => 'DESC']); } public function testCompletingAnAppointmentRecordsTheEvent(): void { $doctor = $this->makeDoctor(); $start = time() + 86_400; $appointment = $this->newAppointment($doctor, $this->createUser(), $start, $start + 1_800); $this->em->persist($appointment); $this->em->flush(); $this->authJson('PATCH', "/api/v1/appointment/{$appointment->getUuid()}/status", $doctor->getUser(), [ 'status' => Appointment::STATUS_CONFIRMED, 'version' => $appointment->getVersion(), ]); self::assertSame(200, $this->responseCode()); $this->em->clear(); $reloaded = $this->em->getRepository(Appointment::class)->findOneBy(['uuid' => $appointment->getUuid()]); $this->authJson('PATCH', "/api/v1/appointment/{$reloaded->getUuid()}/status", $doctor->getUser(), [ 'status' => Appointment::STATUS_COMPLETED, 'version' => $reloaded->getVersion(), ]); self::assertSame(200, $this->responseCode()); $event = $this->latest(DomainEvents::APPOINTMENT_COMPLETED); self::assertNotNull($event); self::assertSame($appointment->getUuid(), $event->getPayload()['appointment_uuid']); self::assertSame($start, $event->getPayload()['slot_start']); } /** * انتقال ردشده نباید رویداد بگذارد؛ وگرنه گزارش «انجام‌شده»ها از خودِ نوبت‌ها جلو می‌زند. */ public function testARejectedTransitionRecordsNothing(): void { $doctor = $this->makeDoctor(); $start = time() + 86_400; $appointment = $this->newAppointment($doctor, $this->createUser(), $start, $start + 1_800); $this->em->persist($appointment); $this->em->flush(); $before = $this->latest(DomainEvents::APPOINTMENT_COMPLETED); // `pending → completed` در جدول انتقال‌ها نیست. $this->authJson('PATCH', "/api/v1/appointment/{$appointment->getUuid()}/status", $doctor->getUser(), [ 'status' => Appointment::STATUS_COMPLETED, 'version' => $appointment->getVersion(), ]); self::assertSame(422, $this->responseCode()); $after = $this->latest(DomainEvents::APPOINTMENT_COMPLETED); self::assertSame($before?->getId(), $after?->getId()); } }