test: dedupe infra runtime and heartbeat coverage

This commit is contained in:
Peter Steinberger
2026-03-13 17:54:38 +00:00
parent 118abfbdb7
commit a68caaf719
2 changed files with 126 additions and 158 deletions

View File

@@ -13,7 +13,6 @@ import {
setGatewaySigusr1RestartPolicy,
setPreRestartDeferralCheck,
} from "./restart.js";
import { createTelegramRetryRunner } from "./retry-policy.js";
import { listTailnetAddresses } from "./tailnet.js";
describe("infra runtime", () => {
@@ -61,27 +60,6 @@ describe("infra runtime", () => {
});
});
describe("createTelegramRetryRunner", () => {
afterEach(() => {
vi.useRealTimers();
});
it("retries when custom shouldRetry matches non-telegram error", async () => {
vi.useFakeTimers();
const runner = createTelegramRetryRunner({
retry: { attempts: 2, minDelayMs: 0, maxDelayMs: 0, jitter: 0 },
shouldRetry: (err) => err instanceof Error && err.message === "boom",
});
const fn = vi.fn().mockRejectedValueOnce(new Error("boom")).mockResolvedValue("ok");
const promise = runner(fn, "request");
await vi.runAllTimersAsync();
await expect(promise).resolves.toBe("ok");
expect(fn).toHaveBeenCalledTimes(2);
});
});
describe("restart authorization", () => {
setupRestartSignalSuite();

View File

@@ -339,35 +339,138 @@ describe("resolveSessionDeliveryTarget", () => {
},
});
it("allows heartbeat delivery to Slack DMs and avoids inherited threadId by default", () => {
const resolved = resolveHeartbeatTarget({
sessionId: "sess-heartbeat-outbound",
updatedAt: 1,
lastChannel: "slack",
lastTo: "user:U123",
lastThreadId: "1739142736.000100",
});
const expectHeartbeatTarget = (params: {
name: string;
entry: Parameters<typeof resolveHeartbeatDeliveryTarget>[0]["entry"];
directPolicy?: "allow" | "block";
expectedChannel: string;
expectedTo?: string;
expectedReason?: string;
expectedThreadId?: string | number;
}) => {
const resolved = resolveHeartbeatTarget(params.entry, params.directPolicy);
expect(resolved.channel, params.name).toBe(params.expectedChannel);
expect(resolved.to, params.name).toBe(params.expectedTo);
expect(resolved.reason, params.name).toBe(params.expectedReason);
expect(resolved.threadId, params.name).toBe(params.expectedThreadId);
};
expect(resolved.channel).toBe("slack");
expect(resolved.to).toBe("user:U123");
expect(resolved.threadId).toBeUndefined();
});
it("blocks heartbeat delivery to Slack DMs when directPolicy is block", () => {
const resolved = resolveHeartbeatTarget(
{
sessionId: "sess-heartbeat-outbound",
it.each([
{
name: "allows heartbeat delivery to Slack DMs by default and drops inherited thread ids",
entry: {
sessionId: "sess-heartbeat-slack-direct",
updatedAt: 1,
lastChannel: "slack",
lastTo: "user:U123",
lastThreadId: "1739142736.000100",
},
"block",
);
expect(resolved.channel).toBe("none");
expect(resolved.reason).toBe("dm-blocked");
expect(resolved.threadId).toBeUndefined();
expectedChannel: "slack",
expectedTo: "user:U123",
},
{
name: "blocks heartbeat delivery to Slack DMs when directPolicy is block",
entry: {
sessionId: "sess-heartbeat-slack-direct-blocked",
updatedAt: 1,
lastChannel: "slack",
lastTo: "user:U123",
lastThreadId: "1739142736.000100",
},
directPolicy: "block" as const,
expectedChannel: "none",
expectedReason: "dm-blocked",
},
{
name: "allows heartbeat delivery to Telegram direct chats by default",
entry: {
sessionId: "sess-heartbeat-telegram-direct",
updatedAt: 1,
lastChannel: "telegram",
lastTo: "5232990709",
},
expectedChannel: "telegram",
expectedTo: "5232990709",
},
{
name: "blocks heartbeat delivery to Telegram direct chats when directPolicy is block",
entry: {
sessionId: "sess-heartbeat-telegram-direct-blocked",
updatedAt: 1,
lastChannel: "telegram",
lastTo: "5232990709",
},
directPolicy: "block" as const,
expectedChannel: "none",
expectedReason: "dm-blocked",
},
{
name: "keeps heartbeat delivery to Telegram groups",
entry: {
sessionId: "sess-heartbeat-telegram-group",
updatedAt: 1,
lastChannel: "telegram",
lastTo: "-1001234567890",
},
expectedChannel: "telegram",
expectedTo: "-1001234567890",
},
{
name: "allows heartbeat delivery to WhatsApp direct chats by default",
entry: {
sessionId: "sess-heartbeat-whatsapp-direct",
updatedAt: 1,
lastChannel: "whatsapp",
lastTo: "+15551234567",
},
expectedChannel: "whatsapp",
expectedTo: "+15551234567",
},
{
name: "keeps heartbeat delivery to WhatsApp groups",
entry: {
sessionId: "sess-heartbeat-whatsapp-group",
updatedAt: 1,
lastChannel: "whatsapp",
lastTo: "120363140186826074@g.us",
},
expectedChannel: "whatsapp",
expectedTo: "120363140186826074@g.us",
},
{
name: "uses session chatType hints when target parsing cannot classify a direct chat",
entry: {
sessionId: "sess-heartbeat-imessage-direct",
updatedAt: 1,
lastChannel: "imessage",
lastTo: "chat-guid-unknown-shape",
chatType: "direct",
},
expectedChannel: "imessage",
expectedTo: "chat-guid-unknown-shape",
},
{
name: "blocks session chatType direct hints when directPolicy is block",
entry: {
sessionId: "sess-heartbeat-imessage-direct-blocked",
updatedAt: 1,
lastChannel: "imessage",
lastTo: "chat-guid-unknown-shape",
chatType: "direct",
},
directPolicy: "block" as const,
expectedChannel: "none",
expectedReason: "dm-blocked",
},
])("$name", ({ name, entry, directPolicy, expectedChannel, expectedTo, expectedReason }) => {
expectHeartbeatTarget({
name,
entry,
directPolicy,
expectedChannel,
expectedTo,
expectedReason,
});
});
it("allows heartbeat delivery to Discord DMs by default", () => {
@@ -389,119 +492,6 @@ describe("resolveSessionDeliveryTarget", () => {
expect(resolved.to).toBe("user:12345");
});
it("allows heartbeat delivery to Telegram direct chats by default", () => {
const resolved = resolveHeartbeatTarget({
sessionId: "sess-heartbeat-telegram-direct",
updatedAt: 1,
lastChannel: "telegram",
lastTo: "5232990709",
});
expect(resolved.channel).toBe("telegram");
expect(resolved.to).toBe("5232990709");
});
it("blocks heartbeat delivery to Telegram direct chats when directPolicy is block", () => {
const resolved = resolveHeartbeatTarget(
{
sessionId: "sess-heartbeat-telegram-direct",
updatedAt: 1,
lastChannel: "telegram",
lastTo: "5232990709",
},
"block",
);
expect(resolved.channel).toBe("none");
expect(resolved.reason).toBe("dm-blocked");
});
it("keeps heartbeat delivery to Telegram groups", () => {
const cfg: OpenClawConfig = {};
const resolved = resolveHeartbeatDeliveryTarget({
cfg,
entry: {
sessionId: "sess-heartbeat-telegram-group",
updatedAt: 1,
lastChannel: "telegram",
lastTo: "-1001234567890",
},
heartbeat: {
target: "last",
},
});
expect(resolved.channel).toBe("telegram");
expect(resolved.to).toBe("-1001234567890");
});
it("allows heartbeat delivery to WhatsApp direct chats by default", () => {
const cfg: OpenClawConfig = {};
const resolved = resolveHeartbeatDeliveryTarget({
cfg,
entry: {
sessionId: "sess-heartbeat-whatsapp-direct",
updatedAt: 1,
lastChannel: "whatsapp",
lastTo: "+15551234567",
},
heartbeat: {
target: "last",
},
});
expect(resolved.channel).toBe("whatsapp");
expect(resolved.to).toBe("+15551234567");
});
it("keeps heartbeat delivery to WhatsApp groups", () => {
const cfg: OpenClawConfig = {};
const resolved = resolveHeartbeatDeliveryTarget({
cfg,
entry: {
sessionId: "sess-heartbeat-whatsapp-group",
updatedAt: 1,
lastChannel: "whatsapp",
lastTo: "120363140186826074@g.us",
},
heartbeat: {
target: "last",
},
});
expect(resolved.channel).toBe("whatsapp");
expect(resolved.to).toBe("120363140186826074@g.us");
});
it("uses session chatType hint when target parser cannot classify and allows direct by default", () => {
const resolved = resolveHeartbeatTarget({
sessionId: "sess-heartbeat-imessage-direct",
updatedAt: 1,
lastChannel: "imessage",
lastTo: "chat-guid-unknown-shape",
chatType: "direct",
});
expect(resolved.channel).toBe("imessage");
expect(resolved.to).toBe("chat-guid-unknown-shape");
});
it("blocks session chatType direct hints when directPolicy is block", () => {
const resolved = resolveHeartbeatTarget(
{
sessionId: "sess-heartbeat-imessage-direct",
updatedAt: 1,
lastChannel: "imessage",
lastTo: "chat-guid-unknown-shape",
chatType: "direct",
},
"block",
);
expect(resolved.channel).toBe("none");
expect(resolved.reason).toBe("dm-blocked");
});
it("keeps heartbeat delivery to Discord channels", () => {
const cfg: OpenClawConfig = {};
const resolved = resolveHeartbeatDeliveryTarget({