@llblab/pi-telegram 0.2.0

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.
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Regression tests for the Telegram polling domain
3
+ * Covers polling request helpers, stop conditions, and the long-poll loop runtime in one suite
4
+ */
5
+
6
+ import assert from "node:assert/strict";
7
+ import test from "node:test";
8
+
9
+ import {
10
+ TELEGRAM_ALLOWED_UPDATES,
11
+ buildTelegramInitialSyncRequest,
12
+ buildTelegramLongPollRequest,
13
+ getLatestTelegramUpdateId,
14
+ runTelegramPollLoop,
15
+ shouldStopTelegramPolling,
16
+ } from "../lib/polling.ts";
17
+
18
+ test("Polling helpers build the initial sync request", () => {
19
+ assert.deepEqual(buildTelegramInitialSyncRequest(), {
20
+ offset: -1,
21
+ limit: 1,
22
+ timeout: 0,
23
+ });
24
+ });
25
+
26
+ test("Polling helpers build long-poll requests with and without lastUpdateId", () => {
27
+ assert.deepEqual(buildTelegramLongPollRequest(), {
28
+ offset: undefined,
29
+ limit: 10,
30
+ timeout: 30,
31
+ allowed_updates: TELEGRAM_ALLOWED_UPDATES,
32
+ });
33
+ assert.deepEqual(buildTelegramLongPollRequest(41), {
34
+ offset: 42,
35
+ limit: 10,
36
+ timeout: 30,
37
+ allowed_updates: TELEGRAM_ALLOWED_UPDATES,
38
+ });
39
+ });
40
+
41
+ test("Polling helpers extract the latest update id", () => {
42
+ assert.equal(getLatestTelegramUpdateId([]), undefined);
43
+ assert.equal(
44
+ getLatestTelegramUpdateId([{ update_id: 1 }, { update_id: 7 }]),
45
+ 7,
46
+ );
47
+ });
48
+
49
+ test("Polling helpers stop only for abort conditions", () => {
50
+ assert.equal(shouldStopTelegramPolling(true, new Error("ignored")), true);
51
+ assert.equal(
52
+ shouldStopTelegramPolling(false, new DOMException("aborted", "AbortError")),
53
+ true,
54
+ );
55
+ assert.equal(shouldStopTelegramPolling(false, new Error("network")), false);
56
+ });
57
+
58
+ test("Poll loop initializes lastUpdateId and processes updates", async () => {
59
+ const handled: number[] = [];
60
+ const config: { botToken: string; lastUpdateId?: number } = {
61
+ botToken: "123:abc",
62
+ };
63
+ let getUpdatesCalls = 0;
64
+ let persistCount = 0;
65
+ const signal = new AbortController().signal;
66
+ await runTelegramPollLoop({
67
+ ctx: {} as never,
68
+ signal,
69
+ config,
70
+ deleteWebhook: async () => {},
71
+ getUpdates: async () => {
72
+ getUpdatesCalls += 1;
73
+ if (getUpdatesCalls === 1) {
74
+ return [{ update_id: 5 }];
75
+ }
76
+ if (getUpdatesCalls === 2) {
77
+ return [{ update_id: 6 }, { update_id: 7 }];
78
+ }
79
+ throw new DOMException("stop", "AbortError");
80
+ },
81
+ persistConfig: async () => {
82
+ persistCount += 1;
83
+ },
84
+ handleUpdate: async (update) => {
85
+ handled.push(update.update_id);
86
+ },
87
+ onErrorStatus: () => {},
88
+ onStatusReset: () => {},
89
+ sleep: async () => {},
90
+ });
91
+ assert.equal(config.lastUpdateId, 7);
92
+ assert.deepEqual(handled, [6, 7]);
93
+ assert.equal(persistCount, 3);
94
+ });
95
+
96
+ test("Poll loop reports retryable errors and sleeps before retrying", async () => {
97
+ const config = { botToken: "123:abc", lastUpdateId: 1 };
98
+ const statusMessages: string[] = [];
99
+ let calls = 0;
100
+ await runTelegramPollLoop({
101
+ ctx: {} as never,
102
+ signal: new AbortController().signal,
103
+ config,
104
+ deleteWebhook: async () => {},
105
+ getUpdates: async () => {
106
+ calls += 1;
107
+ if (calls === 1) {
108
+ throw new Error("network down");
109
+ }
110
+ throw new DOMException("stop", "AbortError");
111
+ },
112
+ persistConfig: async () => {},
113
+ handleUpdate: async () => {},
114
+ onErrorStatus: (message) => {
115
+ statusMessages.push(`error:${message}`);
116
+ },
117
+ onStatusReset: () => {
118
+ statusMessages.push("reset");
119
+ },
120
+ sleep: async (ms) => {
121
+ statusMessages.push(`sleep:${ms}`);
122
+ },
123
+ });
124
+ assert.deepEqual(statusMessages, [
125
+ "error:network down",
126
+ "sleep:3000",
127
+ "reset",
128
+ ]);
129
+ });