TenantAtlas/apps/platform/tests/Feature/System/CustomerHealth/CustomerHealthDashboardWidgetsTest.php
Ahmed Darrazi 324ee45e64
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m3s
feat(customer-health): add detail decision card and update attention widget link (spec 245)
2026-04-27 10:26:00 +02:00

186 lines
6.4 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\System\Pages\Dashboard;
use App\Filament\System\Widgets\CustomerHealthKpis;
use App\Models\Finding;
use App\Models\OperationRun;
use App\Models\PlatformUser;
use App\Models\ProductUsageEvent;
use App\Models\ProviderConnection;
use App\Models\ReviewPack;
use App\Models\Tenant;
use App\Models\Workspace;
use App\Support\Auth\PlatformCapabilities;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\ProductTelemetry\ProductUsageEventCatalog;
use App\Support\SystemConsole\SystemConsoleWindow;
use Carbon\CarbonImmutable;
use Filament\Facades\Filament;
use Filament\Widgets\StatsOverviewWidget\Stat;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
uses(RefreshDatabase::class);
beforeEach(function (): void {
Filament::setCurrentPanel('system');
Filament::bootCurrentPanel();
CarbonImmutable::setTestNow(CarbonImmutable::parse('2026-04-27 12:00:00'));
});
afterEach(function (): void {
CarbonImmutable::setTestNow();
});
it('renders aggregate healthy, warning, critical, and unknown counts with a visible time-basis cue', function (): void {
actingAsCustomerHealthSystemUser();
$baselineStats = customerHealthStats(Livewire::withQueryParams([
'window' => SystemConsoleWindow::LastDay,
])->test(CustomerHealthKpis::class));
seedCustomerHealthWorkspace('Healthy Workspace');
seedCustomerHealthWorkspace('Warning Workspace', recentUsage: false, historicalUsage: true);
seedCustomerHealthWorkspace('Critical Workspace', failedRun: true);
seedCustomerHealthWorkspace('Unknown Workspace', recentRun: false, readyReviewPack: false);
$stats = customerHealthStats(Livewire::withQueryParams([
'window' => SystemConsoleWindow::LastDay,
])->test(CustomerHealthKpis::class));
expect((int) $stats['Healthy']['value'] - (int) $baselineStats['Healthy']['value'])->toBe(1)
->and($stats['Healthy']['description'])->toBe('Operational stability, review-pack readiness, and engagement freshness honor Last 24 hours.')
->and((int) $stats['Warning']['value'] - (int) $baselineStats['Warning']['value'])->toBe(1)
->and($stats['Warning']['description'])->toBe('Onboarding readiness, provider health, and governance pressure stay point-in-time.')
->and((int) $stats['Critical']['value'] - (int) $baselineStats['Critical']['value'])->toBe(1)
->and((int) $stats['Unknown']['value'] - (int) $baselineStats['Unknown']['value'])->toBe(1)
->and($stats['Unknown']['description'])->toBe('Missing or stale inputs stay explicit instead of silently reading healthy.');
});
it('registers the customer health widget on the system dashboard for authorized users', function (): void {
$user = actingAsCustomerHealthSystemUser();
$response = $this->actingAs($user, 'platform')->get(Dashboard::getUrl(panel: 'system'));
$response->assertSuccessful()
->assertSee('Customer health')
->assertSeeLivewire(CustomerHealthKpis::class);
});
/**
* @return array<string, array{value:string,description:string|null}>
*/
function customerHealthStats($component): array
{
$method = new ReflectionMethod(CustomerHealthKpis::class, 'getStats');
$method->setAccessible(true);
return collect($method->invoke($component->instance()))
->mapWithKeys(fn (Stat $stat): array => [
(string) $stat->getLabel() => [
'value' => (string) $stat->getValue(),
'description' => $stat->getDescription(),
],
])
->all();
}
function actingAsCustomerHealthSystemUser(): PlatformUser
{
$user = PlatformUser::factory()->create([
'capabilities' => [
PlatformCapabilities::ACCESS_SYSTEM_PANEL,
PlatformCapabilities::CONSOLE_VIEW,
],
'is_active' => true,
]);
test()->actingAs($user, 'platform');
return $user;
}
/**
* @return array{workspace: Workspace, tenant: Tenant}
*/
function seedCustomerHealthWorkspace(
string $workspaceName,
bool $readyReviewPack = true,
bool $recentUsage = true,
bool $historicalUsage = false,
bool $recentRun = true,
bool $failedRun = false,
): array {
$workspace = Workspace::factory()->create(['name' => $workspaceName]);
$tenant = Tenant::factory()->for($workspace)->create([
'name' => $workspaceName.' Tenant',
'status' => Tenant::STATUS_ACTIVE,
]);
ProviderConnection::factory()
->for($tenant)
->verifiedHealthy()
->create([
'workspace_id' => (int) $workspace->getKey(),
'is_default' => true,
]);
if ($readyReviewPack) {
ReviewPack::factory()
->for($tenant)
->ready()
->create([
'workspace_id' => (int) $workspace->getKey(),
'created_at' => now()->subHour(),
'generated_at' => now()->subHour(),
'expires_at' => now()->addDays(30),
]);
}
if ($recentUsage) {
ProductUsageEvent::factory()
->for($tenant)
->forEvent(ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED)
->create([
'workspace_id' => (int) $workspace->getKey(),
'occurred_at' => now()->subMinutes(20),
]);
} elseif ($historicalUsage) {
ProductUsageEvent::factory()
->for($tenant)
->forEvent(ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED)
->create([
'workspace_id' => (int) $workspace->getKey(),
'occurred_at' => now()->subDays(3),
]);
}
if ($recentRun) {
OperationRun::factory()
->forTenant($tenant)
->create([
'workspace_id' => (int) $workspace->getKey(),
'status' => OperationRunStatus::Completed->value,
'outcome' => $failedRun ? OperationRunOutcome::Failed->value : OperationRunOutcome::Succeeded->value,
'created_at' => now()->subMinutes(10),
'started_at' => now()->subMinutes(15),
'completed_at' => now()->subMinutes(5),
]);
}
Finding::factory()
->for($tenant)
->closed()
->create([
'severity' => Finding::SEVERITY_LOW,
]);
return [
'workspace' => $workspace,
'tenant' => $tenant,
];
}