mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 15:47:28 +00:00
test: clear ui cron broad matchers
This commit is contained in:
@@ -70,6 +70,35 @@ function findRequestCall(
|
||||
return call;
|
||||
}
|
||||
|
||||
function requireRecord(value: unknown, label: string): Record<string, unknown> {
|
||||
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
||||
throw new Error(`expected ${label} to be a record`);
|
||||
}
|
||||
return value as Record<string, unknown>;
|
||||
}
|
||||
|
||||
function expectRecordFields(record: Record<string, unknown>, fields: Record<string, unknown>) {
|
||||
for (const [key, value] of Object.entries(fields)) {
|
||||
expect(record[key]).toEqual(value);
|
||||
}
|
||||
}
|
||||
|
||||
function expectNestedRecordFields(
|
||||
record: Record<string, unknown>,
|
||||
key: string,
|
||||
fields: Record<string, unknown>,
|
||||
) {
|
||||
expectRecordFields(requireRecord(record[key], key), fields);
|
||||
}
|
||||
|
||||
function requestPayload(call: readonly [method: string, payload?: unknown]) {
|
||||
return requireRecord(call[1], `${call[0]} payload`);
|
||||
}
|
||||
|
||||
function requestPatch(call: readonly [method: string, payload?: unknown]) {
|
||||
return requireRecord(requestPayload(call).patch, `${call[0]} patch`);
|
||||
}
|
||||
|
||||
describe("cron controller", () => {
|
||||
it("loads model suggestions from the configured model view", async () => {
|
||||
const request = vi.fn(async () => ({
|
||||
@@ -150,9 +179,13 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const addCall = findRequestCall(request.mock.calls, "cron.add");
|
||||
expect(addCall[1]).toMatchObject({
|
||||
const payload = requestPayload(addCall);
|
||||
expectRecordFields(payload, {
|
||||
name: "webhook job",
|
||||
delivery: { mode: "webhook", to: "https://example.invalid/cron" },
|
||||
});
|
||||
expectNestedRecordFields(payload, "delivery", {
|
||||
mode: "webhook",
|
||||
to: "https://example.invalid/cron",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -189,9 +222,13 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const addCall = findRequestCall(request.mock.calls, "cron.add");
|
||||
expect(addCall[1]).toMatchObject({
|
||||
const payload = requestPayload(addCall);
|
||||
expectRecordFields(payload, {
|
||||
sessionKey: "agent:ops:main",
|
||||
delivery: { mode: "announce", accountId: "ops-bot" },
|
||||
});
|
||||
expectNestedRecordFields(payload, "delivery", {
|
||||
mode: "announce",
|
||||
accountId: "ops-bot",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -228,8 +265,8 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const addCall = findRequestCall(request.mock.calls, "cron.add");
|
||||
expect(addCall[1]).toMatchObject({
|
||||
delivery: { mode: "announce" },
|
||||
expectRecordFields(requireRecord(requestPayload(addCall).delivery, "delivery"), {
|
||||
mode: "announce",
|
||||
});
|
||||
expect(
|
||||
(addCall[1] as { delivery?: { channel?: string } } | undefined)?.delivery?.channel,
|
||||
@@ -267,8 +304,9 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const addCall = findRequestCall(request.mock.calls, "cron.add");
|
||||
expect(addCall[1]).toMatchObject({
|
||||
payload: { kind: "agentTurn", lightContext: true },
|
||||
expectNestedRecordFields(requestPayload(addCall), "payload", {
|
||||
kind: "agentTurn",
|
||||
lightContext: true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -391,7 +429,7 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const addCall = findRequestCall(request.mock.calls, "cron.add");
|
||||
expect(addCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(addCall), {
|
||||
name: "main job",
|
||||
});
|
||||
// Delivery is explicitly sent as { mode: "none" } to clear the announce delivery on the backend.
|
||||
@@ -440,17 +478,17 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-1",
|
||||
patch: {
|
||||
name: "edited job",
|
||||
description: "",
|
||||
agentId: null,
|
||||
deleteAfterRun: false,
|
||||
schedule: { kind: "cron", expr: "0 8 * * *", staggerMs: 0 },
|
||||
payload: { kind: "systemEvent", text: "updated" },
|
||||
delivery: { mode: "none" },
|
||||
},
|
||||
});
|
||||
expectRecordFields(requestPatch(updateCall), {
|
||||
name: "edited job",
|
||||
description: "",
|
||||
agentId: null,
|
||||
deleteAfterRun: false,
|
||||
schedule: { kind: "cron", expr: "0 8 * * *", staggerMs: 0 },
|
||||
payload: { kind: "systemEvent", text: "updated" },
|
||||
delivery: { mode: "none" },
|
||||
});
|
||||
expect(state.cronEditingJobId).toBeNull();
|
||||
});
|
||||
@@ -504,14 +542,12 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-clear-account-id",
|
||||
patch: {
|
||||
delivery: {
|
||||
mode: "announce",
|
||||
accountId: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
expectRecordFields(requireRecord(requestPatch(updateCall).delivery, "delivery"), {
|
||||
mode: "announce",
|
||||
accountId: "",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -587,11 +623,12 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-implicit-delivery",
|
||||
patch: {
|
||||
delivery: { mode: "announce", to: "123" },
|
||||
},
|
||||
});
|
||||
expectRecordFields(requireRecord(requestPatch(updateCall).delivery, "delivery"), {
|
||||
mode: "announce",
|
||||
to: "123",
|
||||
});
|
||||
expect(
|
||||
(updateCall[1] as { patch?: { delivery?: { channel?: string } } } | undefined)?.patch
|
||||
@@ -676,19 +713,23 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-2",
|
||||
patch: {
|
||||
schedule: { kind: "cron", expr: "0 9 * * *", staggerMs: 30_000 },
|
||||
payload: {
|
||||
kind: "agentTurn",
|
||||
message: "run it",
|
||||
model: "opus",
|
||||
thinking: "low",
|
||||
},
|
||||
delivery: { mode: "announce", bestEffort: true },
|
||||
});
|
||||
const patch = requestPatch(updateCall);
|
||||
expectRecordFields(patch, {
|
||||
schedule: { kind: "cron", expr: "0 9 * * *", staggerMs: 30_000 },
|
||||
payload: {
|
||||
kind: "agentTurn",
|
||||
message: "run it",
|
||||
model: "opus",
|
||||
thinking: "low",
|
||||
},
|
||||
});
|
||||
expectNestedRecordFields(patch, "delivery", {
|
||||
mode: "announce",
|
||||
bestEffort: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("sends lightContext=false in cron.update when clearing prior light-context setting", async () => {
|
||||
@@ -735,14 +776,12 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-clear-light",
|
||||
patch: {
|
||||
payload: {
|
||||
kind: "agentTurn",
|
||||
lightContext: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
expectRecordFields(requireRecord(requestPatch(updateCall).payload, "payload"), {
|
||||
kind: "agentTurn",
|
||||
lightContext: false,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -778,18 +817,16 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-alert",
|
||||
patch: {
|
||||
failureAlert: {
|
||||
after: 3,
|
||||
cooldownMs: 120_000,
|
||||
channel: "telegram",
|
||||
to: "123456",
|
||||
mode: "announce",
|
||||
accountId: undefined,
|
||||
},
|
||||
},
|
||||
});
|
||||
expectRecordFields(requireRecord(requestPatch(updateCall).failureAlert, "failureAlert"), {
|
||||
after: 3,
|
||||
cooldownMs: 120_000,
|
||||
channel: "telegram",
|
||||
to: "123456",
|
||||
mode: "announce",
|
||||
accountId: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -824,15 +861,13 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-alert-mode",
|
||||
patch: {
|
||||
failureAlert: {
|
||||
after: 1,
|
||||
mode: "webhook",
|
||||
accountId: "bot-a",
|
||||
},
|
||||
},
|
||||
});
|
||||
expectRecordFields(requireRecord(requestPatch(updateCall).failureAlert, "failureAlert"), {
|
||||
after: 1,
|
||||
mode: "webhook",
|
||||
accountId: "bot-a",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -872,15 +907,13 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-alert-implicit-channel",
|
||||
patch: {
|
||||
failureAlert: {
|
||||
after: 2,
|
||||
to: "123",
|
||||
mode: "announce",
|
||||
},
|
||||
},
|
||||
});
|
||||
expectRecordFields(requireRecord(requestPatch(updateCall).failureAlert, "failureAlert"), {
|
||||
after: 2,
|
||||
to: "123",
|
||||
mode: "announce",
|
||||
});
|
||||
expect(
|
||||
(updateCall[1] as { patch?: { failureAlert?: { channel?: string } } } | undefined)?.patch
|
||||
@@ -963,15 +996,13 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-alert-no-cooldown",
|
||||
patch: {
|
||||
failureAlert: {
|
||||
after: 3,
|
||||
channel: "telegram",
|
||||
to: "123456",
|
||||
},
|
||||
},
|
||||
});
|
||||
expectRecordFields(requireRecord(requestPatch(updateCall).failureAlert, "failureAlert"), {
|
||||
after: 3,
|
||||
channel: "telegram",
|
||||
to: "123456",
|
||||
});
|
||||
expect(
|
||||
(updateCall[1] as { patch?: { failureAlert?: { cooldownMs?: number } } })?.patch
|
||||
@@ -1007,10 +1038,10 @@ describe("cron controller", () => {
|
||||
await addCronJob(state);
|
||||
|
||||
const updateCall = findRequestCall(request.mock.calls, "cron.update");
|
||||
expect(updateCall[1]).toMatchObject({
|
||||
expectRecordFields(requestPayload(updateCall), {
|
||||
id: "job-no-alert",
|
||||
patch: { failureAlert: false },
|
||||
});
|
||||
expect(requestPatch(updateCall).failureAlert).toBe(false);
|
||||
});
|
||||
|
||||
it("maps cron stagger, model, thinking, and best effort into form", () => {
|
||||
@@ -1109,7 +1140,7 @@ describe("cron controller", () => {
|
||||
});
|
||||
await addCronJob(state);
|
||||
expect(request).not.toHaveBeenCalled();
|
||||
expect(state.cronFieldErrors).toMatchObject({
|
||||
expectRecordFields(state.cronFieldErrors, {
|
||||
name: "cron.errors.nameRequired",
|
||||
payloadText: "cron.errors.agentMessageRequired",
|
||||
});
|
||||
@@ -1215,7 +1246,7 @@ describe("cron controller", () => {
|
||||
it("loads paged jobs with query/filter/sort params", async () => {
|
||||
const request = vi.fn(async (method: string, payload?: unknown) => {
|
||||
if (method === "cron.list") {
|
||||
expect(payload).toMatchObject({
|
||||
expectRecordFields(requireRecord(payload, "cron.list payload"), {
|
||||
limit: 50,
|
||||
offset: 0,
|
||||
query: "daily",
|
||||
@@ -1346,7 +1377,10 @@ describe("cron controller", () => {
|
||||
it("runs cron job in due mode when requested", async () => {
|
||||
const request = vi.fn(async (method: string, payload?: unknown) => {
|
||||
if (method === "cron.run") {
|
||||
expect(payload).toMatchObject({ id: "job-due", mode: "due" });
|
||||
expectRecordFields(requireRecord(payload, "cron.run payload"), {
|
||||
id: "job-due",
|
||||
mode: "due",
|
||||
});
|
||||
return { ok: true };
|
||||
}
|
||||
if (method === "cron.runs") {
|
||||
|
||||
Reference in New Issue
Block a user