mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-04-17 15:20:58 +00:00
- modules may declare crons: [{ schedule, name, handler }]
- handler signature (event, { db, sql, env }) matches init context
- scheduled() export in src/index.js dispatches to matching handlers with fan-out and per-handler error isolation
- registry validates cron entries and collects into registry.crons
- wrangler.toml [triggers] crons must still be populated manually by module author
60 lines
2.1 KiB
JavaScript
60 lines
2.1 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
|
import { validateCron } from "../../src/modules/validate-cron.js";
|
|
|
|
const noop = async () => {};
|
|
const base = (overrides = {}) => ({
|
|
name: "nightly",
|
|
schedule: "0 1 * * *",
|
|
handler: noop,
|
|
...overrides,
|
|
});
|
|
|
|
describe("validateCron", () => {
|
|
it("accepts a valid cron entry", () => {
|
|
expect(() => validateCron(base(), "mod")).not.toThrow();
|
|
});
|
|
|
|
it("accepts 6-field schedule (with seconds)", () => {
|
|
expect(() => validateCron(base({ schedule: "0 0 1 * * *" }), "mod")).not.toThrow();
|
|
});
|
|
|
|
it("accepts names with hyphens and underscores", () => {
|
|
expect(() => validateCron(base({ name: "my-cron_job" }), "mod")).not.toThrow();
|
|
});
|
|
|
|
it("rejects non-object entry", () => {
|
|
expect(() => validateCron(null, "mod")).toThrow(/not an object/);
|
|
expect(() => validateCron("string", "mod")).toThrow(/not an object/);
|
|
});
|
|
|
|
it("rejects name that fails pattern", () => {
|
|
expect(() => validateCron(base({ name: "Bad Name!" }), "mod")).toThrow(/name must match/);
|
|
expect(() => validateCron(base({ name: "" }), "mod")).toThrow(/name must match/);
|
|
expect(() => validateCron(base({ name: "a".repeat(33) }), "mod")).toThrow(/name must match/);
|
|
});
|
|
|
|
it("rejects empty schedule", () => {
|
|
expect(() => validateCron(base({ schedule: "" }), "mod")).toThrow(/non-empty/);
|
|
expect(() => validateCron(base({ schedule: " " }), "mod")).toThrow(/non-empty/);
|
|
});
|
|
|
|
it("rejects schedule with wrong field count", () => {
|
|
expect(() => validateCron(base({ schedule: "* * * *" }), "mod")).toThrow(/cron expression/);
|
|
expect(() => validateCron(base({ schedule: "not-a-cron" }), "mod")).toThrow(/cron expression/);
|
|
});
|
|
|
|
it("rejects non-function handler", () => {
|
|
expect(() => validateCron(base({ handler: null }), "mod")).toThrow(/handler/);
|
|
expect(() => validateCron(base({ handler: "fn" }), "mod")).toThrow(/handler/);
|
|
});
|
|
|
|
it("error messages include module name and cron name", () => {
|
|
try {
|
|
validateCron(base({ handler: null }), "trading");
|
|
} catch (err) {
|
|
expect(err.message).toContain("trading");
|
|
expect(err.message).toContain("nightly");
|
|
}
|
|
});
|
|
});
|