browser()->timeout(60_000); beforeEach(function (): void { Storage::fake('exports'); }); it('Spec357 smokes report profile variants on the rendered report route', function (): void { [$user, $customerEnvironment, $customerReview, $customerPack] = spec357BrowserCreateProfilePack( environmentName: 'Spec357 Browser Customer', customerSafeReady: true, ); [$limitedUser, $limitedEnvironment, $limitedReview, $limitedPack] = spec357BrowserCreateProfilePack( user: $user, workspaceId: (int) $customerEnvironment->workspace_id, environmentName: 'Spec357 Browser Limited', customerSafeReady: true, packOverrides: [ 'options' => [ 'include_pii' => true, 'include_operations' => true, ], ], ); spec357AuthenticateBrowser($this, $user, $customerEnvironment); $customerExecutiveUrl = app(ReviewPackService::class)->generateRenderedReportUrl($customerPack, [ 'source_surface' => 'review_pack', 'review_id' => (int) $customerReview->getKey(), 'interpretation_version' => $customerReview->controlInterpretationVersion(), ReportProfileRegistry::QUERY_PARAMETER => ReportProfileRegistry::CUSTOMER_EXECUTIVE, ]); visit($customerExecutiveUrl) ->resize(1280, 1440) ->waitForText(__('localization.review.report_profile_customer_executive')) ->assertSee(ReportProfileRegistry::CUSTOMER_EXECUTIVE) ->assertSee(__('localization.review.report_appendix_hidden_for_profile')) ->assertDontSee('Spec357 Technical Control') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec357BrowserScreenshotName('01-customer-executive')); spec357CopyBrowserScreenshot('01-customer-executive'); $customerTechnicalUrl = app(ReviewPackService::class)->generateRenderedReportUrl($customerPack, [ 'source_surface' => 'review_pack', 'review_id' => (int) $customerReview->getKey(), 'interpretation_version' => $customerReview->controlInterpretationVersion(), ReportProfileRegistry::QUERY_PARAMETER => ReportProfileRegistry::CUSTOMER_TECHNICAL, ]); visit($customerTechnicalUrl) ->resize(1280, 1440) ->waitForText(__('localization.review.report_profile_customer_technical')) ->assertSee('Spec357 Technical Control') ->assertDontSee(__('localization.review.report_appendix_hidden_for_profile')) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec357BrowserScreenshotName('02-customer-technical')); spec357CopyBrowserScreenshot('02-customer-technical'); $internalUrl = app(ReviewPackService::class)->generateRenderedReportUrl($limitedPack, [ 'source_surface' => 'review_pack', 'review_id' => (int) $limitedReview->getKey(), 'interpretation_version' => $limitedReview->controlInterpretationVersion(), ReportProfileRegistry::QUERY_PARAMETER => ReportProfileRegistry::INTERNAL_MSP_REVIEW, ]); visit($internalUrl) ->resize(1280, 1440) ->waitForText(__('localization.review.report_profile_internal_msp_review')) ->assertSee(__('localization.review.report_profile_internal_msp_review')) ->assertSee(__('localization.review.proof_state_not_applicable')) ->assertSee('Spec357 Technical Control') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec357BrowserScreenshotName('03-internal-msp')); spec357CopyBrowserScreenshot('03-internal-msp'); $auditorUrl = app(ReviewPackService::class)->generateRenderedReportUrl($customerPack, [ 'source_surface' => 'review_pack', 'review_id' => (int) $customerReview->getKey(), 'interpretation_version' => $customerReview->controlInterpretationVersion(), ReportProfileRegistry::QUERY_PARAMETER => ReportProfileRegistry::AUDITOR_APPENDIX, ]); visit($auditorUrl) ->resize(1280, 1440) ->waitForText(__('localization.review.report_profile_auditor_appendix')) ->assertSee(__('localization.review.report_audience_controlled_auditor')) ->assertSee('Spec357 Technical Control') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec357BrowserScreenshotName('04-auditor-appendix')); spec357CopyBrowserScreenshot('04-auditor-appendix'); $fallbackUrl = app(ReviewPackService::class)->generateRenderedReportUrl($customerPack, [ 'source_surface' => 'review_pack', 'review_id' => (int) $customerReview->getKey(), 'interpretation_version' => $customerReview->controlInterpretationVersion(), ReportProfileRegistry::QUERY_PARAMETER => ReportProfileRegistry::FRAMEWORK_READINESS, ]); visit($fallbackUrl) ->resize(1280, 1440) ->waitForText(__('localization.review.report_profile_fallback_notice')) ->assertSee(ReportProfileRegistry::FRAMEWORK_READINESS) ->assertSee(ReportProfileRegistry::INTERNAL_MSP_REVIEW) ->assertSee(__('localization.review.report_profile_internal_msp_review')) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->screenshot(true, spec357BrowserScreenshotName('05-fallback-framework')); spec357CopyBrowserScreenshot('05-fallback-framework'); expect($limitedUser)->toBeInstanceOf(User::class); }); function spec357BrowserScreenshotName(string $name): string { return 'spec357-report-profiles-'.$name; } function spec357CopyBrowserScreenshot(string $name): void { $filename = spec357BrowserScreenshotName($name).'.png'; $primarySource = base_path('tests/Browser/Screenshots/'.$filename); $fallbackSource = \Pest\Browser\Support\Screenshot::path($filename); $targetDirectory = repo_path('specs/357-report-profiles-disclosure-policy-v1/artifacts/screenshots'); if (! is_dir($targetDirectory)) { @mkdir($targetDirectory, 0755, true); } $source = null; for ($attempt = 0; $attempt < 50 && $source === null; $attempt++) { foreach ([$primarySource, $fallbackSource] as $candidate) { if (is_file($candidate)) { $source = $candidate; break; } } if ($source !== null) { break; } usleep(100_000); clearstatcache(true, $primarySource); clearstatcache(true, $fallbackSource); } if (is_string($source) && is_file($source) && is_dir($targetDirectory) && is_writable($targetDirectory)) { @copy($source, $targetDirectory.DIRECTORY_SEPARATOR.$name.'.png'); } } function spec357AuthenticateBrowser(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); } /** * @param array|null $packOverrides * @return array{0:User,1:ManagedEnvironment,2:\App\Models\EnvironmentReview,3:ReviewPack} */ function spec357BrowserCreateProfilePack( ?User $user = null, ?int $workspaceId = null, string $environmentName = 'Spec357 Browser Environment', bool $customerSafeReady = false, ?array $packOverrides = [], ): array { $workspaceId ??= null; $environment = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => $workspaceId, 'name' => $environmentName, ]); if ($user === null) { [$user, $environment] = createUserWithTenant(tenant: $environment, role: 'owner', workspaceRole: 'manager'); } else { createUserWithTenant(tenant: $environment, user: $user, role: 'owner', workspaceRole: 'manager'); } $snapshot = seedEnvironmentReviewEvidence($environment, findingCount: 0, driftCount: 0); $review = composeEnvironmentReviewForTest($environment, $user, $snapshot); $review->forceFill([ 'status' => 'published', 'published_at' => now(), 'published_by_user_id' => (int) $user->getKey(), ])->save(); if ($customerSafeReady) { $review = markEnvironmentReviewCustomerSafeReady($review); } $review->loadMissing('sections'); $appendixSection = $review->sections->first(); if ($appendixSection instanceof \App\Models\EnvironmentReviewSection) { $appendixSection->forceFill([ 'render_payload' => array_replace_recursive( is_array($appendixSection->render_payload) ? $appendixSection->render_payload : [], [ 'entries' => [ [ 'title' => 'Spec357 Technical Control', 'summary' => 'Visible only on appendix-capable profiles.', ], ], ], ), ])->save(); } $filePath = 'review-packs/'.($environment->external_id ?: 'spec357').'/browser-report.zip'; Storage::disk('exports')->put($filePath, 'PK-spec357-browser-report'); $summary = array_replace_recursive([ 'governance_package' => [ 'executive_summary' => 'Spec 357 browser report summary.', 'top_findings' => [], 'accepted_risks' => [], 'decision_summary' => [ 'status' => 'none', 'summary' => '', 'next_action' => '', 'entries' => [], ], ], 'control_interpretation' => [ 'non_certification_disclosure' => 'Spec 357 browser non-certification disclosure.', ], 'recommended_next_actions' => [], 'delivery_bundle' => [ 'executive_entrypoint_file' => 'executive-summary.md', 'appendix_files' => ['metadata.json', 'summary.json', 'sections.json'], ], ], is_array($packOverrides['summary'] ?? null) ? $packOverrides['summary'] : []); $pack = ReviewPack::factory()->ready()->create(array_merge([ '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(), 'options' => [ 'include_pii' => false, 'include_operations' => true, ], 'summary' => $summary, 'file_path' => $filePath, 'file_disk' => 'exports', 'generated_at' => now()->subMinutes(3), 'expires_at' => now()->addDay(), ], $packOverrides ?? [])); $review->forceFill([ 'current_export_review_pack_id' => (int) $pack->getKey(), ])->save(); return [$user, $environment, $review->fresh(['sections', 'evidenceSnapshot', 'currentExportReviewPack']), $pack->fresh()]; }