import { beforeEach, describe, expect, it } from "vitest"; import { Timestamp } from "firebase-admin/firestore"; import { firestore } from "../../src/firebase"; import { listAllOrders } from "../../src/repositories/orderRepository"; import type { OrderDoc } from "../../src/types/reward"; function makeOrder(uid: string, createdAt: Timestamp, overrides: Partial = {}): OrderDoc { return { uid, items: [{ productId: "p1", qty: 1, pointPrice: 500, name: "굿즈" }], totalPoints: 500, recipient: { name: "홍길동", phone: "01000000000", address1: "서울", postalCode: "00000" }, status: "reserved", clientIdempotencyKey: `key-${uid}-${createdAt.toMillis()}`, reserveLedgerTxIds: [], orderedAt: createdAt, statusHistory: [{ status: "reserved", at: createdAt, actor: uid }], createdAt, updatedAt: createdAt, ...overrides, }; } describe("orderRepository.listAllOrders", () => { beforeEach(async () => { await firestore.recursiveDelete(firestore.collection("orders")); }); it("uid 필터 없이 서로 다른 유저의 주문을 모두 createdAt desc로 반환한다", async () => { const t1 = Timestamp.fromDate(new Date("2026-07-01T00:00:00.000Z")); const t2 = Timestamp.fromDate(new Date("2026-07-02T00:00:00.000Z")); const t3 = Timestamp.fromDate(new Date("2026-07-03T00:00:00.000Z")); await firestore.doc("orders/o1").set(makeOrder("uid-a", t1)); await firestore.doc("orders/o2").set(makeOrder("uid-b", t2)); await firestore.doc("orders/o3").set(makeOrder("uid-a", t3)); const page = await listAllOrders(20); expect(page.items.map((o) => o.id)).toEqual(["o3", "o2", "o1"]); expect(page.items.map((o) => o.uid).sort()).toEqual(["uid-a", "uid-a", "uid-b"].sort()); }); it("cursor 기반 페이지네이션이 동작한다", async () => { const t1 = Timestamp.fromDate(new Date("2026-07-01T00:00:00.000Z")); const t2 = Timestamp.fromDate(new Date("2026-07-02T00:00:00.000Z")); const t3 = Timestamp.fromDate(new Date("2026-07-03T00:00:00.000Z")); await firestore.doc("orders/o1").set(makeOrder("uid-a", t1)); await firestore.doc("orders/o2").set(makeOrder("uid-b", t2)); await firestore.doc("orders/o3").set(makeOrder("uid-a", t3)); const firstPage = await listAllOrders(2); expect(firstPage.items.map((o) => o.id)).toEqual(["o3", "o2"]); expect(firstPage.cursor).toBe("o2"); const secondPage = await listAllOrders(2, firstPage.cursor ?? undefined); expect(secondPage.items.map((o) => o.id)).toEqual(["o1"]); expect(secondPage.cursor).toBe("o1"); }); it("status 필터를 걸면 해당 상태 주문만 반환한다 (기존 status+createdAt 인덱스 재사용)", async () => { const t1 = Timestamp.fromDate(new Date("2026-07-01T00:00:00.000Z")); const t2 = Timestamp.fromDate(new Date("2026-07-02T00:00:00.000Z")); await firestore.doc("orders/o1").set(makeOrder("uid-a", t1, { status: "reserved" })); await firestore.doc("orders/o2").set(makeOrder("uid-b", t2, { status: "confirmed" })); const page = await listAllOrders(20, undefined, "confirmed"); expect(page.items.map((o) => o.id)).toEqual(["o2"]); }); });