TenantAtlas/apps/platform/tests/Browser/Spec349OutputResolutionGuidanceSmokeTest.php
Ahmed Darrazi acdb205e1b
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 3m42s
feat: customer review workspace output resolution guidance (spec 349)
Implemented the output resolution guidance for the customer review workspace and internal views. Added ReviewPackOutputResolutionGuidance, updated CustomerReviewWorkspace and EnvironmentReviewResource, and added related blade views and tests.
2026-06-03 03:31:29 +02:00

268 lines
11 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
use App\Models\EnvironmentReview;
use App\Models\EvidenceSnapshot;
use App\Models\ManagedEnvironment;
use App\Models\ReviewPack;
use App\Models\User;
use App\Support\EnvironmentReviewCompletenessState;
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('Spec349 smokes output resolution guidance states and collapsed disclosures', function (): void {
[$user, $readyEnvironment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager');
$readyEnvironment->forceFill(['name' => 'Spec349 Browser Ready'])->save();
$blockedEnvironment = spec349BrowserEnvironmentFor($user, $readyEnvironment, 'Spec349 Browser Blocked');
$internalEnvironment = spec349BrowserEnvironmentFor($user, $readyEnvironment, 'Spec349 Browser Internal');
spec349BrowserCreatePublishedReviewWithPack(
$readyEnvironment,
$user,
seedEnvironmentReviewEvidence($readyEnvironment, findingCount: 0, driftCount: 0),
[],
[
'include_pii' => false,
'include_operations' => true,
],
'review-packs/spec349-browser-ready.zip',
markReady: true,
);
spec349BrowserCreatePublishedReviewWithPack(
$blockedEnvironment,
$user,
seedPartialEnvironmentReviewEvidence($blockedEnvironment, findingCount: 0, driftCount: 0),
[
'governance_package' => [
'decision_summary' => [
'status' => 'incomplete',
'evidence_state' => EnvironmentReviewCompletenessState::Partial->value,
'decision_data_state' => 'incomplete',
'total_count' => 1,
'summary' => 'Decision evidence is incomplete for this released review.',
'next_action' => 'Review the evidence basis before relying on the decision summary.',
'entries' => [],
],
],
],
[
'include_pii' => false,
'include_operations' => true,
],
'review-packs/spec349-browser-blocked.zip',
markReady: false,
);
spec349BrowserCreatePublishedReviewWithPack(
$internalEnvironment,
$user,
seedEnvironmentReviewEvidence($internalEnvironment, findingCount: 0, driftCount: 0),
[],
[
'include_pii' => true,
'include_operations' => true,
],
'review-packs/spec349-browser-internal.zip',
markReady: true,
);
spec349AuthenticateBrowser($this, $user, $readyEnvironment);
$page = visit(CustomerReviewWorkspace::environmentFilterUrl($blockedEnvironment))
->resize(1236, 900)
->waitForText('Output not customer-ready')
->assertSee('Inspect review blockers')
->assertSee('Download review pack with limitations')
->assertSee('The primary action opens the review detail with blockers, evidence status, and next steps.')
->assertScript('Array.from(document.querySelectorAll("[data-testid=\"customer-review-decision-card\"] [data-testid=\"customer-review-secondary-action\"]")).some((element) => element.innerText.includes("Open review")) === false', true)
->assertSee('Requires review')
->assertScript('document.querySelector("[data-testid=\"customer-review-output-limitations\"]")?.open === false', true)
->assertScript('document.querySelector("[data-testid=\"customer-review-technical-details\"]")?.open === false', true)
->assertNoJavaScriptErrors()
->assertNoConsoleLogs();
$page->screenshot(true, spec349BrowserScreenshotName('01-output-blocked'));
spec349CopyBrowserScreenshot('01-output-blocked');
$page = visit(CustomerReviewWorkspace::environmentFilterUrl($internalEnvironment))
->waitForText('Internal review package available')
->assertSee('Review PII/redaction state')
->assertSee('Download internal review pack')
->assertSee('Internal only')
->assertNoJavaScriptErrors()
->assertNoConsoleLogs();
$page->screenshot(true, spec349BrowserScreenshotName('02-internal-only'));
spec349CopyBrowserScreenshot('02-internal-only');
$page = visit(CustomerReviewWorkspace::environmentFilterUrl($readyEnvironment))
->waitForText('Customer-safe review pack ready')
->assertSee('Download customer-safe review pack')
->assertDontSee('Ready to share')
->assertNoJavaScriptErrors()
->assertNoConsoleLogs();
$page->screenshot(true, spec349BrowserScreenshotName('03-customer-safe-ready'));
spec349CopyBrowserScreenshot('03-customer-safe-ready');
});
function spec349BrowserScreenshotName(string $name): string
{
return 'spec349-output-resolution-guidance-'.$name;
}
function spec349CopyBrowserScreenshot(string $name): void
{
$filename = spec349BrowserScreenshotName($name).'.png';
$source = base_path('tests/Browser/Screenshots/'.$filename);
$targetDirectory = repo_path('specs/349-customer-review-workspace-output-resolution-guidance/artifacts/screenshots');
if (! is_dir($targetDirectory)) {
@mkdir($targetDirectory, 0755, true);
}
if (! is_file($source)) {
$source = \Pest\Browser\Support\Screenshot::path($filename);
}
for ($attempt = 0; $attempt < 10 && ! is_file($source); $attempt++) {
usleep(100_000);
clearstatcache(true, $source);
}
if (is_file($source) && is_dir($targetDirectory) && is_writable($targetDirectory)) {
@copy($source, $targetDirectory.DIRECTORY_SEPARATOR.$name.'.png');
}
}
function spec349AuthenticateBrowser(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);
}
function spec349BrowserEnvironmentFor(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;
}
/**
* @param array<string, mixed> $summaryOverrides
* @param array<string, mixed> $packOptions
* @return array{0: EnvironmentReview, 1: ReviewPack}
*/
function spec349BrowserCreatePublishedReviewWithPack(
ManagedEnvironment $environment,
User $user,
EvidenceSnapshot $snapshot,
array $summaryOverrides = [],
array $packOptions = [],
string $filePath = 'review-packs/spec349-browser-review-pack.zip',
bool $markReady = true,
): array {
$review = composeEnvironmentReviewForTest($environment, $user, $snapshot);
$summary = array_replace_recursive(
is_array($review->summary) ? $review->summary : [],
[
'control_interpretation' => [
'version_key' => ComplianceEvidenceMappingV1::VERSION_KEY,
'controls' => [
[
'control_key' => 'customer-output',
'title' => 'Customer output',
'readiness_bucket' => $markReady ? 'evidence_on_record' : 'review_recommended',
'readiness_label' => $markReady ? 'Evidence on record' : 'Review recommended',
'primary_reason' => $markReady ? 'Evidence path is complete.' : 'Evidence basis needs review.',
'recommended_next_action' => $markReady ? 'Open the current customer review pack.' : 'Review the evidence basis before sharing.',
],
],
],
'governance_package' => [
'decision_summary' => [
'status' => $markReady ? 'none' : 'incomplete',
'evidence_state' => $markReady ? EnvironmentReviewCompletenessState::Complete->value : EnvironmentReviewCompletenessState::Partial->value,
'decision_data_state' => $markReady ? 'complete' : 'incomplete',
'total_count' => $markReady ? 0 : 1,
'summary' => $markReady
? 'No governance decisions require customer awareness.'
: 'Decision evidence is incomplete for this released review.',
'next_action' => $markReady
? 'Open the current customer review pack.'
: 'Review the evidence basis before relying on the decision summary.',
'entries' => [],
],
],
],
$summaryOverrides,
);
Storage::disk('exports')->put($filePath, 'PK-spec349-browser-test');
$review->forceFill([
'status' => EnvironmentReviewStatus::Published->value,
'completeness_state' => $markReady
? EnvironmentReviewCompletenessState::Complete->value
: (string) $review->completeness_state,
'summary' => $summary,
'generated_at' => now()->subMinutes(5),
'published_at' => now()->subMinutes(3),
'published_by_user_id' => (int) $user->getKey(),
])->save();
if ($markReady) {
$review = markEnvironmentReviewCustomerSafeReady($review);
}
$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(),
'options' => array_replace([
'include_pii' => false,
'include_operations' => true,
], $packOptions),
'file_path' => $filePath,
'file_disk' => 'exports',
'generated_at' => now()->subMinutes(4),
]);
$review->forceFill([
'current_export_review_pack_id' => (int) $pack->getKey(),
])->save();
return [$review->refresh(), $pack->refresh()];
}