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/ai.naniguide.com/tests/Feature/CustomerVerificationServerServiceTest.php
<?php

/**
 * Feature test for the customer-side VerificationServerService — read aggregator
 * powering the rich-redesigned /rui/sending/verification-servers page.
 *
 * Guards:
 *  - headerMeta() returns the 4-key shape (total/active/inactive/vendors)
 *  - sidebarStats() returns DTO with header meta + coverage + capacity
 *  - list() honours keyword + status filters and sort whitelist
 *  - GET /rui/sending/verification-servers renders 200 with rich-redesign markers
 *    (banner-led, no stats-strip, 4-card rail, chart palette in scripts)
 */

use App\Model\Customer;
use App\Model\EmailVerificationServer;
use App\Services\Customer\VerificationServerService;
use App\Services\Plans\Entitlements\EntitlementKey;
use App\Services\Plans\Gates\EntitlementGate;

uses(\Tests\TestCase::class);

beforeEach(function () {
    $hostId = EmailVerificationServer::query()->whereNotNull('customer_id')->value('customer_id');
    $this->customer = $hostId
        ? Customer::find($hostId)
        : Customer::first();
    if (! $this->customer) {
        $this->markTestSkipped('No customer in DB — run DemoSeeder first');
    }
    $this->service = app(VerificationServerService::class);
});

test('headerMeta returns total/active/inactive/vendors integers', function () {
    $meta = $this->service->headerMeta($this->customer);

    expect($meta)->toHaveKeys(['total', 'active', 'inactive', 'vendors']);
    foreach (['total', 'active', 'inactive', 'vendors'] as $k) {
        expect($meta[$k])->toBeInt();
    }
    expect($meta['active'] + $meta['inactive'])->toBe($meta['total']);
});

test('sidebarStats returns DTO with all three pre-shaped payloads', function () {
    $dto = $this->service->sidebarStats($this->customer);

    expect($dto)->toBeInstanceOf(\App\Dto\Refactor\VerificationServer\VerificationServerSidebarStatsDto::class);

    expect($dto->headerMeta)->toHaveKeys(['total', 'active', 'inactive', 'vendors']);
    expect($dto->coverage)->toHaveKeys(['used_vendor_ids', 'catalog']);
    expect($dto->coverage['catalog'])->toBeArray();
    foreach ($dto->coverage['catalog'] as $entry) {
        expect($entry)->toHaveKeys(['id', 'name', 'connected', 'count']);
        expect($entry['connected'])->toBeBool();
    }
    expect($dto->combinedCapacity)->toHaveKeys(['value', 'unit', 'base', 'formatted']);
    expect($dto->combinedCapacity['value'])->toBeInt();
});

test('coverage catalog lists connected vendors first', function () {
    $dto = $this->service->sidebarStats($this->customer);
    $catalog = $dto->coverage['catalog'];

    if (empty($catalog)) {
        $this->markTestSkipped('verification.services config empty');
    }

    $sawDisconnectedAlready = false;
    foreach ($catalog as $entry) {
        if (! $entry['connected']) {
            $sawDisconnectedAlready = true;
            continue;
        }
        // Once we've seen a disconnected entry, no connected entry should follow.
        expect($sawDisconnectedAlready)->toBeFalse();
    }
});

test('list honours status=active — only STATUS_ACTIVE rows', function () {
    $list = $this->service->list($this->customer, null, 'active');

    foreach ($list->items() as $server) {
        expect($server->status)->toBe(EmailVerificationServer::STATUS_ACTIVE);
    }
});

test('list rejects unknown sort column', function () {
    $list = $this->service->list($this->customer, null, null, 'pwned_column', 'asc');
    expect($list)->toBeInstanceOf(\Illuminate\Contracts\Pagination\LengthAwarePaginator::class);
});

test('GET /rui/sending/verification-servers renders 200 with rich-redesign markers', function () {
    if (! EntitlementGate::allows($this->customer, EntitlementKey::HAS_OWN_EMAIL_VERIFICATION_SERVER)) {
        $this->markTestSkipped('Customer plan disallows own verification server');
    }
    $user = $this->customer->user;
    if (! $user) {
        $this->markTestSkipped('No user attached to customer');
    }

    $resp = $this->actingAs($user)->get(route('refactor.sending.verification_servers'));

    $resp->assertStatus(200);
    $resp->assertSee('mc-banner mc-banner-open', false);
    $resp->assertSee('mc-banner-meta', false);
    $resp->assertSee('mc-page-grid', false);
    $resp->assertSee('mc-page-rail', false);
    $resp->assertSee('rui-verifiers-page-grid', false);
    $resp->assertSee('rui-verifiers-rail-card', false);
    // Banner H2 must NOT duplicate the page H1.
    $resp->assertDontSee('>Email verification servers<', false);
});

test('GET listing renders rich row partial', function () {
    if (! EntitlementGate::allows($this->customer, EntitlementKey::HAS_OWN_EMAIL_VERIFICATION_SERVER)) {
        $this->markTestSkipped('Customer plan disallows own verification server');
    }
    $user = $this->customer->user;
    if (! $user) {
        $this->markTestSkipped('No user attached to customer');
    }

    $resp = $this->actingAs($user)->get(route('refactor.sending.verification_servers_listing'));

    $resp->assertStatus(200);
    if (EmailVerificationServer::where('customer_id', $this->customer->id)->count() > 0) {
        $resp->assertSee('rui-verifiers-list-name-cell', false);
        $resp->assertSee('rui-verifiers-list-sub', false);
    }
});