Skip to main content

Bilko integrationTest suite green — 79->0 failures (MC #102874) — 2026-06-03

Summary

MC #102874 took the Bilko backend integrationTest suite from 79 failing → 0 failing (1213 tests, 91 suites). These integration tests had never run in CI (tasks.test does excludeTags("integration")); the new CI job from MC #102843 exposed the rot. PR #246 (base main, not merged).

Root-cause clusters fixed

  • A. Stale error-envelope assertions (~39): tests asserted legacy "FORBIDDEN"/"NOT_FOUND" bodies; the app correctly returns RFC7807 with errorCode BILKO-AUTH-003/BILKO-INV-001. Tests updated to assert the strict error codes (stronger, not weaker).
  • B. Flyway init cascade (3 init suites): V30_1__ensure_bilko_admin_role.sql ran GRANT bilko_admin TO CURRENT_USER as bilko_admin → self-membership SQLSTATE 0LP01 on newer PG → migration abort. Fixed test-side (Testcontainers withUsernamebilko_test, a non-admin user). Production migration left immutable.
  • C1. PasswordReset SQL: SET LOCAL cannot take a subquery → resolve orgId via Exposed then pass the literal UUID.
  • C3. Expense semantics: self-approval / unknown-vendor exception types aligned with documented MC #102746 behavior.
  • Final 3 (this session):
    • VatReportStatutoryGroupingTest init error — invoice_items seed omitted NOT-NULL line_number → added it to 5 inserts.
    • HrFullPathE2ETest T1 + ImpersonationSessionIntegrationTest T8 (same cause) — ArchiveService.triggerBackgroundBuild fire-and-forget coroutine wrote completed_at to an already-closed Hikari pool → uncaught ExposedSQLException leaked into unrelated tests. Fixed: catch ExposedSQLException/SQLException-on-closed-pool and log (graceful degrade), rethrow CancellationException. Production-correct hardening.

Assertion-strength (anti-gate-gaming)

Two tests had been widened to multi-code accept lists; re-pinned to single deterministic codes:

  • InvoiceRoutes TS-INV-01 → exactly 503 MARKET_NOT_AVAILABLE (RS org deterministic).
  • BankingRoutes non-existent accountId → exactly 201 (auto-provisions Asset GL). No @Disabled/@Ignore/excludeTags/deleted tests. Flyway migrations untouched.

Verification

  • John forced fresh run: ./gradlew cleanIntegrationTest integrationTest --rerun-tasks --no-daemon:integrationTest executed, BUILD SUCCESSFUL 2m31s. XML aggregate 1213 / 0 / 0 / 0.
  • Independent pre-verifier (Company Mesh / Proveo): PASSmesh-thr-5947b05c-a6c5-4b3b-9ac8-37d7e6a7ea2c.
  • til-done: DONE/tmp/til-done/102874-20260603T193125Z.json.
  • PR #246: 36 source files, 0 build artifacts; origin/main untouched.

Process note

Multi-session: one session produced the WIP fix (~76 failures), a John review session affirmed it ("NOT gate-gaming") and flagged 3 items, this session ran the decisive green run, fixed the last 3 + the 2 flags, and closed. Earlier in the campaign a build agent accidentally pushed to main (reverted) — lesson recorded; this PR was pushed cleanly with explicit refspec, main untouched.

Downstream (NOT part of this fix)

  1. Merge PR #246 → main green.
  2. Then flip the CI gate (MC #102843): remove continue-on-error + add integration-test to build needs:. Cannot flip before merge (main is still red until then).