diff --git a/src/cli/nodes-cli.coverage.test.ts b/src/cli/nodes-cli.coverage.test.ts index 13fc36caf..1898549cd 100644 --- a/src/cli/nodes-cli.coverage.test.ts +++ b/src/cli/nodes-cli.coverage.test.ts @@ -75,23 +75,6 @@ vi.mock("../config/config.js", () => ({ })); describe("nodes-cli coverage", () => { - it("lists nodes via node.list", async () => { - runtimeLogs.length = 0; - runtimeErrors.length = 0; - callGateway.mockClear(); - - const { registerNodesCli } = await import("./nodes-cli.js"); - const program = new Command(); - program.exitOverride(); - registerNodesCli(program); - - await program.parseAsync(["nodes", "status"], { from: "user" }); - - expect(callGateway).toHaveBeenCalled(); - expect(callGateway.mock.calls[0]?.[0]?.method).toBe("node.list"); - expect(runtimeErrors).toHaveLength(0); - }); - it("invokes system.run with parsed params", async () => { runtimeLogs.length = 0; runtimeErrors.length = 0; diff --git a/src/telegram/bot.test.ts b/src/telegram/bot.test.ts index cb919a023..1d4b7bd4b 100644 --- a/src/telegram/bot.test.ts +++ b/src/telegram/bot.test.ts @@ -1608,160 +1608,6 @@ describe("createTelegramBot", () => { expect(replySpy).not.toHaveBeenCalled(); }); - it("blocks group messages from senders not in allowFrom when groupPolicy is 'allowlist'", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["123456789"], // Does not include sender 999999 - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - from: { id: 999999, username: "notallowed" }, // Not in allowFrom - text: "@openclaw_bot hello", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - expect(replySpy).not.toHaveBeenCalled(); - }); - - it("allows group messages from senders in allowFrom (by ID) when groupPolicy is 'allowlist'", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["123456789"], - groups: { "*": { requireMention: false } }, // Skip mention check - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - from: { id: 123456789, username: "testuser" }, // In allowFrom - text: "hello", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - expect(replySpy).toHaveBeenCalledTimes(1); - }); - - it("allows group messages from senders in allowFrom (by username) when groupPolicy is 'allowlist'", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["@testuser"], // By username - groups: { "*": { requireMention: false } }, - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - from: { id: 12345, username: "testuser" }, // Username matches @testuser - text: "hello", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - expect(replySpy).toHaveBeenCalledTimes(1); - }); - - it("allows group messages from telegram:-prefixed allowFrom entries when groupPolicy is 'allowlist'", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["telegram:77112533"], - groups: { "*": { requireMention: false } }, - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - from: { id: 77112533, username: "mneves" }, - text: "hello", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - expect(replySpy).toHaveBeenCalledTimes(1); - }); - - it("allows group messages from tg:-prefixed allowFrom entries case-insensitively when groupPolicy is 'allowlist'", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["TG:77112533"], - groups: { "*": { requireMention: false } }, - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - from: { id: 77112533, username: "mneves" }, - text: "hello", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - expect(replySpy).toHaveBeenCalledTimes(1); - }); - it("allows all group messages when groupPolicy is 'open'", async () => { onSpy.mockReset(); const replySpy = replyModule.__replySpy as unknown as ReturnType; @@ -1792,37 +1638,6 @@ describe("createTelegramBot", () => { expect(replySpy).toHaveBeenCalledTimes(1); }); - it("matches usernames case-insensitively when groupPolicy is 'allowlist'", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["@TestUser"], // Uppercase in config - groups: { "*": { requireMention: false } }, - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - from: { id: 12345, username: "testuser" }, // Lowercase in message - text: "hello", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - expect(replySpy).toHaveBeenCalledTimes(1); - }); - it("allows direct messages regardless of groupPolicy", async () => { onSpy.mockReset(); const replySpy = replyModule.__replySpy as unknown as ReturnType; @@ -1882,160 +1697,6 @@ describe("createTelegramBot", () => { expect(replySpy).toHaveBeenCalledTimes(1); }); - it("allows direct messages with telegram:-prefixed allowFrom entries", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - allowFrom: ["telegram:123456789"], - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: 123456789, type: "private" }, - from: { id: 123456789, username: "testuser" }, - text: "hello", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - expect(replySpy).toHaveBeenCalledTimes(1); - }); - - it("allows group messages with wildcard in allowFrom when groupPolicy is 'allowlist'", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["*"], // Wildcard allows everyone - groups: { "*": { requireMention: false } }, - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - from: { id: 999999, username: "random" }, // Random sender, but wildcard allows - text: "hello", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - expect(replySpy).toHaveBeenCalledTimes(1); - }); - - it("blocks group messages with no sender ID when groupPolicy is 'allowlist'", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["123456789"], - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - // No `from` field (e.g., channel post or anonymous admin) - text: "hello", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - expect(replySpy).not.toHaveBeenCalled(); - }); - - it("matches telegram:-prefixed allowFrom entries in group allowlist", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["telegram:123456789"], // Prefixed format - groups: { "*": { requireMention: false } }, - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - from: { id: 123456789, username: "testuser" }, // Matches after stripping prefix - text: "hello from prefixed user", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - // Should call reply because sender ID matches after stripping telegram: prefix - expect(replySpy).toHaveBeenCalled(); - }); - - it("matches tg:-prefixed allowFrom entries case-insensitively in group allowlist", async () => { - onSpy.mockReset(); - const replySpy = replyModule.__replySpy as unknown as ReturnType; - replySpy.mockReset(); - loadConfig.mockReturnValue({ - channels: { - telegram: { - groupPolicy: "allowlist", - allowFrom: ["TG:123456789"], // Prefixed format (case-insensitive) - groups: { "*": { requireMention: false } }, - }, - }, - }); - - createTelegramBot({ token: "tok" }); - const handler = getOnHandler("message") as (ctx: Record) => Promise; - - await handler({ - message: { - chat: { id: -100123456789, type: "group", title: "Test Group" }, - from: { id: 123456789, username: "testuser" }, // Matches after stripping tg: prefix - text: "hello from prefixed user", - date: 1736380800, - }, - me: { username: "openclaw_bot" }, - getFile: async () => ({ download: async () => new Uint8Array() }), - }); - - // Should call reply because sender ID matches after stripping tg: prefix - expect(replySpy).toHaveBeenCalled(); - }); - it("blocks group messages when groupPolicy allowlist has no groupAllowFrom", async () => { onSpy.mockReset(); const replySpy = replyModule.__replySpy as unknown as ReturnType; diff --git a/src/tui/theme/theme.test.ts b/src/tui/theme/theme.test.ts index 3e9f91b40..9a9bd2d0c 100644 --- a/src/tui/theme/theme.test.ts +++ b/src/tui/theme/theme.test.ts @@ -6,24 +6,14 @@ describe("markdownTheme", () => { it("returns highlighted lines for common language inputs", () => { const code = `const x = 42;`; const js = markdownTheme.highlightCode!(code, "javascript"); - const ts = markdownTheme.highlightCode!( - `function greet(name: string) { - return "Hello, " + name; -}`, - "typescript", - ); expect(js).toBeInstanceOf(Array); expect(js).toHaveLength(1); expect(js[0]).toContain("const"); expect(js[0]).toContain("42"); - expect(ts).toHaveLength(3); - expect(ts[0]).toContain("function"); - expect(ts[1]).toContain("return"); - expect(ts[2]).toContain("}"); }); - it("handles unknown and missing language without throwing", () => { + it("handles unknown or missing language and preserves content", () => { const code = `echo "hello"`; const unknown = markdownTheme.highlightCode!(code, "not-a-real-language"); const missing = markdownTheme.highlightCode!(code, undefined); @@ -33,12 +23,9 @@ describe("markdownTheme", () => { expect(missing).toHaveLength(1); expect(unknown[0]).toContain("echo"); expect(missing[0]).toContain("echo"); - }); - - it("preserves code content and handles empty input", () => { - const code = `const message = "Hello, World!"; + const codeBlock = `const message = "Hello, World!"; console.log(message);`; - const result = markdownTheme.highlightCode!(code, "javascript"); + const result = markdownTheme.highlightCode!(codeBlock, "javascript"); const empty = markdownTheme.highlightCode!("", "javascript"); const stripAnsi = (str: string) => diff --git a/src/web/inbound.media.test.ts b/src/web/inbound.media.test.ts index 382a54a14..2ebdd5f12 100644 --- a/src/web/inbound.media.test.ts +++ b/src/web/inbound.media.test.ts @@ -89,7 +89,10 @@ vi.mock("./session.js", () => { import { monitorWebInbox, resetWebInboundDedupe } from "./inbound.js"; async function waitForMessage(onMessage: ReturnType) { - await vi.waitFor(() => expect(onMessage).toHaveBeenCalledTimes(1)); + await vi.waitFor(() => expect(onMessage).toHaveBeenCalledTimes(1), { + interval: 1, + timeout: 250, + }); return onMessage.mock.calls[0][0]; } diff --git a/src/web/media.test.ts b/src/web/media.test.ts index 3305e764f..83e663d09 100644 --- a/src/web/media.test.ts +++ b/src/web/media.test.ts @@ -40,8 +40,8 @@ beforeAll(async () => { fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-media-test-")); largeJpegBuffer = await sharp({ create: { - width: 900, - height: 900, + width: 800, + height: 800, channels: 3, background: "#ff0000", }, @@ -63,7 +63,7 @@ beforeAll(async () => { }) .png() .toBuffer(); - const size = 96; + const size = 72; const raw = buildDeterministicBytes(size * size * 4); fallbackPngBuffer = await sharp(raw, { raw: { width: size, height: size, channels: 4 } }) .png()