@mtcute/test 0.6.0 → 0.7.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 (69) hide show
  1. package/cjs/client.d.ts +3 -4
  2. package/cjs/client.js +5 -8
  3. package/cjs/client.js.map +1 -1
  4. package/cjs/index.d.ts +1 -1
  5. package/cjs/index.js +1 -1
  6. package/cjs/index.js.map +1 -1
  7. package/cjs/storage/auth-keys.d.ts +3 -0
  8. package/cjs/storage/auth-keys.js +95 -0
  9. package/cjs/storage/auth-keys.js.map +1 -0
  10. package/cjs/storage/index.d.ts +4 -0
  11. package/cjs/storage/index.js +21 -0
  12. package/cjs/storage/index.js.map +1 -0
  13. package/cjs/storage/key-value.d.ts +3 -0
  14. package/cjs/storage/key-value.js +41 -0
  15. package/cjs/storage/key-value.js.map +1 -0
  16. package/cjs/storage/peers.d.ts +3 -0
  17. package/cjs/storage/peers.js +75 -0
  18. package/cjs/storage/peers.js.map +1 -0
  19. package/cjs/storage/ref-messages.d.ts +3 -0
  20. package/cjs/storage/ref-messages.js +69 -0
  21. package/cjs/storage/ref-messages.js.map +1 -0
  22. package/cjs/storage.d.ts +2 -16
  23. package/cjs/storage.js +18 -29
  24. package/cjs/storage.js.map +1 -1
  25. package/cjs/transport.test.js +1 -2
  26. package/cjs/transport.test.js.map +1 -1
  27. package/cjs/utils.js +1 -2
  28. package/cjs/utils.js.map +1 -1
  29. package/esm/client.d.ts +3 -4
  30. package/esm/client.js +6 -9
  31. package/esm/client.js.map +1 -1
  32. package/esm/index.d.ts +1 -1
  33. package/esm/index.js +1 -1
  34. package/esm/index.js.map +1 -1
  35. package/esm/storage/auth-keys.d.ts +3 -0
  36. package/esm/storage/auth-keys.js +90 -0
  37. package/esm/storage/auth-keys.js.map +1 -0
  38. package/esm/storage/index.d.ts +4 -0
  39. package/esm/storage/index.js +5 -0
  40. package/esm/storage/index.js.map +1 -0
  41. package/esm/storage/key-value.d.ts +3 -0
  42. package/esm/storage/key-value.js +36 -0
  43. package/esm/storage/key-value.js.map +1 -0
  44. package/esm/storage/peers.d.ts +3 -0
  45. package/esm/storage/peers.js +70 -0
  46. package/esm/storage/peers.js.map +1 -0
  47. package/esm/storage/ref-messages.d.ts +3 -0
  48. package/esm/storage/ref-messages.js +64 -0
  49. package/esm/storage/ref-messages.js.map +1 -0
  50. package/esm/storage.d.ts +2 -16
  51. package/esm/storage.js +18 -29
  52. package/esm/storage.js.map +1 -1
  53. package/esm/transport.test.js +1 -2
  54. package/esm/transport.test.js.map +1 -1
  55. package/esm/utils.js +2 -3
  56. package/esm/utils.js.map +1 -1
  57. package/package.json +2 -2
  58. package/cjs/storage-test.d.ts +0 -24
  59. package/cjs/storage-test.js +0 -365
  60. package/cjs/storage-test.js.map +0 -1
  61. package/cjs/storage.test.d.ts +0 -1
  62. package/cjs/storage.test.js +0 -43
  63. package/cjs/storage.test.js.map +0 -1
  64. package/esm/storage-test.d.ts +0 -24
  65. package/esm/storage-test.js +0 -357
  66. package/esm/storage-test.js.map +0 -1
  67. package/esm/storage.test.d.ts +0 -1
  68. package/esm/storage.test.js +0 -41
  69. package/esm/storage.test.js.map +0 -1
@@ -1,357 +0,0 @@
1
- import Long from 'long';
2
- import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
3
- import { defaultProductionDc, hexEncode, LogManager } from '@mtcute/core/utils.js';
4
- import { __tlReaderMap } from '@mtcute/tl/binary/reader.js';
5
- import { __tlWriterMap } from '@mtcute/tl/binary/writer.js';
6
- import { createStub } from './stub.js';
7
- export const stubPeerUser = {
8
- id: 123123,
9
- accessHash: Long.fromBits(123, 456),
10
- type: 'user',
11
- username: 'some_user',
12
- phone: '78005553535',
13
- full: createStub('user', { id: 123123 }),
14
- };
15
- const peerUserInput = {
16
- _: 'inputPeerUser',
17
- userId: 123123,
18
- accessHash: Long.fromBits(123, 456),
19
- };
20
- const peerChannel = {
21
- id: -1001183945448,
22
- accessHash: Long.fromBits(666, 555),
23
- type: 'channel',
24
- username: 'some_channel',
25
- full: createStub('channel', { id: 123123 }),
26
- };
27
- const peerChannelInput = {
28
- _: 'inputPeerChannel',
29
- channelId: 1183945448,
30
- accessHash: Long.fromBits(666, 555),
31
- };
32
- function maybeHexEncode(x) {
33
- if (x == null)
34
- return null;
35
- return hexEncode(x);
36
- }
37
- export function testStorage(s, params) {
38
- beforeAll(async () => {
39
- const logger = new LogManager();
40
- logger.level = 0;
41
- s.setup?.(logger, __tlReaderMap, __tlWriterMap);
42
- await s.load?.();
43
- });
44
- afterAll(() => s.destroy?.());
45
- beforeEach(() => s.reset(true));
46
- describe('default dc', () => {
47
- it('should store', async () => {
48
- await s.setDefaultDcs(defaultProductionDc);
49
- expect(await s.getDefaultDcs()).toEqual(defaultProductionDc);
50
- });
51
- it('should remove', async () => {
52
- await s.setDefaultDcs(null);
53
- expect(await s.getDefaultDcs()).toBeNull();
54
- });
55
- });
56
- describe('auth keys', () => {
57
- beforeAll(() => void vi.useFakeTimers());
58
- afterAll(() => void vi.useRealTimers());
59
- const key2 = new Uint8Array(256).fill(0x42);
60
- const key3 = new Uint8Array(256).fill(0x43);
61
- const key2i0 = new Uint8Array(256).fill(0x44);
62
- const key2i1 = new Uint8Array(256).fill(0x45);
63
- const key3i0 = new Uint8Array(256).fill(0x46);
64
- const key3i1 = new Uint8Array(256).fill(0x47);
65
- it('should store perm auth key', async () => {
66
- await s.setAuthKeyFor(2, key2);
67
- await s.setAuthKeyFor(3, key3);
68
- expect(maybeHexEncode(await s.getAuthKeyFor(2))).toEqual(hexEncode(key2));
69
- expect(maybeHexEncode(await s.getAuthKeyFor(3))).toEqual(hexEncode(key3));
70
- });
71
- it('should store temp auth keys', async () => {
72
- const expire = Date.now() + 1000;
73
- await s.setTempAuthKeyFor(2, 0, key2i0, expire);
74
- await s.setTempAuthKeyFor(2, 1, key2i1, expire);
75
- await s.setTempAuthKeyFor(3, 0, key3i0, expire);
76
- await s.setTempAuthKeyFor(3, 1, key3i1, expire);
77
- expect(maybeHexEncode(await s.getAuthKeyFor(2, 0))).toEqual(hexEncode(key2i0));
78
- expect(maybeHexEncode(await s.getAuthKeyFor(2, 1))).toEqual(hexEncode(key2i1));
79
- expect(maybeHexEncode(await s.getAuthKeyFor(3, 0))).toEqual(hexEncode(key3i0));
80
- expect(maybeHexEncode(await s.getAuthKeyFor(3, 1))).toEqual(hexEncode(key3i1));
81
- });
82
- it('should expire temp auth keys', async () => {
83
- const expire = Date.now() + 1000;
84
- await s.setTempAuthKeyFor(2, 0, key2i0, expire);
85
- await s.setTempAuthKeyFor(2, 1, key2i1, expire);
86
- await s.setTempAuthKeyFor(3, 0, key3i0, expire);
87
- await s.setTempAuthKeyFor(3, 1, key3i1, expire);
88
- vi.advanceTimersByTime(10000);
89
- expect(await s.getAuthKeyFor(2, 0)).toBeNull();
90
- expect(await s.getAuthKeyFor(2, 1)).toBeNull();
91
- expect(await s.getAuthKeyFor(3, 0)).toBeNull();
92
- expect(await s.getAuthKeyFor(3, 1)).toBeNull();
93
- });
94
- it('should remove auth keys', async () => {
95
- const expire = Date.now() + 1000;
96
- await s.setTempAuthKeyFor(2, 0, key2i0, expire);
97
- await s.setTempAuthKeyFor(2, 1, key2i1, expire);
98
- await s.setAuthKeyFor(2, key2);
99
- await s.setAuthKeyFor(3, key3);
100
- await s.setAuthKeyFor(2, null);
101
- await s.setTempAuthKeyFor(2, 0, null, 0);
102
- await s.setTempAuthKeyFor(2, 1, null, 0);
103
- expect(await s.getAuthKeyFor(2)).toBeNull();
104
- expect(await s.getAuthKeyFor(2, 0)).toBeNull();
105
- expect(await s.getAuthKeyFor(2, 1)).toBeNull();
106
- expect(maybeHexEncode(await s.getAuthKeyFor(3))).toEqual(hexEncode(key3)); // should not be removed
107
- });
108
- it('should remove all auth keys with dropAuthKeysFor', async () => {
109
- const expire = Date.now() + 1000;
110
- await s.setTempAuthKeyFor(2, 0, key2i0, expire);
111
- await s.setTempAuthKeyFor(2, 1, key2i1, expire);
112
- await s.setAuthKeyFor(2, key2);
113
- await s.setAuthKeyFor(3, key3);
114
- await s.dropAuthKeysFor(2);
115
- expect(await s.getAuthKeyFor(2)).toBeNull();
116
- expect(await s.getAuthKeyFor(2, 0)).toBeNull();
117
- expect(await s.getAuthKeyFor(2, 1)).toBeNull();
118
- expect(maybeHexEncode(await s.getAuthKeyFor(3))).toEqual(hexEncode(key3)); // should not be removed
119
- });
120
- it('should not reset auth keys on reset()', async () => {
121
- await s.setAuthKeyFor(2, key2);
122
- await s.setAuthKeyFor(3, key3);
123
- await s.reset();
124
- expect(maybeHexEncode(await s.getAuthKeyFor(2))).toEqual(hexEncode(key2));
125
- expect(maybeHexEncode(await s.getAuthKeyFor(3))).toEqual(hexEncode(key3));
126
- });
127
- it('should reset auth keys on reset(true)', async () => {
128
- await s.setAuthKeyFor(2, key2);
129
- await s.setAuthKeyFor(3, key3);
130
- await s.reset(true);
131
- expect(await s.getAuthKeyFor(2)).toBeNull();
132
- expect(await s.getAuthKeyFor(3)).toBeNull();
133
- });
134
- });
135
- describe('future salts', () => {
136
- const someFutureSalt1 = Long.fromBits(123, 456);
137
- const someFutureSalt2 = Long.fromBits(789, 101112);
138
- const someFutureSalt3 = Long.fromBits(131415, 161718);
139
- const someFutureSalt4 = Long.fromBits(192021, 222324);
140
- const salts1 = [
141
- { _: 'mt_future_salt', validSince: 123, validUntil: 456, salt: someFutureSalt1 },
142
- { _: 'mt_future_salt', validSince: 789, validUntil: 101112, salt: someFutureSalt2 },
143
- ];
144
- const salts2 = [
145
- { _: 'mt_future_salt', validSince: 123, validUntil: 456, salt: someFutureSalt3 },
146
- { _: 'mt_future_salt', validSince: 789, validUntil: 101112, salt: someFutureSalt4 },
147
- ];
148
- it('should store and retrieve future salts', async () => {
149
- await s.setFutureSalts(1, salts1);
150
- await s.setFutureSalts(2, salts2);
151
- expect(await s.getFutureSalts(1)).toEqual(salts1);
152
- expect(await s.getFutureSalts(2)).toEqual(salts2);
153
- });
154
- });
155
- describe('peers', () => {
156
- it('should cache and return peers', async () => {
157
- await s.updatePeers([stubPeerUser, peerChannel]);
158
- await s.save?.(); // update-related methods are batched, so we need to save
159
- expect(await s.getPeerById(stubPeerUser.id)).toEqual(peerUserInput);
160
- expect(await s.getPeerById(peerChannel.id)).toEqual(peerChannelInput);
161
- });
162
- it('should cache and return peers by username', async () => {
163
- await s.updatePeers([stubPeerUser, peerChannel]);
164
- await s.save?.(); // update-related methods are batched, so we need to save
165
- expect(await s.getPeerByUsername(stubPeerUser.username)).toEqual(peerUserInput);
166
- expect(await s.getPeerByUsername(peerChannel.username)).toEqual(peerChannelInput);
167
- });
168
- it('should cache and return peers by phone', async () => {
169
- await s.updatePeers([stubPeerUser]);
170
- await s.save?.(); // update-related methods are batched, so we need to save
171
- expect(await s.getPeerByPhone(stubPeerUser.phone)).toEqual(peerUserInput);
172
- });
173
- if (!params?.skipEntityOverwrite) {
174
- it('should overwrite existing cached peers', async () => {
175
- await s.updatePeers([stubPeerUser]);
176
- await s.updatePeers([{ ...stubPeerUser, username: 'whatever' }]);
177
- await s.save?.(); // update-related methods are batched, so we need to save
178
- expect(await s.getPeerById(stubPeerUser.id)).toEqual(peerUserInput);
179
- expect(await s.getPeerByUsername(stubPeerUser.username)).toBeNull();
180
- expect(await s.getPeerByUsername('whatever')).toEqual(peerUserInput);
181
- });
182
- }
183
- it('should cache full peer info', async () => {
184
- await s.updatePeers([stubPeerUser, peerChannel]);
185
- await s.save?.(); // update-related methods are batched, so we need to save
186
- expect({
187
- ...(await s.getFullPeerById(stubPeerUser.id)),
188
- usernames: [],
189
- restrictionReason: [],
190
- }).toEqual(stubPeerUser.full);
191
- expect({
192
- ...(await s.getFullPeerById(peerChannel.id)),
193
- usernames: [],
194
- restrictionReason: [],
195
- }).toEqual(peerChannel.full);
196
- });
197
- describe('min peers', () => {
198
- it('should generate *FromMessage constructors from reference messages', async () => {
199
- await s.updatePeers([peerChannel]);
200
- await s.saveReferenceMessage(stubPeerUser.id, peerChannel.id, 456);
201
- await s.save?.(); // update-related methods are batched, so we need to save
202
- expect(await s.getPeerById(stubPeerUser.id)).toEqual({
203
- _: 'inputPeerUserFromMessage',
204
- peer: peerChannelInput,
205
- msgId: 456,
206
- userId: stubPeerUser.id,
207
- });
208
- });
209
- it('should handle cases when referenced chat is not available', async () => {
210
- // this shouldn't really happen, but the storage should be able to handle it
211
- await s.saveReferenceMessage(stubPeerUser.id, peerChannel.id, 456);
212
- await s.save?.(); // update-related methods are batched, so we need to save
213
- expect(await s.getPeerById(stubPeerUser.id)).toEqual(null);
214
- });
215
- it('should return full peer if it gets available', async () => {
216
- await s.updatePeers([peerChannel]);
217
- await s.saveReferenceMessage(stubPeerUser.id, peerChannel.id, 456);
218
- await s.save?.(); // update-related methods are batched, so we need to save
219
- await s.updatePeers([stubPeerUser]);
220
- await s.save?.();
221
- expect(await s.getPeerById(stubPeerUser.id)).toEqual(peerUserInput);
222
- });
223
- it('should handle cases when referenced message is deleted', async () => {
224
- await s.updatePeers([peerChannel]);
225
- await s.saveReferenceMessage(stubPeerUser.id, peerChannel.id, 456);
226
- await s.save?.(); // update-related methods are batched, so we need to save
227
- await s.deleteReferenceMessages(peerChannel.id, [456]);
228
- await s.save?.();
229
- expect(await s.getPeerById(stubPeerUser.id)).toEqual(null);
230
- });
231
- });
232
- });
233
- describe('current user', () => {
234
- const self = {
235
- userId: 123123,
236
- isBot: false,
237
- };
238
- it('should store and return self info', async () => {
239
- await s.setSelf(self);
240
- expect(await s.getSelf()).toEqual(self);
241
- });
242
- it('should remove self info', async () => {
243
- await s.setSelf(self);
244
- await s.setSelf(null);
245
- expect(await s.getSelf()).toBeNull();
246
- });
247
- });
248
- describe('updates state', () => {
249
- it('should store and return updates state', async () => {
250
- await s.setUpdatesPts(1);
251
- await s.setUpdatesQts(2);
252
- await s.setUpdatesDate(3);
253
- await s.setUpdatesSeq(4);
254
- await s.save?.(); // update-related methods are batched, so we need to save
255
- expect(await s.getUpdatesState()).toEqual([1, 2, 3, 4]);
256
- });
257
- it('should store and return channel pts', async () => {
258
- await s.setManyChannelPts(new Map([
259
- [1, 2],
260
- [3, 4],
261
- ]));
262
- await s.save?.(); // update-related methods are batched, so we need to save
263
- expect(await s.getChannelPts(1)).toEqual(2);
264
- expect(await s.getChannelPts(3)).toEqual(4);
265
- expect(await s.getChannelPts(2)).toBeNull();
266
- });
267
- it('should be null after reset', async () => {
268
- expect(await s.getUpdatesState()).toBeNull();
269
- });
270
- });
271
- params?.customTests?.(s);
272
- }
273
- export function testStateStorage(s) {
274
- beforeAll(async () => {
275
- const logger = new LogManager();
276
- logger.level = 0;
277
- s.setup?.(logger, __tlReaderMap, __tlWriterMap);
278
- await s.load?.();
279
- });
280
- afterAll(() => s.destroy?.());
281
- beforeEach(() => s.reset());
282
- describe('key-value state', () => {
283
- beforeAll(() => void vi.useFakeTimers());
284
- afterAll(() => void vi.useRealTimers());
285
- it('should store and return state', async () => {
286
- await s.setState('a', 'b');
287
- await s.setState('c', 'd');
288
- await s.setState('e', 'f');
289
- expect(await s.getState('a')).toEqual('b');
290
- expect(await s.getState('c')).toEqual('d');
291
- expect(await s.getState('e')).toEqual('f');
292
- });
293
- it('should remove state', async () => {
294
- await s.setState('a', 'b');
295
- await s.setState('c', 'd');
296
- await s.setState('e', 'f');
297
- await s.deleteState('a');
298
- await s.deleteState('c');
299
- await s.deleteState('e');
300
- expect(await s.getState('a')).toBeNull();
301
- expect(await s.getState('c')).toBeNull();
302
- expect(await s.getState('e')).toBeNull();
303
- });
304
- it('should expire state', async () => {
305
- await s.setState('a', 'b', 1);
306
- await s.setState('c', 'd', 1);
307
- await s.setState('e', 'f', 1);
308
- vi.advanceTimersByTime(10000);
309
- expect(await s.getState('a')).toBeNull();
310
- expect(await s.getState('c')).toBeNull();
311
- expect(await s.getState('e')).toBeNull();
312
- });
313
- });
314
- describe('scenes', () => {
315
- it('should store and return scenes', async () => {
316
- await s.setCurrentScene('a', 'b');
317
- await s.setCurrentScene('c', 'd');
318
- await s.setCurrentScene('e', 'f');
319
- expect(await s.getCurrentScene('a')).toEqual('b');
320
- expect(await s.getCurrentScene('c')).toEqual('d');
321
- expect(await s.getCurrentScene('e')).toEqual('f');
322
- });
323
- it('should remove scenes', async () => {
324
- await s.setCurrentScene('a', 'b');
325
- await s.setCurrentScene('c', 'd');
326
- await s.setCurrentScene('e', 'f');
327
- await s.deleteCurrentScene('a');
328
- await s.deleteCurrentScene('c');
329
- await s.deleteCurrentScene('e');
330
- expect(await s.getCurrentScene('a')).toBeNull();
331
- expect(await s.getCurrentScene('c')).toBeNull();
332
- expect(await s.getCurrentScene('e')).toBeNull();
333
- });
334
- });
335
- describe('rate limit', () => {
336
- beforeAll(() => void vi.useFakeTimers());
337
- afterAll(() => void vi.useRealTimers());
338
- const check = () => s.getRateLimit('test', 3, 1);
339
- it('should implement basic rate limiting', async () => {
340
- vi.setSystemTime(0);
341
- expect(await check()).toEqual([3, 1000]);
342
- expect(await check()).toEqual([2, 1000]);
343
- expect(await check()).toEqual([1, 1000]);
344
- expect(await check()).toEqual([0, 1000]);
345
- vi.setSystemTime(1001);
346
- expect(await check()).toEqual([3, 2001]);
347
- });
348
- it('should allow resetting rate limit', async () => {
349
- vi.setSystemTime(0);
350
- await check();
351
- await check();
352
- await s.resetRateLimit('test');
353
- expect(await check()).toEqual([3, 1000]);
354
- });
355
- });
356
- }
357
- //# sourceMappingURL=storage-test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage-test.js","sourceRoot":"","sources":["../../src/storage-test.ts"],"names":[],"mappings":"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","sourcesContent":["import Long from 'long'\nimport { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport { ITelegramStorage, MaybeAsync } from '@mtcute/core'\nimport { defaultProductionDc, hexEncode, Logger, LogManager, TlReaderMap, TlWriterMap } from '@mtcute/core/utils.js'\nimport { mtp, tl } from '@mtcute/tl'\nimport { __tlReaderMap } from '@mtcute/tl/binary/reader.js'\nimport { __tlWriterMap } from '@mtcute/tl/binary/writer.js'\n\nimport { createStub } from './stub.js'\n\nexport const stubPeerUser: ITelegramStorage.PeerInfo = {\n id: 123123,\n accessHash: Long.fromBits(123, 456),\n type: 'user',\n username: 'some_user',\n phone: '78005553535',\n full: createStub('user', { id: 123123 }),\n}\nconst peerUserInput: tl.TypeInputPeer = {\n _: 'inputPeerUser',\n userId: 123123,\n accessHash: Long.fromBits(123, 456),\n}\n\nconst peerChannel: ITelegramStorage.PeerInfo = {\n id: -1001183945448,\n accessHash: Long.fromBits(666, 555),\n type: 'channel',\n username: 'some_channel',\n full: createStub('channel', { id: 123123 }),\n}\n\nconst peerChannelInput: tl.TypeInputPeer = {\n _: 'inputPeerChannel',\n channelId: 1183945448,\n accessHash: Long.fromBits(666, 555),\n}\n\nfunction maybeHexEncode(x: Uint8Array | null): string | null {\n if (x == null) return null\n\n return hexEncode(x)\n}\n\nexport function testStorage<T extends ITelegramStorage>(\n s: T,\n params?: {\n skipEntityOverwrite?: boolean\n customTests?: (s: T) => void\n },\n): void {\n beforeAll(async () => {\n const logger = new LogManager()\n logger.level = 0\n s.setup?.(logger, __tlReaderMap, __tlWriterMap)\n\n await s.load?.()\n })\n\n afterAll(() => s.destroy?.())\n beforeEach(() => s.reset(true))\n\n describe('default dc', () => {\n it('should store', async () => {\n await s.setDefaultDcs(defaultProductionDc)\n expect(await s.getDefaultDcs()).toEqual(defaultProductionDc)\n })\n\n it('should remove', async () => {\n await s.setDefaultDcs(null)\n expect(await s.getDefaultDcs()).toBeNull()\n })\n })\n\n describe('auth keys', () => {\n beforeAll(() => void vi.useFakeTimers())\n afterAll(() => void vi.useRealTimers())\n\n const key2 = new Uint8Array(256).fill(0x42)\n const key3 = new Uint8Array(256).fill(0x43)\n\n const key2i0 = new Uint8Array(256).fill(0x44)\n const key2i1 = new Uint8Array(256).fill(0x45)\n const key3i0 = new Uint8Array(256).fill(0x46)\n const key3i1 = new Uint8Array(256).fill(0x47)\n\n it('should store perm auth key', async () => {\n await s.setAuthKeyFor(2, key2)\n await s.setAuthKeyFor(3, key3)\n\n expect(maybeHexEncode(await s.getAuthKeyFor(2))).toEqual(hexEncode(key2))\n expect(maybeHexEncode(await s.getAuthKeyFor(3))).toEqual(hexEncode(key3))\n })\n\n it('should store temp auth keys', async () => {\n const expire = Date.now() + 1000\n\n await s.setTempAuthKeyFor(2, 0, key2i0, expire)\n await s.setTempAuthKeyFor(2, 1, key2i1, expire)\n await s.setTempAuthKeyFor(3, 0, key3i0, expire)\n await s.setTempAuthKeyFor(3, 1, key3i1, expire)\n\n expect(maybeHexEncode(await s.getAuthKeyFor(2, 0))).toEqual(hexEncode(key2i0))\n expect(maybeHexEncode(await s.getAuthKeyFor(2, 1))).toEqual(hexEncode(key2i1))\n expect(maybeHexEncode(await s.getAuthKeyFor(3, 0))).toEqual(hexEncode(key3i0))\n expect(maybeHexEncode(await s.getAuthKeyFor(3, 1))).toEqual(hexEncode(key3i1))\n })\n\n it('should expire temp auth keys', async () => {\n const expire = Date.now() + 1000\n\n await s.setTempAuthKeyFor(2, 0, key2i0, expire)\n await s.setTempAuthKeyFor(2, 1, key2i1, expire)\n await s.setTempAuthKeyFor(3, 0, key3i0, expire)\n await s.setTempAuthKeyFor(3, 1, key3i1, expire)\n\n vi.advanceTimersByTime(10000)\n\n expect(await s.getAuthKeyFor(2, 0)).toBeNull()\n expect(await s.getAuthKeyFor(2, 1)).toBeNull()\n expect(await s.getAuthKeyFor(3, 0)).toBeNull()\n expect(await s.getAuthKeyFor(3, 1)).toBeNull()\n })\n\n it('should remove auth keys', async () => {\n const expire = Date.now() + 1000\n\n await s.setTempAuthKeyFor(2, 0, key2i0, expire)\n await s.setTempAuthKeyFor(2, 1, key2i1, expire)\n await s.setAuthKeyFor(2, key2)\n await s.setAuthKeyFor(3, key3)\n\n await s.setAuthKeyFor(2, null)\n await s.setTempAuthKeyFor(2, 0, null, 0)\n await s.setTempAuthKeyFor(2, 1, null, 0)\n\n expect(await s.getAuthKeyFor(2)).toBeNull()\n expect(await s.getAuthKeyFor(2, 0)).toBeNull()\n expect(await s.getAuthKeyFor(2, 1)).toBeNull()\n expect(maybeHexEncode(await s.getAuthKeyFor(3))).toEqual(hexEncode(key3)) // should not be removed\n })\n\n it('should remove all auth keys with dropAuthKeysFor', async () => {\n const expire = Date.now() + 1000\n\n await s.setTempAuthKeyFor(2, 0, key2i0, expire)\n await s.setTempAuthKeyFor(2, 1, key2i1, expire)\n await s.setAuthKeyFor(2, key2)\n await s.setAuthKeyFor(3, key3)\n\n await s.dropAuthKeysFor(2)\n\n expect(await s.getAuthKeyFor(2)).toBeNull()\n expect(await s.getAuthKeyFor(2, 0)).toBeNull()\n expect(await s.getAuthKeyFor(2, 1)).toBeNull()\n expect(maybeHexEncode(await s.getAuthKeyFor(3))).toEqual(hexEncode(key3)) // should not be removed\n })\n\n it('should not reset auth keys on reset()', async () => {\n await s.setAuthKeyFor(2, key2)\n await s.setAuthKeyFor(3, key3)\n await s.reset()\n\n expect(maybeHexEncode(await s.getAuthKeyFor(2))).toEqual(hexEncode(key2))\n expect(maybeHexEncode(await s.getAuthKeyFor(3))).toEqual(hexEncode(key3))\n })\n\n it('should reset auth keys on reset(true)', async () => {\n await s.setAuthKeyFor(2, key2)\n await s.setAuthKeyFor(3, key3)\n await s.reset(true)\n\n expect(await s.getAuthKeyFor(2)).toBeNull()\n expect(await s.getAuthKeyFor(3)).toBeNull()\n })\n })\n\n describe('future salts', () => {\n const someFutureSalt1 = Long.fromBits(123, 456)\n const someFutureSalt2 = Long.fromBits(789, 101112)\n const someFutureSalt3 = Long.fromBits(131415, 161718)\n const someFutureSalt4 = Long.fromBits(192021, 222324)\n\n const salts1: mtp.RawMt_future_salt[] = [\n { _: 'mt_future_salt', validSince: 123, validUntil: 456, salt: someFutureSalt1 },\n { _: 'mt_future_salt', validSince: 789, validUntil: 101112, salt: someFutureSalt2 },\n ]\n const salts2: mtp.RawMt_future_salt[] = [\n { _: 'mt_future_salt', validSince: 123, validUntil: 456, salt: someFutureSalt3 },\n { _: 'mt_future_salt', validSince: 789, validUntil: 101112, salt: someFutureSalt4 },\n ]\n\n it('should store and retrieve future salts', async () => {\n await s.setFutureSalts(1, salts1)\n await s.setFutureSalts(2, salts2)\n\n expect(await s.getFutureSalts(1)).toEqual(salts1)\n expect(await s.getFutureSalts(2)).toEqual(salts2)\n })\n })\n\n describe('peers', () => {\n it('should cache and return peers', async () => {\n await s.updatePeers([stubPeerUser, peerChannel])\n await s.save?.() // update-related methods are batched, so we need to save\n\n expect(await s.getPeerById(stubPeerUser.id)).toEqual(peerUserInput)\n expect(await s.getPeerById(peerChannel.id)).toEqual(peerChannelInput)\n })\n\n it('should cache and return peers by username', async () => {\n await s.updatePeers([stubPeerUser, peerChannel])\n await s.save?.() // update-related methods are batched, so we need to save\n\n expect(await s.getPeerByUsername(stubPeerUser.username!)).toEqual(peerUserInput)\n expect(await s.getPeerByUsername(peerChannel.username!)).toEqual(peerChannelInput)\n })\n\n it('should cache and return peers by phone', async () => {\n await s.updatePeers([stubPeerUser])\n await s.save?.() // update-related methods are batched, so we need to save\n\n expect(await s.getPeerByPhone(stubPeerUser.phone!)).toEqual(peerUserInput)\n })\n\n if (!params?.skipEntityOverwrite) {\n it('should overwrite existing cached peers', async () => {\n await s.updatePeers([stubPeerUser])\n await s.updatePeers([{ ...stubPeerUser, username: 'whatever' }])\n await s.save?.() // update-related methods are batched, so we need to save\n\n expect(await s.getPeerById(stubPeerUser.id)).toEqual(peerUserInput)\n expect(await s.getPeerByUsername(stubPeerUser.username!)).toBeNull()\n expect(await s.getPeerByUsername('whatever')).toEqual(peerUserInput)\n })\n }\n\n it('should cache full peer info', async () => {\n await s.updatePeers([stubPeerUser, peerChannel])\n await s.save?.() // update-related methods are batched, so we need to save\n\n expect({\n ...(await s.getFullPeerById(stubPeerUser.id)),\n usernames: [],\n restrictionReason: [],\n }).toEqual(stubPeerUser.full)\n expect({\n ...(await s.getFullPeerById(peerChannel.id)),\n usernames: [],\n restrictionReason: [],\n }).toEqual(peerChannel.full)\n })\n\n describe('min peers', () => {\n it('should generate *FromMessage constructors from reference messages', async () => {\n await s.updatePeers([peerChannel])\n await s.saveReferenceMessage(stubPeerUser.id, peerChannel.id, 456)\n await s.save?.() // update-related methods are batched, so we need to save\n\n expect(await s.getPeerById(stubPeerUser.id)).toEqual({\n _: 'inputPeerUserFromMessage',\n peer: peerChannelInput,\n msgId: 456,\n userId: stubPeerUser.id,\n })\n })\n\n it('should handle cases when referenced chat is not available', async () => {\n // this shouldn't really happen, but the storage should be able to handle it\n await s.saveReferenceMessage(stubPeerUser.id, peerChannel.id, 456)\n await s.save?.() // update-related methods are batched, so we need to save\n\n expect(await s.getPeerById(stubPeerUser.id)).toEqual(null)\n })\n\n it('should return full peer if it gets available', async () => {\n await s.updatePeers([peerChannel])\n await s.saveReferenceMessage(stubPeerUser.id, peerChannel.id, 456)\n await s.save?.() // update-related methods are batched, so we need to save\n\n await s.updatePeers([stubPeerUser])\n await s.save?.()\n\n expect(await s.getPeerById(stubPeerUser.id)).toEqual(peerUserInput)\n })\n\n it('should handle cases when referenced message is deleted', async () => {\n await s.updatePeers([peerChannel])\n await s.saveReferenceMessage(stubPeerUser.id, peerChannel.id, 456)\n await s.save?.() // update-related methods are batched, so we need to save\n\n await s.deleteReferenceMessages(peerChannel.id, [456])\n await s.save?.()\n\n expect(await s.getPeerById(stubPeerUser.id)).toEqual(null)\n })\n })\n })\n\n describe('current user', () => {\n const self: ITelegramStorage.SelfInfo = {\n userId: 123123,\n isBot: false,\n }\n\n it('should store and return self info', async () => {\n await s.setSelf(self)\n expect(await s.getSelf()).toEqual(self)\n })\n\n it('should remove self info', async () => {\n await s.setSelf(self)\n await s.setSelf(null)\n expect(await s.getSelf()).toBeNull()\n })\n })\n\n describe('updates state', () => {\n it('should store and return updates state', async () => {\n await s.setUpdatesPts(1)\n await s.setUpdatesQts(2)\n await s.setUpdatesDate(3)\n await s.setUpdatesSeq(4)\n await s.save?.() // update-related methods are batched, so we need to save\n\n expect(await s.getUpdatesState()).toEqual([1, 2, 3, 4])\n })\n\n it('should store and return channel pts', async () => {\n await s.setManyChannelPts(\n new Map([\n [1, 2],\n [3, 4],\n ]),\n )\n await s.save?.() // update-related methods are batched, so we need to save\n\n expect(await s.getChannelPts(1)).toEqual(2)\n expect(await s.getChannelPts(3)).toEqual(4)\n expect(await s.getChannelPts(2)).toBeNull()\n })\n\n it('should be null after reset', async () => {\n expect(await s.getUpdatesState()).toBeNull()\n })\n })\n\n params?.customTests?.(s)\n}\n\ninterface IStateStorage {\n setup?(log: Logger, readerMap: TlReaderMap, writerMap: TlWriterMap): void\n\n load?(): MaybeAsync<void>\n\n save?(): MaybeAsync<void>\n\n destroy?(): MaybeAsync<void>\n\n reset(): MaybeAsync<void>\n\n getState(key: string): MaybeAsync<unknown>\n\n setState(key: string, state: unknown, ttl?: number): MaybeAsync<void>\n\n deleteState(key: string): MaybeAsync<void>\n\n getCurrentScene(key: string): MaybeAsync<string | null>\n\n setCurrentScene(key: string, scene: string, ttl?: number): MaybeAsync<void>\n\n deleteCurrentScene(key: string): MaybeAsync<void>\n\n getRateLimit(key: string, limit: number, window: number): MaybeAsync<[number, number]>\n\n resetRateLimit(key: string): MaybeAsync<void>\n}\n\nexport function testStateStorage(s: IStateStorage) {\n beforeAll(async () => {\n const logger = new LogManager()\n logger.level = 0\n s.setup?.(logger, __tlReaderMap, __tlWriterMap)\n\n await s.load?.()\n })\n\n afterAll(() => s.destroy?.())\n beforeEach(() => s.reset())\n\n describe('key-value state', () => {\n beforeAll(() => void vi.useFakeTimers())\n afterAll(() => void vi.useRealTimers())\n\n it('should store and return state', async () => {\n await s.setState('a', 'b')\n await s.setState('c', 'd')\n await s.setState('e', 'f')\n\n expect(await s.getState('a')).toEqual('b')\n expect(await s.getState('c')).toEqual('d')\n expect(await s.getState('e')).toEqual('f')\n })\n\n it('should remove state', async () => {\n await s.setState('a', 'b')\n await s.setState('c', 'd')\n await s.setState('e', 'f')\n\n await s.deleteState('a')\n await s.deleteState('c')\n await s.deleteState('e')\n\n expect(await s.getState('a')).toBeNull()\n expect(await s.getState('c')).toBeNull()\n expect(await s.getState('e')).toBeNull()\n })\n\n it('should expire state', async () => {\n await s.setState('a', 'b', 1)\n await s.setState('c', 'd', 1)\n await s.setState('e', 'f', 1)\n\n vi.advanceTimersByTime(10000)\n\n expect(await s.getState('a')).toBeNull()\n expect(await s.getState('c')).toBeNull()\n expect(await s.getState('e')).toBeNull()\n })\n })\n\n describe('scenes', () => {\n it('should store and return scenes', async () => {\n await s.setCurrentScene('a', 'b')\n await s.setCurrentScene('c', 'd')\n await s.setCurrentScene('e', 'f')\n\n expect(await s.getCurrentScene('a')).toEqual('b')\n expect(await s.getCurrentScene('c')).toEqual('d')\n expect(await s.getCurrentScene('e')).toEqual('f')\n })\n\n it('should remove scenes', async () => {\n await s.setCurrentScene('a', 'b')\n await s.setCurrentScene('c', 'd')\n await s.setCurrentScene('e', 'f')\n\n await s.deleteCurrentScene('a')\n await s.deleteCurrentScene('c')\n await s.deleteCurrentScene('e')\n\n expect(await s.getCurrentScene('a')).toBeNull()\n expect(await s.getCurrentScene('c')).toBeNull()\n expect(await s.getCurrentScene('e')).toBeNull()\n })\n })\n\n describe('rate limit', () => {\n beforeAll(() => void vi.useFakeTimers())\n afterAll(() => void vi.useRealTimers())\n\n const check = () => s.getRateLimit('test', 3, 1)\n\n it('should implement basic rate limiting', async () => {\n vi.setSystemTime(0)\n\n expect(await check()).toEqual([3, 1000])\n expect(await check()).toEqual([2, 1000])\n expect(await check()).toEqual([1, 1000])\n expect(await check()).toEqual([0, 1000])\n\n vi.setSystemTime(1001)\n\n expect(await check()).toEqual([3, 2001])\n })\n\n it('should allow resetting rate limit', async () => {\n vi.setSystemTime(0)\n\n await check()\n await check()\n\n await s.resetRateLimit('test')\n expect(await check()).toEqual([3, 1000])\n })\n })\n}\n"]}
@@ -1 +0,0 @@
1
- export {};
@@ -1,41 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { BaseTelegramClient } from '@mtcute/core';
3
- import { StubMemoryTelegramStorage } from './storage.js';
4
- import { createStub } from './stub.js';
5
- import { StubTelegramTransport } from './transport.js';
6
- describe('storage stub', () => {
7
- it('should correctly intercept calls', async () => {
8
- const log = [];
9
- const client = new BaseTelegramClient({
10
- apiId: 0,
11
- apiHash: '',
12
- logLevel: 0,
13
- defaultDcs: {
14
- main: createStub('dcOption', { ipAddress: '1.2.3.4', port: 1234 }),
15
- media: createStub('dcOption', { ipAddress: '1.2.3.4', port: 5678 }),
16
- },
17
- transport: () => new StubTelegramTransport({
18
- onMessage: (msg) => {
19
- if (msg.slice(0, 8).reduce((a, b) => a + b, 0) === 0) {
20
- // should not happen, since we're providing stub keys
21
- log.push('unauthed_message');
22
- }
23
- setTimeout(() => {
24
- client.close().catch(() => { });
25
- }, 10);
26
- },
27
- }),
28
- storage: new StubMemoryTelegramStorage({
29
- hasKeys: true,
30
- onLoad: () => log.push('load'),
31
- onSave: () => log.push('save'),
32
- onDestroy: () => log.push('destroy'),
33
- onReset: () => log.push('reset'),
34
- }),
35
- });
36
- await client.connect();
37
- await client.call({ _: 'help.getConfig' }).catch(() => { }); // ignore "client closed" error
38
- expect(log).toEqual(['load', 'save', 'destroy']);
39
- });
40
- });
41
- //# sourceMappingURL=storage.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage.test.js","sourceRoot":"","sources":["../../src/storage.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,GAAG,GAAa,EAAE,CAAA;QAExB,MAAM,MAAM,GAAG,IAAI,kBAAkB,CAAC;YAClC,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE;gBACR,IAAI,EAAE,UAAU,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBAClE,KAAK,EAAE,UAAU,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;aACtE;YACD,SAAS,EAAE,GAAG,EAAE,CACZ,IAAI,qBAAqB,CAAC;gBACtB,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;oBACf,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;wBAClD,qDAAqD;wBACrD,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;qBAC/B;oBACD,UAAU,CAAC,GAAG,EAAE;wBACZ,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;oBAClC,CAAC,EAAE,EAAE,CAAC,CAAA;gBACV,CAAC;aACJ,CAAC;YACN,OAAO,EAAE,IAAI,yBAAyB,CAAC;gBACnC,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC9B,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC9B,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBACpC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;aACnC,CAAC;SACL,CAAC,CAAA;QAEF,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;QACtB,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA,CAAC,+BAA+B;QAE1F,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAA;IACpD,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA","sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { BaseTelegramClient } from '@mtcute/core'\n\nimport { StubMemoryTelegramStorage } from './storage.js'\nimport { createStub } from './stub.js'\nimport { StubTelegramTransport } from './transport.js'\n\ndescribe('storage stub', () => {\n it('should correctly intercept calls', async () => {\n const log: string[] = []\n\n const client = new BaseTelegramClient({\n apiId: 0,\n apiHash: '',\n logLevel: 0,\n defaultDcs: {\n main: createStub('dcOption', { ipAddress: '1.2.3.4', port: 1234 }),\n media: createStub('dcOption', { ipAddress: '1.2.3.4', port: 5678 }),\n },\n transport: () =>\n new StubTelegramTransport({\n onMessage: (msg) => {\n if (msg.slice(0, 8).reduce((a, b) => a + b, 0) === 0) {\n // should not happen, since we're providing stub keys\n log.push('unauthed_message')\n }\n setTimeout(() => {\n client.close().catch(() => {})\n }, 10)\n },\n }),\n storage: new StubMemoryTelegramStorage({\n hasKeys: true,\n onLoad: () => log.push('load'),\n onSave: () => log.push('save'),\n onDestroy: () => log.push('destroy'),\n onReset: () => log.push('reset'),\n }),\n })\n\n await client.connect()\n await client.call({ _: 'help.getConfig' }).catch(() => {}) // ignore \"client closed\" error\n\n expect(log).toEqual(['load', 'save', 'destroy'])\n })\n})\n"]}