create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); OperationRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', 'initiator_name' => 'System', 'run_identity_hash' => 'hash123', ]); Filament::setTenant(null, true); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get('/admin/operations') ->assertSuccessful() ->assertSee('Policy sync'); }); it('renders Monitoring → Operations pages DB-only (never calls Graph)', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $run = OperationRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', 'initiator_name' => 'System', 'run_identity_hash' => 'hash123', ]); $this->mock(GraphClientInterface::class, function ($mock): void { $mock->shouldReceive('listPolicies')->never(); $mock->shouldReceive('getPolicy')->never(); $mock->shouldReceive('getOrganization')->never(); $mock->shouldReceive('applyPolicy')->never(); $mock->shouldReceive('getServicePrincipalPermissions')->never(); $mock->shouldReceive('request')->never(); }); Filament::setTenant(null, true); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get('/admin/operations') ->assertSuccessful(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertSuccessful(); }); it('defaults the operations list to the active tenant when tenant context is set', function (): void { $tenantA = Tenant::factory()->create(); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner'); $tenantB = Tenant::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, ]); $user->tenants()->syncWithoutDetaching([ $tenantB->getKey() => ['role' => 'owner'], ]); OperationRun::factory()->create([ 'tenant_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'initiator_name' => 'TenantA', ]); OperationRun::factory()->create([ 'tenant_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory.sync', 'initiator_name' => 'TenantB', ]); Filament::setTenant($tenantA, true); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id]) ->get('/admin/operations') ->assertSee('Policy sync') ->assertDontSee('Inventory sync'); }); it('allows readonly users to view operations list and detail', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'readonly'); $run = OperationRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', 'initiator_name' => 'System', 'run_identity_hash' => 'hash123', ]); Filament::setTenant(null, true); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get('/admin/operations') ->assertSuccessful() ->assertSee('Policy sync'); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertSuccessful() ->assertSee('Operation run'); }); it('returns 404 when viewing an operation run outside workspace membership', function (): void { $run = OperationRun::factory()->create(); $user = User::factory()->create(); $this->actingAs($user) ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertNotFound(); });