@yaebal/test 0.0.1 → 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.
Files changed (107) hide show
  1. package/README.md +400 -15
  2. package/lib/api.d.ts +83 -0
  3. package/lib/api.d.ts.map +1 -0
  4. package/lib/api.js +186 -0
  5. package/lib/api.js.map +1 -0
  6. package/lib/api.test.d.ts +2 -0
  7. package/lib/api.test.d.ts.map +1 -0
  8. package/lib/api.test.js +131 -0
  9. package/lib/api.test.js.map +1 -0
  10. package/lib/bot-messages.d.ts +42 -0
  11. package/lib/bot-messages.d.ts.map +1 -0
  12. package/lib/bot-messages.js +72 -0
  13. package/lib/bot-messages.js.map +1 -0
  14. package/lib/chat-actor.d.ts +45 -0
  15. package/lib/chat-actor.d.ts.map +1 -0
  16. package/lib/chat-actor.js +72 -0
  17. package/lib/chat-actor.js.map +1 -0
  18. package/lib/clock.d.ts +22 -0
  19. package/lib/clock.d.ts.map +1 -0
  20. package/lib/clock.js +72 -0
  21. package/lib/clock.js.map +1 -0
  22. package/lib/clock.test.d.ts +2 -0
  23. package/lib/clock.test.d.ts.map +1 -0
  24. package/lib/clock.test.js +69 -0
  25. package/lib/clock.test.js.map +1 -0
  26. package/lib/env.d.ts +100 -0
  27. package/lib/env.d.ts.map +1 -0
  28. package/lib/env.js +164 -0
  29. package/lib/env.js.map +1 -0
  30. package/lib/env.test.d.ts +2 -0
  31. package/lib/env.test.d.ts.map +1 -0
  32. package/lib/env.test.js +302 -0
  33. package/lib/env.test.js.map +1 -0
  34. package/lib/fetch.d.ts +3 -0
  35. package/lib/fetch.d.ts.map +1 -0
  36. package/lib/fetch.js +12 -0
  37. package/lib/fetch.js.map +1 -0
  38. package/lib/index.d.ts +19 -52
  39. package/lib/index.d.ts.map +1 -1
  40. package/lib/index.js +19 -115
  41. package/lib/index.js.map +1 -1
  42. package/lib/internal.d.ts +25 -0
  43. package/lib/internal.d.ts.map +1 -0
  44. package/lib/internal.js +19 -0
  45. package/lib/internal.js.map +1 -0
  46. package/lib/keyboard.d.ts +15 -0
  47. package/lib/keyboard.d.ts.map +1 -0
  48. package/lib/keyboard.js +25 -0
  49. package/lib/keyboard.js.map +1 -0
  50. package/lib/keyboard.test.d.ts +2 -0
  51. package/lib/keyboard.test.d.ts.map +1 -0
  52. package/lib/keyboard.test.js +31 -0
  53. package/lib/keyboard.test.js.map +1 -0
  54. package/lib/normalize.d.ts +10 -0
  55. package/lib/normalize.d.ts.map +1 -0
  56. package/lib/normalize.js +27 -0
  57. package/lib/normalize.js.map +1 -0
  58. package/lib/reactions.d.ts +3 -0
  59. package/lib/reactions.d.ts.map +1 -0
  60. package/lib/reactions.js +17 -0
  61. package/lib/reactions.js.map +1 -0
  62. package/lib/updates.d.ts +126 -0
  63. package/lib/updates.d.ts.map +1 -0
  64. package/lib/updates.js +200 -0
  65. package/lib/updates.js.map +1 -0
  66. package/lib/updates.test.d.ts +2 -0
  67. package/lib/updates.test.d.ts.map +1 -0
  68. package/lib/updates.test.js +72 -0
  69. package/lib/updates.test.js.map +1 -0
  70. package/lib/user-actor.d.ts +188 -0
  71. package/lib/user-actor.d.ts.map +1 -0
  72. package/lib/user-actor.js +465 -0
  73. package/lib/user-actor.js.map +1 -0
  74. package/lib/webhook.d.ts +18 -0
  75. package/lib/webhook.d.ts.map +1 -0
  76. package/lib/webhook.js +25 -0
  77. package/lib/webhook.js.map +1 -0
  78. package/lib/webhook.test.d.ts +2 -0
  79. package/lib/webhook.test.d.ts.map +1 -0
  80. package/lib/webhook.test.js +36 -0
  81. package/lib/webhook.test.js.map +1 -0
  82. package/package.json +7 -5
  83. package/src/api.test.ts +180 -0
  84. package/src/api.ts +289 -0
  85. package/src/bot-messages.ts +117 -0
  86. package/src/chat-actor.ts +101 -0
  87. package/src/clock.test.ts +80 -0
  88. package/src/clock.ts +118 -0
  89. package/src/env.test.ts +370 -0
  90. package/src/env.ts +235 -0
  91. package/src/fetch.ts +11 -0
  92. package/src/index.ts +79 -169
  93. package/src/internal.ts +43 -0
  94. package/src/keyboard.test.ts +35 -0
  95. package/src/keyboard.ts +38 -0
  96. package/src/normalize.ts +34 -0
  97. package/src/reactions.ts +18 -0
  98. package/src/updates.test.ts +107 -0
  99. package/src/updates.ts +354 -0
  100. package/src/user-actor.ts +702 -0
  101. package/src/webhook.test.ts +54 -0
  102. package/src/webhook.ts +48 -0
  103. package/lib/index.test.d.ts +0 -2
  104. package/lib/index.test.d.ts.map +0 -1
  105. package/lib/index.test.js +0 -66
  106. package/lib/index.test.js.map +0 -1
  107. package/src/index.test.ts +0 -101
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-actor.js","sourceRoot":"","sources":["../src/user-actor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Update, UpdateSink } from "@yaebal/core";
2
+ /** result of {@link collectUpdates}: an {@link UpdateSink} plus the updates it received, in order. */
3
+ export interface UpdateCollector {
4
+ sink: UpdateSink;
5
+ updates: Update[];
6
+ }
7
+ /** a minimal {@link UpdateSink} (the `{ handleUpdate }` shape `webhookCallback`/runners expect) that just records. */
8
+ export declare function collectUpdates(): UpdateCollector;
9
+ /** options for {@link webhookRequest}. */
10
+ export interface WebhookRequestOptions {
11
+ url?: string;
12
+ method?: string;
13
+ secretToken?: string;
14
+ headers?: Record<string, string>;
15
+ }
16
+ /** build a `Request` carrying `update` as JSON, as telegram would POST it to a webhook handler. */
17
+ export declare function webhookRequest(update: Update, options?: WebhookRequestOptions): Request;
18
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvD,sGAAsG;AACtG,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,sHAAsH;AACtH,wBAAgB,cAAc,IAAI,eAAe,CAWhD;AAED,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,mGAAmG;AACnG,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAgB3F"}
package/lib/webhook.js ADDED
@@ -0,0 +1,25 @@
1
+ /** a minimal {@link UpdateSink} (the `{ handleUpdate }` shape `webhookCallback`/runners expect) that just records. */
2
+ export function collectUpdates() {
3
+ const updates = [];
4
+ return {
5
+ sink: {
6
+ handleUpdate: async (update) => {
7
+ updates.push(update);
8
+ },
9
+ },
10
+ updates,
11
+ };
12
+ }
13
+ /** build a `Request` carrying `update` as JSON, as telegram would POST it to a webhook handler. */
14
+ export function webhookRequest(update, options = {}) {
15
+ const { url = "https://example.invalid/webhook", method = "POST", secretToken, headers = {}, } = options;
16
+ const finalHeaders = { "content-type": "application/json", ...headers };
17
+ if (secretToken)
18
+ finalHeaders["x-telegram-bot-api-secret-token"] = secretToken;
19
+ return new Request(url, {
20
+ method,
21
+ headers: finalHeaders,
22
+ body: method === "GET" || method === "HEAD" ? undefined : JSON.stringify(update),
23
+ });
24
+ }
25
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":"AAQA,sHAAsH;AACtH,MAAM,UAAU,cAAc;IAC7B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,OAAO;QACN,IAAI,EAAE;YACL,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBAC9B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtB,CAAC;SACD;QACD,OAAO;KACP,CAAC;AACH,CAAC;AAUD,mGAAmG;AACnG,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,UAAiC,EAAE;IACjF,MAAM,EACL,GAAG,GAAG,iCAAiC,EACvC,MAAM,GAAG,MAAM,EACf,WAAW,EACX,OAAO,GAAG,EAAE,GACZ,GAAG,OAAO,CAAC;IAEZ,MAAM,YAAY,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,OAAO,EAAE,CAAC;IAChG,IAAI,WAAW;QAAE,YAAY,CAAC,iCAAiC,CAAC,GAAG,WAAW,CAAC;IAE/E,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE;QACvB,MAAM;QACN,OAAO,EAAE,YAAY;QACrB,IAAI,EAAE,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;KAChF,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=webhook.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.test.d.ts","sourceRoot":"","sources":["../src/webhook.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { withFetch } from "./fetch.js";
4
+ import { messageUpdate } from "./updates.js";
5
+ import { collectUpdates, webhookRequest } from "./webhook.js";
6
+ test("collectUpdates records every update handed to the sink", async () => {
7
+ const { sink, updates } = collectUpdates();
8
+ await sink.handleUpdate(messageUpdate({ text: "one" }));
9
+ await sink.handleUpdate(messageUpdate({ text: "two" }));
10
+ assert.equal(updates.length, 2);
11
+ assert.equal(updates[0]?.message?.text, "one");
12
+ });
13
+ test("webhookRequest builds a POST carrying the update as JSON, with an optional secret header", async () => {
14
+ const update = messageUpdate({ text: "hi" });
15
+ const req = webhookRequest(update, { secretToken: "s3cret" });
16
+ assert.equal(req.method, "POST");
17
+ assert.equal(req.headers.get("x-telegram-bot-api-secret-token"), "s3cret");
18
+ assert.deepEqual(await req.json(), update);
19
+ });
20
+ test("withFetch stubs globalThis.fetch for the duration of fn, then restores it", async () => {
21
+ const realFetch = globalThis.fetch;
22
+ const result = await withFetch(async () => new Response("stubbed"), async () => {
23
+ const res = await fetch("https://example.invalid/");
24
+ return res.text();
25
+ });
26
+ assert.equal(result, "stubbed");
27
+ assert.equal(globalThis.fetch, realFetch);
28
+ });
29
+ test("withFetch restores the original fetch even if fn throws", async () => {
30
+ const realFetch = globalThis.fetch;
31
+ await assert.rejects(withFetch(async () => new Response("x"), () => {
32
+ throw new Error("boom");
33
+ }));
34
+ assert.equal(globalThis.fetch, realFetch);
35
+ });
36
+ //# sourceMappingURL=webhook.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.test.js","sourceRoot":"","sources":["../src/webhook.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9D,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;IACzE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAE3C,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACxD,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAExD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0FAA0F,EAAE,KAAK,IAAI,EAAE;IAC3G,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE9D,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3E,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;IAC5F,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC;IAEnC,MAAM,MAAM,GAAG,MAAM,SAAS,CAC7B,KAAK,IAAI,EAAE,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,EACnC,KAAK,IAAI,EAAE;QACV,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACpD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC,CACD,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;IAC1E,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC;IAEnC,MAAM,MAAM,CAAC,OAAO,CACnB,SAAS,CACR,KAAK,IAAI,EAAE,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,EAC7B,GAAG,EAAE;QACJ,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC,CACD,CACD,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yaebal/test",
3
- "version": "0.0.1",
4
- "description": "yaebal test — testing utilities for yaebal bots: mock api, update factories, and context builders.",
3
+ "version": "0.2.0",
4
+ "description": "yaebal test — an actor-driven test framework for yaebal bots: users/chats that send real updates, a virtual clock, apiError stubs, and satellite-plugin test packs.",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
7
7
  "types": "./lib/index.d.ts",
@@ -16,7 +16,7 @@
16
16
  "src"
17
17
  ],
18
18
  "dependencies": {
19
- "@yaebal/core": "0.0.1"
19
+ "@yaebal/core": "0.0.8"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/node": "latest"
@@ -30,7 +30,9 @@
30
30
  "yaebal",
31
31
  "test",
32
32
  "testing",
33
- "mock"
33
+ "mock",
34
+ "actor",
35
+ "e2e"
34
36
  ],
35
37
  "license": "MIT",
36
38
  "repository": {
@@ -44,6 +46,6 @@
44
46
  "scripts": {
45
47
  "build": "tsc -p tsconfig.json",
46
48
  "typecheck": "tsc -p tsconfig.json --noEmit",
47
- "test": "node --test lib"
49
+ "test": "node --test lib/*.test.js"
48
50
  }
49
51
  }
@@ -0,0 +1,180 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { TelegramError } from "@yaebal/core";
4
+ import { apiError, isApiErrorSentinel, mockApi, TestApiError } from "./api.js";
5
+
6
+ test("mockApi records calls and resolves sensible defaults", async () => {
7
+ const { api, calls } = mockApi();
8
+
9
+ const sent = await api.sendMessage({ chat_id: 1, text: "hi" });
10
+ assert.deepEqual(sent, { message_id: 1 });
11
+
12
+ const answered = await api.answerCallbackQuery({ callback_query_id: "1" });
13
+ assert.equal(answered, true);
14
+
15
+ const viaCall = await api.call("setMyCommands", { commands: [] });
16
+ assert.deepEqual(viaCall, {});
17
+
18
+ assert.equal(calls.length, 3);
19
+ assert.equal(calls[0]?.method, "sendMessage");
20
+ assert.deepEqual(calls[0]?.params, { chat_id: 1, text: "hi" });
21
+ assert.deepEqual(calls[0]?.result, { message_id: 1 });
22
+ assert.equal(typeof calls[0]?.at, "number");
23
+ });
24
+
25
+ test("mockApi hook registrars are chainable", () => {
26
+ const { api } = mockApi();
27
+ assert.equal(
28
+ api.before(() => undefined),
29
+ api,
30
+ );
31
+ assert.equal(
32
+ api.after((_m, _p, r) => r),
33
+ api,
34
+ );
35
+ });
36
+
37
+ test("mockApi auto-increments message_id across send* calls", async () => {
38
+ const { api } = mockApi();
39
+
40
+ const first = await api.sendMessage({ chat_id: 1, text: "a" });
41
+ const second = await api.sendMessage({ chat_id: 1, text: "b" });
42
+
43
+ assert.deepEqual(first, { message_id: 1 });
44
+ assert.deepEqual(second, { message_id: 2 });
45
+ });
46
+
47
+ test("mockApi results: static override replaces the built-in default", async () => {
48
+ const { api } = mockApi({ results: { sendMessage: { message_id: 99 } } });
49
+
50
+ assert.deepEqual(await api.sendMessage({ chat_id: 1 }), { message_id: 99 });
51
+ });
52
+
53
+ test("mockApi results: an Error value makes the call throw", async () => {
54
+ const { api } = mockApi({
55
+ results: { sendMessage: new TelegramError("sendMessage", 400, "Bad Request") },
56
+ });
57
+
58
+ await assert.rejects(api.sendMessage({ chat_id: 1 }), TelegramError);
59
+ });
60
+
61
+ test("mockApi results: a function sees params and a running attempt count", async () => {
62
+ const { api } = mockApi({
63
+ results: {
64
+ sendMessage: (params: Record<string, unknown> | undefined, attempt: number) =>
65
+ attempt <= 2
66
+ ? new TelegramError("sendMessage", 429, "retry after 0")
67
+ : { message_id: 1, echo: params?.text },
68
+ },
69
+ });
70
+
71
+ api.onError((_m, _e, attempt) => (attempt <= 2 ? { retry: true } : undefined));
72
+
73
+ const result = await api.sendMessage({ chat_id: 1, text: "hi" });
74
+ assert.deepEqual(result, { message_id: 1, echo: "hi" });
75
+ });
76
+
77
+ test("onApi sets a permanent override; reset() clears calls and counters but keeps it", async () => {
78
+ const { api, calls, onApi, reset } = mockApi();
79
+
80
+ await api.sendMessage({ chat_id: 1 });
81
+ onApi("sendMessage", { message_id: 42 });
82
+ assert.deepEqual(await api.sendMessage({ chat_id: 1 }), { message_id: 42 });
83
+ assert.equal(calls.length, 2);
84
+
85
+ reset();
86
+ assert.equal(calls.length, 0);
87
+ assert.deepEqual(await api.sendMessage({ chat_id: 1 }), { message_id: 42 });
88
+ });
89
+
90
+ test("onApi with { times } is one-shot, then falls back to the previous permanent reply", async () => {
91
+ const { api, onApi } = mockApi({ results: { sendMessage: { message_id: 1 } } });
92
+
93
+ onApi("sendMessage", apiError(429, "Too Many Requests"), { times: 1 });
94
+
95
+ await assert.rejects(api.sendMessage({ chat_id: 1 }), TestApiError);
96
+ assert.deepEqual(await api.sendMessage({ chat_id: 1 }), { message_id: 1 });
97
+ });
98
+
99
+ test("onApi { times: 2 } is consumed over exactly two calls", async () => {
100
+ const { api, onApi } = mockApi();
101
+
102
+ onApi("getChat", { id: 1, type: "private", stale: true }, { times: 2 });
103
+ onApi("getChat", { id: 1, type: "private", stale: false });
104
+
105
+ assert.equal((await api.call<{ stale: boolean }>("getChat")).stale, true);
106
+ assert.equal((await api.call<{ stale: boolean }>("getChat")).stale, true);
107
+ assert.equal((await api.call<{ stale: boolean }>("getChat")).stale, false);
108
+ });
109
+
110
+ test("offApi drops a method's override, or every override with no argument", async () => {
111
+ const { api, onApi, offApi } = mockApi();
112
+
113
+ onApi("sendMessage", { message_id: 99 });
114
+ offApi("sendMessage");
115
+ assert.deepEqual(await api.sendMessage({ chat_id: 1 }), { message_id: 1 });
116
+
117
+ onApi("getMe", { id: 7, is_bot: true, first_name: "x" });
118
+ offApi();
119
+ assert.deepEqual(await api.getMe(), { id: 1, is_bot: true, first_name: "bot", username: "bot" });
120
+ });
121
+
122
+ test("apiError() produces a sentinel that throws a TestApiError carrying parameters", async () => {
123
+ const sentinel = apiError(429, "Too Many Requests", { retry_after: 30 });
124
+ assert.ok(isApiErrorSentinel(sentinel));
125
+
126
+ const { api } = mockApi({ results: { sendMessage: sentinel } });
127
+
128
+ await assert.rejects(api.sendMessage({ chat_id: 1 }), (error: unknown) => {
129
+ assert.ok(error instanceof TestApiError);
130
+ assert.ok(error instanceof TelegramError);
131
+ assert.equal(error.code, 429);
132
+ assert.deepEqual(error.parameters, { retry_after: 30 });
133
+ return true;
134
+ });
135
+ });
136
+
137
+ test("strictApi throws for methods with no builtin default and no override", async () => {
138
+ const { api } = mockApi({ strictApi: true });
139
+
140
+ await assert.rejects(api.call("getChatMember"), /no stub for "getChatMember"/);
141
+ assert.deepEqual(await api.sendMessage({ chat_id: 1 }), { message_id: 1 });
142
+ });
143
+
144
+ test("mockApi.lastCall and callsTo filter recorded calls", async () => {
145
+ const { api, lastCall, callsTo } = mockApi();
146
+
147
+ await api.sendMessage({ chat_id: 1, text: "a" });
148
+ await api.answerCallbackQuery({ callback_query_id: "1" });
149
+ await api.sendMessage({ chat_id: 1, text: "b" });
150
+
151
+ assert.equal(lastCall()?.method, "sendMessage");
152
+ assert.equal(lastCall("answerCallbackQuery")?.method, "answerCallbackQuery");
153
+ assert.equal(lastCall("sendMessage")?.params?.text, "b");
154
+ assert.equal(callsTo("sendMessage").length, 2);
155
+ });
156
+
157
+ test("mockApi hooks actually run: before rewrites params, after rewrites result", async () => {
158
+ const { api } = mockApi();
159
+
160
+ api.before((_method, params) => ({ ...params, injected: true }));
161
+ api.after((_method, _params, result) => ({ ...(result as object), tagged: true }));
162
+
163
+ const result = await api.sendMessage({ chat_id: 1 });
164
+
165
+ assert.deepEqual(result, { message_id: 1, tagged: true });
166
+ });
167
+
168
+ test("reply_markup builder instances are normalized to plain JSON on recorded calls", async () => {
169
+ const { api, calls } = mockApi();
170
+
171
+ await api.sendMessage({
172
+ chat_id: 1,
173
+ text: "hi",
174
+ reply_markup: { toJSON: () => ({ inline_keyboard: [[{ text: "ok", callback_data: "ok" }]] }) },
175
+ });
176
+
177
+ assert.deepEqual(calls[0]?.params?.reply_markup, {
178
+ inline_keyboard: [[{ text: "ok", callback_data: "ok" }]],
179
+ });
180
+ });
package/src/api.ts ADDED
@@ -0,0 +1,289 @@
1
+ import {
2
+ type AfterHook,
3
+ type Api,
4
+ type BeforeHook,
5
+ type ErrorAction,
6
+ type ErrorHook,
7
+ TelegramError,
8
+ } from "@yaebal/core";
9
+ import { normalizeParams } from "./normalize.js";
10
+
11
+ /** a single recorded api call: the method, the params it was given, and how it resolved. */
12
+ export interface RecordedCall {
13
+ method: string;
14
+ params: Record<string, unknown> | undefined;
15
+ /** the resolved result, if the call succeeded. */
16
+ result?: unknown;
17
+ /** the thrown error, if the call failed (and no `onError` hook rescued it). */
18
+ error?: unknown;
19
+ /** ms since epoch when the call was made — honors an installed {@link TestClock}. */
20
+ at: number;
21
+ }
22
+
23
+ /** a canned result for one method: a static value, an {@link ApiErrorSentinel}/`Error`, or a function of `(params, attempt)`. */
24
+ export type MockResult =
25
+ | unknown
26
+ | Error
27
+ | ApiErrorSentinel
28
+ | ((params: Record<string, unknown> | undefined, attempt: number) => unknown);
29
+
30
+ /** the shape `apiError(...)` returns — a sentinel telling the mock to throw a {@link TestApiError}. */
31
+ export interface ApiErrorSentinel {
32
+ readonly __yaebalApiError: true;
33
+ code: number;
34
+ description: string;
35
+ parameters?: Record<string, unknown>;
36
+ }
37
+
38
+ /**
39
+ * simulate a real Telegram Bot API error response — the bot sees exactly what it would see
40
+ * from the real api: a thrown {@link TestApiError} (a {@link TelegramError} subclass).
41
+ *
42
+ * @example
43
+ * env.onApi("sendMessage", apiError(403, "Forbidden: bot was blocked by the user"));
44
+ * env.onApi("sendMessage", apiError(429, "Too Many Requests", { retry_after: 30 }));
45
+ */
46
+ export function apiError(
47
+ code: number,
48
+ description: string,
49
+ parameters?: Record<string, unknown>,
50
+ ): ApiErrorSentinel {
51
+ return { __yaebalApiError: true, code, description, parameters };
52
+ }
53
+
54
+ /** typeguard for a stored `apiError(...)` sentinel. */
55
+ export function isApiErrorSentinel(value: unknown): value is ApiErrorSentinel {
56
+ return typeof value === "object" && value !== null && "__yaebalApiError" in value;
57
+ }
58
+
59
+ /** a {@link TelegramError} carrying the optional `parameters` bag (e.g. `retry_after`) real errors ship. */
60
+ export class TestApiError extends TelegramError {
61
+ readonly parameters?: Record<string, unknown>;
62
+
63
+ constructor(
64
+ method: string,
65
+ code: number,
66
+ description: string,
67
+ parameters?: Record<string, unknown>,
68
+ ) {
69
+ super(method, code, description);
70
+ this.parameters = parameters;
71
+ }
72
+ }
73
+
74
+ /** options accepted by `{ times }` overrides: one-shot (or N-shot) replies. */
75
+ export interface OnApiOptions {
76
+ /** consume this override for exactly `times` calls, then fall back to the next queued/permanent reply. default: permanent (never expires). */
77
+ times?: number;
78
+ }
79
+
80
+ export interface MockApiOptions {
81
+ /** per-method canned results/errors, keyed by method name — seeds the permanent override, same as calling `onApi(method, result)` for each entry. */
82
+ results?: Record<string, MockResult>;
83
+ /** throw instead of falling back to `{}` when a method has no builtin default and no override registered. catches "forgot to stub this" in tests that care. default `false`. */
84
+ strictApi?: boolean;
85
+ /** clock to timestamp recorded calls with; defaults to the real `Date.now`. */
86
+ now?: () => number;
87
+ }
88
+
89
+ /** result of {@link mockApi}: the fake `api`, its recorded calls, and inspection/stubbing helpers. */
90
+ export interface MockApi {
91
+ api: Api;
92
+ calls: RecordedCall[];
93
+ /** hooks registered on `api` via `before`/`after`/`onError` — inspect them or invoke them yourself. */
94
+ hooks: { before: BeforeHook[]; after: AfterHook[]; onError: ErrorHook[] };
95
+ /** the most recent recorded call, optionally filtered to a method. */
96
+ lastCall(method?: string): RecordedCall | undefined;
97
+ /** every recorded call to a given method, in call order. */
98
+ callsTo(method: string): RecordedCall[];
99
+ /** override a method's reply. permanent unless `opts.times` is given (then it's consumed after `times` calls and the previous permanent, if any, resumes). */
100
+ onApi(method: string, reply: MockResult, opts?: OnApiOptions): void;
101
+ /** drop a method's overrides (or every method's, if none given) — reverts to the builtin default. */
102
+ offApi(method?: string): void;
103
+ /** clear recorded calls and per-method attempt counters. keeps hooks and overrides. */
104
+ reset(): void;
105
+ }
106
+
107
+ /** default results for known methods; everything else resolves to `{}` (or throws, with `strictApi`). */
108
+ const STUBBED_METHODS = new Set(["getMe", "answerCallbackQuery"]);
109
+
110
+ function builtinResult(method: string, nextMessageId: () => number): unknown {
111
+ if (method.startsWith("send") || method === "copyMessage" || method === "forwardMessage") {
112
+ return { message_id: nextMessageId() };
113
+ }
114
+
115
+ if (method === "answerCallbackQuery") return true;
116
+ if (method === "getMe") return { id: 1, is_bot: true, first_name: "bot", username: "bot" };
117
+
118
+ return {};
119
+ }
120
+
121
+ function hasBuiltin(method: string): boolean {
122
+ return (
123
+ method.startsWith("send") ||
124
+ method === "copyMessage" ||
125
+ method === "forwardMessage" ||
126
+ STUBBED_METHODS.has(method)
127
+ );
128
+ }
129
+
130
+ interface QueuedReply {
131
+ reply: MockResult;
132
+ remaining: number;
133
+ }
134
+
135
+ interface MethodOverride {
136
+ queue: QueuedReply[];
137
+ permanent?: MockResult;
138
+ }
139
+
140
+ /**
141
+ * a fake {@link Api} whose every method records `{ method, params, result | error, at }` into
142
+ * `calls` and resolves to a sensible default (auto-incrementing `message_id` for `send*`, `true`
143
+ * for `answerCallbackQuery`, `{}` otherwise) — or to whatever `onApi`/`options.results` says.
144
+ * `before`/`after`/`onError` are real hook registrars (not no-ops): register a hook the same way
145
+ * you would on the production `Api` and it actually runs, including retries requested by an
146
+ * `onError` hook. the mock never actually waits on a requested `delayMs` — retries settle
147
+ * instantly, so tests stay fast (pair with {@link installTestClock} if the code under test
148
+ * schedules the retry itself via `setTimeout`).
149
+ */
150
+ export function mockApi(options: MockApiOptions = {}): MockApi {
151
+ const calls: RecordedCall[] = [];
152
+ const overrides = new Map<string, MethodOverride>();
153
+ const attempts = new Map<string, number>();
154
+ const now = options.now ?? (() => Date.now());
155
+ let nextMessageId = 1;
156
+
157
+ for (const [method, reply] of Object.entries(options.results ?? {})) {
158
+ overrides.set(method, { queue: [], permanent: reply });
159
+ }
160
+
161
+ const hooks = {
162
+ before: [] as BeforeHook[],
163
+ after: [] as AfterHook[],
164
+ onError: [] as ErrorHook[],
165
+ };
166
+
167
+ function resolveReply(method: string, params: Record<string, unknown> | undefined): unknown {
168
+ const attempt = (attempts.get(method) ?? 0) + 1;
169
+ attempts.set(method, attempt);
170
+
171
+ const override = overrides.get(method);
172
+ let reply: MockResult | undefined;
173
+
174
+ if (override?.queue.length) {
175
+ const head = override.queue[0] as QueuedReply;
176
+ head.remaining--;
177
+ reply = head.reply;
178
+ if (head.remaining <= 0) override.queue.shift();
179
+ } else if (override && "permanent" in override) {
180
+ reply = override.permanent;
181
+ } else if (options.strictApi && !hasBuiltin(method)) {
182
+ throw new Error(
183
+ `mockApi: no stub for "${method}" — register one with onApi("${method}", ...), or disable strictApi`,
184
+ );
185
+ } else {
186
+ return builtinResult(method, () => nextMessageId++);
187
+ }
188
+
189
+ if (typeof reply === "function") {
190
+ return (reply as (p: typeof params, a: number) => unknown)(params, attempt);
191
+ }
192
+
193
+ if (isApiErrorSentinel(reply)) {
194
+ return new TestApiError(method, reply.code, reply.description, reply.parameters);
195
+ }
196
+
197
+ return reply;
198
+ }
199
+
200
+ const call = async (method: string, rawParams?: Record<string, unknown>): Promise<never> => {
201
+ let p = normalizeParams(rawParams);
202
+ for (const hook of hooks.before) {
203
+ const next = await hook(method, p);
204
+ if (next !== undefined) p = next;
205
+ }
206
+
207
+ for (let attempt = 1; ; attempt++) {
208
+ let result: unknown;
209
+
210
+ try {
211
+ result = resolveReply(method, p);
212
+ if (result instanceof Error) throw result;
213
+ } catch (error) {
214
+ let retry: ErrorAction | undefined;
215
+ for (const hook of hooks.onError) {
216
+ const action = await hook(method, error, attempt);
217
+ if (action?.retry) {
218
+ retry = action;
219
+ break;
220
+ }
221
+ }
222
+
223
+ calls.push({ method, params: p, error, at: now() });
224
+ if (!retry) throw error;
225
+ continue; // the mock never actually waits on retry.delayMs
226
+ }
227
+
228
+ for (const hook of hooks.after) {
229
+ const next = await hook(method, p, result);
230
+ if (next !== undefined) result = next;
231
+ }
232
+
233
+ calls.push({ method, params: p, result, at: now() });
234
+ return result as never;
235
+ }
236
+ };
237
+
238
+ const registrar: Record<string, unknown> = {
239
+ call: (method: string, params?: Record<string, unknown>) => call(method, params),
240
+ fileUrl: (filePath: string) => `https://example.invalid/file/${filePath}`,
241
+ before(hook: BeforeHook) {
242
+ hooks.before.push(hook);
243
+ return api;
244
+ },
245
+ after(hook: AfterHook) {
246
+ hooks.after.push(hook);
247
+ return api;
248
+ },
249
+ onError(hook: ErrorHook) {
250
+ hooks.onError.push(hook);
251
+ return api;
252
+ },
253
+ };
254
+
255
+ const api = new Proxy(registrar, {
256
+ get(obj, prop: string) {
257
+ if (prop in obj) return obj[prop];
258
+
259
+ const method = (params?: Record<string, unknown>) => call(prop, params);
260
+ obj[prop] = method;
261
+
262
+ return method;
263
+ },
264
+ }) as unknown as Api;
265
+
266
+ return {
267
+ api,
268
+ calls,
269
+ hooks,
270
+ lastCall: (method) =>
271
+ method ? [...calls].reverse().find((c) => c.method === method) : calls.at(-1),
272
+ callsTo: (method) => calls.filter((c) => c.method === method),
273
+ onApi: (method, reply, opts) => {
274
+ const entry = overrides.get(method) ?? { queue: [] };
275
+ if (opts?.times !== undefined) entry.queue.push({ reply, remaining: opts.times });
276
+ else entry.permanent = reply;
277
+ overrides.set(method, entry);
278
+ },
279
+ offApi: (method) => {
280
+ if (method) overrides.delete(method);
281
+ else overrides.clear();
282
+ },
283
+ reset: () => {
284
+ calls.length = 0;
285
+ attempts.clear();
286
+ nextMessageId = 1;
287
+ },
288
+ };
289
+ }