createUser(['ROLE_CLINIC']); $clinic = new Clinic($owner); $this->em->persist($clinic); $doctorA = new Doctor($this->createUser(['ROLE_DOCTOR']), 'دکتر A'); $doctorB = new Doctor($this->createUser(['ROLE_DOCTOR']), 'دکتر B'); $this->em->persist($doctorA); $this->em->persist($doctorB); $clinic->getDoctors()->add($doctorA); $clinic->getDoctors()->add($doctorB); // منشی فقط به دکتر A تخصیص داده شده $secretaryUser = $this->createUser(['ROLE_SECRETARY']); $rel = new DoctorSecretary($doctorA, $secretaryUser, DoctorSecretary::OWNER_CLINIC, $clinic); $this->em->persist($rel); // scope فعالِ منشی = این کلینیک $this->em->persist(new UserActiveContext($secretaryUser, $clinic->getUuid())); // یک نوبت برای هر پزشک $patient = $this->createUser(['ROLE_USER']); $start = time() + 3600; $this->em->persist($this->newAppointment($doctorA, $patient, $start, $start + 900)); $this->em->persist($this->newAppointment($doctorB, $patient, $start + 1800, $start + 2700)); $this->em->flush(); $body = $this->authJson('GET', '/api/v1/my/appointments', $secretaryUser); $this->assertSame(200, $this->responseCode()); // فقط نوبت دکتر A دیده می‌شود، نه دکتر B $this->assertSame(1, $body['meta']['totalRecords']); } public function testSecretaryWithNoAssignmentSeesNothing(): void { $owner = $this->createUser(['ROLE_CLINIC']); $clinic = new Clinic($owner); $this->em->persist($clinic); $doctor = new Doctor($this->createUser(['ROLE_DOCTOR']), 'دکتر تنها'); $this->em->persist($doctor); $clinic->getDoctors()->add($doctor); // منشی context کلینیک دارد ولی رابطه‌ی فعال ندارد $secretaryUser = $this->createUser(['ROLE_SECRETARY']); $this->em->persist(new UserActiveContext($secretaryUser, $clinic->getUuid())); $patient = $this->createUser(['ROLE_USER']); $start = time() + 3600; $this->em->persist($this->newAppointment($doctor, $patient, $start, $start + 900)); $this->em->flush(); $body = $this->authJson('GET', '/api/v1/my/appointments', $secretaryUser); // بدون رابطه‌ی فعال → resolveSecretaryFilter=null → لیست خالی $this->assertSame(0, $body['meta']['totalRecords']); } }