signal-sdk 0.1.2 → 0.1.3
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/README.md +18 -8
- package/dist/MultiAccountManager.js +11 -19
- package/dist/SignalBot.js +40 -36
- package/dist/SignalCli.d.ts +23 -319
- package/dist/SignalCli.js +224 -998
- package/dist/__tests__/DeviceManager.test.d.ts +1 -0
- package/dist/__tests__/DeviceManager.test.js +135 -0
- package/dist/__tests__/MultiAccountManager.coverage.test.d.ts +1 -0
- package/dist/__tests__/MultiAccountManager.coverage.test.js +33 -0
- package/dist/__tests__/MultiAccountManager.test.js +3 -3
- package/dist/__tests__/SignalBot.additional.test.js +40 -37
- package/dist/__tests__/SignalBot.coverage.test.d.ts +1 -0
- package/dist/__tests__/SignalBot.coverage.test.js +385 -0
- package/dist/__tests__/SignalBot.test.js +8 -8
- package/dist/__tests__/SignalCli.advanced.test.js +47 -58
- package/dist/__tests__/SignalCli.connections.test.d.ts +1 -0
- package/dist/__tests__/SignalCli.connections.test.js +110 -0
- package/dist/__tests__/SignalCli.e2e.test.js +28 -32
- package/dist/__tests__/SignalCli.events.test.d.ts +1 -0
- package/dist/__tests__/SignalCli.events.test.js +113 -0
- package/dist/__tests__/SignalCli.integration.test.js +6 -5
- package/dist/__tests__/SignalCli.methods.test.js +77 -77
- package/dist/__tests__/SignalCli.parsing.test.js +4 -13
- package/dist/__tests__/SignalCli.simple.test.d.ts +1 -0
- package/dist/__tests__/SignalCli.simple.test.js +77 -0
- package/dist/__tests__/SignalCli.test.js +96 -82
- package/dist/__tests__/config.test.js +19 -29
- package/dist/__tests__/errors.test.js +2 -2
- package/dist/__tests__/retry.test.js +10 -8
- package/dist/__tests__/robustness.test.d.ts +1 -0
- package/dist/__tests__/robustness.test.js +59 -0
- package/dist/__tests__/security.test.d.ts +1 -0
- package/dist/__tests__/security.test.js +50 -0
- package/dist/config.js +3 -3
- package/dist/interfaces.d.ts +18 -0
- package/dist/managers/AccountManager.d.ts +27 -0
- package/dist/managers/AccountManager.js +147 -0
- package/dist/managers/BaseManager.d.ts +9 -0
- package/dist/managers/BaseManager.js +17 -0
- package/dist/managers/ContactManager.d.ts +15 -0
- package/dist/managers/ContactManager.js +123 -0
- package/dist/managers/DeviceManager.d.ts +11 -0
- package/dist/managers/DeviceManager.js +139 -0
- package/dist/managers/GroupManager.d.ts +12 -0
- package/dist/managers/GroupManager.js +78 -0
- package/dist/managers/MessageManager.d.ts +18 -0
- package/dist/managers/MessageManager.js +301 -0
- package/dist/managers/StickerManager.d.ts +8 -0
- package/dist/managers/StickerManager.js +39 -0
- package/dist/retry.js +3 -3
- package/dist/validators.d.ts +9 -0
- package/dist/validators.js +20 -0
- package/package.json +11 -4
|
@@ -10,7 +10,8 @@ describe('SignalCli Advanced Features', () => {
|
|
|
10
10
|
let sendJsonRpcRequestSpy;
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
signalCli = new SignalCli_1.SignalCli('+1234567890');
|
|
13
|
-
sendJsonRpcRequestSpy = jest
|
|
13
|
+
sendJsonRpcRequestSpy = jest
|
|
14
|
+
.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
14
15
|
.mockResolvedValue({ timestamp: Date.now(), results: [] });
|
|
15
16
|
});
|
|
16
17
|
afterEach(() => {
|
|
@@ -19,37 +20,29 @@ describe('SignalCli Advanced Features', () => {
|
|
|
19
20
|
describe('Advanced sendMessage Options', () => {
|
|
20
21
|
it('should send message with text styles', async () => {
|
|
21
22
|
await signalCli.sendMessage('+33123456789', 'Hello *bold* text', {
|
|
22
|
-
textStyles: [
|
|
23
|
-
{ start: 6, length: 6, style: 'BOLD' }
|
|
24
|
-
]
|
|
23
|
+
textStyles: [{ start: 6, length: 6, style: 'BOLD' }],
|
|
25
24
|
});
|
|
26
25
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('send', expect.objectContaining({
|
|
27
26
|
message: 'Hello *bold* text',
|
|
28
|
-
textStyles: [
|
|
29
|
-
{ start: 6, length: 6, style: 'BOLD' }
|
|
30
|
-
]
|
|
27
|
+
textStyles: [{ start: 6, length: 6, style: 'BOLD' }],
|
|
31
28
|
}));
|
|
32
29
|
});
|
|
33
30
|
it('should send message with mentions', async () => {
|
|
34
31
|
await signalCli.sendMessage('+33123456789', 'Hello @John', {
|
|
35
|
-
mentions: [
|
|
36
|
-
{ start: 6, length: 5, number: '+33111111111' }
|
|
37
|
-
]
|
|
32
|
+
mentions: [{ start: 6, length: 5, number: '+33111111111' }],
|
|
38
33
|
});
|
|
39
34
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('send', expect.objectContaining({
|
|
40
35
|
message: 'Hello @John',
|
|
41
|
-
mentions: [
|
|
42
|
-
{ start: 6, length: 5, number: '+33111111111' }
|
|
43
|
-
]
|
|
36
|
+
mentions: [{ start: 6, length: 5, number: '+33111111111' }],
|
|
44
37
|
}));
|
|
45
38
|
});
|
|
46
39
|
it('should send message with preview URL', async () => {
|
|
47
40
|
await signalCli.sendMessage('+33123456789', 'Check this out', {
|
|
48
|
-
previewUrl: 'https://example.com'
|
|
41
|
+
previewUrl: 'https://example.com',
|
|
49
42
|
});
|
|
50
43
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('send', expect.objectContaining({
|
|
51
44
|
message: 'Check this out',
|
|
52
|
-
previewUrl: 'https://example.com'
|
|
45
|
+
previewUrl: 'https://example.com',
|
|
53
46
|
}));
|
|
54
47
|
});
|
|
55
48
|
it('should send message with quote and advanced fields', async () => {
|
|
@@ -59,8 +52,8 @@ describe('SignalCli Advanced Features', () => {
|
|
|
59
52
|
author: '+33111111111',
|
|
60
53
|
text: 'Original message',
|
|
61
54
|
mentions: [{ start: 0, length: 5, number: '+33222222222' }],
|
|
62
|
-
textStyles: [{ start: 0, length: 8, style: 'BOLD' }]
|
|
63
|
-
}
|
|
55
|
+
textStyles: [{ start: 0, length: 8, style: 'BOLD' }],
|
|
56
|
+
},
|
|
64
57
|
});
|
|
65
58
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('send', expect.objectContaining({
|
|
66
59
|
message: 'I agree!',
|
|
@@ -68,45 +61,45 @@ describe('SignalCli Advanced Features', () => {
|
|
|
68
61
|
quoteAuthor: '+33111111111',
|
|
69
62
|
quoteMessage: 'Original message',
|
|
70
63
|
quoteMentions: [{ start: 0, length: 5, number: '+33222222222' }],
|
|
71
|
-
quoteTextStyles: [{ start: 0, length: 8, style: 'BOLD' }]
|
|
64
|
+
quoteTextStyles: [{ start: 0, length: 8, style: 'BOLD' }],
|
|
72
65
|
}));
|
|
73
66
|
});
|
|
74
67
|
it('should send message edit', async () => {
|
|
75
68
|
await signalCli.sendMessage('+33123456789', 'Corrected text', {
|
|
76
|
-
editTimestamp: 123456789
|
|
69
|
+
editTimestamp: 123456789,
|
|
77
70
|
});
|
|
78
71
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('send', expect.objectContaining({
|
|
79
72
|
message: 'Corrected text',
|
|
80
|
-
editTimestamp: 123456789
|
|
73
|
+
editTimestamp: 123456789,
|
|
81
74
|
}));
|
|
82
75
|
});
|
|
83
76
|
it('should send reply to story', async () => {
|
|
84
77
|
await signalCli.sendMessage('+33123456789', 'Nice story!', {
|
|
85
78
|
storyTimestamp: 123456789,
|
|
86
|
-
storyAuthor: '+33111111111'
|
|
79
|
+
storyAuthor: '+33111111111',
|
|
87
80
|
});
|
|
88
81
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('send', expect.objectContaining({
|
|
89
82
|
message: 'Nice story!',
|
|
90
83
|
storyTimestamp: 123456789,
|
|
91
|
-
storyAuthor: '+33111111111'
|
|
84
|
+
storyAuthor: '+33111111111',
|
|
92
85
|
}));
|
|
93
86
|
});
|
|
94
87
|
it('should send message with noteToSelf flag', async () => {
|
|
95
88
|
await signalCli.sendMessage('+1234567890', 'Note to myself', {
|
|
96
|
-
noteToSelf: true
|
|
89
|
+
noteToSelf: true,
|
|
97
90
|
});
|
|
98
91
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('send', expect.objectContaining({
|
|
99
92
|
message: 'Note to myself',
|
|
100
|
-
noteToSelf: true
|
|
93
|
+
noteToSelf: true,
|
|
101
94
|
}));
|
|
102
95
|
});
|
|
103
96
|
it('should send message with endSession flag', async () => {
|
|
104
97
|
await signalCli.sendMessage('+33123456789', 'Goodbye', {
|
|
105
|
-
endSession: true
|
|
98
|
+
endSession: true,
|
|
106
99
|
});
|
|
107
100
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('send', expect.objectContaining({
|
|
108
101
|
message: 'Goodbye',
|
|
109
|
-
endSession: true
|
|
102
|
+
endSession: true,
|
|
110
103
|
}));
|
|
111
104
|
});
|
|
112
105
|
});
|
|
@@ -116,12 +109,12 @@ describe('SignalCli Advanced Features', () => {
|
|
|
116
109
|
{
|
|
117
110
|
timestamp: 123456789,
|
|
118
111
|
source: '+33123456789',
|
|
119
|
-
dataMessage: { message: 'Hello!' }
|
|
120
|
-
}
|
|
112
|
+
dataMessage: { message: 'Hello!' },
|
|
113
|
+
},
|
|
121
114
|
]);
|
|
122
115
|
const messages = await signalCli.receive();
|
|
123
116
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('receive', expect.objectContaining({
|
|
124
|
-
account: '+1234567890'
|
|
117
|
+
account: '+1234567890',
|
|
125
118
|
}));
|
|
126
119
|
expect(messages).toHaveLength(1);
|
|
127
120
|
expect(messages[0].text).toBe('Hello!');
|
|
@@ -130,32 +123,32 @@ describe('SignalCli Advanced Features', () => {
|
|
|
130
123
|
sendJsonRpcRequestSpy.mockResolvedValue([]);
|
|
131
124
|
await signalCli.receive({ timeout: 10 });
|
|
132
125
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('receive', expect.objectContaining({
|
|
133
|
-
timeout: 10
|
|
126
|
+
timeout: 10,
|
|
134
127
|
}));
|
|
135
128
|
});
|
|
136
129
|
it('should receive messages with maxMessages limit', async () => {
|
|
137
130
|
sendJsonRpcRequestSpy.mockResolvedValue([]);
|
|
138
131
|
await signalCli.receive({ maxMessages: 5 });
|
|
139
132
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('receive', expect.objectContaining({
|
|
140
|
-
maxMessages: 5
|
|
133
|
+
maxMessages: 5,
|
|
141
134
|
}));
|
|
142
135
|
});
|
|
143
136
|
it('should receive messages with ignoreAttachments', async () => {
|
|
144
137
|
await signalCli.receive({ ignoreAttachments: true });
|
|
145
138
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('receive', expect.objectContaining({
|
|
146
|
-
ignoreAttachments: true
|
|
139
|
+
ignoreAttachments: true,
|
|
147
140
|
}));
|
|
148
141
|
});
|
|
149
142
|
it('should receive messages with ignoreStories', async () => {
|
|
150
143
|
await signalCli.receive({ ignoreStories: true });
|
|
151
144
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('receive', expect.objectContaining({
|
|
152
|
-
ignoreStories: true
|
|
145
|
+
ignoreStories: true,
|
|
153
146
|
}));
|
|
154
147
|
});
|
|
155
148
|
it('should receive messages with sendReadReceipts', async () => {
|
|
156
149
|
await signalCli.receive({ sendReadReceipts: true });
|
|
157
150
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('receive', expect.objectContaining({
|
|
158
|
-
sendReadReceipts: true
|
|
151
|
+
sendReadReceipts: true,
|
|
159
152
|
}));
|
|
160
153
|
});
|
|
161
154
|
it('should handle empty message array', async () => {
|
|
@@ -168,11 +161,11 @@ describe('SignalCli Advanced Features', () => {
|
|
|
168
161
|
it('should set username', async () => {
|
|
169
162
|
sendJsonRpcRequestSpy.mockResolvedValue({
|
|
170
163
|
username: 'myuser.123',
|
|
171
|
-
usernameLink: 'https://signal.me/#myuser.123'
|
|
164
|
+
usernameLink: 'https://signal.me/#myuser.123',
|
|
172
165
|
});
|
|
173
166
|
const result = await signalCli.setUsername('myuser');
|
|
174
167
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateAccount', expect.objectContaining({
|
|
175
|
-
username: 'myuser'
|
|
168
|
+
username: 'myuser',
|
|
176
169
|
}));
|
|
177
170
|
expect(result.success).toBe(true);
|
|
178
171
|
expect(result.username).toBe('myuser.123');
|
|
@@ -181,7 +174,7 @@ describe('SignalCli Advanced Features', () => {
|
|
|
181
174
|
sendJsonRpcRequestSpy.mockResolvedValue({});
|
|
182
175
|
const result = await signalCli.deleteUsername();
|
|
183
176
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateAccount', expect.objectContaining({
|
|
184
|
-
deleteUsername: true
|
|
177
|
+
deleteUsername: true,
|
|
185
178
|
}));
|
|
186
179
|
expect(result.success).toBe(true);
|
|
187
180
|
});
|
|
@@ -192,12 +185,12 @@ describe('SignalCli Advanced Features', () => {
|
|
|
192
185
|
{
|
|
193
186
|
number: '+33123456789',
|
|
194
187
|
safetyNumber: '12345 67890 12345 67890 12345 67890',
|
|
195
|
-
trustLevel: 'TRUSTED'
|
|
196
|
-
}
|
|
188
|
+
trustLevel: 'TRUSTED',
|
|
189
|
+
},
|
|
197
190
|
]);
|
|
198
191
|
const safetyNumber = await signalCli.getSafetyNumber('+33123456789');
|
|
199
192
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('listIdentities', expect.objectContaining({
|
|
200
|
-
number: '+33123456789'
|
|
193
|
+
number: '+33123456789',
|
|
201
194
|
}));
|
|
202
195
|
expect(safetyNumber).toBe('12345 67890 12345 67890 12345 67890');
|
|
203
196
|
});
|
|
@@ -212,15 +205,15 @@ describe('SignalCli Advanced Features', () => {
|
|
|
212
205
|
{
|
|
213
206
|
number: '+33123456789',
|
|
214
207
|
safetyNumber: '12345 67890 12345 67890 12345 67890',
|
|
215
|
-
trustLevel: 'TRUSTED'
|
|
216
|
-
}
|
|
208
|
+
trustLevel: 'TRUSTED',
|
|
209
|
+
},
|
|
217
210
|
]);
|
|
218
211
|
// Mock trustIdentity response
|
|
219
212
|
sendJsonRpcRequestSpy.mockResolvedValueOnce({});
|
|
220
213
|
const verified = await signalCli.verifySafetyNumber('+33123456789', '12345 67890 12345 67890 12345 67890');
|
|
221
214
|
expect(verified).toBe(true);
|
|
222
215
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('trust', expect.objectContaining({
|
|
223
|
-
recipient: '+33123456789'
|
|
216
|
+
recipient: '+33123456789',
|
|
224
217
|
}));
|
|
225
218
|
});
|
|
226
219
|
it('should fail to verify incorrect safety number', async () => {
|
|
@@ -228,8 +221,8 @@ describe('SignalCli Advanced Features', () => {
|
|
|
228
221
|
{
|
|
229
222
|
number: '+33123456789',
|
|
230
223
|
safetyNumber: '12345 67890 12345 67890 12345 67890',
|
|
231
|
-
trustLevel: 'TRUSTED'
|
|
232
|
-
}
|
|
224
|
+
trustLevel: 'TRUSTED',
|
|
225
|
+
},
|
|
233
226
|
]);
|
|
234
227
|
const verified = await signalCli.verifySafetyNumber('+33123456789', '99999 99999 99999 99999 99999 99999');
|
|
235
228
|
expect(verified).toBe(false);
|
|
@@ -239,15 +232,11 @@ describe('SignalCli Advanced Features', () => {
|
|
|
239
232
|
{ number: '+33111111111', trustLevel: 'TRUSTED' },
|
|
240
233
|
{ number: '+33222222222', trustLevel: 'UNTRUSTED' },
|
|
241
234
|
{ number: '+33333333333', trustLevel: 'TRUST_ON_FIRST_USE' },
|
|
242
|
-
{ number: '+33444444444' }
|
|
235
|
+
{ number: '+33444444444' },
|
|
243
236
|
]);
|
|
244
237
|
const untrusted = await signalCli.listUntrustedIdentities();
|
|
245
238
|
expect(untrusted).toHaveLength(3);
|
|
246
|
-
expect(untrusted.map(i => i.number)).toEqual([
|
|
247
|
-
'+33222222222',
|
|
248
|
-
'+33333333333',
|
|
249
|
-
'+33444444444'
|
|
250
|
-
]);
|
|
239
|
+
expect(untrusted.map((i) => i.number)).toEqual(['+33222222222', '+33333333333', '+33444444444']);
|
|
251
240
|
});
|
|
252
241
|
});
|
|
253
242
|
describe('Advanced Group Management', () => {
|
|
@@ -257,23 +246,23 @@ describe('SignalCli Advanced Features', () => {
|
|
|
257
246
|
{
|
|
258
247
|
groupId: 'group123==',
|
|
259
248
|
name: 'Test Group',
|
|
260
|
-
groupInviteLink: 'https://signal.group/...'
|
|
261
|
-
}
|
|
249
|
+
groupInviteLink: 'https://signal.group/...',
|
|
250
|
+
},
|
|
262
251
|
]);
|
|
263
252
|
// Mock sendMessage response
|
|
264
253
|
sendJsonRpcRequestSpy.mockResolvedValueOnce({ timestamp: Date.now() });
|
|
265
254
|
await signalCli.sendGroupInviteLink('group123==', '+33123456789');
|
|
266
255
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('send', expect.objectContaining({
|
|
267
256
|
message: expect.stringContaining('https://signal.group/'),
|
|
268
|
-
recipients: ['+33123456789']
|
|
257
|
+
recipients: ['+33123456789'],
|
|
269
258
|
}));
|
|
270
259
|
});
|
|
271
260
|
it('should throw error when group has no invite link', async () => {
|
|
272
261
|
sendJsonRpcRequestSpy.mockResolvedValue([
|
|
273
262
|
{
|
|
274
263
|
groupId: 'group123==',
|
|
275
|
-
name: 'Test Group'
|
|
276
|
-
}
|
|
264
|
+
name: 'Test Group',
|
|
265
|
+
},
|
|
277
266
|
]);
|
|
278
267
|
await expect(signalCli.sendGroupInviteLink('group123==', '+33123456789')).rejects.toThrow('Group not found or does not have an invite link');
|
|
279
268
|
});
|
|
@@ -281,14 +270,14 @@ describe('SignalCli Advanced Features', () => {
|
|
|
281
270
|
await signalCli.setBannedMembers('group123==', ['+33111111111', '+33222222222']);
|
|
282
271
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateGroup', expect.objectContaining({
|
|
283
272
|
groupId: 'group123==',
|
|
284
|
-
banMembers: ['+33111111111', '+33222222222']
|
|
273
|
+
banMembers: ['+33111111111', '+33222222222'],
|
|
285
274
|
}));
|
|
286
275
|
});
|
|
287
276
|
it('should reset group link', async () => {
|
|
288
277
|
await signalCli.resetGroupLink('group123==');
|
|
289
278
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateGroup', expect.objectContaining({
|
|
290
279
|
groupId: 'group123==',
|
|
291
|
-
resetLink: true
|
|
280
|
+
resetLink: true,
|
|
292
281
|
}));
|
|
293
282
|
});
|
|
294
283
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const SignalCli_1 = require("../SignalCli");
|
|
37
|
+
const net = __importStar(require("net"));
|
|
38
|
+
const http = __importStar(require("http"));
|
|
39
|
+
const events_1 = require("events");
|
|
40
|
+
jest.mock('net');
|
|
41
|
+
jest.mock('http');
|
|
42
|
+
jest.mock('https');
|
|
43
|
+
describe('SignalCli Connections', () => {
|
|
44
|
+
let signalCli;
|
|
45
|
+
let mockSocket;
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
jest.clearAllMocks();
|
|
48
|
+
mockSocket = new events_1.EventEmitter();
|
|
49
|
+
mockSocket.write = jest.fn();
|
|
50
|
+
mockSocket.destroy = jest.fn();
|
|
51
|
+
net.createConnection.mockReturnValue(mockSocket);
|
|
52
|
+
});
|
|
53
|
+
it('should connect via Unix socket', async () => {
|
|
54
|
+
signalCli = new SignalCli_1.SignalCli('+1234567890', undefined, {
|
|
55
|
+
daemonMode: 'unix-socket',
|
|
56
|
+
socketPath: '/tmp/test.sock'
|
|
57
|
+
});
|
|
58
|
+
const connectPromise = signalCli.connect();
|
|
59
|
+
setImmediate(() => mockSocket.emit('connect'));
|
|
60
|
+
await connectPromise;
|
|
61
|
+
expect(net.createConnection).toHaveBeenCalledWith('/tmp/test.sock');
|
|
62
|
+
});
|
|
63
|
+
it('should connect via TCP', async () => {
|
|
64
|
+
signalCli = new SignalCli_1.SignalCli('+1234567890', undefined, {
|
|
65
|
+
daemonMode: 'tcp',
|
|
66
|
+
tcpHost: '1.2.3.4',
|
|
67
|
+
tcpPort: 1234
|
|
68
|
+
});
|
|
69
|
+
const connectPromise = signalCli.connect();
|
|
70
|
+
setImmediate(() => mockSocket.emit('connect'));
|
|
71
|
+
await connectPromise;
|
|
72
|
+
expect(net.createConnection).toHaveBeenCalledWith(1234, '1.2.3.4');
|
|
73
|
+
});
|
|
74
|
+
it('should connect via HTTP', async () => {
|
|
75
|
+
const mockRes = new events_1.EventEmitter();
|
|
76
|
+
mockRes.on = jest.fn().mockImplementation((event, cb) => {
|
|
77
|
+
if (event === 'data')
|
|
78
|
+
cb(JSON.stringify({ jsonrpc: '2.0', result: 'ok', id: '1' }));
|
|
79
|
+
if (event === 'end')
|
|
80
|
+
cb();
|
|
81
|
+
return mockRes;
|
|
82
|
+
});
|
|
83
|
+
const mockReq = new events_1.EventEmitter();
|
|
84
|
+
mockReq.write = jest.fn();
|
|
85
|
+
mockReq.end = jest.fn();
|
|
86
|
+
mockReq.setTimeout = jest.fn();
|
|
87
|
+
http.request.mockImplementation((url, opts, cb) => {
|
|
88
|
+
setImmediate(() => cb(mockRes));
|
|
89
|
+
return mockReq;
|
|
90
|
+
});
|
|
91
|
+
signalCli = new SignalCli_1.SignalCli('+1234567890', undefined, {
|
|
92
|
+
daemonMode: 'http',
|
|
93
|
+
httpBaseUrl: 'http://localhost:8080'
|
|
94
|
+
});
|
|
95
|
+
await signalCli.connect();
|
|
96
|
+
expect(http.request).toHaveBeenCalled();
|
|
97
|
+
});
|
|
98
|
+
it('should handle socket data and errors', async () => {
|
|
99
|
+
signalCli = new SignalCli_1.SignalCli('+1234567890', undefined, {
|
|
100
|
+
daemonMode: 'tcp'
|
|
101
|
+
});
|
|
102
|
+
const connectPromise = signalCli.connect();
|
|
103
|
+
setImmediate(() => mockSocket.emit('connect'));
|
|
104
|
+
await connectPromise;
|
|
105
|
+
const errorSpy = jest.fn();
|
|
106
|
+
signalCli.on('error', errorSpy);
|
|
107
|
+
mockSocket.emit('data', Buffer.from('invalid json\n'));
|
|
108
|
+
expect(errorSpy).toHaveBeenCalled();
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -16,23 +16,17 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
16
16
|
});
|
|
17
17
|
describe('Complete Messaging Workflow', () => {
|
|
18
18
|
it('should send message with full options and handle response', async () => {
|
|
19
|
-
signal.sendJsonRpcRequest = jest.fn()
|
|
20
|
-
.mockResolvedValue(mockSendResponse);
|
|
19
|
+
signal.sendJsonRpcRequest = jest.fn().mockResolvedValue(mockSendResponse);
|
|
21
20
|
const result = await signal.sendMessage('+33987654321', 'Hello!', {
|
|
22
21
|
attachments: ['/path/to/image.jpg'],
|
|
23
|
-
textStyles: [
|
|
24
|
-
|
|
25
|
-
],
|
|
26
|
-
mentions: [
|
|
27
|
-
{ start: 0, length: 5, number: '+33987654321' },
|
|
28
|
-
],
|
|
22
|
+
textStyles: [{ start: 0, length: 5, style: 'BOLD' }],
|
|
23
|
+
mentions: [{ start: 0, length: 5, number: '+33987654321' }],
|
|
29
24
|
});
|
|
30
25
|
expect(result.timestamp).toBeDefined();
|
|
31
26
|
expect(result.results).toBeDefined();
|
|
32
27
|
});
|
|
33
28
|
it('should send quoted message with attachments', async () => {
|
|
34
|
-
signal.sendJsonRpcRequest = jest.fn()
|
|
35
|
-
.mockResolvedValue(mockSendResponse);
|
|
29
|
+
signal.sendJsonRpcRequest = jest.fn().mockResolvedValue(mockSendResponse);
|
|
36
30
|
const result = await signal.sendMessage('+33987654321', 'Reply', {
|
|
37
31
|
quote: {
|
|
38
32
|
timestamp: 1234567890,
|
|
@@ -60,7 +54,8 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
60
54
|
blocked: false,
|
|
61
55
|
},
|
|
62
56
|
];
|
|
63
|
-
signal.sendJsonRpcRequest = jest
|
|
57
|
+
signal.sendJsonRpcRequest = jest
|
|
58
|
+
.fn()
|
|
64
59
|
.mockResolvedValueOnce(mockContacts)
|
|
65
60
|
.mockResolvedValueOnce(undefined)
|
|
66
61
|
.mockResolvedValueOnce([mockContacts[0]]);
|
|
@@ -80,10 +75,7 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
80
75
|
isMember: true,
|
|
81
76
|
isBlocked: false,
|
|
82
77
|
messageExpirationTime: 0,
|
|
83
|
-
members: [
|
|
84
|
-
{ number: '+33111111111' },
|
|
85
|
-
{ number: '+33222222222' },
|
|
86
|
-
],
|
|
78
|
+
members: [{ number: '+33111111111' }, { number: '+33222222222' }],
|
|
87
79
|
pendingMembers: [],
|
|
88
80
|
requestingMembers: [],
|
|
89
81
|
admins: [{ number: '+33111111111' }],
|
|
@@ -93,17 +85,15 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
93
85
|
permissionSendMessage: 'EVERY_MEMBER',
|
|
94
86
|
groupInviteLink: 'https://signal.group/test',
|
|
95
87
|
};
|
|
96
|
-
signal.sendJsonRpcRequest = jest
|
|
88
|
+
signal.sendJsonRpcRequest = jest
|
|
89
|
+
.fn()
|
|
97
90
|
.mockResolvedValueOnce([mockGroup])
|
|
98
91
|
.mockResolvedValueOnce(undefined)
|
|
99
92
|
.mockResolvedValueOnce(mockSendResponse)
|
|
100
93
|
.mockResolvedValueOnce([
|
|
101
94
|
{
|
|
102
95
|
...mockGroup,
|
|
103
|
-
members: [
|
|
104
|
-
...mockGroup.members,
|
|
105
|
-
{ number: '+33333333333' },
|
|
106
|
-
],
|
|
96
|
+
members: [...mockGroup.members, { number: '+33333333333' }],
|
|
107
97
|
},
|
|
108
98
|
]);
|
|
109
99
|
const groups = await signal.getGroupsWithDetails();
|
|
@@ -120,11 +110,14 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
120
110
|
describe('Identity Management Workflow', () => {
|
|
121
111
|
it('should verify safety number before sending', async () => {
|
|
122
112
|
const mockSafetyNumber = '12345 67890 12345 67890 12345 67890';
|
|
123
|
-
const mockIdentities = [
|
|
113
|
+
const mockIdentities = [
|
|
114
|
+
{
|
|
124
115
|
safetyNumber: mockSafetyNumber,
|
|
125
116
|
number: '+33987654321',
|
|
126
|
-
}
|
|
127
|
-
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
signal.sendJsonRpcRequest = jest
|
|
120
|
+
.fn()
|
|
128
121
|
.mockResolvedValueOnce(mockIdentities) // listIdentities
|
|
129
122
|
.mockResolvedValueOnce(mockIdentities) // listIdentities again for verify
|
|
130
123
|
.mockResolvedValueOnce(undefined) // trust
|
|
@@ -138,7 +131,8 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
138
131
|
});
|
|
139
132
|
describe('Username Management Workflow', () => {
|
|
140
133
|
it('should manage username lifecycle', async () => {
|
|
141
|
-
signal.sendJsonRpcRequest = jest
|
|
134
|
+
signal.sendJsonRpcRequest = jest
|
|
135
|
+
.fn()
|
|
142
136
|
.mockResolvedValueOnce({ username: 'alice.01' })
|
|
143
137
|
.mockResolvedValueOnce(mockSendResponse)
|
|
144
138
|
.mockResolvedValueOnce(undefined);
|
|
@@ -176,7 +170,8 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
176
170
|
},
|
|
177
171
|
},
|
|
178
172
|
];
|
|
179
|
-
signal.sendJsonRpcRequest = jest
|
|
173
|
+
signal.sendJsonRpcRequest = jest
|
|
174
|
+
.fn()
|
|
180
175
|
.mockResolvedValueOnce(mockMessages)
|
|
181
176
|
.mockResolvedValueOnce(mockSendResponse)
|
|
182
177
|
.mockResolvedValueOnce(mockSendResponse);
|
|
@@ -188,7 +183,8 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
188
183
|
if (msg0.envelope && msg0.envelope.source) {
|
|
189
184
|
await signal.sendMessage(msg0.envelope.source, 'Hello back!');
|
|
190
185
|
}
|
|
191
|
-
if (msg1.envelope &&
|
|
186
|
+
if (msg1.envelope &&
|
|
187
|
+
msg1.envelope.dataMessage &&
|
|
192
188
|
msg1.envelope.dataMessage.groupInfo &&
|
|
193
189
|
msg1.envelope.dataMessage.groupInfo.groupId) {
|
|
194
190
|
await signal.sendMessage(msg1.envelope.dataMessage.groupInfo.groupId, 'Hi everyone!');
|
|
@@ -200,7 +196,8 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
200
196
|
describe('Multi-Step Group Operations', () => {
|
|
201
197
|
it('should create group, add members, and send announcement', async () => {
|
|
202
198
|
const mockGroupId = 'newgroup123==';
|
|
203
|
-
signal.sendJsonRpcRequest = jest
|
|
199
|
+
signal.sendJsonRpcRequest = jest
|
|
200
|
+
.fn()
|
|
204
201
|
.mockResolvedValueOnce({ groupId: mockGroupId })
|
|
205
202
|
.mockResolvedValueOnce(undefined)
|
|
206
203
|
.mockResolvedValueOnce(undefined)
|
|
@@ -220,7 +217,8 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
220
217
|
});
|
|
221
218
|
describe('Error Handling in Workflows', () => {
|
|
222
219
|
it('should handle errors gracefully in message sending workflow', async () => {
|
|
223
|
-
signal.sendJsonRpcRequest = jest
|
|
220
|
+
signal.sendJsonRpcRequest = jest
|
|
221
|
+
.fn()
|
|
224
222
|
.mockRejectedValueOnce(new Error('Network error'))
|
|
225
223
|
.mockResolvedValueOnce(mockSendResponse);
|
|
226
224
|
await expect(signal.sendMessage('+33987654321', 'Test')).rejects.toThrow('Network error');
|
|
@@ -228,12 +226,10 @@ describe('SignalCli - E2E Workflow Tests (Phase 6)', () => {
|
|
|
228
226
|
expect(result.timestamp).toBeDefined();
|
|
229
227
|
});
|
|
230
228
|
it('should handle non-existent group in workflow', async () => {
|
|
231
|
-
signal.sendJsonRpcRequest = jest.fn()
|
|
232
|
-
.mockResolvedValue([]);
|
|
229
|
+
signal.sendJsonRpcRequest = jest.fn().mockResolvedValue([]);
|
|
233
230
|
const groups = await signal.getGroupsWithDetails();
|
|
234
231
|
expect(groups).toHaveLength(0);
|
|
235
|
-
signal.sendJsonRpcRequest = jest.fn()
|
|
236
|
-
.mockRejectedValue(new Error('Group not found'));
|
|
232
|
+
signal.sendJsonRpcRequest = jest.fn().mockRejectedValue(new Error('Group not found'));
|
|
237
233
|
await expect(signal.sendMessage('nonexistent==', 'Test')).rejects.toThrow('Group not found');
|
|
238
234
|
});
|
|
239
235
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|