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
163 lines
6.3 KiB
PHP
163 lines
6.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Pages\EnvironmentRequiredPermissions;
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\ManagedEnvironmentPermission;
|
|
use App\Models\ProviderConnection;
|
|
use App\Models\User;
|
|
use App\Support\Links\RequiredPermissionsLinks;
|
|
use App\Support\Providers\ProviderVerificationStatus;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Carbon;
|
|
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 spec353RequiredPermissionsApplicationPermissionKey(): 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 spec353RequiredPermissionsSeedRows(
|
|
ManagedEnvironment $environment,
|
|
array $missingKeys = [],
|
|
array $errorKeys = [],
|
|
?string $lastCheckedAt = null,
|
|
): 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-required-permissions-test'],
|
|
'last_checked_at' => $lastCheckedAt ? Carbon::parse($lastCheckedAt) : now(),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
function spec353RequiredPermissionsComponent(User $user, ManagedEnvironment $environment, array $query = [])
|
|
{
|
|
test()->actingAs($user);
|
|
setAdminPanelContext($environment);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $environment->workspace_id);
|
|
|
|
return Livewire::withQueryParams($query)->test(EnvironmentRequiredPermissions::class, [
|
|
'environment' => $environment,
|
|
]);
|
|
}
|
|
|
|
it('renders guidance before the raw permissions matrix on the required-permissions page', function (): void {
|
|
[$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
|
|
ProviderConnection::factory()->platform()->verifiedHealthy()->create([
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'is_default' => true,
|
|
]);
|
|
|
|
$missingPermissionKey = spec353RequiredPermissionsApplicationPermissionKey();
|
|
spec353RequiredPermissionsSeedRows($environment, missingKeys: [$missingPermissionKey]);
|
|
|
|
$response = $this->actingAs($user)
|
|
->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id,
|
|
])
|
|
->get(RequiredPermissionsLinks::requiredPermissions($environment))
|
|
->assertSuccessful();
|
|
|
|
$content = $response->getContent();
|
|
$primaryActionUrl = RequiredPermissionsLinks::adminConsentPrimaryUrl($environment);
|
|
|
|
expect($content)->toContain(__('localization.provider_guidance.required_permissions_missing_title'))
|
|
->and($content)->toContain($missingPermissionKey)
|
|
->and(strpos($content, 'data-testid="provider-readiness-guidance-card"'))->toBeLessThan(strpos($content, $missingPermissionKey))
|
|
->and($content)->toContain('data-testid="provider-readiness-primary-action"')
|
|
->and($content)->toContain('href="'.e($primaryActionUrl).'"');
|
|
});
|
|
|
|
it('shows run-verification guidance when stored verification evidence is stale or absent', function (): void {
|
|
[$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
|
|
ProviderConnection::factory()->platform()->consentGranted()->create([
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'is_default' => true,
|
|
'verification_status' => ProviderVerificationStatus::Unknown->value,
|
|
'last_health_check_at' => null,
|
|
]);
|
|
|
|
spec353RequiredPermissionsSeedRows(
|
|
$environment,
|
|
lastCheckedAt: now()->subDays(45)->toIso8601String(),
|
|
);
|
|
|
|
$this->actingAs($user)
|
|
->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id,
|
|
])
|
|
->get(RequiredPermissionsLinks::requiredPermissions($environment))
|
|
->assertSuccessful()
|
|
->assertSee(__('localization.provider_guidance.verification_required_title'))
|
|
->assertSee(__('localization.provider_guidance.action_run_provider_verification'))
|
|
->assertSee('wire:click="runProviderVerification"', false)
|
|
->assertDontSee('Start verification');
|
|
});
|
|
|
|
it('renders required-permissions guidance without Graph, outbound http, or queue dispatches', function (): void {
|
|
bindFailHardGraphClient();
|
|
|
|
[$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
|
|
ProviderConnection::factory()->platform()->verifiedHealthy()->create([
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'is_default' => true,
|
|
]);
|
|
|
|
spec353RequiredPermissionsSeedRows($environment);
|
|
Queue::fake();
|
|
|
|
assertNoOutboundHttp(function () use ($user, $environment): void {
|
|
$this->actingAs($user)
|
|
->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id,
|
|
])
|
|
->get(RequiredPermissionsLinks::requiredPermissions($environment))
|
|
->assertSuccessful();
|
|
});
|
|
|
|
Queue::assertNothingPushed();
|
|
});
|