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/CustomerSendingServerServiceTest.php
<?php

/**
 * Feature test for the customer-side SendingServerService — read aggregator
 * powering the rich-redesigned /rui/sending/servers page.
 */

use App\Model\Customer;
use App\Model\SendingServer;
use App\Services\Customer\SendingServerService;

uses(\Tests\TestCase::class);

beforeEach(function () {
    $hostId = SendingServer::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(SendingServerService::class);
});

test('headerMeta returns 5-key shape with integers', function () {
    $meta = $this->service->headerMeta($this->customer);

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

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

    expect($dto)->toBeInstanceOf(\App\Dto\Refactor\SendingServer\SendingServerSidebarStatsDto::class);

    expect($dto->headerMeta)->toHaveKeys(['total', 'active', 'inactive', 'warmup', 'vendors']);

    expect($dto->vendorMix)->toHaveKeys(['slices', 'total']);
    expect($dto->vendorMix['slices'])->toBeArray();
    foreach ($dto->vendorMix['slices'] as $s) {
        expect($s)->toHaveKeys(['key', 'name', 'count']);
        expect($s['count'])->toBeInt();
    }

    expect($dto->throughput)->toHaveKeys(['total_per_hour', 'formatted', 'by_vendor']);
    expect($dto->throughput['total_per_hour'])->toBeInt();

    expect($dto->warmupStatus)->toHaveKeys(['enabled', 'disabled', 'started']);
    foreach (['enabled', 'disabled', 'started'] as $k) {
        expect($dto->warmupStatus[$k])->toBeInt();
    }

    expect($dto->coverage)->toHaveKeys(['used_vendor_keys', 'catalog']);
});

test('vendorMix slice counts sum to total', function () {
    $dto = $this->service->sidebarStats($this->customer);
    $sum = array_sum(array_column($dto->vendorMix['slices'], 'count'));
    expect($sum)->toBe($dto->vendorMix['total']);
});

test('throughput by_vendor sum matches total_per_hour', function () {
    $dto = $this->service->sidebarStats($this->customer);
    if (empty($dto->throughput['by_vendor'])) {
        $this->markTestSkipped('No throughput data');
    }
    $sum = array_sum(array_column($dto->throughput['by_vendor'], 'per_hour'));
    expect($sum)->toBe($dto->throughput['total_per_hour']);
});

test('coverage catalog lists connected first', function () {
    $dto = $this->service->sidebarStats($this->customer);
    $sawDisconnected = false;
    foreach ($dto->coverage['catalog'] as $row) {
        if (! $row['connected']) { $sawDisconnected = true; continue; }
        expect($sawDisconnected)->toBeFalse();
    }
});

test('list honours status=active', function () {
    $list = $this->service->list($this->customer, null, 'active');
    foreach ($list->items() as $server) {
        expect($server->status)->toBe(SendingServer::STATUS_ACTIVE);
    }
});

test('list honours type filter', function () {
    $first = SendingServer::where('customer_id', $this->customer->id)->first();
    if (! $first) {
        $this->markTestSkipped('No servers for this customer');
    }
    $list = $this->service->list($this->customer, null, null, $first->type);
    foreach ($list->items() as $server) {
        expect($server->type)->toBe($first->type);
    }
});

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

test('GET /rui/sending/servers renders 200 with rich-redesign markers', function () {
    $user = $this->customer->user;
    if (! $user) {
        $this->markTestSkipped('No user attached to customer');
    }

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

    if ($resp->status() === 302) {
        $this->markTestSkipped('Customer plan blocks own sending server (entitlement gate)');
    }

    $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-servers-page-grid', false);
    $resp->assertSee('rui-servers-rail-card', false);
    $resp->assertSee('data-rui-servers-mix', false);
});

test('GET listing renders rich row partial', function () {
    $user = $this->customer->user;
    if (! $user) {
        $this->markTestSkipped('No user attached to customer');
    }

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

    if ($resp->status() === 302) {
        $this->markTestSkipped('Customer plan blocks own sending server');
    }

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