| import "./test-helpers.js"; |
| import { describe, expect, it, vi } from "vitest"; |
| import type { OpenClawConfig } from "../config/config.js"; |
| import { monitorWebChannel } from "./auto-reply.js"; |
| import { |
| installWebAutoReplyTestHomeHooks, |
| installWebAutoReplyUnitTestHooks, |
| resetLoadConfigMock, |
| setLoadConfigMock, |
| } from "./auto-reply.test-harness.js"; |
|
|
| installWebAutoReplyTestHomeHooks(); |
|
|
| describe("typing controller idle", () => { |
| installWebAutoReplyUnitTestHooks(); |
|
|
| 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(), |
| isActive: vi.fn(() => false), |
| 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: OpenClawConfig = { |
| channels: { whatsapp: { allowFrom: ["*"] } }, |
| }; |
|
|
| setLoadConfigMock(mockConfig); |
|
|
| await monitorWebChannel( |
| 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(); |
| }); |
| }); |
|
|