Files
clinicpro/tests/Resource/ResourceQuotaTest.php

122 lines
5.0 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Tests\Resource;
use App\Resource\Entity\ClinicResource;
use App\Shared\Constant\ErrorCodes;
use App\Subscription\Entity\SubscriptionPlan;
/**
* سقف منابع بر اساس پلن اشتراک: free یک منبع، basic سه، professional بی‌نهایت.
*
* سقف روی همهٔ منابع محیط اعمال می‌شود — فعال و غیرفعال — وگرنه یک بار
* غیرفعال‌کردن، سقف را دور می‌زد.
*/
class ResourceQuotaTest extends ResourceTestCase
{
public function testFreePlanAllowsExactlyOneResource(): void
{
$this->setPlanResourceQuota(1);
[$user, , $address] = $this->clinicWithAddress();
$type = $this->resourceType($address);
$this->createResource($user, $address, $type, ['name' => 'اتاق ۱']);
self::assertSame(201, $this->responseCode());
$body = $this->createResource($user, $address, $type, ['name' => 'اتاق ۲']);
self::assertSame(422, $this->responseCode(), json_encode($body, JSON_UNESCAPED_UNICODE));
self::assertSame(ErrorCodes::ERR_RESOURCE_LIMIT_001, $body['errors'][0]['code']);
}
public function testBasicPlanAllowsThreeResourcesAndRejectsTheFourth(): void
{
$this->setPlanResourceQuota(3);
[$user, , $address] = $this->clinicWithAddress();
$type = $this->resourceType($address);
foreach (['اتاق ۱', 'اتاق ۲', 'اتاق ۳'] as $name) {
$this->createResource($user, $address, $type, ['name' => $name]);
self::assertSame(201, $this->responseCode(), $name);
}
$body = $this->createResource($user, $address, $type, ['name' => 'اتاق ۴']);
self::assertSame(422, $this->responseCode());
self::assertSame(ErrorCodes::ERR_RESOURCE_LIMIT_001, $body['errors'][0]['code']);
self::assertStringContainsString('۳', $this->toPersianDigits($body['errors'][0]['message']));
}
public function testProfessionalPlanIsUnlimited(): void
{
$this->setPlanResourceQuota(SubscriptionPlan::UNLIMITED);
[$user, , $address] = $this->clinicWithAddress();
$type = $this->resourceType($address);
foreach (range(1, 5) as $i) {
$this->createResource($user, $address, $type, ['name' => "اتاق $i"]);
self::assertSame(201, $this->responseCode(), "resource #$i");
}
}
/** غیرفعال‌کردن منبع، جای خالی نمی‌سازد. */
public function testDeactivatedResourcesStillCountTowardTheQuota(): void
{
$this->setPlanResourceQuota(1);
[$user, , $address] = $this->clinicWithAddress();
$type = $this->resourceType($address);
$first = $this->createResource($user, $address, $type, ['name' => 'اتاق ۱']);
$this->authJson('PATCH', '/api/v1/resource/' . $first['data']['uuid'], $user, ['active' => false]);
self::assertSame(200, $this->responseCode());
$this->createResource($user, $address, $type, ['name' => 'اتاق ۲']);
self::assertSame(422, $this->responseCode());
}
/** حذف منبع، جا را واقعاً آزاد می‌کند — شمارش زندهٔ دیتابیس است نه شمارندهٔ ذخیره‌شده. */
public function testDeletingAResourceFreesTheSlot(): void
{
$this->setPlanResourceQuota(1);
[$user, , $address] = $this->clinicWithAddress();
$type = $this->resourceType($address);
$first = $this->createResource($user, $address, $type, ['name' => 'اتاق ۱']);
$this->authJson('DELETE', '/api/v1/resource/' . $first['data']['uuid'], $user);
self::assertSame(200, $this->responseCode());
$this->createResource($user, $address, $type, ['name' => 'اتاق ۲']);
self::assertSame(201, $this->responseCode());
}
/** سقف مالِ همان محیط است؛ پر شدن یک کلینیک، کلینیک دیگر را قفل نمی‌کند. */
public function testQuotaIsCountedPerTenantPair(): void
{
$this->setPlanResourceQuota(1);
[$userA, , $addressA] = $this->clinicWithAddress();
$this->createResource($userA, $addressA, $this->resourceType($addressA), ['name' => 'اتاق A']);
self::assertSame(201, $this->responseCode());
[$userB, , $addressB] = $this->clinicWithAddress('شعبهٔ کلینیک دوم');
$this->createResource($userB, $addressB, $this->resourceType($addressB), ['name' => 'اتاق B']);
self::assertSame(201, $this->responseCode());
self::assertSame(1, $this->em->getRepository(ClinicResource::class)->countForPair(
$addressB->tenantEntityType(),
$addressB->tenantEntityId(),
));
}
private function toPersianDigits(string $value): string
{
return strtr($value, ['0' => '۰', '1' => '۱', '2' => '۲', '3' => '۳', '4' => '۴',
'5' => '۵', '6' => '۶', '7' => '۷', '8' => '۸', '9' => '۹']);
}
}