@llblab/pi-telegram 0.2.8 → 0.2.9

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.
@@ -1,239 +1,19 @@
1
1
  /**
2
- * Regression tests for the Telegram replies domain
3
- * Covers preview decisions, rendered-message delivery, and plain or markdown reply sending in one suite
2
+ * Regression tests for Telegram reply delivery helpers
3
+ * Covers rendered-message transport, chunk delivery, and plain or markdown final reply sending
4
4
  */
5
5
 
6
6
  import assert from "node:assert/strict";
7
7
  import test from "node:test";
8
8
 
9
9
  import {
10
- buildTelegramPreviewFinalText,
11
- buildTelegramPreviewFlushText,
12
10
  buildTelegramReplyTransport,
13
- clearTelegramPreview,
14
11
  editTelegramRenderedMessage,
15
- finalizeTelegramMarkdownPreview,
16
- finalizeTelegramPreview,
17
- flushTelegramPreview,
18
12
  sendTelegramMarkdownReply,
19
13
  sendTelegramPlainReply,
20
14
  sendTelegramRenderedChunks,
21
- shouldUseTelegramDraftPreview,
22
15
  } from "../lib/replies.ts";
23
16
 
24
- function createPreviewRuntimeHarness(state?: {
25
- mode: "draft" | "message";
26
- draftId?: number;
27
- messageId?: number;
28
- pendingText: string;
29
- lastSentText: string;
30
- flushTimer?: ReturnType<typeof setTimeout>;
31
- }) {
32
- let previewState = state;
33
- let draftSupport: "unknown" | "supported" | "unsupported" = "unknown";
34
- let nextDraftId = 10;
35
- const events: string[] = [];
36
- return {
37
- events,
38
- getState: () => previewState,
39
- getDraftSupport: () => draftSupport,
40
- setDraftSupport: (support: "unknown" | "supported" | "unsupported") => {
41
- draftSupport = support;
42
- },
43
- deps: {
44
- getState: () => previewState,
45
- setState: (nextState: typeof previewState) => {
46
- previewState = nextState;
47
- },
48
- clearScheduledFlush: (nextState: NonNullable<typeof previewState>) => {
49
- if (!nextState.flushTimer) return;
50
- clearTimeout(nextState.flushTimer);
51
- nextState.flushTimer = undefined;
52
- events.push("clear-timer");
53
- },
54
- maxMessageLength: 5,
55
- renderPreviewText: (markdown: string) => markdown.replaceAll("*", ""),
56
- getDraftSupport: () => draftSupport,
57
- setDraftSupport: (support: "unknown" | "supported" | "unsupported") => {
58
- draftSupport = support;
59
- },
60
- allocateDraftId: () => nextDraftId++,
61
- sendDraft: async (chatId: number, draftId: number, text: string) => {
62
- events.push(`draft:${chatId}:${draftId}:${text}`);
63
- },
64
- sendMessage: async (chatId: number, text: string) => {
65
- events.push(`send:${chatId}:${text}`);
66
- return { message_id: 77 };
67
- },
68
- editMessageText: async (
69
- chatId: number,
70
- messageId: number,
71
- text: string,
72
- ) => {
73
- events.push(`edit:${chatId}:${messageId}:${text}`);
74
- },
75
- renderTelegramMessage: (text: string, options?: { mode?: string }) => [
76
- { text: `${options?.mode ?? "plain"}:${text}` },
77
- ],
78
- sendRenderedChunks: async (
79
- chatId: number,
80
- chunks: Array<{ text: string }>,
81
- ) => {
82
- events.push(
83
- `render-send:${chatId}:${chunks.map((chunk) => chunk.text).join("|")}`,
84
- );
85
- return 88;
86
- },
87
- editRenderedMessage: async (
88
- chatId: number,
89
- messageId: number,
90
- chunks: Array<{ text: string }>,
91
- ) => {
92
- events.push(
93
- `render-edit:${chatId}:${messageId}:${chunks.map((chunk) => chunk.text).join("|")}`,
94
- );
95
- return messageId;
96
- },
97
- },
98
- };
99
- }
100
-
101
- test("Reply previews build flush text only when the preview changed", () => {
102
- assert.equal(
103
- buildTelegramPreviewFlushText({
104
- state: {
105
- mode: "draft",
106
- pendingText: "**hello**",
107
- lastSentText: "",
108
- },
109
- maxMessageLength: 4096,
110
- renderPreviewText: (markdown) => markdown.replaceAll("*", ""),
111
- }),
112
- "hello",
113
- );
114
- assert.equal(
115
- buildTelegramPreviewFlushText({
116
- state: {
117
- mode: "draft",
118
- pendingText: "**hello**",
119
- lastSentText: "hello",
120
- },
121
- maxMessageLength: 4096,
122
- renderPreviewText: (markdown) => markdown.replaceAll("*", ""),
123
- }),
124
- undefined,
125
- );
126
- });
127
-
128
- test("Reply previews truncate long flush text and compute final text fallback", () => {
129
- assert.equal(
130
- buildTelegramPreviewFlushText({
131
- state: {
132
- mode: "message",
133
- pendingText: "abcdef",
134
- lastSentText: "",
135
- },
136
- maxMessageLength: 3,
137
- renderPreviewText: (markdown) => markdown,
138
- }),
139
- "abc",
140
- );
141
- assert.equal(
142
- buildTelegramPreviewFinalText({
143
- mode: "message",
144
- pendingText: " ",
145
- lastSentText: "saved",
146
- }),
147
- "saved",
148
- );
149
- assert.equal(
150
- buildTelegramPreviewFinalText({
151
- mode: "message",
152
- pendingText: " ",
153
- lastSentText: " ",
154
- }),
155
- undefined,
156
- );
157
- });
158
-
159
- test("Reply previews use drafts unless support is explicitly disabled", () => {
160
- assert.equal(
161
- shouldUseTelegramDraftPreview({ draftSupport: "unknown" }),
162
- true,
163
- );
164
- assert.equal(
165
- shouldUseTelegramDraftPreview({ draftSupport: "supported" }),
166
- true,
167
- );
168
- assert.equal(
169
- shouldUseTelegramDraftPreview({ draftSupport: "unsupported" }),
170
- false,
171
- );
172
- });
173
-
174
- test("Reply preview runtime prefers draft updates and can clear draft previews", async () => {
175
- const harness = createPreviewRuntimeHarness({
176
- mode: "draft",
177
- pendingText: "**hello**",
178
- lastSentText: "",
179
- flushTimer: setTimeout(() => {}, 1000),
180
- });
181
- await flushTelegramPreview(7, harness.deps);
182
- assert.deepEqual(harness.events, ["draft:7:10:hello"]);
183
- assert.equal(harness.getState()?.mode, "draft");
184
- assert.equal(harness.getState()?.draftId, 10);
185
- assert.equal(harness.getState()?.lastSentText, "hello");
186
- assert.equal(harness.getDraftSupport(), "supported");
187
- await clearTelegramPreview(7, harness.deps);
188
- assert.deepEqual(harness.events, ["draft:7:10:hello", "draft:7:10:"]);
189
- assert.equal(harness.getState(), undefined);
190
- });
191
-
192
- test("Reply preview runtime falls back to editable messages when draft delivery fails", async () => {
193
- const harness = createPreviewRuntimeHarness({
194
- mode: "draft",
195
- pendingText: "abcdef",
196
- lastSentText: "",
197
- });
198
- harness.deps.sendDraft = async () => {
199
- throw new Error("draft unsupported");
200
- };
201
- await flushTelegramPreview(7, harness.deps);
202
- assert.deepEqual(harness.events, ["send:7:abcde"]);
203
- assert.equal(harness.getState()?.mode, "message");
204
- assert.equal(harness.getState()?.messageId, 77);
205
- assert.equal(harness.getDraftSupport(), "unsupported");
206
- });
207
-
208
- test("Reply preview runtime finalizes plain and markdown previews", async () => {
209
- const plainHarness = createPreviewRuntimeHarness({
210
- mode: "message",
211
- messageId: 44,
212
- pendingText: "done",
213
- lastSentText: "",
214
- });
215
- plainHarness.setDraftSupport("unsupported");
216
- assert.equal(await finalizeTelegramPreview(7, plainHarness.deps), true);
217
- assert.deepEqual(plainHarness.events, ["edit:7:44:done"]);
218
- assert.equal(plainHarness.getState(), undefined);
219
- const markdownHarness = createPreviewRuntimeHarness({
220
- mode: "message",
221
- messageId: 55,
222
- pendingText: "done",
223
- lastSentText: "",
224
- });
225
- markdownHarness.setDraftSupport("unsupported");
226
- assert.equal(
227
- await finalizeTelegramMarkdownPreview(7, "**done**", markdownHarness.deps),
228
- true,
229
- );
230
- assert.deepEqual(markdownHarness.events, [
231
- "edit:7:55:done",
232
- "render-edit:7:55:markdown:**done**",
233
- ]);
234
- assert.equal(markdownHarness.getState(), undefined);
235
- });
236
-
237
17
  test("Reply transport forwards send and edit operations through delivery helpers", async () => {
238
18
  const events: string[] = [];
239
19
  const transport = buildTelegramReplyTransport({
@@ -119,7 +119,9 @@ test("Update flow returns authorized callback and message actions", () => {
119
119
  );
120
120
  assert.equal(callbackAction.kind, "callback");
121
121
  assert.deepEqual(
122
- callbackAction.kind === "callback" ? callbackAction.authorization : undefined,
122
+ callbackAction.kind === "callback"
123
+ ? callbackAction.authorization
124
+ : undefined,
123
125
  { kind: "allow" },
124
126
  );
125
127
  const messageAction = buildTelegramUpdateFlowAction({
@@ -223,10 +225,10 @@ test("Update runtime executes delete and reaction plans through the right side e
223
225
  {
224
226
  ctx: {} as never,
225
227
  removePendingMediaGroupMessages: (ids) => {
226
- events.push(`media:${ids.join(',')}`);
228
+ events.push(`media:${ids.join(",")}`);
227
229
  },
228
230
  removeQueuedTelegramTurnsByMessageIds: (ids) => {
229
- events.push(`queue:${ids.join(',')}`);
231
+ events.push(`queue:${ids.join(",")}`);
230
232
  return ids.length;
231
233
  },
232
234
  handleAuthorizedTelegramReactionUpdate: async () => {
@@ -273,7 +275,11 @@ test("Update runtime can execute directly from raw updates", async () => {
273
275
  },
274
276
  },
275
277
  );
276
- assert.deepEqual(events, ["pair", "reply:Telegram bridge paired with this account.", "message"]);
278
+ assert.deepEqual(events, [
279
+ "pair",
280
+ "reply:Telegram bridge paired with this account.",
281
+ "message",
282
+ ]);
277
283
  });
278
284
 
279
285
  test("Update runtime handles callback deny and message pair flows", async () => {