## Summary - implement Spec 198 monitoring page-state contracts across Operations, Audit Log, Finding Exceptions Queue, Evidence Overview, Baseline Compare Landing, and Baseline Compare Matrix - align selected-record and draft/apply behavior with query/session restoration semantics, including canonical navigation and tenant-filter normalization helpers - add Spec 198 feature and browser coverage, update closure/spec artifacts, and refresh affected regression tests that asserted pre-contract behavior ## Verification - focused Spec 198 feature pack passed through Sail - Spec 198 browser smoke passed through Sail - existing Spec 190 and Spec 194 browser smokes passed through Sail - targeted fallout tests were updated and rerun during full-suite triage ## Notes - Livewire v4 / Filament v5 compliant only; no legacy API reintroduction - no provider registration changes; Laravel 11+ provider registration remains in `bootstrap/providers.php` - no global-search behavior changed for any resource - destructive queue decision actions remain confirmation-gated and authorization-backed - no new Filament assets were added; existing deploy step for `php artisan filament:assets` remains unchanged Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #238
153 lines
5.5 KiB
PHP
153 lines
5.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Resources\BaselineProfileResource;
|
|
use App\Models\Finding;
|
|
use App\Models\User;
|
|
use App\Models\WorkspaceMembership;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Tests\Feature\Concerns\BuildsBaselineCompareMatrixFixtures;
|
|
|
|
uses(BuildsBaselineCompareMatrixFixtures::class);
|
|
|
|
pest()->browser()->timeout(15_000);
|
|
|
|
it('smokes dense multi-tenant scanning and finding drilldown continuity', function (): void {
|
|
$fixture = $this->makeBaselineCompareMatrixFixture();
|
|
|
|
$run = $this->makeBaselineCompareMatrixRun(
|
|
$fixture['visibleTenant'],
|
|
$fixture['profile'],
|
|
$fixture['snapshot'],
|
|
);
|
|
|
|
$this->makeBaselineCompareMatrixRun(
|
|
$fixture['visibleTenantTwo'],
|
|
$fixture['profile'],
|
|
$fixture['snapshot'],
|
|
);
|
|
|
|
$this->makeBaselineCompareMatrixFinding(
|
|
$fixture['visibleTenant'],
|
|
$fixture['profile'],
|
|
$run,
|
|
'wifi-corp-profile',
|
|
['severity' => Finding::SEVERITY_CRITICAL],
|
|
);
|
|
|
|
$this->actingAs($fixture['user'])->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $fixture['workspace']->getKey(),
|
|
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
|
(string) $fixture['workspace']->getKey() => (int) $fixture['visibleTenant']->getKey(),
|
|
],
|
|
]);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $fixture['workspace']->getKey());
|
|
|
|
$page = visit(BaselineProfileResource::compareMatrixUrl($fixture['profile']));
|
|
|
|
$page
|
|
->assertNoJavaScriptErrors()
|
|
->waitForText('Requested: Auto mode. Resolved: Dense mode.')
|
|
->assertSee('Dense multi-tenant scan')
|
|
->assertSee('Applied filters and the focused subject are carried by the URL so the current matrix scan can be reopened or shared.')
|
|
->assertSee('Grouped legend')
|
|
->assertSee('Open finding')
|
|
->assertSee('More follow-up')
|
|
->click('Open finding')
|
|
->waitForText('Back to compare matrix')
|
|
->assertNoJavaScriptErrors()
|
|
->assertSee('Back to compare matrix');
|
|
});
|
|
|
|
it('smokes the compact single-tenant path when only one visible tenant remains', function (): void {
|
|
$fixture = $this->makeBaselineCompareMatrixFixture();
|
|
|
|
$run = $this->makeBaselineCompareMatrixRun(
|
|
$fixture['visibleTenant'],
|
|
$fixture['profile'],
|
|
$fixture['snapshot'],
|
|
);
|
|
|
|
$this->makeBaselineCompareMatrixRun(
|
|
$fixture['visibleTenantTwo'],
|
|
$fixture['profile'],
|
|
$fixture['snapshot'],
|
|
);
|
|
|
|
$this->makeBaselineCompareMatrixFinding(
|
|
$fixture['visibleTenant'],
|
|
$fixture['profile'],
|
|
$run,
|
|
'wifi-corp-profile',
|
|
['severity' => Finding::SEVERITY_HIGH],
|
|
);
|
|
|
|
$viewer = User::factory()->create();
|
|
|
|
WorkspaceMembership::factory()->create([
|
|
'workspace_id' => (int) $fixture['workspace']->getKey(),
|
|
'user_id' => (int) $viewer->getKey(),
|
|
'role' => 'owner',
|
|
]);
|
|
|
|
$viewer->tenants()->syncWithoutDetaching([
|
|
(int) $fixture['visibleTenant']->getKey() => ['role' => 'owner'],
|
|
]);
|
|
|
|
$this->actingAs($viewer)->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $fixture['workspace']->getKey(),
|
|
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
|
(string) $fixture['workspace']->getKey() => (int) $fixture['visibleTenant']->getKey(),
|
|
],
|
|
]);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $fixture['workspace']->getKey());
|
|
|
|
visit(BaselineProfileResource::compareMatrixUrl($fixture['profile']))
|
|
->assertNoJavaScriptErrors()
|
|
->waitForText('Requested: Auto mode. Resolved: Compact mode.')
|
|
->assertSee('Compact compare results')
|
|
->assertSee('Applied filters and the focused subject are carried by the URL so the current matrix scan can be reopened or shared.')
|
|
->assertSee('Open finding');
|
|
});
|
|
|
|
it('smokes filtered zero-results reset flow and passive refresh cues without losing the matrix route', function (): void {
|
|
$fixture = $this->makeBaselineCompareMatrixFixture();
|
|
|
|
$this->makeBaselineCompareMatrixRun(
|
|
$fixture['visibleTenant'],
|
|
$fixture['profile'],
|
|
$fixture['snapshot'],
|
|
attributes: [
|
|
'status' => \App\Support\OperationRunStatus::Queued->value,
|
|
'outcome' => \App\Support\OperationRunOutcome::Pending->value,
|
|
'completed_at' => null,
|
|
'started_at' => now(),
|
|
],
|
|
);
|
|
|
|
$this->makeBaselineCompareMatrixRun(
|
|
$fixture['visibleTenantTwo'],
|
|
$fixture['profile'],
|
|
$fixture['snapshot'],
|
|
);
|
|
|
|
$this->actingAs($fixture['user'])->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $fixture['workspace']->getKey(),
|
|
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
|
(string) $fixture['workspace']->getKey() => (int) $fixture['visibleTenant']->getKey(),
|
|
],
|
|
]);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $fixture['workspace']->getKey());
|
|
|
|
visit(BaselineProfileResource::compareMatrixUrl($fixture['profile']).'?mode=dense&state[]=missing')
|
|
->assertNoJavaScriptErrors()
|
|
->waitForText('No rows match the current filters')
|
|
->assertSee('Passive auto-refresh every 5 seconds')
|
|
->assertSee('Applied filters and the focused subject are carried by the URL so the current matrix scan can be reopened or shared.')
|
|
->click('Reset filters')
|
|
->waitForText('Dense multi-tenant scan')
|
|
->assertSee('Requested: Dense mode. Resolved: Dense mode.')
|
|
->assertNoJavaScriptErrors();
|
|
});
|