feat: update user roles and passwords in QA driver, enhance documentation with error codes, and improve trial activation error handling
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\ClinicService;
|
||||
|
||||
use App\ClinicService\Entity\ServiceItem;
|
||||
use App\ClinicService\Entity\ServiceSection;
|
||||
use App\Doctor\Entity\Doctor;
|
||||
use App\Tests\ApiTestCase;
|
||||
|
||||
/**
|
||||
* GET /api/v1/service-items resolves the caller's working context. A user with
|
||||
* neither a doctor profile nor a clinic (admin, secretary, representation, plain
|
||||
* patient) resolves to EntityContext::unknown(), whose id is null — which used
|
||||
* to reach ServiceItemRepository::findByEntity(int $entityId) and fatal with a
|
||||
* 500. It must be a 403 instead.
|
||||
*/
|
||||
class ServiceItemsUnresolvedContextTest extends ApiTestCase
|
||||
{
|
||||
public function testUserWithoutDoctorOrClinicGetsForbiddenNotServerError(): void
|
||||
{
|
||||
foreach ([['ROLE_ADMIN'], ['ROLE_SECRETARY'], ['ROLE_REPRESENTATION'], ['ROLE_USER']] as $roles) {
|
||||
$user = $this->createUser($roles);
|
||||
|
||||
$this->authJson('GET', '/api/v1/service-items', $user);
|
||||
|
||||
$this->assertSame(
|
||||
403,
|
||||
$this->responseCode(),
|
||||
sprintf('roles %s should be forbidden, not a server error', implode(',', $roles)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function testDoctorStillGetsTheirOwnItems(): void
|
||||
{
|
||||
$owner = $this->createUser(['ROLE_DOCTOR']);
|
||||
$doctor = new Doctor($owner, 'دکتر تست محیط');
|
||||
$this->em->persist($doctor);
|
||||
$this->em->flush();
|
||||
|
||||
$section = new ServiceSection('doctor', $doctor->getId(), 'تزریقات');
|
||||
$item = new ServiceItem($section, 'سرم ۵۰۰cc');
|
||||
$this->em->persist($section);
|
||||
$this->em->persist($item);
|
||||
$this->em->flush();
|
||||
|
||||
$body = $this->authJson('GET', '/api/v1/service-items', $owner);
|
||||
|
||||
$this->assertSame(200, $this->responseCode());
|
||||
$this->assertTrue($body['success']);
|
||||
$this->assertContains('سرم ۵۰۰cc', array_column($body['data'], 'name'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Subscription;
|
||||
|
||||
use App\Config\Repository\SiteConfigRepository;
|
||||
use App\Shared\Constant\ErrorCodes;
|
||||
use App\Shared\Exception\AppException;
|
||||
use App\Subscription\Entity\SubscriptionPlan;
|
||||
use App\Subscription\Repository\ClinicSubscriptionRepository;
|
||||
use App\Subscription\Repository\SubscriptionPeriodRepository;
|
||||
use App\Subscription\Repository\SubscriptionPlanRepository;
|
||||
use App\Subscription\Service\SubscriptionService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* A `basic` plan whose trial period has been deactivated is a normal admin
|
||||
* configuration. It used to surface as ERR_NOT_FOUND_001/500; it must now be
|
||||
* the same ERR_TRIAL_DISABLED/422 the trial_enabled flag produces.
|
||||
*/
|
||||
class ActivateTrialTest extends TestCase
|
||||
{
|
||||
private function service(
|
||||
bool $usedTrial,
|
||||
?string $trialEnabled,
|
||||
?SubscriptionPlan $basicPlan,
|
||||
mixed $trialPeriod,
|
||||
): SubscriptionService {
|
||||
$subscriptionRepo = $this->createMock(ClinicSubscriptionRepository::class);
|
||||
$subscriptionRepo->method('hasUsedTrial')->willReturn($usedTrial);
|
||||
|
||||
$planRepo = $this->createMock(SubscriptionPlanRepository::class);
|
||||
$planRepo->method('findByName')->willReturn($basicPlan);
|
||||
|
||||
$periodRepo = $this->createMock(SubscriptionPeriodRepository::class);
|
||||
$periodRepo->method('findTrialPeriodForPlan')->willReturn($trialPeriod);
|
||||
|
||||
$configRepo = $this->createMock(SiteConfigRepository::class);
|
||||
$configRepo->method('get')->willReturn($trialEnabled);
|
||||
|
||||
return new SubscriptionService($subscriptionRepo, $planRepo, $periodRepo, $configRepo);
|
||||
}
|
||||
|
||||
public function testNoActiveTrialPeriodIsReportedAsTrialDisabled(): void
|
||||
{
|
||||
$service = $this->service(
|
||||
usedTrial: false,
|
||||
trialEnabled: '1',
|
||||
basicPlan: $this->createMock(SubscriptionPlan::class),
|
||||
trialPeriod: null,
|
||||
);
|
||||
|
||||
try {
|
||||
$service->activateTrial('doctor', 1);
|
||||
$this->fail('expected AppException');
|
||||
} catch (AppException $e) {
|
||||
$this->assertSame(ErrorCodes::ERR_TRIAL_DISABLED, $e->getErrorCode());
|
||||
$this->assertSame(422, $e->getHttpStatus());
|
||||
}
|
||||
}
|
||||
|
||||
public function testMissingBasicPlanStaysAServerError(): void
|
||||
{
|
||||
$service = $this->service(
|
||||
usedTrial: false,
|
||||
trialEnabled: '1',
|
||||
basicPlan: null,
|
||||
trialPeriod: null,
|
||||
);
|
||||
|
||||
try {
|
||||
$service->activateTrial('doctor', 1);
|
||||
$this->fail('expected AppException');
|
||||
} catch (AppException $e) {
|
||||
$this->assertSame(ErrorCodes::ERR_NOT_FOUND_001, $e->getErrorCode());
|
||||
$this->assertSame(500, $e->getHttpStatus());
|
||||
}
|
||||
}
|
||||
|
||||
public function testAlreadyUsedTrialTakesPrecedence(): void
|
||||
{
|
||||
$service = $this->service(
|
||||
usedTrial: true,
|
||||
trialEnabled: '1',
|
||||
basicPlan: null,
|
||||
trialPeriod: null,
|
||||
);
|
||||
|
||||
try {
|
||||
$service->activateTrial('doctor', 1);
|
||||
$this->fail('expected AppException');
|
||||
} catch (AppException $e) {
|
||||
$this->assertSame(ErrorCodes::ERR_TRIAL_ALREADY_USED, $e->getErrorCode());
|
||||
$this->assertSame(422, $e->getHttpStatus());
|
||||
}
|
||||
}
|
||||
|
||||
public function testDisabledFlagTakesPrecedenceOverMissingPlan(): void
|
||||
{
|
||||
$service = $this->service(
|
||||
usedTrial: false,
|
||||
trialEnabled: '0',
|
||||
basicPlan: null,
|
||||
trialPeriod: null,
|
||||
);
|
||||
|
||||
try {
|
||||
$service->activateTrial('doctor', 1);
|
||||
$this->fail('expected AppException');
|
||||
} catch (AppException $e) {
|
||||
$this->assertSame(ErrorCodes::ERR_TRIAL_DISABLED, $e->getErrorCode());
|
||||
$this->assertSame(422, $e->getHttpStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user