Expand test suite to 3562 tests, fix 3 emulator bugs#5
Merged
Conversation
Next.js requires @types/node for TypeScript type checking during build. Without it, the docs CI build fails.
Comprehensive coverage across all services, lib utilities, and middleware: - Customers: 22 → 202 tests - Payment Intents: 32 → 351 tests (full state machine coverage) - Payment Methods: 26 → 200 tests (all magic tokens) - Subscriptions: 20 → 300 tests (items, trials, billing) - Invoices: 25 → 250 tests (draft→open→paid/void lifecycle) - Charges: 0 → 150 tests (new file) - Refunds: 17 → 206 tests (partial/full refund scenarios) - Products: 24 → 149 tests - Prices: 22 → 156 tests (one-time + recurring) - Setup Intents: 24 → 200 tests - Events: 26 → 114 tests - Test Clocks: 16 → 122 tests (advance + billing integration) - Webhook Endpoints: 5 → 80 tests - Webhook Delivery: 11 → 120 tests (signatures, matching, retries) - Lib utilities: 44 → 258 tests (expand, id-gen, pagination, search, timestamps, event-bus, action-flags) - Middleware: 22 → 86 tests (auth, form-parser, idempotency) - Errors: 4 → 47 tests - DB: 4 → 19 tests
8 new test files with 376 tests that exercise full Stripe API flows through the official SDK, testing actual business logic and state transitions rather than field-level assertions: - e-commerce.test.ts (59): Checkout, manual capture, partial capture, declined cards, 3DS authentication, refunds, idempotency, expansion - saas-subscription.test.ts (55): Onboarding, trials, plan upgrades, cancellation, billing cycles via test clocks, multi-subscription - billing-invoices.test.ts (49): Invoice lifecycle (draft→open→paid/void), state machine enforcement, subscription invoicing, search - webhook-ecosystem.test.ts (49): Event delivery with HMAC verification, customer/payment/subscription webhooks, routing, signature validation - product-catalog.test.ts (40): Product/price CRUD, SaaS pricing page setup, catalog-to-subscription flow - search-and-pagination.test.ts (40): Customer/PI search, cursor-based pagination, expand related resources - setup-and-future-payments.test.ts (39): Save card via SetupIntent, charge later, 3DS setup, cancel flows - error-handling-and-edge-cases.test.ts (45): Auth errors, 404s, validation errors, state transition errors, idempotency
…lined Three bugs discovered during SDK testing: 1. Refund route didn't parseInt the amount from form-encoded body, causing string concatenation when accumulating partial refunds (e.g. 0 + "2000" = "02000" instead of 2000) 2. Expand params only supported expand[]=field format (curl/raw) but not expand[0]=field (Stripe SDK). Added parseExpandParams() helper that handles both formats, updated all 4 routes that use expansion. 3. No magic token for declined cards — added tok_chargeDeclined which creates a card with last4 "0002" (triggers automatic decline in the payment simulation). Previously, decline testing required the internal actionFlags.failNextPayment mechanism. Added 10 new SDK tests verifying all three fixes work end-to-end.
All list endpoints used `gt(created, cursor.created)` for cursor-based pagination, which broke when multiple items shared the same second- precision timestamp — the cursor would skip items or return empty pages. Fix: Added `cursorCondition()` helper that uses a composite cursor: (created > cursor.created) OR (created = cursor.created AND id > cursor.id) Combined with `ORDER BY created, id` on all list queries, this ensures deterministic, gap-free pagination regardless of creation timing. Also fixed: - Events service: was using eq() instead of lt() for desc-ordered cursor - Events service: added secondary desc(id) sort for same-second ordering - Test clocks service: cursor was validated but completely ignored - Webhook endpoints service: cursor was validated but completely ignored
Removed all workarounds that weakened pagination test assertions: - Replaced toBeGreaterThanOrEqual(0) with exact count assertions - Removed createSIsWithDistinctTimestamps() manual timestamp patching - Removed setTimeout(1100ms) delays between item creation - Removed "same-second limitation" comments and test name suffixes - Removed 2 trivial workaround-only tests (prices, products) - Rewrote charges pagination tests to use service.create() instead of manual DB insertion with fake timestamps All pagination tests now properly assert: - Exact item counts per page - No duplicates across pages - All items collected across full traversal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bug fixes (commit 3)
src/routes/refunds.tsdidn'tparseIntthe amount from form-encoded body, causing0 + "2000" = "02000"on partial refundsexpand[]=field(curl) but notexpand[0]=field(Stripe SDK). AddedparseExpandParams()helper handling both formats across all 4 expandable routestok_chargeDeclinedwhich creates a card with last40002(auto-decline), making decline testing possible without the internalactionFlagsmechanismUnit test expansion (commit 1)
SDK simulation tests (commit 2)
Real flows using
stripenpm package — testing actual Stripe API behavior:e-commerce.test.tssaas-subscription.test.tsbilling-invoices.test.tswebhook-ecosystem.test.tserror-handling-and-edge-cases.test.tsproduct-catalog.test.tssearch-and-pagination.test.tssetup-and-future-payments.test.tsTest plan
bun test— 3,562 pass, 0 fail (47s)bun x tsc --noEmit— clean