import type { MessageBlock, RoutineEventBlock } from "@rakazo/contracts"; import { describe, expect, it } from "vitest"; import { blocksToAgentHistoryText } from "./attachments.js"; import { isRoutineEventMessage, markRoutineEventsRemoved, routineScheduleShape, } from "./routine-events.js"; const line: RoutineEventBlock = { kind: "event", event: "routine.created", routineId: "routine-1", botId: "bot-1", name: "Weekly plan", crons: ["0 18 * * 1"], timezone: "Europe/Berlin", nextRunAt: "2026-10-05T16:00:00.000Z", }; describe("routine lines", () => { it("are messages of their own", () => { expect(isRoutineEventMessage([line])).toBe(true); expect(isRoutineEventMessage([line, { kind: "text", text: "Done." }])).toBe(false); expect(isRoutineEventMessage([])).toBe(false); }); it("are marked removed once and leave other routines alone", () => { const other: MessageBlock = { ...line, routineId: "routine-2" }; const marked = markRoutineEventsRemoved([line, other], "routine-1"); expect(marked).toEqual([{ ...line, removed: true }, other]); expect(markRoutineEventsRemoved(marked!, "routine-1")).toBeNull(); expect(markRoutineEventsRemoved([other], "routine-1")).toBeNull(); }); it("tell a later turn what was set up, changed or removed", () => { expect(blocksToAgentHistoryText([line])).toBe( "[routine set up: Weekly plan (Every Monday at 6:00 PM, Europe/Berlin)]", ); expect( blocksToAgentHistoryText([ { ...line, event: "routine.updated", crons: ["@once"], name: "Call mum" }, ]), ).toBe("[routine updated: Call mum (once at 2026-10-05T16:00:00.000Z)]"); expect(blocksToAgentHistoryText([{ ...line, removed: true }])).toBe( "[routine removed: Weekly plan]", ); }); }); describe("routineScheduleShape", () => { it("reads the schedules people say out loud", () => { expect(routineScheduleShape(["@once"])).toEqual({ kind: "once" }); expect(routineScheduleShape(["0 8 * * *"])).toEqual({ kind: "daily", hour: 8, minute: 0 }); expect(routineScheduleShape(["30 7 * * 1-5"])).toEqual({ kind: "weekdays", hour: 7, minute: 30, }); expect(routineScheduleShape(["0 18 * * 7"])).toEqual({ kind: "weekly", weekday: 0, hour: 18, minute: 0, }); expect(routineScheduleShape(["0 9 1 * *"])).toEqual({ kind: "monthly", day: 1, hour: 9, minute: 0, }); expect(routineScheduleShape(["*/15 * * * *"])).toEqual({ kind: "minutes", every: 15 }); expect(routineScheduleShape(["0 */2 * * *"])).toEqual({ kind: "hours", every: 2 }); expect(routineScheduleShape(["0 * * * *"])).toEqual({ kind: "hourly" }); }); it("leaves everything else to the next run", () => { for (const crons of [["0 9 * * 1,3"], ["0 9 * 1 *"], ["0 9 * * *", "0 18 * * *"], ["nope"]]) { expect(routineScheduleShape(crons)).toEqual({ kind: "other" }); } }); });