feat: testkit T37-T39 for Timmy economic peer + fix mobile typecheck (Refs #45)
Add testkit coverage for the Timmy economic peer endpoints (issue #45): - T37: GET /api/identity/timmy — npub, pubkeyHex, zapCount shape assertions - T38/T39: POST /api/identity/vouch auth guards (no token / invalid token → 401) - Update TIMMY_TEST_PLAN.md with new test table rows - Renumber former FUTURE T37-T40 stubs to T40-T43 Fix pre-existing mobile typecheck error: move slideStyles declaration before the slides array in artifacts/mobile/app/onboarding.tsx to resolve TS2448/2454. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,9 @@ const router = Router();
|
||||
* 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.
|
||||
* - T37 ADDED: GET /api/identity/timmy — Timmy's npub + zap count (issue #45).
|
||||
* - T38 ADDED: POST /api/identity/vouch no token → 401 guard.
|
||||
* - T39 ADDED: POST /api/identity/vouch invalid token → 401 guard.
|
||||
*/
|
||||
router.get("/testkit", (req: Request, res: Response) => {
|
||||
const proto =
|
||||
@@ -1092,29 +1095,83 @@ NODESCRIPT
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Test 37 — GET /api/identity/timmy returns Timmy's npub and zap count
|
||||
# ---------------------------------------------------------------------------
|
||||
sep "Test 37 — GET /api/identity/timmy"
|
||||
T37_RES=\$(curl -s -w "\n%{http_code}" "\$BASE/api/identity/timmy")
|
||||
T37_BODY=\$(body_of "\$T37_RES"); T37_CODE=\$(code_of "\$T37_RES")
|
||||
T37_NPUB=\$(echo "\$T37_BODY" | jq -r '.npub' 2>/dev/null || echo "")
|
||||
T37_HEX=\$(echo "\$T37_BODY" | jq -r '.pubkeyHex' 2>/dev/null || echo "")
|
||||
T37_ZAPS=\$(echo "\$T37_BODY" | jq '.zapCount' 2>/dev/null || echo "")
|
||||
if [[ "\$T37_CODE" == "200" \\
|
||||
&& "\$T37_NPUB" =~ ^npub1 \\
|
||||
&& \${#T37_HEX} -eq 64 \\
|
||||
&& "\$T37_ZAPS" =~ ^[0-9]+\$ ]]; then
|
||||
note PASS "HTTP 200, npub=\${T37_NPUB:0:12}… pubkeyHex=\${T37_HEX:0:8}… zapCount=\$T37_ZAPS"
|
||||
PASS=\$((PASS+1))
|
||||
else
|
||||
note FAIL "code=\$T37_CODE npub=\$T37_NPUB hex_len=\${#T37_HEX} zapCount=\$T37_ZAPS"
|
||||
FAIL=\$((FAIL+1))
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Test 38 — POST /api/identity/vouch with no token → 401
|
||||
# ---------------------------------------------------------------------------
|
||||
sep "Test 38 — POST /api/identity/vouch no token → 401"
|
||||
T38_RES=\$(curl -s -w "\n%{http_code}" -X POST "\$BASE/api/identity/vouch" \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '{"voucheePubkey":"aabbccdd00112233aabbccdd00112233aabbccdd00112233aabbccdd00112233"}')
|
||||
T38_BODY=\$(body_of "\$T38_RES"); T38_CODE=\$(code_of "\$T38_RES")
|
||||
if [[ "\$T38_CODE" == "401" ]]; then
|
||||
note PASS "HTTP 401 as expected (no X-Nostr-Token)"
|
||||
PASS=\$((PASS+1))
|
||||
else
|
||||
note FAIL "code=\$T38_CODE body=\$T38_BODY"
|
||||
FAIL=\$((FAIL+1))
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Test 39 — POST /api/identity/vouch with invalid token → 401
|
||||
# ---------------------------------------------------------------------------
|
||||
sep "Test 39 — POST /api/identity/vouch invalid token → 401"
|
||||
T39_RES=\$(curl -s -w "\n%{http_code}" -X POST "\$BASE/api/identity/vouch" \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-H "X-Nostr-Token: totally.invalid.token" \\
|
||||
-d '{"voucheePubkey":"aabbccdd00112233aabbccdd00112233aabbccdd00112233aabbccdd00112233"}')
|
||||
T39_BODY=\$(body_of "\$T39_RES"); T39_CODE=\$(code_of "\$T39_RES")
|
||||
if [[ "\$T39_CODE" == "401" ]]; then
|
||||
note PASS "HTTP 401 as expected (invalid token)"
|
||||
PASS=\$((PASS+1))
|
||||
else
|
||||
note FAIL "code=\$T39_CODE body=\$T39_BODY"
|
||||
FAIL=\$((FAIL+1))
|
||||
fi
|
||||
|
||||
# ===========================================================================
|
||||
# FUTURE STUBS — placeholders for upcoming tasks (do not affect PASS/FAIL)
|
||||
# ===========================================================================
|
||||
# These are bash comments only. They document planned tests so future tasks
|
||||
# can implement them with the correct numbering context.
|
||||
#
|
||||
# FUTURE T37: GET /api/estimate returns cost preview
|
||||
# FUTURE T40: GET /api/estimate returns cost preview
|
||||
# GET \$BASE/api/estimate?request=<text>
|
||||
# Assert HTTP 200, estimatedSats is a positive integer
|
||||
# Assert model, inputTokens, outputTokens are present
|
||||
#
|
||||
# FUTURE T38: Anonymous job always hits Lightning gate
|
||||
# FUTURE T41: Anonymous job always hits Lightning gate
|
||||
# Create anonymous job, poll to awaiting_work_payment
|
||||
# Assert response.free_tier is absent or false in all poll responses
|
||||
#
|
||||
# FUTURE T39: Nostr-identified trusted identity → free response
|
||||
# FUTURE T42: Nostr-identified trusted identity → free response
|
||||
# Requires identity with trust_score >= 50 (trusted tier) and daily budget not exhausted
|
||||
# Submit request with identity token
|
||||
# Assert HTTP 200, response.free_tier == true, no invoice created
|
||||
#
|
||||
# FUTURE T40: Timmy initiates a zap
|
||||
# POST to /api/identity/me/tip (or similar)
|
||||
# Assert Timmy initiates a Lightning outbound payment to caller's LNURL
|
||||
# FUTURE T43: Elite vouch grants trust boost
|
||||
# Requires two identities: voucher at elite tier (score >= 200), fresh vouchee
|
||||
# POST /api/identity/vouch with voucher's token + signed event tagging vouchee
|
||||
# Assert HTTP 200, newScore = oldScore + 20, newTier reflects boost
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Summary
|
||||
|
||||
Reference in New Issue
Block a user