Files
openclaw/src/web/auto-reply.web-auto-reply.monitor-logging.test.ts
2026-02-22 20:04:51 +00:00

90 lines
2.6 KiB
TypeScript

import crypto from "node:crypto";
import fs from "node:fs/promises";
import { describe, expect, it, vi } from "vitest";
import { setLoggerOverride } from "../logging.js";
import {
createWebListenerFactoryCapture,
installWebAutoReplyTestHomeHooks,
installWebAutoReplyUnitTestHooks,
} from "./auto-reply.test-harness.js";
import { monitorWebChannel } from "./auto-reply/monitor.js";
installWebAutoReplyTestHomeHooks();
describe("web auto-reply monitor logging", () => {
installWebAutoReplyUnitTestHooks();
it("emits heartbeat logs with connection metadata", async () => {
vi.useFakeTimers();
const logPath = `/tmp/openclaw-heartbeat-${crypto.randomUUID()}.log`;
setLoggerOverride({ level: "trace", file: logPath });
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
const controller = new AbortController();
const listenerFactory = vi.fn(async () => {
const onClose = new Promise<void>(() => {
// never resolves; abort will short-circuit
});
return { close: vi.fn(), onClose };
});
const run = monitorWebChannel(
false,
listenerFactory as never,
true,
async () => ({ text: "ok" }),
runtime as never,
controller.signal,
{
heartbeatSeconds: 1,
reconnect: { initialMs: 5, maxMs: 5, maxAttempts: 1, factor: 1.1 },
},
);
await vi.advanceTimersByTimeAsync(1_000);
controller.abort();
await vi.runAllTimersAsync();
await run.catch(() => {});
const content = await fs.readFile(logPath, "utf-8");
expect(content).toMatch(/web-heartbeat/);
expect(content).toMatch(/connectionId/);
expect(content).toMatch(/messagesHandled/);
});
it("logs outbound replies to file", async () => {
const logPath = `/tmp/openclaw-log-test-${crypto.randomUUID()}.log`;
setLoggerOverride({ level: "trace", file: logPath });
const capture = createWebListenerFactoryCapture();
const resolver = vi.fn().mockResolvedValue({ text: "auto" });
await monitorWebChannel(false, capture.listenerFactory as never, false, resolver as never);
const capturedOnMessage = capture.getOnMessage();
expect(capturedOnMessage).toBeDefined();
await capturedOnMessage?.({
body: "hello",
from: "+1",
conversationId: "+1",
to: "+2",
accountId: "default",
chatType: "direct",
chatId: "+1",
id: "msg1",
sendComposing: vi.fn(),
reply: vi.fn(),
sendMedia: vi.fn(),
});
const content = await fs.readFile(logPath, "utf-8");
expect(content).toMatch(/web-auto-reply/);
expect(content).toMatch(/auto/);
});
});