@auxiora/channels 1.0.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.
- package/LICENSE +191 -0
- package/dist/adapters/bluebubbles.d.ts +63 -0
- package/dist/adapters/bluebubbles.d.ts.map +1 -0
- package/dist/adapters/bluebubbles.js +197 -0
- package/dist/adapters/bluebubbles.js.map +1 -0
- package/dist/adapters/discord.d.ts +27 -0
- package/dist/adapters/discord.d.ts.map +1 -0
- package/dist/adapters/discord.js +202 -0
- package/dist/adapters/discord.js.map +1 -0
- package/dist/adapters/email.d.ts +39 -0
- package/dist/adapters/email.d.ts.map +1 -0
- package/dist/adapters/email.js +359 -0
- package/dist/adapters/email.js.map +1 -0
- package/dist/adapters/googlechat.d.ts +77 -0
- package/dist/adapters/googlechat.d.ts.map +1 -0
- package/dist/adapters/googlechat.js +232 -0
- package/dist/adapters/googlechat.js.map +1 -0
- package/dist/adapters/matrix.d.ts +37 -0
- package/dist/adapters/matrix.d.ts.map +1 -0
- package/dist/adapters/matrix.js +262 -0
- package/dist/adapters/matrix.js.map +1 -0
- package/dist/adapters/signal.d.ts +32 -0
- package/dist/adapters/signal.d.ts.map +1 -0
- package/dist/adapters/signal.js +216 -0
- package/dist/adapters/signal.js.map +1 -0
- package/dist/adapters/slack.d.ts +29 -0
- package/dist/adapters/slack.d.ts.map +1 -0
- package/dist/adapters/slack.js +202 -0
- package/dist/adapters/slack.js.map +1 -0
- package/dist/adapters/teams.d.ts +66 -0
- package/dist/adapters/teams.d.ts.map +1 -0
- package/dist/adapters/teams.js +227 -0
- package/dist/adapters/teams.js.map +1 -0
- package/dist/adapters/telegram.d.ts +28 -0
- package/dist/adapters/telegram.d.ts.map +1 -0
- package/dist/adapters/telegram.js +170 -0
- package/dist/adapters/telegram.js.map +1 -0
- package/dist/adapters/twilio.d.ts +63 -0
- package/dist/adapters/twilio.d.ts.map +1 -0
- package/dist/adapters/twilio.js +193 -0
- package/dist/adapters/twilio.js.map +1 -0
- package/dist/adapters/whatsapp.d.ts +99 -0
- package/dist/adapters/whatsapp.d.ts.map +1 -0
- package/dist/adapters/whatsapp.js +218 -0
- package/dist/adapters/whatsapp.js.map +1 -0
- package/dist/adapters/zalo.d.ts +64 -0
- package/dist/adapters/zalo.d.ts.map +1 -0
- package/dist/adapters/zalo.js +216 -0
- package/dist/adapters/zalo.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/manager.d.ts +35 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +127 -0
- package/dist/manager.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +32 -0
- package/src/adapters/bluebubbles.ts +294 -0
- package/src/adapters/discord.ts +253 -0
- package/src/adapters/email.ts +457 -0
- package/src/adapters/googlechat.ts +364 -0
- package/src/adapters/matrix.ts +376 -0
- package/src/adapters/signal.ts +313 -0
- package/src/adapters/slack.ts +252 -0
- package/src/adapters/teams.ts +320 -0
- package/src/adapters/telegram.ts +208 -0
- package/src/adapters/twilio.ts +256 -0
- package/src/adapters/whatsapp.ts +342 -0
- package/src/adapters/zalo.ts +319 -0
- package/src/index.ts +78 -0
- package/src/manager.ts +180 -0
- package/src/types.ts +84 -0
- package/tests/bluebubbles.test.ts +438 -0
- package/tests/email.test.ts +136 -0
- package/tests/googlechat.test.ts +439 -0
- package/tests/matrix.test.ts +564 -0
- package/tests/signal.test.ts +404 -0
- package/tests/slack.test.ts +343 -0
- package/tests/teams.test.ts +429 -0
- package/tests/twilio.test.ts +269 -0
- package/tests/whatsapp.test.ts +530 -0
- package/tests/zalo.test.ts +499 -0
- package/tsconfig.json +8 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { SignalAdapter } from '../src/adapters/signal.js';
|
|
3
|
+
|
|
4
|
+
// Mock audit
|
|
5
|
+
vi.mock('@auxiora/audit', () => ({
|
|
6
|
+
audit: vi.fn(),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
describe('SignalAdapter', () => {
|
|
10
|
+
let adapter: SignalAdapter;
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
adapter = new SignalAdapter({
|
|
14
|
+
signalCliEndpoint: 'http://localhost:7583',
|
|
15
|
+
phoneNumber: '+1234567890',
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
vi.restoreAllMocks();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should have correct metadata', () => {
|
|
24
|
+
expect(adapter.type).toBe('signal');
|
|
25
|
+
expect(adapter.name).toBe('Signal');
|
|
26
|
+
expect(adapter.isConnected()).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should connect successfully', async () => {
|
|
30
|
+
vi.spyOn(globalThis, 'fetch')
|
|
31
|
+
.mockResolvedValueOnce({
|
|
32
|
+
ok: true,
|
|
33
|
+
json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }),
|
|
34
|
+
} as Response)
|
|
35
|
+
.mockImplementation(() => new Promise(() => {})); // Hang on poll
|
|
36
|
+
|
|
37
|
+
await adapter.connect();
|
|
38
|
+
expect(adapter.isConnected()).toBe(true);
|
|
39
|
+
|
|
40
|
+
await adapter.disconnect();
|
|
41
|
+
expect(adapter.isConnected()).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should fail to connect on API error', async () => {
|
|
45
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce({
|
|
46
|
+
ok: false,
|
|
47
|
+
status: 500,
|
|
48
|
+
statusText: 'Internal Server Error',
|
|
49
|
+
} as Response);
|
|
50
|
+
|
|
51
|
+
await expect(adapter.connect()).rejects.toThrow('Signal CLI API error 500');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should fail to connect on RPC error', async () => {
|
|
55
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce({
|
|
56
|
+
ok: true,
|
|
57
|
+
json: async () => ({
|
|
58
|
+
jsonrpc: '2.0',
|
|
59
|
+
id: 1,
|
|
60
|
+
error: { code: -1, message: 'Account not found' },
|
|
61
|
+
}),
|
|
62
|
+
} as Response);
|
|
63
|
+
|
|
64
|
+
await expect(adapter.connect()).rejects.toThrow('Account not found');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should send a direct message', async () => {
|
|
68
|
+
// Connect
|
|
69
|
+
vi.spyOn(globalThis, 'fetch')
|
|
70
|
+
.mockResolvedValueOnce({
|
|
71
|
+
ok: true,
|
|
72
|
+
json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }),
|
|
73
|
+
} as Response)
|
|
74
|
+
.mockImplementation(() => new Promise(() => {}));
|
|
75
|
+
|
|
76
|
+
await adapter.connect();
|
|
77
|
+
|
|
78
|
+
// Send
|
|
79
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce({
|
|
80
|
+
ok: true,
|
|
81
|
+
json: async () => ({
|
|
82
|
+
jsonrpc: '2.0',
|
|
83
|
+
id: 3,
|
|
84
|
+
result: { timestamp: 1700000000000 },
|
|
85
|
+
}),
|
|
86
|
+
} as Response);
|
|
87
|
+
|
|
88
|
+
const result = await adapter.send('+0987654321', {
|
|
89
|
+
content: 'Hello from Signal!',
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
expect(result.success).toBe(true);
|
|
93
|
+
expect(result.messageId).toBe('1700000000000');
|
|
94
|
+
|
|
95
|
+
await adapter.disconnect();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should send a group message', async () => {
|
|
99
|
+
// Connect
|
|
100
|
+
vi.spyOn(globalThis, 'fetch')
|
|
101
|
+
.mockResolvedValueOnce({
|
|
102
|
+
ok: true,
|
|
103
|
+
json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }),
|
|
104
|
+
} as Response)
|
|
105
|
+
.mockImplementation(() => new Promise(() => {}));
|
|
106
|
+
|
|
107
|
+
await adapter.connect();
|
|
108
|
+
|
|
109
|
+
// Send to group (non-+ prefix = group ID)
|
|
110
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce({
|
|
111
|
+
ok: true,
|
|
112
|
+
json: async () => ({
|
|
113
|
+
jsonrpc: '2.0',
|
|
114
|
+
id: 3,
|
|
115
|
+
result: { timestamp: 1700000000001 },
|
|
116
|
+
}),
|
|
117
|
+
} as Response);
|
|
118
|
+
|
|
119
|
+
const result = await adapter.send('group-abc123', {
|
|
120
|
+
content: 'Hello group!',
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
expect(result.success).toBe(true);
|
|
124
|
+
|
|
125
|
+
// Verify the group param was used
|
|
126
|
+
const lastCall = vi.mocked(globalThis.fetch).mock.calls.at(-1);
|
|
127
|
+
const body = JSON.parse(lastCall![1]?.body as string);
|
|
128
|
+
expect(body.params.groupId).toBe('group-abc123');
|
|
129
|
+
expect(body.params.recipient).toBeUndefined();
|
|
130
|
+
|
|
131
|
+
await adapter.disconnect();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should handle send errors', async () => {
|
|
135
|
+
// Connect
|
|
136
|
+
vi.spyOn(globalThis, 'fetch')
|
|
137
|
+
.mockResolvedValueOnce({
|
|
138
|
+
ok: true,
|
|
139
|
+
json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }),
|
|
140
|
+
} as Response)
|
|
141
|
+
.mockImplementation(() => new Promise(() => {}));
|
|
142
|
+
|
|
143
|
+
await adapter.connect();
|
|
144
|
+
|
|
145
|
+
// Fail send
|
|
146
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValueOnce({
|
|
147
|
+
ok: true,
|
|
148
|
+
json: async () => ({
|
|
149
|
+
jsonrpc: '2.0',
|
|
150
|
+
id: 3,
|
|
151
|
+
error: { code: -1, message: 'Recipient not found' },
|
|
152
|
+
}),
|
|
153
|
+
} as Response);
|
|
154
|
+
|
|
155
|
+
const result = await adapter.send('+0987654321', {
|
|
156
|
+
content: 'Should fail',
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
expect(result.success).toBe(false);
|
|
160
|
+
expect(result.error).toContain('Recipient not found');
|
|
161
|
+
|
|
162
|
+
await adapter.disconnect();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should receive messages from poll', async () => {
|
|
166
|
+
const receivedMessages: unknown[] = [];
|
|
167
|
+
adapter.onMessage(async (msg) => {
|
|
168
|
+
receivedMessages.push(msg);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const pollResponse = [
|
|
172
|
+
{
|
|
173
|
+
envelope: {
|
|
174
|
+
source: '+0987654321',
|
|
175
|
+
sourceName: 'Alice',
|
|
176
|
+
sourceNumber: '+0987654321',
|
|
177
|
+
timestamp: 1700000000000,
|
|
178
|
+
dataMessage: {
|
|
179
|
+
message: 'Hello!',
|
|
180
|
+
timestamp: 1700000000000,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
vi.spyOn(globalThis, 'fetch')
|
|
187
|
+
.mockResolvedValueOnce({
|
|
188
|
+
ok: true,
|
|
189
|
+
json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }),
|
|
190
|
+
} as Response)
|
|
191
|
+
.mockResolvedValueOnce({
|
|
192
|
+
ok: true,
|
|
193
|
+
json: async () => ({ jsonrpc: '2.0', id: 2, result: pollResponse }),
|
|
194
|
+
} as Response)
|
|
195
|
+
.mockImplementation(() => new Promise(() => {}));
|
|
196
|
+
|
|
197
|
+
await adapter.connect();
|
|
198
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
199
|
+
|
|
200
|
+
expect(receivedMessages).toHaveLength(1);
|
|
201
|
+
const msg = receivedMessages[0] as { content: string; senderId: string };
|
|
202
|
+
expect(msg.content).toBe('Hello!');
|
|
203
|
+
expect(msg.senderId).toBe('+0987654321');
|
|
204
|
+
|
|
205
|
+
await adapter.disconnect();
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should ignore own messages', async () => {
|
|
209
|
+
const receivedMessages: unknown[] = [];
|
|
210
|
+
adapter.onMessage(async (msg) => {
|
|
211
|
+
receivedMessages.push(msg);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const pollResponse = [
|
|
215
|
+
{
|
|
216
|
+
envelope: {
|
|
217
|
+
source: '+1234567890',
|
|
218
|
+
sourceNumber: '+1234567890', // Own number
|
|
219
|
+
timestamp: 1700000000000,
|
|
220
|
+
dataMessage: {
|
|
221
|
+
message: 'My own message',
|
|
222
|
+
timestamp: 1700000000000,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
vi.spyOn(globalThis, 'fetch')
|
|
229
|
+
.mockResolvedValueOnce({
|
|
230
|
+
ok: true,
|
|
231
|
+
json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }),
|
|
232
|
+
} as Response)
|
|
233
|
+
.mockResolvedValueOnce({
|
|
234
|
+
ok: true,
|
|
235
|
+
json: async () => ({ jsonrpc: '2.0', id: 2, result: pollResponse }),
|
|
236
|
+
} as Response)
|
|
237
|
+
.mockImplementation(() => new Promise(() => {}));
|
|
238
|
+
|
|
239
|
+
await adapter.connect();
|
|
240
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
241
|
+
|
|
242
|
+
expect(receivedMessages).toHaveLength(0);
|
|
243
|
+
|
|
244
|
+
await adapter.disconnect();
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('should handle group messages', async () => {
|
|
248
|
+
const receivedMessages: unknown[] = [];
|
|
249
|
+
adapter.onMessage(async (msg) => {
|
|
250
|
+
receivedMessages.push(msg);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
const pollResponse = [
|
|
254
|
+
{
|
|
255
|
+
envelope: {
|
|
256
|
+
source: '+0987654321',
|
|
257
|
+
sourceName: 'Bob',
|
|
258
|
+
sourceNumber: '+0987654321',
|
|
259
|
+
timestamp: 1700000000000,
|
|
260
|
+
dataMessage: {
|
|
261
|
+
message: 'Hello group!',
|
|
262
|
+
timestamp: 1700000000000,
|
|
263
|
+
groupInfo: {
|
|
264
|
+
groupId: 'group-xyz',
|
|
265
|
+
type: 'DELIVER',
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
];
|
|
271
|
+
|
|
272
|
+
vi.spyOn(globalThis, 'fetch')
|
|
273
|
+
.mockResolvedValueOnce({
|
|
274
|
+
ok: true,
|
|
275
|
+
json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }),
|
|
276
|
+
} as Response)
|
|
277
|
+
.mockResolvedValueOnce({
|
|
278
|
+
ok: true,
|
|
279
|
+
json: async () => ({ jsonrpc: '2.0', id: 2, result: pollResponse }),
|
|
280
|
+
} as Response)
|
|
281
|
+
.mockImplementation(() => new Promise(() => {}));
|
|
282
|
+
|
|
283
|
+
await adapter.connect();
|
|
284
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
285
|
+
|
|
286
|
+
expect(receivedMessages).toHaveLength(1);
|
|
287
|
+
const msg = receivedMessages[0] as { channelId: string };
|
|
288
|
+
expect(msg.channelId).toBe('group-xyz');
|
|
289
|
+
|
|
290
|
+
await adapter.disconnect();
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('should register error handler', () => {
|
|
294
|
+
const handler = vi.fn();
|
|
295
|
+
adapter.onError(handler);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
describe('sender filtering', () => {
|
|
299
|
+
it('should allow all messages when allowedNumbers is not set', async () => {
|
|
300
|
+
const receivedMessages: unknown[] = [];
|
|
301
|
+
adapter.onMessage(async (msg) => {
|
|
302
|
+
receivedMessages.push(msg);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const pollResponse = [
|
|
306
|
+
{
|
|
307
|
+
envelope: {
|
|
308
|
+
source: '+0987654321',
|
|
309
|
+
sourceName: 'Alice',
|
|
310
|
+
sourceNumber: '+0987654321',
|
|
311
|
+
timestamp: 1700000000000,
|
|
312
|
+
dataMessage: { message: 'Hello!', timestamp: 1700000000000 },
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
];
|
|
316
|
+
|
|
317
|
+
vi.spyOn(globalThis, 'fetch')
|
|
318
|
+
.mockResolvedValueOnce({ ok: true, json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }) } as Response)
|
|
319
|
+
.mockResolvedValueOnce({ ok: true, json: async () => ({ jsonrpc: '2.0', id: 2, result: pollResponse }) } as Response)
|
|
320
|
+
.mockImplementation(() => new Promise(() => {}));
|
|
321
|
+
|
|
322
|
+
await adapter.connect();
|
|
323
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
324
|
+
expect(receivedMessages).toHaveLength(1);
|
|
325
|
+
await adapter.disconnect();
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('should allow messages from allowed numbers', async () => {
|
|
329
|
+
const filteredAdapter = new SignalAdapter({
|
|
330
|
+
signalCliEndpoint: 'http://localhost:7583',
|
|
331
|
+
phoneNumber: '+1234567890',
|
|
332
|
+
allowedNumbers: ['+0987654321'],
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const receivedMessages: unknown[] = [];
|
|
336
|
+
filteredAdapter.onMessage(async (msg) => {
|
|
337
|
+
receivedMessages.push(msg);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
const pollResponse = [
|
|
341
|
+
{
|
|
342
|
+
envelope: {
|
|
343
|
+
source: '+0987654321',
|
|
344
|
+
sourceName: 'Alice',
|
|
345
|
+
sourceNumber: '+0987654321',
|
|
346
|
+
timestamp: 1700000000000,
|
|
347
|
+
dataMessage: { message: 'Allowed!', timestamp: 1700000000000 },
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
];
|
|
351
|
+
|
|
352
|
+
vi.spyOn(globalThis, 'fetch')
|
|
353
|
+
.mockResolvedValueOnce({ ok: true, json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }) } as Response)
|
|
354
|
+
.mockResolvedValueOnce({ ok: true, json: async () => ({ jsonrpc: '2.0', id: 2, result: pollResponse }) } as Response)
|
|
355
|
+
.mockImplementation(() => new Promise(() => {}));
|
|
356
|
+
|
|
357
|
+
await filteredAdapter.connect();
|
|
358
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
359
|
+
expect(receivedMessages).toHaveLength(1);
|
|
360
|
+
await filteredAdapter.disconnect();
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it('should block messages from non-allowed numbers', async () => {
|
|
364
|
+
const { audit } = await import('@auxiora/audit');
|
|
365
|
+
const filteredAdapter = new SignalAdapter({
|
|
366
|
+
signalCliEndpoint: 'http://localhost:7583',
|
|
367
|
+
phoneNumber: '+1234567890',
|
|
368
|
+
allowedNumbers: ['+0987654321'],
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
const receivedMessages: unknown[] = [];
|
|
372
|
+
filteredAdapter.onMessage(async (msg) => {
|
|
373
|
+
receivedMessages.push(msg);
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
const pollResponse = [
|
|
377
|
+
{
|
|
378
|
+
envelope: {
|
|
379
|
+
source: '+5555555555',
|
|
380
|
+
sourceName: 'Eve',
|
|
381
|
+
sourceNumber: '+5555555555',
|
|
382
|
+
timestamp: 1700000000000,
|
|
383
|
+
dataMessage: { message: 'Blocked!', timestamp: 1700000000000 },
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
];
|
|
387
|
+
|
|
388
|
+
vi.spyOn(globalThis, 'fetch')
|
|
389
|
+
.mockResolvedValueOnce({ ok: true, json: async () => ({ jsonrpc: '2.0', id: 1, result: [] }) } as Response)
|
|
390
|
+
.mockResolvedValueOnce({ ok: true, json: async () => ({ jsonrpc: '2.0', id: 2, result: pollResponse }) } as Response)
|
|
391
|
+
.mockImplementation(() => new Promise(() => {}));
|
|
392
|
+
|
|
393
|
+
await filteredAdapter.connect();
|
|
394
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
395
|
+
expect(receivedMessages).toHaveLength(0);
|
|
396
|
+
expect(audit).toHaveBeenCalledWith('message.filtered', expect.objectContaining({
|
|
397
|
+
channelType: 'signal',
|
|
398
|
+
senderId: '+5555555555',
|
|
399
|
+
reason: 'number_not_allowed',
|
|
400
|
+
}));
|
|
401
|
+
await filteredAdapter.disconnect();
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
});
|