From c9a7c77b24ffd40fe3b208aacb90e38cae7515f0 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 23 Jan 2026 23:22:08 +0000 Subject: [PATCH] test: cover typing and history helpers --- src/auto-reply/reply/history.test.ts | 44 ++++++++++++++++++++++++++++ src/channels/typing.test.ts | 42 ++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/channels/typing.test.ts diff --git a/src/auto-reply/reply/history.test.ts b/src/auto-reply/reply/history.test.ts index addbf5860..7991731da 100644 --- a/src/auto-reply/reply/history.test.ts +++ b/src/auto-reply/reply/history.test.ts @@ -5,7 +5,9 @@ import { buildHistoryContextFromEntries, buildHistoryContextFromMap, buildPendingHistoryContextFromMap, + clearHistoryEntriesIfEnabled, HISTORY_CONTEXT_MARKER, + recordPendingHistoryEntryIfEnabled, } from "./history.js"; import { CURRENT_MESSAGE_MARKER } from "./mentions.js"; @@ -105,4 +107,46 @@ describe("history helpers", () => { expect(result).toContain(CURRENT_MESSAGE_MARKER); expect(result).toContain("current"); }); + + it("records pending entries only when enabled", () => { + const historyMap = new Map(); + + recordPendingHistoryEntryIfEnabled({ + historyMap, + historyKey: "group", + limit: 0, + entry: { sender: "A", body: "one" }, + }); + expect(historyMap.get("group")).toEqual(undefined); + + recordPendingHistoryEntryIfEnabled({ + historyMap, + historyKey: "group", + limit: 2, + entry: null, + }); + expect(historyMap.get("group")).toEqual(undefined); + + recordPendingHistoryEntryIfEnabled({ + historyMap, + historyKey: "group", + limit: 2, + entry: { sender: "B", body: "two" }, + }); + expect(historyMap.get("group")?.map((entry) => entry.body)).toEqual(["two"]); + }); + + it("clears history entries only when enabled", () => { + const historyMap = new Map(); + historyMap.set("group", [ + { sender: "A", body: "one" }, + { sender: "B", body: "two" }, + ]); + + clearHistoryEntriesIfEnabled({ historyMap, historyKey: "group", limit: 0 }); + expect(historyMap.get("group")?.map((entry) => entry.body)).toEqual(["one", "two"]); + + clearHistoryEntriesIfEnabled({ historyMap, historyKey: "group", limit: 2 }); + expect(historyMap.get("group")).toEqual([]); + }); }); diff --git a/src/channels/typing.test.ts b/src/channels/typing.test.ts new file mode 100644 index 000000000..42080b3c1 --- /dev/null +++ b/src/channels/typing.test.ts @@ -0,0 +1,42 @@ +import { describe, expect, it, vi } from "vitest"; + +import { createTypingCallbacks } from "./typing.js"; + +const flush = () => new Promise((resolve) => setTimeout(resolve, 0)); + +describe("createTypingCallbacks", () => { + it("invokes start on reply start", async () => { + const start = vi.fn().mockResolvedValue(undefined); + const onStartError = vi.fn(); + const callbacks = createTypingCallbacks({ start, onStartError }); + + await callbacks.onReplyStart(); + + expect(start).toHaveBeenCalledTimes(1); + expect(onStartError).not.toHaveBeenCalled(); + }); + + it("reports start errors", async () => { + const start = vi.fn().mockRejectedValue(new Error("fail")); + const onStartError = vi.fn(); + const callbacks = createTypingCallbacks({ start, onStartError }); + + await callbacks.onReplyStart(); + + expect(onStartError).toHaveBeenCalledTimes(1); + }); + + it("invokes stop on idle and reports stop errors", async () => { + const start = vi.fn().mockResolvedValue(undefined); + const stop = vi.fn().mockRejectedValue(new Error("stop")); + const onStartError = vi.fn(); + const onStopError = vi.fn(); + const callbacks = createTypingCallbacks({ start, stop, onStartError, onStopError }); + + callbacks.onIdle?.(); + await flush(); + + expect(stop).toHaveBeenCalledTimes(1); + expect(onStopError).toHaveBeenCalledTimes(1); + }); +});