Added e2e Stripe checkout initiation support - #26875
Conversation
ref #26810 This adds the fake Stripe product, price, customer, and checkout-session surface needed to start migrating paid signup browser coverage into e2e.
WalkthroughReworks E2E Stripe test tooling: introduces exported Stripe-like TypeScript types and refactors builder functions to return those types; adds composite helpers (StripeList, subscription/checkout session shapes); expands FakeStripeServer with in-memory storage, new product/price/checkout endpoints, parsing utilities, explicit error responses, and upsert/getter methods; exposes server getters via StripeTestService; extends TiersService with AdminTier and createTier; and adds a new E2E smoke test for Stripe checkout initiation. Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
e2e/tests/public/stripe-checkout-initiation.test.ts (1)
18-82: Split this into clearer Arrange / Act / Assert phases.The flow currently does
arrange -> assert -> act -> assert -> act -> assert, which makes failures harder to localize and doesn't match the ADR's "clear sections" requirement. Pulling the Stripe-sync checks fully into Arrange (or a helper) and keeping the checkout request/navigation in Act would make this easier to read and debug.As per coding guidelines, "Use the AAA Pattern (Arrange, Act, Assert) in E2E tests with clear sections".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@e2e/tests/public/stripe-checkout-initiation.test.ts` around lines 18 - 82, Split the test into clear Arrange / Act / Assert sections: in Arrange create the member and tier (using createMemberFactory and TiersService.createTier), wait for Stripe to sync (use stripe!.getProducts(), stripe!.getPrices(), stripe!.getCustomers(), stripe!.getCheckoutSessions() checks or extract them into a helper like ensureStripeSynced) and capture product/monthlyPrice/yearlyPrice variables; in Act perform the checkout session creation request (the page.request.post to /members/api/create-stripe-checkout-session/ and navigation to sessionResponse.url); in Assert move all expect(...) checks (product/monthlyPrice/yearlyPrice properties, response.ok(), sessionResponse contents, customer/session assertions, and page heading visibility) into the final Assert block so failures are isolated and the flow follows AAA.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@e2e/helpers/services/stripe/fake-stripe-server.ts`:
- Around line 157-171: The price-creation route builds a synthetic product id
when req.body.product is missing but never saves that product, causing later
/v1/products/:id lookups to 404; update the handler so when product is derived
from buildProduct() (i.e., parseString(req.body.product) returns null) you
create and persist that synthetic product via the existing buildProduct() and
upsertProduct(...) before calling upsertPrice(...). Use the same product id
assigned to buildPrice (reference parseString, buildProduct, buildPrice,
upsertProduct, upsertPrice) so the created price’s product exists in the fake
store.
In `@e2e/tests/public/stripe-checkout-initiation.test.ts`:
- Around line 14-17: Rename the test suite string and the individual test title
to follow E2E naming rules: change the suite name "Public - Stripe Checkout
Initiation" to "Ghost Public - Stripe Checkout Initiation" and rename the test
title from "paid tier syncs to fake Stripe and checkout returns a fake session
URL" to a lowercase "what is tested - expected outcome" form such as "paid tier
syncs to fake Stripe - checkout returns a fake session url"; update the strings
where test.describe(...) and test(...) are declared so all assertions and
test.use({stripeEnabled: true}) remain unchanged.
---
Nitpick comments:
In `@e2e/tests/public/stripe-checkout-initiation.test.ts`:
- Around line 18-82: Split the test into clear Arrange / Act / Assert sections:
in Arrange create the member and tier (using createMemberFactory and
TiersService.createTier), wait for Stripe to sync (use stripe!.getProducts(),
stripe!.getPrices(), stripe!.getCustomers(), stripe!.getCheckoutSessions()
checks or extract them into a helper like ensureStripeSynced) and capture
product/monthlyPrice/yearlyPrice variables; in Act perform the checkout session
creation request (the page.request.post to
/members/api/create-stripe-checkout-session/ and navigation to
sessionResponse.url); in Assert move all expect(...) checks
(product/monthlyPrice/yearlyPrice properties, response.ok(), sessionResponse
contents, customer/session assertions, and page heading visibility) into the
final Assert block so failures are isolated and the flow follows AAA.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: fb930ac6-65e5-478d-b883-8aac5b89bbb1
📒 Files selected for processing (6)
e2e/helpers/services/stripe/builders.tse2e/helpers/services/stripe/fake-stripe-server.tse2e/helpers/services/stripe/index.tse2e/helpers/services/stripe/stripe-service.tse2e/helpers/services/tiers/tiers-service.tse2e/tests/public/stripe-checkout-initiation.test.ts
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@e2e/helpers/services/stripe/fake-stripe-server.ts`:
- Around line 395-407: The mapping over subscriptionData.items and line_items
can crash if entries are null; update the items and line_items handling in
fake-stripe-server.ts to first filter entries with "item != null && typeof item
=== 'object'" before mapping, and use optional chaining when calling helpers
(e.g., replace parseString(item.plan) with parseString(item?.plan) and
parseNumber(item.price) with parseNumber(item?.price)); ensure you still filter
out empty strings after parsing (e.g., .map(...).filter(item => item.plan)).
This touches the code that uses parseString, parseNumber, parseBoolean, and
parseMetadata so keep those calls but guard inputs as described.
- Around line 159-169: The handler currently accepts a caller-provided product
ID (via parseString(req.body.product)) without verifying it exists, leading to
prices referencing missing products; change the logic in the price-creation path
(involving parseString, buildProduct, upsertProduct, buildPrice, and
parseBoolean) so that if a product ID is provided you first check this.products
(or the products store) for that ID and reject the request with a 4xx error when
not found; only create a synthetic product (via buildProduct and upsertProduct)
when no product ID was provided, then proceed to buildPrice using a
guaranteed-existing productId.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 792e218d-fa96-4038-bdee-49855333c9cd
📒 Files selected for processing (2)
e2e/helpers/services/stripe/fake-stripe-server.tse2e/tests/public/stripe-checkout-initiation.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- e2e/tests/public/stripe-checkout-initiation.test.ts
There was a problem hiding this comment.
🧹 Nitpick comments (1)
e2e/helpers/services/stripe/fake-stripe-server.ts (1)
326-329: Consider returning 404 for unhandled routes.The fallback returns 200 for all unhandled routes, which could mask issues where Ghost calls unexpected Stripe endpoints. While permissive behavior helps tests not fail on unimplemented routes, a 404 would more accurately simulate Stripe's behavior and help surface integration gaps earlier.
♻️ Optional: Return 404 for unhandled routes
this.app.use((req, res) => { debug(`Unhandled route: ${req.method} ${req.originalUrl} — returning fallback`); - res.status(200).json({id: 'fake', object: 'unknown'}); + res.status(404).json({error: {type: 'invalid_request_error', message: `Unhandled route: ${req.method} ${req.originalUrl}`}}); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@e2e/helpers/services/stripe/fake-stripe-server.ts` around lines 326 - 329, The fallback route in the fake Stripe server (the middleware using this.app.use that currently logs via debug and responds with res.status(200).json(...)) should return a 404 to better simulate Stripe and surface unexpected calls; update the middleware to send res.status(404).json(...) (optionally include a small error object like {error: 'Unhandled route'} or the original path) while keeping the debug(...) log so unhandled requests are still recorded.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@e2e/helpers/services/stripe/fake-stripe-server.ts`:
- Around line 326-329: The fallback route in the fake Stripe server (the
middleware using this.app.use that currently logs via debug and responds with
res.status(200).json(...)) should return a 404 to better simulate Stripe and
surface unexpected calls; update the middleware to send
res.status(404).json(...) (optionally include a small error object like {error:
'Unhandled route'} or the original path) while keeping the debug(...) log so
unhandled requests are still recorded.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: dfb066e8-9820-4ca1-ba96-0ea1d78ad6d4
📒 Files selected for processing (1)
e2e/helpers/services/stripe/fake-stripe-server.ts
no ref Added Stripe checkout initialization tests to `/e2e/`. This includes a nasty-looking smoke test that is helping validate the fake Stripe functionality while we build out the rest of this suite.
no ref
Added Stripe checkout initialization tests to
/e2e/. This includes a nasty-looking smoke test that is helping validate the fake Stripe functionality while we build out the rest of this suite.