115 lines
3.8 KiB
PHP
115 lines
3.8 KiB
PHP
<?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());
|
|
}
|
|
}
|
|
}
|