From 950d5a46b292e311fc458cfd71a96861567c1c5e Mon Sep 17 00:00:00 2001 From: cpojer Date: Tue, 17 Feb 2026 10:26:36 +0900 Subject: [PATCH] chore: Fix types in tests 2/N. --- .../bot.create-telegram-bot.test-harness.ts | 25 ++++++++--------- src/telegram/bot.create-telegram-bot.test.ts | 27 +++++++++++-------- src/telegram/send.ts | 21 ++++++++------- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/telegram/bot.create-telegram-bot.test-harness.ts b/src/telegram/bot.create-telegram-bot.test-harness.ts index d9646ba126a..3617fb6fd54 100644 --- a/src/telegram/bot.create-telegram-bot.test-harness.ts +++ b/src/telegram/bot.create-telegram-bot.test-harness.ts @@ -1,16 +1,13 @@ import { beforeEach, vi } from "vitest"; import { resetInboundDedupe } from "../auto-reply/reply/inbound-dedupe.js"; +import type { MsgContext } from "../auto-reply/templating.js"; +import type { GetReplyOptions, ReplyPayload } from "../auto-reply/types.js"; +import type { OpenClawConfig } from "../config/config.js"; import type { MockFn } from "../test-utils/vitest-mock-fn.js"; type AnyMock = MockFn<(...args: unknown[]) => unknown>; type AnyAsyncMock = MockFn<(...args: unknown[]) => Promise>; -type ReplyOpts = - | { - onReplyStart?: () => void | Promise; - } - | undefined; - const { sessionStorePath } = vi.hoisted(() => ({ sessionStorePath: `/tmp/openclaw-telegram-${Math.random().toString(16).slice(2)}.json`, })); @@ -185,12 +182,16 @@ vi.mock("@grammyjs/transformer-throttler", () => ({ apiThrottler: () => throttlerSpy(), })); -export const replySpy: MockFn<(ctx: unknown, opts?: ReplyOpts) => Promise> = vi.fn( - async (_ctx, opts) => { - await opts?.onReplyStart?.(); - return undefined; - }, -); +export const replySpy: MockFn< + ( + ctx: MsgContext, + opts?: GetReplyOptions, + configOverride?: OpenClawConfig, + ) => Promise +> = vi.fn(async (_ctx, opts) => { + await opts?.onReplyStart?.(); + return undefined; +}); vi.mock("../auto-reply/reply.js", () => ({ getReplyFromConfig: replySpy, diff --git a/src/telegram/bot.create-telegram-bot.test.ts b/src/telegram/bot.create-telegram-bot.test.ts index 8704eebeb7e..c0e0f3387a5 100644 --- a/src/telegram/bot.create-telegram-bot.test.ts +++ b/src/telegram/bot.create-telegram-bot.test.ts @@ -1,6 +1,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import type { Chat } from "@grammyjs/types"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { escapeRegExp, formatEnvelopeTimestamp } from "../../test/helpers/envelope-timestamp.js"; import { @@ -36,6 +37,8 @@ const readChannelAllowFromStore = getReadChannelAllowFromStoreMock(); const upsertChannelPairingRequest = getUpsertChannelPairingRequestMock(); const ORIGINAL_TZ = process.env.TZ; +const mockChat = (chat: Pick & Partial>): Chat => + chat as Chat; describe("createTelegramBot", () => { beforeEach(() => { @@ -109,55 +112,57 @@ describe("createTelegramBot", () => { expect(sequentializeSpy).toHaveBeenCalledTimes(1); expect(middlewareUseSpy).toHaveBeenCalledWith(sequentializeSpy.mock.results[0]?.value); expect(sequentializeKey).toBe(getTelegramSequentialKey); - expect(getTelegramSequentialKey({ message: { chat: { id: 123 } } })).toBe("telegram:123"); + expect(getTelegramSequentialKey({ message: { chat: mockChat({ id: 123 }) } })).toBe( + "telegram:123", + ); expect( getTelegramSequentialKey({ - message: { chat: { id: 123, type: "private" }, message_thread_id: 9 }, + message: { chat: mockChat({ id: 123, type: "private" }), message_thread_id: 9 }, }), ).toBe("telegram:123:topic:9"); expect( getTelegramSequentialKey({ - message: { chat: { id: 123, type: "supergroup" }, message_thread_id: 9 }, + message: { chat: mockChat({ id: 123, type: "supergroup" }), message_thread_id: 9 }, }), ).toBe("telegram:123"); expect( getTelegramSequentialKey({ - message: { chat: { id: 123, type: "supergroup", is_forum: true } }, + message: { chat: mockChat({ id: 123, type: "supergroup", is_forum: true }) }, }), ).toBe("telegram:123:topic:1"); expect( getTelegramSequentialKey({ - update: { message: { chat: { id: 555 } } }, + update: { message: { chat: mockChat({ id: 555 }) } }, }), ).toBe("telegram:555"); expect( getTelegramSequentialKey({ - message: { chat: { id: 123 }, text: "/stop" }, + message: { chat: mockChat({ id: 123 }), text: "/stop" }, }), ).toBe("telegram:123:control"); expect( getTelegramSequentialKey({ - message: { chat: { id: 123 }, text: "/status" }, + message: { chat: mockChat({ id: 123 }), text: "/status" }, }), ).toBe("telegram:123"); expect( getTelegramSequentialKey({ - message: { chat: { id: 123 }, text: "stop" }, + message: { chat: mockChat({ id: 123 }), text: "stop" }, }), ).toBe("telegram:123:control"); expect( getTelegramSequentialKey({ - message: { chat: { id: 123 }, text: "stop please" }, + message: { chat: mockChat({ id: 123 }), text: "stop please" }, }), ).toBe("telegram:123"); expect( getTelegramSequentialKey({ - message: { chat: { id: 123 }, text: "/abort" }, + message: { chat: mockChat({ id: 123 }), text: "/abort" }, }), ).toBe("telegram:123"); expect( getTelegramSequentialKey({ - message: { chat: { id: 123 }, text: "/abort now" }, + message: { chat: mockChat({ id: 123 }), text: "/abort now" }, }), ).toBe("telegram:123"); }); diff --git a/src/telegram/send.ts b/src/telegram/send.ts index e04372e1257..4e37a240287 100644 --- a/src/telegram/send.ts +++ b/src/telegram/send.ts @@ -33,6 +33,9 @@ import { recordSentMessage } from "./sent-message-cache.js"; import { parseTelegramTarget, stripTelegramInternalPrefixes } from "./targets.js"; import { resolveTelegramVoiceSend } from "./voice.js"; +type TelegramApi = Bot["api"]; +type TelegramApiOverride = Partial; + type TelegramSendOpts = { token?: string; accountId?: string; @@ -40,7 +43,7 @@ type TelegramSendOpts = { mediaUrl?: string; mediaLocalRoots?: readonly string[]; maxBytes?: number; - api?: Bot["api"]; + api?: TelegramApiOverride; retry?: RetryConfig; textMode?: "markdown" | "html"; plainText?: string; @@ -73,7 +76,7 @@ type TelegramMessageLike = { type TelegramReactionOpts = { token?: string; accountId?: string; - api?: Bot["api"]; + api?: TelegramApiOverride; remove?: boolean; verbose?: boolean; retry?: RetryConfig; @@ -289,13 +292,13 @@ async function withTelegramHtmlParseFallback(params: { type TelegramApiContext = { cfg: ReturnType; account: ResolvedTelegramAccount; - api: Bot["api"]; + api: TelegramApi; }; function resolveTelegramApiContext(opts: { token?: string; accountId?: string; - api?: Bot["api"]; + api?: TelegramApiOverride; cfg?: ReturnType; }): TelegramApiContext { const cfg = opts.cfg ?? loadConfig(); @@ -305,7 +308,7 @@ function resolveTelegramApiContext(opts: { }); const token = resolveToken(opts.token, account); const client = resolveTelegramClientOptions(account); - const api = opts.api ?? new Bot(token, client ? { client } : undefined).api; + const api = (opts.api ?? new Bot(token, client ? { client } : undefined).api) as TelegramApi; return { cfg, account, api }; } @@ -759,7 +762,7 @@ type TelegramDeleteOpts = { token?: string; accountId?: string; verbose?: boolean; - api?: Bot["api"]; + api?: TelegramApiOverride; retry?: RetryConfig; }; @@ -787,7 +790,7 @@ type TelegramEditOpts = { token?: string; accountId?: string; verbose?: boolean; - api?: Bot["api"]; + api?: TelegramApiOverride; retry?: RetryConfig; textMode?: "markdown" | "html"; /** Controls whether link previews are shown in the edited message. */ @@ -904,7 +907,7 @@ type TelegramStickerOpts = { token?: string; accountId?: string; verbose?: boolean; - api?: Bot["api"]; + api?: TelegramApiOverride; retry?: RetryConfig; /** Message ID to reply to (for threading) */ replyToMessageId?: number; @@ -980,7 +983,7 @@ type TelegramPollOpts = { token?: string; accountId?: string; verbose?: boolean; - api?: Bot["api"]; + api?: TelegramApiOverride; retry?: RetryConfig; /** Message ID to reply to (for threading) */ replyToMessageId?: number;