task(#24): Bootstrap route + cost-ledger testkit coverage — 29/29 PASS

Task: Add T23 (bootstrap stub flow) and T24 (cost-ledger completeness) to the
testkit, bringing total from 27/27 to 29/29 PASS with 0 FAIL, 0 SKIP.

## What was changed
- `artifacts/api-server/src/routes/testkit.ts`:
  - Updated audit-log comment block to document T23 + T24 additions.
  - Inserted Test 23 after T22 (line ~654):
      POST /api/bootstrap → assert 201 + bootstrapJobId present.
      Guard on stubMode=true; SKIP if real DO mode (prevents hanging).
      Stub-pay the paymentHash via /api/dev/stub/pay/:hash.
      Poll GET /api/bootstrap/:id every 2s (20s timeout) until
      state=provisioning or state=ready; assert message field present.
  - Inserted Test 24 after T23:
      Guarded on STATE_T6=complete (reuses completed job from T6).
      GET /api/jobs/:id, extract costLedger.
      Assert all 8 fields non-null: actualInputTokens, actualOutputTokens,
        totalTokens, actualCostUsd, actualAmountSats, workAmountSats,
        refundAmountSats, refundState.
      Honest-accounting invariant: actualAmountSats <= workAmountSats.
      refundAmountSats >= 0.
      refundState must match ^(not_applicable|pending|paid)$.

## No deviations from task spec
- T23 guard logic matches spec exactly (stubMode check before poll).
- T24 fields match the 8 specified in task-24.md plus the invariants.
- No changes to bootstrap.ts or jobs.ts — existing routes already correct.

## Test run result
29/29 PASS, 0 FAIL, 0 SKIP (fresh server restart, rate-limit slots clean).
T23: state=provisioning in 1s. T24: actualAmountSats(179)<=workAmountSats(182),
refundAmountSats=3, refundState=pending.
This commit is contained in:
alexpaynex
2026-03-19 04:04:49 +00:00
parent 00d3233db3
commit 031ca5a5c3

View File

@@ -23,6 +23,10 @@ const router = Router();
* - T20 ADDED: POST /api/jobs/:id/refund guards — financial endpoint, zero prior coverage.
* - T21 ADDED: GET /api/jobs/:id/stream SSE replay on completed job — never tested.
* - T22 ADDED: GET /api/sessions/:id unknown ID → 404 — never tested.
* - T23 ADDED: POST /api/bootstrap stub flow — highest-value endpoint, zero prior coverage.
* Guarded on stubMode=true; polls until state=provisioning|ready (20 s timeout).
* - T24 ADDED: costLedger completeness after job completion — 8 fields, honest-accounting
* invariant (actualAmountSats ≤ workAmountSats), refundState enum check.
*/
router.get("/testkit", (req: Request, res: Response) => {
const proto =
@@ -644,6 +648,97 @@ else
FAIL=\$((FAIL+1))
fi
# ---------------------------------------------------------------------------
# Test 23 — Bootstrap: create → stub-pay → poll provisioning state
# Highest-value paid feature (10,000 sats default) — previously zero coverage.
# Guarded on stubMode=true: real DO provisioning requires DO_API_TOKEN (out of scope).
# Polls GET /api/bootstrap/:id until state=provisioning or state=ready (20 s timeout).
# ---------------------------------------------------------------------------
sep "Test 23 — Bootstrap: create + stub-pay + poll provisioning"
T23_RES=\$(curl -s -w "\\n%{http_code}" -X POST "\$BASE/api/bootstrap" \\
-H "Content-Type: application/json")
T23_BODY=\$(body_of "\$T23_RES"); T23_CODE=\$(code_of "\$T23_RES")
BOOTSTRAP_ID=\$(echo "\$T23_BODY" | jq -r '.bootstrapJobId' 2>/dev/null || echo "")
T23_STUB=\$(echo "\$T23_BODY" | jq -r '.stubMode' 2>/dev/null || echo "false")
BOOTSTRAP_HASH=\$(echo "\$T23_BODY" | jq -r '.invoice.paymentHash' 2>/dev/null || echo "")
if [[ "\$T23_CODE" != "201" || -z "\$BOOTSTRAP_ID" || "\$BOOTSTRAP_ID" == "null" ]]; then
note FAIL "Bootstrap create failed: code=\$T23_CODE body=\$T23_BODY"
FAIL=\$((FAIL+1))
elif [[ "\$T23_STUB" != "true" ]]; then
note SKIP "stubMode=false — skipping (requires DO_API_TOKEN for real provisioning)"
SKIP=\$((SKIP+1))
else
if [[ -n "\$BOOTSTRAP_HASH" && "\$BOOTSTRAP_HASH" != "null" ]]; then
curl -s -X POST "\$BASE/api/dev/stub/pay/\$BOOTSTRAP_HASH" >/dev/null
fi
START_T23=\$(date +%s); T23_TIMEOUT=20
T23_STATE=""; T23_MSG=""; T23_POLL_CODE=""
while :; do
T23_POLL=\$(curl -s -w "\\n%{http_code}" "\$BASE/api/bootstrap/\$BOOTSTRAP_ID")
T23_POLL_BODY=\$(body_of "\$T23_POLL"); T23_POLL_CODE=\$(code_of "\$T23_POLL")
T23_STATE=\$(echo "\$T23_POLL_BODY" | jq -r '.state' 2>/dev/null || echo "")
T23_MSG=\$(echo "\$T23_POLL_BODY" | jq -r '.message' 2>/dev/null || echo "")
NOW_T23=\$(date +%s); ELAPSED_T23=\$((NOW_T23 - START_T23))
if [[ "\$T23_STATE" == "provisioning" || "\$T23_STATE" == "ready" ]]; then break; fi
if (( ELAPSED_T23 > T23_TIMEOUT )); then break; fi
sleep 2
done
if [[ "\$T23_POLL_CODE" == "200" \\
&& ("\$T23_STATE" == "provisioning" || "\$T23_STATE" == "ready") \\
&& -n "\$T23_MSG" && "\$T23_MSG" != "null" ]]; then
note PASS "state=\$T23_STATE in \$ELAPSED_T23 s, message present, bootstrapJobId=\$BOOTSTRAP_ID"
PASS=\$((PASS+1))
else
note FAIL "code=\$T23_POLL_CODE state=\$T23_STATE elapsed=\${ELAPSED_T23}s body=\$T23_POLL_BODY"
FAIL=\$((FAIL+1))
fi
fi
# ---------------------------------------------------------------------------
# Test 24 — Cost ledger completeness after job completion
# Uses the completed JOB_ID from T6 (guarded on STATE_T6=complete).
# Verifies 8 cost-ledger fields are non-null:
# actualInputTokens, actualOutputTokens, totalTokens, actualCostUsd,
# actualAmountSats, workAmountSats, refundAmountSats, refundState.
# Honest-accounting invariant: actualAmountSats <= workAmountSats.
# refundState must be one of: not_applicable | pending | paid.
# ---------------------------------------------------------------------------
sep "Test 24 — Cost ledger completeness (job completed)"
if [[ -n "\$JOB_ID" && "\$STATE_T6" == "complete" ]]; then
T24_RES=\$(curl -s -w "\\n%{http_code}" "\$BASE/api/jobs/\$JOB_ID")
T24_BODY=\$(body_of "\$T24_RES"); T24_CODE=\$(code_of "\$T24_RES")
T24_LEDGER=\$(echo "\$T24_BODY" | jq '.costLedger' 2>/dev/null || echo "null")
T24_REFUND_STATE=\$(echo "\$T24_LEDGER" | jq -r '.refundState' 2>/dev/null || echo "")
T24_FIELDS_OK=true
for field in actualInputTokens actualOutputTokens totalTokens actualCostUsd actualAmountSats workAmountSats refundAmountSats refundState; do
VAL=\$(echo "\$T24_LEDGER" | jq -r ".\$field" 2>/dev/null || echo "MISSING")
[[ -z "\$VAL" || "\$VAL" == "null" ]] && T24_FIELDS_OK=false || true
done
T24_INV_OK=\$(echo "\$T24_LEDGER" | jq '
(.actualAmountSats != null) and
(.workAmountSats != null) and
(.actualAmountSats <= .workAmountSats) and
(.refundAmountSats >= 0)
' 2>/dev/null || echo "false")
if [[ "\$T24_CODE" == "200" \\
&& "\$T24_LEDGER" != "null" \\
&& "\$T24_FIELDS_OK" == "true" \\
&& "\$T24_INV_OK" == "true" \\
&& "\$T24_REFUND_STATE" =~ ^(not_applicable|pending|paid)\$ ]]; then
T24_ACTUAL=\$(echo "\$T24_LEDGER" | jq -r '.actualAmountSats' 2>/dev/null || echo "?")
T24_WORK=\$(echo "\$T24_LEDGER" | jq -r '.workAmountSats' 2>/dev/null || echo "?")
T24_REFUND=\$(echo "\$T24_LEDGER" | jq -r '.refundAmountSats' 2>/dev/null || echo "?")
note PASS "8 fields non-null, actualAmountSats(\$T24_ACTUAL)<=workAmountSats(\$T24_WORK), refundAmountSats=\$T24_REFUND, refundState=\$T24_REFUND_STATE"
PASS=\$((PASS+1))
else
note FAIL "code=\$T24_CODE ledger=\$T24_LEDGER fields_ok=\$T24_FIELDS_OK inv_ok=\$T24_INV_OK refundState=\$T24_REFUND_STATE"
FAIL=\$((FAIL+1))
fi
else
note SKIP "Skipping — job not complete (STATE_T6=\${STATE_T6:-not_set}) or no JOB_ID"
SKIP=\$((SKIP+1))
fi
# ---------------------------------------------------------------------------
# Summary
# ---------------------------------------------------------------------------