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
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();
|
|
});
|
|
});
|