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'], ]); $runA = OperationRun::factory()->create([ 'tenant_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'initiator_name' => 'TenantA', ]); $runB = OperationRun::factory()->create([ 'tenant_id' => (int) $tenantB->getKey(), 'workspace_id' => (int) $tenantB->workspace_id, 'type' => 'inventory.sync', 'initiator_name' => 'TenantB', ]); Filament::setTenant(null, true); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id]) ->get('/admin/operations') ->assertOk() ->assertSee('Policy sync') ->assertSee('Inventory sync') ->assertSee('TenantA') ->assertSee('TenantB'); }); it('serves /admin/operations/{run} with and without tenant context', 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', ]); Filament::setTenant(null, true); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() ->assertSee('Operation run') ->assertSee('/admin/t/'.((int) $tenant->getKey()).'/operations/r/'.((int) $run->getKey())); Filament::setTenant($tenant, true); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() ->assertSee('Operation run'); }); it('defaults the tenant filter from tenant context and can be cleared', 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'], ]); $runA = OperationRun::factory()->create([ 'tenant_id' => (int) $tenantA->getKey(), 'workspace_id' => (int) $tenantA->workspace_id, 'type' => 'policy.sync', 'initiator_name' => 'TenantA', ]); $runB = 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->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id, ]); session([ WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id, ]); $component = Livewire::actingAs($user) ->test(ListOperationRuns::class) ->assertCanSeeTableRecords([$runA]) ->assertCanNotSeeTableRecords([$runB]); $component ->filterTable('tenant_id', null) ->assertCanSeeTableRecords([$runA, $runB]); }); it('has reserved Monitoring placeholder pages for Alerts and Audit Log', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); Filament::setTenant(null, true); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get('/admin/alerts') ->assertOk(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get('/admin/audit-log') ->assertOk(); });