Files
clawdbot/src/infra/heartbeat-visibility.test.ts
Dave Lauer f9cf508cff feat(heartbeat): add configurable visibility for heartbeat responses
Add per-channel and per-account heartbeat visibility settings:
- showOk: hide/show HEARTBEAT_OK messages (default: false)
- showAlerts: hide/show alert messages (default: true)
- useIndicator: emit typing indicator events (default: true)

Config precedence: per-account > per-channel > channel-defaults > global

This allows silencing routine heartbeat acks while still surfacing
alerts when something needs attention.
2026-01-24 09:07:03 +00:00

251 lines
5.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { ClawdbotConfig } from "../config/config.js";
import { resolveHeartbeatVisibility } from "./heartbeat-visibility.js";
describe("resolveHeartbeatVisibility", () => {
it("returns default values when no config is provided", () => {
const cfg = {} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({ cfg, channel: "telegram" });
expect(result).toEqual({
showOk: false,
showAlerts: true,
useIndicator: true,
});
});
it("uses channel defaults when provided", () => {
const cfg = {
channels: {
defaults: {
heartbeat: {
showOk: true,
showAlerts: false,
useIndicator: false,
},
},
},
} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({ cfg, channel: "telegram" });
expect(result).toEqual({
showOk: true,
showAlerts: false,
useIndicator: false,
});
});
it("per-channel config overrides channel defaults", () => {
const cfg = {
channels: {
defaults: {
heartbeat: {
showOk: false,
showAlerts: true,
useIndicator: true,
},
},
telegram: {
heartbeat: {
showOk: true,
},
},
},
} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({ cfg, channel: "telegram" });
expect(result).toEqual({
showOk: true,
showAlerts: true,
useIndicator: true,
});
});
it("per-account config overrides per-channel config", () => {
const cfg = {
channels: {
defaults: {
heartbeat: {
showOk: false,
showAlerts: true,
useIndicator: true,
},
},
telegram: {
heartbeat: {
showOk: false,
showAlerts: false,
},
accounts: {
primary: {
heartbeat: {
showOk: true,
showAlerts: true,
},
},
},
},
},
} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({
cfg,
channel: "telegram",
accountId: "primary",
});
expect(result).toEqual({
showOk: true,
showAlerts: true,
useIndicator: true,
});
});
it("falls through to defaults when account has no heartbeat config", () => {
const cfg = {
channels: {
defaults: {
heartbeat: {
showOk: false,
},
},
telegram: {
heartbeat: {
showAlerts: false,
},
accounts: {
primary: {},
},
},
},
} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({
cfg,
channel: "telegram",
accountId: "primary",
});
expect(result).toEqual({
showOk: false,
showAlerts: false,
useIndicator: true,
});
});
it("handles missing accountId gracefully", () => {
const cfg = {
channels: {
telegram: {
heartbeat: {
showOk: true,
},
accounts: {
primary: {
heartbeat: {
showOk: false,
},
},
},
},
},
} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({ cfg, channel: "telegram" });
expect(result.showOk).toBe(true);
});
it("handles non-existent account gracefully", () => {
const cfg = {
channels: {
telegram: {
heartbeat: {
showOk: true,
},
accounts: {
primary: {
heartbeat: {
showOk: false,
},
},
},
},
},
} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({
cfg,
channel: "telegram",
accountId: "nonexistent",
});
expect(result.showOk).toBe(true);
});
it("works with whatsapp channel", () => {
const cfg = {
channels: {
whatsapp: {
heartbeat: {
showOk: true,
showAlerts: false,
},
},
},
} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({ cfg, channel: "whatsapp" });
expect(result).toEqual({
showOk: true,
showAlerts: false,
useIndicator: true,
});
});
it("works with discord channel", () => {
const cfg = {
channels: {
discord: {
heartbeat: {
useIndicator: false,
},
},
},
} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({ cfg, channel: "discord" });
expect(result).toEqual({
showOk: false,
showAlerts: true,
useIndicator: false,
});
});
it("works with slack channel", () => {
const cfg = {
channels: {
slack: {
heartbeat: {
showOk: true,
showAlerts: true,
useIndicator: true,
},
},
},
} as ClawdbotConfig;
const result = resolveHeartbeatVisibility({ cfg, channel: "slack" });
expect(result).toEqual({
showOk: true,
showAlerts: true,
useIndicator: true,
});
});
});