import { beforeEach, describe, expect, it, vi } from "vitest"; import { appRouter } from "./routers"; import * as db from "./db"; import type { TrpcContext } from "./_core/context"; vi.mock("./db", () => ({ findInspectionTaskByModelAndName: vi.fn(async () => undefined), createInspectionTask: vi.fn(async (data) => ({ id: 1, modelId: data.modelId, name: data.name, inspector: data.inspector ?? null, notes: data.notes ?? null, status: data.status, createdAt: new Date(), updatedAt: new Date(), completedAt: null, })), })); type AuthenticatedUser = NonNullable; function createAuthContext(): TrpcContext { const user: AuthenticatedUser = { id: 1, openId: "test-user", email: "test@example.com", name: "Test User", loginMethod: "manus", role: "user", createdAt: new Date(), updatedAt: new Date(), lastSignedIn: new Date(), }; return { user, req: { protocol: "https", headers: {}, } as TrpcContext["req"], res: { clearCookie: vi.fn(), } as unknown as TrpcContext["res"], }; } describe("inspection task router", () => { beforeEach(() => { vi.clearAllMocks(); vi.mocked(db.findInspectionTaskByModelAndName).mockResolvedValue(undefined); }); it("trims name and creates a task in created status", async () => { const ctx = createAuthContext(); const caller = appRouter.createCaller(ctx); const result = await caller.inspectionTask.create({ modelId: 1, name: " 首检任务 ", }); expect(result.status).toBe("created"); expect(db.findInspectionTaskByModelAndName).toHaveBeenCalledWith(1, "首检任务"); expect(db.createInspectionTask).toHaveBeenCalledWith({ modelId: 1, name: "首检任务", inspector: null, notes: null, status: "created", }); }); it("returns CONFLICT when the same model already has the task name", async () => { vi.mocked(db.findInspectionTaskByModelAndName).mockResolvedValueOnce({ id: 1, modelId: 1, name: "首检任务", inspector: null, notes: null, status: "created", createdAt: new Date(), updatedAt: new Date(), completedAt: null, }); const ctx = createAuthContext(); const caller = appRouter.createCaller(ctx); await expect(caller.inspectionTask.create({ modelId: 1, name: "首检任务", })).rejects.toMatchObject({ code: "CONFLICT", message: "该车型下已存在同名检测任务。", }); expect(db.createInspectionTask).not.toHaveBeenCalled(); }); it("returns CONFLICT when the database unique key rejects a concurrent duplicate", async () => { vi.mocked(db.createInspectionTask).mockRejectedValueOnce({ code: "ER_DUP_ENTRY", errno: 1062, message: "Duplicate entry '1-首检任务' for key 'uk_inspection_tasks_model_name'", }); const ctx = createAuthContext(); const caller = appRouter.createCaller(ctx); await expect(caller.inspectionTask.create({ modelId: 1, name: "首检任务", })).rejects.toMatchObject({ code: "CONFLICT", message: "该车型下已存在同名检测任务。", }); }); });