TenantAtlas/tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php
ahmido dc46c4fa58 feat: complete provider truth cleanup (#207)
## Summary
- implement Spec 179 to make tenant lifecycle, provider consent, and provider verification the primary truth axes on the targeted Filament surfaces
- demote legacy tenant app status and legacy provider status and health to diagnostic-only roles, add centralized badge mappings for provider consent and verification, and keep provider connections excluded from global search
- add the full Spec 179 artifact set under `specs/179-provider-truth-cleanup/` plus focused Pest coverage for tenant truth cleanup, provider truth cleanup, RBAC, discovery safety, and badge semantics
- fix the numeric out-of-scope tenant route regression so inaccessible `/admin/tenants/{id}` paths return `404 Not Found` instead of `500`

## Testing
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantLifecycleStatusDomainSeparationTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantTruthCleanupSpec179Test.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php`
- `vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/RequiredFiltersTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Rbac/TenantResourceAuthorizationTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionListAuthorizationTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Rbac/AdminGlobalSearchContextSafetyTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantScopingTest.php`
- `vendor/bin/sail artisan test --compact tests/Unit/Badges/TenantBadgesTest.php`
- `vendor/bin/sail artisan test --compact tests/Unit/Badges/ProviderConnectionBadgesTest.php`

## Manual validation
- integrated-browser smoke on `/admin/tenants`, tenant detail, `/admin/provider-connections`, provider detail, and provider edit
- verified out-of-scope tenant and provider URLs return `404 Not Found` with the current session

## Notes
- branch: `179-provider-truth-cleanup`
- commit: `e54c6632`
- target: `dev`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #207
2026-04-05 00:48:31 +00:00

83 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Resources\ProviderConnectionResource;
use App\Filament\Resources\ProviderConnectionResource\Pages\ListProviderConnections;
use App\Models\ProviderConnection;
use Filament\Facades\Filament;
use Illuminate\Support\Facades\Bus;
use Livewire\Livewire;
it('renders Provider Connections DB-only (no outbound HTTP, no background work)', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$connection = ProviderConnection::factory()->create([
'tenant_id' => $tenant->getKey(),
'display_name' => 'Contoso',
'entra_tenant_id' => fake()->uuid(),
'provider' => 'microsoft',
]);
$this->actingAs($user);
Bus::fake();
assertNoOutboundHttp(function () use ($tenant, $connection): void {
$this->get(ProviderConnectionResource::getUrl('index', tenant: $tenant))
->assertOk()
->assertSee('Contoso');
$this->get(ProviderConnectionResource::getUrl('edit', ['record' => $connection], tenant: $tenant))
->assertOk()
->assertSee('Contoso');
});
Bus::assertNothingDispatched();
});
it('keeps provider connection table defaults calm and persists state without outbound HTTP', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner', ensureDefaultMicrosoftProviderConnection: false);
$this->actingAs($user);
$tenant->makeCurrent();
Filament::setTenant($tenant, true);
assertNoOutboundHttp(function () use ($user): void {
$component = Livewire::actingAs($user)
->test(ListProviderConnections::class)
->assertTableEmptyStateActionsExistInOrder(['create'])
->searchTable('Contoso')
->call('sortTable', 'display_name', 'desc')
->set('tableFilters.default_only.isActive', true);
$table = $component->instance()->getTable();
$visibleColumnNames = collect($table->getVisibleColumns())
->map(fn ($column): string => $column->getName())
->values()
->all();
expect($table->getPaginationPageOptions())->toBe(\App\Support\Filament\TablePaginationProfiles::resource());
expect($table->getEmptyStateHeading())->toBe('No Microsoft connections found');
expect($table->getColumn('display_name')?->isSearchable())->toBeTrue();
expect($table->getColumn('display_name')?->isSortable())->toBeTrue();
expect($visibleColumnNames)->toContain('consent_status', 'verification_status');
expect($visibleColumnNames)->not->toContain('status');
expect($visibleColumnNames)->not->toContain('health_status');
expect($table->getColumn('status')?->isToggledHiddenByDefault())->toBeTrue();
expect($table->getColumn('health_status')?->isToggledHiddenByDefault())->toBeTrue();
expect($table->getColumn('provider')?->isToggledHiddenByDefault())->toBeTrue();
expect($table->getColumn('entra_tenant_id')?->isToggledHiddenByDefault())->toBeTrue();
expect($table->getColumn('migration_review_required'))->not->toBeNull();
expect(count($table->getVisibleColumns()))->toBeLessThanOrEqual(8);
expect(session()->get($component->instance()->getTableSearchSessionKey()))->toBe('Contoso');
expect(session()->get($component->instance()->getTableSortSessionKey()))->toBe('display_name:desc');
Livewire::actingAs($user)
->test(ListProviderConnections::class)
->assertSet('tableSearch', 'Contoso')
->assertSet('tableSort', 'display_name:desc')
->assertSet('tableFilters.default_only.isActive', true);
});
});