browser()->timeout(60_000); it('Spec361 smokes canonical evidence snapshot reconciliation drill-through on the existing operations surfaces', function (): void { [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); spec361AuthenticateBrowser($this, $user, $environment); $snapshot = restateEnvironmentReviewEvidenceSnapshot( seedEnvironmentReviewEvidence($environment, operationRunCount: 2), EvidenceCompletenessState::Complete, ); $run = spec361BrowserCreateCanonicalReconciledEvidenceRun($environment, $user, $snapshot); visit(OperationRunLinks::index($environment)) ->resize(1440, 1100) ->waitForText('Operations Hub') ->assertSee('Automatically reconciled') ->assertSee('No action needed.') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); visit(OperationRunLinks::tenantlessView($run)) ->waitForText('Monitoring detail') ->assertSee('Automatically reconciled') ->click('Open') ->assertSee('View evidence snapshot') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); }); it('Spec361 smokes canonical review-pack reconciliation drill-through on the existing operations surfaces', function (): void { [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); spec361AuthenticateBrowser($this, $user, $environment); [$pack, $run] = spec361BrowserCreateCanonicalReconciledReviewPackRun($environment, $user); visit(OperationRunLinks::index($environment)) ->resize(1440, 1100) ->waitForText('Operations Hub') ->assertSee('Automatically reconciled') ->assertSee('Review the source review before sharing this pack.') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); visit(OperationRunLinks::tenantlessView($run)) ->waitForText('Monitoring detail') ->assertSee('Automatically reconciled') ->click('Open') ->assertSee('View review pack') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); }); function spec361AuthenticateBrowser(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 spec361BrowserCreateCanonicalReconciledEvidenceRun( ManagedEnvironment $environment, User $user, mixed $snapshot, ): OperationRun { $run = OperationRun::factory()->forTenant($environment)->create([ 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'tenant.evidence.snapshot.generate', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, 'created_at' => now()->subMinutes(30), 'context' => [ 'workspace_id' => (int) $environment->workspace_id, 'managed_environment_id' => (int) $environment->getKey(), 'fingerprint' => (string) $snapshot->fingerprint, ], ]); return app(OperationRunService::class)->updateRunWithReconciliation( run: $run, status: OperationRunStatus::Completed->value, outcome: OperationRunOutcome::Succeeded->value, summaryCounts: [ 'finding_count' => (int) data_get($snapshot->summary, 'finding_count', 0), 'report_count' => (int) data_get($snapshot->summary, 'report_count', 0), 'operation_count' => (int) data_get($snapshot->summary, 'operation_count', 0), ], failures: [], reasonCode: 'run.adapter_out_of_sync', reasonMessage: 'A matching evidence snapshot was already available for this run.', source: 'adapter_reconciler', evidence: [ 'fingerprint' => (string) $snapshot->fingerprint, ], adapter: 'evidence_snapshot', decision: 'reconciled_succeeded', related: [ 'type' => 'evidence_snapshot', 'id' => (int) $snapshot->getKey(), 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, ], )->fresh(); } /** * @return array{0: ReviewPack, 1: OperationRun} */ function spec361BrowserCreateCanonicalReconciledReviewPackRun( ManagedEnvironment $environment, User $user, ): array { $snapshot = restateEnvironmentReviewEvidenceSnapshot( seedEnvironmentReviewEvidence($environment, operationRunCount: 2), EvidenceCompletenessState::Complete, ); $review = composeEnvironmentReviewForTest($environment, $user, $snapshot); $options = [ 'include_pii' => false, 'include_operations' => true, ]; $fingerprint = app(ReviewPackService::class)->computeFingerprintForReview($review, $options); $publishedRun = OperationRun::factory()->forTenant($environment)->create([ 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'environment.review_pack.generate', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'completed_at' => now()->subMinutes(5), ]); $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(), 'operation_run_id' => (int) $publishedRun->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), 'fingerprint' => $fingerprint, 'options' => $options, 'status' => ReviewPackStatus::Ready->value, 'summary' => [ 'finding_count' => 4, 'report_count' => 2, 'operation_count' => 3, ], ]); $run = OperationRun::factory()->forTenant($environment)->create([ 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'environment.review_pack.generate', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, 'created_at' => now()->subMinutes(30), 'context' => [ 'workspace_id' => (int) $environment->workspace_id, 'managed_environment_id' => (int) $environment->getKey(), 'environment_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'include_pii' => $options['include_pii'], 'include_operations' => $options['include_operations'], ], ]); $run = app(OperationRunService::class)->updateRunWithReconciliation( run: $run, status: OperationRunStatus::Completed->value, outcome: OperationRunOutcome::Succeeded->value, summaryCounts: [ 'finding_count' => 4, 'report_count' => 2, 'operation_count' => 3, ], failures: [], reasonCode: 'run.adapter_out_of_sync', reasonMessage: 'A matching review pack was already available for this run.', source: 'adapter_reconciler', evidence: [ 'fingerprint' => $fingerprint, ], adapter: 'review_pack', decision: 'reconciled_succeeded', related: [ 'type' => 'review_pack', 'id' => (int) $pack->getKey(), 'status' => ReviewPackStatus::Ready->value, 'environment_review_id' => (int) $review->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), ], )->fresh(); return [$pack, $run]; }