## Summary - add a workspace-scoped baseline compare matrix page under baseline profiles - derive matrix tenant summaries, subject rows, cell states, freshness, and trust from existing snapshots, compare runs, and findings - add confirmation-gated `Compare assigned tenants` actions on the baseline detail and matrix surfaces without introducing a workspace umbrella run - preserve matrix navigation context into tenant compare and finding drilldowns and add centralized matrix badge semantics - include spec, plan, data model, contracts, quickstart, tasks, and focused feature/browser coverage for Spec 190 ## Verification - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Badges/BaselineCompareMatrixBadgesTest.php tests/Feature/Baselines/BaselineCompareMatrixBuilderTest.php tests/Feature/Baselines/BaselineCompareMatrixCompareAllActionTest.php tests/Feature/Baselines/BaselineComparePerformanceGuardTest.php tests/Feature/Filament/BaselineCompareMatrixPageTest.php tests/Feature/Filament/BaselineProfileCompareStartSurfaceTest.php tests/Feature/Rbac/BaselineCompareMatrixAuthorizationTest.php tests/Feature/Guards/ActionSurfaceContractTest.php tests/Feature/Guards/NoAdHocStatusBadgesTest.php tests/Feature/Guards/NoDiagnosticWarningBadgesTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - completed an integrated-browser smoke flow locally for matrix render, differ filter, finding drilldown round-trip, and `Compare assigned tenants` confirmation/action Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #221
73 lines
2.3 KiB
PHP
73 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Resources\BaselineProfileResource;
|
|
use App\Models\Finding;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Tests\Feature\Concerns\BuildsBaselineCompareMatrixFixtures;
|
|
|
|
uses(BuildsBaselineCompareMatrixFixtures::class);
|
|
|
|
pest()->browser()->timeout(15_000);
|
|
|
|
it('smokes the baseline compare matrix render, filter interaction, 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'],
|
|
);
|
|
|
|
$finding = $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('Visible-set baseline')
|
|
->assertSee('Reference overview')
|
|
->assertSee('Subject-by-tenant matrix')
|
|
->assertSee('WiFi Corp Profile')
|
|
->assertSee('Windows Compliance')
|
|
->assertSee('Open finding');
|
|
|
|
$page->script(<<<'JS'
|
|
const input = document.querySelector('[data-testid="matrix-filter-state-differ"]');
|
|
if (input instanceof HTMLInputElement) {
|
|
input.click();
|
|
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
}
|
|
JS);
|
|
|
|
$page
|
|
->waitForText('Open finding')
|
|
->assertDontSee('Windows Compliance')
|
|
->click('Open finding')
|
|
->waitForText('Back to compare matrix')
|
|
->assertNoJavaScriptErrors()
|
|
->assertSee('Back to compare matrix');
|
|
});
|