refactor(test): share telegram send test setup

This commit is contained in:
Peter Steinberger
2026-02-14 21:08:29 +00:00
parent 96f80d6d82
commit 3c043f5d2d
4 changed files with 95 additions and 157 deletions

View File

@@ -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<typeof import("../config/config.js")>();
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

View File

@@ -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<typeof import("../config/config.js")>();
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 } },

View File

@@ -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<typeof import("../config/config.js")>();
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");
}

View File

@@ -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<typeof import("../config/config.js")>();
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