test(stripe): add real-Stripe regression coverage and complete the opt-in TEST-mode check
e2e-phase9.js: one new deterministic regression test proving the webhook-correlation fix — a test event referencing a transaction's own UUID (the exact shape a real Stripe payment_intent.payment_failed/charge.refunded event now produces) is still matched. 20/20. stripe-integration-test.js: configurable price/currency (STRIPE_TEST_PRICE_CENTS/ STRIPE_TEST_CURRENCY) and a STRIPE_TEST_MINOR=true guardian+minor path. Once a real payment lands, now fully automates deep post-payment verification: exactly-one payment_transactions record, registration/enrollment/cohort/guardian reconciliation, a genuine duplicate-delivery proof (re-signing the REAL event fetched via stripe.events.retrieve — never a fabricated one), real student activation + program-visibility, and a real refund with the non-cascade rule reconfirmed — plus a fully automated, browser-free abandoned-checkout proof via Stripe's own sessions.expire() API. Still opt-in, still a guaranteed no-op by default, still refuses live-mode keys.
This commit is contained in:
@@ -175,6 +175,29 @@ async function main() {
|
||||
assert.equal(regAfter.body.status, 'started', 'a failed payment leaves the registration open to retry, not cancelled');
|
||||
});
|
||||
|
||||
// Phase 9.1 real-Stripe-TEST regression — a real Stripe payment_intent.payment_failed/
|
||||
// charge.refunded event references the PaymentIntent/Charge, not the Checkout Session, so
|
||||
// StripeProvider.normalizeEvent() resolves those back to OUR OWN transaction_id (never the
|
||||
// stored provider_reference) via payment_intent_data.metadata. This deterministic test
|
||||
// simulates exactly that shape — a webhook event whose providerReference is the transaction's
|
||||
// own UUID, not its provider_reference — proving commerce.js's lookup matches on either
|
||||
// column. Found and fixed only by testing against real Stripe (the deterministic
|
||||
// provider previously always reused one caller-supplied reference, which never exposed this).
|
||||
await test('a webhook event referencing OUR OWN transaction_id (not provider_reference) — the real Stripe payment_intent/charge shape — is still matched', async () => {
|
||||
const idOffering = `off-p9-txidref-${RUN_ID}`, idSlug = `p9-txidref-${RUN_ID}`;
|
||||
await setupPaidOffering(owner, { offeringId: idOffering, slug: idSlug, capacity: 2, requireAgreement: false });
|
||||
const reg = await integrationPost('/api/integrations/registrations', { event_id: `p9-txidref-evt-${RUN_ID}`, offering_slug: idSlug, registrant: { display_name: 'TxIdRef', email: `txidref-${RUN_ID}@example.com` } });
|
||||
await integrationPost(`/api/integrations/registrations/${reg.body.registration_id}/checkout`, { success_url: 'https://example.com/s', cancel_url: 'https://example.com/c' });
|
||||
const txRow = await owner.request('GET', `/api/admin/registrations/${reg.body.registration_id}/payments`);
|
||||
const transactionId = txRow.body[0].transaction_id;
|
||||
assert.notEqual(transactionId, txRow.body[0].provider_reference, 'sanity check — these must be genuinely different values for this test to mean anything');
|
||||
const event = provider.buildTestEvent({ providerReference: transactionId, eventType: 'payment_intent.payment_failed' });
|
||||
const result = await webhookPost(event.body, event.signature);
|
||||
assert.equal(result.body.result, 'processed', 'the transaction must be found via transaction_id, not just provider_reference');
|
||||
const regAfter = await owner.request('GET', `/api/admin/registrations/${reg.body.registration_id}`);
|
||||
assert.equal(regAfter.body.status, 'started', 'a failed payment (matched via transaction_id) still leaves the registration retriable, not cancelled');
|
||||
});
|
||||
|
||||
// ── 19/21: capacity handling, last-seat race ─────────────────────────────────────────────
|
||||
await test('a last-seat race between two concurrent registration attempts yields exactly one winner', async () => {
|
||||
const raceOffering = `off-p9-race-${RUN_ID}`, raceSlug = `p9-race-${RUN_ID}`;
|
||||
|
||||
Reference in New Issue
Block a user