TenantAtlas/apps/platform/tests/Browser/Spec326CustomerReviewWorkspaceProductizationSmokeTest.php
Ahmed Darrazi 549a9a0004
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m0s
feat: review pack output contract and readiness semantics (spec 347)
Implemented the output contract and readiness semantics for review packs. Also added spec 348.
Includes changes to ChooseEnvironment, CustomerReviewWorkspace, GenerateReviewPackJob and related blade views.
Added comprehensive tests.
2026-06-03 01:14:29 +02:00

239 lines
10 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
use App\Models\ManagedEnvironment;
use App\Models\ReviewPack;
use App\Models\User;
use App\Support\EnvironmentReviewStatus;
use App\Support\Governance\Controls\ComplianceEvidenceMappingV1;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
uses(RefreshDatabase::class);
pest()->browser()->timeout(60_000);
beforeEach(function (): void {
Storage::fake('exports');
});
it('Spec326 smokes clean customer review workspace entry', function (): void {
[$user, $environmentA, $environmentB] = spec326CustomerReviewWorkspaceFixture();
spec326AuthenticateCustomerReviewWorkspaceBrowser($this, $user, $environmentA);
visit(CustomerReviewWorkspace::getUrl(panel: 'admin'))
->waitForText('Customer-safe review packages')
->assertDontSee('No environment selected')
->assertDontSee('Environment filter:')
->assertSee('What is the current review pack output state?')
->assertSee('Evidence path')
->assertSee('Review pack state')
->assertSee('Accepted risks')
->assertSee('Disclosure rule')
->assertSee('Diagnostics')
->assertSee('Collapsed')
->assertSee('Raw/support')
->assertSee('Review package index')
->assertSee('Decision trail')
->assertSee('Customer-safe follow-ups')
->assertScript('(() => {
const decision = document.querySelector("[data-testid=\"customer-review-decision-card\"]");
const aside = document.querySelector("[data-testid=\"customer-review-evidence-aside\"]");
if (! decision || ! aside) {
return false;
}
const decisionBox = decision.getBoundingClientRect();
const asideBox = aside.getBoundingClientRect();
return window.innerWidth < 768 || asideBox.left > decisionBox.left;
})()', true)
->assertSee($environmentB->name)
->assertDontSee('entitled tenant')
->assertDontSee('tenant filter')
->assertDontSee('raw payload should stay hidden')
->assertDontSee('stack trace should stay hidden')
->assertDontSee('provider secret should stay hidden')
->assertDontSee('debug metadata should stay hidden')
->assertDontSee('source fingerprint should stay hidden')
->assertScript('document.querySelector("[data-testid=\"customer-review-diagnostics\"]")?.open === false', true)
->assertNoJavaScriptErrors()
->assertNoConsoleLogs()
->screenshot(true, spec326CustomerReviewWorkspaceScreenshot('customer-review-workspace--clean'));
});
it('Spec326 smokes filtered customer review workspace clear and reload behavior', function (): void {
[$user, $environmentA, $environmentB] = spec326CustomerReviewWorkspaceFixture();
$cleanPath = json_encode((string) parse_url(CustomerReviewWorkspace::getUrl(panel: 'admin'), PHP_URL_PATH), JSON_THROW_ON_ERROR);
spec326AuthenticateCustomerReviewWorkspaceBrowser($this, $user, $environmentA);
$page = visit(CustomerReviewWorkspace::environmentFilterUrl($environmentA))
->waitForText('Environment filter:')
->assertSee($environmentA->name)
->assertDontSee($environmentB->name)
->assertSee('Environment filter: '.$environmentA->name)
->assertSee('What is the current review pack output state?')
->assertSee('Evidence path')
->assertSee('Review package index')
->assertScript('document.querySelector("[data-testid=\"customer-review-diagnostics\"]")?.open === false', true)
->assertNoJavaScriptErrors()
->assertNoConsoleLogs()
->screenshot(true, spec326CustomerReviewWorkspaceScreenshot('customer-review-workspace--filtered'));
$page
->click('[data-testid="workspace-hub-environment-filter-clear"]')
->waitForText($environmentB->name)
->assertDontSee('Environment filter:')
->assertSee($environmentB->name)
->assertScript("window.location.pathname === {$cleanPath}", true)
->assertScript('! window.location.search.includes("environment_id=")', true)
->assertNoJavaScriptErrors()
->assertNoConsoleLogs()
->screenshot(true, spec326CustomerReviewWorkspaceScreenshot('customer-review-workspace--after-clear'));
$page->script('window.location.reload();');
$page
->waitForText($environmentB->name)
->assertDontSee('Environment filter:')
->assertSee($environmentB->name)
->assertScript("window.location.pathname === {$cleanPath}", true)
->assertScript('! window.location.search.includes("environment_id=")', true)
->assertNoJavaScriptErrors()
->assertNoConsoleLogs()
->screenshot(true, spec326CustomerReviewWorkspaceScreenshot('customer-review-workspace--after-reload'));
});
it('Spec326 smokes customer-safe diagnostics disclosure', function (): void {
[$user, $environmentA] = spec326CustomerReviewWorkspaceFixture();
spec326AuthenticateCustomerReviewWorkspaceBrowser($this, $user, $environmentA);
visit(CustomerReviewWorkspace::getUrl(panel: 'admin'))
->waitForText('Diagnostics')
->assertScript('document.querySelector("[data-testid=\"customer-review-diagnostics\"]")?.open === false', true)
->click('[data-testid="customer-review-diagnostics"] summary')
->assertScript('document.querySelector("[data-testid=\"customer-review-diagnostics\"]")?.open === true', true)
->assertSee('Support details stay on authorized diagnostic surfaces')
->assertDontSee('raw payload should stay hidden')
->assertDontSee('internal exception should stay hidden')
->assertDontSee('source fingerprint should stay hidden')
->assertNoJavaScriptErrors()
->assertNoConsoleLogs()
->screenshot(true, spec326CustomerReviewWorkspaceScreenshot('customer-review-workspace--diagnostics'));
});
/**
* @return array{0: User, 1: ManagedEnvironment, 2: ManagedEnvironment}
*/
function spec326CustomerReviewWorkspaceFixture(): array
{
$environmentA = ManagedEnvironment::factory()->active()->create([
'name' => 'Spec326 Browser Environment A',
'external_id' => 'spec326-browser-environment-a',
]);
[$user, $environmentA] = createUserWithTenant(
tenant: $environmentA,
role: 'owner',
workspaceRole: 'manager',
);
$environmentB = ManagedEnvironment::factory()->active()->create([
'workspace_id' => (int) $environmentA->workspace_id,
'name' => 'Spec326 Browser Environment B',
'external_id' => 'spec326-browser-environment-b',
]);
createUserWithTenant(
tenant: $environmentB,
user: $user,
role: 'owner',
workspaceRole: 'manager',
);
spec326CreatePublishedReview($environmentA, $user, 'review-packs/spec326-browser-a.zip', now());
spec326CreatePublishedReview($environmentB, $user, 'review-packs/spec326-browser-b.zip', now()->subHour());
return [$user, $environmentA, $environmentB];
}
function spec326AuthenticateCustomerReviewWorkspaceBrowser(
mixed $test,
User $user,
ManagedEnvironment $environment,
): void {
$workspaceId = (int) $environment->workspace_id;
$test->actingAs($user)->withSession([
WorkspaceContext::SESSION_KEY => $workspaceId,
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
(string) $workspaceId => (int) $environment->getKey(),
],
]);
session()->put(WorkspaceContext::SESSION_KEY, $workspaceId);
session()->put(WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY, [
(string) $workspaceId => (int) $environment->getKey(),
]);
}
function spec326CreatePublishedReview(
ManagedEnvironment $environment,
User $user,
string $filePath,
\Illuminate\Support\Carbon $publishedAt,
): void {
$snapshot = seedEnvironmentReviewEvidence($environment);
$review = composeEnvironmentReviewForTest($environment, $user, $snapshot);
$summary = is_array($review->summary) ? $review->summary : [];
$summary['debug_payload'] = 'raw payload should stay hidden';
$summary['stack_trace'] = 'stack trace should stay hidden';
$summary['provider_secret'] = 'provider secret should stay hidden';
$summary['debug_metadata'] = 'debug metadata should stay hidden';
$summary['internal_exception'] = 'internal exception should stay hidden';
$summary['source_fingerprint'] = 'source fingerprint should stay hidden';
$summary['control_interpretation']['version_key'] = ComplianceEvidenceMappingV1::VERSION_KEY;
$summary['control_interpretation']['controls'] = [
[
'control_key' => 'customer-handoff-readiness',
'title' => 'Customer handoff readiness',
'readiness_bucket' => 'evidence_on_record',
'readiness_label' => 'Evidence on record',
'primary_reason' => 'Evidence path is complete.',
'recommended_next_action' => 'Share the current review pack.',
],
];
$review->forceFill([
'status' => EnvironmentReviewStatus::Published->value,
'summary' => $summary,
'generated_at' => $publishedAt,
'published_at' => $publishedAt,
'published_by_user_id' => (int) $user->getKey(),
])->save();
Storage::disk('exports')->put($filePath, 'PK-test');
$pack = ReviewPack::factory()->ready()->create([
'managed_environment_id' => (int) $environment->getKey(),
'workspace_id' => (int) $environment->workspace_id,
'environment_review_id' => (int) $review->getKey(),
'evidence_snapshot_id' => (int) $snapshot->getKey(),
'initiated_by_user_id' => (int) $user->getKey(),
'file_path' => $filePath,
'file_disk' => 'exports',
'generated_at' => $publishedAt,
]);
$review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save();
}
function spec326CustomerReviewWorkspaceScreenshot(string $name): string
{
return 'spec326-'.$name;
}