HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/be.naniguide.com/tests/Unit/Plans/EntitlementsServiceTest.php
<?php

/**
 * EntitlementsServiceTest — explicit-enabled boolean entitlements.
 *
 * See docs/payment-order-plan-subscription-saas/SUBSCRIPTION-COMPREHENSIVE-DESIGN.md §6.3, §12 #11.
 */

use App\Model\Customer;
use App\Model\PlanEntitlement;
use App\Model\Plan;
use App\Model\Subscription;
use App\Services\Plans\Entitlements\EntitlementKey;
use App\Services\Plans\Entitlements\EntitlementsService;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;

uses(TestCase::class);

beforeEach(function () {
    $this->customer = Customer::forceCreate([
        'uid'      => uniqid('test_c_'),
        'timezone' => 'UTC',
        'status'   => 'active',
    ]);
    $this->plan     = Plan::forceCreate([
        'uid'              => uniqid('test_plan_'),
        'name'             => 'Test Plan',
        'currency_id'      => 1,
        'frequency_amount' => 1,
        'frequency_unit'   => 'month',
        'price'            => 0,
        'status'           => 'active',
    ]);
    $this->sub      = Subscription::create([
        'uid'                    => (string) \Illuminate\Support\Str::uuid(),
        'customer_id'            => $this->customer->id,
        'plan_id'                => $this->plan->id,
        'status'                 => 'active',
        'current_period_ends_at' => now()->addMonth(),
    ]);

    $this->svc = app(EntitlementsService::class);
});

afterEach(function () {
    DB::table('plan_entitlements')->where('plan_id', $this->plan->id)->delete();
    $this->sub->delete();
    $this->plan->delete();
    $this->customer->delete();
});

test('has returns false when no subscription', function () {
    $this->sub->delete();

    expect($this->svc->has($this->customer, EntitlementKey::HAS_SSO))->toBeFalse();
});

test('has returns false when entitlement row missing', function () {
    expect($this->svc->has($this->customer, EntitlementKey::HAS_SSO))->toBeFalse();
});

test('has returns false when row exists but enabled=false', function () {
    PlanEntitlement::factory()->for($this->plan, 'plan')
        ->forKey(EntitlementKey::HAS_SSO)
        ->create(); // default enabled=false

    expect($this->svc->has($this->customer, EntitlementKey::HAS_SSO))->toBeFalse();
});

test('has returns true when row enabled', function () {
    PlanEntitlement::factory()->for($this->plan, 'plan')
        ->forKey(EntitlementKey::HAS_SSO)
        ->enabled()
        ->create();

    expect($this->svc->has($this->customer, EntitlementKey::HAS_SSO))->toBeTrue();
});

test('seedCatalogForPlan creates full catalog rows', function () {
    $this->svc->seedCatalogForPlan($this->plan->id);

    $count = PlanEntitlement::where('plan_id', $this->plan->id)->count();
    expect($count)->toBe(count(EntitlementKey::cases()));

    // All default false
    $enabled = PlanEntitlement::where('plan_id', $this->plan->id)
        ->where('enabled', true)->count();
    expect($enabled)->toBe(0);
});

test('setEnabled flips the enabled flag', function () {
    $this->svc->seedCatalogForPlan($this->plan->id);

    $this->svc->setEnabled($this->plan->id, EntitlementKey::HAS_API_ACCESS, true);

    expect($this->svc->has($this->customer, EntitlementKey::HAS_API_ACCESS))->toBeTrue();

    $this->svc->setEnabled($this->plan->id, EntitlementKey::HAS_API_ACCESS, false);

    expect($this->svc->has($this->customer, EntitlementKey::HAS_API_ACCESS))->toBeFalse();
});

test('entitlementsOfPlan returns map of every catalog key with enabled flag', function () {
    $this->svc->seedCatalogForPlan($this->plan->id);
    $this->svc->setEnabled($this->plan->id, EntitlementKey::HAS_API_ACCESS, true);

    $map = $this->svc->entitlementsOfPlan($this->plan);

    expect($map)->toHaveCount(count(EntitlementKey::cases()));
    expect($map['has_api_access'])->toBeTrue();
    expect($map['has_sso'])->toBeFalse();
});