TenantAtlas/apps/platform/tests/Feature/Filament/BaselineCompareEnvironmentRouteContractTest.php
ahmido ddf7c15c52 feat: enforce environment-owned baseline compare routing (#374)
## Summary
- move Baseline Compare onto the canonical workspace plus environment owned route instead of workspace-style access
- remove legacy environment query and remembered-context fallback paths from the affected Baseline Compare entry points and shell handling
- update related navigation, support links, and regression coverage for admin surface scope and managed environment route contracts
- add Spec 319 artifacts for the environment-owned surface routing and shell context contract

## Testing
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareEnvironmentRouteContractTest.php tests/Feature/Filament/BaselineCompareLandingAdminTenantParityTest.php tests/Feature/Filament/BaselineCompareLandingDuplicateNamesBannerTest.php tests/Feature/Filament/BaselineCompareLandingRbacLabelsTest.php tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php tests/Feature/Filament/BaselineCompareLandingWhyNoFindingsTest.php tests/Feature/Filament/PanelNavigationSegregationTest.php tests/Feature/Guards/ManagedEnvironmentCanonicalRouteContractTest.php tests/Feature/Navigation/WorkspaceHubRegistryTest.php tests/Feature/Rbac/BaselineCompareMatrixAuthorizationTest.php tests/Feature/Rbac/DriftLandingUiEnforcementTest.php tests/Unit/Tenants/AdminSurfaceScopeTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #374
2026-05-16 20:45:39 +00:00

125 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\BaselineCompareLanding;
use App\Models\ManagedEnvironment;
use App\Support\EnvironmentDashboard\EnvironmentDashboardSummaryBuilder;
use App\Support\ManagedEnvironmentLinks;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Illuminate\Support\Arr;
function baselineCompareRouteContractForbiddenQueryKeys(): array
{
return [
'environment_id',
'tenant',
'tenant_id',
'managed_environment_id',
'environment',
'tenant_scope',
'tableFilters',
];
}
it('generates a canonical environment-owned baseline compare URL without legacy scope query keys', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$this->actingAs($user);
$url = ManagedEnvironmentLinks::baselineCompareUrl($tenant, [
'environment_id' => (int) $tenant->getKey(),
'tenant' => (string) $tenant->external_id,
'tenant_id' => (int) $tenant->getKey(),
'managed_environment_id' => (int) $tenant->getKey(),
'environment' => 'legacy-query-value',
'tenant_scope' => 'selected',
'tableFilters' => ['managed_environment_id' => ['value' => (int) $tenant->getKey()]],
'baseline_profile_id' => 42,
'subject_key' => 'wifi-corp-profile',
]);
parse_str((string) parse_url($url, PHP_URL_QUERY), $query);
expect((string) parse_url($url, PHP_URL_PATH))
->toBe(sprintf(
'/admin/workspaces/%s/environments/%s/baseline-compare',
$tenant->workspace()->firstOrFail()->slug,
$tenant->getRouteKey(),
))
->and(array_keys($query))->not->toContain(...baselineCompareRouteContractForbiddenQueryKeys())
->and($query)->toMatchArray([
'baseline_profile_id' => '42',
'subject_key' => 'wifi-corp-profile',
]);
});
it('renders baseline compare from the route-owned environment context', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$this->actingAs($user)
->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
->get(ManagedEnvironmentLinks::baselineCompareUrl($tenant))
->assertOk()
->assertSeeText('Baseline Compare')
->assertSeeText($tenant->workspace()->firstOrFail()->name)
->assertSeeText($tenant->name)
->assertSeeText('This environment has no baseline assignment');
});
it('rejects old workspace-style baseline compare URLs and remembered environment fallback', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
Filament::setTenant(null, true);
$this->actingAs($user)
->withSession([
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
(string) $tenant->workspace_id => (int) $tenant->getKey(),
],
])
->get('/admin/baseline-compare-landing?environment_id='.(int) $tenant->getKey())
->assertNotFound();
expect(BaselineCompareLanding::canAccess())->toBeFalse();
});
it('rejects baseline compare when the workspace route and environment route disagree', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$foreignTenant = ManagedEnvironment::factory()->active()->create(['name' => 'Foreign Environment']);
createUserWithTenant(tenant: $foreignTenant, user: $user, role: 'owner');
$url = sprintf(
'/admin/workspaces/%s/environments/%s/baseline-compare',
$tenant->workspace()->firstOrFail()->slug,
$foreignTenant->getRouteKey(),
);
$this->actingAs($user)
->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
->get($url)
->assertNotFound();
});
it('emits the environment-owned route from the environment dashboard baseline compare action', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$summary = app(EnvironmentDashboardSummaryBuilder::class)
->build($tenant, $user)
->toArray();
$baselineCompareStatus = Arr::first(
$summary['governanceStatus'],
static fn (array $status): bool => ($status['key'] ?? null) === 'baseline_compare',
);
$url = is_array($baselineCompareStatus) ? ($baselineCompareStatus['actionUrl'] ?? null) : null;
parse_str((string) parse_url((string) $url, PHP_URL_QUERY), $query);
expect($url)->toBe(ManagedEnvironmentLinks::baselineCompareUrl($tenant))
->and((string) parse_url((string) $url, PHP_URL_PATH))->toEndWith('/environments/'.$tenant->getRouteKey().'/baseline-compare')
->and(array_keys($query))->not->toContain(...baselineCompareRouteContractForbiddenQueryKeys());
});