create(); $workspaceB = Workspace::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'owner', ]); $tenantB = Tenant::factory()->create([ 'workspace_id' => (int) $workspaceB->getKey(), ]); $runB = OperationRun::factory()->create([ 'tenant_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $workspaceB->getKey(), 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspaceA->getKey()]) ->get(route('admin.operations.view', ['run' => (int) $runB->getKey()])) ->assertNotFound(); }); it('keeps queue approval and rejection actions behind the approval capability', function (): void { [$approver, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); $readonly = User::factory()->create(); createUserWithTenant(tenant: $tenant, user: $readonly, role: 'readonly', workspaceRole: 'readonly'); $finding = Finding::factory()->for($tenant)->create(); $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $approver->getKey(), 'owner_user_id' => (int) $approver->getKey(), 'status' => FindingException::STATUS_PENDING, 'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT, 'request_reason' => 'Authorization continuity test', 'requested_at' => now()->subDay(), 'review_due_at' => now()->addDay(), 'evidence_summary' => ['reference_count' => 0], ]); $this->actingAs($approver); Filament::setCurrentPanel('admin'); Filament::setTenant(null, true); Filament::bootCurrentPanel(); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); Livewire::withQueryParams([ 'exception' => (int) $exception->getKey(), ]) ->actingAs($approver) ->test(FindingExceptionsQueue::class) ->assertActionVisible('approve_selected_exception') ->assertActionVisible('reject_selected_exception'); $this->actingAs($readonly) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(FindingExceptionsQueue::getUrl(panel: 'admin')) ->assertForbidden(); }); it('drops unauthorized requested tenant filters on operations instead of honoring cross-tenant query state', function (): void { $tenantA = Tenant::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner'); $unauthorizedTenant = Tenant::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); OperationRun::factory()->create([ 'tenant_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'inventory_sync', 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, 'created_at' => now()->subMinute(), 'started_at' => now()->subMinute(), ]); $this->actingAs($user); Filament::setTenant($tenantA, true); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); Livewire::withQueryParams([ 'tenant_id' => (string) $unauthorizedTenant->getKey(), 'activeTab' => 'active', ]) ->actingAs($user) ->test(Operations::class) ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) ->assertSet('activeTab', 'active'); }); it('falls back to an unselected audit history when the requested event is outside the accessible scope', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $foreignTenant = Tenant::factory()->create(); $foreignAudit = AuditLog::query()->create([ 'workspace_id' => (int) $foreignTenant->workspace_id, 'tenant_id' => (int) $foreignTenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', 'action' => 'workspace.selected', 'status' => 'success', 'resource_type' => 'workspace', 'resource_id' => (string) $foreignTenant->workspace_id, 'target_label' => 'Foreign workspace', 'summary' => 'Foreign workspace selected', 'recorded_at' => now(), ]); $this->actingAs($user); Filament::setTenant(null, true); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); Livewire::withQueryParams(['event' => (int) $foreignAudit->getKey()]) ->actingAs($user) ->test(AuditLogPage::class) ->assertSet('selectedAuditLogId', null) ->assertActionDoesNotExist('close_selected_audit_event'); }); it('falls back to an unselected queue state when the requested exception is outside the accessible tenant set', function (): void { [$approver, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); $foreignTenant = Tenant::factory()->create(); [$foreignRequester] = createUserWithTenant(tenant: $foreignTenant, role: 'owner'); $foreignFinding = Finding::factory()->for($foreignTenant)->create(); $foreignException = FindingException::query()->create([ 'workspace_id' => (int) $foreignTenant->workspace_id, 'tenant_id' => (int) $foreignTenant->getKey(), 'finding_id' => (int) $foreignFinding->getKey(), 'requested_by_user_id' => (int) $foreignRequester->getKey(), 'owner_user_id' => (int) $foreignRequester->getKey(), 'status' => FindingException::STATUS_PENDING, 'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT, 'request_reason' => 'Foreign exception', 'requested_at' => now()->subDay(), 'review_due_at' => now()->addDay(), 'evidence_summary' => ['reference_count' => 0], ]); $this->actingAs($approver); Filament::setCurrentPanel('admin'); Filament::setTenant(null, true); Filament::bootCurrentPanel(); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); Livewire::withQueryParams(['exception' => (int) $foreignException->getKey()]) ->actingAs($approver) ->test(FindingExceptionsQueue::class) ->assertSet('selectedFindingExceptionId', null) ->assertActionHidden('clear_selected_exception') ->assertActionHidden('approve_selected_exception') ->assertActionHidden('reject_selected_exception'); });