browser()->timeout(60_000); it('Spec365 smokes confirmed review reconciliation guidance on operations surfaces', function (): void { [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); spec365BrowserAuthenticate($this, $user, $environment); $snapshot = seedEnvironmentReviewEvidence($environment, operationRunCount: 0); $fingerprint = app(EnvironmentReviewFingerprint::class)->forSnapshot($environment, $snapshot); $run = spec365BrowserCreateStaleReviewRun($environment, $user, $fingerprint, $snapshot); spec365BrowserCreateReadyReviewTruth($environment, $user, $snapshot, $fingerprint); visit(OperationRunLinks::index($environment)) ->resize(1440, 1100) ->waitForText('Operations Hub') ->assertSee('Reconcile run') ->assertSee('Existing repository proof may safely reconcile this stale run.') ->assertDontSee('SQLSTATE') ->assertDontSee('access token') ->assertDontSee('client secret') ->assertDontSee('serialized job') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); visit(OperationRunLinks::tenantlessView($run)) ->waitForText('Monitoring detail') ->assertSee('Reconcile run') ->click('Reconcile run') ->assertSee('Reconcile this operation run?') ->assertSee('This does not retry or change the Microsoft tenant.') ->assertDontSee('SQLSTATE') ->assertDontSee('environment_reviews_fingerprint_mutable_unique') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); }); it('Spec365 smokes related proof actions across evidence report sync and backup states', function (): void { [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); spec365BrowserAuthenticate($this, $user, $environment); spec365BrowserCreateEvidenceRun($environment, $user); spec365BrowserCreateReviewPackRun($environment, $user); spec365BrowserCreatePartialInventoryRun($environment, $user); spec365BrowserCreateBlockedBackupRun($environment, $user); visit(OperationRunLinks::index($environment)) ->resize(1440, 1100) ->waitForText('Operations Hub') ->assertSee('View evidence') ->assertSee('View report') ->assertSee('View affected families') ->assertSee('View backup details') ->assertDontSee('SQLSTATE') ->assertDontSee('Guzzle') ->assertDontSee('stack trace') ->assertDontSee('access token') ->assertDontSee('client secret') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); }); it('Spec365 smokes high-risk restore guidance without unsafe operator actions', function (): void { [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'manager'); spec365BrowserAuthenticate($this, $user, $environment); $run = spec365BrowserCreateStaleRestoreRun($environment, $user); visit(OperationRunLinks::tenantlessView($run)) ->resize(1440, 1100) ->waitForText('Monitoring detail') ->assertSee('View restore details') ->assertSee('High-risk operations cannot be retried from this view.') ->assertDontSee('Retry restore') ->assertDontSee('Force complete') ->assertDontSee('Mark succeeded') ->assertDontSee('Delete run') ->assertDontSee('Purge run') ->assertDontSee('stack trace') ->assertDontSee('access token') ->assertDontSee('client secret') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); }); function spec365BrowserAuthenticate(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 spec365BrowserCreateStaleReviewRun( ManagedEnvironment $environment, User $user, string $fingerprint, EvidenceSnapshot $snapshot, ): OperationRun { return OperationRun::factory()->forTenant($environment)->create([ 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'environment.review.compose', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, 'created_at' => now()->subMinutes(10), 'context' => [ 'workspace_id' => (int) $environment->workspace_id, 'managed_environment_id' => (int) $environment->getKey(), 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'review_fingerprint' => $fingerprint, ], ]); } function spec365BrowserCreateReadyReviewTruth( ManagedEnvironment $environment, User $user, EvidenceSnapshot $snapshot, string $fingerprint, ): EnvironmentReview { $publishedRun = OperationRun::factory()->forTenant($environment)->create([ 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'environment.review.compose', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'completed_at' => now()->subMinutes(5), 'context' => [ 'workspace_id' => (int) $environment->workspace_id, 'managed_environment_id' => (int) $environment->getKey(), 'review_fingerprint' => $fingerprint, ], ]); return EnvironmentReview::factory()->ready()->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(), 'operation_run_id' => (int) $publishedRun->getKey(), 'fingerprint' => $fingerprint, 'summary' => [ 'finding_count' => 4, 'report_count' => 2, 'operation_count' => 1, ], ]); } function spec365BrowserCreateStaleRestoreRun(ManagedEnvironment $environment, User $user): OperationRun { $backupSet = BackupSet::factory()->for($environment)->create(['status' => 'completed']); $run = OperationRun::factory()->forTenant($environment)->create([ 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'restore.execute', 'status' => OperationRunStatus::Queued->value, 'outcome' => OperationRunOutcome::Pending->value, 'created_at' => now()->subMinutes(10), ]); $restoreRun = RestoreRun::withoutEvents(fn (): RestoreRun => RestoreRun::factory() ->for($environment, 'tenant') ->for($backupSet) ->create([ 'workspace_id' => (int) $environment->workspace_id, 'operation_run_id' => (int) $run->getKey(), 'status' => RestoreRunStatus::Completed->value, 'is_dry_run' => false, ])); $run->forceFill([ 'context' => [ 'restore_run_id' => (int) $restoreRun->getKey(), 'backup_set_id' => (int) $backupSet->getKey(), ], ])->save(); return $run->fresh(); } function spec365BrowserCreateEvidenceRun(ManagedEnvironment $environment, User $user): OperationRun { $run = OperationRun::factory()->forTenant($environment)->create([ 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'tenant.evidence.snapshot.generate', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'completed_at' => now()->subMinutes(3), ]); EvidenceSnapshot::query()->create([ 'workspace_id' => (int) $environment->workspace_id, 'managed_environment_id' => (int) $environment->getKey(), 'operation_run_id' => (int) $run->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), 'fingerprint' => hash('sha256', 'spec365-browser-evidence-'.$run->getKey()), 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, 'summary' => ['source' => 'spec365-browser'], 'generated_at' => now()->subMinutes(3), ]); return $run->fresh(); } function spec365BrowserCreateReviewPackRun(ManagedEnvironment $environment, User $user): OperationRun { $run = 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(4), ]); ReviewPack::factory()->ready()->create([ 'workspace_id' => (int) $environment->workspace_id, 'managed_environment_id' => (int) $environment->getKey(), 'operation_run_id' => (int) $run->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), ]); return $run->fresh(); } function spec365BrowserCreatePartialInventoryRun(ManagedEnvironment $environment, User $user): OperationRun { return OperationRun::factory()->forTenant($environment)->create([ 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory.sync', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::PartiallySucceeded->value, 'completed_at' => now()->subMinutes(5), 'summary_counts' => [ 'total' => 4, 'processed' => 4, 'succeeded' => 2, 'failed' => 1, 'skipped' => 1, ], ]); } function spec365BrowserCreateBlockedBackupRun(ManagedEnvironment $environment, User $user): OperationRun { $backupSet = BackupSet::factory()->for($environment)->create(['status' => 'completed']); return OperationRun::factory()->forTenant($environment)->create([ 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'backup.schedule.execute', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Blocked->value, 'completed_at' => now()->subMinutes(6), 'context' => [ 'backup_set_id' => (int) $backupSet->getKey(), 'reason_code' => 'missing_provider_permission', ], ]); }