UNPKG

@bsv/message-box-client

Version:

A client for P2P messaging and payments

599 lines 29.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-env jest */ const MessageBoxClient_js_1 = require("../MessageBoxClient.js"); const sdk_1 = require("@bsv/sdk"); // MOCK: WalletClient methods globally jest.spyOn(sdk_1.WalletClient.prototype, 'createHmac').mockResolvedValue({ hmac: Array.from(new Uint8Array([1, 2, 3])) }); jest.spyOn(sdk_1.WalletClient.prototype, 'getPublicKey').mockResolvedValue({ publicKey: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4' }); jest.spyOn(sdk_1.WalletClient.prototype, 'encrypt').mockResolvedValue({ ciphertext: [9, 9, 9, 9] }); jest.spyOn(sdk_1.WalletClient.prototype, 'decrypt').mockResolvedValue({ plaintext: [1, 2, 3, 4, 5] }); jest.spyOn(sdk_1.WalletClient.prototype, 'createSignature').mockResolvedValue({ signature: [1, 2, 3, 4, 5] // <-- any dummy byte array }); jest.spyOn(sdk_1.WalletClient.prototype, 'connectToSubstrate').mockImplementation(async function () { this.substrate = { createSignature: async (message) => { return Array.from(new Uint8Array([1, 2, 3])); // Return mock signature } }; }); const minimalTx = new sdk_1.Transaction(); minimalTx.addOutput({ satoshis: 1, lockingScript: new sdk_1.LockingScript([]) // ✅ must wrap in LockingScript class }); const realAtomicBEEF = minimalTx.toAtomicBEEF(); jest.spyOn(sdk_1.WalletClient.prototype, 'createAction').mockResolvedValue({ txid: 'mocked-txid', tx: realAtomicBEEF }); // MOCK: AuthFetch responses const defaultMockResponse = { json: async () => ({ status: 'success', message: 'Mocked response' }), headers: new Headers(), ok: true, status: 200 }; jest.spyOn(MessageBoxClient_js_1.MessageBoxClient.prototype, 'anointHost').mockImplementation(async () => { return { txid: 'mocked-anoint-txid' }; }); jest.spyOn(MessageBoxClient_js_1.MessageBoxClient.prototype, 'queryAdvertisements') .mockResolvedValue([]); jest.spyOn(sdk_1.AuthFetch.prototype, 'fetch') .mockResolvedValue(defaultMockResponse); // MOCK: WebSocket behavior const socketOnMap = {}; const mockSocket = { on: jest.fn((event, callback) => { socketOnMap[event] = callback; }), emit: jest.fn(), disconnect: jest.fn(), connected: true, off: jest.fn() }; jest.mock('@bsv/authsocket-client', () => ({ AuthSocketClient: jest.fn(() => mockSocket) })); // Optional: Global WebSocket override (not strictly needed with AuthSocketClient) class MockWebSocket { constructor() { this.readyState = MockWebSocket.OPEN; this.on = jest.fn(); this.send = jest.fn(); this.close = jest.fn(); } } MockWebSocket.CONNECTING = 0; MockWebSocket.OPEN = 1; MockWebSocket.CLOSING = 2; MockWebSocket.CLOSED = 3; global.WebSocket = MockWebSocket; describe('MessageBoxClient', () => { let mockWalletClient; beforeEach(() => { mockWalletClient = new sdk_1.WalletClient(); jest.clearAllMocks(); // (Optional, but if you want per-test control, you could move mocks here instead of globally.) }); const VALID_LIST_AND_READ_RESULT = { body: JSON.stringify({ status: 200, messages: [ { sender: 'mockSender', messageId: 42, body: {} }, { sender: 'mockSender', messageId: 43, body: {} } ] }) }; const VALID_ACK_RESULT = { body: JSON.stringify({ status: 200, message: 'Messages marked as acknowledged!' }) }; it('Creates an instance of the MessageBoxClient class', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); expect(messageBoxClient).toHaveProperty('host', 'https://messagebox.babbage.systems'); // Ensure the socket is initialized as undefined before connecting expect(messageBoxClient.testSocket).toBeUndefined(); }); it('Initializes WebSocket connection', async () => { await new Promise(resolve => setTimeout(resolve, 100)); const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); const connection = messageBoxClient.initializeConnection(); // Simulate server response setTimeout(() => { var _a; (_a = socketOnMap.authenticationSuccess) === null || _a === void 0 ? void 0 : _a.call(socketOnMap, { status: 'ok' }); }, 100); await expect(connection).resolves.toBeUndefined(); }, 10000); it('Falls back to HTTP when WebSocket is not initialized', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); // Bypass the real connection logic jest.spyOn(messageBoxClient, 'initializeConnection').mockImplementation(async () => { }); messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; messageBoxClient.socket = null; // Expect it to fall back to HTTP and succeed const result = await messageBoxClient.sendLiveMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: 'test_inbox', body: 'Test message' }); expect(result).toEqual({ status: 'success', message: 'Mocked response', messageId: '010203' }); }); it('Listens for live messages', async () => { var _a; const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); const connection = messageBoxClient.initializeConnection(); setTimeout(() => { var _a; (_a = socketOnMap.authenticationSuccess) === null || _a === void 0 ? void 0 : _a.call(socketOnMap, { status: 'ok' }); }, 100); await connection; const mockOnMessage = jest.fn(); await messageBoxClient.listenForLiveMessages({ messageBox: 'test_inbox', onMessage: mockOnMessage }); expect((_a = messageBoxClient.testSocket) === null || _a === void 0 ? void 0 : _a.emit).toHaveBeenCalledWith('joinRoom', '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4-test_inbox'); }, 10000); it('Sends a live message', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); const connection = messageBoxClient.initializeConnection(); // Simulate WebSocket auth success setTimeout(() => { var _a; (_a = socketOnMap.authenticationSuccess) === null || _a === void 0 ? void 0 : _a.call(socketOnMap, { status: 'ok' }); }, 100); await connection; const emitSpy = jest.spyOn(messageBoxClient.testSocket, 'emit'); // Kick off sending a message (this sets up the ack listener) const sendPromise = messageBoxClient.sendLiveMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: 'test_inbox', body: 'Test message' }); // Simulate WebSocket acknowledgment setTimeout(() => { var _a; (_a = socketOnMap['sendMessageAck-02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4-test_inbox']) === null || _a === void 0 ? void 0 : _a.call(socketOnMap, { status: 'success', messageId: 'mocked123' }); }, 100); const result = await sendPromise; // Check that WebSocket emit happened correctly expect(emitSpy).toHaveBeenCalledWith('sendMessage', expect.objectContaining({ roomId: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4-test_inbox', message: expect.objectContaining({ messageId: '010203', recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', body: expect.stringMatching(/encrypted/) }) })); // Check the resolved result expect(result).toEqual({ status: 'success', messageId: 'mocked123' }); }, 15000); it('Sends a message', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; jest.spyOn(messageBoxClient.authFetch, 'fetch').mockResolvedValue({ json: async () => ({ status: 'success', message: 'Your message has been sent!' }), headers: new Headers(), ok: true, status: 200 }); const result = await messageBoxClient.sendMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: 'test_inbox', body: { data: 'test' } }); expect(result).toHaveProperty('message', 'Your message has been sent!'); }); it('Lists available messages', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; jest.spyOn(messageBoxClient.authFetch, 'fetch').mockResolvedValue({ json: async () => JSON.parse(VALID_LIST_AND_READ_RESULT.body), headers: new Headers(), ok: true, status: 200 }); const result = await messageBoxClient.listMessages({ messageBox: 'test_inbox' }); expect(result).toEqual(JSON.parse(VALID_LIST_AND_READ_RESULT.body).messages); }); it('Acknowledges a message', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; jest.spyOn(messageBoxClient.authFetch, 'fetch').mockResolvedValue({ json: async () => JSON.parse(VALID_ACK_RESULT.body), headers: new Headers(), ok: true, status: 200 }); const result = await messageBoxClient.acknowledgeMessage({ messageIds: ['42'] }); expect(result).toEqual(200); }); it('Throws an error when sendMessage() API fails', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; jest.spyOn(messageBoxClient.authFetch, 'fetch') .mockResolvedValue({ status: 500, statusText: 'Internal Server Error', ok: false, json: async () => ({ status: 'error', description: 'Internal Server Error' }), headers: new Headers() }); await expect(messageBoxClient.sendMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: 'test_inbox', body: 'Test Message' })).rejects.toThrow('Message sending failed: HTTP 500 - Internal Server Error'); }); it('throws when every host fails', async () => { const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://primary', enableLogging: false }); await client.init(); // Pretend there are no advertised replicas jest.spyOn(client, 'queryAdvertisements').mockResolvedValue([]); // Primary host responds with 500 jest.spyOn(client.authFetch, 'fetch').mockResolvedValue({ ok: false, status: 500, statusText: 'Internal Server Error', json: async () => ({ status: 'error', description: 'DB down' }) }); await expect(client.listMessages({ messageBox: 'inbox' })) .rejects.toThrow('Failed to retrieve messages from any host'); }); it('returns [] when at least one host succeeds but has no messages', async () => { const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://primary', enableLogging: false }); await client.init(); // One failing replica, one healthy replica jest.spyOn(client, 'queryAdvertisements').mockResolvedValue([{ host: 'https://replica' }]); jest.spyOn(client.authFetch, 'fetch') .mockImplementation(async (url) => // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions url.startsWith('https://primary') ? await Promise.resolve({ ok: false, status: 500, statusText: 'Internal Server Error', json: async () => ({ status: 'error', description: 'DB down' }) }) : await Promise.resolve({ ok: true, status: 200, json: async () => ({ status: 'success', messages: [] }) })); await expect(client.listMessages({ messageBox: 'inbox' })).resolves.toEqual([]); }); it('Throws an error when acknowledgeMessage() API fails', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; jest.spyOn(messageBoxClient.authFetch, 'fetch') .mockResolvedValue({ status: 500, json: async () => ({ status: 'error', description: 'Failed to acknowledge messages' }) }); await expect(messageBoxClient.acknowledgeMessage({ messageIds: ['42'] })) .rejects.toThrow('Failed to acknowledge messages'); }); it('Emits joinRoom event and listens for incoming messages', async () => { var _a; const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); // Mock identity key properly jest.spyOn(mockWalletClient, 'getPublicKey').mockResolvedValue({ publicKey: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4' }); // Mock socket with `on` method capturing event handlers const mockSocket = { emit: jest.fn(), on: jest.fn() }; // Mock `initializeConnection` so it assigns `socket` & identity key jest.spyOn(messageBoxClient, 'initializeConnection').mockImplementation(async () => { Object.defineProperty(messageBoxClient, 'testIdentityKey', { get: () => '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4' }); Object.defineProperty(messageBoxClient, 'testSocket', { get: () => mockSocket }); messageBoxClient.socket = mockSocket; // Ensures internal socket is set messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; // Ensures identity key is set }); const onMessageMock = jest.fn(); await messageBoxClient.listenForLiveMessages({ onMessage: onMessageMock, messageBox: 'test_inbox' }); // Ensure `joinRoom` event was emitted with the correct identity key expect(mockSocket.emit).toHaveBeenCalledWith('joinRoom', '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4-test_inbox'); // Simulate receiving a message const receivedMessage = { text: 'Hello, world!' }; // Extract & invoke the callback function stored in `on` 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 if (typeof sendMessageCallback === 'function') { sendMessageCallback(receivedMessage); } // Ensure `onMessage` was called with the received message expect(onMessageMock).toHaveBeenCalledWith(receivedMessage); }); it('Handles WebSocket connection and disconnection events', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); // Simulate identity key jest.spyOn(mockWalletClient, 'getPublicKey').mockResolvedValue({ publicKey: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4' }); // Simulate connection + disconnection + auth success setTimeout(() => { var _a, _b, _c; (_a = socketOnMap.connect) === null || _a === void 0 ? void 0 : _a.call(socketOnMap); (_b = socketOnMap.disconnect) === null || _b === void 0 ? void 0 : _b.call(socketOnMap); (_c = socketOnMap.authenticationSuccess) === null || _c === void 0 ? void 0 : _c.call(socketOnMap, { status: 'ok' }); }, 100); await messageBoxClient.initializeConnection(); // Verify event listeners were registered expect(mockSocket.on).toHaveBeenCalledWith('connect', expect.any(Function)); expect(mockSocket.on).toHaveBeenCalledWith('disconnect', expect.any(Function)); }, 10000); it('throws an error when recipient is empty in sendLiveMessage', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); // Mock `initializeConnection` so it assigns `socket` & identity key jest.spyOn(messageBoxClient, 'initializeConnection').mockImplementation(async () => { Object.defineProperty(messageBoxClient, 'testIdentityKey', { get: () => '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4' }); Object.defineProperty(messageBoxClient, 'testSocket', { get: () => mockSocket }); messageBoxClient.socket = mockSocket; // Ensures internal socket is set messageBoxClient.myIdentityKey = '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4'; // Ensures identity key is set }); // Mock socket to ensure WebSocket validation does not fail const mockSocket = { emit: jest.fn() }; jest.spyOn(messageBoxClient, 'testSocket', 'get').mockReturnValue(mockSocket); await expect(messageBoxClient.sendLiveMessage({ recipient: ' ', messageBox: 'test_inbox', body: 'Test message' })).rejects.toThrow('[MB CLIENT ERROR] Recipient identity key is required'); }); it('throws an error when recipient is missing in sendMessage', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); await expect(messageBoxClient.sendMessage({ recipient: '', // Empty recipient messageBox: 'test_inbox', body: 'Test message' })).rejects.toThrow('You must provide a message recipient!'); await expect(messageBoxClient.sendMessage({ recipient: ' ', // Whitespace recipient messageBox: 'test_inbox', body: 'Test message' })).rejects.toThrow('You must provide a message recipient!'); await expect(messageBoxClient.sendMessage({ recipient: null, // Null recipient messageBox: 'test_inbox', body: 'Test message' })).rejects.toThrow('You must provide a message recipient!'); }); it('throws an error when messageBox is missing in sendMessage', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); await expect(messageBoxClient.sendMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: '', // Empty messageBox body: 'Test message' })).rejects.toThrow('You must provide a messageBox to send this message into!'); await expect(messageBoxClient.sendMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: ' ', // Whitespace messageBox body: 'Test message' })).rejects.toThrow('You must provide a messageBox to send this message into!'); await expect(messageBoxClient.sendMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: null, // Null messageBox body: 'Test message' })).rejects.toThrow('You must provide a messageBox to send this message into!'); }); it('throws an error when message body is missing in sendMessage', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); await expect(messageBoxClient.sendMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: 'test_inbox', body: '' // Empty body })).rejects.toThrow('Every message must have a body!'); await expect(messageBoxClient.sendMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: 'test_inbox', body: ' ' // Whitespace body })).rejects.toThrow('Every message must have a body!'); await expect(messageBoxClient.sendMessage({ recipient: '02b463b8ef7f03c47fba2679c7334d13e4939b8ca30dbb6bbd22e34ea3e9b1b0e4', messageBox: 'test_inbox', body: null // Null body })).rejects.toThrow('Every message must have a body!'); }); it('throws an error when messageBox is empty in listMessages', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); await expect(messageBoxClient.listMessages({ messageBox: '' // Empty messageBox })).rejects.toThrow('MessageBox cannot be empty'); await expect(messageBoxClient.listMessages({ messageBox: ' ' // Whitespace messageBox })).rejects.toThrow('MessageBox cannot be empty'); }); it('throws an error when messageIds is empty in acknowledgeMessage', async () => { const messageBoxClient = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://messagebox.babbage.systems', enableLogging: true }); await messageBoxClient.init(); await expect(messageBoxClient.acknowledgeMessage({ messageIds: [] // Empty array })).rejects.toThrow('Message IDs array cannot be empty'); await expect(messageBoxClient.acknowledgeMessage({ messageIds: undefined // Undefined value })).rejects.toThrow('Message IDs array cannot be empty'); await expect(messageBoxClient.acknowledgeMessage({ messageIds: null // Null value })).rejects.toThrow('Message IDs array cannot be empty'); await expect(messageBoxClient.acknowledgeMessage({ messageIds: 'invalid' // Not an array })).rejects.toThrow('Message IDs array cannot be empty'); }); it('Uses default host if none is provided', () => { const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient }); expect(client.initialized).toBe(false); expect(client.host).toBe('https://messagebox.babbage.systems'); }); it('Calls init() to set up a default host when missing', async () => { const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient }); expect(client.initialized).toBe(false); await client.init(); expect(client.initialized).toBe(true); expect(typeof client.host).toBe('string'); expect(client.host.length).toBeGreaterThan(0); }); it('init() overrides host if passed with override=true', async () => { const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://original-host.example' }); expect(client.initialized).toBe(false); expect(client.host).toBe('https://original-host.example'); await client.init('https://new-host.example'); expect(client.initialized).toBe(true); expect(client.host).toBe('https://new-host.example'); }); it('does not anoint when advert already exists', async () => { jest.spyOn(MessageBoxClient_js_1.MessageBoxClient.prototype, 'queryAdvertisements').mockResolvedValue([{ host: 'https://messagebox.babbage.systems' }]); const spy = jest.spyOn(MessageBoxClient_js_1.MessageBoxClient.prototype, 'anointHost'); await new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient }).init(); expect(spy).not.toHaveBeenCalled(); }); it('resolveHostForRecipient returns the first advertised host', async () => { const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://default.box' }); await client.init(); MessageBoxClient_js_1.MessageBoxClient.prototype.queryAdvertisements .mockResolvedValueOnce([ { host: 'https://peer.box' }, { host: 'https://second.box' } ]); const result = await client.resolveHostForRecipient('02aa…deadbeef'); expect(result).toBe('https://peer.box'); }); it('resolveHostForRecipient falls back to this.host when no adverts exist', async () => { const client = new MessageBoxClient_js_1.MessageBoxClient({ walletClient: mockWalletClient, host: 'https://default.box' }); await client.init(); MessageBoxClient_js_1.MessageBoxClient.prototype.queryAdvertisements .mockResolvedValueOnce([]); const result = await client.resolveHostForRecipient('03bb…cafef00d'); expect(result).toBe('https://default.box'); }); }); //# sourceMappingURL=MessageBoxClient.test.js.map