feat(subscription): return plan features for users without subscription permission

This commit is contained in:
hamed
2026-08-04 12:54:12 +03:30
parent 85a27812c7
commit 4653cd0e4a
3 changed files with 68 additions and 9 deletions
@@ -272,23 +272,39 @@ class SecretaryResourceEnforcementTest extends ApiTestCase
$this->assertSame(403, $this->responseCode());
}
public function testSubscriptionDeniedByDefault(): void
/**
* بدون مجوز اشتراک، `subscription/my` می‌ماند ولی فقط قابلیت‌های پلن را می‌دهد:
* پنل بدون این فهرست، آیتم‌های feature-دار منو را قفل نشان می‌داد در حالی که خودِ
* API آن‌ها را به منشی می‌دهد. وضعیت/تاریخ اشتراک همچنان پنهان است.
*/
public function testSubscriptionWithoutPermissionReturnsFeaturesOnly(): void
{
[$secretary] = $this->makeClinicSecretary();
$this->em->flush();
$this->authJson('GET', '/api/v1/subscription/my', $secretary);
$this->assertSame(403, $this->responseCode());
$res = $this->authJson('GET', '/api/v1/subscription/my', $secretary);
$this->assertSame(200, $this->responseCode());
$this->assertNull($res['data']['subscription']);
$this->assertFalse($res['data']['used_trial']);
$this->assertArrayHasKey('features', $res['data']['effective_plan']);
$this->assertTrue($res['data']['effective_plan']['features']['patient_records']);
// فیلدهای مالی/هویتیِ پلن نباید بیایند.
$this->assertArrayNotHasKey('periods', $res['data']['effective_plan']);
$this->assertArrayNotHasKey('name', $res['data']['effective_plan']);
}
/** با مجوز، پاسخ کامل است — نه نسخهٔ کاهش‌یافته. */
public function testSubscriptionAllowedWhenGranted(): void
{
[$secretary, $rel] = $this->makeClinicSecretary();
$rel->mergePermissions(['resources' => ['subscription' => ['view' => true]]]);
$this->em->flush();
$this->authJson('GET', '/api/v1/subscription/my', $secretary);
$res = $this->authJson('GET', '/api/v1/subscription/my', $secretary);
$this->assertSame(200, $this->responseCode());
$this->assertArrayHasKey('name', $res['data']['effective_plan']);
$this->assertArrayHasKey('used_trial', $res['data']);
}
public function testPatientDeleteSeparateFromUpdate(): void