examples/storefront Public
import assert from "node:assert/strict";import { test } from "node:test";import { setup } from "./helpers/app.ts";const SHIP_TO = { name: "Ada Park", line1: "12 Alder St", city: "Portland", postal_code: "97205", country: "us" };const CHECKOUT = { email: "ada@park.test", ship_to: SHIP_TO };async function filledCart(stock = 3) { const s = setup(); await s.addProduct("wool-socks", { name: "Wool socks", price_cents: 1800, stock }); await s.addProduct("canvas-tote", { name: "Canvas tote", price_cents: 2400, stock: 10 }); const cartId = (await s.call("POST", "/carts")).body.cart.id as string; await s.call("PUT", `/carts/${cartId}/items/wool-socks`, { quantity: 2 }); await s.call("PUT", `/carts/${cartId}/items/canvas-tote`, { quantity: 1 }); return { ...s, cartId };}async function stockOf(s: ReturnType<typeof setup>, id: string): Promise<number> { return (await s.call("GET", `/products/${id}`)).body.product.stock;}test("checkout creates a pending order, takes the stock and returns the client secret", async () => { const s = await filledCart(); const res = await s.call("POST", `/carts/${s.cartId}/checkout`, CHECKOUT); assert.equal(res.status, 201); const { order, payment } = res.body; assert.equal(order.status, "pending_payment"); assert.equal(order.total_cents, 6000); assert.equal(order.ship_to.country, "US"); assert.equal(order.items.length, 2); assert.equal(payment.client_secret, `pi_${order.id}_secret`); assert.deepEqual(s.payments.charges, [{ order_id: order.id, amount_cents: 6000, currency: "usd", email: "ada@park.test" }]); assert.equal(await stockOf(s, "wool-socks"), 1); assert.equal((await s.call("GET", `/carts/${s.cartId}`)).body.cart.status, "checked_out"); assert.equal((await s.call("GET", `/orders/${order.id}`)).body.order.status, "pending_payment");});test("a retried checkout returns the same order and takes no more stock", async () => { const s = await filledCart(); const first = await s.call("POST", `/carts/${s.cartId}/checkout`, CHECKOUT); const again = await s.call("POST", `/carts/${s.cartId}/checkout`, CHECKOUT); assert.equal(again.status, 200); assert.equal(again.body.order.id, first.body.order.id); assert.equal(again.body.payment.client_secret, first.body.payment.client_secret); assert.equal(await stockOf(s, "wool-socks"), 1);});test("a checked-out cart can no longer change", async () => { const s = await filledCart(); await s.call("POST", `/carts/${s.cartId}/checkout`, CHECKOUT); const res = await s.call("PUT", `/carts/${s.cartId}/items/wool-socks`, { quantity: 1 }); assert.equal(res.body.error, "cart_closed");});test("refuses the checkout when stock ran out after the item was added", async () => { const s = await filledCart(); await s.addProduct("wool-socks", { name: "Wool socks", price_cents: 1800, stock: 1 }); const res = await s.call("POST", `/carts/${s.cartId}/checkout`, CHECKOUT); assert.equal(res.status, 409); assert.equal(res.body.error, "out_of_stock"); assert.deepEqual(res.body.items, [{ product_id: "wool-socks", available: 1 }]); assert.equal(await stockOf(s, "canvas-tote"), 10, "nothing was taken"); assert.equal((await s.call("GET", `/carts/${s.cartId}`)).body.cart.status, "open");});test("the stock constraint stops two checkouts from both taking the last items", async () => { const s = await filledCart(2); const other = (await s.call("POST", "/carts")).body.cart.id; await s.call("PUT", `/carts/${other}/items/wool-socks`, { quantity: 2 }); assert.equal((await s.call("POST", `/carts/${other}/checkout`, CHECKOUT)).status, 201); const res = await s.call("POST", `/carts/${s.cartId}/checkout`, CHECKOUT); assert.equal(res.body.error, "out_of_stock"); assert.equal(await stockOf(s, "wool-socks"), 0);});test("when the payment provider fails, the checkout is undone", async () => { const s = await filledCart(); s.payments.failNext = true; const res = await s.call("POST", `/carts/${s.cartId}/checkout`, CHECKOUT); assert.equal(res.status, 502); assert.equal(res.body.error, "payments_unavailable"); assert.equal(await stockOf(s, "wool-socks"), 3); assert.equal((await s.call("GET", `/carts/${s.cartId}`)).body.cart.status, "open"); assert.equal((await s.call("POST", `/carts/${s.cartId}/checkout`, CHECKOUT)).status, 201, "and can be retried");});test("checkout needs an email, a full address and a non-empty cart", async () => { const s = await filledCart(); assert.equal((await s.call("POST", `/carts/${s.cartId}/checkout`, { ...CHECKOUT, email: "ada" })).body.error, "bad_email"); assert.equal((await s.call("POST", `/carts/${s.cartId}/checkout`, { email: "ada@park.test" })).body.error, "bad_address"); const noCity = { ...CHECKOUT, ship_to: { ...SHIP_TO, city: " " } }; assert.equal((await s.call("POST", `/carts/${s.cartId}/checkout`, noCity)).body.error, "bad_address"); const empty = (await s.call("POST", "/carts")).body.cart.id; assert.equal((await s.call("POST", `/carts/${empty}/checkout`, CHECKOUT)).body.error, "cart_empty"); assert.equal((await s.call("GET", "/orders/nope")).status, 404);});