e2e-paypal-portal-fix.mjs now passes against live prod: completing a compliance order creates the customers row (id, name=E2E Tester, company from intake_data, no password) -> customer can register/reset + log in. PayPal login bug fixed.
70 lines
3.4 KiB
JavaScript
70 lines
3.4 KiB
JavaScript
/**
|
|
* e2e-paypal-portal-fix.mjs - verify that completing a compliance order (the
|
|
* path PayPal/Stripe/crypto all funnel through) creates the Postgres `customers`
|
|
* row, so the customer can log in / reset password. Regression test for the
|
|
* Paul Wilson PayPal login bug (2026-06-09).
|
|
*
|
|
* It seeds a fake pending compliance order, calls the compiled
|
|
* handlePaymentComplete(), then asserts a customers row now exists. Cleans up.
|
|
*
|
|
* Run: docker exec performancewest-api-1 node /app/scripts/e2e-paypal-portal-fix.mjs
|
|
*/
|
|
import pg from "pg";
|
|
|
|
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
|
|
const { handlePaymentComplete } = await import("/app/dist/routes/checkout.js");
|
|
|
|
const EMAIL = `e2e-portal+${Date.now().toString().slice(-7)}@example-e2e.test`;
|
|
const ORDER = `CO-E2E${Date.now().toString().slice(-6)}`;
|
|
let fail = 0;
|
|
const ok = (m) => console.log(" [PASS] " + m);
|
|
const bad = (m) => { console.log(" [FAIL] " + m); fail++; };
|
|
|
|
try {
|
|
// 1) seed a pending compliance order (admin-assisted D&A, no intake gating needed for this test)
|
|
await pool.query(
|
|
`INSERT INTO compliance_orders
|
|
(order_number, service_slug, service_name, customer_name, customer_email,
|
|
payment_method, payment_status, service_fee_cents, intake_data)
|
|
VALUES ($1,'dot-drug-alcohol','DOT Drug & Alcohol Compliance Program',
|
|
'E2E Tester','${EMAIL}','paypal','pending_payment',14900,
|
|
'{"company":"E2E Co"}'::jsonb)`,
|
|
[ORDER],
|
|
);
|
|
ok(`seeded pending compliance order ${ORDER}`);
|
|
|
|
// precondition: no customers row yet
|
|
const before = await pool.query(`SELECT id FROM customers WHERE email=$1`, [EMAIL]);
|
|
if (before.rows.length === 0) ok("precondition: no customers row before payment");
|
|
else bad("precondition failed: customers row already existed");
|
|
|
|
// 2) simulate payment completion (the PayPal/Stripe/crypto common path)
|
|
await handlePaymentComplete(ORDER, "compliance", "e2e-test-session");
|
|
ok("handlePaymentComplete ran");
|
|
|
|
// 3) assert: order marked paid + customers row created
|
|
const ord = await pool.query(`SELECT payment_status FROM compliance_orders WHERE order_number=$1`, [ORDER]);
|
|
if (ord.rows[0]?.payment_status === "paid") ok("order marked paid");
|
|
else bad(`order not paid (got ${ord.rows[0]?.payment_status})`);
|
|
|
|
const after = await pool.query(`SELECT id, name, company, password_hash FROM customers WHERE email=$1`, [EMAIL]);
|
|
if (after.rows.length === 1) {
|
|
ok(`customers row created (id=${after.rows[0].id}, name=${after.rows[0].name}, company=${after.rows[0].company})`);
|
|
if (after.rows[0].password_hash === null) ok("customers row has no password (correct: customer sets it via register/reset)");
|
|
else bad("customers row unexpectedly has a password_hash");
|
|
} else {
|
|
bad("customers row was NOT created (the bug would still be present)");
|
|
}
|
|
} catch (e) {
|
|
bad("exception: " + e.message);
|
|
} finally {
|
|
// cleanup
|
|
await pool.query(`DELETE FROM password_reset_tokens WHERE customer_id IN (SELECT id FROM customers WHERE email=$1)`, [EMAIL]).catch(()=>{});
|
|
await pool.query(`DELETE FROM customers WHERE email=$1`, [EMAIL]).catch(()=>{});
|
|
await pool.query(`DELETE FROM compliance_orders WHERE order_number=$1`, [ORDER]).catch(()=>{});
|
|
console.log(" cleaned up test order + customers row");
|
|
await pool.end();
|
|
}
|
|
|
|
console.log(fail === 0 ? "\n=== ALL CHECKS PASSED ===" : `\n=== ${fail} CHECK(S) FAILED ===`);
|
|
process.exit(fail === 0 ? 0 : 1);
|