@bsv/message-box-client 1.1.7 → 1.1.8
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/cjs/mod.js +20 -0
- package/dist/cjs/mod.js.map +1 -0
- package/dist/cjs/package.json +69 -0
- package/dist/cjs/src/MessageBoxClient.js +1171 -0
- package/dist/cjs/src/MessageBoxClient.js.map +1 -0
- package/dist/cjs/src/PeerPayClient.js +309 -0
- package/dist/cjs/src/PeerPayClient.js.map +1 -0
- package/dist/cjs/src/Utils/logger.js +27 -0
- package/dist/cjs/src/Utils/logger.js.map +1 -0
- package/dist/cjs/src/__tests/MessageBoxClient.test.js +614 -0
- package/dist/cjs/src/__tests/MessageBoxClient.test.js.map +1 -0
- package/dist/cjs/src/__tests/PeerPayClientUnit.test.js +213 -0
- package/dist/cjs/src/__tests/PeerPayClientUnit.test.js.map +1 -0
- package/dist/cjs/src/__tests/integration/integrationEncrypted.test.js +84 -0
- package/dist/cjs/src/__tests/integration/integrationEncrypted.test.js.map +1 -0
- package/dist/cjs/src/__tests/integration/integrationHTTP.test.js +128 -0
- package/dist/cjs/src/__tests/integration/integrationHTTP.test.js.map +1 -0
- package/dist/cjs/src/__tests/integration/integrationOverlay.test.js +138 -0
- package/dist/cjs/src/__tests/integration/integrationOverlay.test.js.map +1 -0
- package/dist/cjs/src/__tests/integration/integrationWS.test.js +123 -0
- package/dist/cjs/src/__tests/integration/integrationWS.test.js.map +1 -0
- package/dist/cjs/src/__tests/integration/testServer.js +65 -0
- package/dist/cjs/src/__tests/integration/testServer.js.map +1 -0
- package/dist/cjs/src/types.js +3 -0
- package/dist/cjs/src/types.js.map +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/esm/mod.js +4 -0
- package/dist/esm/mod.js.map +1 -0
- package/dist/esm/src/MessageBoxClient.js +1165 -0
- package/dist/esm/src/MessageBoxClient.js.map +1 -0
- package/dist/esm/src/PeerPayClient.js +307 -0
- package/dist/esm/src/PeerPayClient.js.map +1 -0
- package/dist/esm/src/Utils/logger.js +23 -0
- package/dist/esm/src/Utils/logger.js.map +1 -0
- package/dist/esm/src/__tests/MessageBoxClient.test.js +603 -0
- package/dist/esm/src/__tests/MessageBoxClient.test.js.map +1 -0
- package/dist/esm/src/__tests/PeerPayClientUnit.test.js +211 -0
- package/dist/esm/src/__tests/PeerPayClientUnit.test.js.map +1 -0
- package/dist/esm/src/__tests/integration/integrationEncrypted.test.js +81 -0
- package/dist/esm/src/__tests/integration/integrationEncrypted.test.js.map +1 -0
- package/dist/esm/src/__tests/integration/integrationHTTP.test.js +126 -0
- package/dist/esm/src/__tests/integration/integrationHTTP.test.js.map +1 -0
- package/dist/esm/src/__tests/integration/integrationOverlay.test.js +135 -0
- package/dist/esm/src/__tests/integration/integrationOverlay.test.js.map +1 -0
- package/dist/esm/src/__tests/integration/integrationWS.test.js +121 -0
- package/dist/esm/src/__tests/integration/integrationWS.test.js.map +1 -0
- package/dist/esm/src/__tests/integration/testServer.js +61 -0
- package/dist/esm/src/__tests/integration/testServer.js.map +1 -0
- package/dist/esm/src/types.js +2 -0
- package/dist/esm/src/types.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/types/mod.d.ts +4 -0
- package/dist/types/mod.d.ts.map +1 -0
- package/dist/types/src/MessageBoxClient.d.ts +441 -0
- package/dist/types/src/MessageBoxClient.d.ts.map +1 -0
- package/dist/types/src/PeerPayClient.d.ts +144 -0
- package/dist/types/src/PeerPayClient.d.ts.map +1 -0
- package/dist/types/src/Utils/logger.d.ts +9 -0
- package/dist/types/src/Utils/logger.d.ts.map +1 -0
- package/dist/types/src/__tests/MessageBoxClient.test.d.ts +2 -0
- package/dist/types/src/__tests/MessageBoxClient.test.d.ts.map +1 -0
- package/dist/types/src/__tests/PeerPayClientUnit.test.d.ts +2 -0
- package/dist/types/src/__tests/PeerPayClientUnit.test.d.ts.map +1 -0
- package/dist/types/src/__tests/integration/integrationEncrypted.test.d.ts +2 -0
- package/dist/types/src/__tests/integration/integrationEncrypted.test.d.ts.map +1 -0
- package/dist/types/src/__tests/integration/integrationHTTP.test.d.ts +2 -0
- package/dist/types/src/__tests/integration/integrationHTTP.test.d.ts.map +1 -0
- package/dist/types/src/__tests/integration/integrationOverlay.test.d.ts +2 -0
- package/dist/types/src/__tests/integration/integrationOverlay.test.d.ts.map +1 -0
- package/dist/types/src/__tests/integration/integrationWS.test.d.ts +2 -0
- package/dist/types/src/__tests/integration/integrationWS.test.d.ts.map +1 -0
- package/dist/types/src/__tests/integration/testServer.d.ts +9 -0
- package/dist/types/src/__tests/integration/testServer.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +99 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -0
- package/dist/umd/bundle.js +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/* eslint-env jest */
|
|
4
|
+
const MessageBoxClient_js_1 = require("../MessageBoxClient.js");
|
|
5
|
+
const sdk_1 = require("@bsv/sdk");
|
|
6
|
+
// MOCK: WalletClient methods globally
|
|
7
|
+
jest.spyOn(sdk_1.WalletClient.prototype, 'createHmac').mockResolvedValue({
|
|
8
|
+
hmac: Array.from(new Uint8Array([1, 2, 3]))
|
|
9
|
+
});
|
|
10
|
+
jest.spyOn(sdk_1.WalletClient.prototype, 'getPublicKey').mockResolvedValue({
|
|
11
|
+
publicKey: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'
|
|
12
|
+
});
|
|
13
|
+
jest.spyOn(sdk_1.WalletClient.prototype, 'encrypt').mockResolvedValue({
|
|
14
|
+
ciphertext: [9, 9, 9, 9]
|
|
15
|
+
});
|
|
16
|
+
jest.spyOn(sdk_1.WalletClient.prototype, 'decrypt').mockResolvedValue({
|
|
17
|
+
plaintext: [1, 2, 3, 4, 5]
|
|
18
|
+
});
|
|
19
|
+
jest.spyOn(sdk_1.WalletClient.prototype, 'createSignature').mockResolvedValue({
|
|
20
|
+
signature: [1, 2, 3, 4, 5] // <-- any dummy byte array
|
|
21
|
+
});
|
|
22
|
+
jest.spyOn(sdk_1.WalletClient.prototype, 'connectToSubstrate').mockImplementation(async function () {
|
|
23
|
+
this.substrate = {
|
|
24
|
+
createSignature: async (message) => {
|
|
25
|
+
return Array.from(new Uint8Array([1, 2, 3])); // Return mock signature
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
const minimalTx = new sdk_1.Transaction();
|
|
30
|
+
minimalTx.addOutput({
|
|
31
|
+
satoshis: 1,
|
|
32
|
+
lockingScript: new sdk_1.LockingScript([]) // ✅ must wrap in LockingScript class
|
|
33
|
+
});
|
|
34
|
+
const realAtomicBEEF = minimalTx.toAtomicBEEF();
|
|
35
|
+
jest.spyOn(sdk_1.WalletClient.prototype, 'createAction').mockResolvedValue({
|
|
36
|
+
txid: 'mocked-txid',
|
|
37
|
+
tx: realAtomicBEEF
|
|
38
|
+
});
|
|
39
|
+
// MOCK: AuthFetch responses
|
|
40
|
+
const defaultMockResponse = {
|
|
41
|
+
json: async () => ({ status: 'success', message: 'Mocked response' }),
|
|
42
|
+
headers: new Headers(),
|
|
43
|
+
ok: true,
|
|
44
|
+
status: 200
|
|
45
|
+
};
|
|
46
|
+
jest.spyOn(MessageBoxClient_js_1.MessageBoxClient.prototype, 'anointHost').mockImplementation(async () => {
|
|
47
|
+
return { txid: 'mocked-anoint-txid' };
|
|
48
|
+
});
|
|
49
|
+
jest.spyOn(MessageBoxClient_js_1.MessageBoxClient.prototype, 'queryAdvertisements')
|
|
50
|
+
.mockResolvedValue([]);
|
|
51
|
+
jest.spyOn(sdk_1.AuthFetch.prototype, 'fetch')
|
|
52
|
+
.mockResolvedValue(defaultMockResponse);
|
|
53
|
+
// MOCK: WebSocket behavior
|
|
54
|
+
const socketOnMap = {};
|
|
55
|
+
const mockSocket = {
|
|
56
|
+
on: jest.fn((event, callback) => {
|
|
57
|
+
socketOnMap[event] = callback;
|
|
58
|
+
}),
|
|
59
|
+
emit: jest.fn(),
|
|
60
|
+
disconnect: jest.fn(),
|
|
61
|
+
connected: true,
|
|
62
|
+
off: jest.fn()
|
|
63
|
+
};
|
|
64
|
+
jest.mock('@bsv/authsocket-client', () => ({
|
|
65
|
+
AuthSocketClient: jest.fn(() => mockSocket)
|
|
66
|
+
}));
|
|
67
|
+
// Optional: Global WebSocket override (not strictly needed with AuthSocketClient)
|
|
68
|
+
class MockWebSocket {
|
|
69
|
+
constructor() {
|
|
70
|
+
this.readyState = MockWebSocket.OPEN;
|
|
71
|
+
this.on = jest.fn();
|
|
72
|
+
this.send = jest.fn();
|
|
73
|
+
this.close = jest.fn();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
MockWebSocket.CONNECTING = 0;
|
|
77
|
+
MockWebSocket.OPEN = 1;
|
|
78
|
+
MockWebSocket.CLOSING = 2;
|
|
79
|
+
MockWebSocket.CLOSED = 3;
|
|
80
|
+
global.WebSocket = MockWebSocket;
|
|
81
|
+
describe('MessageBoxClient', () => {
|
|
82
|
+
let mockWalletClient;
|
|
83
|
+
beforeEach(() => {
|
|
84
|
+
mockWalletClient = new sdk_1.WalletClient();
|
|
85
|
+
jest.clearAllMocks();
|
|
86
|
+
// (Optional, but if you want per-test control, you could move mocks here instead of globally.)
|
|
87
|
+
});
|
|
88
|
+
const VALID_LIST_AND_READ_RESULT = {
|
|
89
|
+
body: JSON.stringify({
|
|
90
|
+
status: 200,
|
|
91
|
+
messages: [
|
|
92
|
+
{ sender: 'mockSender', messageId: 42, body: {} },
|
|
93
|
+
{ sender: 'mockSender', messageId: 43, body: {} }
|
|
94
|
+
]
|
|
95
|
+
})
|
|
96
|
+
};
|
|
97
|
+
const VALID_ACK_RESULT = {
|
|
98
|
+
body: JSON.stringify({
|
|
99
|
+
status: 200,
|
|
100
|
+
message: 'Messages marked as acknowledged!'
|
|
101
|
+
})
|
|
102
|
+
};
|
|
103
|
+
it('Creates an instance of the MessageBoxClient class', async () => {
|
|
104
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
105
|
+
walletClient: mockWalletClient,
|
|
106
|
+
host: 'https://messagebox.babbage.systems',
|
|
107
|
+
enableLogging: true
|
|
108
|
+
});
|
|
109
|
+
await messageBoxClient.init();
|
|
110
|
+
expect(messageBoxClient).toHaveProperty('host', 'https://messagebox.babbage.systems');
|
|
111
|
+
// Ensure the socket is initialized as undefined before connecting
|
|
112
|
+
expect(messageBoxClient.testSocket).toBeUndefined();
|
|
113
|
+
});
|
|
114
|
+
it('Initializes WebSocket connection', async () => {
|
|
115
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
116
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
117
|
+
walletClient: mockWalletClient,
|
|
118
|
+
host: 'https://messagebox.babbage.systems',
|
|
119
|
+
enableLogging: true
|
|
120
|
+
});
|
|
121
|
+
await messageBoxClient.init();
|
|
122
|
+
const connection = messageBoxClient.initializeConnection();
|
|
123
|
+
// Simulate server response
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
var _a;
|
|
126
|
+
(_a = socketOnMap.authenticationSuccess) === null || _a === void 0 ? void 0 : _a.call(socketOnMap, { status: 'ok' });
|
|
127
|
+
}, 100);
|
|
128
|
+
await expect(connection).resolves.toBeUndefined();
|
|
129
|
+
}, 10000);
|
|
130
|
+
it('Falls back to HTTP when WebSocket is not initialized', async () => {
|
|
131
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
132
|
+
walletClient: mockWalletClient,
|
|
133
|
+
host: 'https://messagebox.babbage.systems',
|
|
134
|
+
enableLogging: true
|
|
135
|
+
});
|
|
136
|
+
await messageBoxClient.init();
|
|
137
|
+
// Bypass the real connection logic
|
|
138
|
+
jest.spyOn(messageBoxClient, 'initializeConnection').mockImplementation(async () => { });
|
|
139
|
+
messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4';
|
|
140
|
+
messageBoxClient.socket = null;
|
|
141
|
+
// Expect it to fall back to HTTP and succeed
|
|
142
|
+
const result = await messageBoxClient.sendLiveMessage({
|
|
143
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
144
|
+
messageBox: 'test_inbox',
|
|
145
|
+
body: 'Test message'
|
|
146
|
+
});
|
|
147
|
+
expect(result).toEqual({
|
|
148
|
+
status: 'success',
|
|
149
|
+
message: 'Mocked response',
|
|
150
|
+
messageId: '010203'
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
it('Listens for live messages', async () => {
|
|
154
|
+
var _a;
|
|
155
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
156
|
+
walletClient: mockWalletClient,
|
|
157
|
+
host: 'https://messagebox.babbage.systems',
|
|
158
|
+
enableLogging: true
|
|
159
|
+
});
|
|
160
|
+
await messageBoxClient.init();
|
|
161
|
+
const connection = messageBoxClient.initializeConnection();
|
|
162
|
+
setTimeout(() => {
|
|
163
|
+
var _a;
|
|
164
|
+
(_a = socketOnMap.authenticationSuccess) === null || _a === void 0 ? void 0 : _a.call(socketOnMap, { status: 'ok' });
|
|
165
|
+
}, 100);
|
|
166
|
+
await connection;
|
|
167
|
+
const mockOnMessage = jest.fn();
|
|
168
|
+
await messageBoxClient.listenForLiveMessages({
|
|
169
|
+
messageBox: 'test_inbox',
|
|
170
|
+
onMessage: mockOnMessage
|
|
171
|
+
});
|
|
172
|
+
expect((_a = messageBoxClient.testSocket) === null || _a === void 0 ? void 0 : _a.emit).toHaveBeenCalledWith('joinRoom', '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4-test_inbox');
|
|
173
|
+
}, 10000);
|
|
174
|
+
it('Sends a live message', async () => {
|
|
175
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
176
|
+
walletClient: mockWalletClient,
|
|
177
|
+
host: 'https://messagebox.babbage.systems',
|
|
178
|
+
enableLogging: true
|
|
179
|
+
});
|
|
180
|
+
await messageBoxClient.init();
|
|
181
|
+
const connection = messageBoxClient.initializeConnection();
|
|
182
|
+
// Simulate WebSocket auth success
|
|
183
|
+
setTimeout(() => {
|
|
184
|
+
var _a;
|
|
185
|
+
(_a = socketOnMap.authenticationSuccess) === null || _a === void 0 ? void 0 : _a.call(socketOnMap, { status: 'ok' });
|
|
186
|
+
}, 100);
|
|
187
|
+
await connection;
|
|
188
|
+
const emitSpy = jest.spyOn(messageBoxClient.testSocket, 'emit');
|
|
189
|
+
// Kick off sending a message (this sets up the ack listener)
|
|
190
|
+
const sendPromise = messageBoxClient.sendLiveMessage({
|
|
191
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
192
|
+
messageBox: 'test_inbox',
|
|
193
|
+
body: 'Test message'
|
|
194
|
+
});
|
|
195
|
+
// Simulate WebSocket acknowledgment
|
|
196
|
+
setTimeout(() => {
|
|
197
|
+
var _a;
|
|
198
|
+
(_a = socketOnMap['sendMessageAck-02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4-test_inbox']) === null || _a === void 0 ? void 0 : _a.call(socketOnMap, {
|
|
199
|
+
status: 'success',
|
|
200
|
+
messageId: 'mocked123'
|
|
201
|
+
});
|
|
202
|
+
}, 100);
|
|
203
|
+
const result = await sendPromise;
|
|
204
|
+
// Check that WebSocket emit happened correctly
|
|
205
|
+
expect(emitSpy).toHaveBeenCalledWith('sendMessage', expect.objectContaining({
|
|
206
|
+
roomId: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4-test_inbox',
|
|
207
|
+
message: expect.objectContaining({
|
|
208
|
+
messageId: '010203',
|
|
209
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
210
|
+
body: expect.stringMatching(/encrypted/)
|
|
211
|
+
})
|
|
212
|
+
}));
|
|
213
|
+
// Check the resolved result
|
|
214
|
+
expect(result).toEqual({
|
|
215
|
+
status: 'success',
|
|
216
|
+
messageId: 'mocked123'
|
|
217
|
+
});
|
|
218
|
+
}, 15000);
|
|
219
|
+
it('Sends a message', async () => {
|
|
220
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
221
|
+
walletClient: mockWalletClient,
|
|
222
|
+
host: 'https://messagebox.babbage.systems',
|
|
223
|
+
enableLogging: true
|
|
224
|
+
});
|
|
225
|
+
await messageBoxClient.init();
|
|
226
|
+
messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4';
|
|
227
|
+
jest.spyOn(messageBoxClient.authFetch, 'fetch').mockResolvedValue({
|
|
228
|
+
json: async () => ({
|
|
229
|
+
status: 'success',
|
|
230
|
+
message: 'Your message has been sent!'
|
|
231
|
+
}),
|
|
232
|
+
headers: new Headers(),
|
|
233
|
+
ok: true,
|
|
234
|
+
status: 200
|
|
235
|
+
});
|
|
236
|
+
const result = await messageBoxClient.sendMessage({
|
|
237
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
238
|
+
messageBox: 'test_inbox',
|
|
239
|
+
body: { data: 'test' }
|
|
240
|
+
});
|
|
241
|
+
expect(result).toHaveProperty('message', 'Your message has been sent!');
|
|
242
|
+
});
|
|
243
|
+
it('Lists available messages', async () => {
|
|
244
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
245
|
+
walletClient: mockWalletClient,
|
|
246
|
+
host: 'https://messagebox.babbage.systems',
|
|
247
|
+
enableLogging: true
|
|
248
|
+
});
|
|
249
|
+
await messageBoxClient.init();
|
|
250
|
+
messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4';
|
|
251
|
+
jest.spyOn(messageBoxClient.authFetch, 'fetch').mockResolvedValue({
|
|
252
|
+
json: async () => JSON.parse(VALID_LIST_AND_READ_RESULT.body),
|
|
253
|
+
headers: new Headers(),
|
|
254
|
+
ok: true,
|
|
255
|
+
status: 200
|
|
256
|
+
});
|
|
257
|
+
const result = await messageBoxClient.listMessages({ messageBox: 'test_inbox' });
|
|
258
|
+
expect(result).toEqual(JSON.parse(VALID_LIST_AND_READ_RESULT.body).messages);
|
|
259
|
+
});
|
|
260
|
+
it('Acknowledges a message', async () => {
|
|
261
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
262
|
+
walletClient: mockWalletClient,
|
|
263
|
+
host: 'https://messagebox.babbage.systems',
|
|
264
|
+
enableLogging: true
|
|
265
|
+
});
|
|
266
|
+
await messageBoxClient.init();
|
|
267
|
+
messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4';
|
|
268
|
+
jest.spyOn(messageBoxClient.authFetch, 'fetch').mockResolvedValue({
|
|
269
|
+
json: async () => JSON.parse(VALID_ACK_RESULT.body),
|
|
270
|
+
headers: new Headers(),
|
|
271
|
+
ok: true,
|
|
272
|
+
status: 200
|
|
273
|
+
});
|
|
274
|
+
const result = await messageBoxClient.acknowledgeMessage({ messageIds: ['42'] });
|
|
275
|
+
expect(result).toEqual(200);
|
|
276
|
+
});
|
|
277
|
+
it('Throws an error when sendMessage() API fails', async () => {
|
|
278
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
279
|
+
walletClient: mockWalletClient,
|
|
280
|
+
host: 'https://messagebox.babbage.systems',
|
|
281
|
+
enableLogging: true
|
|
282
|
+
});
|
|
283
|
+
await messageBoxClient.init();
|
|
284
|
+
messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4';
|
|
285
|
+
jest.spyOn(messageBoxClient.authFetch, 'fetch')
|
|
286
|
+
.mockResolvedValue({
|
|
287
|
+
status: 500,
|
|
288
|
+
statusText: 'Internal Server Error',
|
|
289
|
+
ok: false,
|
|
290
|
+
json: async () => ({ status: 'error', description: 'Internal Server Error' }),
|
|
291
|
+
headers: new Headers()
|
|
292
|
+
});
|
|
293
|
+
await expect(messageBoxClient.sendMessage({
|
|
294
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
295
|
+
messageBox: 'test_inbox',
|
|
296
|
+
body: 'Test Message'
|
|
297
|
+
})).rejects.toThrow('Message sending failed: HTTP 500 - Internal Server Error');
|
|
298
|
+
});
|
|
299
|
+
it('throws when every host fails', async () => {
|
|
300
|
+
const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://primary', enableLogging: false });
|
|
301
|
+
await client.init();
|
|
302
|
+
// Pretend there are no advertised replicas
|
|
303
|
+
jest.spyOn(client, 'queryAdvertisements').mockResolvedValue([]);
|
|
304
|
+
// Primary host responds with 500
|
|
305
|
+
jest.spyOn(client.authFetch, 'fetch').mockResolvedValue({
|
|
306
|
+
ok: false,
|
|
307
|
+
status: 500,
|
|
308
|
+
statusText: 'Internal Server Error',
|
|
309
|
+
json: async () => ({ status: 'error', description: 'DB down' })
|
|
310
|
+
});
|
|
311
|
+
await expect(client.listMessages({ messageBox: 'inbox' }))
|
|
312
|
+
.rejects.toThrow('Failed to retrieve messages from any host');
|
|
313
|
+
});
|
|
314
|
+
it('returns [] when at least one host succeeds but has no messages', async () => {
|
|
315
|
+
const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://primary', enableLogging: false });
|
|
316
|
+
await client.init();
|
|
317
|
+
// One failing replica, one healthy replica
|
|
318
|
+
jest.spyOn(client, 'queryAdvertisements').mockResolvedValue([{
|
|
319
|
+
host: 'https://replica'
|
|
320
|
+
}]);
|
|
321
|
+
jest.spyOn(client.authFetch, 'fetch')
|
|
322
|
+
.mockImplementation(async (url) =>
|
|
323
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
324
|
+
url.startsWith('https://primary')
|
|
325
|
+
? await Promise.resolve({
|
|
326
|
+
ok: false,
|
|
327
|
+
status: 500,
|
|
328
|
+
statusText: 'Internal Server Error',
|
|
329
|
+
json: async () => ({ status: 'error', description: 'DB down' })
|
|
330
|
+
})
|
|
331
|
+
: await Promise.resolve({
|
|
332
|
+
ok: true,
|
|
333
|
+
status: 200,
|
|
334
|
+
json: async () => ({ status: 'success', messages: [] })
|
|
335
|
+
}));
|
|
336
|
+
await expect(client.listMessages({ messageBox: 'inbox' })).resolves.toEqual([]);
|
|
337
|
+
});
|
|
338
|
+
it('Throws an error when acknowledgeMessage() API fails', async () => {
|
|
339
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
340
|
+
walletClient: mockWalletClient,
|
|
341
|
+
host: 'https://messagebox.babbage.systems',
|
|
342
|
+
enableLogging: true
|
|
343
|
+
});
|
|
344
|
+
await messageBoxClient.init();
|
|
345
|
+
messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4';
|
|
346
|
+
jest.spyOn(messageBoxClient.authFetch, 'fetch')
|
|
347
|
+
.mockResolvedValue({
|
|
348
|
+
status: 500,
|
|
349
|
+
json: async () => ({ status: 'error', description: 'Failed to acknowledge messages' })
|
|
350
|
+
});
|
|
351
|
+
await expect(messageBoxClient.acknowledgeMessage({ messageIds: ['42'] }))
|
|
352
|
+
.rejects.toThrow('Failed to acknowledge messages');
|
|
353
|
+
});
|
|
354
|
+
it('Throws an error when WebSocket is not initialized before listening for messages', async () => {
|
|
355
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
356
|
+
walletClient: mockWalletClient,
|
|
357
|
+
host: 'https://messagebox.babbage.systems',
|
|
358
|
+
enableLogging: true
|
|
359
|
+
});
|
|
360
|
+
await messageBoxClient.init();
|
|
361
|
+
messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4';
|
|
362
|
+
// Stub out joinRoom to throw like the real one might
|
|
363
|
+
jest.spyOn(messageBoxClient, 'joinRoom').mockRejectedValue(new Error('WebSocket connection not initialized'));
|
|
364
|
+
await expect(messageBoxClient.listenForLiveMessages({
|
|
365
|
+
onMessage: jest.fn(),
|
|
366
|
+
messageBox: 'test_inbox'
|
|
367
|
+
})).rejects.toThrow('WebSocket connection not initialized');
|
|
368
|
+
});
|
|
369
|
+
it('Emits joinRoom event and listens for incoming messages', async () => {
|
|
370
|
+
var _a;
|
|
371
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
372
|
+
walletClient: mockWalletClient,
|
|
373
|
+
host: 'https://messagebox.babbage.systems',
|
|
374
|
+
enableLogging: true
|
|
375
|
+
});
|
|
376
|
+
await messageBoxClient.init();
|
|
377
|
+
// Mock identity key properly
|
|
378
|
+
jest.spyOn(mockWalletClient, 'getPublicKey').mockResolvedValue({ publicKey: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4' });
|
|
379
|
+
// Mock socket with `on` method capturing event handlers
|
|
380
|
+
const mockSocket = {
|
|
381
|
+
emit: jest.fn(),
|
|
382
|
+
on: jest.fn()
|
|
383
|
+
};
|
|
384
|
+
// Mock `initializeConnection` so it assigns `socket` & identity key
|
|
385
|
+
jest.spyOn(messageBoxClient, 'initializeConnection').mockImplementation(async () => {
|
|
386
|
+
Object.defineProperty(messageBoxClient, 'testIdentityKey', { get: () => '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4' });
|
|
387
|
+
Object.defineProperty(messageBoxClient, 'testSocket', { get: () => mockSocket });
|
|
388
|
+
messageBoxClient.socket = mockSocket; // Ensures internal socket is set
|
|
389
|
+
messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; // Ensures identity key is set
|
|
390
|
+
});
|
|
391
|
+
const onMessageMock = jest.fn();
|
|
392
|
+
await messageBoxClient.listenForLiveMessages({
|
|
393
|
+
onMessage: onMessageMock,
|
|
394
|
+
messageBox: 'test_inbox'
|
|
395
|
+
});
|
|
396
|
+
// Ensure `joinRoom` event was emitted with the correct identity key
|
|
397
|
+
expect(mockSocket.emit).toHaveBeenCalledWith('joinRoom', '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4-test_inbox');
|
|
398
|
+
// Simulate receiving a message
|
|
399
|
+
const receivedMessage = { text: 'Hello, world!' };
|
|
400
|
+
// Extract & invoke the callback function stored in `on`
|
|
401
|
+
const sendMessageCallback = (_a = mockSocket.on.mock.calls.find(([eventName]) => eventName === 'sendMessage-02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4-test_inbox')) === null || _a === void 0 ? void 0 : _a[1]; // Extract the callback function
|
|
402
|
+
if (typeof sendMessageCallback === 'function') {
|
|
403
|
+
sendMessageCallback(receivedMessage);
|
|
404
|
+
}
|
|
405
|
+
// Ensure `onMessage` was called with the received message
|
|
406
|
+
expect(onMessageMock).toHaveBeenCalledWith(receivedMessage);
|
|
407
|
+
});
|
|
408
|
+
it('Handles WebSocket connection and disconnection events', async () => {
|
|
409
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
410
|
+
walletClient: mockWalletClient,
|
|
411
|
+
host: 'https://messagebox.babbage.systems',
|
|
412
|
+
enableLogging: true
|
|
413
|
+
});
|
|
414
|
+
await messageBoxClient.init();
|
|
415
|
+
// Simulate identity key
|
|
416
|
+
jest.spyOn(mockWalletClient, 'getPublicKey').mockResolvedValue({ publicKey: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4' });
|
|
417
|
+
// Simulate connection + disconnection + auth success
|
|
418
|
+
setTimeout(() => {
|
|
419
|
+
var _a, _b, _c;
|
|
420
|
+
(_a = socketOnMap.connect) === null || _a === void 0 ? void 0 : _a.call(socketOnMap);
|
|
421
|
+
(_b = socketOnMap.disconnect) === null || _b === void 0 ? void 0 : _b.call(socketOnMap);
|
|
422
|
+
(_c = socketOnMap.authenticationSuccess) === null || _c === void 0 ? void 0 : _c.call(socketOnMap, { status: 'ok' });
|
|
423
|
+
}, 100);
|
|
424
|
+
await messageBoxClient.initializeConnection();
|
|
425
|
+
// Verify event listeners were registered
|
|
426
|
+
expect(mockSocket.on).toHaveBeenCalledWith('connect', expect.any(Function));
|
|
427
|
+
expect(mockSocket.on).toHaveBeenCalledWith('disconnect', expect.any(Function));
|
|
428
|
+
}, 10000);
|
|
429
|
+
it('throws an error when recipient is empty in sendLiveMessage', async () => {
|
|
430
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
431
|
+
walletClient: mockWalletClient,
|
|
432
|
+
host: 'https://messagebox.babbage.systems',
|
|
433
|
+
enableLogging: true
|
|
434
|
+
});
|
|
435
|
+
await messageBoxClient.init();
|
|
436
|
+
// Mock `initializeConnection` so it assigns `socket` & identity key
|
|
437
|
+
jest.spyOn(messageBoxClient, 'initializeConnection').mockImplementation(async () => {
|
|
438
|
+
Object.defineProperty(messageBoxClient, 'testIdentityKey', { get: () => '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4' });
|
|
439
|
+
Object.defineProperty(messageBoxClient, 'testSocket', { get: () => mockSocket });
|
|
440
|
+
messageBoxClient.socket = mockSocket; // Ensures internal socket is set
|
|
441
|
+
messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; // Ensures identity key is set
|
|
442
|
+
});
|
|
443
|
+
// Mock socket to ensure WebSocket validation does not fail
|
|
444
|
+
const mockSocket = {
|
|
445
|
+
emit: jest.fn()
|
|
446
|
+
};
|
|
447
|
+
jest.spyOn(messageBoxClient, 'testSocket', 'get').mockReturnValue(mockSocket);
|
|
448
|
+
await expect(messageBoxClient.sendLiveMessage({
|
|
449
|
+
recipient: ' ',
|
|
450
|
+
messageBox: 'test_inbox',
|
|
451
|
+
body: 'Test message'
|
|
452
|
+
})).rejects.toThrow('[MB CLIENT ERROR] Recipient identity key is required');
|
|
453
|
+
});
|
|
454
|
+
it('throws an error when recipient is missing in sendMessage', async () => {
|
|
455
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
456
|
+
walletClient: mockWalletClient,
|
|
457
|
+
host: 'https://messagebox.babbage.systems',
|
|
458
|
+
enableLogging: true
|
|
459
|
+
});
|
|
460
|
+
await messageBoxClient.init();
|
|
461
|
+
await expect(messageBoxClient.sendMessage({
|
|
462
|
+
recipient: '', // Empty recipient
|
|
463
|
+
messageBox: 'test_inbox',
|
|
464
|
+
body: 'Test message'
|
|
465
|
+
})).rejects.toThrow('You must provide a message recipient!');
|
|
466
|
+
await expect(messageBoxClient.sendMessage({
|
|
467
|
+
recipient: ' ', // Whitespace recipient
|
|
468
|
+
messageBox: 'test_inbox',
|
|
469
|
+
body: 'Test message'
|
|
470
|
+
})).rejects.toThrow('You must provide a message recipient!');
|
|
471
|
+
await expect(messageBoxClient.sendMessage({
|
|
472
|
+
recipient: null, // Null recipient
|
|
473
|
+
messageBox: 'test_inbox',
|
|
474
|
+
body: 'Test message'
|
|
475
|
+
})).rejects.toThrow('You must provide a message recipient!');
|
|
476
|
+
});
|
|
477
|
+
it('throws an error when messageBox is missing in sendMessage', async () => {
|
|
478
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
479
|
+
walletClient: mockWalletClient,
|
|
480
|
+
host: 'https://messagebox.babbage.systems',
|
|
481
|
+
enableLogging: true
|
|
482
|
+
});
|
|
483
|
+
await messageBoxClient.init();
|
|
484
|
+
await expect(messageBoxClient.sendMessage({
|
|
485
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
486
|
+
messageBox: '', // Empty messageBox
|
|
487
|
+
body: 'Test message'
|
|
488
|
+
})).rejects.toThrow('You must provide a messageBox to send this message into!');
|
|
489
|
+
await expect(messageBoxClient.sendMessage({
|
|
490
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
491
|
+
messageBox: ' ', // Whitespace messageBox
|
|
492
|
+
body: 'Test message'
|
|
493
|
+
})).rejects.toThrow('You must provide a messageBox to send this message into!');
|
|
494
|
+
await expect(messageBoxClient.sendMessage({
|
|
495
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
496
|
+
messageBox: null, // Null messageBox
|
|
497
|
+
body: 'Test message'
|
|
498
|
+
})).rejects.toThrow('You must provide a messageBox to send this message into!');
|
|
499
|
+
});
|
|
500
|
+
it('throws an error when message body is missing in sendMessage', async () => {
|
|
501
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
502
|
+
walletClient: mockWalletClient,
|
|
503
|
+
host: 'https://messagebox.babbage.systems',
|
|
504
|
+
enableLogging: true
|
|
505
|
+
});
|
|
506
|
+
await messageBoxClient.init();
|
|
507
|
+
await expect(messageBoxClient.sendMessage({
|
|
508
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
509
|
+
messageBox: 'test_inbox',
|
|
510
|
+
body: '' // Empty body
|
|
511
|
+
})).rejects.toThrow('Every message must have a body!');
|
|
512
|
+
await expect(messageBoxClient.sendMessage({
|
|
513
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
514
|
+
messageBox: 'test_inbox',
|
|
515
|
+
body: ' ' // Whitespace body
|
|
516
|
+
})).rejects.toThrow('Every message must have a body!');
|
|
517
|
+
await expect(messageBoxClient.sendMessage({
|
|
518
|
+
recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4',
|
|
519
|
+
messageBox: 'test_inbox',
|
|
520
|
+
body: null // Null body
|
|
521
|
+
})).rejects.toThrow('Every message must have a body!');
|
|
522
|
+
});
|
|
523
|
+
it('throws an error when messageBox is empty in listMessages', async () => {
|
|
524
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
525
|
+
walletClient: mockWalletClient,
|
|
526
|
+
host: 'https://messagebox.babbage.systems',
|
|
527
|
+
enableLogging: true
|
|
528
|
+
});
|
|
529
|
+
await messageBoxClient.init();
|
|
530
|
+
await expect(messageBoxClient.listMessages({
|
|
531
|
+
messageBox: '' // Empty messageBox
|
|
532
|
+
})).rejects.toThrow('MessageBox cannot be empty');
|
|
533
|
+
await expect(messageBoxClient.listMessages({
|
|
534
|
+
messageBox: ' ' // Whitespace messageBox
|
|
535
|
+
})).rejects.toThrow('MessageBox cannot be empty');
|
|
536
|
+
});
|
|
537
|
+
it('throws an error when messageIds is empty in acknowledgeMessage', async () => {
|
|
538
|
+
const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({
|
|
539
|
+
walletClient: mockWalletClient,
|
|
540
|
+
host: 'https://messagebox.babbage.systems',
|
|
541
|
+
enableLogging: true
|
|
542
|
+
});
|
|
543
|
+
await messageBoxClient.init();
|
|
544
|
+
await expect(messageBoxClient.acknowledgeMessage({
|
|
545
|
+
messageIds: [] // Empty array
|
|
546
|
+
})).rejects.toThrow('Message IDs array cannot be empty');
|
|
547
|
+
await expect(messageBoxClient.acknowledgeMessage({
|
|
548
|
+
messageIds: undefined // Undefined value
|
|
549
|
+
})).rejects.toThrow('Message IDs array cannot be empty');
|
|
550
|
+
await expect(messageBoxClient.acknowledgeMessage({
|
|
551
|
+
messageIds: null // Null value
|
|
552
|
+
})).rejects.toThrow('Message IDs array cannot be empty');
|
|
553
|
+
await expect(messageBoxClient.acknowledgeMessage({
|
|
554
|
+
messageIds: 'invalid' // Not an array
|
|
555
|
+
})).rejects.toThrow('Message IDs array cannot be empty');
|
|
556
|
+
});
|
|
557
|
+
it('Uses default host if none is provided', () => {
|
|
558
|
+
const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient });
|
|
559
|
+
expect(client.initialized).toBe(false);
|
|
560
|
+
expect(client.host).toBe('https://messagebox.babbage.systems');
|
|
561
|
+
});
|
|
562
|
+
it('Calls init() to set up a default host when missing', async () => {
|
|
563
|
+
const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient });
|
|
564
|
+
expect(client.initialized).toBe(false);
|
|
565
|
+
await client.init();
|
|
566
|
+
expect(client.initialized).toBe(true);
|
|
567
|
+
expect(typeof client.host).toBe('string');
|
|
568
|
+
expect(client.host.length).toBeGreaterThan(0);
|
|
569
|
+
});
|
|
570
|
+
it('init() overrides host if passed with override=true', async () => {
|
|
571
|
+
const client = new MessageBoxClient_js_1.MessageBoxClient({
|
|
572
|
+
walletClient: mockWalletClient,
|
|
573
|
+
host: 'https://original-host.example'
|
|
574
|
+
});
|
|
575
|
+
expect(client.initialized).toBe(false);
|
|
576
|
+
expect(client.host).toBe('https://original-host.example');
|
|
577
|
+
await client.init('https://new-host.example');
|
|
578
|
+
expect(client.initialized).toBe(true);
|
|
579
|
+
expect(client.host).toBe('https://new-host.example');
|
|
580
|
+
});
|
|
581
|
+
it('does not anoint when advert already exists', async () => {
|
|
582
|
+
jest.spyOn(MessageBoxClient_js_1.MessageBoxClient.prototype, 'queryAdvertisements').mockResolvedValue([{
|
|
583
|
+
host: 'https://messagebox.babbage.systems'
|
|
584
|
+
}]);
|
|
585
|
+
const spy = jest.spyOn(MessageBoxClient_js_1.MessageBoxClient.prototype, 'anointHost');
|
|
586
|
+
await new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient }).init();
|
|
587
|
+
expect(spy).not.toHaveBeenCalled();
|
|
588
|
+
});
|
|
589
|
+
it('resolveHostForRecipient returns the first advertised host', async () => {
|
|
590
|
+
const client = new MessageBoxClient_js_1.MessageBoxClient({
|
|
591
|
+
walletClient: mockWalletClient,
|
|
592
|
+
host: 'https://default.box'
|
|
593
|
+
});
|
|
594
|
+
await client.init();
|
|
595
|
+
MessageBoxClient_js_1.MessageBoxClient.prototype.queryAdvertisements
|
|
596
|
+
.mockResolvedValueOnce([
|
|
597
|
+
{ host: 'https://peer.box' }, { host: 'https://second.box' }
|
|
598
|
+
]);
|
|
599
|
+
const result = await client.resolveHostForRecipient('02aa…deadbeef');
|
|
600
|
+
expect(result).toBe('https://peer.box');
|
|
601
|
+
});
|
|
602
|
+
it('resolveHostForRecipient falls back to this.host when no adverts exist', async () => {
|
|
603
|
+
const client = new MessageBoxClient_js_1.MessageBoxClient({
|
|
604
|
+
walletClient: mockWalletClient,
|
|
605
|
+
host: 'https://default.box'
|
|
606
|
+
});
|
|
607
|
+
await client.init();
|
|
608
|
+
MessageBoxClient_js_1.MessageBoxClient.prototype.queryAdvertisements
|
|
609
|
+
.mockResolvedValueOnce([]);
|
|
610
|
+
const result = await client.resolveHostForRecipient('03bb…cafef00d');
|
|
611
|
+
expect(result).toBe('https://default.box');
|
|
612
|
+
});
|
|
613
|
+
});
|
|
614
|
+
//# sourceMappingURL=MessageBoxClient.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageBoxClient.test.js","sourceRoot":"","sources":["../../../../src/__tests/MessageBoxClient.test.ts"],"names":[],"mappings":"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"}
|