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); }); });