Context
Two gaps in billing test coverage worth filling.
1. Unit tests for syncStripeSubscription
New command at packages/workers/src/commands/billing/syncStripeSubscription.ts
has real branching that should be locked down. Add
packages/workers/src/commands/billing/__tests__/syncStripeSubscription.test.ts
covering:
- Stripe returns no subs, no existing DB row → returns
{status: 'none'}, no write
- Stripe returns no subs, existing active row → row marked
canceled with endedAt
- Stripe returns no subs, existing already-canceled row → no-op (idempotent)
- Stripe returns a sub, existing row → row updated with canonical Stripe state
- Stripe returns a sub, no existing row, metadata has
orgId → new row inserted
- Stripe returns a sub, no existing row, no
orgId → returns without writing
Pattern is already established in packages/workers/src/routes/billing/__tests__/.
Stripe is globally mocked in test setup; D1 seeded via resetTestDatabase.
Estimate: ~30 min.
2. Stand up test setup for packages/stripe-purchases
The stripe-purchases worker (handles checkout.session.completed →
orgAccessGrants) has zero test coverage. The duplicate billing webhook
tree in packages/workers previously carried 5 test files that exercised the
main-worker copy — but that copy was dead in prod, and it has since been
removed.
Tasks:
- Add vitest +
@cloudflare/vitest-pool-workers config to packages/stripe-purchases
- Port the deleted tests and adapt them to the live code paths there:
processCheckoutSession (grant creation, grant extension, idempotency via
stripeCheckoutSessionId unique constraint)
- Customer handlers (
customer.updated, customer.deleted)
- Invoice handlers (dunning flow)
- Payment intent handlers
- Two-phase ledger trust model (signature verification, dedupe by
payload hash + event ID)
Estimate: 2–3 hours.
Out of scope
- Route-level test for
POST /sync-after-success — thin plumbing
- Frontend
useEffect test — low value, covered by existing
billing-flow.spec.ts e2e
Context
Two gaps in billing test coverage worth filling.
1. Unit tests for
syncStripeSubscriptionNew command at
packages/workers/src/commands/billing/syncStripeSubscription.tshas real branching that should be locked down. Add
packages/workers/src/commands/billing/__tests__/syncStripeSubscription.test.tscovering:
{status: 'none'}, no writecanceledwithendedAtorgId→ new row insertedorgId→ returns without writingPattern is already established in
packages/workers/src/routes/billing/__tests__/.Stripe is globally mocked in test setup; D1 seeded via
resetTestDatabase.Estimate: ~30 min.
2. Stand up test setup for
packages/stripe-purchasesThe
stripe-purchasesworker (handlescheckout.session.completed→orgAccessGrants) has zero test coverage. The duplicate billing webhooktree in
packages/workerspreviously carried 5 test files that exercised themain-worker copy — but that copy was dead in prod, and it has since been
removed.
Tasks:
@cloudflare/vitest-pool-workersconfig topackages/stripe-purchasesprocessCheckoutSession(grant creation, grant extension, idempotency viastripeCheckoutSessionIdunique constraint)customer.updated,customer.deleted)payload hash + event ID)
Estimate: 2–3 hours.
Out of scope
POST /sync-after-success— thin plumbinguseEffecttest — low value, covered by existingbilling-flow.spec.tse2e