actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => (string) $tenant->tenant_id, 'is_default' => true, 'status' => 'connected', ]); ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $connection->getKey(), 'type' => 'client_secret', 'payload' => [ 'client_id' => 'client-id', 'client_secret' => 'client-secret', ], ]); Livewire::test(ViewTenant::class, ['record' => $tenant->getRouteKey()]) ->callAction('verify'); $run = OperationRun::query() ->where('tenant_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); expect($run)->not->toBeNull(); $notifications = collect(session('filament.notifications', [])); expect($notifications)->not->toBeEmpty(); $last = $notifications->last(); $actionUrls = collect($last['actions'] ?? [])->pluck('url')->filter()->values()->all(); expect($actionUrls)->toContain(OperationRunLinks::tenantlessView($run)); Queue::assertPushed(ProviderConnectionHealthCheckJob::class, function (ProviderConnectionHealthCheckJob $job) use ($run, $connection): bool { return (int) $job->providerConnectionId === (int) $connection->getKey() && (int) ($job->operationRun?->getKey() ?? 0) === (int) ($run?->getKey() ?? 0); }); }); it('renders the tenant verification widget from stored run context only', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); Filament::setTenant($tenant, true); $report = VerificationReportWriter::build('provider.connection.check', [ [ 'key' => 'provider.connection.check', 'title' => 'Provider connection preflight', 'status' => 'fail', 'severity' => 'critical', 'blocking' => true, 'reason_code' => 'provider_connection_missing', 'message' => 'No provider connection configured.', 'evidence' => [], 'next_steps' => [], ], ]); OperationRun::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'blocked', 'context' => [ 'target_scope' => [ 'entra_tenant_id' => (string) $tenant->tenant_id, ], 'verification_report' => $report, ], ]); bindFailHardGraphClient(); assertNoOutboundHttp(function () use ($user): void { Livewire::actingAs($user) ->test(TenantVerificationReport::class) ->assertSee('Provider connection preflight') ->assertSee('Read-only:') ->assertSee('Insufficient permission — ask a tenant Owner.'); }); }); it('renders tenant detail without invoking synchronous verification or permission persistence services', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); Filament::setTenant($tenant, true); $this->mock(TenantConfigService::class, function ($mock): void { $mock->shouldReceive('testConnectivity')->never(); }); $this->mock(TenantPermissionService::class, function ($mock): void { $mock->shouldReceive('compare')->never(); }); $this->mock(RbacHealthService::class, function ($mock): void { $mock->shouldReceive('check')->never(); }); bindFailHardGraphClient(); assertNoOutboundHttp(function () use ($user, $tenant): void { $this->actingAs($user) ->get(route('filament.admin.resources.tenants.view', array_merge( filamentTenantRouteParams($tenant), ['record' => $tenant] ))) ->assertOk() ->assertSee('Verification report'); }); }); it('starts verification from the embedded widget CTA and uses canonical view-run links', function (): void { Queue::fake(); [$user, $tenant] = createUserWithTenant(role: 'operator'); $this->actingAs($user); $connection = ProviderConnection::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => (string) $tenant->tenant_id, 'is_default' => true, 'status' => 'connected', ]); ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $connection->getKey(), 'type' => 'client_secret', 'payload' => [ 'client_id' => 'client-id', 'client_secret' => 'client-secret', ], ]); Livewire::test(TenantVerificationReport::class, ['record' => $tenant]) ->assertSee('No verification run has been started yet.') ->call('startVerification'); $run = OperationRun::query() ->where('tenant_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); expect($run)->not->toBeNull(); $notifications = collect(session('filament.notifications', [])); expect($notifications)->not->toBeEmpty(); $last = $notifications->last(); $actionUrls = collect($last['actions'] ?? [])->pluck('url')->filter()->values()->all(); expect($actionUrls)->toContain(OperationRunLinks::tenantlessView($run)); Queue::assertPushed(ProviderConnectionHealthCheckJob::class, 1); }); it('starts tenant verification from the tenant list row action via the unified run path', function (): void { Queue::fake(); [$user, $tenant] = createUserWithTenant(role: 'operator'); $this->actingAs($user); Filament::setTenant($tenant, true); $connection = ProviderConnection::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => (string) $tenant->tenant_id, 'is_default' => true, 'status' => 'connected', ]); ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $connection->getKey(), 'type' => 'client_secret', 'payload' => [ 'client_id' => 'client-id', 'client_secret' => 'client-secret', ], ]); Livewire::test(ListTenants::class) ->callTableAction('verify', $tenant); $run = OperationRun::query() ->where('tenant_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->latest('id') ->first(); expect($run)->not->toBeNull() ->and($run?->context['surface']['kind'] ?? null)->toBe('tenant_list_row'); $notificationActionUrls = collect(session('filament.notifications', [])) ->flatMap(static fn (array $notification): array => is_array($notification['actions'] ?? null) ? $notification['actions'] : []) ->pluck('url') ->filter(static fn (mixed $url): bool => is_string($url) && trim($url) !== '') ->values() ->all(); expect($notificationActionUrls)->toContain(OperationRunLinks::tenantlessView($run)); Queue::assertPushed(ProviderConnectionHealthCheckJob::class, 1); });