createUser(['ROLE_USER', 'ROLE_DOCTOR']); $doctor = new Doctor($user, $name); $doctor->setMobileNumber($user->getMobileNumber()); $this->em->persist($doctor); $this->em->flush(); return $doctor; } /** @return array{0: \App\Auth\Entity\User, 1: Clinic} */ private function makeClinicWith(Doctor ...$doctors): array { $owner = $this->createUser(['ROLE_USER', 'ROLE_CLINIC']); $clinic = new Clinic($owner); $clinic->setName('کلینیک تست بیمه'); foreach ($doctors as $d) { $clinic->getDoctors()->add($d); } $this->em->persist($clinic); $this->em->flush(); return [$owner, $clinic]; } private function makeInsurance(InsuranceType $type = InsuranceType::Basic): Insurance { $insurance = new Insurance('بیمه ' . random_int(1000, 9999), $type); $this->em->persist($insurance); $this->em->flush(); return $insurance; } public function testClinicOwnerCreatesContractForMemberDoctor(): void { $doctor = $this->makeDoctor('دکتر عضو'); [$owner, $clinic] = $this->makeClinicWith($doctor); $insurance = $this->makeInsurance(); $body = $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'doctor_uuid' => $doctor->getUuid(), 'insurance_id' => $insurance->getId(), 'coverage_percent' => 80, ]); self::assertSame(201, $this->responseCode()); self::assertSame('doctor', $body['data']['data']['entity_type']); self::assertSame($doctor->getId(), $body['data']['data']['entity_id']); } public function testContractsAreIsolatedPerDoctor(): void { $first = $this->makeDoctor('دکتر اول'); $second = $this->makeDoctor('دکتر دوم'); [$owner, $clinic] = $this->makeClinicWith($first, $second); $insA = $this->makeInsurance(); $insB = $this->makeInsurance(); $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'doctor_uuid' => $first->getUuid(), 'insurance_id' => $insA->getId(), 'coverage_percent' => 70, ]); $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'doctor_uuid' => $second->getUuid(), 'insurance_id' => $insB->getId(), 'coverage_percent' => 40, ]); $body = $this->authJson('GET', "/api/v1/billing/tenant-insurances?doctor_uuid={$first->getUuid()}", $owner); self::assertSame(200, $this->responseCode()); $insuranceIds = array_map(fn ($r) => $r['insurance_id'], $body['data']['data']); self::assertContains($insA->getId(), $insuranceIds, 'قرارداد پزشک اول باید دیده شود'); self::assertNotContains($insB->getId(), $insuranceIds, 'قرارداد پزشک دوم نباید در فهرست پزشک اول باشد'); } public function testStrangerDoctorUuidIsForbidden(): void { $member = $this->makeDoctor('دکتر عضو'); $outsider = $this->makeDoctor('دکتر بیرونی'); [$owner, $clinic] = $this->makeClinicWith($member); $insurance = $this->makeInsurance(); $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'doctor_uuid' => $outsider->getUuid(), 'insurance_id' => $insurance->getId(), 'coverage_percent' => 50, ]); self::assertSame(403, $this->responseCode(), 'پزشکِ خارج از کلینیک قابل تنظیم نیست'); } public function testUnknownDoctorUuidReturns404(): void { [$owner] = $this->makeClinicWith($this->makeDoctor('دکتر عضو')); $this->authJson('GET', '/api/v1/billing/tenant-insurances?doctor_uuid=' . Uuid::v4()->toRfc4122(), $owner); self::assertSame(404, $this->responseCode()); } public function testWithoutDoctorUuidKeepsLegacyBehavior(): void { $doctor = $this->makeDoctor('دکتر مستقل'); $insurance = $this->makeInsurance(); $body = $this->authJson('POST', '/api/v1/billing/tenant-insurances', $doctor->getUser(), [ 'insurance_id' => $insurance->getId(), 'coverage_percent' => 60, ]); self::assertSame(201, $this->responseCode()); self::assertSame('doctor', $body['data']['data']['entity_type']); self::assertSame($doctor->getId(), $body['data']['data']['entity_id']); } }