createUser(['ROLE_DOCTOR', 'ROLE_CLINIC']); $doctor = new Doctor($user, 'دکتر تست'); $this->em->persist($doctor); $clinic = new Clinic($user); $clinic->setName('کلینیک تست'); $this->em->persist($clinic); $this->em->flush(); return [$user, $doctor, $clinic]; } private function makePeriod(): SubscriptionPeriod { $plan = new SubscriptionPlan('pro-' . bin2hex(random_bytes(4)), 5, 2, ['patient_records' => true]); $this->em->persist($plan); $period = new SubscriptionPeriod($plan, 'سه ماهه', 3, 1_000_000); $this->em->persist($period); $this->em->flush(); return $period; } private function setActiveContext(User $user, string $dbUuid, string $dbType): void { $this->em->persist(new UserActiveContext($user, $dbUuid, $dbType)); $this->em->flush(); } private function service(): SubscriptionService { return static::getContainer()->get(SubscriptionService::class); } public function testGrantingTheClinicLeavesThePersonalPracticeOnFree(): void { [$user, $doctor, $clinic] = $this->makeUserWithBothEnvironments(); $period = $this->makePeriod(); $this->service()->grant('clinic', $clinic->getId(), $period->getUuid(), $user); self::assertSame( $period->getPlan()->getId(), $this->service()->getEffectivePlan('clinic', $clinic->getId())?->getId(), ); self::assertSame('free', $this->service()->getEffectivePlan('doctor', $doctor->getId())?->getName()); self::assertNull($this->service()->getActiveSubscription('doctor', $doctor->getId())); } public function testMyReportsTheClinicPlanOnlyWhileStandingInTheClinic(): void { [$user, $doctor, $clinic] = $this->makeUserWithBothEnvironments(); $period = $this->makePeriod(); $this->service()->grant('clinic', $clinic->getId(), $period->getUuid(), $user); $this->setActiveContext($user, $clinic->getUuid(), EntityContext::TYPE_CLINIC); $body = $this->authJson('GET', '/api/v1/subscription/my', $user); self::assertSame($period->getPlan()->getName(), $body['data']['effective_plan']['name']); self::assertNotNull($body['data']['subscription']); } /** * پزشکِ مهمانِ کلینیکِ دیگری سقف و قابلیت‌هایش را از کلینیکِ میزبان می‌گیرد — چون * سرور هم با همان محیط می‌سنجد — ولی اشتراکِ خودش دست‌نخورده می‌ماند. */ public function testContextPlanFollowsTheHostClinicForAGuestDoctor(): void { $guest = $this->createUser(['ROLE_DOCTOR']); $doctor = new Doctor($guest, 'دکتر مهمان'); $this->em->persist($doctor); $host = new Clinic($this->createUser(['ROLE_CLINIC'])); $host->setName('کلینیک میزبان'); $this->em->persist($host); $this->em->flush(); $host->getDoctors()->add($doctor); $this->em->persist(new ClinicDoctorPermission($host, $doctor)); $this->em->flush(); $period = $this->makePeriod(); $this->service()->grant('clinic', $host->getId(), $period->getUuid(), $host->getUser()); $this->setActiveContext($guest, $host->getUuid(), EntityContext::TYPE_CLINIC); $body = $this->authJson('GET', '/api/v1/subscription/my', $guest); // سقف‌ها از کلینیک میزبان self::assertSame($period->getPlan()->getMaxResources(), $body['data']['context_plan']['max_resources']); self::assertTrue($body['data']['context_plan']['features']['patient_records']); // ولی اشتراکِ خودِ پزشک همچنان free و بدون اشتراک فعال self::assertSame('free', $body['data']['effective_plan']['name']); self::assertNull($body['data']['subscription']); // هویتِ پلنِ محیطِ میزبان افشا نمی‌شود self::assertArrayNotHasKey('name', $body['data']['context_plan']); } public function testMyFallsBackToFreeWhileStandingInThePersonalPractice(): void { [$user, $doctor, $clinic] = $this->makeUserWithBothEnvironments(); $period = $this->makePeriod(); $this->service()->grant('clinic', $clinic->getId(), $period->getUuid(), $user); $this->setActiveContext($user, $doctor->getUuid(), EntityContext::TYPE_DOCTOR); $body = $this->authJson('GET', '/api/v1/subscription/my', $user); self::assertSame('free', $body['data']['effective_plan']['name']); self::assertNull($body['data']['subscription']); } }