diff --git a/src/telegram/send.caption-split.test.ts b/src/telegram/send.caption-split.test.ts index 7911e289082..564f3138880 100644 --- a/src/telegram/send.caption-split.test.ts +++ b/src/telegram/send.caption-split.test.ts @@ -1,59 +1,16 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { describe, expect, it, vi } from "vitest"; +import { + getTelegramSendTestMocks, + importTelegramSendModule, + installTelegramSendTestHooks, +} from "./send.test-harness.js"; -const { botApi, botCtorSpy } = vi.hoisted(() => ({ - botApi: { - sendMessage: vi.fn(), - sendPhoto: vi.fn(), - }, - botCtorSpy: vi.fn(), -})); +installTelegramSendTestHooks(); -const { loadWebMedia } = vi.hoisted(() => ({ - loadWebMedia: vi.fn(), -})); - -vi.mock("../web/media.js", () => ({ - loadWebMedia, -})); - -vi.mock("grammy", () => ({ - Bot: class { - api = botApi; - catch = vi.fn(); - constructor( - public token: string, - public options?: { - client?: { fetch?: typeof fetch; timeoutSeconds?: number }; - }, - ) { - botCtorSpy(token, options); - } - }, - InputFile: class {}, -})); - -const { loadConfig } = vi.hoisted(() => ({ - loadConfig: vi.fn(() => ({})), -})); -vi.mock("../config/config.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - loadConfig, - }; -}); - -import { sendMessageTelegram } from "./send.js"; +const { loadWebMedia } = getTelegramSendTestMocks(); +const { sendMessageTelegram } = await importTelegramSendModule(); describe("sendMessageTelegram caption splitting", () => { - beforeEach(() => { - loadConfig.mockReturnValue({}); - loadWebMedia.mockReset(); - botApi.sendMessage.mockReset(); - botApi.sendPhoto.mockReset(); - botCtorSpy.mockReset(); - }); - it("splits long captions into media + text messages when text exceeds 1024 chars", async () => { const chatId = "123"; // Generate text longer than 1024 characters diff --git a/src/telegram/send.returns-undefined-empty-input.test.ts b/src/telegram/send.returns-undefined-empty-input.test.ts index b73a3292684..d0d9eb7cd47 100644 --- a/src/telegram/send.returns-undefined-empty-input.test.ts +++ b/src/telegram/send.returns-undefined-empty-input.test.ts @@ -1,50 +1,15 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; +import { + getTelegramSendTestMocks, + importTelegramSendModule, + installTelegramSendTestHooks, +} from "./send.test-harness.js"; -const { botApi, botCtorSpy } = vi.hoisted(() => ({ - botApi: { - sendMessage: vi.fn(), - setMessageReaction: vi.fn(), - sendSticker: vi.fn(), - }, - botCtorSpy: vi.fn(), -})); +installTelegramSendTestHooks(); -const { loadWebMedia } = vi.hoisted(() => ({ - loadWebMedia: vi.fn(), -})); - -vi.mock("../web/media.js", () => ({ - loadWebMedia, -})); - -vi.mock("grammy", () => ({ - Bot: class { - api = botApi; - catch = vi.fn(); - constructor( - public token: string, - public options?: { - client?: { fetch?: typeof fetch; timeoutSeconds?: number }; - }, - ) { - botCtorSpy(token, options); - } - }, - InputFile: class {}, -})); - -const { loadConfig } = vi.hoisted(() => ({ - loadConfig: vi.fn(() => ({})), -})); -vi.mock("../config/config.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - loadConfig, - }; -}); - -import { buildInlineKeyboard, sendMessageTelegram, sendStickerTelegram } from "./send.js"; +const { botApi, botCtorSpy, loadConfig, loadWebMedia } = getTelegramSendTestMocks(); +const { buildInlineKeyboard, sendMessageTelegram, sendStickerTelegram } = + await importTelegramSendModule(); describe("buildInlineKeyboard", () => { it("returns undefined for empty input", () => { @@ -87,13 +52,6 @@ describe("buildInlineKeyboard", () => { }); describe("sendMessageTelegram", () => { - beforeEach(() => { - loadConfig.mockReturnValue({}); - loadWebMedia.mockReset(); - botApi.sendMessage.mockReset(); - botCtorSpy.mockReset(); - }); - it("passes timeoutSeconds to grammY client when configured", async () => { loadConfig.mockReturnValue({ channels: { telegram: { timeoutSeconds: 60 } }, diff --git a/src/telegram/send.test-harness.ts b/src/telegram/send.test-harness.ts new file mode 100644 index 00000000000..79d05ded658 --- /dev/null +++ b/src/telegram/send.test-harness.ts @@ -0,0 +1,68 @@ +import { beforeEach, vi } from "vitest"; + +const { botApi, botCtorSpy } = vi.hoisted(() => ({ + botApi: { + sendMessage: vi.fn(), + sendPhoto: vi.fn(), + sendVideo: vi.fn(), + sendVideoNote: vi.fn(), + setMessageReaction: vi.fn(), + sendSticker: vi.fn(), + }, + botCtorSpy: vi.fn(), +})); + +const { loadWebMedia } = vi.hoisted(() => ({ + loadWebMedia: vi.fn(), +})); + +const { loadConfig } = vi.hoisted(() => ({ + loadConfig: vi.fn(() => ({})), +})); + +vi.mock("../web/media.js", () => ({ + loadWebMedia, +})); + +vi.mock("grammy", () => ({ + Bot: class { + api = botApi; + catch = vi.fn(); + constructor( + public token: string, + public options?: { + client?: { fetch?: typeof fetch; timeoutSeconds?: number }; + }, + ) { + botCtorSpy(token, options); + } + }, + InputFile: class {}, +})); + +vi.mock("../config/config.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + loadConfig, + }; +}); + +export function getTelegramSendTestMocks() { + return { botApi, botCtorSpy, loadConfig, loadWebMedia }; +} + +export function installTelegramSendTestHooks() { + beforeEach(() => { + loadConfig.mockReturnValue({}); + loadWebMedia.mockReset(); + botCtorSpy.mockReset(); + for (const fn of Object.values(botApi)) { + fn.mockReset(); + } + }); +} + +export async function importTelegramSendModule() { + return await import("./send.js"); +} diff --git a/src/telegram/send.video-note.test.ts b/src/telegram/send.video-note.test.ts index 6a42305f6a0..6924bad2170 100644 --- a/src/telegram/send.video-note.test.ts +++ b/src/telegram/send.video-note.test.ts @@ -1,61 +1,16 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { describe, expect, it, vi } from "vitest"; +import { + getTelegramSendTestMocks, + importTelegramSendModule, + installTelegramSendTestHooks, +} from "./send.test-harness.js"; -const { botApi, botCtorSpy } = vi.hoisted(() => ({ - botApi: { - sendMessage: vi.fn(), - sendVideo: vi.fn(), - sendVideoNote: vi.fn(), - }, - botCtorSpy: vi.fn(), -})); +installTelegramSendTestHooks(); -const { loadWebMedia } = vi.hoisted(() => ({ - loadWebMedia: vi.fn(), -})); - -vi.mock("../web/media.js", () => ({ - loadWebMedia, -})); - -vi.mock("grammy", () => ({ - Bot: class { - api = botApi; - catch = vi.fn(); - constructor( - public token: string, - public options?: { - client?: { fetch?: typeof fetch; timeoutSeconds?: number }; - }, - ) { - botCtorSpy(token, options); - } - }, - InputFile: class {}, -})); - -const { loadConfig } = vi.hoisted(() => ({ - loadConfig: vi.fn(() => ({})), -})); -vi.mock("../config/config.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - loadConfig, - }; -}); - -import { sendMessageTelegram } from "./send.js"; +const { loadWebMedia } = getTelegramSendTestMocks(); +const { sendMessageTelegram } = await importTelegramSendModule(); describe("sendMessageTelegram video notes", () => { - beforeEach(() => { - loadConfig.mockReturnValue({}); - loadWebMedia.mockReset(); - botApi.sendMessage.mockReset(); - botApi.sendVideo.mockReset(); - botApi.sendVideoNote.mockReset(); - botCtorSpy.mockReset(); - }); - it("sends video as video note when asVideoNote is true", async () => { const chatId = "123"; const text = "ignored caption context"; // Should be sent separately