TenantAtlas/apps/platform/tests/Feature/EnvironmentReview/Spec359ReviewComposeIdempotencyTest.php
Ahmed Darrazi 77c68d2d90
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m1s
feat: implement review compose reconciliation adapter (spec 359)
2026-06-06 16:41:10 +02:00

74 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
use App\Jobs\ComposeEnvironmentReviewJob;
use App\Models\EnvironmentReview;
use App\Services\EnvironmentReviews\EnvironmentReviewFingerprint;
use App\Services\EnvironmentReviews\EnvironmentReviewService;
use App\Support\EnvironmentReviewStatus;
use Illuminate\Database\QueryException;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
uses(RefreshDatabase::class);
it('reuses the existing mutable review and active run for repeated Spec359 create triggers', function (): void {
Queue::fake();
[$user, $tenant] = createUserWithTenant(role: 'owner');
$snapshot = seedEnvironmentReviewEvidence($tenant, operationRunCount: 2);
/** @var EnvironmentReviewService $service */
$service = app(EnvironmentReviewService::class);
$first = $service->create($tenant, $snapshot, $user);
$second = $service->create($tenant, $snapshot, $user);
expect((int) $second->getKey())->toBe((int) $first->getKey())
->and((int) $second->operation_run_id)->toBe((int) $first->operation_run_id);
Queue::assertPushed(ComposeEnvironmentReviewJob::class, 1);
});
it('reuses the existing mutable review for repeated Spec359 refresh triggers', function (): void {
Queue::fake();
[$user, $tenant] = createUserWithTenant(role: 'owner');
$snapshot = seedEnvironmentReviewEvidence($tenant);
/** @var EnvironmentReviewService $service */
$service = app(EnvironmentReviewService::class);
$review = $service->create($tenant, $snapshot, $user)->refresh();
$reused = $service->refresh($review, $user, $snapshot);
expect((int) $reused->getKey())->toBe((int) $review->getKey())
->and((int) $reused->operation_run_id)->toBe((int) $review->operation_run_id);
Queue::assertPushed(ComposeEnvironmentReviewJob::class, 1);
});
it('enforces the Spec359 mutable fingerprint uniqueness contract on PostgreSQL', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$snapshot = seedEnvironmentReviewEvidence($tenant);
$fingerprint = app(EnvironmentReviewFingerprint::class)->forSnapshot($tenant, $snapshot);
EnvironmentReview::factory()->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(),
'fingerprint' => $fingerprint,
'status' => EnvironmentReviewStatus::Draft->value,
]);
expect(fn () => 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(),
'fingerprint' => $fingerprint,
]))->toThrow(QueryException::class);
})->group('pgsql');