getRoutes()->match($request); $request->setRouteResolver(static fn () => $route); app()->instance('request', $request); } test('cached groups can be listed, searched, and filtered (DB-only)', function () { [$user, $tenant] = createUserWithTenant(role: 'owner', fixtureProfile: 'credential-enabled'); $this->actingAs($user); $otherTenant = ManagedEnvironment::factory()->create(); $stalenessDays = (int) config('directory_groups.staleness_days', 30); EntraGroup::query()->create([ 'managed_environment_id' => $tenant->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000001', 'display_name' => 'Alpha Team', 'group_types' => null, 'security_enabled' => true, 'mail_enabled' => false, 'last_seen_at' => now(), ]); EntraGroup::query()->create([ 'managed_environment_id' => $tenant->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000002', 'display_name' => 'Beta Unified', 'group_types' => ['Unified'], 'security_enabled' => false, 'mail_enabled' => true, 'last_seen_at' => now()->subDays(max(1, $stalenessDays) + 1), ]); EntraGroup::query()->create([ 'managed_environment_id' => $otherTenant->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000003', 'display_name' => 'Other ManagedEnvironment Group', 'group_types' => null, 'security_enabled' => true, 'mail_enabled' => false, 'last_seen_at' => now(), ]); $tenant->makeCurrent(); Filament::setTenant($tenant, true); $extractNames = function ($livewire): Collection { $records = $livewire->instance()->getTableRecords(); $items = method_exists($records, 'items') ? collect($records->items()) : collect($records); return $items->pluck('display_name'); }; $forgetPersistedFilters = function (): void { $component = Livewire::test(ListEntraGroups::class)->instance(); session()->forget($component->getTableFiltersSessionKey()); session()->forget($component->getTableSearchSessionKey()); session()->forget($component->getTableSortSessionKey()); }; $names = $extractNames(Livewire::test(ListEntraGroups::class)); expect($names)->toContain('Alpha Team'); expect($names)->toContain('Beta Unified'); expect($names)->not->toContain('Other ManagedEnvironment Group'); $names = $extractNames( Livewire::test(ListEntraGroups::class) ->set('tableSearch', 'Beta') ); expect($names)->toContain('Beta Unified'); expect($names)->not->toContain('Alpha Team'); $forgetPersistedFilters(); $names = $extractNames( Livewire::test(ListEntraGroups::class) ->set('tableFilters.stale.value', 1) ); expect($names)->toContain('Beta Unified'); expect($names)->not->toContain('Alpha Team'); $forgetPersistedFilters(); $names = $extractNames( Livewire::test(ListEntraGroups::class) ->set('tableFilters.group_type.value', 'security') ); expect($names)->toContain('Alpha Team'); expect($names)->not->toContain('Beta Unified'); }); test('group detail is tenant-scoped and cross-tenant access is not found (404)', function () { $tenantA = ManagedEnvironment::factory()->create(); $tenantB = ManagedEnvironment::factory()->create([ 'workspace_id' => $tenantA->workspace_id, ]); $groupB = EntraGroup::query()->create([ 'managed_environment_id' => $tenantB->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000099', 'display_name' => 'ManagedEnvironment B Group', 'group_types' => null, 'security_enabled' => true, 'mail_enabled' => false, 'last_seen_at' => now(), ]); $user = User::factory()->create(); [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, user: $user, role: 'owner', fixtureProfile: 'credential-enabled'); $this->actingAs($user) ->get(EntraGroupResource::getUrl('view', ['record' => $groupB], tenant: $tenantA)) ->assertNotFound(); }); test('registers Entra groups navigation only inside the environment admin context', function () { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); Filament::setCurrentPanel(Filament::getPanel('admin')); bindDirectoryGroupsNavigationRequestPath(route('admin.workspace.home', ['workspace' => $tenant->workspace_id])); expect(EntraGroupResource::shouldRegisterNavigation())->toBeFalse(); bindDirectoryGroupsNavigationRequestPath(ManagedEnvironmentLinks::viewUrl($tenant)); expect(EntraGroupResource::shouldRegisterNavigation())->toBeTrue(); Filament::setCurrentPanel(null); });