From 1b8dd2e504ca860a3e4e6de627f7edbc8f6a56a5 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 05:31:50 +0000 Subject: [PATCH] perf(web): consolidate heartbeat runner tests --- src/web/auto-reply/heartbeat-runner.test.ts | 18 +++++++- .../heartbeat-runner.timestamp.test.ts | 45 ------------------- 2 files changed, 17 insertions(+), 46 deletions(-) delete mode 100644 src/web/auto-reply/heartbeat-runner.timestamp.test.ts diff --git a/src/web/auto-reply/heartbeat-runner.test.ts b/src/web/auto-reply/heartbeat-runner.test.ts index 4e3d0b2c8..5b878641a 100644 --- a/src/web/auto-reply/heartbeat-runner.test.ts +++ b/src/web/auto-reply/heartbeat-runner.test.ts @@ -16,7 +16,8 @@ const state = vi.hoisted(() => ({ })); vi.mock("../../agents/current-time.js", () => ({ - appendCronStyleCurrentTimeLine: (body: string) => body, + appendCronStyleCurrentTimeLine: (body: string) => + `${body}\nCurrent time: 2026-02-15T00:00:00Z (mock)`, })); // Perf: this module otherwise pulls a large dependency graph that we don't need @@ -136,6 +137,21 @@ describe("runWebHeartbeatOnce", () => { ); }); + it("injects a cron-style Current time line into the heartbeat prompt", async () => { + const { runWebHeartbeatOnce } = await getModules(); + await runWebHeartbeatOnce({ + cfg: { agents: { defaults: { heartbeat: { prompt: "Ops check" } } }, session: {} } as never, + to: "+123", + sender, + replyResolver, + dryRun: true, + }); + expect(replyResolver).toHaveBeenCalledTimes(1); + const ctx = replyResolver.mock.calls[0]?.[0]; + expect(ctx?.Body).toContain("Ops check"); + expect(ctx?.Body).toContain("Current time: 2026-02-15T00:00:00Z (mock)"); + }); + it("treats heartbeat token-only replies as ok-token and preserves session updatedAt", async () => { replyResolver.mockResolvedValue({ text: HEARTBEAT_TOKEN }); const { runWebHeartbeatOnce } = await getModules(); diff --git a/src/web/auto-reply/heartbeat-runner.timestamp.test.ts b/src/web/auto-reply/heartbeat-runner.timestamp.test.ts deleted file mode 100644 index e83aacdb2..000000000 --- a/src/web/auto-reply/heartbeat-runner.timestamp.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import fs from "node:fs/promises"; -import os from "node:os"; -import path from "node:path"; -import { describe, expect, it, vi } from "vitest"; -import type { OpenClawConfig } from "../../config/config.js"; -import { runWebHeartbeatOnce } from "./heartbeat-runner.js"; - -describe("runWebHeartbeatOnce (timestamp)", () => { - it("injects a cron-style Current time line into the heartbeat prompt", async () => { - const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-web-hb-")); - const storePath = path.join(tmpDir, "sessions.json"); - try { - await fs.writeFile(storePath, JSON.stringify({}, null, 2)); - - const replyResolver = vi.fn().mockResolvedValue([{ text: "HEARTBEAT_OK" }]); - const cfg = { - agents: { - defaults: { - heartbeat: { prompt: "Ops check", every: "5m" }, - userTimezone: "America/Chicago", - timeFormat: "24", - }, - }, - session: { store: storePath }, - channels: { whatsapp: { allowFrom: ["*"] } }, - } as unknown as OpenClawConfig; - - await runWebHeartbeatOnce({ - cfg, - to: "+1555", - dryRun: true, - replyResolver, - sender: vi.fn(), - }); - - expect(replyResolver).toHaveBeenCalledTimes(1); - const ctx = replyResolver.mock.calls[0]?.[0]; - expect(ctx?.Body).toMatch(/Ops check/); - expect(ctx?.Body).toMatch(/Current time: /); - expect(ctx?.Body).toMatch(/\(.+\)/); - } finally { - await fs.rm(tmpDir, { recursive: true, force: true }); - } - }); -});