chz-telegram-bot 0.7.13 → 0.7.15
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/dtos/propertyProviderSets.d.ts +0 -1
- package/dist/dtos/propertyProviderSets.d.ts.map +1 -1
- package/dist/entities/actions/commandAction.d.ts +1 -1
- package/dist/entities/actions/commandAction.d.ts.map +1 -1
- package/dist/entities/actions/commandAction.js +2 -2
- package/dist/helpers/builders/commandActionBuilder.d.ts.map +1 -1
- package/dist/helpers/builders/commandActionBuilder.js +2 -3
- package/package.json +4 -1
- package/eslint.config.ts +0 -62
- package/src/builtin/helpAction.ts +0 -17
- package/src/dtos/chatHistoryMessage.ts +0 -22
- package/src/dtos/chatInfo.ts +0 -12
- package/src/dtos/commandTriggerCheckResult.ts +0 -40
- package/src/dtos/cooldownInfo.ts +0 -10
- package/src/dtos/incomingMessage.ts +0 -71
- package/src/dtos/incomingQuery.ts +0 -14
- package/src/dtos/messageInfo.ts +0 -15
- package/src/dtos/propertyProviderSets.ts +0 -21
- package/src/dtos/replyInfo.ts +0 -9
- package/src/dtos/responses/delay.ts +0 -28
- package/src/dtos/responses/imageMessage.ts +0 -41
- package/src/dtos/responses/inlineQueryResponse.ts +0 -26
- package/src/dtos/responses/reaction.ts +0 -30
- package/src/dtos/responses/textMessage.ts +0 -44
- package/src/dtos/responses/unpin.ts +0 -27
- package/src/dtos/responses/videoMessage.ts +0 -41
- package/src/dtos/userInfo.ts +0 -8
- package/src/entities/actions/commandAction.ts +0 -275
- package/src/entities/actions/inlineQueryAction.ts +0 -83
- package/src/entities/actions/replyCaptureAction.ts +0 -110
- package/src/entities/actions/scheduledAction.ts +0 -182
- package/src/entities/botInstance.ts +0 -92
- package/src/entities/cachedStateFactory.ts +0 -14
- package/src/entities/context/baseContext.ts +0 -111
- package/src/entities/context/chatContext.ts +0 -135
- package/src/entities/context/inlineQueryContext.ts +0 -63
- package/src/entities/context/messageContext.ts +0 -250
- package/src/entities/context/replyContext.ts +0 -260
- package/src/entities/states/actionStateBase.ts +0 -6
- package/src/entities/taskRecord.ts +0 -11
- package/src/helpers/builders/commandActionBuilder.ts +0 -214
- package/src/helpers/builders/inlineQueryActionBuilder.ts +0 -71
- package/src/helpers/builders/scheduledActionBuilder.ts +0 -143
- package/src/helpers/mapUtils.ts +0 -28
- package/src/helpers/noop.ts +0 -20
- package/src/helpers/objectFromEntries.ts +0 -7
- package/src/helpers/timeConvertions.ts +0 -13
- package/src/helpers/toArray.ts +0 -3
- package/src/helpers/traceFactory.ts +0 -11
- package/src/index.ts +0 -33
- package/src/main.ts +0 -76
- package/src/services/actionProcessingService.ts +0 -125
- package/src/services/actionProcessors/baseProcessor.ts +0 -67
- package/src/services/actionProcessors/commandActionProcessor.ts +0 -231
- package/src/services/actionProcessors/inlineQueryActionProcessor.ts +0 -165
- package/src/services/actionProcessors/scheduledActionProcessor.ts +0 -136
- package/src/services/jsonFileStorage.ts +0 -181
- package/src/services/nodeTimeoutScheduler.ts +0 -79
- package/src/services/responseProcessingQueue.ts +0 -57
- package/src/services/telegramApi.ts +0 -278
- package/src/types/action.ts +0 -15
- package/src/types/actionState.ts +0 -4
- package/src/types/cachedValueAccessor.ts +0 -1
- package/src/types/capture.ts +0 -33
- package/src/types/commandCondition.ts +0 -9
- package/src/types/commandTrigger.ts +0 -1
- package/src/types/events.ts +0 -286
- package/src/types/externalAliases.ts +0 -18
- package/src/types/handlers.ts +0 -26
- package/src/types/inputFile.ts +0 -4
- package/src/types/messageSendingOptions.ts +0 -10
- package/src/types/messageTypes.ts +0 -21
- package/src/types/propertyProvider.ts +0 -14
- package/src/types/response.ts +0 -51
- package/src/types/scheduler.ts +0 -20
- package/src/types/storage.ts +0 -23
- package/src/types/timeValues.ts +0 -33
- package/src/types/trace.ts +0 -5
- package/tests/dtos/commandTriggerCheckResult.test.ts +0 -301
- package/tests/entities/actions/inlineQueryAction.test.ts +0 -359
- package/tests/entities/actions/replyCaptureAction.test.ts +0 -501
- package/tests/entities/cachedStateFactory.test.ts +0 -98
- package/tests/entities/context/chatContext.test.ts +0 -606
- package/tests/entities/context/messageContext.test.ts +0 -370
- package/tests/entities/states/actionStateBase.test.ts +0 -138
- package/tests/entities/taskRecord.test.ts +0 -195
- package/tests/helpers/mapUtils.test.ts +0 -163
- package/tests/helpers/timeConvertions.test.ts +0 -129
- package/tests/services/actionProcessors/baseActionProcessor.test.ts +0 -359
- package/tests/services/actionProcessors/commandActionProcessor.test.ts +0 -268
- package/tests/services/actionProcessors/inlineQueryActionProcessor.test.ts +0 -616
- package/tests/services/actionProcessors/processorTestHelpers.ts +0 -147
- package/tests/services/actionProcessors/scheduledActionProcessor.test.ts +0 -153
- package/tests/services/jsonFileStorage.test.ts +0 -927
- package/tests/services/nodeTimeoutScheduler.test.ts +0 -421
- package/tests/services/responseProcessingQueue.test.ts +0 -388
- package/tsconfig.build.json +0 -8
- package/tsconfig.json +0 -118
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect, mock } from 'bun:test';
|
|
2
|
-
import { MessageContextInternal } from '../../../src/entities/context/messageContext';
|
|
3
|
-
import { ActionStateBase } from '../../../src/entities/states/actionStateBase';
|
|
4
|
-
import { TypedEventEmitter } from '../../../src/types/events';
|
|
5
|
-
import { TextMessage } from '../../../src/dtos/responses/textMessage';
|
|
6
|
-
import { ImageMessage } from '../../../src/dtos/responses/imageMessage';
|
|
7
|
-
import { VideoMessage } from '../../../src/dtos/responses/videoMessage';
|
|
8
|
-
import { Reaction } from '../../../src/dtos/responses/reaction';
|
|
9
|
-
import { ActionKey } from '../../../src/types/action';
|
|
10
|
-
import { Seconds } from '../../../src/types/timeValues';
|
|
11
|
-
import { CommandAction } from '../../../src/entities/actions/commandAction';
|
|
12
|
-
import { Message, UserFromGetMe } from '@telegraf/types';
|
|
13
|
-
import {
|
|
14
|
-
createMockStorage,
|
|
15
|
-
createMockScheduler
|
|
16
|
-
} from '../../services/actionProcessors/processorTestHelpers';
|
|
17
|
-
import { IncomingMessage } from '../../../src/dtos/incomingMessage';
|
|
18
|
-
|
|
19
|
-
function createMockCommandAction(): CommandAction<ActionStateBase> {
|
|
20
|
-
return {
|
|
21
|
-
key: 'command:test-action' as ActionKey,
|
|
22
|
-
name: 'test-action',
|
|
23
|
-
stateConstructor: () => new ActionStateBase(),
|
|
24
|
-
exec: mock(() => Promise.resolve([])),
|
|
25
|
-
triggers: [],
|
|
26
|
-
handler: mock(() => Promise.resolve()),
|
|
27
|
-
condition: () => true,
|
|
28
|
-
ratelimitSemaphores: new Map(),
|
|
29
|
-
maxAllowedSimultaniousExecutions: 1,
|
|
30
|
-
readmeFactory: () => ''
|
|
31
|
-
} as unknown as CommandAction<ActionStateBase>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function createMessageContext(
|
|
35
|
-
messageText: string = 'test message'
|
|
36
|
-
): MessageContextInternal<ActionStateBase> {
|
|
37
|
-
const storage = createMockStorage();
|
|
38
|
-
const scheduler = createMockScheduler();
|
|
39
|
-
const eventEmitter = new TypedEventEmitter();
|
|
40
|
-
const action = createMockCommandAction();
|
|
41
|
-
|
|
42
|
-
// Create a minimal TelegramMessage-like object
|
|
43
|
-
const telegramMessage = {
|
|
44
|
-
message_id: 100,
|
|
45
|
-
date: Math.floor(Date.now() / 1000),
|
|
46
|
-
chat: { id: 12345, type: 'private' },
|
|
47
|
-
from: { id: 999, is_bot: false, first_name: 'TestUser' },
|
|
48
|
-
text: messageText
|
|
49
|
-
} as Message;
|
|
50
|
-
|
|
51
|
-
const incomingMessage = new IncomingMessage(telegramMessage, 'TestBot', []);
|
|
52
|
-
|
|
53
|
-
const botInfo = {
|
|
54
|
-
id: 111,
|
|
55
|
-
is_bot: true,
|
|
56
|
-
first_name: 'Bot',
|
|
57
|
-
username: 'testbot',
|
|
58
|
-
can_join_groups: true,
|
|
59
|
-
can_read_all_group_messages: false,
|
|
60
|
-
supports_inline_queries: false,
|
|
61
|
-
can_connect_to_business: false,
|
|
62
|
-
has_main_web_app: false
|
|
63
|
-
} as UserFromGetMe;
|
|
64
|
-
|
|
65
|
-
const ctx = new MessageContextInternal<ActionStateBase>(
|
|
66
|
-
storage,
|
|
67
|
-
scheduler,
|
|
68
|
-
eventEmitter,
|
|
69
|
-
action,
|
|
70
|
-
incomingMessage,
|
|
71
|
-
'TestBot',
|
|
72
|
-
botInfo
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
return ctx;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
describe('MessageContextInternal', () => {
|
|
79
|
-
describe('properties', () => {
|
|
80
|
-
test('should have startCooldown default to true', () => {
|
|
81
|
-
const ctx = createMessageContext();
|
|
82
|
-
|
|
83
|
-
expect(ctx.startCooldown).toBe(true);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test('should have customCooldown as undefined by default', () => {
|
|
87
|
-
const ctx = createMessageContext();
|
|
88
|
-
|
|
89
|
-
expect(ctx.customCooldown).toBeUndefined();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
test('should have empty matchResults by default', () => {
|
|
93
|
-
const ctx = createMessageContext();
|
|
94
|
-
|
|
95
|
-
expect(ctx.matchResults).toEqual([]);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
describe('skipCooldown', () => {
|
|
100
|
-
test('should set startCooldown to false', () => {
|
|
101
|
-
const ctx = createMessageContext();
|
|
102
|
-
|
|
103
|
-
ctx.skipCooldown();
|
|
104
|
-
|
|
105
|
-
expect(ctx.startCooldown).toBe(false);
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
describe('startCustomCooldown', () => {
|
|
110
|
-
test('should set startCooldown to true', () => {
|
|
111
|
-
const ctx = createMessageContext();
|
|
112
|
-
ctx.startCooldown = false;
|
|
113
|
-
|
|
114
|
-
ctx.startCustomCooldown(60 as Seconds);
|
|
115
|
-
|
|
116
|
-
expect(ctx.startCooldown).toBe(true);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
test('should set customCooldown value', () => {
|
|
120
|
-
const ctx = createMessageContext();
|
|
121
|
-
const cooldown = 120 as Seconds;
|
|
122
|
-
|
|
123
|
-
ctx.startCustomCooldown(cooldown);
|
|
124
|
-
|
|
125
|
-
expect(ctx.customCooldown).toBe(cooldown);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
describe('reply.withText', () => {
|
|
130
|
-
test('should add TextMessage to responses', () => {
|
|
131
|
-
const ctx = createMessageContext();
|
|
132
|
-
|
|
133
|
-
ctx.reply.withText('Hello!');
|
|
134
|
-
|
|
135
|
-
expect(ctx.responses.length).toBe(1);
|
|
136
|
-
expect(ctx.responses[0]).toBeInstanceOf(TextMessage);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
test('should set reply info with message id', () => {
|
|
140
|
-
const ctx = createMessageContext();
|
|
141
|
-
|
|
142
|
-
ctx.reply.withText('Reply');
|
|
143
|
-
|
|
144
|
-
const response = ctx.responses[0] as TextMessage;
|
|
145
|
-
expect(response.replyInfo?.id).toBe(ctx.messageInfo.id);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test('should not include quote by default', () => {
|
|
149
|
-
const ctx = createMessageContext();
|
|
150
|
-
|
|
151
|
-
ctx.reply.withText('Reply');
|
|
152
|
-
|
|
153
|
-
const response = ctx.responses[0] as TextMessage;
|
|
154
|
-
expect(response.replyInfo?.quote).toBeUndefined();
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
test('should return capture controller', () => {
|
|
158
|
-
const ctx = createMessageContext();
|
|
159
|
-
|
|
160
|
-
const controller = ctx.reply.withText('Reply');
|
|
161
|
-
|
|
162
|
-
expect(controller.captureReplies).toBeDefined();
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe('reply.withImage', () => {
|
|
167
|
-
test('should add ImageMessage to responses', () => {
|
|
168
|
-
const ctx = createMessageContext();
|
|
169
|
-
|
|
170
|
-
ctx.reply.withImage('test-image');
|
|
171
|
-
|
|
172
|
-
expect(ctx.responses.length).toBe(1);
|
|
173
|
-
expect(ctx.responses[0]).toBeInstanceOf(ImageMessage);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
test('should set reply info with message id', () => {
|
|
177
|
-
const ctx = createMessageContext();
|
|
178
|
-
|
|
179
|
-
ctx.reply.withImage('test');
|
|
180
|
-
|
|
181
|
-
const response = ctx.responses[0] as ImageMessage;
|
|
182
|
-
expect(response.replyInfo?.id).toBe(ctx.messageInfo.id);
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
describe('reply.withVideo', () => {
|
|
187
|
-
test('should add VideoMessage to responses', () => {
|
|
188
|
-
const ctx = createMessageContext();
|
|
189
|
-
|
|
190
|
-
ctx.reply.withVideo('test-video');
|
|
191
|
-
|
|
192
|
-
expect(ctx.responses.length).toBe(1);
|
|
193
|
-
expect(ctx.responses[0]).toBeInstanceOf(VideoMessage);
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
test('should set reply info with message id', () => {
|
|
197
|
-
const ctx = createMessageContext();
|
|
198
|
-
|
|
199
|
-
ctx.reply.withVideo('test');
|
|
200
|
-
|
|
201
|
-
const response = ctx.responses[0] as VideoMessage;
|
|
202
|
-
expect(response.replyInfo?.id).toBe(ctx.messageInfo.id);
|
|
203
|
-
});
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
describe('reply.withReaction', () => {
|
|
207
|
-
test('should add Reaction to responses', () => {
|
|
208
|
-
const ctx = createMessageContext();
|
|
209
|
-
|
|
210
|
-
ctx.reply.withReaction('👍');
|
|
211
|
-
|
|
212
|
-
expect(ctx.responses.length).toBe(1);
|
|
213
|
-
expect(ctx.responses[0]).toBeInstanceOf(Reaction);
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
test('should set correct emoji', () => {
|
|
217
|
-
const ctx = createMessageContext();
|
|
218
|
-
|
|
219
|
-
ctx.reply.withReaction('❤');
|
|
220
|
-
|
|
221
|
-
const response = ctx.responses[0] as Reaction;
|
|
222
|
-
expect(response.emoji).toBe('❤');
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
test('should set correct message id', () => {
|
|
226
|
-
const ctx = createMessageContext();
|
|
227
|
-
|
|
228
|
-
ctx.reply.withReaction('👍');
|
|
229
|
-
|
|
230
|
-
const response = ctx.responses[0] as Reaction;
|
|
231
|
-
expect(response.messageId).toBe(ctx.messageInfo.id);
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
describe('reply.andQuote.withText', () => {
|
|
236
|
-
test('should add TextMessage to responses', () => {
|
|
237
|
-
const ctx = createMessageContext('original message');
|
|
238
|
-
|
|
239
|
-
ctx.reply.andQuote.withText('Quoted reply');
|
|
240
|
-
|
|
241
|
-
expect(ctx.responses.length).toBe(1);
|
|
242
|
-
expect(ctx.responses[0]).toBeInstanceOf(TextMessage);
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
test('should include quote from message text when no match results', () => {
|
|
246
|
-
const ctx = createMessageContext('original message');
|
|
247
|
-
|
|
248
|
-
ctx.reply.andQuote.withText('Quoted reply');
|
|
249
|
-
|
|
250
|
-
const response = ctx.responses[0] as TextMessage;
|
|
251
|
-
expect(response.replyInfo?.quote).toBe('original message');
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
test('should include quote from match results when available', () => {
|
|
255
|
-
const ctx = createMessageContext('test 123 value');
|
|
256
|
-
ctx.matchResults = [
|
|
257
|
-
['test 123', '123'] as unknown as RegExpMatchArray
|
|
258
|
-
];
|
|
259
|
-
|
|
260
|
-
ctx.reply.andQuote.withText('Quoted reply');
|
|
261
|
-
|
|
262
|
-
const response = ctx.responses[0] as TextMessage;
|
|
263
|
-
expect(response.replyInfo?.quote).toBe('123');
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
test('should use custom quote string when provided', () => {
|
|
267
|
-
const ctx = createMessageContext('original message');
|
|
268
|
-
|
|
269
|
-
ctx.reply.andQuote.withText('Reply', 'custom quote');
|
|
270
|
-
|
|
271
|
-
const response = ctx.responses[0] as TextMessage;
|
|
272
|
-
expect(response.replyInfo?.quote).toBe('custom quote');
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
describe('reply.andQuote.withImage', () => {
|
|
277
|
-
test('should add ImageMessage with quote', () => {
|
|
278
|
-
const ctx = createMessageContext('original message');
|
|
279
|
-
|
|
280
|
-
ctx.reply.andQuote.withImage('test-image');
|
|
281
|
-
|
|
282
|
-
const response = ctx.responses[0] as ImageMessage;
|
|
283
|
-
expect(response.replyInfo?.quote).toBe('original message');
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
test('should use custom quote when provided', () => {
|
|
287
|
-
const ctx = createMessageContext('original message');
|
|
288
|
-
|
|
289
|
-
ctx.reply.andQuote.withImage('test-image', 'custom quote');
|
|
290
|
-
|
|
291
|
-
const response = ctx.responses[0] as ImageMessage;
|
|
292
|
-
expect(response.replyInfo?.quote).toBe('custom quote');
|
|
293
|
-
});
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
describe('reply.andQuote.withVideo', () => {
|
|
297
|
-
test('should add VideoMessage with quote', () => {
|
|
298
|
-
const ctx = createMessageContext('original message');
|
|
299
|
-
|
|
300
|
-
ctx.reply.andQuote.withVideo('test-video');
|
|
301
|
-
|
|
302
|
-
const response = ctx.responses[0] as VideoMessage;
|
|
303
|
-
expect(response.replyInfo?.quote).toBe('original message');
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
test('should use custom quote when provided', () => {
|
|
307
|
-
const ctx = createMessageContext('original message');
|
|
308
|
-
|
|
309
|
-
ctx.reply.andQuote.withVideo('test-video', 'custom quote');
|
|
310
|
-
|
|
311
|
-
const response = ctx.responses[0] as VideoMessage;
|
|
312
|
-
expect(response.replyInfo?.quote).toBe('custom quote');
|
|
313
|
-
});
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
describe('inherited send methods', () => {
|
|
317
|
-
test('send.text should work from parent class', () => {
|
|
318
|
-
const ctx = createMessageContext();
|
|
319
|
-
|
|
320
|
-
ctx.send.text('Standalone message');
|
|
321
|
-
|
|
322
|
-
expect(ctx.responses.length).toBe(1);
|
|
323
|
-
expect(ctx.responses[0]).toBeInstanceOf(TextMessage);
|
|
324
|
-
|
|
325
|
-
const response = ctx.responses[0] as TextMessage;
|
|
326
|
-
expect(response.replyInfo).toBeUndefined();
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
test('send.image should work from parent class', () => {
|
|
330
|
-
const ctx = createMessageContext();
|
|
331
|
-
|
|
332
|
-
ctx.send.image('standalone-image');
|
|
333
|
-
|
|
334
|
-
expect(ctx.responses.length).toBe(1);
|
|
335
|
-
expect(ctx.responses[0]).toBeInstanceOf(ImageMessage);
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
test('send.video should work from parent class', () => {
|
|
339
|
-
const ctx = createMessageContext();
|
|
340
|
-
|
|
341
|
-
ctx.send.video('standalone-video');
|
|
342
|
-
|
|
343
|
-
expect(ctx.responses.length).toBe(1);
|
|
344
|
-
expect(ctx.responses[0]).toBeInstanceOf(VideoMessage);
|
|
345
|
-
});
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
describe('combined operations', () => {
|
|
349
|
-
test('should support mixing send and reply operations', () => {
|
|
350
|
-
const ctx = createMessageContext();
|
|
351
|
-
|
|
352
|
-
ctx.reply.withText('Reply first');
|
|
353
|
-
ctx.send.text('Then send');
|
|
354
|
-
ctx.reply.withReaction('👍');
|
|
355
|
-
|
|
356
|
-
expect(ctx.responses.length).toBe(3);
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
test('should maintain order of all operations', () => {
|
|
360
|
-
const ctx = createMessageContext();
|
|
361
|
-
|
|
362
|
-
ctx.send.text('1');
|
|
363
|
-
ctx.reply.withText('2');
|
|
364
|
-
ctx.send.image('3');
|
|
365
|
-
ctx.reply.andQuote.withText('4');
|
|
366
|
-
|
|
367
|
-
expect(ctx.responses.length).toBe(4);
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
});
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect } from 'bun:test';
|
|
2
|
-
import { ActionStateBase } from '../../../src/entities/states/actionStateBase';
|
|
3
|
-
import { IActionState } from '../../../src/types/actionState';
|
|
4
|
-
|
|
5
|
-
describe('ActionStateBase', () => {
|
|
6
|
-
describe('default values', () => {
|
|
7
|
-
test('should have empty pinnedMessages array', () => {
|
|
8
|
-
const state = new ActionStateBase();
|
|
9
|
-
|
|
10
|
-
expect(state.pinnedMessages).toEqual([]);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
test('should have lastExecutedDate as 0', () => {
|
|
14
|
-
const state = new ActionStateBase();
|
|
15
|
-
|
|
16
|
-
expect(state.lastExecutedDate).toBe(0);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
describe('pinnedMessages', () => {
|
|
21
|
-
test('should allow adding message ids', () => {
|
|
22
|
-
const state = new ActionStateBase();
|
|
23
|
-
state.pinnedMessages.push(123, 456);
|
|
24
|
-
|
|
25
|
-
expect(state.pinnedMessages).toEqual([123, 456]);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test('should allow setting to new array', () => {
|
|
29
|
-
const state = new ActionStateBase();
|
|
30
|
-
state.pinnedMessages = [1, 2, 3];
|
|
31
|
-
|
|
32
|
-
expect(state.pinnedMessages).toEqual([1, 2, 3]);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test('should allow clearing', () => {
|
|
36
|
-
const state = new ActionStateBase();
|
|
37
|
-
state.pinnedMessages = [100, 200];
|
|
38
|
-
state.pinnedMessages = [];
|
|
39
|
-
|
|
40
|
-
expect(state.pinnedMessages).toEqual([]);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('lastExecutedDate', () => {
|
|
45
|
-
test('should allow setting timestamp', () => {
|
|
46
|
-
const state = new ActionStateBase();
|
|
47
|
-
const now = Date.now();
|
|
48
|
-
state.lastExecutedDate = now;
|
|
49
|
-
|
|
50
|
-
expect(state.lastExecutedDate).toBe(now);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test('should allow updating to new timestamp', () => {
|
|
54
|
-
const state = new ActionStateBase();
|
|
55
|
-
state.lastExecutedDate = 1000;
|
|
56
|
-
state.lastExecutedDate = 2000;
|
|
57
|
-
|
|
58
|
-
expect(state.lastExecutedDate).toBe(2000);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test('should handle epoch timestamp', () => {
|
|
62
|
-
const state = new ActionStateBase();
|
|
63
|
-
state.lastExecutedDate = 0;
|
|
64
|
-
|
|
65
|
-
expect(state.lastExecutedDate).toBe(0);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe('IActionState interface compliance', () => {
|
|
70
|
-
test('should implement IActionState interface', () => {
|
|
71
|
-
const state: IActionState = new ActionStateBase();
|
|
72
|
-
|
|
73
|
-
expect(state.pinnedMessages).toBeDefined();
|
|
74
|
-
expect(state.lastExecutedDate).toBeDefined();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test('should be assignable to IActionState', () => {
|
|
78
|
-
const state = new ActionStateBase();
|
|
79
|
-
const assignable: IActionState = state;
|
|
80
|
-
|
|
81
|
-
expect(assignable).toBe(state);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe('inheritance/extension', () => {
|
|
86
|
-
test('should be extensible for custom state', () => {
|
|
87
|
-
class CustomActionState extends ActionStateBase {
|
|
88
|
-
customProperty: string = 'default';
|
|
89
|
-
counter: number = 0;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const state = new CustomActionState();
|
|
93
|
-
state.customProperty = 'modified';
|
|
94
|
-
state.counter = 5;
|
|
95
|
-
state.pinnedMessages = [1, 2];
|
|
96
|
-
state.lastExecutedDate = Date.now();
|
|
97
|
-
|
|
98
|
-
expect(state.customProperty).toBe('modified');
|
|
99
|
-
expect(state.counter).toBe(5);
|
|
100
|
-
expect(state.pinnedMessages).toEqual([1, 2]);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
test('extended class should still implement IActionState', () => {
|
|
104
|
-
class ExtendedState extends ActionStateBase {
|
|
105
|
-
extra: boolean = true;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const state: IActionState = new ExtendedState();
|
|
109
|
-
|
|
110
|
-
expect(state.pinnedMessages).toEqual([]);
|
|
111
|
-
expect(state.lastExecutedDate).toBe(0);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
describe('isolation', () => {
|
|
116
|
-
test('should have separate pinnedMessages arrays per instance', () => {
|
|
117
|
-
const state1 = new ActionStateBase();
|
|
118
|
-
const state2 = new ActionStateBase();
|
|
119
|
-
|
|
120
|
-
state1.pinnedMessages.push(1);
|
|
121
|
-
state2.pinnedMessages.push(2);
|
|
122
|
-
|
|
123
|
-
expect(state1.pinnedMessages).toEqual([1]);
|
|
124
|
-
expect(state2.pinnedMessages).toEqual([2]);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
test('should have separate lastExecutedDate per instance', () => {
|
|
128
|
-
const state1 = new ActionStateBase();
|
|
129
|
-
const state2 = new ActionStateBase();
|
|
130
|
-
|
|
131
|
-
state1.lastExecutedDate = 1000;
|
|
132
|
-
state2.lastExecutedDate = 2000;
|
|
133
|
-
|
|
134
|
-
expect(state1.lastExecutedDate).toBe(1000);
|
|
135
|
-
expect(state2.lastExecutedDate).toBe(2000);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
});
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect } from 'bun:test';
|
|
2
|
-
import { TaskRecord } from '../../src/entities/taskRecord';
|
|
3
|
-
import { Milliseconds } from '../../src/types/timeValues';
|
|
4
|
-
import { TraceId } from '../../src/types/trace';
|
|
5
|
-
|
|
6
|
-
function createMockTimeoutId(): NodeJS.Timeout {
|
|
7
|
-
return setTimeout(() => {}, 0);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function createMockTraceId(): TraceId {
|
|
11
|
-
return 'test:trace-id' as TraceId;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe('TaskRecord', () => {
|
|
15
|
-
describe('constructor', () => {
|
|
16
|
-
test('should store name', () => {
|
|
17
|
-
const taskId = createMockTimeoutId();
|
|
18
|
-
const interval = 1000 as Milliseconds;
|
|
19
|
-
const traceId = createMockTraceId();
|
|
20
|
-
const record = new TaskRecord(
|
|
21
|
-
'test-task',
|
|
22
|
-
taskId,
|
|
23
|
-
interval,
|
|
24
|
-
traceId
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
expect(record.name).toBe('test-task');
|
|
28
|
-
clearTimeout(taskId);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('should store taskId', () => {
|
|
32
|
-
const taskId = createMockTimeoutId();
|
|
33
|
-
const interval = 1000 as Milliseconds;
|
|
34
|
-
const traceId = createMockTraceId();
|
|
35
|
-
const record = new TaskRecord(
|
|
36
|
-
'test-task',
|
|
37
|
-
taskId,
|
|
38
|
-
interval,
|
|
39
|
-
traceId
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
expect(record.taskId).toBe(taskId);
|
|
43
|
-
clearTimeout(taskId);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test('should store interval', () => {
|
|
47
|
-
const taskId = createMockTimeoutId();
|
|
48
|
-
const interval = 5000 as Milliseconds;
|
|
49
|
-
const traceId = createMockTraceId();
|
|
50
|
-
const record = new TaskRecord(
|
|
51
|
-
'test-task',
|
|
52
|
-
taskId,
|
|
53
|
-
interval,
|
|
54
|
-
traceId
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
expect(record.interval).toBe(interval);
|
|
58
|
-
clearTimeout(taskId);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test('should store traceId', () => {
|
|
62
|
-
const taskId = createMockTimeoutId();
|
|
63
|
-
const interval = 1000 as Milliseconds;
|
|
64
|
-
const traceId = createMockTraceId();
|
|
65
|
-
const record = new TaskRecord(
|
|
66
|
-
'test-task',
|
|
67
|
-
taskId,
|
|
68
|
-
interval,
|
|
69
|
-
traceId
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
expect(record.traceId).toBe(traceId);
|
|
73
|
-
clearTimeout(taskId);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
describe('properties', () => {
|
|
78
|
-
test('should have readonly name', () => {
|
|
79
|
-
const taskId = createMockTimeoutId();
|
|
80
|
-
const interval = 1000 as Milliseconds;
|
|
81
|
-
const traceId = createMockTraceId();
|
|
82
|
-
const record = new TaskRecord(
|
|
83
|
-
'readonly-task',
|
|
84
|
-
taskId,
|
|
85
|
-
interval,
|
|
86
|
-
traceId
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
expect(record.name).toBe('readonly-task');
|
|
90
|
-
clearTimeout(taskId);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test('should have readonly taskId', () => {
|
|
94
|
-
const taskId = createMockTimeoutId();
|
|
95
|
-
const interval = 1000 as Milliseconds;
|
|
96
|
-
const traceId = createMockTraceId();
|
|
97
|
-
const record = new TaskRecord(
|
|
98
|
-
'test-task',
|
|
99
|
-
taskId,
|
|
100
|
-
interval,
|
|
101
|
-
traceId
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
expect(record.taskId).toBe(taskId);
|
|
105
|
-
clearTimeout(taskId);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
test('should have readonly interval', () => {
|
|
109
|
-
const taskId = createMockTimeoutId();
|
|
110
|
-
const interval = 30000 as Milliseconds;
|
|
111
|
-
const traceId = createMockTraceId();
|
|
112
|
-
const record = new TaskRecord(
|
|
113
|
-
'test-task',
|
|
114
|
-
taskId,
|
|
115
|
-
interval,
|
|
116
|
-
traceId
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
expect(record.interval).toBe(interval);
|
|
120
|
-
clearTimeout(taskId);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test('should have readonly traceId', () => {
|
|
124
|
-
const taskId = createMockTimeoutId();
|
|
125
|
-
const interval = 1000 as Milliseconds;
|
|
126
|
-
const traceId = createMockTraceId();
|
|
127
|
-
const record = new TaskRecord(
|
|
128
|
-
'test-task',
|
|
129
|
-
taskId,
|
|
130
|
-
interval,
|
|
131
|
-
traceId
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
expect(record.traceId).toBe(traceId);
|
|
135
|
-
clearTimeout(taskId);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
test('should preserve Milliseconds type value', () => {
|
|
139
|
-
const taskId = createMockTimeoutId();
|
|
140
|
-
const interval = 60000 as Milliseconds;
|
|
141
|
-
const traceId = createMockTraceId();
|
|
142
|
-
const record = new TaskRecord(
|
|
143
|
-
'test-task',
|
|
144
|
-
taskId,
|
|
145
|
-
interval,
|
|
146
|
-
traceId
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
expect(record.interval).toBe(interval);
|
|
150
|
-
clearTimeout(taskId);
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
describe('edge cases', () => {
|
|
155
|
-
test('should handle empty name', () => {
|
|
156
|
-
const taskId = createMockTimeoutId();
|
|
157
|
-
const interval = 1000 as Milliseconds;
|
|
158
|
-
const traceId = createMockTraceId();
|
|
159
|
-
const record = new TaskRecord('', taskId, interval, traceId);
|
|
160
|
-
|
|
161
|
-
expect(record.name).toBe('');
|
|
162
|
-
clearTimeout(taskId);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
test('should handle zero interval', () => {
|
|
166
|
-
const taskId = createMockTimeoutId();
|
|
167
|
-
const interval = 0 as Milliseconds;
|
|
168
|
-
const traceId = createMockTraceId();
|
|
169
|
-
const record = new TaskRecord(
|
|
170
|
-
'test-task',
|
|
171
|
-
taskId,
|
|
172
|
-
interval,
|
|
173
|
-
traceId
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
expect(record.interval).toBe(interval);
|
|
177
|
-
clearTimeout(taskId);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
test('should handle very large interval', () => {
|
|
181
|
-
const taskId = createMockTimeoutId();
|
|
182
|
-
const largeInterval = 86400000 as Milliseconds; // 24 hours
|
|
183
|
-
const traceId = createMockTraceId();
|
|
184
|
-
const record = new TaskRecord(
|
|
185
|
-
'test-task',
|
|
186
|
-
taskId,
|
|
187
|
-
largeInterval,
|
|
188
|
-
traceId
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
expect(record.interval).toBe(largeInterval);
|
|
192
|
-
clearTimeout(taskId);
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
});
|