Skip to content

Commit cf04f9e

Browse files
authored
Merge pull request #4 from cs-internship/feature/add-base64
feat: implement base64 image conversion and update related
2 parents 9975822 + d3deb9f commit cf04f9e

8 files changed

Lines changed: 265 additions & 117 deletions

File tree

__tests__/bot/handlers/messages/groupHandler.extra.test.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
jest.resetModules();
22

3+
const mockFetchSuccess = () =>
4+
jest.doMock("node-fetch", () =>
5+
jest.fn(async () => ({
6+
ok: true,
7+
buffer: async () => Buffer.from("imgdata"),
8+
}))
9+
);
10+
11+
mockFetchSuccess();
12+
313
describe("groupHandler additional edge branches", () => {
414
test("buildChunks uses formatGroupMessageChunks when available", async () => {
515
jest.resetModules();
@@ -33,15 +43,15 @@ describe("groupHandler additional edge branches", () => {
3343
} = require("../../../../bot/services/perplexity");
3444
const groupHandler = require("../../../../bot/handlers/messages/groupHandler");
3545

36-
let editedText = null;
3746
const ctx = {
3847
message: { text: "hi", entities: [], message_id: 1 },
3948
chat: { id: 1, type: "group" },
4049
from: { username: "user" },
4150
telegram: {
4251
sendMessage: async () => ({ message_id: 10 }),
4352
editMessageText: async (c, mid, u, text) => {
44-
editedText = text;
53+
// eslint-disable-next-line no-unused-vars
54+
const editedText = text;
4555
},
4656
callApi: async () => {},
4757
getFile: async () => ({ file_path: "p" }),
@@ -64,6 +74,7 @@ describe("groupHandler additional edge branches", () => {
6474

6575
test("media_group setTimeout catch logs error when processMessage throws", async () => {
6676
jest.resetModules();
77+
mockFetchSuccess();
6778

6879
const consoleSpy = jest
6980
.spyOn(console, "error")

__tests__/bot/handlers/messages/groupHandler.test.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
jest.resetModules();
22

3+
const mockFetchSuccess = () =>
4+
jest.doMock("node-fetch", () =>
5+
jest.fn(async () => ({
6+
ok: true,
7+
buffer: async () => Buffer.from("imgdata"),
8+
}))
9+
);
10+
11+
mockFetchSuccess();
12+
313
// Mock deps
414
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
515
groupMessageValidator: jest.fn().mockResolvedValue(true),
@@ -75,7 +85,7 @@ test("photo message gets file and included in photoUrls", async () => {
7585
};
7686
const _ctx = await runHandler(message);
7787
expect(sendToPerplexity).toHaveBeenCalledWith("with photo", [
78-
"https://api.telegram.org/file/botTOKEN/path.jpg",
88+
"data:image/jpeg;base64,aW1nZGF0YQ==",
7989
]);
8090
});
8191

@@ -197,6 +207,7 @@ test("error response from sendToPerplexity triggers editMessageText with error e
197207
};
198208
// re-require module to use overwritten sendToPerplexity
199209
jest.resetModules();
210+
mockFetchSuccess();
200211
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
201212
groupMessageValidator: jest.fn().mockResolvedValue(true),
202213
}));
@@ -224,6 +235,7 @@ test("error response from sendToPerplexity triggers editMessageText with error e
224235
test("processing error triggers fallback reply and fallback sendMessage in processMessage", async () => {
225236
// simulate sendToPerplexity throwing inside processMessage to hit fallback sendMessage
226237
jest.resetModules();
238+
mockFetchSuccess();
227239
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
228240
groupMessageValidator: jest.fn().mockResolvedValue(true),
229241
}));
@@ -278,6 +290,7 @@ test("processing error triggers fallback reply and fallback sendMessage in proce
278290

279291
test("splits long response into multiple chunks and sends subsequent messages", async () => {
280292
jest.resetModules();
293+
mockFetchSuccess();
281294
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
282295
groupMessageValidator: jest.fn().mockResolvedValue(true),
283296
}));
@@ -364,6 +377,7 @@ test("private chat returns next() immediately", async () => {
364377

365378
test("exact-command reaction callApi throws but does not call perplexity", async () => {
366379
jest.resetModules();
380+
mockFetchSuccess();
367381
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
368382
groupMessageValidator: jest.fn().mockResolvedValue(true),
369383
}));
@@ -408,6 +422,7 @@ test("exact-command reaction callApi throws but does not call perplexity", async
408422

409423
test("photo getFile throws and processing continues without photoUrls", async () => {
410424
jest.resetModules();
425+
mockFetchSuccess();
411426
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
412427
groupMessageValidator: jest.fn().mockResolvedValue(true),
413428
}));
@@ -465,6 +480,7 @@ test("photo getFile throws and processing continues without photoUrls", async ()
465480

466481
test("media_group processing logs error when processing throws inside timeout", async () => {
467482
jest.resetModules();
483+
mockFetchSuccess();
468484
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
469485
groupMessageValidator: jest.fn().mockResolvedValue(true),
470486
}));
@@ -540,6 +556,7 @@ test("media_group processing logs error when processing throws inside timeout",
540556

541557
test("processMessage handles errorEntry for media_group by editing message with error text", async () => {
542558
jest.resetModules();
559+
mockFetchSuccess();
543560
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
544561
groupMessageValidator: jest.fn().mockResolvedValue(true),
545562
}));
@@ -619,6 +636,7 @@ test("processMessage handles errorEntry for media_group by editing message with
619636

620637
test("processMessage splits long response into chunks for media_group and sends subsequent messages", async () => {
621638
jest.resetModules();
639+
mockFetchSuccess();
622640
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
623641
groupMessageValidator: jest.fn().mockResolvedValue(true),
624642
}));
@@ -699,6 +717,7 @@ test("processMessage splits long response into chunks for media_group and sends
699717

700718
test("top-level handler fallback reply when sendToPerplexity throws", async () => {
701719
jest.resetModules();
720+
mockFetchSuccess();
702721
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
703722
groupMessageValidator: jest.fn().mockResolvedValue(true),
704723
}));
@@ -753,6 +772,7 @@ test("top-level handler fallback reply when sendToPerplexity throws", async () =
753772

754773
test("top-level nested fallback logs error when ctx.reply also throws", async () => {
755774
jest.resetModules();
775+
mockFetchSuccess();
756776
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
757777
groupMessageValidator: jest.fn().mockResolvedValue(true),
758778
}));
@@ -811,6 +831,7 @@ test("top-level nested fallback logs error when ctx.reply also throws", async ()
811831

812832
test("processMessage nested fallback logs error when fallback sendMessage throws", async () => {
813833
jest.resetModules();
834+
mockFetchSuccess();
814835
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
815836
groupMessageValidator: jest.fn().mockResolvedValue(true),
816837
}));
@@ -892,6 +913,7 @@ test("processMessage nested fallback logs error when fallback sendMessage throws
892913

893914
test("direct call to _processMessage edits message when errorEntry returned", async () => {
894915
jest.resetModules();
916+
mockFetchSuccess();
895917
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
896918
groupMessageValidator: jest.fn().mockResolvedValue(true),
897919
}));
@@ -925,6 +947,7 @@ test("direct call to _processMessage edits message when errorEntry returned", as
925947

926948
test("direct call to _processMessage logs error when fallback sendMessage throws", async () => {
927949
jest.resetModules();
950+
mockFetchSuccess();
928951
jest.doMock("../../../../bot/utils/groupMessageValidator", () => ({
929952
groupMessageValidator: jest.fn().mockResolvedValue(true),
930953
}));

__tests__/bot/utils/branchCoverage.test.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,6 @@ describe("Branch coverage extra edge cases", () => {
44
expect(safeChunkText("")).toEqual([]);
55
});
66

7-
test("createOptions with undefined message still sets system message", () => {
8-
jest.resetModules();
9-
jest.doMock("../../../bot/constants/systemMessage", () => ({
10-
systemMessage: "SYS",
11-
}));
12-
const { createOptions } = require("../../../bot/utils/createOptions");
13-
const opts = createOptions("K");
14-
const body = JSON.parse(opts.body);
15-
expect(body.messages[0].content[0].text).toBe("SYS");
16-
});
17-
187
test("getUsernameByFullname empty rich_text returns null", async () => {
198
jest.resetModules();
209
jest.doMock("@notionhq/client", () => ({

__tests__/bot/utils/formatGroupMessageChunks.test.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ const {
22
formatGroupMessageChunks,
33
} = require("../../../bot/utils/formatGroupMessage");
44

5-
const explanationLink =
6-
"\n\nتوضیح نحوه ساخت پیام:\n\nhttps://t.me/cs_internship/729";
7-
85
describe("formatGroupMessageChunks", () => {
96
test("when no chart splits by lines and escapes", () => {
107
const resp = "hello & world";

0 commit comments

Comments
 (0)