TenantAtlas/apps/platform/tests/Feature/SupportDiagnostics/TenantSupportDiagnosticActionTest.php
ahmido 17d3ca8313
Some checks failed
Main Confidence / confidence (push) Failing after 45s
feat(support-diagnostics): guardrail refactor and UI polish (agent) (#278)
Implements support diagnostics bundle, moves audit writes to action mountUsing to avoid side-effects during render, replaces custom slide-over with Filament-native schema, updates tests and adds spec docs.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #278
2026-04-25 23:32:30 +00:00

187 lines
7.7 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\TenantDashboard;
use App\Models\AuditLog;
use App\Models\EvidenceSnapshot;
use App\Models\Finding;
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\ReviewPack;
use App\Models\StoredReport;
use App\Models\Tenant;
use App\Models\TenantReview;
use App\Models\User;
use App\Models\WorkspaceMembership;
use App\Support\Auth\UiTooltips;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use App\Support\Providers\ProviderReasonCodes;
use App\Support\Providers\ProviderVerificationStatus;
use App\Support\TenantReviewStatus;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Actions\Action;
use Livewire\Livewire;
function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable
{
test()->actingAs($user);
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
setTenantPanelContext($tenant);
return Livewire::actingAs($user)->test(TenantDashboard::class);
}
it('opens a redacted tenant support diagnostic bundle from the tenant dashboard', function (): void {
$tenant = Tenant::factory()->create(['name' => 'Contoso Support Tenant']);
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator');
$connection = ProviderConnection::factory()
->withCredential()
->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'display_name' => 'Contoso Microsoft connection',
'verification_status' => ProviderVerificationStatus::Blocked->value,
'last_error_reason_code' => ProviderReasonCodes::ProviderPermissionMissing,
'last_error_message' => 'raw-provider-secret-message',
'last_health_check_at' => now()->subMinutes(15),
]);
$run = OperationRun::factory()
->forTenant($tenant)
->create([
'type' => OperationRunType::BaselineCompare->value,
'status' => OperationRunStatus::Completed->value,
'outcome' => OperationRunOutcome::Failed->value,
'context' => [
'provider_connection_id' => (int) $connection->getKey(),
'raw_response_body' => 'secret-provider-body',
],
'failure_summary' => [[
'message' => 'Compare failed after provider permission validation.',
]],
'completed_at' => now()->subMinutes(10),
]);
$finding = Finding::factory()->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'current_operation_run_id' => (int) $run->getKey(),
'severity' => Finding::SEVERITY_HIGH,
'last_seen_at' => now()->subMinutes(8),
]);
StoredReport::factory()->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE,
'payload' => [
'raw_response_body' => 'stored-report-secret-body',
],
'fingerprint' => 'permission-fingerprint',
]);
$evidenceSnapshot = EvidenceSnapshot::query()->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'operation_run_id' => (int) $run->getKey(),
'initiated_by_user_id' => (int) $user->getKey(),
'fingerprint' => fake()->sha256(),
'status' => 'active',
'completeness_state' => 'complete',
'summary' => [
'dimension_count' => 1,
'missing_dimensions' => 0,
'stale_dimensions' => 0,
],
'generated_at' => now()->subMinutes(7),
]);
$review = TenantReview::factory()->ready()->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'evidence_snapshot_id' => (int) $evidenceSnapshot->getKey(),
'operation_run_id' => (int) $run->getKey(),
'status' => TenantReviewStatus::Ready->value,
'generated_at' => now()->subMinutes(7),
]);
$pack = ReviewPack::factory()->ready()->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'tenant_review_id' => (int) $review->getKey(),
'operation_run_id' => (int) $run->getKey(),
'generated_at' => now()->subMinutes(6),
]);
$review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save();
AuditLog::query()->create([
'workspace_id' => (int) $tenant->workspace_id,
'tenant_id' => (int) $tenant->getKey(),
'operation_run_id' => (int) $run->getKey(),
'action' => 'operation.failed',
'resource_type' => 'operation_run',
'resource_id' => (string) $run->getKey(),
'target_label' => 'Operation #'.$run->getKey(),
'metadata' => [
'raw_response_body' => 'audit-secret-body',
'reason_code' => 'provider_permission_missing',
],
'outcome' => 'success',
'recorded_at' => now()->subMinutes(5),
]);
tenantSupportDiagnosticsComponent($user, $tenant)
->assertActionVisible('openSupportDiagnostics')
->assertActionEnabled('openSupportDiagnostics')
->assertActionExists('openSupportDiagnostics', fn (Action $action): bool => $action->getLabel() === 'Open support diagnostics')
->mountAction('openSupportDiagnostics')
->assertMountedActionModalSee('Support diagnostics')
->assertMountedActionModalSee('Contoso Support Tenant')
->assertMountedActionModalSee('Permissions missing')
->assertMountedActionModalSee('provider app is missing required Microsoft Graph permissions')
->assertMountedActionModalSee('Operation #'.$run->getKey())
->assertMountedActionModalSee('High finding #'.$finding->getKey())
->assertMountedActionModalSee('permission posture report')
->assertMountedActionModalSee('Tenant review #'.$review->getKey())
->assertMountedActionModalSee('Review pack #'.$pack->getKey())
->assertMountedActionModalSee('Operation failed')
->assertMountedActionModalSee('default-redacted')
->assertMountedActionModalSee('[REDACTED]')
->assertMountedActionModalDontSee('raw-provider-secret-message')
->assertMountedActionModalDontSee('secret-provider-body')
->assertMountedActionModalDontSee('stored-report-secret-body')
->assertMountedActionModalDontSee('audit-secret-body');
});
it('denies non-entitled tenant dashboard access as not found', function (): void {
$tenant = Tenant::factory()->create();
$user = User::factory()->create();
WorkspaceMembership::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'user_id' => (int) $user->getKey(),
'role' => 'operator',
]);
$this
->actingAs($user)
->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
->get(TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant))
->assertNotFound();
});
it('shows support diagnostics as disabled for entitled members without the support capability', function (): void {
$tenant = Tenant::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
tenantSupportDiagnosticsComponent($user, $tenant)
->assertActionVisible('openSupportDiagnostics')
->assertActionDisabled('openSupportDiagnostics')
->assertActionExists('openSupportDiagnostics', fn (Action $action): bool => $action->getTooltip() === UiTooltips::insufficientPermission());
});