test: extend typing idle coverage
This commit is contained in:
@@ -30,4 +30,25 @@ describe("typing controller", () => {
|
|||||||
vi.advanceTimersByTime(2_000);
|
vi.advanceTimersByTime(2_000);
|
||||||
expect(onReplyStart).toHaveBeenCalledTimes(4);
|
expect(onReplyStart).toHaveBeenCalledTimes(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps typing until both idle and run completion are set", async () => {
|
||||||
|
vi.useFakeTimers();
|
||||||
|
const onReplyStart = vi.fn(async () => {});
|
||||||
|
const typing = createTypingController({
|
||||||
|
onReplyStart,
|
||||||
|
typingIntervalSeconds: 1,
|
||||||
|
typingTtlMs: 30_000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await typing.startTypingLoop();
|
||||||
|
expect(onReplyStart).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
typing.markDispatchIdle();
|
||||||
|
vi.advanceTimersByTime(2_000);
|
||||||
|
expect(onReplyStart).toHaveBeenCalledTimes(3);
|
||||||
|
|
||||||
|
typing.markRunComplete();
|
||||||
|
vi.advanceTimersByTime(2_000);
|
||||||
|
expect(onReplyStart).toHaveBeenCalledTimes(3);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -244,6 +244,63 @@ describe("partial reply gating", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("typing controller idle", () => {
|
||||||
|
it("marks dispatch idle after replies flush", async () => {
|
||||||
|
const markDispatchIdle = vi.fn();
|
||||||
|
const typingMock = {
|
||||||
|
onReplyStart: vi.fn(async () => {}),
|
||||||
|
startTypingLoop: vi.fn(async () => {}),
|
||||||
|
startTypingOnText: vi.fn(async () => {}),
|
||||||
|
refreshTypingTtl: vi.fn(),
|
||||||
|
markRunComplete: vi.fn(),
|
||||||
|
markDispatchIdle,
|
||||||
|
cleanup: vi.fn(),
|
||||||
|
};
|
||||||
|
const reply = vi.fn().mockResolvedValue(undefined);
|
||||||
|
const sendComposing = vi.fn().mockResolvedValue(undefined);
|
||||||
|
const sendMedia = vi.fn().mockResolvedValue(undefined);
|
||||||
|
|
||||||
|
const replyResolver = vi.fn().mockImplementation(async (_ctx, opts) => {
|
||||||
|
opts?.onTypingController?.(typingMock);
|
||||||
|
return { text: "final reply" };
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockConfig: ClawdbotConfig = {
|
||||||
|
whatsapp: {
|
||||||
|
allowFrom: ["*"],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
setLoadConfigMock(mockConfig);
|
||||||
|
|
||||||
|
await monitorWebProvider(
|
||||||
|
false,
|
||||||
|
async ({ onMessage }) => {
|
||||||
|
await onMessage({
|
||||||
|
id: "m1",
|
||||||
|
from: "+1000",
|
||||||
|
conversationId: "+1000",
|
||||||
|
to: "+2000",
|
||||||
|
body: "hello",
|
||||||
|
timestamp: Date.now(),
|
||||||
|
chatType: "direct",
|
||||||
|
chatId: "direct:+1000",
|
||||||
|
sendComposing,
|
||||||
|
reply,
|
||||||
|
sendMedia,
|
||||||
|
});
|
||||||
|
return { close: vi.fn().mockResolvedValue(undefined) };
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
replyResolver,
|
||||||
|
);
|
||||||
|
|
||||||
|
resetLoadConfigMock();
|
||||||
|
|
||||||
|
expect(markDispatchIdle).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("web auto-reply", () => {
|
describe("web auto-reply", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
|
|||||||
Reference in New Issue
Block a user