TenantAtlas/apps/platform/tests/Browser/Spec326CustomerReviewWorkspaceProductizationSmokeTest.php

239 lines
9.9 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('Is this review ready to share?')
->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('Is this review ready to share?')
->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;
}