import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { afterEach, describe, expect, it, vi } from "vitest"; import { resetLogger, setLoggerOverride } from "../../logging.js"; import { logsHandlers } from "./logs.js"; const noop = () => false; describe("logs.tail", () => { afterEach(() => { resetLogger(); setLoggerOverride(null); }); it("falls back to latest rolling log file when today is missing", async () => { const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-logs-")); const older = path.join(tempDir, "openclaw-2026-01-20.log"); const newer = path.join(tempDir, "openclaw-2026-01-21.log"); await fs.writeFile(older, '{"msg":"old"}\n'); await fs.writeFile(newer, '{"msg":"new"}\n'); await fs.utimes(older, new Date(0), new Date(0)); await fs.utimes(newer, new Date(), new Date()); setLoggerOverride({ file: path.join(tempDir, "openclaw-2026-01-22.log") }); const respond = vi.fn(); await logsHandlers["logs.tail"]({ params: {}, respond, context: {} as unknown as Parameters<(typeof logsHandlers)["logs.tail"]>[0]["context"], client: null, req: { id: "req-1", type: "req", method: "logs.tail" }, isWebchatConnect: noop, }); expect(respond).toHaveBeenCalledWith( true, expect.objectContaining({ file: newer, lines: ['{"msg":"new"}'], }), undefined, ); await fs.rm(tempDir, { recursive: true, force: true }); }); });