[object Object]

← back to Costa Rica

costa-rica: fix date-dependent payouts test (113/113 green)

5cf7dca285f77dbae15dcb86c22fb8ed6378bbb9 · 2026-09-04 05:58:59 -0700 · Steve

Two tests failed today and would have passed on other dates — a genuinely flaky,
calendar-sensitive suite rather than a constant failure.

Root cause: mkBooking() hardcoded CURRENT_DATE + 7 .. + 9 on place_id 1 for every
booking. Migration 008 adds

  EXCLUDE USING gist (place_id WITH =, daterange(check_in, check_out, '[)') WITH &&)
  WHERE status IN ('confirmed','pending')

so a booking created with a non-completed status is covered by the constraint, while
the suite's default 'completed' bookings are not. There is a seeded confirmed booking
on place 1 for 2026-09-10..2026-09-13; with today at 2026-09-04 the +7/+9 window is
2026-09-11..2026-09-13, which overlaps it, so the 'rejects a booking that is not
completed' subtest collided and took its parent down with it.

Fix: give each test booking its own far-future, non-overlapping window via a
per-booking offset (CURRENT_DATE + 1000 + n*3, two nights each). That clears both the
seeded-row collision and the possibility of two pending test bookings colliding with
each other, and makes the suite deterministic on every date.

Test-only change; no product code touched. Verified 113 pass / 0 fail, and the same
2 failures reproduce on the pre-fix tree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QfGYEoLBywwJD1nfrHe1on

Files touched

Diff

commit 5cf7dca285f77dbae15dcb86c22fb8ed6378bbb9
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Sep 4 05:58:59 2026 -0700

    costa-rica: fix date-dependent payouts test (113/113 green)
    
    Two tests failed today and would have passed on other dates — a genuinely flaky,
    calendar-sensitive suite rather than a constant failure.
    
    Root cause: mkBooking() hardcoded CURRENT_DATE + 7 .. + 9 on place_id 1 for every
    booking. Migration 008 adds
    
      EXCLUDE USING gist (place_id WITH =, daterange(check_in, check_out, '[)') WITH &&)
      WHERE status IN ('confirmed','pending')
    
    so a booking created with a non-completed status is covered by the constraint, while
    the suite's default 'completed' bookings are not. There is a seeded confirmed booking
    on place 1 for 2026-09-10..2026-09-13; with today at 2026-09-04 the +7/+9 window is
    2026-09-11..2026-09-13, which overlaps it, so the 'rejects a booking that is not
    completed' subtest collided and took its parent down with it.
    
    Fix: give each test booking its own far-future, non-overlapping window via a
    per-booking offset (CURRENT_DATE + 1000 + n*3, two nights each). That clears both the
    seeded-row collision and the possibility of two pending test bookings colliding with
    each other, and makes the suite deterministic on every date.
    
    Test-only change; no product code touched. Verified 113 pass / 0 fail, and the same
    2 failures reproduce on the pre-fix tree.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01QfGYEoLBywwJD1nfrHe1on
---
 test/payouts.test.js | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/test/payouts.test.js b/test/payouts.test.js
index 9c39ced..45f4736 100644
--- a/test/payouts.test.js
+++ b/test/payouts.test.js
@@ -37,13 +37,30 @@ async function mkPayoutMethod(hostId, kind, extra = {}) {
   await pool.query(`UPDATE hosts SET default_payout_method_id=$1 WHERE id=$2`, [pm.id, hostId]);
   return pm.id;
 }
+// Each test booking gets its OWN far-future, non-overlapping date window.
+//
+// The old version hardcoded CURRENT_DATE + 7 .. + 9 for every booking on place_id 1,
+// which made this suite DATE-DEPENDENT: migration 008 adds
+//   EXCLUDE ... (place_id WITH =, daterange(check_in, check_out, '[)') WITH &&)
+//   WHERE status IN ('confirmed','pending')
+// so any booking created with a non-completed status collided with the seeded
+// confirmed booking on place 1 (2026-09-10 .. 2026-09-13) whenever today's date put
+// the +7/+9 window inside it — passing most days and failing for a few. It also meant
+// two pending bookings in one run could collide with each other.
+//
+// A per-booking offset far past any seeded row removes both collision classes and
+// keeps the suite deterministic on every date.
+let bookingWindow = 0;
 async function mkBooking(hostId, travelerId, { status = 'completed', hostPayout = 36000 } = {}) {
+  const startOffset = 1000 + bookingWindow * 3;
+  bookingWindow += 1;
   const { rows: [b] } = await pool.query(
     // Satisfy the bookings CHECKs: has-a-date (check_in), stay-order (check_out>check_in),
     // and total_reconciles (total = platform_fee + host_payout, so platform_fee = 40000 - host_payout).
     `INSERT INTO bookings (code, place_id, host_id, traveler_id, currency, subtotal, total, platform_fee, host_payout, status, check_in, check_out)
-     VALUES ($1, 1, $2, $3, 'CRC', 36000, 40000, 40000 - $4, $4, $5, CURRENT_DATE + 7, CURRENT_DATE + 9) RETURNING id`,
-    [`${SENT}-${Math.random().toString(36).slice(2, 8)}`, hostId, travelerId, hostPayout, status]);
+     VALUES ($1, 1, $2, $3, 'CRC', 36000, 40000, 40000 - $4, $4, $5,
+             CURRENT_DATE + $6::int, CURRENT_DATE + ($6::int + 2)) RETURNING id`,
+    [`${SENT}-${Math.random().toString(36).slice(2, 8)}`, hostId, travelerId, hostPayout, status, startOffset]);
   return b.id;
 }
 

← 89fa33c Costa Rica server: remove the contacts import / list / invit  ·  back to Costa Rica  ·  app API: expose region_image_url so listings can fall back ( 26bd9e3 →