Skip to content

Settings page regression tests (3/6): Membership Plans tab - #135

Open
conatus wants to merge 3 commits into
admin-e2e-theme-copyfrom
admin-e2e-membership-plans
Open

conatus wants to merge 3 commits into
admin-e2e-theme-copyfrom
admin-e2e-membership-plans

Conversation

@conatus

@conatus conatus commented Oct 24, 2026

Copy link
Copy Markdown
Member

Third of the settings page regression test PRs. Stacked on #134 (Theme + Copy), which is stacked on #133 (foundation + Features).

Covers every setting on the Membership Plans tab. Each test changes the setting on the settings page, reads it back through Settings::get, and checks it does what the rest of the plugin expects. A legacy test loads the settings as Carbon Fields stored them and checks they still work.

What's covered (tests/settings/membership-plans.spec.ts)

Global plans

  • A plan added on the settings page is saved, stored under its ID (ck_join_flow_membership_plan_<id>) and offered on a join form with no plans of its own, with the right price label, description and "Continue and pay" text.
  • Each plan field:
    • Price Point ID becomes the plan's ID, and joins use it.
    • Frequency and Currency set how the price is shown. New plans are monthly GBP unless changed.
    • Allow users to change the amount shows an amount box with the price as its minimum. /join also enforces that minimum.
  • Removing a plan takes it off the form. Its stored copy is kept, so a form opened earlier can still complete a join.
  • A changed price reaches the form and the stored plan.
  • Saving is refused with no plans, or with a plan missing its Name or Price, and nothing is saved.
  • Stripe (fake API): each plan gets a product, and a recurring price in its currency, amount and frequency (week/month/year). A changed price gets a new price on the same product.

Member tags (fake Stripe and Mailchimp)

  • Defaults: "Lapsed - failed payment", "Cancelled", "Lapsing".
  • On a join, the plan's Add Tags are added. The lapsed, cancelled and lapsing tags and other plans' tags are removed.
  • Stripe webhook events apply the tags:
    • A subscription ended by failed payments gets Lapsed Tag.
    • A subscription the member cancelled gets Cancelled Tag.
    • A failed payment Stripe will retry gets Lapsing Tag.
    • A blank tag turns that tagging off.
  • Moving to another plan in Stripe swaps the old plan's Add Tags for the new plan's.

Legacy: plans and tags in Carbon Fields' storage format are still read, offered on the form and can be joined on.

Supporting changes

  • JoinSettingsPage: plans(), addPlan(), editPlan(), removePlan(), expectSaveRefused().
  • postJoin() and postStripeWebhook() helpers, plus GLOBAL_PLANS_PAGE.
  • Fake Stripe: list endpoints, plus a control endpoint for tests to put objects in place first (seedFakeStripe), e.g. the customer a webhook names.
  • Docs: coverage table and readme updated.

Problems found

  • JOIN-166: saving creates a duplicate Stripe price every time for plans priced in pence (e.g. £9.50). There's a skipped test for it; I checked it fails when enabled.
  • JOIN-165 (found while reading the webhook code): the Stripe webhook endpoint doesn't verify Stripe's signature. The tests here post unsigned events, so they'll need signing once that's fixed.

Testing

Locally, all of tests/settings: 89 passed, 5 skipped (the known-problem tests).


Generated by Claude Code

Covers the global membership plans and the lapsed, cancelled and lapsing
tags: each setting is saved, read back through Settings::get, has its
effect on the join form, on joins and in Stripe and Mailchimp (fake API),
and is still read when loaded as Carbon Fields stored it.

The fake Stripe now lists objects and can have objects put in place by a
test, so the plugin's webhook handlers can be driven end to end.

Duplicate Stripe prices for prices with pence (JOIN-166) are a skipped test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BL2bFrTk84JMy3CPAsCTV9
Comment thread packages/join-e2e/fake-api/server.js Resolved
Comment thread docs/e2e-testing.md Resolved

@conatus conatus left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Supplementary review: one issue with how expectSaveRefused will behave once the page is rebuilt. This adds to the inline findings already posted.


Generated by Claude Code

# Conflicts:
#	packages/join-e2e/tests/settings/support.ts
- Fake Stripe lists filter as Stripe does for what the plugin sends:
  status=all, ranges such as created[gte], and no canceled subscriptions
  unless asked for.
- expectSaveRefused tries the save when Save isn't disabled, so a page
  that leaves the check to the browser (native `required`) works too.
  saveSkippingPageChecksExpectingErrors tests the plugin's own checks; a
  skipped test shows it doesn't check a plan's Name (JOIN-169).
- New test: a member with another active subscription isn't tagged when
  one ends.
- The legacy fixture stores the plan without a Price Point ID under its
  name alone, as pre-1.4.4 sites have it, so the plugin's lookup for
  those is tested.
- The "never saved" plan test pairs its 500 with a join that succeeds.
- The removed-plan test notes it pins today's behaviour (JOIN-170).
- addPlan uses the Membership Plans field's own Add button; stored plans
  are read in one WP-CLI call; the member's Mailchimp hash is worked out
  from a shared MEMBER_EMAIL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BL2bFrTk84JMy3CPAsCTV9
@conatus conatus changed the title Settings page regression tests: Membership Plans tab Settings page regression tests (3/6): Membership Plans tab Oct 25, 2026
@linear-code

linear-code Bot commented Oct 25, 2026

Copy link
Copy Markdown

JOIN-173

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants