- Introduced clinic_id to weekly_schedules, date_overrides, and holidays to differentiate between personal and clinic schedules. - Updated unique constraints and indexes to accommodate the new clinic context. feat(command): create AssignScheduleClinicCommand to move schedules - Added a command to move a doctor's personal weekly schedule into a clinic context. - Implemented checks to ensure sessions align with the target clinic. feat(context): implement EntityContext and EntityContextResolver - Created EntityContext to represent the effective working environment of a request (doctor or clinic). - Developed EntityContextResolver to determine the execution context based on user roles and active contexts. test: add ServiceModeContextTest for appointment scheduling - Implemented tests to ensure service booking respects clinic and personal contexts. - Verified that financial data is omitted in clinic contexts in InvitedDoctorDashboardScopeTest.
84 lines
3.2 KiB
PHP
84 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Dashboard;
|
|
|
|
use App\Clinic\Entity\Clinic;
|
|
use App\Doctor\Entity\Doctor;
|
|
use App\Tests\ApiTestCase;
|
|
|
|
/**
|
|
* داشبورد پزشک در محیط کلینیک نباید هیچ رقم مالی برگرداند. مخفیکردن کارتها در
|
|
* پنل کافی نیست — endpoint مستقیماً قابل صدا زدن است.
|
|
*/
|
|
class InvitedDoctorDashboardScopeTest extends ApiTestCase
|
|
{
|
|
private const FINANCIAL_KEYS = [
|
|
'revenue_period_rials',
|
|
'today_payments_rials',
|
|
'week_payments_rials',
|
|
'sms_wallet_balance',
|
|
];
|
|
|
|
private function makeDoctorInClinic(): array
|
|
{
|
|
$doctorUser = $this->createUser(['ROLE_USER', 'ROLE_DOCTOR']);
|
|
$doctor = new Doctor($doctorUser, 'دکتر دعوتشده');
|
|
$doctor->setMobileNumber($doctorUser->getMobileNumber());
|
|
$this->em->persist($doctor);
|
|
|
|
$clinic = new Clinic($this->createUser(['ROLE_USER', 'ROLE_CLINIC']));
|
|
$clinic->setName('کلینیک میزبان');
|
|
$clinic->getDoctors()->add($doctor);
|
|
$this->em->persist($clinic);
|
|
$this->em->flush();
|
|
|
|
return [$doctor, $clinic];
|
|
}
|
|
|
|
public function testClinicContextOmitsFinancialFields(): void
|
|
{
|
|
[$doctor, $clinic] = $this->makeDoctorInClinic();
|
|
|
|
$body = $this->authJson('GET', "/api/v1/dashboard/doctor?clinic_uuid={$clinic->getUuid()}", $doctor->getUser());
|
|
self::assertSame(200, $this->responseCode());
|
|
|
|
$stats = $body['data']['stats'] ?? [];
|
|
foreach (self::FINANCIAL_KEYS as $key) {
|
|
self::assertArrayNotHasKey($key, $stats, "«{$key}» نباید در محیط کلینیک برگردد");
|
|
}
|
|
|
|
self::assertArrayNotHasKey('revenue_by_day', $body['data']['charts'] ?? []);
|
|
self::assertSame('clinic', $body['data']['context']['type'] ?? null);
|
|
self::assertSame([], $body['data']['clinics'] ?? null, 'فهرست کلینیکها فقط در محیط شخصی معنا دارد');
|
|
}
|
|
|
|
public function testPersonalContextStillReturnsFinancialFields(): void
|
|
{
|
|
[$doctor] = $this->makeDoctorInClinic();
|
|
|
|
$body = $this->authJson('GET', '/api/v1/dashboard/doctor', $doctor->getUser());
|
|
self::assertSame(200, $this->responseCode());
|
|
|
|
$stats = $body['data']['stats'] ?? [];
|
|
foreach (self::FINANCIAL_KEYS as $key) {
|
|
self::assertArrayHasKey($key, $stats);
|
|
}
|
|
|
|
self::assertSame('personal', $body['data']['context']['type'] ?? null);
|
|
}
|
|
|
|
public function testForeignClinicUuidFallsBackToPersonalScope(): void
|
|
{
|
|
[$doctor] = $this->makeDoctorInClinic();
|
|
$outsider = new Clinic($this->createUser(['ROLE_USER', 'ROLE_CLINIC']));
|
|
$outsider->setName('کلینیک بیگانه');
|
|
$this->em->persist($outsider);
|
|
$this->em->flush();
|
|
|
|
$body = $this->authJson('GET', "/api/v1/dashboard/doctor?clinic_uuid={$outsider->getUuid()}", $doctor->getUser());
|
|
|
|
self::assertSame(200, $this->responseCode());
|
|
self::assertSame('personal', $body['data']['context']['type'] ?? null, 'کلینیکی که عضوش نیست، محیط نمیسازد');
|
|
}
|
|
}
|