import { describe, expect, it } from "vitest"; import { routineRevisionSnapshotV1Schema, routineVariableSchema, updateRoutineSchema, } from "./routine.js"; const routineId = "11111111-1111-4111-8111-111111111111"; const companyId = "22222222-2222-4222-8222-222222222222"; const triggerId = "33333333-3333-4333-8333-333333333333"; const baseRevisionId = "44444444-4444-4444-8444-444444444444"; describe("routine validators", () => { it.each(["bearer", "app_webhook", "fireflies_hmac"])("accepts versioned routine revision snapshots with %s trigger metadata", (signingMode) => { const parsed = routineRevisionSnapshotV1Schema.parse({ version: 1, routine: { id: routineId, companyId, projectId: null, goalId: null, parentIssueId: null, title: "Daily triage", description: null, assigneeAgentId: null, priority: "medium", status: "active", concurrencyPolicy: "coalesce_if_active", catchUpPolicy: "skip_missed", variables: [], }, triggers: [{ id: triggerId, kind: "webhook", label: "Inbound", enabled: true, cronExpression: null, timezone: null, publicId: "routine_webhook_123", signingMode, replayWindowSec: 300, }], }); expect(parsed.triggers[0]?.publicId).toBe("routine_webhook_123"); expect(parsed.routine.activityGatePolicy).toBe("always"); expect(parsed.routine.activityGateScope).toBe("company"); }); it("rejects secret-bearing trigger fields in routine revision snapshots", () => { expect(() => routineRevisionSnapshotV1Schema.parse({ version: 1, routine: { id: routineId, companyId, projectId: null, goalId: null, parentIssueId: null, title: "Daily triage", description: null, assigneeAgentId: null, priority: "medium", status: "active", concurrencyPolicy: "coalesce_if_active", catchUpPolicy: "skip_missed", variables: [], }, triggers: [{ id: triggerId, kind: "webhook", label: "Inbound", enabled: true, cronExpression: null, timezone: null, publicId: "routine_webhook_123", signingMode: "bearer", replayWindowSec: 300, secretId: "55555555-5555-4555-8555-555555555555", }], })).toThrow(); }); it("accepts optional base revision ids on routine updates", () => { expect(updateRoutineSchema.parse({ title: "Daily triage", baseRevisionId, }).baseRevisionId).toBe(baseRevisionId); }); it("validates routine activity gate values", () => { expect(updateRoutineSchema.parse({ activityGatePolicy: "require_external_activity", activityGateScope: "project", })).toMatchObject({ activityGatePolicy: "require_external_activity", activityGateScope: "project", }); expect(() => updateRoutineSchema.parse({ activityGatePolicy: "when_busy" })).toThrow(); expect(() => updateRoutineSchema.parse({ activityGateScope: "agent" })).toThrow(); }); it("accepts date variables with valid YYYY-MM-DD defaults", () => { expect(routineVariableSchema.parse({ name: "startDate", type: "date", defaultValue: "2024-02-29", })).toMatchObject({ name: "startDate", type: "date", defaultValue: "2024-02-29", }); }); it("rejects date variables with non-calendar or non-string defaults", () => { expect(() => routineVariableSchema.parse({ name: "startDate", type: "date", defaultValue: "2024-02-30", })).toThrow(/YYYY-MM-DD/); expect(() => routineVariableSchema.parse({ name: "startDate", type: "date", defaultValue: 20240229, })).toThrow(/YYYY-MM-DD/); }); });