From 4e22e756971b238edb00a94f30ee5d9b5cc9f340 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 3 Apr 2026 12:00:07 +0100 Subject: [PATCH] test: reduce telegram broad partial mocks --- extensions/telegram/src/audit.test.ts | 12 +++---- .../telegram/src/bot-handlers.runtime.ts | 2 +- .../bot-native-commands.menu-test-support.ts | 13 +------ .../bot.create-telegram-bot.test-harness.ts | 24 ------------- extensions/telegram/src/bot.ts | 11 +++--- .../telegram/src/network-config.test.ts | 12 +++---- .../telegram/src/polling-session.test.ts | 13 +++---- extensions/telegram/src/send.runtime.ts | 10 ++++++ extensions/telegram/src/send.test-harness.ts | 34 ++++++++++--------- extensions/telegram/src/send.ts | 20 ++++++----- .../src/sendchataction-401-backoff.test.ts | 11 +++--- 11 files changed, 68 insertions(+), 94 deletions(-) create mode 100644 extensions/telegram/src/send.runtime.ts diff --git a/extensions/telegram/src/audit.test.ts b/extensions/telegram/src/audit.test.ts index 37f9a12ea90..fc4ce4a069c 100644 --- a/extensions/telegram/src/audit.test.ts +++ b/extensions/telegram/src/audit.test.ts @@ -6,13 +6,11 @@ const fetchWithTimeoutMock = vi.hoisted(() => vi.fn()); const resolveTelegramFetchMock = vi.hoisted(() => vi.fn(() => fetchWithTimeoutMock)); const resolveTelegramApiBaseMock = vi.hoisted(() => vi.fn(() => "https://api.telegram.org")); -vi.mock("openclaw/plugin-sdk/text-runtime", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - fetchWithTimeout: fetchWithTimeoutMock, - }; -}); +vi.mock("openclaw/plugin-sdk/text-runtime", () => ({ + fetchWithTimeout: fetchWithTimeoutMock, + isRecord: (value: unknown): value is Record => + typeof value === "object" && value !== null, +})); function mockGetChatMemberStatus(status: string) { fetchWithTimeoutMock.mockResolvedValueOnce( diff --git a/extensions/telegram/src/bot-handlers.runtime.ts b/extensions/telegram/src/bot-handlers.runtime.ts index b480a6a7d52..b09915f6e3c 100644 --- a/extensions/telegram/src/bot-handlers.runtime.ts +++ b/extensions/telegram/src/bot-handlers.runtime.ts @@ -10,7 +10,6 @@ import { import { buildCommandsMessagePaginated, buildCommandsPaginationKeyboard, - formatModelsAvailableHeader, resolveStoredModelOverride, } from "openclaw/plugin-sdk/command-auth"; import { writeConfigFile } from "openclaw/plugin-sdk/config-runtime"; @@ -32,6 +31,7 @@ import { resolvePluginConversationBindingApproval, } from "openclaw/plugin-sdk/conversation-runtime"; import { parseExecApprovalCommandText } from "openclaw/plugin-sdk/infra-runtime"; +import { formatModelsAvailableHeader } from "openclaw/plugin-sdk/models-provider-runtime"; import { dispatchPluginInteractiveHandler } from "openclaw/plugin-sdk/plugin-runtime"; import { resolveAgentRoute } from "openclaw/plugin-sdk/routing"; import { resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing"; diff --git a/extensions/telegram/src/bot-native-commands.menu-test-support.ts b/extensions/telegram/src/bot-native-commands.menu-test-support.ts index 488fa2e0caa..f7691a022ec 100644 --- a/extensions/telegram/src/bot-native-commands.menu-test-support.ts +++ b/extensions/telegram/src/bot-native-commands.menu-test-support.ts @@ -1,4 +1,3 @@ -import type { SkillCommandSpec } from "openclaw/plugin-sdk/command-auth"; import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env"; import { expect, vi } from "vitest"; import type { OpenClawConfig } from "../runtime-api.js"; @@ -23,9 +22,7 @@ type CreateCommandBotResult = { }; const skillCommandMocks = vi.hoisted(() => ({ - listSkillCommandsForAgents: vi.fn< - (params: { cfg: OpenClawConfig; agentIds?: string[] }) => SkillCommandSpec[] - >(() => []), + listSkillCommandsForAgents: vi.fn(() => []), })); const deliveryMocks = vi.hoisted(() => ({ @@ -39,14 +36,6 @@ export const deliverReplies = deliveryMocks.deliverReplies; export const editMessageTelegram = deliveryMocks.editMessageTelegram; export const emitTelegramMessageSentHooks = deliveryMocks.emitTelegramMessageSentHooks; -vi.mock("openclaw/plugin-sdk/command-auth", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - listSkillCommandsForAgents, - }; -}); - vi.mock("./bot/delivery.js", () => ({ deliverReplies, emitTelegramMessageSentHooks, diff --git a/extensions/telegram/src/bot.create-telegram-bot.test-harness.ts b/extensions/telegram/src/bot.create-telegram-bot.test-harness.ts index 375fdb3ad7b..d41f1bf7f60 100644 --- a/extensions/telegram/src/bot.create-telegram-bot.test-harness.ts +++ b/extensions/telegram/src/bot.create-telegram-bot.test-harness.ts @@ -249,22 +249,6 @@ function createModelsProviderDataFromConfig(cfg: OpenClawConfig): { return { byProvider, providers, resolvedDefault, modelNames: new Map() }; } -vi.doMock("openclaw/plugin-sdk/command-auth", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - listSkillCommandsForAgents: skillCommandListHoisted.listSkillCommandsForAgents, - buildModelsProviderData, - }; -}); -vi.doMock("openclaw/plugin-sdk/command-auth.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - listSkillCommandsForAgents: skillCommandListHoisted.listSkillCommandsForAgents, - buildModelsProviderData, - }; -}); vi.doMock("openclaw/plugin-sdk/reply-runtime", async (importOriginal) => { const actual = await importOriginal(); return { @@ -296,14 +280,6 @@ const execApprovalHoisted = vi.hoisted(() => ({ })); export const resolveExecApprovalSpy = execApprovalHoisted.resolveExecApprovalSpy; -vi.doMock("openclaw/plugin-sdk/infra-runtime", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - enqueueSystemEvent: systemEventsHoisted.enqueueSystemEventSpy, - }; -}); - const sentMessageCacheHoisted = vi.hoisted(() => ({ wasSentByBot: vi.fn(() => false), })); diff --git a/extensions/telegram/src/bot.ts b/extensions/telegram/src/bot.ts index e3ec75883ef..3e36bfaa52f 100644 --- a/extensions/telegram/src/bot.ts +++ b/extensions/telegram/src/bot.ts @@ -9,15 +9,14 @@ import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention, } from "openclaw/plugin-sdk/config-runtime"; -import { loadSessionStore, resolveStorePath } from "openclaw/plugin-sdk/config-runtime"; import { resolveThreadBindingIdleTimeoutMsForChannel, resolveThreadBindingMaxAgeMsForChannel, resolveThreadBindingSpawnPolicy, } from "openclaw/plugin-sdk/conversation-runtime"; import { formatUncaughtError } from "openclaw/plugin-sdk/error-runtime"; -import { DEFAULT_GROUP_HISTORY_LIMIT, type HistoryEntry } from "openclaw/plugin-sdk/reply-history"; import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking"; +import { DEFAULT_GROUP_HISTORY_LIMIT, type HistoryEntry } from "openclaw/plugin-sdk/reply-history"; import { danger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env"; import { getChildLogger } from "openclaw/plugin-sdk/runtime-env"; import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env"; @@ -437,9 +436,13 @@ export function createTelegramBot(opts: TelegramBotOptions) { const sessionKey = params.sessionKey ?? `agent:${agentId}:telegram:group:${buildTelegramGroupPeerId(params.chatId, params.messageThreadId)}`; - const storePath = resolveStorePath(cfg.session?.store, { agentId }); + const storePath = telegramDeps.resolveStorePath(cfg.session?.store, { agentId }); try { - const store = (telegramDeps.loadSessionStore ?? loadSessionStore)(storePath); + const loadSessionStore = telegramDeps.loadSessionStore; + if (!loadSessionStore) { + return undefined; + } + const store = loadSessionStore(storePath); const entry = store[sessionKey]; if (entry?.groupActivation === "always") { return false; diff --git a/extensions/telegram/src/network-config.test.ts b/extensions/telegram/src/network-config.test.ts index 0657da0a239..8432d252c1d 100644 --- a/extensions/telegram/src/network-config.test.ts +++ b/extensions/telegram/src/network-config.test.ts @@ -1,13 +1,11 @@ import type { TelegramNetworkConfig } from "openclaw/plugin-sdk/config-runtime"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -vi.mock("openclaw/plugin-sdk/runtime-env", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - isWSL2Sync: vi.fn(() => false), - }; -}); +vi.mock("openclaw/plugin-sdk/runtime-env", () => ({ + isTruthyEnvValue: (value: string | undefined) => + typeof value === "string" && /^(1|true|yes|on)$/i.test(value.trim()), + isWSL2Sync: vi.fn(() => false), +})); let isWSL2Sync: typeof import("openclaw/plugin-sdk/runtime-env").isWSL2Sync; let resetTelegramNetworkConfigStateForTests: typeof import("./network-config.js").resetTelegramNetworkConfigStateForTests; diff --git a/extensions/telegram/src/polling-session.test.ts b/extensions/telegram/src/polling-session.test.ts index cf6f3f22ada..c28b8967d48 100644 --- a/extensions/telegram/src/polling-session.test.ts +++ b/extensions/telegram/src/polling-session.test.ts @@ -22,14 +22,11 @@ vi.mock("./api-logging.js", () => ({ withTelegramApiErrorLogging: async ({ fn }: { fn: () => Promise }) => await fn(), })); -vi.mock("openclaw/plugin-sdk/runtime-env", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - computeBackoff: computeBackoffMock, - sleepWithAbort: sleepWithAbortMock, - }; -}); +vi.mock("openclaw/plugin-sdk/runtime-env", () => ({ + computeBackoff: computeBackoffMock, + formatDurationPrecise: vi.fn((ms: number) => `${ms}ms`), + sleepWithAbort: sleepWithAbortMock, +})); let TelegramPollingSession: typeof import("./polling-session.js").TelegramPollingSession; diff --git a/extensions/telegram/src/send.runtime.ts b/extensions/telegram/src/send.runtime.ts new file mode 100644 index 00000000000..e91c73edec0 --- /dev/null +++ b/extensions/telegram/src/send.runtime.ts @@ -0,0 +1,10 @@ +export { loadConfig, resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime"; +export type { PollInput, MediaKind } from "openclaw/plugin-sdk/media-runtime"; +export { + buildOutboundMediaLoadOptions, + getImageMetadata, + isGifMedia, + kindFromMime, + normalizePollInput, +} from "openclaw/plugin-sdk/media-runtime"; +export { loadWebMedia } from "openclaw/plugin-sdk/web-media"; diff --git a/extensions/telegram/src/send.test-harness.ts b/extensions/telegram/src/send.test-harness.ts index 541f234d3ec..25b04af4479 100644 --- a/extensions/telegram/src/send.test-harness.ts +++ b/extensions/telegram/src/send.test-harness.ts @@ -1,3 +1,10 @@ +import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime"; +import { + buildOutboundMediaLoadOptions, + isGifMedia, + kindFromMime, + normalizePollInput, +} from "openclaw/plugin-sdk/media-runtime"; import type { MockFn } from "openclaw/plugin-sdk/testing"; import { beforeEach, vi } from "vitest"; @@ -89,14 +96,6 @@ vi.mock("openclaw/plugin-sdk/web-media", () => ({ loadWebMedia, })); -vi.mock("openclaw/plugin-sdk/media-runtime", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - getImageMetadata: vi.fn(async () => ({ ...imageMetadata })), - }; -}); - vi.mock("grammy", () => ({ API_CONSTANTS: { DEFAULT_UPDATE_TYPES: ["message"], @@ -136,14 +135,17 @@ vi.mock("undici", () => ({ setGlobalDispatcher: undiciSetGlobalDispatcher, })); -vi.mock("openclaw/plugin-sdk/config-runtime", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - loadConfig, - resolveStorePath, - }; -}); +vi.mock("./send.runtime.js", () => ({ + buildOutboundMediaLoadOptions, + getImageMetadata: vi.fn(async () => ({ ...imageMetadata })), + isGifMedia, + kindFromMime, + loadConfig, + loadWebMedia, + normalizePollInput, + resolveMarkdownTableMode, + resolveStorePath, +})); vi.mock("./target-writeback.js", () => ({ maybePersistResolvedTelegramTarget, diff --git a/extensions/telegram/src/send.ts b/extensions/telegram/src/send.ts index 6ac0fad363f..fcc689048ba 100644 --- a/extensions/telegram/src/send.ts +++ b/extensions/telegram/src/send.ts @@ -6,22 +6,14 @@ import type { } from "@grammyjs/types"; import { type ApiClientOptions, Bot, HttpError } from "grammy"; import * as grammy from "grammy"; -import { loadConfig } from "openclaw/plugin-sdk/config-runtime"; -import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime"; import { isDiagnosticFlagEnabled } from "openclaw/plugin-sdk/diagnostic-runtime"; import { formatUncaughtError } from "openclaw/plugin-sdk/error-runtime"; import { recordChannelActivity } from "openclaw/plugin-sdk/infra-runtime"; -import type { MediaKind } from "openclaw/plugin-sdk/media-runtime"; -import { buildOutboundMediaLoadOptions } from "openclaw/plugin-sdk/media-runtime"; -import { getImageMetadata } from "openclaw/plugin-sdk/media-runtime"; -import { isGifMedia, kindFromMime } from "openclaw/plugin-sdk/media-runtime"; -import { normalizePollInput, type PollInput } from "openclaw/plugin-sdk/media-runtime"; import { createTelegramRetryRunner, type RetryConfig } from "openclaw/plugin-sdk/retry-runtime"; import { logVerbose } from "openclaw/plugin-sdk/runtime-env"; import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env"; import { formatErrorMessage } from "openclaw/plugin-sdk/ssrf-runtime"; import { redactSensitiveText } from "openclaw/plugin-sdk/text-runtime"; -import { loadWebMedia } from "openclaw/plugin-sdk/web-media"; import { type ResolvedTelegramAccount, resolveTelegramAccount } from "./accounts.js"; import { withTelegramApiErrorLogging } from "./api-logging.js"; import { buildTelegramThreadParams, buildTypingThreadParams } from "./bot/helpers.js"; @@ -37,6 +29,18 @@ import { } from "./network-errors.js"; import { normalizeTelegramReplyToMessageId } from "./outbound-params.js"; import { makeProxyFetch } from "./proxy.js"; +import { + buildOutboundMediaLoadOptions, + getImageMetadata, + isGifMedia, + kindFromMime, + loadConfig, + loadWebMedia, + normalizePollInput, + type PollInput, + type MediaKind, + resolveMarkdownTableMode, +} from "./send.runtime.js"; import { recordSentMessage } from "./sent-message-cache.js"; import { maybePersistResolvedTelegramTarget } from "./target-writeback.js"; import { diff --git a/extensions/telegram/src/sendchataction-401-backoff.test.ts b/extensions/telegram/src/sendchataction-401-backoff.test.ts index 641479fc00a..e070066fb7e 100644 --- a/extensions/telegram/src/sendchataction-401-backoff.test.ts +++ b/extensions/telegram/src/sendchataction-401-backoff.test.ts @@ -5,13 +5,10 @@ const mocks = vi.hoisted(() => ({ })); // Mock the runtime-exported backoff sleep that the handler actually imports. -vi.mock("openclaw/plugin-sdk/runtime-env", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - sleepWithAbort: mocks.sleepWithAbort, - }; -}); +vi.mock("openclaw/plugin-sdk/runtime-env", () => ({ + computeBackoff: vi.fn((_policy, attempt: number) => attempt * 1000), + sleepWithAbort: mocks.sleepWithAbort, +})); let createTelegramSendChatActionHandler: typeof import("./sendchataction-401-backoff.js").createTelegramSendChatActionHandler;