Some checks failed
Main Confidence / confidence (push) Failing after 52s
Add Customer Health decision card to tenant & workspace detail pages (spec 245). What I changed: - Render a decision-first Customer Health card on tenant and workspace detail pages. - Reuse `WorkspaceHealthSummaryQuery` and preserve `window` query param. - Update attention widget link text to "Review health details" and include `?window=`. - Add/adjust tests to cover new behavior and explainability. - Run Pint formatting. Compare URL: https://git.cloudarix.de/ahmido/TenantAtlas/compare/dev...245-customer-health-score Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #283
171 lines
5.8 KiB
PHP
171 lines
5.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\System\Pages\Dashboard;
|
|
use App\Filament\System\Widgets\CustomerHealthKpis;
|
|
use App\Filament\System\Widgets\CustomerHealthTopWorkspaces;
|
|
use App\Models\OperationRun;
|
|
use App\Models\PlatformUser;
|
|
use App\Models\ProviderConnection;
|
|
use App\Models\Tenant;
|
|
use App\Models\Workspace;
|
|
use App\Support\Auth\PlatformCapabilities;
|
|
use App\Support\OperationRunOutcome;
|
|
use App\Support\OperationRunStatus;
|
|
use App\Support\Providers\ProviderConsentStatus;
|
|
use App\Support\Providers\ProviderVerificationStatus;
|
|
use Filament\Facades\Filament;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function (): void {
|
|
Filament::setCurrentPanel('system');
|
|
Filament::bootCurrentPanel();
|
|
});
|
|
|
|
it('shows customer health widgets to authorized system users', function (): void {
|
|
$user = PlatformUser::factory()->create([
|
|
'capabilities' => [
|
|
PlatformCapabilities::ACCESS_SYSTEM_PANEL,
|
|
PlatformCapabilities::CONSOLE_VIEW,
|
|
PlatformCapabilities::DIRECTORY_VIEW,
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->actingAs($user, 'platform')
|
|
->get(Dashboard::getUrl(panel: 'system'))
|
|
->assertSuccessful()
|
|
->assertSeeLivewire(CustomerHealthKpis::class)
|
|
->assertSeeLivewire(CustomerHealthTopWorkspaces::class);
|
|
});
|
|
|
|
it('keeps the attention-needed widget hidden when no linked system detail surface is accessible', function (): void {
|
|
$user = PlatformUser::factory()->create([
|
|
'capabilities' => [
|
|
PlatformCapabilities::ACCESS_SYSTEM_PANEL,
|
|
PlatformCapabilities::CONSOLE_VIEW,
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->actingAs($user, 'platform')
|
|
->get(Dashboard::getUrl(panel: 'system'))
|
|
->assertSuccessful()
|
|
->assertSeeLivewire(CustomerHealthKpis::class)
|
|
->assertDontSeeLivewire(CustomerHealthTopWorkspaces::class);
|
|
});
|
|
|
|
it('shows the attention-needed widget to operations-only users when operational rows are accessible', function (): void {
|
|
seedOperationalAttentionWorkspace('Ops Only Workspace');
|
|
|
|
$user = PlatformUser::factory()->create([
|
|
'capabilities' => [
|
|
PlatformCapabilities::ACCESS_SYSTEM_PANEL,
|
|
PlatformCapabilities::CONSOLE_VIEW,
|
|
PlatformCapabilities::OPERATIONS_VIEW,
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->actingAs($user, 'platform')
|
|
->get(Dashboard::getUrl(panel: 'system'))
|
|
->assertSuccessful()
|
|
->assertSeeLivewire(CustomerHealthKpis::class)
|
|
->assertSeeLivewire(CustomerHealthTopWorkspaces::class);
|
|
});
|
|
|
|
it('shows the attention-needed widget to ops and runbooks users when operational rows are accessible', function (): void {
|
|
seedOperationalAttentionWorkspace('Runbooks Ops Workspace');
|
|
|
|
$user = PlatformUser::factory()->create([
|
|
'capabilities' => [
|
|
PlatformCapabilities::ACCESS_SYSTEM_PANEL,
|
|
PlatformCapabilities::CONSOLE_VIEW,
|
|
PlatformCapabilities::OPS_VIEW,
|
|
PlatformCapabilities::RUNBOOKS_VIEW,
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->actingAs($user, 'platform')
|
|
->get(Dashboard::getUrl(panel: 'system'))
|
|
->assertSuccessful()
|
|
->assertSeeLivewire(CustomerHealthKpis::class)
|
|
->assertSeeLivewire(CustomerHealthTopWorkspaces::class);
|
|
});
|
|
|
|
it('filters directory-only attention rows out for operations-only users', function (): void {
|
|
seedOperationalAttentionWorkspace('Accessible Ops Workspace');
|
|
seedProviderAttentionWorkspace('Directory Only Workspace');
|
|
|
|
$user = PlatformUser::factory()->create([
|
|
'capabilities' => [
|
|
PlatformCapabilities::ACCESS_SYSTEM_PANEL,
|
|
PlatformCapabilities::CONSOLE_VIEW,
|
|
PlatformCapabilities::OPERATIONS_VIEW,
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->actingAs($user, 'platform')
|
|
->get(Dashboard::getUrl(panel: 'system'))
|
|
->assertSuccessful()
|
|
->assertSeeLivewire(CustomerHealthKpis::class)
|
|
->assertSeeLivewire(CustomerHealthTopWorkspaces::class)
|
|
->assertSee('Accessible Ops Workspace')
|
|
->assertDontSee('Directory Only Workspace');
|
|
});
|
|
|
|
it('forbids customer health widgets when system dashboard access is denied', function (): void {
|
|
$user = PlatformUser::factory()->create([
|
|
'capabilities' => [
|
|
PlatformCapabilities::ACCESS_SYSTEM_PANEL,
|
|
],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$this->actingAs($user, 'platform')
|
|
->get(Dashboard::getUrl(panel: 'system'))
|
|
->assertForbidden();
|
|
});
|
|
|
|
function seedOperationalAttentionWorkspace(string $workspaceName): void
|
|
{
|
|
$workspace = Workspace::factory()->create(['name' => $workspaceName]);
|
|
$tenant = Tenant::factory()->for($workspace)->create([
|
|
'name' => $workspaceName.' Tenant',
|
|
'status' => Tenant::STATUS_ACTIVE,
|
|
]);
|
|
|
|
OperationRun::factory()
|
|
->forTenant($tenant)
|
|
->create([
|
|
'workspace_id' => (int) $workspace->getKey(),
|
|
'status' => OperationRunStatus::Queued->value,
|
|
'outcome' => OperationRunOutcome::Pending->value,
|
|
'created_at' => now()->subHours(2),
|
|
'started_at' => null,
|
|
]);
|
|
}
|
|
|
|
function seedProviderAttentionWorkspace(string $workspaceName): void
|
|
{
|
|
$workspace = Workspace::factory()->create(['name' => $workspaceName]);
|
|
$tenant = Tenant::factory()->for($workspace)->create([
|
|
'name' => $workspaceName.' Tenant',
|
|
'status' => Tenant::STATUS_ACTIVE,
|
|
]);
|
|
|
|
ProviderConnection::factory()
|
|
->for($tenant)
|
|
->create([
|
|
'workspace_id' => (int) $workspace->getKey(),
|
|
'is_default' => true,
|
|
'is_enabled' => true,
|
|
'consent_status' => ProviderConsentStatus::Granted->value,
|
|
'verification_status' => ProviderVerificationStatus::Blocked->value,
|
|
]);
|
|
} |