examples/storefront Public
import assert from "node:assert/strict";import { test } from "node:test";import { expireOrders, MAX_PER_RUN, PAYMENT_WINDOW_MS } from "../src/expiry.ts";import { markPaid } from "../src/orders.ts";import { NOW, setup } from "./helpers/app.ts";const CHECKOUT = { email: "ada@park.test", ship_to: { name: "Ada Park", line1: "12 Alder St", city: "Portland", postal_code: "97205", country: "US" } };async function pending() { const s = setup(); await s.addProduct("wool-socks", { stock: 3 }); const cartId = (await s.call("POST", "/carts")).body.cart.id; await s.call("PUT", `/carts/${cartId}/items/wool-socks`, { quantity: 2 }); const order = (await s.call("POST", `/carts/${cartId}/checkout`, CHECKOUT)).body.order; const expire = (at: number) => expireOrders(s.env.DB, s.events, s.payments, at); const status = async () => (await s.call("GET", `/orders/${order.id}`)).body.order.status; const stock = async () => (await s.call("GET", "/products/wool-socks")).body.product.stock; return { ...s, order, expire, status, stock };}test("an order unpaid after 30 minutes is cancelled with its intent, and the stock comes back", async () => { const s = await pending(); const report = await s.expire(NOW + PAYMENT_WINDOW_MS + 1); assert.deepEqual(report, { cancelled: [s.order.id], left_to_webhook: [] }); assert.deepEqual(s.payments.cancelled, [`pi_${s.order.id}`]); assert.equal(await s.status(), "cancelled"); assert.equal(await s.stock(), 3); assert.deepEqual(s.events.sent.map((e) => e.type), ["order.cancelled"]);});test("orders inside the payment window are left alone", async () => { const s = await pending(); assert.deepEqual(await s.expire(NOW + PAYMENT_WINDOW_MS - 1), { cancelled: [], left_to_webhook: [] }); assert.equal(await s.status(), "pending_payment");});test("an intent that succeeded at the last moment is left for the webhook", async () => { const s = await pending(); s.payments.uncancellable.add(`pi_${s.order.id}`); const report = await s.expire(NOW + PAYMENT_WINDOW_MS + 1); assert.deepEqual(report, { cancelled: [], left_to_webhook: [s.order.id] }); assert.equal(await s.status(), "pending_payment"); await markPaid(s.env.DB, s.events, s.order.id, `pi_${s.order.id}`, NOW); assert.equal(await s.status(), "paid");});test("paid orders are never expired", async () => { const s = await pending(); await markPaid(s.env.DB, s.events, s.order.id, `pi_${s.order.id}`, NOW); assert.deepEqual(await s.expire(NOW + 2 * PAYMENT_WINDOW_MS), { cancelled: [], left_to_webhook: [] }); assert.deepEqual(s.payments.cancelled, []);});// Regression: the query used to take the 50 oldest pending orders every run. Orders whose payment// had gone through but whose webhook had not arrived stayed pending and stayed oldest, so once// there were 50 of them, no abandoned order behind them was ever cancelled.test("orders left to the webhook do not stop the run from reaching newer abandoned orders", async () => { const s = setup(); await s.addProduct("wool-socks", { stock: 60 }); for (let i = 0; i < 51; i++) { const cartId = (await s.call("POST", "/carts")).body.cart.id; await s.call("PUT", `/carts/${cartId}/items/wool-socks`, { quantity: 1 }); await s.call("POST", `/carts/${cartId}/checkout`, CHECKOUT); } const { results } = await s.env.DB.prepare("SELECT id FROM orders ORDER BY created_at, id").all<{ id: string }>(); const paid = results.slice(0, 50).map((o) => o.id); const abandoned = results[50]!.id; for (const id of paid) s.payments.uncancellable.add(`pi_${id}`); const report = await expireOrders(s.env.DB, s.events, s.payments, NOW + PAYMENT_WINDOW_MS + 1); assert.deepEqual(report.left_to_webhook, paid); assert.deepEqual(report.cancelled, [abandoned]); assert.equal((await s.call("GET", "/products/wool-socks")).body.product.stock, 10);});test("one run looks at no more than MAX_PER_RUN orders", async () => { const s = setup(); await s.addProduct("wool-socks", { stock: MAX_PER_RUN + 5 }); for (let i = 0; i < MAX_PER_RUN + 5; i++) { const cartId = (await s.call("POST", "/carts")).body.cart.id; await s.call("PUT", `/carts/${cartId}/items/wool-socks`, { quantity: 1 }); await s.call("POST", `/carts/${cartId}/checkout`, CHECKOUT); } const first = await expireOrders(s.env.DB, s.events, s.payments, NOW + PAYMENT_WINDOW_MS + 1); assert.equal(first.cancelled.length, MAX_PER_RUN); const second = await expireOrders(s.env.DB, s.events, s.payments, NOW + PAYMENT_WINDOW_MS + 1); assert.equal(second.cancelled.length, 5);});