diff --git a/extensions/telegram/src/bot-message-context.route-test-support.ts b/extensions/telegram/src/bot-message-context.route-test-support.ts index f2ac59eb290..c2c84bf7b26 100644 --- a/extensions/telegram/src/bot-message-context.route-test-support.ts +++ b/extensions/telegram/src/bot-message-context.route-test-support.ts @@ -1,4 +1,5 @@ import { vi, type Mock } from "vitest"; +import { finalizeTelegramInboundContextForTest } from "./bot-message-context.session-runtime-test-support.js"; type AsyncUnknownMock = Mock<(...args: unknown[]) => Promise>; type BuildTelegramMessageContextForTest = @@ -13,27 +14,9 @@ const hoisted = vi.hoisted((): { recordInboundSessionMock: AsyncUnknownMock } => })); export const recordInboundSessionMock: AsyncUnknownMock = hoisted.recordInboundSessionMock; -const finalizeInboundContextForTest = ((ctx) => { - const next = ctx as Record; - const body = typeof next.Body === "string" ? next.Body : ""; - next.Body = body; - next.BodyForAgent = - typeof next.BodyForAgent === "string" - ? next.BodyForAgent - : typeof next.RawBody === "string" - ? next.RawBody - : body; - next.BodyForCommands = - typeof next.BodyForCommands === "string" - ? next.BodyForCommands - : typeof next.CommandBody === "string" - ? next.CommandBody - : typeof next.RawBody === "string" - ? next.RawBody - : body; - next.CommandAuthorized = Boolean(next.CommandAuthorized); - return next; -}) as NonNullable; +const finalizeInboundContextForTest = finalizeTelegramInboundContextForTest as NonNullable< + TelegramTestSessionRuntime["finalizeInboundContext"] +>; const recordInboundSessionForTest: NonNullable< TelegramTestSessionRuntime["recordInboundSession"] > = async (params) => { diff --git a/extensions/telegram/src/bot-message-context.session-runtime-test-support.ts b/extensions/telegram/src/bot-message-context.session-runtime-test-support.ts new file mode 100644 index 00000000000..fbbfea0a256 --- /dev/null +++ b/extensions/telegram/src/bot-message-context.session-runtime-test-support.ts @@ -0,0 +1,21 @@ +export function finalizeTelegramInboundContextForTest(ctx: unknown): Record { + const next = ctx as Record; + const body = typeof next.Body === "string" ? next.Body : ""; + next.Body = body; + next.BodyForAgent = + typeof next.BodyForAgent === "string" + ? next.BodyForAgent + : typeof next.RawBody === "string" + ? next.RawBody + : body; + next.BodyForCommands = + typeof next.BodyForCommands === "string" + ? next.BodyForCommands + : typeof next.CommandBody === "string" + ? next.CommandBody + : typeof next.RawBody === "string" + ? next.RawBody + : body; + next.CommandAuthorized = Boolean(next.CommandAuthorized); + return next; +} diff --git a/extensions/telegram/src/bot-message-context.test-harness.ts b/extensions/telegram/src/bot-message-context.test-harness.ts index 3dd0dec8bad..5f4a3443b02 100644 --- a/extensions/telegram/src/bot-message-context.test-harness.ts +++ b/extensions/telegram/src/bot-message-context.test-harness.ts @@ -1,4 +1,5 @@ import type { BuildTelegramMessageContextParams, TelegramMediaRef } from "./bot-message-context.js"; +import { finalizeTelegramInboundContextForTest } from "./bot-message-context.session-runtime-test-support.js"; export const baseTelegramMessageContextConfig = { agents: { defaults: { model: "anthropic/claude-opus-4-5", workspace: "/tmp/openclaw" } }, @@ -7,27 +8,9 @@ export const baseTelegramMessageContextConfig = { } as never; type TelegramTestSessionRuntime = NonNullable; -const finalizeInboundContextForTest = ((ctx) => { - const next = ctx as Record; - const body = typeof next.Body === "string" ? next.Body : ""; - next.Body = body; - next.BodyForAgent = - typeof next.BodyForAgent === "string" - ? next.BodyForAgent - : typeof next.RawBody === "string" - ? next.RawBody - : body; - next.BodyForCommands = - typeof next.BodyForCommands === "string" - ? next.BodyForCommands - : typeof next.CommandBody === "string" - ? next.CommandBody - : typeof next.RawBody === "string" - ? next.RawBody - : body; - next.CommandAuthorized = Boolean(next.CommandAuthorized); - return next; -}) as NonNullable; +const finalizeInboundContextForTest = finalizeTelegramInboundContextForTest as NonNullable< + TelegramTestSessionRuntime["finalizeInboundContext"] +>; type BuildTelegramMessageContextForTestParams = { message: Record; diff --git a/extensions/whatsapp/src/directory-contract.test.ts b/extensions/whatsapp/src/directory-contract.test.ts index 26af1ad1bc5..51e3b7cd689 100644 --- a/extensions/whatsapp/src/directory-contract.test.ts +++ b/extensions/whatsapp/src/directory-contract.test.ts @@ -1,4 +1,3 @@ -import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk/channel-contract"; import type { OpenClawConfig } from "openclaw/plugin-sdk/testing"; import { describe, expect, it } from "vitest"; import { @@ -6,29 +5,8 @@ import { listWhatsAppDirectoryPeersFromConfig, } from "../directory-contract-api.js"; -type DirectoryListFn = (params: { - cfg: OpenClawConfig; - accountId?: string; - query?: string | null; - limit?: number | null; -}) => Promise; - -async function listDirectoryEntriesWithDefaults(listFn: DirectoryListFn, cfg: OpenClawConfig) { - return await listFn({ - cfg, - accountId: "default", - query: null, - limit: null, - }); -} - -async function expectDirectoryIds( - listFn: DirectoryListFn, - cfg: OpenClawConfig, - expected: string[], -) { - const entries = await listDirectoryEntriesWithDefaults(listFn, cfg); - expect(entries.map((entry) => entry.id)).toEqual(expected); +function ids(entries: Array<{ id: string }>) { + return entries.map((entry) => entry.id); } describe("WhatsApp directory contract", () => { @@ -42,8 +20,20 @@ describe("WhatsApp directory contract", () => { }, } as unknown as OpenClawConfig; - await expectDirectoryIds(listWhatsAppDirectoryPeersFromConfig, cfg, ["+15550000000"]); - await expectDirectoryIds(listWhatsAppDirectoryGroupsFromConfig, cfg, ["999@g.us"]); + const peers = await listWhatsAppDirectoryPeersFromConfig({ + cfg, + accountId: "default", + query: null, + limit: null, + }); + const groups = await listWhatsAppDirectoryGroupsFromConfig({ + cfg, + accountId: "default", + query: null, + limit: null, + }); + expect(ids(peers)).toEqual(["+15550000000"]); + expect(ids(groups)).toEqual(["999@g.us"]); }); it("applies query and limit filtering for config-backed directories", async () => { @@ -61,6 +51,6 @@ describe("WhatsApp directory contract", () => { query: "@g.us", limit: 1, }); - expect(groups.map((entry) => entry.id)).toEqual(["111@g.us"]); + expect(ids(groups)).toEqual(["111@g.us"]); }); }); diff --git a/extensions/whatsapp/src/reaction-level.test.ts b/extensions/whatsapp/src/reaction-level.test.ts index 79a7ab59a28..d8d0478027d 100644 --- a/extensions/whatsapp/src/reaction-level.test.ts +++ b/extensions/whatsapp/src/reaction-level.test.ts @@ -2,31 +2,14 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import { describe, expect, it } from "vitest"; import { resolveWhatsAppReactionLevel } from "./reaction-level.js"; -type ReactionResolution = ReturnType; - describe("resolveWhatsAppReactionLevel", () => { - const expectReactionFlags = ( - result: ReactionResolution, - expected: { - level: "off" | "ack" | "minimal" | "extensive"; - ackEnabled: boolean; - agentReactionsEnabled: boolean; - agentReactionGuidance?: "minimal" | "extensive"; - }, - ) => { - expect(result.level).toBe(expected.level); - expect(result.ackEnabled).toBe(expected.ackEnabled); - expect(result.agentReactionsEnabled).toBe(expected.agentReactionsEnabled); - expect(result.agentReactionGuidance).toBe(expected.agentReactionGuidance); - }; - it("defaults to minimal level when reactionLevel is not set", () => { const cfg: OpenClawConfig = { channels: { whatsapp: {} }, }; const result = resolveWhatsAppReactionLevel({ cfg }); - expectReactionFlags(result, { + expect(result).toEqual({ level: "minimal", ackEnabled: false, agentReactionsEnabled: true, @@ -40,7 +23,7 @@ describe("resolveWhatsAppReactionLevel", () => { }; const result = resolveWhatsAppReactionLevel({ cfg }); - expectReactionFlags(result, { + expect(result).toEqual({ level: "off", ackEnabled: false, agentReactionsEnabled: false, @@ -53,7 +36,7 @@ describe("resolveWhatsAppReactionLevel", () => { }; const result = resolveWhatsAppReactionLevel({ cfg }); - expectReactionFlags(result, { + expect(result).toEqual({ level: "ack", ackEnabled: true, agentReactionsEnabled: false, @@ -66,7 +49,7 @@ describe("resolveWhatsAppReactionLevel", () => { }; const result = resolveWhatsAppReactionLevel({ cfg }); - expectReactionFlags(result, { + expect(result).toEqual({ level: "minimal", ackEnabled: false, agentReactionsEnabled: true, @@ -80,7 +63,7 @@ describe("resolveWhatsAppReactionLevel", () => { }; const result = resolveWhatsAppReactionLevel({ cfg }); - expectReactionFlags(result, { + expect(result).toEqual({ level: "extensive", ackEnabled: false, agentReactionsEnabled: true, @@ -101,7 +84,7 @@ describe("resolveWhatsAppReactionLevel", () => { }; const result = resolveWhatsAppReactionLevel({ cfg, accountId: "work" }); - expectReactionFlags(result, { + expect(result).toEqual({ level: "extensive", ackEnabled: false, agentReactionsEnabled: true, diff --git a/extensions/whatsapp/src/setup-surface.test.ts b/extensions/whatsapp/src/setup-surface.test.ts index 89d73bbc3ef..e037bd80768 100644 --- a/extensions/whatsapp/src/setup-surface.test.ts +++ b/extensions/whatsapp/src/setup-surface.test.ts @@ -65,25 +65,22 @@ vi.mock("openclaw/plugin-sdk/setup", async () => { vi.mock("./accounts.js", async () => { const actual = await vi.importActual("./accounts.js"); - return { - ...actual, + return Object.assign({}, actual, { resolveWhatsAppAuthDir: hoisted.resolveWhatsAppAuthDir, - }; + }); }); vi.mock("./auth-store.js", async () => { const actual = await vi.importActual("./auth-store.js"); - return { - ...actual, + return Object.assign({}, actual, { readWebAuthState: hoisted.readWebAuthState, - }; + }); }); -function createRuntime(): RuntimeEnv { - return { +const createRuntime = (): RuntimeEnv => + ({ error: vi.fn(), - } as unknown as RuntimeEnv; -} + }) as unknown as RuntimeEnv; const whatsappGetStatus = createPluginSetupWizardStatus({ id: "whatsapp",