Files
Moltbot/src/utils/queue-helpers.test.ts
2026-02-19 07:01:54 +00:00

170 lines
3.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
applyQueueRuntimeSettings,
buildQueueSummaryPrompt,
clearQueueSummaryState,
drainCollectItemIfNeeded,
previewQueueSummaryPrompt,
} from "./queue-helpers.js";
describe("applyQueueRuntimeSettings", () => {
it("updates runtime queue settings with normalization", () => {
const target = {
mode: "followup" as const,
debounceMs: 1000,
cap: 20,
dropPolicy: "summarize" as const,
};
applyQueueRuntimeSettings({
target,
settings: {
mode: "collect",
debounceMs: -12,
cap: 9.8,
dropPolicy: "new",
},
});
expect(target).toEqual({
mode: "collect",
debounceMs: 0,
cap: 9,
dropPolicy: "new",
});
});
it("keeps existing values when optional settings are missing/invalid", () => {
const target = {
mode: "followup" as const,
debounceMs: 1000,
cap: 20,
dropPolicy: "summarize" as const,
};
applyQueueRuntimeSettings({
target,
settings: {
mode: "queue",
cap: 0,
},
});
expect(target).toEqual({
mode: "queue",
debounceMs: 1000,
cap: 20,
dropPolicy: "summarize",
});
});
});
describe("queue summary helpers", () => {
it("previewQueueSummaryPrompt does not mutate state", () => {
const state = {
dropPolicy: "summarize" as const,
droppedCount: 2,
summaryLines: ["first", "second"],
};
const prompt = previewQueueSummaryPrompt({
state,
noun: "message",
});
expect(prompt).toContain("[Queue overflow] Dropped 2 messages due to cap.");
expect(prompt).toContain("first");
expect(state).toEqual({
dropPolicy: "summarize",
droppedCount: 2,
summaryLines: ["first", "second"],
});
});
it("buildQueueSummaryPrompt clears state after rendering", () => {
const state = {
dropPolicy: "summarize" as const,
droppedCount: 1,
summaryLines: ["line"],
};
const prompt = buildQueueSummaryPrompt({
state,
noun: "announce",
});
expect(prompt).toContain("[Queue overflow] Dropped 1 announce due to cap.");
expect(state).toEqual({
dropPolicy: "summarize",
droppedCount: 0,
summaryLines: [],
});
});
it("clearQueueSummaryState resets summary counters", () => {
const state = {
dropPolicy: "summarize" as const,
droppedCount: 5,
summaryLines: ["a", "b"],
};
clearQueueSummaryState(state);
expect(state.droppedCount).toBe(0);
expect(state.summaryLines).toEqual([]);
});
});
describe("drainCollectItemIfNeeded", () => {
it("skips when neither force mode nor cross-channel routing is active", async () => {
const seen: number[] = [];
const items = [1];
const result = await drainCollectItemIfNeeded({
forceIndividualCollect: false,
isCrossChannel: false,
items,
run: async (item) => {
seen.push(item);
},
});
expect(result).toBe("skipped");
expect(seen).toEqual([]);
expect(items).toEqual([1]);
});
it("drains one item in force mode", async () => {
const seen: number[] = [];
const items = [1, 2];
const result = await drainCollectItemIfNeeded({
forceIndividualCollect: true,
isCrossChannel: false,
items,
run: async (item) => {
seen.push(item);
},
});
expect(result).toBe("drained");
expect(seen).toEqual([1]);
expect(items).toEqual([2]);
});
it("switches to force mode and returns empty when cross-channel with no queued item", async () => {
let forced = false;
const result = await drainCollectItemIfNeeded({
forceIndividualCollect: false,
isCrossChannel: true,
setForceIndividualCollect: (next) => {
forced = next;
},
items: [],
run: async () => {},
});
expect(result).toBe("empty");
expect(forced).toBe(true);
});
});