Files
horus-3d/tests/unit/cronSelectors.test.ts
Luke The Dev 4fa4f13558 First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-19 23:14:04 -05:00

105 lines
3.7 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
filterCronJobsForAgent,
formatCronJobDisplay,
formatCronPayload,
formatCronSchedule,
resolveLatestCronJobForAgent,
} from "@/lib/cron/types";
import type { CronJobSummary } from "@/lib/cron/types";
const buildJob = (input: {
id: string;
agentId?: string;
updatedAtMs: number;
}): CronJobSummary => ({
id: input.id,
name: input.id,
enabled: true,
updatedAtMs: input.updatedAtMs,
schedule: { kind: "every", everyMs: 60_000 },
sessionTarget: "isolated",
wakeMode: "next-heartbeat",
payload: { kind: "agentTurn", message: "hello" },
state: {},
...(input.agentId ? { agentId: input.agentId } : {}),
});
describe("cron selectors", () => {
it("filters_jobs_to_selected_agent", () => {
const jobs = [
buildJob({ id: "one", agentId: "agent-1", updatedAtMs: 10 }),
buildJob({ id: "two", agentId: "agent-2", updatedAtMs: 20 }),
buildJob({ id: "three", updatedAtMs: 30 }),
];
expect(filterCronJobsForAgent(jobs, "agent-1").map((job) => job.id)).toEqual(["one"]);
expect(filterCronJobsForAgent(jobs, "agent-2").map((job) => job.id)).toEqual(["two"]);
expect(filterCronJobsForAgent(jobs, "missing")).toEqual([]);
});
it("resolves_latest_agent_job_by_updated_at", () => {
const jobs = [
buildJob({ id: "older", agentId: "agent-1", updatedAtMs: 10 }),
buildJob({ id: "newer", agentId: "agent-1", updatedAtMs: 30 }),
buildJob({ id: "other", agentId: "agent-2", updatedAtMs: 40 }),
];
expect(resolveLatestCronJobForAgent(jobs, "agent-1")?.id).toBe("newer");
expect(resolveLatestCronJobForAgent(jobs, "agent-2")?.id).toBe("other");
expect(resolveLatestCronJobForAgent(jobs, "missing")).toBeNull();
});
it("matches_agent_ids_after_trimming_whitespace", () => {
const jobs = [
buildJob({ id: "trimmed", agentId: "agent-1", updatedAtMs: 20 }),
buildJob({ id: "other", agentId: "agent-2", updatedAtMs: 30 }),
];
expect(filterCronJobsForAgent(jobs, " agent-1 ").map((job) => job.id)).toEqual(["trimmed"]);
expect(resolveLatestCronJobForAgent(jobs, " agent-1 ")?.id).toBe("trimmed");
});
});
describe("cron formatting", () => {
it("formats_every_schedule_with_h_m_s_ms_suffixes", () => {
expect(formatCronSchedule({ kind: "every", everyMs: 3_600_000 })).toBe("Every 1h");
expect(formatCronSchedule({ kind: "every", everyMs: 60_000 })).toBe("Every 1m");
expect(formatCronSchedule({ kind: "every", everyMs: 1_000 })).toBe("Every 1s");
expect(formatCronSchedule({ kind: "every", everyMs: 1_500 })).toBe("Every 1500ms");
});
it("formats_cron_schedule_with_optional_tz", () => {
expect(formatCronSchedule({ kind: "cron", expr: "0 0 * * *" })).toBe("Cron: 0 0 * * *");
expect(formatCronSchedule({ kind: "cron", expr: "0 0 * * *", tz: "UTC" })).toBe(
"Cron: 0 0 * * * (UTC)"
);
});
it("formats_at_schedule_as_raw_when_not_parseable", () => {
expect(formatCronSchedule({ kind: "at", at: "not-a-date" })).toBe("At: not-a-date");
});
it("formats_cron_payload_text", () => {
expect(formatCronPayload({ kind: "systemEvent", text: "hello" })).toBe("hello");
expect(formatCronPayload({ kind: "agentTurn", message: "hi" })).toBe("hi");
});
it("formats_cron_job_display_as_three_lines", () => {
const job: CronJobSummary = {
id: "job-1",
name: "Job name",
enabled: true,
updatedAtMs: 10,
schedule: { kind: "every", everyMs: 60_000 },
sessionTarget: "isolated",
wakeMode: "next-heartbeat",
payload: { kind: "agentTurn", message: "hi" },
state: {},
};
expect(formatCronJobDisplay(job)).toBe("Job name\nEvery 1m\nhi");
});
});