examples/storefront Public
import assert from "node:assert/strict";import { test } from "node:test";import { setup } from "./helpers/app.ts";test("lists active products by name", async () => { const s = setup(); await s.addProduct("wool-socks", { name: "Wool socks", price_cents: 1800 }); await s.addProduct("canvas-tote", { name: "Canvas tote", price_cents: 2400 }); await s.addProduct("old-mug", { name: "Old mug", active: false }); const res = await s.call("GET", "/products"); assert.equal(res.status, 200); assert.deepEqual(res.body.products.map((p: { id: string }) => p.id), ["canvas-tote", "wool-socks"]);});test("an inactive product is not found by shoppers", async () => { const s = setup(); await s.addProduct("old-mug", { active: false }); assert.equal((await s.call("GET", "/products/old-mug")).status, 404);});test("updating a product keeps its id and changes its fields", async () => { const s = setup(); await s.addProduct("wool-socks", { price_cents: 1800 }); await s.addProduct("wool-socks", { price_cents: 1500, stock: 40 }); const { body } = await s.call("GET", "/products/wool-socks"); assert.equal(body.product.price_cents, 1500); assert.equal(body.product.stock, 40);});test("merchant routes need the admin token", async () => { const s = setup(); const res = await s.call("PUT", "/admin/products/wool-socks", { name: "Wool socks", price_cents: 1800 }, { authorization: "Bearer wrong" }); assert.equal(res.status, 401); assert.equal(res.body.error, "unauthorized");});test("rejects a price that is not whole cents", async () => { const s = setup(); const res = await s.call("PUT", "/admin/products/wool-socks", { name: "Wool socks", price_cents: 18.5 }, s.admin); assert.equal(res.status, 400); assert.equal(res.body.error, "bad_price");});test("rejects an id that is not a slug", async () => { const s = setup(); const res = await s.call("PUT", "/admin/products/Wool%20Socks", { name: "Wool socks", price_cents: 1800 }, s.admin); assert.equal(res.body.error, "bad_id");});test("unknown routes and methods", async () => { const s = setup(); assert.equal((await s.call("GET", "/nope")).status, 404); assert.equal((await s.call("DELETE", "/products")).status, 405); assert.equal((await s.call("GET", "/products/%E0%A4%A")).status, 400);});test("pages through the catalog with a cursor", async () => { const s = setup(); for (const id of ["a-mug", "b-tote", "c-socks", "d-apron", "e-candle"]) await s.addProduct(id, { name: id }); const first = (await s.call("GET", "/products?limit=2")).body; assert.deepEqual(first.products.map((p: { id: string }) => p.id), ["a-mug", "b-tote"]); const second = (await s.call("GET", `/products?limit=2&after=${first.next}`)).body; assert.deepEqual(second.products.map((p: { id: string }) => p.id), ["c-socks", "d-apron"]); const last = (await s.call("GET", `/products?limit=2&after=${second.next}`)).body; assert.deepEqual(last.products.map((p: { id: string }) => p.id), ["e-candle"]); assert.equal(last.next, null);});test("products that share a name are ordered by id and none is skipped", async () => { const s = setup(); for (const id of ["mug-blue", "mug-green", "mug-red"]) await s.addProduct(id, { name: "Enamel mug" }); const first = (await s.call("GET", "/products?limit=2")).body; const rest = (await s.call("GET", `/products?limit=2&after=${first.next}`)).body; assert.deepEqual([...first.products, ...rest.products].map((p: { id: string }) => p.id), ["mug-blue", "mug-green", "mug-red"]);});test("a page boundary survives a product being added before it", async () => { const s = setup(); for (const id of ["b-tote", "c-socks", "d-apron"]) await s.addProduct(id, { name: id }); const first = (await s.call("GET", "/products?limit=2")).body; await s.addProduct("a-mug", { name: "a-mug" }); const second = (await s.call("GET", `/products?limit=2&after=${first.next}`)).body; assert.deepEqual(second.products.map((p: { id: string }) => p.id), ["d-apron"]);});test("refuses a bad limit or cursor", async () => { const s = setup(); for (const q of ["limit=0", "limit=101", "limit=ten"]) assert.equal((await s.call("GET", `/products?${q}`)).body.error, "bad_limit", q); assert.equal((await s.call("GET", "/products?after=not-a-cursor")).body.error, "bad_cursor");});