mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
test: stabilize infra tests
This commit is contained in:
@@ -72,7 +72,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Sessions/Maintenance: archive transcripts when pruning stale sessions, clean expired media in subdirectories, and purge `.deleted` transcript archives after the prune window to prevent disk leaks. (#18538)
|
||||
- Infra/Fetch: ensure foreign abort-signal listener cleanup never masks original fetch successes/failures, while still preventing detached-finally unhandled rejection noise in `wrapFetchWithAbortSignal`. Thanks @Jackten.
|
||||
- Heartbeat: allow suppressing tool error warning payloads during heartbeat runs via a new heartbeat config flag. (#18497) Thanks @thewilloftheshadow.
|
||||
- Heartbeat: include sender metadata (From/To/Provider) in heartbeat prompts so model context matches the delivery target. (#18532)
|
||||
- Heartbeat: include sender metadata (From/To/Provider) in heartbeat prompts so model context matches the delivery target. (#18532) Thanks @dinakars777.
|
||||
- Heartbeat/Telegram: strip configured `responsePrefix` before heartbeat ack detection (with boundary-safe matching) so prefixed `HEARTBEAT_OK` replies are correctly suppressed instead of leaking into DMs. (#18602)
|
||||
|
||||
## 2026.2.15
|
||||
|
||||
@@ -2,12 +2,12 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { telegramPlugin } from "../../extensions/telegram/src/channel.js";
|
||||
import { setTelegramRuntime } from "../../extensions/telegram/src/runtime.js";
|
||||
import { whatsappPlugin } from "../../extensions/whatsapp/src/channel.js";
|
||||
import { setWhatsAppRuntime } from "../../extensions/whatsapp/src/runtime.js";
|
||||
import * as replyModule from "../auto-reply/reply.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveAgentMainSessionKey, resolveMainSessionKey } from "../config/sessions.js";
|
||||
import { setActivePluginRegistry } from "../plugins/runtime.js";
|
||||
import { createPluginRuntime } from "../plugins/runtime/index.js";
|
||||
@@ -75,7 +75,10 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("runHeartbeatOnce – heartbeat model override", () => {
|
||||
async function runDefaultsHeartbeat(params: { model?: string }) {
|
||||
async function runDefaultsHeartbeat(params: {
|
||||
model?: string;
|
||||
suppressToolErrorWarnings?: boolean;
|
||||
}) {
|
||||
return withHeartbeatFixture(async ({ tmpDir, storePath, seedSession }) => {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
@@ -85,6 +88,7 @@ describe("runHeartbeatOnce – heartbeat model override", () => {
|
||||
every: "5m",
|
||||
target: "whatsapp",
|
||||
model: params.model,
|
||||
suppressToolErrorWarnings: params.suppressToolErrorWarnings,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -121,6 +125,16 @@ describe("runHeartbeatOnce – heartbeat model override", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("passes suppressToolErrorWarnings when configured", async () => {
|
||||
const replyOpts = await runDefaultsHeartbeat({ suppressToolErrorWarnings: true });
|
||||
expect(replyOpts).toEqual(
|
||||
expect.objectContaining({
|
||||
isHeartbeat: true,
|
||||
suppressToolErrorWarnings: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("passes per-agent heartbeat model override (merged with defaults)", async () => {
|
||||
await withHeartbeatFixture(async ({ storePath, seedSession }) => {
|
||||
const cfg: OpenClawConfig = {
|
||||
|
||||
@@ -70,7 +70,8 @@ vi.mock("./manager.js", () => ({
|
||||
|
||||
import { QmdMemoryManager } from "./qmd-manager.js";
|
||||
import { getMemorySearchManager } from "./search-manager.js";
|
||||
const createQmdManagerMock = vi.mocked(QmdMemoryManager.create.bind(QmdMemoryManager));
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method -- mocked static function
|
||||
const createQmdManagerMock = vi.mocked(QmdMemoryManager.create);
|
||||
|
||||
type SearchManagerResult = Awaited<ReturnType<typeof getMemorySearchManager>>;
|
||||
type SearchManager = NonNullable<SearchManagerResult["manager"]>;
|
||||
|
||||
@@ -63,7 +63,8 @@ describe("runCommandWithTimeout", () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.code).toBe(0);
|
||||
expect(result.signal).toBeNull();
|
||||
expect(result.code ?? 0).toBe(0);
|
||||
expect(result.termination).toBe("exit");
|
||||
expect(result.noOutputTimedOut).toBe(false);
|
||||
expect(result.stdout.length).toBeGreaterThanOrEqual(2);
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { startTelegramWebhook } from "./webhook.js";
|
||||
|
||||
const handlerSpy = vi.fn(
|
||||
(_req: unknown, res: { writeHead: (status: number) => void; end: (body?: string) => void }) => {
|
||||
res.writeHead(200);
|
||||
res.end("ok");
|
||||
},
|
||||
const handlerSpy = vi.hoisted(() =>
|
||||
vi.fn(
|
||||
(_req: unknown, res: { writeHead: (status: number) => void; end: (body?: string) => void }) => {
|
||||
res.writeHead(200);
|
||||
res.end("ok");
|
||||
},
|
||||
),
|
||||
);
|
||||
const setWebhookSpy = vi.hoisted(() => vi.fn());
|
||||
const stopSpy = vi.hoisted(() => vi.fn());
|
||||
const webhookCallbackSpy = vi.hoisted(() => vi.fn(() => handlerSpy));
|
||||
const createTelegramBotSpy = vi.hoisted(() =>
|
||||
vi.fn(() => ({
|
||||
api: { setWebhook: setWebhookSpy },
|
||||
stop: stopSpy,
|
||||
})),
|
||||
);
|
||||
const setWebhookSpy = vi.fn();
|
||||
const stopSpy = vi.fn();
|
||||
const webhookCallbackSpy = vi.fn(() => handlerSpy);
|
||||
|
||||
const createTelegramBotSpy = vi.fn(() => ({
|
||||
api: { setWebhook: setWebhookSpy },
|
||||
stop: stopSpy,
|
||||
}));
|
||||
|
||||
vi.mock("grammy", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("grammy")>();
|
||||
|
||||
Reference in New Issue
Block a user