
> vibe-to-production-academy@1.0.0 test
> node scripts/test-api.mjs


 ⛅️ wrangler 4.130.0
────────────────────
Resource location: local 

Use --remote if you want to access the remote instance.

Migrations to be applied:
┌─────────────────────────┐
│ name                    │
├─────────────────────────┤
│ 0001_initial.sql        │
├─────────────────────────┤
│ 0002_demo_retention.sql │
└─────────────────────────┘
? About to apply 2 migration(s)
Your database may not be available to serve requests during the migration, continue?
🤖 Using fallback value in non-interactive context: yes
🌀 Executing on local database DB (44e091c6-2c5f-4cf1-b94d-136fd164be7d) from .wrangler/test-api-of3WWV/v3/d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.
🚣 21 commands executed successfully.
┌─────────────────────────┬────────┐
│ name                    │ status │
├─────────────────────────┼────────┤
│ 0001_initial.sql        │ ✅     │
├─────────────────────────┼────────┤
│ 0002_demo_retention.sql │ 🕒️    │
└─────────────────────────┴────────┘
🌀 Executing on local database DB (44e091c6-2c5f-4cf1-b94d-136fd164be7d) from .wrangler/test-api-of3WWV/v3/d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.
🚣 24 commands executed successfully.
┌─────────────────────────┬────────┐
│ name                    │ status │
├─────────────────────────┼────────┤
│ 0001_initial.sql        │ ✅     │
├─────────────────────────┼────────┤
│ 0002_demo_retention.sql │ ✅     │
└─────────────────────────┴────────┘

 ⛅️ wrangler 4.130.0
────────────────────
Resource location: local 

Use --remote if you want to access the remote instance.

🌀 Executing on local database DB (44e091c6-2c5f-4cf1-b94d-136fd164be7d) from .wrangler/test-api-of3WWV/v3/d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.
🚣 10 commands executed successfully.
[
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 2
    }
  },
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 0
    }
  },
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 0
    }
  },
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 0
    }
  },
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 2
    }
  },
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 1
    }
  },
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 1
    }
  },
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 0
    }
  },
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 1
    }
  },
  {
    "results": [],
    "success": true,
    "meta": {
      "duration": 0
    }
  }
]

 ⛅️ wrangler 4.130.0
────────────────────
Using secrets defined in .wrangler/test-api-of3WWV/test.env
Your Worker has access to the following bindings:
Binding                                       Resource                  Mode
env.DB (vibe-academy-db)                      D1 Database               local
env.ASSETS                                    Assets                    local
env.DEMO_MODE ("(hidden)")                    Environment Variable      local
env.TURNSTILE_HOSTNAME ("")                   Environment Variable      local
env.DEMO_HMAC_KEY ("(hidden)")                Environment Variable      local

⎔ Starting local server...
[wrangler:info] ✨ Parsed 4 valid header rules.
[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mScheduled Workers are not automatically triggered during local development.[0m

  To manually trigger a scheduled event, run:
    curl "http://127.0.0.1:3321/cdn-cgi/local/scheduled"
  For more details, see [4mhttps://developers.cloudflare.com/workers/configuration/cron-triggers/#test-cron-triggers-locally[0m


Wrangler detected this dev session is running in an AI agent.
The Local Explorer API is available at http://127.0.0.1:3321/cdn-cgi/local/explorer/api
Useful routes:
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/local/workers - local Workers and bindings
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/storage/kv/namespaces - KV namespaces
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/d1/database - D1 databases
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/r2/buckets - R2 buckets
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/workers/durable_objects/namespaces - Durable Object namespaces
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/workflows - Workflows
  POST http://127.0.0.1:3321/cdn-cgi/local/explorer/api/local/observability/query - run a read-only SQL query (SELECT/WITH only) over captured request traces and console logs. Tables: spans, logs (read attributes via json(attributes)). Example:
    curl -X POST http://127.0.0.1:3321/cdn-cgi/local/explorer/api/local/observability/query -H 'Content-Type: application/json' -d '{"sql":"SELECT service, name, outcome, duration_ms FROM spans WHERE parent_id IS NULL LIMIT 20"}'
If the routes above don't cover what you need, fetch the full OpenAPI schema (large - use only as a last resort):
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api - OpenAPI schema
[wrangler:info] Ready on http://127.0.0.1:3321
[wrangler:info] GET /api/health 200 OK (1204ms)
[wrangler:info] GET /api/health 200 OK (72ms)
[wrangler:info] POST /api/contact 201 Created (66ms)
[wrangler:info] POST /api/contact 201 Created (39ms)
TAP version 13
[wrangler:info] GET /api/health 200 OK (18ms)
[wrangler:info] GET /api/catalog 200 OK (23ms)
# Subtest: catalog exposes the D1-backed integer-satang catalog
ok 1 - catalog exposes the D1-backed integer-satang catalog
  ---
  duration_ms: 90.259597
  type: 'test'
  ...
[wrangler:info] GET /api/availability 200 OK (27ms)
[wrangler:info] GET /api/availability 400 Bad Request (17ms)
[wrangler:info] GET /api/availability 400 Bad Request (18ms)
[wrangler:info] GET /api/availability 400 Bad Request (15ms)
[wrangler:info] GET /api/availability 400 Bad Request (19ms)
# Subtest: availability validates real dates, duration, quantity, and unknown parameters
ok 2 - availability validates real dates, duration, quantity, and unknown parameters
  ---
  duration_ms: 119.985841
  type: 'test'
  ...
[wrangler:info] POST /api/rentals 201 Created (41ms)
[wrangler:info] POST /api/rentals 201 Created (41ms)
[wrangler:info] POST /api/rentals 409 Conflict (39ms)
# Subtest: adjacent rentals are allowed while a true overlap is rejected
ok 3 - adjacent rentals are allowed while a true overlap is rejected
  ---
  duration_ms: 158.377662
  type: 'test'
  ...
[wrangler:info] POST /api/rentals 201 Created (34ms)
[wrangler:info] POST /api/rentals 409 Conflict (107ms)
[wrangler:info] POST /api/rentals 201 Created (109ms)
[wrangler:info] GET /api/availability 200 OK (27ms)
# Subtest: concurrent reservations cannot oversell D1 capacity
ok 4 - concurrent reservations cannot oversell D1 capacity
  ---
  duration_ms: 156.035659
  type: 'test'
  ...
[wrangler:info] POST /api/rentals 400 Bad Request (18ms)
# Subtest: rental pricing ignores client claims by rejecting unknown price fields
ok 5 - rental pricing ignores client claims by rejecting unknown price fields
  ---
  duration_ms: 25.426041
  type: 'test'
  ...
[wrangler:info] POST /api/quotes 201 Created (83ms)
[wrangler:info] POST /api/quotes 400 Bad Request (23ms)
# Subtest: quote totals use the server catalog and reject price injection
ok 6 - quote totals use the server catalog and reject price injection
  ---
  duration_ms: 120.970494
  type: 'test'
  ...
[wrangler:info] POST /api/contact 403 Forbidden (13ms)
[wrangler:info] POST /api/contact 415 Unsupported Media Type (13ms)
[wrangler:info] POST /api/contact 400 Bad Request (14ms)
[wrangler:info] POST /api/contact 400 Bad Request (14ms)
[wrangler:info] POST /api/contact 201 Created (29ms)
# Subtest: POST requires JSON, exact same origin, consent, and an empty honeypot
ok 7 - POST requires JSON, exact same origin, consent, and an empty honeypot
  ---
  duration_ms: 111.050424
  type: 'test'
  ...
[wrangler:info] POST /api/rentals 201 Created (40ms)
[wrangler:info] POST /api/rentals 201 Created (41ms)
[wrangler:info] POST /api/rentals 409 Conflict (38ms)
# Subtest: Idempotency-Key replays identical POSTs and rejects changed payloads
ok 8 - Idempotency-Key replays identical POSTs and rejects changed payloads
  ---
  duration_ms: 142.44527
  type: 'test'
  ...
[wrangler:info] POST /api/rentals 201 Created (36ms)
[wrangler:info] POST /api/rentals 201 Created (101ms)
[wrangler:info] POST /api/rentals 201 Created (102ms)
# Subtest: concurrent identical Idempotency-Key requests create one rental and replay one response
ok 9 - concurrent identical Idempotency-Key requests create one rental and replay one response
  ---
  duration_ms: 118.28429
  type: 'test'
  ...
[wrangler:info] POST /api/rentals 201 Created (34ms)
[wrangler:info] POST /api/rentals 201 Created (29ms)
[wrangler:info] POST /api/rentals 201 Created (36ms)
[wrangler:info] POST /api/rentals 201 Created (22ms)
[wrangler:info] POST /api/rentals 429 Too Many Requests (21ms)
# Subtest: the per-client daily rental cap rejects excess demo submissions
ok 10 - the per-client daily rental cap rejects excess demo submissions
  ---
  duration_ms: 175.091458
  type: 'test'
  ...
[wrangler:info] GET /api/private-data 404 Not Found (11ms)
# Subtest: unknown API routes return structured 404 responses
ok 11 - unknown API routes return structured 404 responses
  ---
  duration_ms: 17.971182
  type: 'test'
  ...
[wrangler:info] POST /api/contact 413 Payload Too Large (16ms)
# Subtest: streamed request bodies over 16 KB are rejected
ok 12 - streamed request bodies over 16 KB are rejected
  ---
  duration_ms: 29.444296
  type: 'test'
  ...
1..12
# tests 12
# suites 0
# pass 12
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 1532.86885

 ⛅️ wrangler 4.130.0
────────────────────
Using secrets defined in .wrangler/test-api-of3WWV/test.env
Your Worker has access to the following bindings:
Binding                                       Resource                  Mode
env.DB (vibe-academy-db)                      D1 Database               local
env.ASSETS                                    Assets                    local
env.DEMO_MODE ("(hidden)")                    Environment Variable      local
env.TURNSTILE_HOSTNAME ("")                   Environment Variable      local
env.DEMO_HMAC_KEY ("(hidden)")                Environment Variable      local

⎔ Starting local server...
[wrangler:info] ✨ Parsed 4 valid header rules.
[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mScheduled Workers are not automatically triggered during local development.[0m

  To manually trigger a scheduled event, run:
    curl "http://127.0.0.1:3321/cdn-cgi/local/scheduled"
  For more details, see [4mhttps://developers.cloudflare.com/workers/configuration/cron-triggers/#test-cron-triggers-locally[0m


Wrangler detected this dev session is running in an AI agent.
The Local Explorer API is available at http://127.0.0.1:3321/cdn-cgi/local/explorer/api
Useful routes:
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/local/workers - local Workers and bindings
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/storage/kv/namespaces - KV namespaces
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/d1/database - D1 databases
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/r2/buckets - R2 buckets
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/workers/durable_objects/namespaces - Durable Object namespaces
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api/workflows - Workflows
  POST http://127.0.0.1:3321/cdn-cgi/local/explorer/api/local/observability/query - run a read-only SQL query (SELECT/WITH only) over captured request traces and console logs. Tables: spans, logs (read attributes via json(attributes)). Example:
    curl -X POST http://127.0.0.1:3321/cdn-cgi/local/explorer/api/local/observability/query -H 'Content-Type: application/json' -d '{"sql":"SELECT service, name, outcome, duration_ms FROM spans WHERE parent_id IS NULL LIMIT 20"}'
If the routes above don't cover what you need, fetch the full OpenAPI schema (large - use only as a last resort):
  GET http://127.0.0.1:3321/cdn-cgi/local/explorer/api - OpenAPI schema
[wrangler:info] Ready on http://127.0.0.1:3321
[wrangler:info] GET /api/health 200 OK (719ms)
[wrangler:info] POST /api/contact 201 Created (53ms)
API database audit passed: {"expired_rows":0,"pii_rows":0,"bad_hashes":0,"bad_ttls":0,"concurrent_keys":1,"concurrent_rentals":1,"reclaimed_pending":1,"preserved_completed":1}
