## Summary - remove remaining legacy scope query hint parsing from shared workspace and environment scoping seams so hubs only narrow via explicit `environment_id` - align canonical link generation across workspace hubs, provider connections, audit log, alerts, and decision register flows - add focused Spec 341 regression coverage for canonical link/query behavior and legacy alias rejection - include the Spec 341 artifacts and move the review screenshots into `specs/341-canonical-link-query-cleanup/artifacts/screenshots/` - ignore local `.playwright-mcp` browser tool output so it does not pollute future commits or pull requests ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Navigation --filter=Spec341` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Navigation/Spec341CanonicalLinkQueryCleanupTest.php tests/Feature/Navigation/WorkspaceHubEnvironmentFilterContractTest.php tests/Feature/ProviderConnections/ProviderConnectionsWorkspaceHubContractTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `git diff --check` ## Notes - Livewire v4 compliance unchanged - Filament provider registration remains in `apps/platform/bootstrap/providers.php` - no globally searchable resource behavior was changed in this slice - no destructive action behavior was changed - no new Filament assets; deploy `filament:assets` posture is unchanged Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #413
131 lines
5.2 KiB
PHP
131 lines
5.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Pages\EnvironmentRequiredPermissions;
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Support\ManagedEnvironmentLinks;
|
|
use App\Support\Navigation\WorkspaceHubNavigation;
|
|
use App\Support\OperateHub\OperateHubShell;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Filament\Facades\Filament;
|
|
use Illuminate\Http\Request;
|
|
|
|
it('Spec341 OperateHubShell ignores legacy tenant query hints', function (): void {
|
|
$environment = ManagedEnvironment::factory()->active()->create([
|
|
'name' => 'Spec341 Environment A',
|
|
'external_id' => 'spec341-environment-a',
|
|
]);
|
|
[$user, $environment] = createUserWithTenant(tenant: $environment, role: 'owner', workspaceRole: 'owner');
|
|
$workspace = $environment->workspace()->firstOrFail();
|
|
|
|
$this->actingAs($user);
|
|
setAdminPanelContext();
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey());
|
|
session()->forget(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY);
|
|
|
|
$shell = app(OperateHubShell::class);
|
|
|
|
$queryCases = [
|
|
'tenant' => ['tenant' => (string) $environment->getRouteKey()],
|
|
'managed_environment_id' => ['managed_environment_id' => (int) $environment->getKey()],
|
|
];
|
|
|
|
foreach ($queryCases as $query) {
|
|
$request = Request::create('/admin/onboarding', 'GET', $query);
|
|
$request->setUserResolver(fn () => $user);
|
|
|
|
$resolved = $shell->resolvedContext($request);
|
|
|
|
expect($resolved->hasTenant())->toBeFalse()
|
|
->and($resolved->tenantSource)->not->toBe('query_hint');
|
|
}
|
|
});
|
|
|
|
it('Spec341 EnvironmentRequiredPermissions does not resolve tenant from legacy query keys', function (): void {
|
|
$environment = ManagedEnvironment::factory()->active()->create([
|
|
'name' => 'Spec341 Permissions Environment',
|
|
'external_id' => 'spec341-permissions-environment',
|
|
]);
|
|
|
|
$originalRequest = app('request');
|
|
|
|
try {
|
|
$request = Request::create('/livewire/update', 'GET', [
|
|
'tenant' => (string) $environment->getRouteKey(),
|
|
]);
|
|
app()->instance('request', $request);
|
|
|
|
$method = new ReflectionMethod(EnvironmentRequiredPermissions::class, 'resolveScopedTenant');
|
|
$method->setAccessible(true);
|
|
|
|
/** @var ManagedEnvironment|null $resolvedTenant */
|
|
$resolvedTenant = $method->invoke(null, null);
|
|
|
|
expect($resolvedTenant)->toBeNull();
|
|
} finally {
|
|
app()->instance('request', $originalRequest);
|
|
}
|
|
});
|
|
|
|
it('Spec341 environment-bound routes remain route-owned even when legacy tenant query hints are present', function (): void {
|
|
$environmentA = ManagedEnvironment::factory()->active()->create([
|
|
'name' => 'Spec341 Baseline Environment A',
|
|
'external_id' => 'spec341-baseline-environment-a',
|
|
]);
|
|
[$user, $environmentA] = createUserWithTenant(tenant: $environmentA, role: 'owner', workspaceRole: 'owner');
|
|
|
|
$environmentB = ManagedEnvironment::factory()->active()->create([
|
|
'workspace_id' => (int) $environmentA->workspace_id,
|
|
'name' => 'Spec341 Baseline Environment B',
|
|
'external_id' => 'spec341-baseline-environment-b',
|
|
]);
|
|
createUserWithTenant(tenant: $environmentB, user: $user, role: 'owner', workspaceRole: 'owner');
|
|
|
|
$this->actingAs($user);
|
|
setAdminPanelContext();
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $environmentA->workspace_id);
|
|
|
|
baselineCompareLandingLivewire($environmentB, ['tenant' => (string) $environmentA->getRouteKey()], $user)
|
|
->assertSet('scopedEnvironmentId', (int) $environmentB->getKey());
|
|
});
|
|
|
|
it('Spec341 WorkspaceHubNavigation carries route-owned environment context into workspace hub URLs', function (): void {
|
|
$environment = ManagedEnvironment::factory()->active()->create([
|
|
'name' => 'Spec341 Hub Navigation Environment',
|
|
'external_id' => 'spec341-hub-navigation-environment',
|
|
]);
|
|
[$user, $environment] = createUserWithTenant(tenant: $environment, role: 'owner', workspaceRole: 'owner');
|
|
$workspace = $environment->workspace()->firstOrFail();
|
|
|
|
$this->actingAs($user);
|
|
setAdminPanelContext();
|
|
|
|
Filament::setTenant(null, true);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey());
|
|
session()->forget(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY);
|
|
|
|
$originalRequest = app('request');
|
|
|
|
try {
|
|
$workspaceKey = ManagedEnvironmentLinks::workspaceRouteKey($workspace);
|
|
$environmentKey = ManagedEnvironmentLinks::environmentRouteKey($environment);
|
|
|
|
$request = Request::create('/livewire/update', 'POST');
|
|
$request->headers->set('x-livewire', '1');
|
|
$request->headers->set('referer', url("/admin/workspaces/{$workspaceKey}/environments/{$environmentKey}/required-permissions"));
|
|
$request->setUserResolver(fn () => $user);
|
|
|
|
app()->instance('request', $request);
|
|
|
|
$url = WorkspaceHubNavigation::environmentFilteredUrl(url('/admin/provider-connections'));
|
|
|
|
$query = [];
|
|
parse_str((string) parse_url($url, PHP_URL_QUERY), $query);
|
|
|
|
expect((int) ($query['environment_id'] ?? 0))->toBe((int) $environment->getKey());
|
|
} finally {
|
|
app()->instance('request', $originalRequest);
|
|
}
|
|
});
|