TenantAtlas/apps/platform/tests/Feature/Operations/Spec359OperationRunAdapterReconciliationTest.php
ahmido 3a750726fd feat: implement review compose reconciliation adapter (spec 359) (#430)
Spec 359: add a narrow review-compose reconciliation path, deterministic duplicate/superseded recovery, shared review truth resolution, and bounded unit/feature/browser coverage. PGSQL validation remains locally blocked because the pgsql host/Docker runtime was unavailable.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #430
2026-06-06 14:58:16 +00:00

126 lines
5.2 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\Operations\TenantlessOperationRunViewer;
use App\Filament\Resources\EnvironmentReviewResource;
use App\Models\EnvironmentReview;
use App\Models\OperationRun;
use App\Services\AdapterRunReconciler;
use App\Services\EnvironmentReviews\EnvironmentReviewFingerprint;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
uses(RefreshDatabase::class);
it('reconciles a stale Spec359 review-compose run from a matching ready review and resolves the winning review truth', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$snapshot = seedEnvironmentReviewEvidence($tenant, operationRunCount: 3);
$fingerprint = app(EnvironmentReviewFingerprint::class)->forSnapshot($tenant, $snapshot);
$run = OperationRun::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
'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(30),
'context' => [
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
'evidence_snapshot_id' => (int) $snapshot->getKey(),
'review_fingerprint' => $fingerprint,
],
]);
$publishedRun = OperationRun::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
'type' => 'environment.review.compose',
'status' => OperationRunStatus::Completed->value,
'outcome' => OperationRunOutcome::Succeeded->value,
]);
$review = EnvironmentReview::factory()->ready()->create([
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->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' => 3,
],
]);
$change = app(AdapterRunReconciler::class)->reconcileOperationRun($run, false);
expect($change['applied'] ?? null)->toBeTrue();
$run->refresh();
expect($run->status)->toBe(OperationRunStatus::Completed->value)
->and($run->outcome)->toBe(OperationRunOutcome::Succeeded->value)
->and($run->reconciliationDecision())->toBe('reconciled_succeeded')
->and($run->reconciliationAdapter())->toBe('environment_review_compose')
->and($run->reconciledRelatedReviewId())->toBe((int) $review->getKey());
$truth = app(ArtifactTruthPresenter::class)->forOperationRun($run->fresh());
expect($truth->relatedArtifactUrl)->toBe(
EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant),
);
});
it('shows calm Spec359 matching-review copy on the tenantless run detail surface', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$snapshot = seedEnvironmentReviewEvidence($tenant);
$fingerprint = app(EnvironmentReviewFingerprint::class)->forSnapshot($tenant, $snapshot);
$run = OperationRun::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
'user_id' => (int) $user->getKey(),
'initiator_name' => $user->name,
'type' => 'environment.review.compose',
'status' => OperationRunStatus::Completed->value,
'outcome' => OperationRunOutcome::Succeeded->value,
'context' => [
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
'review_fingerprint' => $fingerprint,
'reconciliation' => [
'reconciled_at' => now()->toIso8601String(),
'reason' => 'run.adapter_out_of_sync',
'reason_code' => 'run.adapter_out_of_sync',
'source' => 'adapter_reconciler',
'adapter' => 'environment_review_compose',
'decision' => 'reconciled_succeeded',
'related' => [
'review' => [
'id' => 88,
],
],
],
],
]);
Filament::setTenant(null, true);
$this->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]);
session([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]);
Livewire::actingAs($user)
->test(TenantlessOperationRunViewer::class, ['run' => $run])
->assertSee('A matching review was already available.')
->assertSee('No action needed. A matching review was already available.');
});