@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,539 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import type {
|
|
3
|
+
ParseMode,
|
|
4
|
+
ITelegramMessage,
|
|
5
|
+
IInlineKeyboardButton,
|
|
6
|
+
IInlineKeyboardMarkup,
|
|
7
|
+
IKeyboardButton,
|
|
8
|
+
IReplyKeyboardMarkup,
|
|
9
|
+
IForceReplyMarkup,
|
|
10
|
+
} from "./types";
|
|
11
|
+
import { TelegramMessageBuilder } from "./builder";
|
|
12
|
+
import { TelegramKeyboardBuilder } from "./keyboard";
|
|
13
|
+
import * as fmt from "../src";
|
|
14
|
+
|
|
15
|
+
describe("Type Validation Tests", () => {
|
|
16
|
+
describe("ParseMode Type", () => {
|
|
17
|
+
it("should accept 'html' as valid ParseMode", () => {
|
|
18
|
+
const mode: ParseMode = "html";
|
|
19
|
+
expect(mode).toBe("html");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should accept 'markdown' as valid ParseMode", () => {
|
|
23
|
+
const mode: ParseMode = "markdown";
|
|
24
|
+
expect(mode).toBe("markdown");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should accept 'markdownv2' as valid ParseMode", () => {
|
|
28
|
+
const mode: ParseMode = "markdownv2";
|
|
29
|
+
expect(mode).toBe("markdownv2");
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("should reject invalid ParseMode values at compile time", () => {
|
|
33
|
+
// @ts-expect-error - Invalid ParseMode
|
|
34
|
+
const invalidMode: ParseMode = "invalid";
|
|
35
|
+
expect(invalidMode).not.toBe("html");
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe("ITelegramMessage Interface", () => {
|
|
40
|
+
it("should create valid TelegramMessage structure", () => {
|
|
41
|
+
const message: ITelegramMessage = {
|
|
42
|
+
text: "Test message",
|
|
43
|
+
parse_mode: "html",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
expect(message.text).toBe("Test message");
|
|
47
|
+
expect(message.parse_mode).toBe("html");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("should accept optional properties in TelegramMessage", () => {
|
|
51
|
+
const message: ITelegramMessage = {
|
|
52
|
+
text: "Test",
|
|
53
|
+
parse_mode: "markdown",
|
|
54
|
+
disable_web_page_preview: true,
|
|
55
|
+
disable_notification: false,
|
|
56
|
+
protect_content: true,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
expect(message.disable_web_page_preview).toBe(true);
|
|
60
|
+
expect(message.disable_notification).toBe(false);
|
|
61
|
+
expect(message.protect_content).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should allow extra properties for Telegram Bot API options", () => {
|
|
65
|
+
const message: ITelegramMessage = {
|
|
66
|
+
text: "Test",
|
|
67
|
+
parse_mode: "html",
|
|
68
|
+
reply_to_message_id: 123,
|
|
69
|
+
allow_sending_without_reply: true,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
expect(message.reply_to_message_id).toBe(123);
|
|
73
|
+
expect(message.allow_sending_without_reply).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("IInlineKeyboardButton Interface", () => {
|
|
78
|
+
it("should create URL button", () => {
|
|
79
|
+
const button: IInlineKeyboardButton = {
|
|
80
|
+
text: "Visit Website",
|
|
81
|
+
url: "https://example.com",
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
expect(button.text).toBe("Visit Website");
|
|
85
|
+
expect(button.url).toBe("https://example.com");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("should create callback button", () => {
|
|
89
|
+
const button: IInlineKeyboardButton = {
|
|
90
|
+
text: "Click Me",
|
|
91
|
+
callback_data: "callback_123",
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
expect(button.text).toBe("Click Me");
|
|
95
|
+
expect(button.callback_data).toBe("callback_123");
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("should create web app button", () => {
|
|
99
|
+
const button: IInlineKeyboardButton = {
|
|
100
|
+
text: "Open Web App",
|
|
101
|
+
web_app: { url: "https://example.com/app" },
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
expect(button.web_app?.url).toBe("https://example.com/app");
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("should create login button", () => {
|
|
108
|
+
const button: IInlineKeyboardButton = {
|
|
109
|
+
text: "Login",
|
|
110
|
+
login_url: {
|
|
111
|
+
url: "https://example.com/auth",
|
|
112
|
+
forward_text: "Continue",
|
|
113
|
+
bot_username: "MyBot",
|
|
114
|
+
request_write_access: true,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
expect(button.login_url?.url).toBe("https://example.com/auth");
|
|
119
|
+
expect(button.login_url?.forward_text).toBe("Continue");
|
|
120
|
+
expect(button.login_url?.bot_username).toBe("MyBot");
|
|
121
|
+
expect(button.login_url?.request_write_access).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("should create switch inline query button", () => {
|
|
125
|
+
const button: IInlineKeyboardButton = {
|
|
126
|
+
text: "Search in chat",
|
|
127
|
+
switch_inline_query: "query",
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
expect(button.switch_inline_query).toBe("query");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("should create switch inline query current chat button", () => {
|
|
134
|
+
const button: IInlineKeyboardButton = {
|
|
135
|
+
text: "Search here",
|
|
136
|
+
switch_inline_query_current_chat: "query",
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
expect(button.switch_inline_query_current_chat).toBe("query");
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("should create callback game button", () => {
|
|
143
|
+
const button: IInlineKeyboardButton = {
|
|
144
|
+
text: "Play Game",
|
|
145
|
+
callback_game: {},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
expect(button.callback_game).toBeDefined();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("should create pay button", () => {
|
|
152
|
+
const button: IInlineKeyboardButton = {
|
|
153
|
+
text: "Pay $10",
|
|
154
|
+
pay: true,
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
expect(button.pay).toBe(true);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe("IInlineKeyboardMarkup Interface", () => {
|
|
162
|
+
it("should create inline keyboard markup", () => {
|
|
163
|
+
const markup: IInlineKeyboardMarkup = {
|
|
164
|
+
inline_keyboard: [
|
|
165
|
+
[
|
|
166
|
+
{ text: "Button 1", url: "https://example.com" },
|
|
167
|
+
{ text: "Button 2", callback_data: "cb2" },
|
|
168
|
+
],
|
|
169
|
+
[{ text: "Button 3", switch_inline_query: "search" }],
|
|
170
|
+
],
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
expect(markup.inline_keyboard).toBeDefined();
|
|
174
|
+
expect(markup.inline_keyboard?.length).toBe(2);
|
|
175
|
+
expect(markup.inline_keyboard?.[0].length).toBe(2);
|
|
176
|
+
expect(markup.inline_keyboard?.[1].length).toBe(1);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("should accept empty inline_keyboard", () => {
|
|
180
|
+
const markup: IInlineKeyboardMarkup = {
|
|
181
|
+
inline_keyboard: [],
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
expect(markup.inline_keyboard).toEqual([]);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
describe("IKeyboardButton Interface", () => {
|
|
189
|
+
it("should create text button", () => {
|
|
190
|
+
const button: IKeyboardButton = {
|
|
191
|
+
text: "Button",
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
expect(button.text).toBe("Button");
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("should create request contact button", () => {
|
|
198
|
+
const button: IKeyboardButton = {
|
|
199
|
+
text: "Share Contact",
|
|
200
|
+
request_contact: true,
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
expect(button.request_contact).toBe(true);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("should create request location button", () => {
|
|
207
|
+
const button: IKeyboardButton = {
|
|
208
|
+
text: "Share Location",
|
|
209
|
+
request_location: true,
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
expect(button.request_location).toBe(true);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("should create request poll button", () => {
|
|
216
|
+
const button: IKeyboardButton = {
|
|
217
|
+
text: "Create Poll",
|
|
218
|
+
request_poll: { type: "quiz" },
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
expect(button.request_poll?.type).toBe("quiz");
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("should create web app button (reply keyboard)", () => {
|
|
225
|
+
const button: IKeyboardButton = {
|
|
226
|
+
text: "Open App",
|
|
227
|
+
web_app: { url: "https://example.com/app" },
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
expect(button.web_app?.url).toBe("https://example.com/app");
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
describe("IReplyKeyboardMarkup Interface", () => {
|
|
235
|
+
it("should create reply keyboard markup", () => {
|
|
236
|
+
const markup: IReplyKeyboardMarkup = {
|
|
237
|
+
keyboard: [
|
|
238
|
+
[{ text: "Button 1" }, { text: "Button 2" }],
|
|
239
|
+
[{ text: "Button 3" }],
|
|
240
|
+
],
|
|
241
|
+
resize_keyboard: true,
|
|
242
|
+
one_time_keyboard: false,
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
expect(markup.keyboard).toBeDefined();
|
|
246
|
+
expect(markup.resize_keyboard).toBe(true);
|
|
247
|
+
expect(markup.one_time_keyboard).toBe(false);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it("should accept all optional properties", () => {
|
|
251
|
+
const markup: IReplyKeyboardMarkup = {
|
|
252
|
+
keyboard: [[{ text: "Button" }]],
|
|
253
|
+
resize_keyboard: true,
|
|
254
|
+
one_time_keyboard: true,
|
|
255
|
+
input_field_placeholder: "Enter text...",
|
|
256
|
+
selective: true,
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
expect(markup.input_field_placeholder).toBe("Enter text...");
|
|
260
|
+
expect(markup.selective).toBe(true);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
describe("IForceReplyMarkup Interface", () => {
|
|
265
|
+
it("should create force reply markup", () => {
|
|
266
|
+
const markup: IForceReplyMarkup = {
|
|
267
|
+
force_reply: true,
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
expect(markup.force_reply).toBe(true);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it("should accept selective property", () => {
|
|
274
|
+
const markup: IForceReplyMarkup = {
|
|
275
|
+
force_reply: true,
|
|
276
|
+
selective: true,
|
|
277
|
+
input_field_placeholder: "Type something...",
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
expect(markup.selective).toBe(true);
|
|
281
|
+
expect(markup.input_field_placeholder).toBe("Type something...");
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
describe("Builder Return Types", () => {
|
|
286
|
+
it("should return correct type from TelegramMessageBuilder.build()", () => {
|
|
287
|
+
const builder = TelegramMessageBuilder.text();
|
|
288
|
+
const message = builder.build();
|
|
289
|
+
|
|
290
|
+
// Type assertion to verify the structure
|
|
291
|
+
expect(message).toHaveProperty("text");
|
|
292
|
+
expect(message).toHaveProperty("parse_mode");
|
|
293
|
+
expect(typeof message.text).toBe("string");
|
|
294
|
+
expect(typeof message.parse_mode).toBe("string");
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it("should return correct type from TelegramKeyboardBuilder.buildMarkup()", () => {
|
|
298
|
+
const keyboard = TelegramKeyboardBuilder.inline()
|
|
299
|
+
.urlButton("Test", "https://example.com")
|
|
300
|
+
.buildMarkup();
|
|
301
|
+
|
|
302
|
+
expect(keyboard).toHaveProperty("inline_keyboard");
|
|
303
|
+
expect(Array.isArray(keyboard.inline_keyboard)).toBe(true);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it("should return correct type from TelegramKeyboardBuilder.buildReplyMarkup()", () => {
|
|
307
|
+
const keyboard = TelegramKeyboardBuilder.reply()
|
|
308
|
+
.textButton("Test")
|
|
309
|
+
.buildReplyMarkup();
|
|
310
|
+
|
|
311
|
+
expect(keyboard).toHaveProperty("keyboard");
|
|
312
|
+
expect(Array.isArray(keyboard.keyboard)).toBe(true);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it("should return correct type from TelegramKeyboardBuilder.buildForceReplyMarkup()", () => {
|
|
316
|
+
const keyboard =
|
|
317
|
+
TelegramKeyboardBuilder.forceReply().buildForceReplyMarkup();
|
|
318
|
+
|
|
319
|
+
expect(keyboard).toHaveProperty("force_reply");
|
|
320
|
+
expect(keyboard.force_reply).toBe(true);
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
describe("Formatter Return Types", () => {
|
|
325
|
+
it("should return string from all HTML formatters", () => {
|
|
326
|
+
expect(typeof fmt.bold("test")).toBe("string");
|
|
327
|
+
expect(typeof fmt.italic("test")).toBe("string");
|
|
328
|
+
expect(typeof fmt.underline("test")).toBe("string");
|
|
329
|
+
expect(typeof fmt.strikethrough("test")).toBe("string");
|
|
330
|
+
expect(typeof fmt.spoiler("test")).toBe("string");
|
|
331
|
+
expect(typeof fmt.code("test")).toBe("string");
|
|
332
|
+
expect(typeof fmt.pre("test")).toBe("string");
|
|
333
|
+
expect(typeof fmt.codeBlock("test")).toBe("string");
|
|
334
|
+
expect(typeof fmt.link("test", "url")).toBe("string");
|
|
335
|
+
expect(typeof fmt.mention(123)).toBe("string");
|
|
336
|
+
expect(typeof fmt.hashtag("test")).toBe("string");
|
|
337
|
+
expect(typeof fmt.email("test@test.com")).toBe("string");
|
|
338
|
+
expect(typeof fmt.url("https://test.com")).toBe("string");
|
|
339
|
+
expect(typeof fmt.customEmoji("123")).toBe("string");
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it("should return string from all Markdown formatters", () => {
|
|
343
|
+
expect(typeof fmt.boldMD("test")).toBe("string");
|
|
344
|
+
expect(typeof fmt.italicMD("test")).toBe("string");
|
|
345
|
+
expect(typeof fmt.codeMD("test")).toBe("string");
|
|
346
|
+
expect(typeof fmt.codeBlockMD("test")).toBe("string");
|
|
347
|
+
expect(typeof fmt.linkMD("test", "url")).toBe("string");
|
|
348
|
+
expect(typeof fmt.mentionMD(123)).toBe("string");
|
|
349
|
+
expect(typeof fmt.hashtagMD("test")).toBe("string");
|
|
350
|
+
expect(typeof fmt.rawMD("test")).toBe("string");
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it("should return string from all MarkdownV2 formatters", () => {
|
|
354
|
+
expect(typeof fmt.boldMDv2("test")).toBe("string");
|
|
355
|
+
expect(typeof fmt.italicMDv2("test")).toBe("string");
|
|
356
|
+
expect(typeof fmt.underlineMDv2("test")).toBe("string");
|
|
357
|
+
expect(typeof fmt.strikethroughMDv2("test")).toBe("string");
|
|
358
|
+
expect(typeof fmt.spoilerMDv2("test")).toBe("string");
|
|
359
|
+
expect(typeof fmt.codeMDv2("test")).toBe("string");
|
|
360
|
+
expect(typeof fmt.codeBlockMDv2("test")).toBe("string");
|
|
361
|
+
expect(typeof fmt.linkMDv2("test", "url")).toBe("string");
|
|
362
|
+
expect(typeof fmt.mentionMDv2(123)).toBe("string");
|
|
363
|
+
expect(typeof fmt.hashtagMDv2("test")).toBe("string");
|
|
364
|
+
expect(typeof fmt.rawMDv2("test")).toBe("string");
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it("should return string from escape functions", () => {
|
|
368
|
+
expect(typeof fmt.escapeHTML("test")).toBe("string");
|
|
369
|
+
expect(typeof fmt.escapeMarkdown("test")).toBe("string");
|
|
370
|
+
expect(typeof fmt.escapeMarkdownV2("test")).toBe("string");
|
|
371
|
+
expect(typeof fmt.escape("test")).toBe("string");
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
describe("Fluent API Chaining Types", () => {
|
|
376
|
+
it("should allow method chaining on TelegramMessageBuilder", () => {
|
|
377
|
+
const message = TelegramMessageBuilder.text()
|
|
378
|
+
.title("Test")
|
|
379
|
+
.newline()
|
|
380
|
+
.section("Section")
|
|
381
|
+
.line("Key", "Value", { bold: true })
|
|
382
|
+
.codeBlock("code")
|
|
383
|
+
.listItem("item")
|
|
384
|
+
.separator()
|
|
385
|
+
.text("text")
|
|
386
|
+
.link("Link", "url")
|
|
387
|
+
.mention(123)
|
|
388
|
+
.hashtag("tag")
|
|
389
|
+
.setParseMode("html")
|
|
390
|
+
.setOption("key", "value")
|
|
391
|
+
.setOptions({ key2: "value2" })
|
|
392
|
+
.build();
|
|
393
|
+
|
|
394
|
+
expect(message.text).toBeDefined();
|
|
395
|
+
expect(message.parse_mode).toBe("html");
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it("should allow method chaining on TelegramKeyboardBuilder (inline)", () => {
|
|
399
|
+
const keyboard = TelegramKeyboardBuilder.inline()
|
|
400
|
+
.urlButton("Button", "url")
|
|
401
|
+
.row()
|
|
402
|
+
.callbackButton("Button2", "data")
|
|
403
|
+
.row()
|
|
404
|
+
.webAppButton("Button3", "url")
|
|
405
|
+
.buildMarkup();
|
|
406
|
+
|
|
407
|
+
expect(keyboard.inline_keyboard).toBeDefined();
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
it("should allow method chaining on TelegramKeyboardBuilder (reply)", () => {
|
|
411
|
+
const keyboard = TelegramKeyboardBuilder.reply()
|
|
412
|
+
.textButton("Button1")
|
|
413
|
+
.row()
|
|
414
|
+
.textButton("Button2")
|
|
415
|
+
.textButton("Button3")
|
|
416
|
+
.buildReplyMarkup();
|
|
417
|
+
|
|
418
|
+
expect(keyboard.keyboard).toBeDefined();
|
|
419
|
+
expect(keyboard.resize_keyboard).toBe(true);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it("should allow method chaining on TelegramKeyboardBuilder (force reply)", () => {
|
|
423
|
+
const keyboard =
|
|
424
|
+
TelegramKeyboardBuilder.forceReply().buildForceReplyMarkup();
|
|
425
|
+
|
|
426
|
+
expect(keyboard.force_reply).toBe(true);
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
describe("Type Guards and Validation", () => {
|
|
431
|
+
it("should validate parse_mode at runtime", () => {
|
|
432
|
+
const validModes: ParseMode[] = ["html", "markdown", "markdownv2"];
|
|
433
|
+
|
|
434
|
+
validModes.forEach((mode) => {
|
|
435
|
+
const builder = TelegramMessageBuilder.text().setParseMode(mode);
|
|
436
|
+
expect(builder.getParseMode()).toBe(mode);
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it("should validate message structure", () => {
|
|
441
|
+
const message = TelegramMessageBuilder.text().title("Test").build();
|
|
442
|
+
|
|
443
|
+
// Runtime validation of message structure
|
|
444
|
+
expect(message).toBeDefined();
|
|
445
|
+
expect(typeof message.text).toBe("string");
|
|
446
|
+
expect(typeof message.parse_mode).toBe("string");
|
|
447
|
+
expect(["html", "markdown", "markdownv2"]).toContain(message.parse_mode);
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
it("should validate keyboard structure", () => {
|
|
451
|
+
const keyboard = TelegramKeyboardBuilder.inline()
|
|
452
|
+
.urlButton("Test", "url")
|
|
453
|
+
.buildMarkup();
|
|
454
|
+
|
|
455
|
+
// Runtime validation of keyboard structure
|
|
456
|
+
expect(keyboard).toBeDefined();
|
|
457
|
+
expect(keyboard.inline_keyboard).toBeDefined();
|
|
458
|
+
expect(Array.isArray(keyboard.inline_keyboard)).toBe(true);
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
describe("Export Validation", () => {
|
|
463
|
+
it("should export all types from index", () => {
|
|
464
|
+
// This test validates that types are properly exported
|
|
465
|
+
// If this compiles, the exports are correct
|
|
466
|
+
type TypesExported = {
|
|
467
|
+
ParseMode: ParseMode;
|
|
468
|
+
ITelegramMessage: ITelegramMessage;
|
|
469
|
+
IInlineKeyboardButton: IInlineKeyboardButton;
|
|
470
|
+
IInlineKeyboardMarkup: IInlineKeyboardMarkup;
|
|
471
|
+
IKeyboardButton: IKeyboardButton;
|
|
472
|
+
IReplyKeyboardMarkup: IReplyKeyboardMarkup;
|
|
473
|
+
IForceReplyMarkup: IForceReplyMarkup;
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
const dummy: TypesExported = {} as TypesExported;
|
|
477
|
+
expect(dummy).toBeDefined();
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it("should export TelegramMessageBuilder", () => {
|
|
481
|
+
expect(TelegramMessageBuilder).toBeDefined();
|
|
482
|
+
expect(typeof TelegramMessageBuilder.text).toBe("function");
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it("should export TelegramKeyboardBuilder", () => {
|
|
486
|
+
expect(TelegramKeyboardBuilder).toBeDefined();
|
|
487
|
+
expect(typeof TelegramKeyboardBuilder.inline).toBe("function");
|
|
488
|
+
expect(typeof TelegramKeyboardBuilder.reply).toBe("function");
|
|
489
|
+
expect(typeof TelegramKeyboardBuilder.forceReply).toBe("function");
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it("should export fmt object with all formatters", () => {
|
|
493
|
+
expect(fmt).toBeDefined();
|
|
494
|
+
expect(typeof fmt.bold).toBe("function");
|
|
495
|
+
expect(typeof fmt.italic).toBe("function");
|
|
496
|
+
expect(typeof fmt.link).toBe("function");
|
|
497
|
+
expect(typeof fmt.escape).toBe("function");
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
describe("Type Compatibility", () => {
|
|
502
|
+
it("should be compatible with Telegram Bot API types", () => {
|
|
503
|
+
// Simulate sending to Telegram Bot API
|
|
504
|
+
const message = TelegramMessageBuilder.text()
|
|
505
|
+
.title("Test")
|
|
506
|
+
.setOption("disable_notification", true)
|
|
507
|
+
.build();
|
|
508
|
+
|
|
509
|
+
// This should match the expected Telegram Bot API structure
|
|
510
|
+
const apiPayload = {
|
|
511
|
+
text: message.text,
|
|
512
|
+
parse_mode: message.parse_mode,
|
|
513
|
+
disable_notification: message.disable_notification,
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
expect(apiPayload.text).toBeDefined();
|
|
517
|
+
expect(apiPayload.parse_mode).toBeDefined();
|
|
518
|
+
expect(apiPayload.disable_notification).toBe(true);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
it("should handle keyboard markup with messages", () => {
|
|
522
|
+
const message = TelegramMessageBuilder.text().title("Test").build();
|
|
523
|
+
|
|
524
|
+
const keyboard = TelegramKeyboardBuilder.inline()
|
|
525
|
+
.urlButton("Button", "url")
|
|
526
|
+
.buildMarkup();
|
|
527
|
+
|
|
528
|
+
// Simulate sending message with keyboard
|
|
529
|
+
const payload = {
|
|
530
|
+
text: message.text,
|
|
531
|
+
parse_mode: message.parse_mode,
|
|
532
|
+
reply_markup: keyboard,
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
expect(payload.reply_markup).toBeDefined();
|
|
536
|
+
expect(payload.reply_markup.inline_keyboard).toBeDefined();
|
|
537
|
+
});
|
|
538
|
+
});
|
|
539
|
+
});
|
package/src/utils/index.d.ts
CHANGED