signal-sdk 0.0.9 → 0.1.1
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 +184 -61
- package/dist/MultiAccountManager.d.ts +149 -0
- package/dist/MultiAccountManager.js +320 -0
- package/dist/SignalBot.d.ts +1 -0
- package/dist/SignalBot.js +20 -2
- package/dist/SignalCli.d.ts +315 -16
- package/dist/SignalCli.js +880 -26
- package/dist/__tests__/MultiAccountManager.test.d.ts +4 -0
- package/dist/__tests__/MultiAccountManager.test.js +209 -0
- package/dist/__tests__/SignalBot.additional.test.d.ts +5 -0
- package/dist/__tests__/SignalBot.additional.test.js +353 -0
- package/dist/__tests__/SignalBot.test.js +5 -0
- package/dist/__tests__/SignalCli.advanced.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.advanced.test.js +295 -0
- package/dist/__tests__/SignalCli.e2e.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.e2e.test.js +240 -0
- package/dist/__tests__/SignalCli.integration.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.integration.test.js +225 -0
- package/dist/__tests__/SignalCli.methods.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.methods.test.js +556 -0
- package/dist/__tests__/SignalCli.parsing.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.parsing.test.js +258 -0
- package/dist/__tests__/SignalCli.test.js +249 -13
- package/dist/__tests__/config.test.d.ts +5 -0
- package/dist/__tests__/config.test.js +252 -0
- package/dist/__tests__/errors.test.d.ts +5 -0
- package/dist/__tests__/errors.test.js +276 -0
- package/dist/__tests__/retry.test.d.ts +4 -0
- package/dist/__tests__/retry.test.js +123 -0
- package/dist/__tests__/validators.test.d.ts +4 -0
- package/dist/__tests__/validators.test.js +147 -0
- package/dist/config.d.ts +82 -0
- package/dist/config.js +116 -0
- package/dist/errors.d.ts +32 -0
- package/dist/errors.js +75 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +7 -1
- package/dist/interfaces.d.ts +200 -10
- package/dist/interfaces.js +1 -1
- package/dist/retry.d.ts +56 -0
- package/dist/retry.js +152 -0
- package/dist/validators.d.ts +59 -0
- package/dist/validators.js +170 -0
- package/package.json +1 -1
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tests for enhanced parsing functionality (Phase 5)
|
|
4
|
+
* Tests profile and group data parsing methods
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const SignalCli_1 = require("../SignalCli");
|
|
8
|
+
describe('SignalCli - Enhanced Parsing (Phase 5)', () => {
|
|
9
|
+
let signal;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
signal = new SignalCli_1.SignalCli('+33123456789');
|
|
12
|
+
// Mock sendJsonRpcRequest to avoid actual signal-cli calls
|
|
13
|
+
signal.sendJsonRpcRequest = jest.fn();
|
|
14
|
+
});
|
|
15
|
+
describe('parseContactProfile', () => {
|
|
16
|
+
it('should parse contact with full profile data', () => {
|
|
17
|
+
const contact = {
|
|
18
|
+
number: '+33123456789',
|
|
19
|
+
name: 'John Doe',
|
|
20
|
+
uuid: 'test-uuid',
|
|
21
|
+
blocked: false,
|
|
22
|
+
givenName: 'John',
|
|
23
|
+
familyName: 'Doe',
|
|
24
|
+
mobileCoinAddress: 'mc1_test_address_123',
|
|
25
|
+
profileName: 'John Doe',
|
|
26
|
+
};
|
|
27
|
+
const parsed = signal.parseContactProfile(contact);
|
|
28
|
+
expect(parsed.givenName).toBe('John');
|
|
29
|
+
expect(parsed.familyName).toBe('Doe');
|
|
30
|
+
expect(parsed.mobileCoinAddress).toBe('mc1_test_address_123');
|
|
31
|
+
expect(parsed.profileName).toBe('John Doe');
|
|
32
|
+
});
|
|
33
|
+
it('should build profileName from givenName and familyName if missing', () => {
|
|
34
|
+
const contact = {
|
|
35
|
+
number: '+33123456789',
|
|
36
|
+
name: 'John Doe',
|
|
37
|
+
uuid: 'test-uuid',
|
|
38
|
+
blocked: false,
|
|
39
|
+
givenName: 'John',
|
|
40
|
+
familyName: 'Doe',
|
|
41
|
+
};
|
|
42
|
+
const parsed = signal.parseContactProfile(contact);
|
|
43
|
+
expect(parsed.profileName).toBe('John Doe');
|
|
44
|
+
});
|
|
45
|
+
it('should use givenName as profileName if no familyName', () => {
|
|
46
|
+
const contact = {
|
|
47
|
+
number: '+33123456789',
|
|
48
|
+
name: 'John',
|
|
49
|
+
uuid: 'test-uuid',
|
|
50
|
+
blocked: false,
|
|
51
|
+
givenName: 'John',
|
|
52
|
+
};
|
|
53
|
+
const parsed = signal.parseContactProfile(contact);
|
|
54
|
+
expect(parsed.profileName).toBe('John');
|
|
55
|
+
});
|
|
56
|
+
it('should handle contact with minimal data', () => {
|
|
57
|
+
const contact = {
|
|
58
|
+
number: '+33123456789',
|
|
59
|
+
name: 'Unknown',
|
|
60
|
+
blocked: false,
|
|
61
|
+
};
|
|
62
|
+
const parsed = signal.parseContactProfile(contact);
|
|
63
|
+
expect(parsed.givenName).toBeUndefined();
|
|
64
|
+
expect(parsed.familyName).toBeUndefined();
|
|
65
|
+
expect(parsed.mobileCoinAddress).toBeUndefined();
|
|
66
|
+
});
|
|
67
|
+
it('should preserve additional contact fields', () => {
|
|
68
|
+
const contact = {
|
|
69
|
+
number: '+33123456789',
|
|
70
|
+
name: 'John Doe',
|
|
71
|
+
uuid: 'test-uuid',
|
|
72
|
+
blocked: true,
|
|
73
|
+
profileAvatar: 'avatar.jpg',
|
|
74
|
+
color: 'blue',
|
|
75
|
+
archived: true,
|
|
76
|
+
mutedUntil: 123456789,
|
|
77
|
+
hideStory: true,
|
|
78
|
+
givenName: 'John',
|
|
79
|
+
};
|
|
80
|
+
const parsed = signal.parseContactProfile(contact);
|
|
81
|
+
expect(parsed.blocked).toBe(true);
|
|
82
|
+
expect(parsed.profileAvatar).toBe('avatar.jpg');
|
|
83
|
+
expect(parsed.color).toBe('blue');
|
|
84
|
+
expect(parsed.archived).toBe(true);
|
|
85
|
+
expect(parsed.mutedUntil).toBe(123456789);
|
|
86
|
+
expect(parsed.hideStory).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe('parseGroupDetails', () => {
|
|
90
|
+
it('should parse group with full membership data', () => {
|
|
91
|
+
const group = {
|
|
92
|
+
groupId: 'group123==',
|
|
93
|
+
name: 'Test Group',
|
|
94
|
+
description: 'A test group',
|
|
95
|
+
isMember: true,
|
|
96
|
+
isBlocked: false,
|
|
97
|
+
messageExpirationTime: 0,
|
|
98
|
+
members: [
|
|
99
|
+
{ number: '+33111111111' },
|
|
100
|
+
{ number: '+33222222222' },
|
|
101
|
+
],
|
|
102
|
+
pendingMembers: [
|
|
103
|
+
{ number: '+33333333333' },
|
|
104
|
+
],
|
|
105
|
+
requestingMembers: [],
|
|
106
|
+
admins: [
|
|
107
|
+
{ number: '+33111111111' },
|
|
108
|
+
],
|
|
109
|
+
banned: [
|
|
110
|
+
{ number: '+33444444444' },
|
|
111
|
+
],
|
|
112
|
+
permissionAddMember: 'ONLY_ADMINS',
|
|
113
|
+
permissionEditDetails: 'ONLY_ADMINS',
|
|
114
|
+
permissionSendMessage: 'EVERY_MEMBER',
|
|
115
|
+
groupInviteLink: 'https://signal.group/test',
|
|
116
|
+
};
|
|
117
|
+
const parsed = signal.parseGroupDetails(group);
|
|
118
|
+
expect(parsed.pendingMembers).toHaveLength(1);
|
|
119
|
+
expect(parsed.pendingMembers[0].number).toBe('+33333333333');
|
|
120
|
+
expect(parsed.banned).toHaveLength(1);
|
|
121
|
+
expect(parsed.banned[0].number).toBe('+33444444444');
|
|
122
|
+
expect(parsed.inviteLink).toBe('https://signal.group/test');
|
|
123
|
+
expect(parsed.groupInviteLink).toBe('https://signal.group/test');
|
|
124
|
+
});
|
|
125
|
+
it('should normalize inviteLink field', () => {
|
|
126
|
+
const group1 = {
|
|
127
|
+
groupId: 'group123==',
|
|
128
|
+
name: 'Test Group',
|
|
129
|
+
isMember: true,
|
|
130
|
+
isBlocked: false,
|
|
131
|
+
messageExpirationTime: 0,
|
|
132
|
+
members: [],
|
|
133
|
+
pendingMembers: [],
|
|
134
|
+
requestingMembers: [],
|
|
135
|
+
admins: [],
|
|
136
|
+
banned: [],
|
|
137
|
+
permissionAddMember: 'EVERY_MEMBER',
|
|
138
|
+
permissionEditDetails: 'EVERY_MEMBER',
|
|
139
|
+
permissionSendMessage: 'EVERY_MEMBER',
|
|
140
|
+
groupInviteLink: 'https://signal.group/test1',
|
|
141
|
+
};
|
|
142
|
+
const parsed1 = signal.parseGroupDetails(group1);
|
|
143
|
+
expect(parsed1.inviteLink).toBe('https://signal.group/test1');
|
|
144
|
+
expect(parsed1.groupInviteLink).toBe('https://signal.group/test1');
|
|
145
|
+
const group2 = {
|
|
146
|
+
...group1,
|
|
147
|
+
groupInviteLink: undefined,
|
|
148
|
+
inviteLink: 'https://signal.group/test2',
|
|
149
|
+
};
|
|
150
|
+
const parsed2 = signal.parseGroupDetails(group2);
|
|
151
|
+
expect(parsed2.inviteLink).toBe('https://signal.group/test2');
|
|
152
|
+
expect(parsed2.groupInviteLink).toBe('https://signal.group/test2');
|
|
153
|
+
});
|
|
154
|
+
it('should ensure membership arrays exist', () => {
|
|
155
|
+
const group = {
|
|
156
|
+
groupId: 'group123==',
|
|
157
|
+
name: 'Minimal Group',
|
|
158
|
+
isMember: true,
|
|
159
|
+
isBlocked: false,
|
|
160
|
+
messageExpirationTime: 0,
|
|
161
|
+
members: [],
|
|
162
|
+
pendingMembers: [],
|
|
163
|
+
requestingMembers: [],
|
|
164
|
+
admins: [],
|
|
165
|
+
banned: [],
|
|
166
|
+
permissionAddMember: 'EVERY_MEMBER',
|
|
167
|
+
permissionEditDetails: 'EVERY_MEMBER',
|
|
168
|
+
permissionSendMessage: 'EVERY_MEMBER',
|
|
169
|
+
};
|
|
170
|
+
const parsed = signal.parseGroupDetails(group);
|
|
171
|
+
expect(Array.isArray(parsed.members)).toBe(true);
|
|
172
|
+
expect(Array.isArray(parsed.pendingMembers)).toBe(true);
|
|
173
|
+
expect(Array.isArray(parsed.requestingMembers)).toBe(true);
|
|
174
|
+
expect(Array.isArray(parsed.admins)).toBe(true);
|
|
175
|
+
expect(Array.isArray(parsed.banned)).toBe(true);
|
|
176
|
+
});
|
|
177
|
+
it('should preserve group permissions', () => {
|
|
178
|
+
const group = {
|
|
179
|
+
groupId: 'group123==',
|
|
180
|
+
name: 'Restricted Group',
|
|
181
|
+
isMember: true,
|
|
182
|
+
isBlocked: false,
|
|
183
|
+
messageExpirationTime: 3600,
|
|
184
|
+
members: [],
|
|
185
|
+
pendingMembers: [],
|
|
186
|
+
requestingMembers: [],
|
|
187
|
+
admins: [],
|
|
188
|
+
banned: [],
|
|
189
|
+
permissionAddMember: 'ONLY_ADMINS',
|
|
190
|
+
permissionEditDetails: 'ONLY_ADMINS',
|
|
191
|
+
permissionSendMessage: 'ONLY_ADMINS',
|
|
192
|
+
};
|
|
193
|
+
const parsed = signal.parseGroupDetails(group);
|
|
194
|
+
expect(parsed.permissionAddMember).toBe('ONLY_ADMINS');
|
|
195
|
+
expect(parsed.permissionEditDetails).toBe('ONLY_ADMINS');
|
|
196
|
+
expect(parsed.permissionSendMessage).toBe('ONLY_ADMINS');
|
|
197
|
+
expect(parsed.messageExpirationTime).toBe(3600);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
describe('getContactsWithProfiles', () => {
|
|
201
|
+
it('should return enriched contacts list', async () => {
|
|
202
|
+
const mockContacts = [
|
|
203
|
+
{
|
|
204
|
+
number: '+33111111111',
|
|
205
|
+
name: 'Alice',
|
|
206
|
+
blocked: false,
|
|
207
|
+
givenName: 'Alice',
|
|
208
|
+
familyName: 'Smith',
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
number: '+33222222222',
|
|
212
|
+
name: 'Bob',
|
|
213
|
+
blocked: false,
|
|
214
|
+
givenName: 'Bob',
|
|
215
|
+
mobileCoinAddress: 'mc1_bob',
|
|
216
|
+
},
|
|
217
|
+
];
|
|
218
|
+
signal.sendJsonRpcRequest = jest.fn().mockResolvedValue(mockContacts);
|
|
219
|
+
const enriched = await signal.getContactsWithProfiles();
|
|
220
|
+
expect(enriched).toHaveLength(2);
|
|
221
|
+
expect(enriched[0].profileName).toBe('Alice Smith');
|
|
222
|
+
expect(enriched[1].profileName).toBe('Bob');
|
|
223
|
+
expect(enriched[1].mobileCoinAddress).toBe('mc1_bob');
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
describe('getGroupsWithDetails', () => {
|
|
227
|
+
it('should return enriched groups list', async () => {
|
|
228
|
+
const mockGroups = [
|
|
229
|
+
{
|
|
230
|
+
groupId: 'group1==',
|
|
231
|
+
name: 'Group 1',
|
|
232
|
+
isMember: true,
|
|
233
|
+
isBlocked: false,
|
|
234
|
+
messageExpirationTime: 0,
|
|
235
|
+
members: [{ number: '+33111111111' }],
|
|
236
|
+
pendingMembers: [{ number: '+33222222222' }],
|
|
237
|
+
requestingMembers: [],
|
|
238
|
+
admins: [{ number: '+33111111111' }],
|
|
239
|
+
banned: [],
|
|
240
|
+
permissionAddMember: 'EVERY_MEMBER',
|
|
241
|
+
permissionEditDetails: 'EVERY_MEMBER',
|
|
242
|
+
permissionSendMessage: 'EVERY_MEMBER',
|
|
243
|
+
groupInviteLink: 'https://signal.group/group1',
|
|
244
|
+
},
|
|
245
|
+
];
|
|
246
|
+
signal.sendJsonRpcRequest = jest.fn().mockResolvedValue(mockGroups);
|
|
247
|
+
const enriched = await signal.getGroupsWithDetails();
|
|
248
|
+
expect(enriched).toHaveLength(1);
|
|
249
|
+
expect(enriched[0].inviteLink).toBe('https://signal.group/group1');
|
|
250
|
+
expect(enriched[0].pendingMembers).toHaveLength(1);
|
|
251
|
+
});
|
|
252
|
+
it('should support list options', async () => {
|
|
253
|
+
signal.sendJsonRpcRequest = jest.fn().mockResolvedValue([]);
|
|
254
|
+
await signal.getGroupsWithDetails({ detailed: true });
|
|
255
|
+
expect(signal.sendJsonRpcRequest).toHaveBeenCalledWith('listGroups', expect.objectContaining({ detailed: true }));
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
});
|
|
@@ -155,31 +155,23 @@ describe('SignalCli', () => {
|
|
|
155
155
|
expect(result).toEqual(mockResponse);
|
|
156
156
|
});
|
|
157
157
|
it('should start change number', async () => {
|
|
158
|
-
const mockResponse = {
|
|
159
|
-
session: 'change-session-id',
|
|
160
|
-
challenge: 'challenge-token'
|
|
161
|
-
};
|
|
162
158
|
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
163
|
-
.mockResolvedValue(
|
|
164
|
-
|
|
159
|
+
.mockResolvedValue({});
|
|
160
|
+
await signalCli.startChangeNumber('+1987654321');
|
|
165
161
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('startChangeNumber', {
|
|
166
162
|
account: '+1234567890',
|
|
167
163
|
number: '+1987654321',
|
|
168
164
|
voice: false
|
|
169
165
|
});
|
|
170
|
-
expect(result).toEqual({
|
|
171
|
-
session: 'change-session-id',
|
|
172
|
-
newNumber: '+1987654321',
|
|
173
|
-
challenge: 'challenge-token'
|
|
174
|
-
});
|
|
175
166
|
});
|
|
176
167
|
it('should finish change number', async () => {
|
|
177
168
|
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
178
169
|
.mockResolvedValue({});
|
|
179
|
-
await signalCli.finishChangeNumber('123456', 'pin-code');
|
|
170
|
+
await signalCli.finishChangeNumber('+1987654321', '123456', 'pin-code');
|
|
180
171
|
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('finishChangeNumber', {
|
|
181
172
|
account: '+1234567890',
|
|
182
|
-
|
|
173
|
+
number: '+1987654321',
|
|
174
|
+
verificationCode: '123456',
|
|
183
175
|
pin: 'pin-code'
|
|
184
176
|
});
|
|
185
177
|
});
|
|
@@ -232,4 +224,248 @@ describe('SignalCli', () => {
|
|
|
232
224
|
Object.defineProperty(process, 'platform', { value: originalPlatform });
|
|
233
225
|
});
|
|
234
226
|
});
|
|
227
|
+
// Test v0.1.0 features: Polls
|
|
228
|
+
describe('Poll Management', () => {
|
|
229
|
+
beforeEach(() => {
|
|
230
|
+
jest.spyOn(signalCli, 'sendJsonRpcRequest').mockResolvedValue({});
|
|
231
|
+
});
|
|
232
|
+
it('should create a poll', async () => {
|
|
233
|
+
const mockResponse = { timestamp: 123456789 };
|
|
234
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
235
|
+
.mockResolvedValue(mockResponse);
|
|
236
|
+
const result = await signalCli.sendPollCreate({
|
|
237
|
+
recipients: ['+1234567890'],
|
|
238
|
+
question: 'What is your favorite color?',
|
|
239
|
+
options: ['Red', 'Blue', 'Green']
|
|
240
|
+
});
|
|
241
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('sendPollCreate', {
|
|
242
|
+
account: '+1234567890',
|
|
243
|
+
recipients: ['+1234567890'],
|
|
244
|
+
question: 'What is your favorite color?',
|
|
245
|
+
options: ['Red', 'Blue', 'Green']
|
|
246
|
+
});
|
|
247
|
+
expect(result).toEqual(mockResponse);
|
|
248
|
+
});
|
|
249
|
+
it('should create a group poll', async () => {
|
|
250
|
+
const mockResponse = { timestamp: 123456789 };
|
|
251
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
252
|
+
.mockResolvedValue(mockResponse);
|
|
253
|
+
const result = await signalCli.sendPollCreate({
|
|
254
|
+
groupId: 'group-123',
|
|
255
|
+
question: 'Best meeting time?',
|
|
256
|
+
options: ['9 AM', '2 PM', '4 PM']
|
|
257
|
+
});
|
|
258
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('sendPollCreate', {
|
|
259
|
+
account: '+1234567890',
|
|
260
|
+
groupId: 'group-123',
|
|
261
|
+
question: 'Best meeting time?',
|
|
262
|
+
options: ['9 AM', '2 PM', '4 PM']
|
|
263
|
+
});
|
|
264
|
+
expect(result).toEqual(mockResponse);
|
|
265
|
+
});
|
|
266
|
+
it('should vote on a poll', async () => {
|
|
267
|
+
const mockResponse = { timestamp: 123456790 };
|
|
268
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
269
|
+
.mockResolvedValue(mockResponse);
|
|
270
|
+
const result = await signalCli.sendPollVote('+1234567890', {
|
|
271
|
+
pollAuthor: '+9876543210',
|
|
272
|
+
pollTimestamp: 123456789,
|
|
273
|
+
optionIndexes: [0, 1]
|
|
274
|
+
});
|
|
275
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('sendPollVote', {
|
|
276
|
+
account: '+1234567890',
|
|
277
|
+
recipient: '+1234567890',
|
|
278
|
+
pollAuthor: '+9876543210',
|
|
279
|
+
pollTimestamp: 123456789,
|
|
280
|
+
options: [0, 1]
|
|
281
|
+
});
|
|
282
|
+
expect(result).toEqual(mockResponse);
|
|
283
|
+
});
|
|
284
|
+
it('should terminate a poll', async () => {
|
|
285
|
+
const mockResponse = { timestamp: 123456791 };
|
|
286
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
287
|
+
.mockResolvedValue(mockResponse);
|
|
288
|
+
const result = await signalCli.sendPollTerminate('+1234567890', {
|
|
289
|
+
pollTimestamp: 123456789
|
|
290
|
+
});
|
|
291
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('sendPollTerminate', {
|
|
292
|
+
account: '+1234567890',
|
|
293
|
+
recipient: '+1234567890',
|
|
294
|
+
pollTimestamp: 123456789
|
|
295
|
+
});
|
|
296
|
+
expect(result).toEqual(mockResponse);
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
// Test v0.1.0 features: Attachment Retrieval
|
|
300
|
+
describe('Attachment Retrieval', () => {
|
|
301
|
+
beforeEach(() => {
|
|
302
|
+
jest.spyOn(signalCli, 'sendJsonRpcRequest').mockResolvedValue({});
|
|
303
|
+
});
|
|
304
|
+
it('should get attachment by ID', async () => {
|
|
305
|
+
const mockBase64 = 'base64-encoded-data';
|
|
306
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
307
|
+
.mockResolvedValue(mockBase64);
|
|
308
|
+
const result = await signalCli.getAttachment({
|
|
309
|
+
id: 'attachment-123'
|
|
310
|
+
});
|
|
311
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('getAttachment', {
|
|
312
|
+
account: '+1234567890',
|
|
313
|
+
id: 'attachment-123'
|
|
314
|
+
});
|
|
315
|
+
expect(result).toBe(mockBase64);
|
|
316
|
+
});
|
|
317
|
+
it('should get contact avatar', async () => {
|
|
318
|
+
const mockBase64 = 'base64-avatar-data';
|
|
319
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
320
|
+
.mockResolvedValue(mockBase64);
|
|
321
|
+
const result = await signalCli.getAvatar({
|
|
322
|
+
contact: '+9876543210'
|
|
323
|
+
});
|
|
324
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('getAvatar', {
|
|
325
|
+
account: '+1234567890',
|
|
326
|
+
contact: '+9876543210'
|
|
327
|
+
});
|
|
328
|
+
expect(result).toBe(mockBase64);
|
|
329
|
+
});
|
|
330
|
+
it('should get profile avatar', async () => {
|
|
331
|
+
const mockBase64 = 'base64-profile-avatar';
|
|
332
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
333
|
+
.mockResolvedValue(mockBase64);
|
|
334
|
+
const result = await signalCli.getAvatar({
|
|
335
|
+
profile: '+1234567890'
|
|
336
|
+
});
|
|
337
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('getAvatar', {
|
|
338
|
+
account: '+1234567890',
|
|
339
|
+
profile: '+1234567890'
|
|
340
|
+
});
|
|
341
|
+
expect(result).toBe(mockBase64);
|
|
342
|
+
});
|
|
343
|
+
it('should get group avatar', async () => {
|
|
344
|
+
const mockBase64 = 'base64-group-avatar';
|
|
345
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
346
|
+
.mockResolvedValue(mockBase64);
|
|
347
|
+
const result = await signalCli.getAvatar({
|
|
348
|
+
groupId: 'group-123'
|
|
349
|
+
});
|
|
350
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('getAvatar', {
|
|
351
|
+
account: '+1234567890',
|
|
352
|
+
groupId: 'group-123'
|
|
353
|
+
});
|
|
354
|
+
expect(result).toBe(mockBase64);
|
|
355
|
+
});
|
|
356
|
+
it('should get sticker data', async () => {
|
|
357
|
+
const mockBase64 = 'base64-sticker-data';
|
|
358
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
359
|
+
.mockResolvedValue(mockBase64);
|
|
360
|
+
const result = await signalCli.getSticker({
|
|
361
|
+
packId: 'pack-123',
|
|
362
|
+
stickerId: 5
|
|
363
|
+
});
|
|
364
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('getSticker', {
|
|
365
|
+
account: '+1234567890',
|
|
366
|
+
packId: 'pack-123',
|
|
367
|
+
stickerId: 5
|
|
368
|
+
});
|
|
369
|
+
expect(result).toBe(mockBase64);
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
// Test v0.1.0 features: Account Management
|
|
373
|
+
describe('Account Management', () => {
|
|
374
|
+
beforeEach(() => {
|
|
375
|
+
jest.spyOn(signalCli, 'sendJsonRpcRequest').mockResolvedValue({});
|
|
376
|
+
});
|
|
377
|
+
it('should update account settings', async () => {
|
|
378
|
+
const mockResponse = {
|
|
379
|
+
username: 'myusername',
|
|
380
|
+
usernameLink: 'https://signal.me/#myusername'
|
|
381
|
+
};
|
|
382
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
383
|
+
.mockResolvedValue(mockResponse);
|
|
384
|
+
const result = await signalCli.updateAccount({
|
|
385
|
+
deviceName: 'My Device',
|
|
386
|
+
username: 'myusername'
|
|
387
|
+
});
|
|
388
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('updateAccount', {
|
|
389
|
+
account: '+1234567890',
|
|
390
|
+
deviceName: 'My Device',
|
|
391
|
+
username: 'myusername'
|
|
392
|
+
});
|
|
393
|
+
expect(result.success).toBe(true);
|
|
394
|
+
expect(result.username).toBe('myusername');
|
|
395
|
+
});
|
|
396
|
+
it('should list accounts with details', async () => {
|
|
397
|
+
const mockResponse = {
|
|
398
|
+
accounts: [
|
|
399
|
+
{ number: '+1234567890', name: 'Account 1', uuid: 'uuid-1' },
|
|
400
|
+
{ number: '+9876543210', name: 'Account 2', uuid: 'uuid-2' }
|
|
401
|
+
]
|
|
402
|
+
};
|
|
403
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
404
|
+
.mockResolvedValue(mockResponse);
|
|
405
|
+
const result = await signalCli.listAccountsDetailed();
|
|
406
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('listAccounts');
|
|
407
|
+
expect(result).toEqual(mockResponse.accounts);
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
// Test v0.1.0 features: Synchronization
|
|
411
|
+
describe('Synchronization', () => {
|
|
412
|
+
beforeEach(() => {
|
|
413
|
+
jest.spyOn(signalCli, 'sendJsonRpcRequest').mockResolvedValue({});
|
|
414
|
+
});
|
|
415
|
+
it('should send contacts to linked devices', async () => {
|
|
416
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
417
|
+
.mockResolvedValue({});
|
|
418
|
+
await signalCli.sendContacts();
|
|
419
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('sendContacts', {
|
|
420
|
+
account: '+1234567890'
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
it('should list groups with detailed information', async () => {
|
|
424
|
+
const mockGroups = [
|
|
425
|
+
{
|
|
426
|
+
id: 'group-1',
|
|
427
|
+
name: 'Test Group 1',
|
|
428
|
+
members: ['+1111111111', '+2222222222'],
|
|
429
|
+
groupType: 'GROUP_V2'
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
id: 'group-2',
|
|
433
|
+
name: 'Test Group 2',
|
|
434
|
+
members: ['+3333333333'],
|
|
435
|
+
groupType: 'GROUP_V2'
|
|
436
|
+
}
|
|
437
|
+
];
|
|
438
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
439
|
+
.mockResolvedValue(mockGroups);
|
|
440
|
+
const result = await signalCli.listGroupsDetailed({
|
|
441
|
+
detailed: true
|
|
442
|
+
});
|
|
443
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('listGroups', {
|
|
444
|
+
account: '+1234567890',
|
|
445
|
+
detailed: true
|
|
446
|
+
});
|
|
447
|
+
expect(result).toEqual(mockGroups);
|
|
448
|
+
});
|
|
449
|
+
it('should filter groups by ID', async () => {
|
|
450
|
+
const mockGroups = [
|
|
451
|
+
{
|
|
452
|
+
id: 'group-1',
|
|
453
|
+
name: 'Specific Group',
|
|
454
|
+
members: ['+1111111111']
|
|
455
|
+
}
|
|
456
|
+
];
|
|
457
|
+
const sendJsonRpcRequestSpy = jest.spyOn(signalCli, 'sendJsonRpcRequest')
|
|
458
|
+
.mockResolvedValue(mockGroups);
|
|
459
|
+
const result = await signalCli.listGroupsDetailed({
|
|
460
|
+
groupIds: ['group-1'],
|
|
461
|
+
detailed: true
|
|
462
|
+
});
|
|
463
|
+
expect(sendJsonRpcRequestSpy).toHaveBeenCalledWith('listGroups', {
|
|
464
|
+
account: '+1234567890',
|
|
465
|
+
detailed: true,
|
|
466
|
+
groupId: ['group-1']
|
|
467
|
+
});
|
|
468
|
+
expect(result).toEqual(mockGroups);
|
|
469
|
+
});
|
|
470
|
+
});
|
|
235
471
|
});
|