You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
1.7 KiB

import { beforeEach, describe, expect, it, vi } from "vitest";
import {
generateQuoteId,
handleQuoteIdConflict,
isQuoteIdUniqueConflict,
} from "@/modules/quote/quote-id";
import { QuoteIdConflictError } from "@/modules/quote/types";
vi.mock("@/lib/prisma", () => ({
prisma: {
quoteRecord: {
findFirst: vi.fn(),
},
auditLog: {
create: vi.fn(),
},
},
}));
import { prisma } from "@/lib/prisma";
const mockedFindFirst = vi.mocked(prisma.quoteRecord.findFirst);
const mockedAuditCreate = vi.mocked(prisma.auditLog.create);
describe("generateQuoteId", () => {
beforeEach(() => {
mockedFindFirst.mockReset();
});
it("首日生成 _0001", async () => {
mockedFindFirst.mockResolvedValue(null);
const id = await generateQuoteId();
expect(id).toMatch(/^QTE_\d{8}_0001$/);
});
it("递增序号", async () => {
mockedFindFirst.mockResolvedValue({
quoteId: "QTE_20260616_0005",
} as never);
const id = await generateQuoteId();
expect(id).toMatch(/_0006$/);
});
});
describe("isQuoteIdUniqueConflict", () => {
it("P2002 quote_id → true", () => {
expect(
isQuoteIdUniqueConflict({
code: "P2002",
meta: { target: ["quote_id"] },
}),
).toBe(true);
});
it("其他错误 → false", () => {
expect(isQuoteIdUniqueConflict({ code: "P2002", meta: { target: ["email"] } })).toBe(false);
});
});
describe("handleQuoteIdConflict", () => {
it("写 audit 并抛 QuoteIdConflictError", async () => {
mockedAuditCreate.mockResolvedValue({} as never);
await expect(
handleQuoteIdConflict("QTE_20260616_0001", "CUST_001"),
).rejects.toThrow(QuoteIdConflictError);
expect(mockedAuditCreate).toHaveBeenCalled();
});
});