Files
clinicpro/tests/Dashboard/InvitedDoctorDashboardScopeTest.php
T
hamed f1258d206d feat(migrations): add clinic_id context to weekly_schedules, date_overrides, and holidays
- 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.
2026-07-18 13:32:56 +03:30

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, 'کلینیکی که عضوش نیست، محیط نمی‌سازد');
}
}