assertSee('Is this evidence package ready for customer or auditor consumption?') ->assertSee('Evidence snapshot required') ->assertSee('Review pack output cannot be trusted or exported yet.') ->assertSee('Generate evidence snapshot') ->assertSee('Evidence readiness flow') ->assertSee('Evidence proof') ->assertSee('Diagnostics - Collapsed') ->assertDontSee('raw payload should stay hidden') ->assertDontSee('provider response should stay hidden') ->assertDontSee('stack trace should stay hidden'); $content = $component->html(); spec337AssertFlowStep($content, 'Source data selected', 'Available', false); spec337AssertFlowStep($content, 'Evidence snapshot', 'Missing', true); spec337AssertFlowStep($content, 'Stored report', 'Unavailable', false); spec337AssertFlowStep($content, 'Review pack', 'Unavailable', false); spec337AssertFlowStep($content, 'Customer-safe output', 'Not ready', false); spec337AssertFlowStep($content, 'Export / delivery', 'Unavailable', false); expect(substr_count($content, 'data-testid="evidence-readiness-step"'))->toBe(6) ->and($content)->toContain('data-testid="evidence-readiness-flow" class="@container') ->and($content)->not->toContain('data-testid="evidence-disclosure-diagnostics" open'); }); it('renders stored report missing without inventing review-pack or export readiness', function (): void { [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); spec337CreateEvidenceSnapshot($environment); $component = spec337EvidenceOverviewLivewire($user, $environment) ->assertSee('Stored report required') ->assertSee('Evidence snapshot exists, but no stored report is available for this review output.') ->assertSee('Open evidence snapshot') ->assertDontSee('Review pack export available') ->assertDontSee('Customer-safe output ready') ->assertDontSee('Download export'); $content = $component->html(); spec337AssertFlowStep($content, 'Evidence snapshot', 'Available', false); spec337AssertFlowStep($content, 'Stored report', 'Missing', true); spec337AssertFlowStep($content, 'Review pack', 'Unavailable', false); spec337AssertFlowStep($content, 'Customer-safe output', 'Not ready', false); spec337AssertFlowStep($content, 'Export / delivery', 'Unavailable', false); }); it('renders review pack required with capability-aware primary action', function (): void { [$owner, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); [$readonly] = createUserWithTenant(tenant: $environment, role: 'readonly', workspaceRole: 'readonly'); $snapshot = spec337CreateEvidenceSnapshot($environment); spec337CreateStoredReport($environment); $ownerComponent = spec337EvidenceOverviewLivewire($owner, $environment) ->assertSee('Review pack required') ->assertSee('Stored report exists, but a review pack has not been generated.') ->assertSee('Generate review pack') ->assertDontSee('Customer-safe output ready') ->assertDontSee('Review pack export available'); spec337AssertFlowStep($ownerComponent->html(), 'Review pack', 'Required', true); spec337EvidenceOverviewLivewire($readonly, $environment) ->assertSee('Review pack required') ->assertDontSee('Generate review pack') ->assertSee('Open evidence snapshot') ->assertSee((string) $snapshot->tenant?->name); }); it('renders repo-backed customer-safe and export-ready output without broad readiness claims', function (): void { [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); $snapshot = spec337CreateEvidenceSnapshot($environment); spec337CreateStoredReport($environment); [$review, $pack] = spec337CreatePublishedReviewWithReadyPack($environment, $user, $snapshot); $component = spec337EvidenceOverviewLivewire($user, $environment) ->assertSee('Review pack export available') ->assertSee('A generated export artifact is available for authorized download.') ->assertSee('external sharing remains governed by workspace policy') ->assertSee('Download export') ->assertSee('Customer-safe output') ->assertSee('Ready') ->assertSee('Review pack contents / coverage') ->assertSee('Findings included') ->assertSee('Evidence dimensions') ->assertDontSee('Auditor-ready') ->assertDontSee('environment is healthy') ->assertDontSee('compliant'); $content = $component->html(); spec337AssertFlowStep($content, 'Evidence snapshot', 'Available', false); spec337AssertFlowStep($content, 'Stored report', 'Available', false); spec337AssertFlowStep($content, 'Review pack', 'Available', false); spec337AssertFlowStep($content, 'Customer-safe output', 'Ready', false); spec337AssertFlowStep($content, 'Export / delivery', 'Available', true); expect($review->current_export_review_pack_id)->toBe($pack->getKey()); }); it('renders generating and failed operation proof separately from usable output', function (): void { [$user, $generatingEnvironment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); $generatingRun = OperationRun::factory()->forTenant($generatingEnvironment)->create([ 'type' => OperationRunType::EvidenceSnapshotGenerate->value, 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, 'started_at' => now()->subMinute(), 'initiator_name' => 'Spec337 Operator', ]); spec337CreateEvidenceSnapshot($generatingEnvironment, [ 'operation_run_id' => (int) $generatingRun->getKey(), 'status' => EvidenceSnapshotStatus::Generating->value, 'generated_at' => null, ]); $generatingComponent = spec337EvidenceOverviewLivewire($user, $generatingEnvironment) ->assertSee('Evidence generation in progress') ->assertSee('View operation progress') ->assertSee('Operation proof') ->assertSee('Generating') ->assertSee('Spec337 Operator') ->assertDontSee('Customer-safe output ready'); spec337AssertFlowStep($generatingComponent->html(), 'Evidence snapshot', 'Generating', true); $failedEnvironment = createUserWithTenant(user: $user, role: 'owner', workspaceRole: 'manager')[1]; $failedRun = OperationRun::factory()->forTenant($failedEnvironment)->create([ 'type' => OperationRunType::ReviewPackGenerate->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, 'started_at' => now()->subMinutes(3), 'completed_at' => now()->subMinute(), 'initiator_name' => 'Spec337 Reviewer', ]); $failedSnapshot = spec337CreateEvidenceSnapshot($failedEnvironment); spec337CreateStoredReport($failedEnvironment); ReviewPack::factory()->failed()->create([ 'managed_environment_id' => (int) $failedEnvironment->getKey(), 'workspace_id' => (int) $failedEnvironment->workspace_id, 'evidence_snapshot_id' => (int) $failedSnapshot->getKey(), 'operation_run_id' => (int) $failedRun->getKey(), ]); $failedComponent = spec337EvidenceOverviewLivewire($user, $failedEnvironment) ->assertSee('Review pack generation failed') ->assertSee('Review operation') ->assertSee('Operation proof') ->assertSee('Failed') ->assertSee('Spec337 Reviewer') ->assertDontSee('Review pack export available'); spec337AssertFlowStep($failedComponent->html(), 'Review pack', 'Failed', true); }); it('preserves workspace isolation and avoids legacy tenant aliases in rendered links', function (): void { [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); $foreignEnvironment = ManagedEnvironment::factory()->active()->create([ 'name' => 'Spec337 Foreign Workspace Environment', ]); spec337CreateEvidenceSnapshot($foreignEnvironment); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id]) ->get(route('admin.evidence.overview')) ->assertOk() ->assertDontSee('Spec337 Foreign Workspace Environment'); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id]) ->get(route('admin.evidence.overview', ['environment_id' => (int) $foreignEnvironment->getKey()])) ->assertNotFound(); $content = spec337EvidenceOverviewLivewire($user, $environment)->html(); expect($content) ->not->toContain('/admin/t/') ->not->toContain('tenant_id='); } ); function spec337EvidenceOverviewLivewire(User $user, ManagedEnvironment $environment): mixed { session()->put(WorkspaceContext::SESSION_KEY, (int) $environment->workspace_id); setAdminPanelContext($environment); return Livewire::withQueryParams([ 'environment_id' => (int) $environment->getKey(), ]) ->actingAs($user) ->test(EvidenceOverview::class); } /** * @param array $attributes */ function spec337CreateEvidenceSnapshot(ManagedEnvironment $environment, array $attributes = []): EvidenceSnapshot { $snapshot = EvidenceSnapshot::query()->create(array_replace([ 'managed_environment_id' => (int) $environment->getKey(), 'workspace_id' => (int) $environment->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => sha1('spec337-snapshot-'.$environment->getKey().'-'.microtime(true)), 'completeness_state' => EvidenceCompletenessState::Complete->value, 'summary' => [ 'dimension_count' => 5, 'missing_dimensions' => 0, 'stale_dimensions' => 0, 'raw_payload' => 'raw payload should stay hidden', 'provider_response' => 'provider response should stay hidden', 'stack_trace' => 'stack trace should stay hidden', ], 'generated_at' => now(), 'expires_at' => now()->addDays(30), ], $attributes)); $snapshot->items()->create([ 'managed_environment_id' => (int) $environment->getKey(), 'workspace_id' => (int) $environment->workspace_id, 'dimension_key' => 'permission_posture', 'state' => (string) ($snapshot->completeness_state ?: EvidenceCompletenessState::Complete->value), 'required' => true, 'source_kind' => 'stored_report', 'source_record_type' => StoredReport::class, 'source_record_id' => null, 'source_fingerprint' => null, 'measured_at' => now(), 'freshness_at' => now(), 'summary_payload' => [ 'label' => 'Permission posture', 'state' => 'complete', ], 'sort_order' => 1, ]); return $snapshot->load([ 'tenant', 'operationRun', 'reviewPacks.operationRun', 'reviewPacks.environmentReview.currentExportReviewPack', 'items', ]); } function spec337CreateStoredReport(ManagedEnvironment $environment): StoredReport { return StoredReport::factory()->permissionPosture([ 'raw_payload' => 'raw payload should stay hidden', 'provider_response' => 'provider response should stay hidden', 'stack_trace' => 'stack trace should stay hidden', ])->create([ 'managed_environment_id' => (int) $environment->getKey(), 'workspace_id' => (int) $environment->workspace_id, 'fingerprint' => sha1('spec337-report-'.$environment->getKey().'-'.microtime(true)), ]); } /** * @return array{0: EnvironmentReview, 1: ReviewPack} */ function spec337CreatePublishedReviewWithReadyPack( ManagedEnvironment $environment, User $user, EvidenceSnapshot $snapshot, ): array { $review = EnvironmentReview::query()->create([ 'workspace_id' => (int) $environment->workspace_id, 'managed_environment_id' => (int) $environment->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), 'published_by_user_id' => (int) $user->getKey(), 'fingerprint' => sha1('spec337-review-'.$environment->getKey().'-'.microtime(true)), 'status' => EnvironmentReviewStatus::Published->value, 'completeness_state' => EnvironmentReviewCompletenessState::Complete->value, 'summary' => [ 'governance_package' => [ 'decision_summary' => [ 'status' => 'ready', 'evidence_state' => EnvironmentReviewCompletenessState::Complete->value, 'decision_data_state' => 'complete', ], ], ], 'generated_at' => now()->subMinutes(5), 'published_at' => now()->subMinutes(3), ]); $run = OperationRun::factory()->forTenant($environment)->create([ 'type' => OperationRunType::ReviewPackGenerate->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'started_at' => now()->subMinutes(4), 'completed_at' => now()->subMinutes(2), 'initiator_name' => $user->name, ]); $pack = ReviewPack::factory()->ready()->create([ 'managed_environment_id' => (int) $environment->getKey(), 'workspace_id' => (int) $environment->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'environment_review_id' => (int) $review->getKey(), 'operation_run_id' => (int) $run->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), 'status' => ReviewPackStatus::Ready->value, 'summary' => [ 'finding_count' => 3, 'report_count' => 2, 'operation_count' => 1, 'section_count' => 4, 'evidence_resolution' => [ 'required_dimensions' => [ 'findings_summary', 'permission_posture', 'entra_admin_roles', ], ], ], ]); $review->forceFill([ 'current_export_review_pack_id' => (int) $pack->getKey(), ])->save(); return [$review->refresh(), $pack->refresh()]; } function spec337AssertFlowStep(string $content, string $label, string $state, bool $currentBlocker): void { $blocker = $currentBlocker ? 'true' : 'false'; expect($content)->toMatch( '/data-step-label="'.preg_quote($label, '/').'"[\s\S]*?data-step-state="'.preg_quote($state, '/').'"[\s\S]*?data-step-current-blocker="'.$blocker.'"[\s\S]*?>\s*'.preg_quote($state, '/').'\s*