create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $workspaceName = $tenant->workspace?->name; Filament::setTenant(null, true); $this->actingAs($user) ->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [ (string) $tenant->workspace_id => (int) $tenant->getKey(), ], ]) ->get('/admin/operations') ->assertOk() ->assertSee($workspaceName ?? 'Select workspace') ->assertSee('Select tenant') ->assertSee('Search tenants…') ->assertSee('Switch workspace') ->assertSee('admin/select-tenant') ->assertSee('Clear tenant context') ->assertSee($tenant->getFilamentName()); $this->actingAs($user) ->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ]) ->post(route('admin.select-tenant'), ['tenant_id' => (int) $tenant->getKey()]) ->assertRedirect(); }); it('disables the tenant picker when no workspace is active (Global Mode)', function (): void { $user = \App\Models\User::factory()->create(); $workspace = \App\Models\Workspace::factory()->create(); \App\Models\WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'owner', ]); Filament::setTenant(null, true); session()->forget(WorkspaceContext::SESSION_KEY); $this->actingAs($user) ->get('/admin/workspaces') ->assertOk() ->assertSee('Select workspace') ->assertSee('Select tenant') ->assertSee('Choose a workspace first.') ->assertDontSee('Search tenants…'); }); it('renders the tenant indicator read-only on tenant-scoped pages (Filament tenant menu is primary)', function (): void { $tenant = Tenant::factory()->create(['status' => 'active']); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner'); $this->actingAs($user) ->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ]) ->get(route('filament.admin.resources.tenants.index', filamentTenantRouteParams($tenant))) ->assertOk() ->assertSee($tenant->getFilamentName()) ->assertDontSee('Search tenants…') ->assertDontSee('admin/select-tenant') ->assertDontSee('Clear tenant context'); }); it('filters the header tenant picker to tenants the user can access', function (): void { $tenantA = Tenant::factory()->create(['status' => 'active']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner', workspaceRole: 'readonly'); $tenantB = Tenant::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'ZZZ-UNAUTHORIZED-TENANT-NAME-12345', ]); Filament::setTenant(null, true); $this->actingAs($user) ->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id, ]) ->get('/admin/operations') ->assertOk() ->assertSee($tenantA->getFilamentName()) ->assertDontSee($tenantB->getFilamentName()); }); it('shows all workspace tenants in the header tenant picker for workspace owners', function (): void { $tenantA = Tenant::factory()->create(['status' => 'active']); [$user, $tenantA] = createUserWithTenant($tenantA, role: 'owner', workspaceRole: 'owner'); $tenantB = Tenant::factory()->create([ 'status' => 'active', 'workspace_id' => (int) $tenantA->workspace_id, 'name' => 'ZZZ-UNASSIGNED-TENANT-NAME-12345', ]); Filament::setTenant(null, true); $this->actingAs($user) ->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id, ]) ->get('/admin/operations') ->assertOk() ->assertSee($tenantA->getFilamentName()) ->assertSee($tenantB->getFilamentName()); }); it('does not implicitly switch tenant when opening canonical operation deep links', function (): void { $tenantA = Tenant::factory()->create(['status' => 'active']); [$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', ]); 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(route('admin.operations.view', ['run' => (int) $runA->getKey()])) ->assertOk(); expect(Filament::getTenant())->toBeNull(); $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'); });