import { test, expect, seed, loginAs, api } from "./fixtures"; type Registration = { id: string; status: string; eventId: string }; type Ticket = { id: string; qrCode: string; eventId: string }; type CashByUser = { rows: { userId: string | null; cash: { total: number; count: number } }[] }; test.describe("registration → payment → ticket → check-in → cashup", () => { test("a free event: register and get a ticket straight away", async ({ page }) => { await loginAs(page, "user"); await page.goto(`/register/${seed().events.free}`); await expect(page.getByText("E2E Free Evening").first()).toBeVisible(); await page.getByRole("button", { name: "+" }).first().click(); await page.getByRole("button", { name: "Register", exact: true }).click(); await page.waitForURL(/\/registration\/success/); const tickets = await api(page, "user", "GET", "/api/tickets/mytickets"); expect(tickets.some((t) => t.eventId === seed().events.free)).toBe(true); }); test("a paid event: pending until paid, then a ticket that checks in once", async ({ page }) => { await loginAs(page, "user"); await page.goto(`/register/${seed().events.paid}`); await page.getByRole("button", { name: "+" }).first().click(); await expect(page.getByText("Total: R150.00")).toBeVisible(); await page.getByRole("button", { name: "Register", exact: true }).click(); await page.waitForURL(/\/registration\/success/); const regs = await api(page, "user", "GET", "/api/registrations/myregistrations"); const reg = regs.find((r) => r.eventId === seed().events.paid); expect(reg?.status).not.toBe("paid"); expect((await api(page, "user", "GET", "/api/tickets/mytickets")).some((t) => t.eventId === seed().events.paid)).toBe(false); // A supervisor records the cash payment at the desk. await api(page, "supervisor", "POST", "/api/payments", { amount: 150, method: "cash", registrationId: reg!.id, eventId: seed().events.paid, userId: seed().users.user.id }); const ticket = (await api(page, "user", "GET", "/api/tickets/mytickets")).find((t) => t.eventId === seed().events.paid); expect(ticket).toBeTruthy(); // My Events shows it. await page.goto("/dashboard/user"); await expect(page.getByText("E2E Paid Conference").first()).toBeVisible(); // Staff check it in; a second scan is refused. await api(page, "staff", "POST", `/api/tickets/scan/${ticket!.qrCode}`, { qty: 1 }); await expect(api(page, "staff", "POST", `/api/tickets/scan/${ticket!.qrCode}`, { qty: 1 })).rejects.toThrow(/403.*fully used/); // Cashup: the R150 cash is on the supervisor who took it. const cash = await api(page, "supervisor", "GET", `/api/cashups/event/${seed().events.paid}/cash-by-user`); const mine = cash.rows.find((r) => r.userId === seed().users.supervisor.id); expect(mine?.cash.total).toBe(150); expect(mine?.cash.count).toBe(1); }); });