Files
massive-cloud/server/inspectionTask.test.ts

123 lines
3.3 KiB
TypeScript

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<TrpcContext["user"]>;
function createAuthContext(): TrpcContext {
const user: AuthenticatedUser = {
id: 1,
username: "test-user",
passwordHash: null,
email: "test@example.com",
name: "Test User",
role: "admin",
isActive: 1,
mustChangePassword: 0,
sessionVersion: 0,
createdAt: new Date(),
updatedAt: new Date(),
lastLoginAt: 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: "该车型下已存在同名检测任务。",
});
});
});