Implemented the first version of provider readiness resolution guidance. Added the ProviderReadinessResolutionAdapter, provider readiness guidance card, and updated EnvironmentRequiredPermissions, ProviderConnectionResource, and ListProviderConnections/ViewProviderConnection. Added tests and updated the design coverage matrix. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #424
181 lines
7.3 KiB
PHP
181 lines
7.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Resources\ProviderConnectionResource;
|
|
use App\Filament\Resources\ProviderConnectionResource\Pages\ViewProviderConnection;
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\ManagedEnvironmentPermission;
|
|
use App\Models\OperationRun;
|
|
use App\Models\ProviderConnection;
|
|
use App\Models\User;
|
|
use App\Support\ManagedEnvironmentLinks;
|
|
use App\Support\Providers\ProviderVerificationStatus;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Filament\Facades\Filament;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Livewire\Livewire;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function (): void {
|
|
config()->set('graph.client_id', 'spec353-platform-client');
|
|
config()->set('graph.client_secret', 'spec353-platform-secret');
|
|
config()->set('graph.managed_environment_id', 'organizations');
|
|
});
|
|
|
|
function spec353FeatureApplicationPermissionKey(): string
|
|
{
|
|
$permission = collect(spec283ConfiguredPermissionRows())
|
|
->first(static fn (mixed $row): bool => is_array($row) && ($row['type'] ?? null) === 'application');
|
|
|
|
expect($permission)->not->toBeNull();
|
|
|
|
return (string) $permission['key'];
|
|
}
|
|
|
|
function spec353FeatureSeedPermissionRows(
|
|
ManagedEnvironment $environment,
|
|
array $missingKeys = [],
|
|
array $errorKeys = [],
|
|
): void {
|
|
foreach (spec283ConfiguredPermissionRows() as $permission) {
|
|
if (! is_array($permission)) {
|
|
continue;
|
|
}
|
|
|
|
$permissionKey = (string) ($permission['key'] ?? '');
|
|
|
|
if ($permissionKey === '') {
|
|
continue;
|
|
}
|
|
|
|
ManagedEnvironmentPermission::query()->updateOrCreate(
|
|
[
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'permission_key' => $permissionKey,
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
],
|
|
[
|
|
'status' => in_array($permissionKey, $errorKeys, true)
|
|
? 'error'
|
|
: (in_array($permissionKey, $missingKeys, true) ? 'missing' : 'granted'),
|
|
'details' => ['source' => 'spec353-feature-test'],
|
|
'last_checked_at' => now(),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
function spec353ProviderConnectionDetailComponent(User $user, ManagedEnvironment $environment, ProviderConnection $connection)
|
|
{
|
|
test()->actingAs($user);
|
|
setAdminPanelContext($environment);
|
|
Filament::setTenant($environment, true);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $environment->workspace_id);
|
|
|
|
return Livewire::test(ViewProviderConnection::class, ['record' => $connection->getKey()]);
|
|
}
|
|
|
|
it('shows decision-first guidance on the provider-connections list when no connection exists', function (): void {
|
|
[$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
|
|
$this->actingAs($user)
|
|
->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id,
|
|
])
|
|
->get(ManagedEnvironmentLinks::providerConnectionsUrl($environment))
|
|
->assertSuccessful()
|
|
->assertSee(__('localization.provider_guidance.connection_missing_title'))
|
|
->assertSee('Create provider connection')
|
|
->assertSee('data-testid="provider-readiness-primary-action"', false)
|
|
->assertSee(ProviderConnectionResource::getUrl('create', [
|
|
'environment_id' => (int) $environment->getKey(),
|
|
], panel: 'admin'))
|
|
->assertDontSee('Fix provider')
|
|
->assertDontSee('Grant permissions automatically');
|
|
});
|
|
|
|
it('shows required-permissions guidance on provider-connection detail when application permissions are missing', function (): void {
|
|
[$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
|
|
$connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'is_default' => true,
|
|
]);
|
|
|
|
spec353FeatureSeedPermissionRows($environment, missingKeys: [spec353FeatureApplicationPermissionKey()]);
|
|
|
|
spec353ProviderConnectionDetailComponent($user, $environment, $connection)
|
|
->assertSee(__('localization.provider_guidance.provider_readiness_blocked_title'))
|
|
->assertSee(__('localization.provider_guidance.required_application_permissions_reason'))
|
|
->assertActionVisible('open_required_permissions')
|
|
->assertDontSee('Fix provider')
|
|
->assertDontSee('Grant permissions automatically');
|
|
});
|
|
|
|
it('shows verification-operation guidance on provider-connection detail when verification failed', function (): void {
|
|
[$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
|
|
$connection = ProviderConnection::factory()->platform()->consentGranted()->create([
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'is_default' => true,
|
|
'verification_status' => ProviderVerificationStatus::Error->value,
|
|
'last_error_message' => 'Verification job failed for this provider connection.',
|
|
]);
|
|
|
|
spec353FeatureSeedPermissionRows($environment);
|
|
|
|
OperationRun::factory()->create([
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'type' => 'provider.connection.check',
|
|
'context' => [
|
|
'provider_connection_id' => (int) $connection->getKey(),
|
|
],
|
|
]);
|
|
|
|
spec353ProviderConnectionDetailComponent($user, $environment, $connection)
|
|
->assertSee(__('localization.provider_guidance.verification_failed_title'))
|
|
->assertActionVisible('open_verification_operation');
|
|
});
|
|
|
|
it('renders provider connection guidance without Graph, outbound http, or queue work on the render path', function (): void {
|
|
bindFailHardGraphClient();
|
|
|
|
[$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
|
|
$connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'is_default' => true,
|
|
]);
|
|
|
|
spec353FeatureSeedPermissionRows($environment);
|
|
Queue::fake();
|
|
|
|
assertNoOutboundHttp(function () use ($user, $environment, $connection): void {
|
|
$this->actingAs($user)
|
|
->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id,
|
|
])
|
|
->get(ManagedEnvironmentLinks::providerConnectionsUrl($environment))
|
|
->assertSuccessful();
|
|
|
|
$this->actingAs($user)
|
|
->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id,
|
|
])
|
|
->get(ProviderConnectionResource::getUrl('view', [
|
|
'record' => $connection,
|
|
'environment_id' => (int) $environment->getKey(),
|
|
], panel: 'admin'))
|
|
->assertSuccessful();
|
|
});
|
|
|
|
Queue::assertNothingPushed();
|
|
});
|