makeBaselineCompareMatrixFixture(); $run = $this->makeBaselineCompareMatrixRun( $fixture['visibleTenantTwo'], $fixture['profile'], $fixture['snapshot'], ); $this->makeBaselineCompareMatrixRun( $fixture['visibleTenant'], $fixture['profile'], $fixture['snapshot'], ); $this->makeBaselineCompareMatrixFinding( $fixture['visibleTenantTwo'], $fixture['profile'], $run, 'wifi-corp-profile', ); $session = $this->setAdminWorkspaceContext($fixture['user'], $fixture['workspace'], $fixture['visibleTenant']); $this->withSession($session) ->get(BaselineProfileResource::compareMatrixUrl($fixture['profile'])) ->assertOk() ->assertSee('Visible-set baseline') ->assertSee('Reference overview') ->assertSee('fi-fo-checkbox-list', false) ->assertSee('fi-fo-select', false) ->assertSee('State legend') ->assertSee('Tenant summaries') ->assertSee('Subject-by-tenant matrix') ->assertSee('No narrowing filters are active. Showing every visible subject and tenant in the current baseline scope.') ->assertSee('1 hidden by access scope') ->assertSee('WiFi Corp Profile') ->assertSee((string) $fixture['visibleTenant']->name) ->assertSee((string) $fixture['visibleTenantTwo']->name) ->assertSee('Needs attention') ->assertSee('Open finding') ->assertSee('Open tenant compare') ->assertSee('data-testid="matrix-active-filters"', false) ->assertSee('sticky left-0', false); }); it('keeps query-backed filters and subject focus on the matrix route and drilldown links', function (): void { $fixture = $this->makeBaselineCompareMatrixFixture(); $run = $this->makeBaselineCompareMatrixRun( $fixture['visibleTenant'], $fixture['profile'], $fixture['snapshot'], ); $finding = $this->makeBaselineCompareMatrixFinding( $fixture['visibleTenant'], $fixture['profile'], $run, 'wifi-corp-profile', ['severity' => 'critical'], ); $this->makeBaselineCompareMatrixRun( $fixture['visibleTenantTwo'], $fixture['profile'], $fixture['snapshot'], ); $this->setAdminWorkspaceContext($fixture['user'], $fixture['workspace'], $fixture['visibleTenant']); $component = Livewire::withQueryParams([ 'policy_type' => ['deviceConfiguration'], 'state' => ['differ'], 'severity' => ['critical'], 'subject_key' => 'wifi-corp-profile', ]) ->actingAs($fixture['user']) ->test(BaselineCompareMatrix::class, ['record' => $fixture['profile']->getKey()]) ->assertSee('4 active filters') ->assertSee('Policy types: 1') ->assertSee('Focused subject: wifi-corp-profile') ->assertSee('Clear subject focus') ->assertDontSee('Windows Compliance'); $tenantCompareUrl = $component->instance()->tenantCompareUrl((int) $fixture['visibleTenant']->getKey(), 'wifi-corp-profile'); $findingUrl = $component->instance()->findingUrl((int) $fixture['visibleTenant']->getKey(), (int) $finding->getKey(), 'wifi-corp-profile'); expect($tenantCompareUrl)->toContain('baseline_profile_id='.(int) $fixture['profile']->getKey()) ->and($tenantCompareUrl)->toContain('subject_key=wifi-corp-profile') ->and($tenantCompareUrl)->toContain('nav%5Bsource_surface%5D=baseline_compare_matrix') ->and($findingUrl)->toContain('nav%5Bsource_surface%5D=baseline_compare_matrix'); }); it('renders a blocked state when the baseline profile has no usable reference snapshot', function (): void { $fixture = $this->makeBaselineCompareMatrixFixture(); $fixture['snapshot']->markIncomplete(); $session = $this->setAdminWorkspaceContext($fixture['user'], $fixture['workspace']); $this->withSession($session) ->get(BaselineProfileResource::compareMatrixUrl($fixture['profile'])) ->assertOk() ->assertSee('No usable reference snapshot') ->assertSee('Capture a complete baseline snapshot before using the compare matrix.'); }); it('renders an empty state when the baseline profile has no assigned tenants', function (): void { $fixture = $this->makeBaselineCompareMatrixFixture(); $fixture['profile']->tenantAssignments()->delete(); $session = $this->setAdminWorkspaceContext($fixture['user'], $fixture['workspace']); $this->withSession($session) ->get(BaselineProfileResource::compareMatrixUrl($fixture['profile'])) ->assertOk() ->assertSee('No assigned tenants'); }); it('renders an empty state when the assigned set is not visible to the current actor', function (): void { $fixture = $this->makeBaselineCompareMatrixFixture(); $viewer = \App\Models\User::factory()->create(); \App\Models\WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $fixture['workspace']->getKey(), 'user_id' => (int) $viewer->getKey(), 'role' => 'owner', ]); $session = $this->setAdminWorkspaceContext($viewer, $fixture['workspace']); $this->withSession($session) ->get(BaselineProfileResource::compareMatrixUrl($fixture['profile'])) ->assertOk() ->assertSee('No visible assigned tenants'); }); it('renders a passive auto-refresh note instead of a perpetual loading state while compare runs remain active', 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(), ], ); $session = $this->setAdminWorkspaceContext($fixture['user'], $fixture['workspace']); $this->withSession($session) ->get(BaselineProfileResource::compareMatrixUrl($fixture['profile'])) ->assertOk() ->assertSee('Auto-refresh every 5 seconds while compare runs are queued or running.') ->assertSee('wire:poll.5s="pollMatrix"', false) ->assertDontSee('Refreshing matrix'); }); it('renders an empty state when no rows match the current filters', function (): void { $fixture = $this->makeBaselineCompareMatrixFixture(); $this->makeBaselineCompareMatrixRun( $fixture['visibleTenant'], $fixture['profile'], $fixture['snapshot'], ); $this->makeBaselineCompareMatrixRun( $fixture['visibleTenantTwo'], $fixture['profile'], $fixture['snapshot'], ); $session = $this->setAdminWorkspaceContext($fixture['user'], $fixture['workspace']); $this->withSession($session) ->get(BaselineProfileResource::compareMatrixUrl($fixture['profile']).'?state[]=missing') ->assertOk() ->assertSee('No rows match the current filters'); });