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 */ 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, ]; }