test: add tests for printCronList defensive jobId/id handling
Tests cover: - Standard id property - jobId fallback (Gateway API variant) - jobId preferred over id when both present - No crash when both id and jobId are missing - Empty job list and multiple jobs - parseDurationMs unit tests
This commit is contained in:
parent
807624a812
commit
e5c0d2eeeb
105
src/cli/cron-cli/shared.test.ts
Normal file
105
src/cli/cron-cli/shared.test.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { CronJob } from "../../cron/types.js";
|
||||
import { parseDurationMs, printCronList } from "./shared.js";
|
||||
|
||||
// Minimal CronJob factory
|
||||
function makeCronJob(overrides: Partial<CronJob> & Record<string, unknown> = {}): CronJob {
|
||||
return {
|
||||
id: "test-id-000",
|
||||
name: "test-job",
|
||||
enabled: true,
|
||||
createdAtMs: Date.now(),
|
||||
updatedAtMs: Date.now(),
|
||||
schedule: { kind: "every", everyMs: 60_000 },
|
||||
sessionTarget: "isolated",
|
||||
wakeMode: "prompt",
|
||||
payload: { prompt: "hello" },
|
||||
state: {},
|
||||
...overrides,
|
||||
} as CronJob;
|
||||
}
|
||||
|
||||
describe("printCronList", () => {
|
||||
const captureLog = () => {
|
||||
const lines: string[] = [];
|
||||
const runtime = {
|
||||
log: vi.fn((msg: string) => lines.push(msg)),
|
||||
error: vi.fn(),
|
||||
};
|
||||
return { lines, runtime };
|
||||
};
|
||||
|
||||
it("prints 'No cron jobs.' for empty list", () => {
|
||||
const { runtime } = captureLog();
|
||||
printCronList([], runtime as never);
|
||||
expect(runtime.log).toHaveBeenCalledWith("No cron jobs.");
|
||||
});
|
||||
|
||||
it("handles job with standard id property", () => {
|
||||
const { lines, runtime } = captureLog();
|
||||
const job = makeCronJob({ id: "abc-123" });
|
||||
printCronList([job], runtime as never);
|
||||
// Header + 1 job line
|
||||
expect(lines).toHaveLength(2);
|
||||
expect(lines[1]).toContain("abc-123");
|
||||
});
|
||||
|
||||
it("handles job with jobId instead of id (Gateway API variant)", () => {
|
||||
const { lines, runtime } = captureLog();
|
||||
// Simulate Gateway returning jobId instead of id
|
||||
const job = makeCronJob({ id: undefined as unknown as string, jobId: "gateway-456" } as never);
|
||||
printCronList([job], runtime as never);
|
||||
expect(lines).toHaveLength(2);
|
||||
expect(lines[1]).toContain("gateway-456");
|
||||
});
|
||||
|
||||
it("prefers jobId over id when both are present", () => {
|
||||
const { lines, runtime } = captureLog();
|
||||
const job = makeCronJob({ id: "fallback-id", jobId: "preferred-jobid" } as never);
|
||||
printCronList([job], runtime as never);
|
||||
expect(lines).toHaveLength(2);
|
||||
expect(lines[1]).toContain("preferred-jobid");
|
||||
expect(lines[1]).not.toContain("fallback-id");
|
||||
});
|
||||
|
||||
it("does not crash when both id and jobId are missing", () => {
|
||||
const { lines, runtime } = captureLog();
|
||||
const job = makeCronJob({ id: undefined as unknown as string });
|
||||
printCronList([job], runtime as never);
|
||||
// Should not throw and should still print a line
|
||||
expect(lines).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("prints multiple jobs", () => {
|
||||
const { lines, runtime } = captureLog();
|
||||
const jobs = [
|
||||
makeCronJob({ id: "job-1", name: "first" }),
|
||||
makeCronJob({ id: "job-2", name: "second" }),
|
||||
];
|
||||
printCronList(jobs, runtime as never);
|
||||
// Header + 2 job lines
|
||||
expect(lines).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("parseDurationMs", () => {
|
||||
it.each([
|
||||
["1s", 1000],
|
||||
["5m", 300_000],
|
||||
["2h", 7_200_000],
|
||||
["1d", 86_400_000],
|
||||
["500ms", 500],
|
||||
["1.5s", 1500],
|
||||
])("parses %s → %d", (input, expected) => {
|
||||
expect(parseDurationMs(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it("returns null for empty string", () => {
|
||||
expect(parseDurationMs("")).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null for invalid input", () => {
|
||||
expect(parseDurationMs("abc")).toBeNull();
|
||||
expect(parseDurationMs("-5s")).toBeNull();
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user