actingAs($user); $otherTenant = Tenant::factory()->create(); $stalenessDays = (int) config('directory_groups.staleness_days', 30); EntraGroup::query()->create([ 'tenant_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([ 'tenant_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([ 'tenant_id' => $otherTenant->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000003', 'display_name' => 'Other Tenant 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'); }; $names = $extractNames(Livewire::test(ListEntraGroups::class)); expect($names)->toContain('Alpha Team'); expect($names)->toContain('Beta Unified'); expect($names)->not->toContain('Other Tenant Group'); $names = $extractNames( Livewire::test(ListEntraGroups::class) ->set('tableSearch', 'Beta') ); expect($names)->toContain('Beta Unified'); expect($names)->not->toContain('Alpha Team'); $names = $extractNames( Livewire::test(ListEntraGroups::class) ->set('tableFilters.stale.value', 1) ); expect($names)->toContain('Beta Unified'); expect($names)->not->toContain('Alpha Team'); $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 forbidden (403)', function () { $tenantA = Tenant::factory()->create(); $tenantB = Tenant::factory()->create(); $groupB = EntraGroup::query()->create([ 'tenant_id' => $tenantB->getKey(), 'entra_id' => '00000000-0000-0000-0000-000000000099', 'display_name' => 'Tenant B Group', 'group_types' => null, 'security_enabled' => true, 'mail_enabled' => false, 'last_seen_at' => now(), ]); $user = User::factory()->create(); $user->tenants()->syncWithoutDetaching([ $tenantA->getKey() => ['role' => 'owner'], $tenantB->getKey() => ['role' => 'owner'], ]); $this->actingAs($user) ->get(EntraGroupResource::getUrl('view', ['record' => $groupB], tenant: $tenantA)) ->assertForbidden(); });