@mks2508/telegram-message-builder 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder/builder.d.ts +87 -0
- package/dist/builder/index.d.ts +2 -0
- package/dist/builder/media.d.ts +351 -0
- package/dist/formatters/index.d.ts +86 -0
- package/dist/formatters/markdown.d.ts +178 -0
- package/dist/formatters/markdownv2.d.ts +183 -0
- package/dist/index.cjs +1057 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.js +1022 -13
- package/dist/index.js.map +1 -1
- package/dist/keyboard/index.d.ts +113 -0
- package/dist/types/constants.d.ts +13 -0
- package/dist/types/core.types.d.ts +74 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/keyboard-types.index.d.ts +1 -0
- package/dist/types/keyboard.types.d.ts +95 -0
- package/dist/types/main.types.d.ts +22 -0
- package/dist/types/media.types.d.ts +157 -0
- package/package.json +1 -1
- package/src/builder/builder.d.ts +55 -0
- package/src/builder/builder.d.ts.map +1 -1
- package/src/builder/builder.ts +145 -10
- package/src/builder/index.d.ts +2 -1
- package/src/builder/index.d.ts.map +1 -1
- package/src/builder/index.ts +2 -1
- package/src/builder/media.d.ts +352 -0
- package/src/builder/media.d.ts.map +1 -0
- package/src/builder/media.test.ts +664 -0
- package/src/builder/media.ts +484 -0
- package/src/builder.test.ts +465 -0
- package/src/escaping.test.ts +2 -2
- package/src/formatters/index.d.ts +47 -0
- package/src/formatters/index.d.ts.map +1 -1
- package/src/formatters/index.ts +92 -1
- package/src/formatters/markdown.d.ts +179 -0
- package/src/formatters/markdown.d.ts.map +1 -0
- package/src/formatters/markdown.test.ts +417 -0
- package/src/formatters/markdown.ts +220 -0
- package/src/formatters/markdownv2.d.ts +184 -0
- package/src/formatters/markdownv2.d.ts.map +1 -0
- package/src/formatters/markdownv2.ts +235 -0
- package/src/formatters.test.ts +17 -7
- package/src/index.d.ts +2 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.ts +12 -0
- package/src/integration.test.ts +523 -0
- package/src/media-integration.test.ts +384 -0
- package/src/types/index.d.ts +1 -0
- package/src/types/index.d.ts.map +1 -1
- package/src/types/index.ts +1 -0
- package/src/types/media.types.d.ts +158 -0
- package/src/types/media.types.d.ts.map +1 -0
- package/src/types/media.types.ts +178 -0
- package/src/types.test.ts +539 -0
- package/src/utils/index.d.ts +1 -1
- package/src/utils/index.ts +0 -5
|
@@ -0,0 +1,664 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { TelegramMediaBuilder } from "./media";
|
|
3
|
+
import type { MediaSource, MediaType, IMediaBuildResult } from "../types";
|
|
4
|
+
|
|
5
|
+
describe("TelegramMediaBuilder", () => {
|
|
6
|
+
describe("Static Factory Methods", () => {
|
|
7
|
+
it("should create photo builder", () => {
|
|
8
|
+
const builder = TelegramMediaBuilder.photo("photo.jpg");
|
|
9
|
+
const result = builder.build();
|
|
10
|
+
|
|
11
|
+
expect(result.type).toBe("photo");
|
|
12
|
+
expect(result.media).toBe("photo.jpg");
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("should create video builder", () => {
|
|
16
|
+
const builder = TelegramMediaBuilder.video("video.mp4");
|
|
17
|
+
const result = builder.build();
|
|
18
|
+
|
|
19
|
+
expect(result.type).toBe("video");
|
|
20
|
+
expect(result.media).toBe("video.mp4");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should create document builder", () => {
|
|
24
|
+
const builder = TelegramMediaBuilder.document("doc.pdf");
|
|
25
|
+
const result = builder.build();
|
|
26
|
+
|
|
27
|
+
expect(result.type).toBe("document");
|
|
28
|
+
expect(result.media).toBe("doc.pdf");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should create audio builder", () => {
|
|
32
|
+
const builder = TelegramMediaBuilder.audio("audio.mp3");
|
|
33
|
+
const result = builder.build();
|
|
34
|
+
|
|
35
|
+
expect(result.type).toBe("audio");
|
|
36
|
+
expect(result.media).toBe("audio.mp3");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should create voice builder", () => {
|
|
40
|
+
const builder = TelegramMediaBuilder.voice("voice.ogg");
|
|
41
|
+
const result = builder.build();
|
|
42
|
+
|
|
43
|
+
expect(result.type).toBe("voice");
|
|
44
|
+
expect(result.media).toBe("voice.ogg");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should accept Buffer as media source", () => {
|
|
48
|
+
const buffer = Buffer.from("test");
|
|
49
|
+
const builder = TelegramMediaBuilder.photo(buffer);
|
|
50
|
+
const result = builder.build();
|
|
51
|
+
|
|
52
|
+
expect(result.media).toBe(buffer);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("should accept URL as media source", () => {
|
|
56
|
+
const url = "https://example.com/photo.jpg";
|
|
57
|
+
const builder = TelegramMediaBuilder.photo(url);
|
|
58
|
+
const result = builder.build();
|
|
59
|
+
|
|
60
|
+
expect(result.media).toBe(url);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should accept file_id as media source", () => {
|
|
64
|
+
const fileId = "AgACAgIAAxkBAAI...";
|
|
65
|
+
const builder = TelegramMediaBuilder.photo(fileId);
|
|
66
|
+
const result = builder.build();
|
|
67
|
+
|
|
68
|
+
expect(result.media).toBe(fileId);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("Common Methods", () => {
|
|
73
|
+
it("should set caption", () => {
|
|
74
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
75
|
+
.caption("My photo")
|
|
76
|
+
.build();
|
|
77
|
+
|
|
78
|
+
expect(result.caption).toBe("My photo");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("should set parse mode to html", () => {
|
|
82
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
83
|
+
.caption("Test")
|
|
84
|
+
.setParseMode("html")
|
|
85
|
+
.build();
|
|
86
|
+
|
|
87
|
+
expect(result.parse_mode).toBe("html");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("should set parse mode to markdown", () => {
|
|
91
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
92
|
+
.caption("Test")
|
|
93
|
+
.setParseMode("markdown")
|
|
94
|
+
.build();
|
|
95
|
+
|
|
96
|
+
expect(result.parse_mode).toBe("markdown");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("should set parse mode to markdownv2", () => {
|
|
100
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
101
|
+
.caption("Test")
|
|
102
|
+
.setParseMode("markdownv2")
|
|
103
|
+
.build();
|
|
104
|
+
|
|
105
|
+
expect(result.parse_mode).toBe("markdownv2");
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("should set custom option", () => {
|
|
109
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
110
|
+
.setOption("protect_content", true)
|
|
111
|
+
.build();
|
|
112
|
+
|
|
113
|
+
expect(result.protect_content).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("should set multiple options", () => {
|
|
117
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
118
|
+
.setOptions({
|
|
119
|
+
protect_content: true,
|
|
120
|
+
disable_notification: true,
|
|
121
|
+
})
|
|
122
|
+
.build();
|
|
123
|
+
|
|
124
|
+
expect(result.protect_content).toBe(true);
|
|
125
|
+
expect(result.disable_notification).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("should build with all options", () => {
|
|
129
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
130
|
+
.caption("My photo")
|
|
131
|
+
.setParseMode("html")
|
|
132
|
+
.setOption("protect_content", true)
|
|
133
|
+
.build();
|
|
134
|
+
|
|
135
|
+
expect(result.type).toBe("photo");
|
|
136
|
+
expect(result.media).toBe("photo.jpg");
|
|
137
|
+
expect(result.caption).toBe("My photo");
|
|
138
|
+
expect(result.parse_mode).toBe("html");
|
|
139
|
+
expect(result.protect_content).toBe(true);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("Photo Builder", () => {
|
|
144
|
+
it("should set thumbnail with string", () => {
|
|
145
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
146
|
+
.thumbnail("thumb.jpg")
|
|
147
|
+
.build();
|
|
148
|
+
|
|
149
|
+
expect(result.thumb).toBe("thumb.jpg");
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("should set thumbnail with Buffer", () => {
|
|
153
|
+
const thumb = Buffer.from("thumbnail");
|
|
154
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
155
|
+
.thumbnail(thumb)
|
|
156
|
+
.build();
|
|
157
|
+
|
|
158
|
+
expect(result.thumb).toBe(thumb);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("should build photo message", () => {
|
|
162
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
163
|
+
.caption("Beautiful sunset")
|
|
164
|
+
.thumbnail("thumb.jpg")
|
|
165
|
+
.build();
|
|
166
|
+
|
|
167
|
+
expect(result.type).toBe("photo");
|
|
168
|
+
expect(result.media).toBe("photo.jpg");
|
|
169
|
+
expect(result.caption).toBe("Beautiful sunset");
|
|
170
|
+
expect(result.thumb).toBe("thumb.jpg");
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("should support all photo options", () => {
|
|
174
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
175
|
+
.caption("Photo caption")
|
|
176
|
+
.setParseMode("markdown")
|
|
177
|
+
.thumbnail("thumb.jpg")
|
|
178
|
+
.setOption("show_caption_above_media", true)
|
|
179
|
+
.setOption("protect_content", true)
|
|
180
|
+
.build();
|
|
181
|
+
|
|
182
|
+
expect(result.caption).toBe("Photo caption");
|
|
183
|
+
expect(result.parse_mode).toBe("markdown");
|
|
184
|
+
expect(result.thumb).toBe("thumb.jpg");
|
|
185
|
+
expect(result.show_caption_above_media).toBe(true);
|
|
186
|
+
expect(result.protect_content).toBe(true);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe("Video Builder", () => {
|
|
191
|
+
it("should set duration", () => {
|
|
192
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
193
|
+
.duration(120)
|
|
194
|
+
.build();
|
|
195
|
+
|
|
196
|
+
expect(result.duration).toBe(120);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("should set width", () => {
|
|
200
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
201
|
+
.width(1920)
|
|
202
|
+
.build();
|
|
203
|
+
|
|
204
|
+
expect(result.width).toBe(1920);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it("should set height", () => {
|
|
208
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
209
|
+
.height(1080)
|
|
210
|
+
.build();
|
|
211
|
+
|
|
212
|
+
expect(result.height).toBe(1080);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("should set thumbnail", () => {
|
|
216
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
217
|
+
.thumbnail("thumb.jpg")
|
|
218
|
+
.build();
|
|
219
|
+
|
|
220
|
+
expect(result.thumb).toBe("thumb.jpg");
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it("should enable streaming", () => {
|
|
224
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
225
|
+
.enableStreaming()
|
|
226
|
+
.build();
|
|
227
|
+
|
|
228
|
+
expect(result.support_streaming).toBe(true);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("should build video message", () => {
|
|
232
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
233
|
+
.caption("My video")
|
|
234
|
+
.duration(120)
|
|
235
|
+
.width(1920)
|
|
236
|
+
.height(1080)
|
|
237
|
+
.thumbnail("thumb.jpg")
|
|
238
|
+
.build();
|
|
239
|
+
|
|
240
|
+
expect(result.type).toBe("video");
|
|
241
|
+
expect(result.media).toBe("video.mp4");
|
|
242
|
+
expect(result.caption).toBe("My video");
|
|
243
|
+
expect(result.duration).toBe(120);
|
|
244
|
+
expect(result.width).toBe(1920);
|
|
245
|
+
expect(result.height).toBe(1080);
|
|
246
|
+
expect(result.thumb).toBe("thumb.jpg");
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
describe("Document Builder", () => {
|
|
251
|
+
it("should set thumbnail", () => {
|
|
252
|
+
const result = TelegramMediaBuilder.document("doc.pdf")
|
|
253
|
+
.thumbnail("thumb.jpg")
|
|
254
|
+
.build();
|
|
255
|
+
|
|
256
|
+
expect(result.thumb).toBe("thumb.jpg");
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it("should set filename", () => {
|
|
260
|
+
const result = TelegramMediaBuilder.document("doc.pdf")
|
|
261
|
+
.fileName("report.pdf")
|
|
262
|
+
.build();
|
|
263
|
+
|
|
264
|
+
expect(result.file_name).toBe("report.pdf");
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it("should set mime type", () => {
|
|
268
|
+
const result = TelegramMediaBuilder.document("doc.pdf")
|
|
269
|
+
.mimeType("application/pdf")
|
|
270
|
+
.build();
|
|
271
|
+
|
|
272
|
+
expect(result.mime_type).toBe("application/pdf");
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("should disable content type detection", () => {
|
|
276
|
+
const result = TelegramMediaBuilder.document("file.bin")
|
|
277
|
+
.disableContentTypeDetection()
|
|
278
|
+
.build();
|
|
279
|
+
|
|
280
|
+
expect(result.disable_content_type_detection).toBe(true);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it("should build document message", () => {
|
|
284
|
+
const result = TelegramMediaBuilder.document("report.pdf")
|
|
285
|
+
.caption("Q4 Report")
|
|
286
|
+
.fileName("q4_2024.pdf")
|
|
287
|
+
.mimeType("application/pdf")
|
|
288
|
+
.disableContentTypeDetection()
|
|
289
|
+
.build();
|
|
290
|
+
|
|
291
|
+
expect(result.type).toBe("document");
|
|
292
|
+
expect(result.media).toBe("report.pdf");
|
|
293
|
+
expect(result.caption).toBe("Q4 Report");
|
|
294
|
+
expect(result.file_name).toBe("q4_2024.pdf");
|
|
295
|
+
expect(result.mime_type).toBe("application/pdf");
|
|
296
|
+
expect(result.disable_content_type_detection).toBe(true);
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
describe("Audio Builder", () => {
|
|
301
|
+
it("should set duration", () => {
|
|
302
|
+
const result = TelegramMediaBuilder.audio("song.mp3")
|
|
303
|
+
.duration(180)
|
|
304
|
+
.build();
|
|
305
|
+
|
|
306
|
+
expect(result.duration).toBe(180);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it("should set performer", () => {
|
|
310
|
+
const result = TelegramMediaBuilder.audio("song.mp3")
|
|
311
|
+
.performer("Artist Name")
|
|
312
|
+
.build();
|
|
313
|
+
|
|
314
|
+
expect(result.performer).toBe("Artist Name");
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it("should set title", () => {
|
|
318
|
+
const result = TelegramMediaBuilder.audio("song.mp3")
|
|
319
|
+
.title("Song Title")
|
|
320
|
+
.build();
|
|
321
|
+
|
|
322
|
+
expect(result.title).toBe("Song Title");
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it("should set thumbnail", () => {
|
|
326
|
+
const result = TelegramMediaBuilder.audio("song.mp3")
|
|
327
|
+
.thumbnail("album_art.jpg")
|
|
328
|
+
.build();
|
|
329
|
+
|
|
330
|
+
expect(result.thumb).toBe("album_art.jpg");
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it("should build audio message", () => {
|
|
334
|
+
const result = TelegramMediaBuilder.audio("song.mp3")
|
|
335
|
+
.caption("My favorite song")
|
|
336
|
+
.duration(180)
|
|
337
|
+
.performer("Artist Name")
|
|
338
|
+
.title("Song Title")
|
|
339
|
+
.thumbnail("album_art.jpg")
|
|
340
|
+
.build();
|
|
341
|
+
|
|
342
|
+
expect(result.type).toBe("audio");
|
|
343
|
+
expect(result.media).toBe("song.mp3");
|
|
344
|
+
expect(result.caption).toBe("My favorite song");
|
|
345
|
+
expect(result.duration).toBe(180);
|
|
346
|
+
expect(result.performer).toBe("Artist Name");
|
|
347
|
+
expect(result.title).toBe("Song Title");
|
|
348
|
+
expect(result.thumb).toBe("album_art.jpg");
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
describe("Voice Builder", () => {
|
|
353
|
+
it("should set duration", () => {
|
|
354
|
+
const result = TelegramMediaBuilder.voice("voice.ogg")
|
|
355
|
+
.duration(30)
|
|
356
|
+
.build();
|
|
357
|
+
|
|
358
|
+
expect(result.duration).toBe(30);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it("should build voice message", () => {
|
|
362
|
+
const result = TelegramMediaBuilder.voice("voice.ogg")
|
|
363
|
+
.caption("Listen to this")
|
|
364
|
+
.duration(30)
|
|
365
|
+
.build();
|
|
366
|
+
|
|
367
|
+
expect(result.type).toBe("voice");
|
|
368
|
+
expect(result.media).toBe("voice.ogg");
|
|
369
|
+
expect(result.caption).toBe("Listen to this");
|
|
370
|
+
expect(result.duration).toBe(30);
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
describe("Caption Formatting", () => {
|
|
375
|
+
it("should format caption in HTML mode (default)", () => {
|
|
376
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
377
|
+
.caption("<b>My photo</b>")
|
|
378
|
+
.build();
|
|
379
|
+
|
|
380
|
+
expect(result.caption).toBe("<b>My photo</b>");
|
|
381
|
+
expect(result.parse_mode).toBe("html");
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it("should format caption in Markdown mode", () => {
|
|
385
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
386
|
+
.caption("*My photo*")
|
|
387
|
+
.setParseMode("markdown")
|
|
388
|
+
.build();
|
|
389
|
+
|
|
390
|
+
expect(result.caption).toBe("\\*My photo\\*");
|
|
391
|
+
expect(result.parse_mode).toBe("markdown");
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
it("should format caption in MarkdownV2 mode", () => {
|
|
395
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
396
|
+
.caption("_My photo_")
|
|
397
|
+
.setParseMode("markdownv2")
|
|
398
|
+
.build();
|
|
399
|
+
|
|
400
|
+
expect(result.caption).toBe("\\_My photo\\_");
|
|
401
|
+
expect(result.parse_mode).toBe("markdownv2");
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
it("should escape HTML entities in caption", () => {
|
|
405
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
406
|
+
.caption("<script>alert('xss')</script>")
|
|
407
|
+
.build();
|
|
408
|
+
|
|
409
|
+
expect(result.caption).toContain("<");
|
|
410
|
+
expect(result.caption).toContain(">");
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it("should escape special chars in MDv2 caption", () => {
|
|
414
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
415
|
+
.caption("_*[]()~`>#+-=|{}.!")
|
|
416
|
+
.setParseMode("markdownv2")
|
|
417
|
+
.build();
|
|
418
|
+
|
|
419
|
+
expect(result.caption).toContain("\\_");
|
|
420
|
+
expect(result.caption).toContain("\\*");
|
|
421
|
+
expect(result.caption).toContain("\\~");
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
describe("Fluent API", () => {
|
|
426
|
+
it("should support method chaining", () => {
|
|
427
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
428
|
+
.caption("My video")
|
|
429
|
+
.duration(120)
|
|
430
|
+
.width(1920)
|
|
431
|
+
.height(1080)
|
|
432
|
+
.thumbnail("thumb.jpg")
|
|
433
|
+
.enableStreaming()
|
|
434
|
+
.setParseMode("markdown")
|
|
435
|
+
.setOption("protect_content", true)
|
|
436
|
+
.build();
|
|
437
|
+
|
|
438
|
+
expect(result.type).toBe("video");
|
|
439
|
+
expect(result.caption).toBe("My video");
|
|
440
|
+
expect(result.duration).toBe(120);
|
|
441
|
+
expect(result.width).toBe(1920);
|
|
442
|
+
expect(result.height).toBe(1080);
|
|
443
|
+
expect(result.thumb).toBe("thumb.jpg");
|
|
444
|
+
expect(result.support_streaming).toBe(true);
|
|
445
|
+
expect(result.parse_mode).toBe("markdown");
|
|
446
|
+
expect(result.protect_content).toBe(true);
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
it("should build complex message", () => {
|
|
450
|
+
const result = TelegramMediaBuilder.document("report.pdf")
|
|
451
|
+
.caption("*Q4 2024 Report*")
|
|
452
|
+
.setParseMode("markdownv2")
|
|
453
|
+
.fileName("q4_2024.pdf")
|
|
454
|
+
.mimeType("application/pdf")
|
|
455
|
+
.thumbnail("thumb.jpg")
|
|
456
|
+
.disableContentTypeDetection()
|
|
457
|
+
.setOptions({
|
|
458
|
+
protect_content: true,
|
|
459
|
+
disable_notification: false,
|
|
460
|
+
})
|
|
461
|
+
.build();
|
|
462
|
+
|
|
463
|
+
expect(result.type).toBe("document");
|
|
464
|
+
expect(result.caption).toContain("\\*");
|
|
465
|
+
expect(result.parse_mode).toBe("markdownv2");
|
|
466
|
+
expect(result.file_name).toBe("q4_2024.pdf");
|
|
467
|
+
expect(result.mime_type).toBe("application/pdf");
|
|
468
|
+
expect(result.thumb).toBe("thumb.jpg");
|
|
469
|
+
expect(result.disable_content_type_detection).toBe(true);
|
|
470
|
+
expect(result.protect_content).toBe(true);
|
|
471
|
+
expect(result.disable_notification).toBe(false);
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
describe("Edge Cases", () => {
|
|
476
|
+
it("should handle empty caption", () => {
|
|
477
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
478
|
+
.caption("")
|
|
479
|
+
.build();
|
|
480
|
+
|
|
481
|
+
expect(result.caption).toBe("");
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
it("should handle no caption", () => {
|
|
485
|
+
const result = TelegramMediaBuilder.photo("photo.jpg").build();
|
|
486
|
+
|
|
487
|
+
expect(result.caption).toBeUndefined();
|
|
488
|
+
expect(result.parse_mode).toBeUndefined();
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
it("should handle special characters in caption", () => {
|
|
492
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
493
|
+
.caption("Special: <>&\"'")
|
|
494
|
+
.build();
|
|
495
|
+
|
|
496
|
+
expect(result.caption).toContain("<");
|
|
497
|
+
expect(result.caption).toContain(">");
|
|
498
|
+
expect(result.caption).toContain(""");
|
|
499
|
+
expect(result.caption).toContain("&");
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
it("should handle unicode in caption", () => {
|
|
503
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
504
|
+
.caption("🎉 Party! 🎊")
|
|
505
|
+
.build();
|
|
506
|
+
|
|
507
|
+
expect(result.caption).toContain("🎉");
|
|
508
|
+
expect(result.caption).toContain("🎊");
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
it("should handle very long captions (up to 1024 chars)", () => {
|
|
512
|
+
const longCaption = "A".repeat(1024);
|
|
513
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
514
|
+
.caption(longCaption)
|
|
515
|
+
.build();
|
|
516
|
+
|
|
517
|
+
expect(result.caption).toHaveLength(1024);
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
it("should handle Buffer as media source", () => {
|
|
521
|
+
const buffer = Buffer.from("test data");
|
|
522
|
+
const result = TelegramMediaBuilder.photo(buffer).caption("Test").build();
|
|
523
|
+
|
|
524
|
+
expect(result.media).toBe(buffer);
|
|
525
|
+
expect(Buffer.isBuffer(result.media)).toBe(true);
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
it("should handle URL as media source", () => {
|
|
529
|
+
const url = "https://example.com/path/to/photo.jpg";
|
|
530
|
+
const result = TelegramMediaBuilder.photo(url)
|
|
531
|
+
.caption("From URL")
|
|
532
|
+
.build();
|
|
533
|
+
|
|
534
|
+
expect(result.media).toBe(url);
|
|
535
|
+
expect(result.type).toBe("photo");
|
|
536
|
+
expect(result.caption).toBe("From URL");
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
it("should handle file_id as media source", () => {
|
|
540
|
+
const fileId = "AgACAgIAAxkBAAI...";
|
|
541
|
+
const result = TelegramMediaBuilder.photo(fileId)
|
|
542
|
+
.caption("Existing file")
|
|
543
|
+
.build();
|
|
544
|
+
|
|
545
|
+
expect(result.media).toBe(fileId);
|
|
546
|
+
expect(result.type).toBe("photo");
|
|
547
|
+
expect(result.caption).toBe("Existing file");
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
it("should handle empty options", () => {
|
|
551
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
552
|
+
.setOptions({})
|
|
553
|
+
.build();
|
|
554
|
+
|
|
555
|
+
expect(result.type).toBe("photo");
|
|
556
|
+
expect(result.media).toBe("photo.jpg");
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
it("should override options when set multiple times", () => {
|
|
560
|
+
const result = TelegramMediaBuilder.photo("photo.jpg")
|
|
561
|
+
.setOption("protect_content", false)
|
|
562
|
+
.setOption("protect_content", true)
|
|
563
|
+
.build();
|
|
564
|
+
|
|
565
|
+
expect(result.protect_content).toBe(true);
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
it("should handle zero duration", () => {
|
|
569
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
570
|
+
.duration(0)
|
|
571
|
+
.build();
|
|
572
|
+
|
|
573
|
+
expect(result.duration).toBe(0);
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
it("should handle negative duration", () => {
|
|
577
|
+
const result = TelegramMediaBuilder.audio("audio.mp3")
|
|
578
|
+
.duration(-1)
|
|
579
|
+
.build();
|
|
580
|
+
|
|
581
|
+
expect(result.duration).toBe(-1);
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
it("should handle zero dimensions", () => {
|
|
585
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
586
|
+
.width(0)
|
|
587
|
+
.height(0)
|
|
588
|
+
.build();
|
|
589
|
+
|
|
590
|
+
expect(result.width).toBe(0);
|
|
591
|
+
expect(result.height).toBe(0);
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it("should handle large dimensions", () => {
|
|
595
|
+
const result = TelegramMediaBuilder.video("video.mp4")
|
|
596
|
+
.width(4096)
|
|
597
|
+
.height(2160)
|
|
598
|
+
.build();
|
|
599
|
+
|
|
600
|
+
expect(result.width).toBe(4096);
|
|
601
|
+
expect(result.height).toBe(2160);
|
|
602
|
+
});
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
describe("Return Type Validation", () => {
|
|
606
|
+
it("should return IMediaBuildResult structure", () => {
|
|
607
|
+
const result: IMediaBuildResult =
|
|
608
|
+
TelegramMediaBuilder.photo("photo.jpg").build();
|
|
609
|
+
|
|
610
|
+
expect(result).toHaveProperty("media");
|
|
611
|
+
expect(result).toHaveProperty("type");
|
|
612
|
+
expect(typeof result.media).toBe("string" as keyof MediaSource);
|
|
613
|
+
expect(typeof result.type).toBe("string");
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
it("should have correct media type for each builder", () => {
|
|
617
|
+
const photo = TelegramMediaBuilder.photo("p").build();
|
|
618
|
+
const video = TelegramMediaBuilder.video("v").build();
|
|
619
|
+
const document = TelegramMediaBuilder.document("d").build();
|
|
620
|
+
const audio = TelegramMediaBuilder.audio("a").build();
|
|
621
|
+
const voice = TelegramMediaBuilder.voice("v").build();
|
|
622
|
+
|
|
623
|
+
expect(photo.type).toBe("photo");
|
|
624
|
+
expect(video.type).toBe("video");
|
|
625
|
+
expect(document.type).toBe("document");
|
|
626
|
+
expect(audio.type).toBe("audio");
|
|
627
|
+
expect(voice.type).toBe("voice");
|
|
628
|
+
});
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
describe("Type Safety", () => {
|
|
632
|
+
it("should infer media type from factory method", () => {
|
|
633
|
+
const photoBuilder = TelegramMediaBuilder.photo("photo.jpg");
|
|
634
|
+
const videoBuilder = TelegramMediaBuilder.video("video.mp4");
|
|
635
|
+
|
|
636
|
+
type PhotoType =
|
|
637
|
+
typeof photoBuilder extends TelegramMediaBuilder<infer T> ? T : never;
|
|
638
|
+
type VideoType =
|
|
639
|
+
typeof videoBuilder extends TelegramMediaBuilder<infer T> ? T : never;
|
|
640
|
+
|
|
641
|
+
const photoType: PhotoType = "photo";
|
|
642
|
+
const videoType: VideoType = "video";
|
|
643
|
+
|
|
644
|
+
expect(photoType).toBe("photo");
|
|
645
|
+
expect(videoType).toBe("video");
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
it("should accept only valid media types", () => {
|
|
649
|
+
const validTypes: MediaType[] = [
|
|
650
|
+
"photo",
|
|
651
|
+
"video",
|
|
652
|
+
"document",
|
|
653
|
+
"audio",
|
|
654
|
+
"voice",
|
|
655
|
+
];
|
|
656
|
+
|
|
657
|
+
validTypes.forEach((type) => {
|
|
658
|
+
expect(["photo", "video", "document", "audio", "voice"]).toContain(
|
|
659
|
+
type,
|
|
660
|
+
);
|
|
661
|
+
});
|
|
662
|
+
});
|
|
663
|
+
});
|
|
664
|
+
});
|