fix(test): make ai_credits_reaper.rs resilient to accumulated stale holds
Some checks failed
build-and-release / build (catering-services) (push) Successful in 1m30s
build-and-release / build (employees) (push) Successful in 1m42s
build-and-release / build (cron) (push) Successful in 2m11s
build-and-release / build (companies) (push) Successful in 2m16s
build-and-release / build (gateway) (push) Successful in 39s
build-and-release / build (developers) (push) Successful in 2m49s
build-and-release / build (customers) (push) Successful in 3m0s
build-and-release / build (graphic-designers) (push) Successful in 1m36s
build-and-release / build (jobs) (push) Successful in 1m46s
build-and-release / build (fitness-trainers) (push) Successful in 2m54s
build-and-release / build (job-seekers) (push) Successful in 2m17s
build-and-release / build (photographers) (push) Successful in 1m43s
build-and-release / build (payments) (push) Successful in 2m45s
build-and-release / build (makeup-artists) (push) Successful in 3m6s
build-and-release / build (social-media-managers) (push) Successful in 2m34s
backend-integration-tests / ai-credits (push) Failing after 1m7s
build-and-release / build (tutors) (push) Successful in 2m46s
build-and-release / build (ugc-content-creators) (push) Successful in 3m1s
build-and-release / build (users) (push) Has been cancelled
build-and-release / build (video-editors) (push) Has been cancelled

The sweep query is intentionally global (matches the real cron
reaper), but against a persistent, never-reset test database re-run
many times over a debugging session, other tests' un-captured/
un-released reservations eventually go stale and get picked up
alongside this test's own hold, breaking the exact-match assertion
(observed: 6 expired holds instead of 1). Clear pre-existing stale
'held' rows first, matching the clean slate a continuously-running
production reaper would actually maintain.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Ashwin Kumar Sivakumar 2026-08-13 22:01:24 +05:30
parent b48a1dd204
commit 85690b3002

View file

@ -36,6 +36,20 @@ async fn expired_hold_is_swept_and_credits_return_to_available() {
AiCreditsRepository::ensure_wallet(&pool, user_id).await.unwrap();
// This test's sweep query below is intentionally global (it mirrors the
// real cron reaper, which sweeps every wallet, not just one) - in a real
// deployment the reaper runs continuously so nothing stays 'held' past
// its expiry for long. Against a persistent test database re-run many
// times over a session (not wiped between CI runs), other tests'
// reservations that were never captured/released can accumulate and go
// stale, which would make the exact-match assertion below flaky. Sweep
// those first so this test starts from the same clean slate a real
// continuously-running reaper would maintain.
sqlx::query("DELETE FROM ai_reservation_holds WHERE status = 'held' AND expires_at < NOW()")
.execute(&pool)
.await
.unwrap();
let hold = AiCreditsRepository::try_reserve_credits(&pool, user_id, "help_answer", 4, None, None)
.await
.expect("reserve");