## Summary - align the Baseline Compare landing page with the shared Product Process Flow contract introduced by Spec 332 - add the horizontal flow rendering primitive and update the landing view/state presentation for readiness, proof, evidence, and next action - add Spec 336 artifacts, screenshots, focused feature coverage, and browser smoke coverage for the aligned states ## Testing - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareEnvironmentRouteContractTest.php tests/Feature/Filament/Spec330EnvironmentDashboardBaselineCompareProductizationTest.php tests/Feature/Filament/Spec336BaselineCompareProductProcessFlowAlignmentTest.php tests/Browser/Spec330EnvironmentDashboardBaselineCompareSmokeTest.php tests/Browser/Spec336BaselineCompareProductProcessFlowAlignmentSmokeTest.php` ## Notes - Filament v5 / Livewire v4 stack remains unchanged - no panel provider registration changes; `bootstrap/providers.php` is unaffected - no global-search resource behavior changes - no new destructive actions and no asset registration/deployment changes Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #406
125 lines
4.7 KiB
PHP
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 does not have an assigned baseline.');
|
|
});
|
|
|
|
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());
|
|
});
|