actingAs($user); Filament::setTenant($tenant, true); $finding = $this->makeFindingForWorkflow($tenant, Finding::STATUS_NEW); Livewire::test(ListFindings::class) ->assertTableActionVisible('triage', $finding) ->assertTableActionDisabled('triage', $finding) ->assertTableActionVisible('resolve', $finding) ->assertTableActionDisabled('resolve', $finding) ->assertTableActionVisible('request_exception', $finding) ->assertTableActionDisabled('request_exception', $finding); Livewire::test(ViewFinding::class, ['record' => $finding->getKey()]) ->assertActionVisible('triage') ->assertActionDisabled('triage') ->assertActionVisible('resolve') ->assertActionDisabled('resolve') ->assertActionVisible('request_exception') ->assertActionDisabled('request_exception'); }); it('preserves the expected workflow action surface by finding status', function (): void { [$user, $tenant] = $this->actingAsFindingOperator('owner'); $newFinding = $this->makeFindingForWorkflow($tenant, Finding::STATUS_NEW); $triagedFinding = $this->makeFindingForWorkflow($tenant, Finding::STATUS_TRIAGED); $resolvedFinding = $this->makeFindingForWorkflow($tenant, Finding::STATUS_RESOLVED); Livewire::test(ListFindings::class) ->assertTableActionVisible('triage', $newFinding) ->assertTableActionHidden('start_progress', $newFinding) ->assertTableActionVisible('start_progress', $triagedFinding) ->assertTableActionHidden('reopen', $triagedFinding) ->filterTable('open', false) ->assertTableActionVisible('reopen', $resolvedFinding) ->assertTableActionHidden('triage', $resolvedFinding) ->assertTableActionHidden('close', $resolvedFinding) ->assertTableActionHidden('request_exception', $resolvedFinding); Livewire::test(ViewFinding::class, ['record' => $resolvedFinding->getKey()]) ->assertActionVisible('reopen') ->assertActionHidden('triage') ->assertActionHidden('close') ->assertActionHidden('request_exception'); }); it('returns 404 when forged foreign-tenant workflow actions are mounted for protected actions', function (): void { $tenantA = Tenant::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); $tenantB = Tenant::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner'); $foreignFinding = $this->makeFindingForWorkflow($tenantB, Finding::STATUS_TRIAGED); $this->actingAs($user); Filament::setCurrentPanel('admin'); Filament::setTenant(null, true); Filament::bootCurrentPanel(); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [ (string) $tenantA->workspace_id => (int) $tenantA->getKey(), ]); $component = Livewire::actingAs($user)->test(ListFindings::class); expect(fn () => $component->instance()->mountTableAction('start_progress', (string) $foreignFinding->getKey())) ->toThrow(NotFoundHttpException::class); expect(fn () => $component->instance()->mountTableAction('request_exception', (string) $foreignFinding->getKey())) ->toThrow(NotFoundHttpException::class); expect($foreignFinding->refresh()->status)->toBe(Finding::STATUS_TRIAGED); });