browser()->timeout(60_000); beforeEach(function (): void { Storage::fake('exports'); }); it('Spec392 smokes customer-output gating and internal-preview separation', function (): void { [$user, $readyEnvironment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); $readyEnvironment->forceFill(['name' => 'Spec392 Browser Ready'])->save(); $blockedEnvironment = spec392BrowserEnvironmentFor($user, $readyEnvironment, 'Spec392 Browser Blocked'); spec392BrowserCreatePublishedReviewWithPack( environment: $readyEnvironment, user: $user, customerSafeReady: true, filePath: 'review-packs/spec392-browser-ready.zip', ); spec392BrowserCreatePublishedReviewWithPack( environment: $blockedEnvironment, user: $user, customerSafeReady: false, filePath: 'review-packs/spec392-browser-blocked.zip', ); spec392AuthenticateBrowser($this, $user, $readyEnvironment); visit(CustomerReviewWorkspace::environmentFilterUrl($readyEnvironment)) ->resize(1236, 900) ->waitForText('Customer-safe review pack ready') ->assertSee('Download customer-safe review pack') ->assertDontSee('Download internal preview') ->assertScript('document.querySelector("[data-testid=\"customer-review-primary-action\"]")?.innerText.includes("Download customer-safe review pack") === true', true) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); visit(CustomerReviewWorkspace::environmentFilterUrl($blockedEnvironment)) ->resize(1236, 900) ->waitForText('Output not customer-ready') ->assertSee('Requires review') ->assertDontSee('Download internal preview') ->assertScript('document.querySelector("[data-testid=\"customer-review-decision-card\"]")?.innerText.includes("Download internal preview") === false', true) ->assertScript('document.querySelector("[data-testid=\"customer-review-primary-action\"]")?.innerText.includes("Download customer-safe review pack") === false', true) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); }); function spec392BrowserEnvironmentFor(User $user, ManagedEnvironment $baseEnvironment, string $name): ManagedEnvironment { $environment = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $baseEnvironment->workspace_id, 'name' => $name, ]); createUserWithTenant(tenant: $environment, user: $user, role: 'owner', workspaceRole: 'manager'); return $environment; } function spec392BrowserCreatePublishedReviewWithPack( ManagedEnvironment $environment, User $user, bool $customerSafeReady, string $filePath, ): array { $snapshot = $customerSafeReady ? seedEnvironmentReviewEvidence($environment, findingCount: 0, driftCount: 0) : seedPartialEnvironmentReviewEvidence($environment, findingCount: 0, driftCount: 0); $review = composeEnvironmentReviewForTest($environment, $user, $snapshot); $review->forceFill([ 'status' => EnvironmentReviewStatus::Published->value, 'published_at' => now()->subMinutes(10), 'published_by_user_id' => (int) $user->getKey(), ])->save(); if ($customerSafeReady) { $review = markEnvironmentReviewCustomerSafeReady($review); } Storage::disk('exports')->put($filePath, 'Spec392 browser review pack'); $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(), 'status' => ReviewPackStatus::Ready->value, 'options' => [ 'include_pii' => false, 'include_operations' => true, ], 'file_path' => $filePath, 'file_disk' => 'exports', 'generated_at' => now()->subMinutes(5), 'expires_at' => now()->addDay(), ]); $review->forceFill([ 'current_export_review_pack_id' => (int) $pack->getKey(), ])->save(); return [$review->refresh(), $pack->refresh()]; } function spec392AuthenticateBrowser(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(), ]); setAdminPanelContext($environment); }