Files
2026-07-13 13:32:57 +08:00

61 lines
2.0 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { ServiceValidationError } from "~/v3/services/common.server";
import { assertNoDuplicateTaskIds } from "~/v3/services/duplicateTaskIds.server";
function task(partial: {
id: string;
filePath?: string;
exportName?: string;
triggerSource?: string;
}) {
return {
filePath: "src/trigger/example.ts",
exportName: "exampleTask",
...partial,
} as any;
}
describe("assertNoDuplicateTaskIds", () => {
it("does not throw when all task ids are unique", () => {
const tasks = [task({ id: "a" }), task({ id: "b" }), task({ id: "c" })];
expect(() => assertNoDuplicateTaskIds(tasks)).not.toThrow();
});
it("throws a ServiceValidationError when a task id is duplicated", () => {
const tasks = [task({ id: "a" }), task({ id: "a" })];
expect(() => assertNoDuplicateTaskIds(tasks)).toThrow(ServiceValidationError);
});
it("reports a 400 and names the duplicate id and its files", () => {
const tasks = [
task({ id: "report", filePath: "src/trigger/report.ts" }),
task({ id: "report", filePath: "src/trigger/scheduled.ts" }),
];
let error: unknown;
try {
assertNoDuplicateTaskIds(tasks);
} catch (e) {
error = e;
}
expect(error).toBeInstanceOf(ServiceValidationError);
const validationError = error as ServiceValidationError;
expect(validationError.status).toBe(400);
expect(validationError.message).toContain("report");
expect(validationError.message).toContain("src/trigger/report.ts");
expect(validationError.message).toContain("src/trigger/scheduled.ts");
});
it("detects duplicates across different task types (a schedule and a regular task sharing an id)", () => {
const tasks = [
task({ id: "report", triggerSource: undefined, filePath: "src/trigger/report.ts" }),
task({ id: "report", triggerSource: "schedule", filePath: "src/trigger/scheduled.ts" }),
];
expect(() => assertNoDuplicateTaskIds(tasks)).toThrow(ServiceValidationError);
});
});