diff --git a/app/pages/events/index.vue b/app/pages/events/index.vue index 4894a07..3a64189 100644 --- a/app/pages/events/index.vue +++ b/app/pages/events/index.vue @@ -430,7 +430,6 @@ const isAlmostFull = (event) => { border-color: var(--candle-faint); color: var(--text-dim); } -/* WCAG 2.4.7 — keyboard focus must be visibly indicated. */ .past-toggle:focus-visible { outline: 2px dashed var(--candle); outline-offset: 3px; diff --git a/tests/server/api/free-signup-flow.test.js b/tests/server/api/free-signup-flow.test.js index c7789ad..521c0b2 100644 --- a/tests/server/api/free-signup-flow.test.js +++ b/tests/server/api/free-signup-flow.test.js @@ -8,11 +8,8 @@ import { resetRateLimit } from '../../../server/utils/rateLimit.js' import { sendWelcomeEmail } from '../../../server/utils/resend.js' import { createMockEvent } from '../helpers/createMockEvent.js' -// IMPORTANT: do NOT mock server/utils/auth.js. This test exists to verify the -// real bridge-cookie hand-off between the two handlers. Mocking auth would -// hide the exact regression we're guarding against (setPaymentBridgeCookie -// being skipped for $0 signups while subscription.post.js still requires -// either a bridge cookie or a verified session). +// Deliberately does NOT mock server/utils/auth.js — the bridge-cookie +// hand-off between the two handlers is the contract under test. vi.mock('../../../server/models/member.js', () => ({ default: { @@ -49,6 +46,14 @@ vi.stubGlobal('helcimSubscriptionSchema', {}) const ALLOWED_ORIGIN = 'https://ghostguild.test' const MEMBER_ID = '69f231152939bf109ac79d83' +const SUBSCRIPTION_BODY = { + customerId: 999, + customerCode: 'CST999', + contributionAmount: 0, + cadence: 'monthly', + cardToken: null +} + function extractBridgeCookie(event) { const setCookie = event.node.res.getHeader('set-cookie') const cookies = Array.isArray(setCookie) ? setCookie : [setCookie].filter(Boolean) @@ -64,6 +69,9 @@ describe('signup → subscription bridge-cookie hand-off', () => { process.env.BASE_URL = ALLOWED_ORIGIN createHelcimCustomer.mockResolvedValue({ id: 999, customerCode: 'CST999' }) + }) + + it('$0 signup: customer endpoint issues a bridge cookie that subscription endpoint accepts', async () => { Member.findOne.mockResolvedValue(null) Member.create.mockResolvedValue({ _id: MEMBER_ID, @@ -73,10 +81,7 @@ describe('signup → subscription bridge-cookie hand-off', () => { contributionAmount: 0, status: 'pending_payment' }) - }) - it('$0 signup: customer endpoint issues a bridge cookie that subscription endpoint accepts', async () => { - // --- Step 1: POST /api/helcim/customer (free tier) --- const customerEvent = createMockEvent({ method: 'POST', path: '/api/helcim/customer', @@ -95,13 +100,9 @@ describe('signup → subscription bridge-cookie hand-off', () => { expect(result1.success).toBe(true) expect(result1.member.status).toBe('pending_payment') - // The regression: prior code skipped setPaymentBridgeCookie when - // contributionAmount === 0, leaving the user unable to complete - // subscription activation in the same flow. const bridgeToken = extractBridgeCookie(customerEvent) expect(bridgeToken, 'payment-bridge cookie missing on $0 signup').toBeTruthy() - // --- Step 2: POST /api/helcim/subscription (free tier) --- Member.findOneAndUpdate.mockResolvedValue({ _id: MEMBER_ID, status: 'pending_payment' }) Member.findById.mockResolvedValue({ _id: MEMBER_ID, @@ -117,13 +118,7 @@ describe('signup → subscription bridge-cookie hand-off', () => { path: '/api/helcim/subscription', headers: { origin: ALLOWED_ORIGIN }, cookies: { 'payment-bridge': bridgeToken }, - body: { - customerId: 999, - customerCode: 'CST999', - contributionAmount: 0, - cadence: 'monthly', - cardToken: null - } + body: SUBSCRIPTION_BODY }) const result2 = await subscriptionHandler(subscriptionEvent) @@ -133,20 +128,11 @@ describe('signup → subscription bridge-cookie hand-off', () => { }) it('$0 signup with no bridge cookie carried forward → subscription returns 401', async () => { - // Sanity check: confirms the auth gate still rejects fresh, unauthenticated - // calls to /api/helcim/subscription. If this ever stops failing, the - // bridge cookie has stopped being load-bearing and the gate is open. const subscriptionEvent = createMockEvent({ method: 'POST', path: '/api/helcim/subscription', headers: { origin: ALLOWED_ORIGIN }, - body: { - customerId: 999, - customerCode: 'CST999', - contributionAmount: 0, - cadence: 'monthly', - cardToken: null - } + body: SUBSCRIPTION_BODY }) await expect(subscriptionHandler(subscriptionEvent)).rejects.toMatchObject({