diff --git a/js/modules/loki_snode_api.js b/js/modules/loki_snode_api.js index 6d04da9c8..b9d4ffa32 100644 --- a/js/modules/loki_snode_api.js +++ b/js/modules/loki_snode_api.js @@ -432,9 +432,7 @@ class LokiSnodeAPI { if (this.guardNodes.length < edKeys.length) { log.warn( - `LokiSnodeAPI::buildNewOnionPaths - could not find some guard nodes: ${ - this.guardNodes.length - }/${edKeys.length} left` + `LokiSnodeAPI::buildNewOnionPaths - could not find some guard nodes: ${this.guardNodes.length}/${edKeys.length} left` ); } } @@ -490,7 +488,10 @@ class LokiSnodeAPI { async buildNewOnionPaths() { // this function may be called concurrently make sure we only have one inflight - return primitives.allowOnlyOneAtATime('buildNewOnionPaths', this.buildNewOnionPathsWorker); + return primitives.allowOnlyOneAtATime( + 'buildNewOnionPaths', + this.buildNewOnionPathsWorker + ); } async getRandomSnodeAddress() { diff --git a/ts/receiver/receiver.ts b/ts/receiver/receiver.ts index 08ccdb3b5..4a4636bc7 100644 --- a/ts/receiver/receiver.ts +++ b/ts/receiver/receiver.ts @@ -651,8 +651,8 @@ export async function handleMessageEvent(event: any): Promise { return; } } else if (source !== ourNumber) { - // Ignore auth from our devices - conversationId = primarySource.key; + // Ignore auth from our devices + conversationId = primarySource.key; } // the conversation with the primary device of that source (can be the same as conversationOrigin) diff --git a/ts/test/session/protocols/MultiDeviceProtocol_test.ts b/ts/test/session/protocols/MultiDeviceProtocol_test.ts index 09230ca2b..ad287a3dc 100644 --- a/ts/test/session/protocols/MultiDeviceProtocol_test.ts +++ b/ts/test/session/protocols/MultiDeviceProtocol_test.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; -import { TestUtils, timeout } from '../../test-utils'; +import { TestUtils } from '../../test-utils'; import { PairingAuthorisation } from '../../../../js/modules/data'; import { MultiDeviceProtocol } from '../../../session/protocols'; import { PubKey } from '../../../session/types'; @@ -183,7 +183,7 @@ describe('MultiDeviceProtocol', () => { it('should not fetch if the refresh delay has not been met', async () => { await MultiDeviceProtocol.fetchPairingAuthorisationsIfNeeded(device); - await timeout(100); + await TestUtils.timeout(100); await MultiDeviceProtocol.fetchPairingAuthorisationsIfNeeded(device); expect(fetchPairingAuthorisationStub.callCount).to.equal( 1, @@ -202,21 +202,21 @@ describe('MultiDeviceProtocol', () => { it('should fetch again if something went wrong while fetching', async () => { fetchPairingAuthorisationStub.throws(new Error('42')); await MultiDeviceProtocol.fetchPairingAuthorisationsIfNeeded(device); - await timeout(100); + await TestUtils.timeout(100); await MultiDeviceProtocol.fetchPairingAuthorisationsIfNeeded(device); expect(fetchPairingAuthorisationStub.callCount).to.equal(2); }); it('should fetch only once if called rapidly', async () => { fetchPairingAuthorisationStub.callsFake(async () => { - await timeout(200); + await TestUtils.timeout(200); return []; }); void MultiDeviceProtocol.fetchPairingAuthorisationsIfNeeded(device); - await timeout(10); + await TestUtils.timeout(10); void MultiDeviceProtocol.fetchPairingAuthorisationsIfNeeded(device); - await timeout(200); + await TestUtils.timeout(200); expect(fetchPairingAuthorisationStub.callCount).to.equal(1); }); diff --git a/ts/test/session/protocols/SessionProtocol_test.ts b/ts/test/session/protocols/SessionProtocol_test.ts index b78d48e24..712088aa2 100644 --- a/ts/test/session/protocols/SessionProtocol_test.ts +++ b/ts/test/session/protocols/SessionProtocol_test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { SessionProtocol } from '../../../session/protocols'; import * as sinon from 'sinon'; -import { Stubs, TestUtils, timeout } from '../../test-utils'; +import { Stubs, TestUtils } from '../../test-utils'; import { UserUtil } from '../../../util'; import { SessionRequestMessage } from '../../../session/messages/outgoing'; import { TextEncoder } from 'util'; @@ -219,7 +219,7 @@ describe('SessionProtocol', () => { expect(SessionProtocol.getProcessedSessionsTimestamp()) .to.have.property('deviceid') .to.be.approximately(Date.now(), 5); - await timeout(5); + await TestUtils.timeout(5); const oldTimestamp = SessionProtocol.getProcessedSessionsTimestamp() .deviceid; await SessionProtocol.onSessionRequestProcessed(pubkey); @@ -291,7 +291,7 @@ describe('SessionProtocol', () => { it('protocol: shouldProcessSessionRequest returns false if there is a more recent sent but a less recent processed', async () => { await SessionProtocol.sendSessionRequest(resetMessage, pubkey); // adds a Date.now() entry - await timeout(100); + await TestUtils.timeout(100); await SessionProtocol.onSessionRequestProcessed(pubkey); // adds a Date.now() entry 100ms after expect( @@ -304,7 +304,7 @@ describe('SessionProtocol', () => { it('protocol: shouldProcessSessionRequest returns false if there is a more recent processed but a less recent sent', async () => { await SessionProtocol.onSessionRequestProcessed(pubkey); // adds a Date.now() entry - await timeout(100); + await TestUtils.timeout(100); await SessionProtocol.sendSessionRequest(resetMessage, pubkey); // adds a Date.now() entry 100ms after expect( diff --git a/ts/test/session/sending/PendingMessageCache_test.ts b/ts/test/session/sending/PendingMessageCache_test.ts index 128947bdb..5f806b5dc 100644 --- a/ts/test/session/sending/PendingMessageCache_test.ts +++ b/ts/test/session/sending/PendingMessageCache_test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import * as _ from 'lodash'; import { MessageUtils } from '../../../session/utils'; -import { TestUtils, timeout } from '../../../test/test-utils'; +import { TestUtils } from '../../../test/test-utils'; import { PendingMessageCache } from '../../../session/sending/PendingMessageCache'; // Equivalent to Data.StorageItem @@ -72,9 +72,9 @@ describe('PendingMessageCache', () => { await pendingMessageCacheStub.add(device, TestUtils.generateChatMessage()); // We have to timeout here otherwise it's processed too fast and messages start having the same timestamp - await timeout(5); + await TestUtils.timeout(5); await pendingMessageCacheStub.add(device, TestUtils.generateChatMessage()); - await timeout(5); + await TestUtils.timeout(5); await pendingMessageCacheStub.add(device, TestUtils.generateChatMessage()); // Verify that the message is in the cache @@ -108,7 +108,7 @@ describe('PendingMessageCache', () => { const rawMessage = MessageUtils.toRawMessage(device, message); await pendingMessageCacheStub.add(device, message); - await timeout(5); + await TestUtils.timeout(5); const one = await pendingMessageCacheStub.add( device, TestUtils.generateChatMessage(message.identifier) diff --git a/ts/test/session/utils/JobQueue_test.ts b/ts/test/session/utils/JobQueue_test.ts index 60ddd9c09..379641ae4 100644 --- a/ts/test/session/utils/JobQueue_test.ts +++ b/ts/test/session/utils/JobQueue_test.ts @@ -1,7 +1,7 @@ import chai from 'chai'; import { v4 as uuid } from 'uuid'; import { JobQueue } from '../../../session/utils/JobQueue'; -import { timeout } from '../../test-utils'; +import { TestUtils } from '../../test-utils'; // tslint:disable-next-line: no-require-imports no-var-requires const chaiAsPromised = require('chai-as-promised'); @@ -16,7 +16,7 @@ describe('JobQueue', () => { const id = 'jobId'; assert.isFalse(queue.has(id)); - const promise = queue.addWithId(id, async () => timeout(100)); + const promise = queue.addWithId(id, async () => TestUtils.timeout(100)); assert.isTrue(queue.has(id)); await promise; assert.isFalse(queue.has(id)); @@ -33,7 +33,7 @@ describe('JobQueue', () => { const queue = new JobQueue(); const mapper = async ([value, ms]: Array): Promise => queue.addWithId(uuid(), async () => { - await timeout(ms); + await TestUtils.timeout(ms); return value; }); @@ -55,12 +55,12 @@ describe('JobQueue', () => { it('should return the result of the job', async () => { const queue = new JobQueue(); const success = queue.addWithId(uuid(), async () => { - await timeout(100); + await TestUtils.timeout(100); return 'success'; }); const failure = queue.addWithId(uuid(), async () => { - await timeout(100); + await TestUtils.timeout(100); throw new Error('failed'); }); @@ -72,7 +72,7 @@ describe('JobQueue', () => { const queue = new JobQueue(); const first = queue.addWithId(uuid(), () => 'first'); const second = queue.addWithId(uuid(), async () => { - await timeout(100); + await TestUtils.timeout(100); return 'second'; }); @@ -89,7 +89,7 @@ describe('JobQueue', () => { const queue = new JobQueue(); const id = uuid(); const job = async () => { - await timeout(100); + await TestUtils.timeout(100); return 'job1'; }; @@ -104,13 +104,15 @@ describe('JobQueue', () => { const queue = new JobQueue(); const id = uuid(); - const successfullJob = queue.addWithId(id, async () => timeout(100)); + const successfullJob = queue.addWithId(id, async () => + TestUtils.timeout(100) + ); assert.isTrue(queue.has(id)); await successfullJob; assert.isFalse(queue.has(id)); const failJob = queue.addWithId(id, async () => { - await timeout(100); + await TestUtils.timeout(100); throw new Error('failed'); }); assert.isTrue(queue.has(id)); diff --git a/ts/test/test-utils/index.ts b/ts/test/test-utils/index.ts index fae05690f..d8ec69320 100644 --- a/ts/test/test-utils/index.ts +++ b/ts/test/test-utils/index.ts @@ -1,5 +1,4 @@ -import * as TestUtils from './testUtils'; +import * as TestUtils from './utils'; import * as Stubs from './stubs'; -export * from './timeout'; export { TestUtils, Stubs }; diff --git a/ts/test/test-utils/testUtils.ts b/ts/test/test-utils/testUtils.ts deleted file mode 100644 index eb9644838..000000000 --- a/ts/test/test-utils/testUtils.ts +++ /dev/null @@ -1,126 +0,0 @@ -import * as sinon from 'sinon'; -import * as crypto from 'crypto'; -import * as window from '../../window'; -import * as DataShape from '../../../js/modules/data'; -import { v4 as uuid } from 'uuid'; - -import { PubKey } from '../../../ts/session/types'; -import { - ChatMessage, - ClosedGroupChatMessage, - OpenGroupMessage, -} from '../../session/messages/outgoing'; -import { OpenGroup } from '../../session/types/OpenGroup'; - -const globalAny: any = global; -const sandbox = sinon.createSandbox(); - -// We have to do this in a weird way because Data uses module.exports -// which doesn't play well with sinon or ImportMock -// tslint:disable-next-line: no-require-imports no-var-requires -const Data = require('../../../js/modules/data'); -type DataFunction = typeof DataShape; - -/** - * Stub a function inside Data. - * - * Note: This uses a custom sandbox. - * Please call `restoreStubs()` or `stub.restore()` to restore original functionality. - */ -export function stubData(fn: K): sinon.SinonStub { - return sandbox.stub(Data, fn); -} - -type WindowValue = Partial | undefined; - -/** - * Stub a window object. - * - * Note: This uses a custom sandbox. - * Please call `restoreStubs()` or `stub.restore()` to restore original functionality. - */ -export function stubWindow( - fn: K, - value: WindowValue -) { - // tslint:disable-next-line: no-typeof-undefined - if (typeof globalAny.window === 'undefined') { - globalAny.window = {}; - } - - const set = (newValue: WindowValue) => { - globalAny.window[fn] = newValue; - }; - - const get = () => { - return globalAny.window[fn] as WindowValue; - }; - - globalAny.window[fn] = value; - - return { - get, - set, - }; -} - -export function restoreStubs() { - globalAny.window = undefined; - sandbox.restore(); -} - -export function generateFakePubKey(): PubKey { - // Generates a mock pubkey for testing - const numBytes = PubKey.PUBKEY_LEN / 2 - 1; - const hexBuffer = crypto.randomBytes(numBytes).toString('hex'); - const pubkeyString = `05${hexBuffer}`; - - return new PubKey(pubkeyString); -} - -export function generateFakePubKeys(amount: number): Array { - const numPubKeys = amount > 0 ? Math.floor(amount) : 0; - - // tslint:disable-next-line: no-unnecessary-callback-wrapper - return new Array(numPubKeys).fill(0).map(() => generateFakePubKey()); -} - -export function generateChatMessage(identifier?: string): ChatMessage { - return new ChatMessage({ - body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', - identifier: identifier ?? uuid(), - timestamp: Date.now(), - attachments: undefined, - quote: undefined, - expireTimer: undefined, - lokiProfile: undefined, - preview: undefined, - }); -} - -export function generateOpenGroupMessage(): OpenGroupMessage { - const group = new OpenGroup({ - server: 'chat.example.server', - channel: 0, - conversationId: '0', - }); - - return new OpenGroupMessage({ - timestamp: Date.now(), - group, - attachments: undefined, - preview: undefined, - body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', - quote: undefined, - }); -} - -export function generateClosedGroupMessage( - groupId?: string -): ClosedGroupChatMessage { - return new ClosedGroupChatMessage({ - identifier: uuid(), - groupId: groupId ?? generateFakePubKey().key, - chatMessage: generateChatMessage(), - }); -} diff --git a/ts/test/test-utils/utils/index.ts b/ts/test/test-utils/utils/index.ts new file mode 100644 index 000000000..7cfc3adc3 --- /dev/null +++ b/ts/test/test-utils/utils/index.ts @@ -0,0 +1,4 @@ +export * from './timeout'; +export * from './stubbing'; +export * from './pubkey'; +export * from './message'; diff --git a/ts/test/test-utils/utils/message.ts b/ts/test/test-utils/utils/message.ts new file mode 100644 index 000000000..e2e71504a --- /dev/null +++ b/ts/test/test-utils/utils/message.ts @@ -0,0 +1,48 @@ +import { + ChatMessage, + ClosedGroupChatMessage, + OpenGroupMessage, +} from '../../../session/messages/outgoing'; +import { v4 as uuid } from 'uuid'; +import { OpenGroup } from '../../../session/types'; +import { generateFakePubKey } from './pubkey'; + +export function generateChatMessage(identifier?: string): ChatMessage { + return new ChatMessage({ + body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', + identifier: identifier ?? uuid(), + timestamp: Date.now(), + attachments: undefined, + quote: undefined, + expireTimer: undefined, + lokiProfile: undefined, + preview: undefined, + }); +} + +export function generateOpenGroupMessage(): OpenGroupMessage { + const group = new OpenGroup({ + server: 'chat.example.server', + channel: 0, + conversationId: '0', + }); + + return new OpenGroupMessage({ + timestamp: Date.now(), + group, + attachments: undefined, + preview: undefined, + body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', + quote: undefined, + }); +} + +export function generateClosedGroupMessage( + groupId?: string +): ClosedGroupChatMessage { + return new ClosedGroupChatMessage({ + identifier: uuid(), + groupId: groupId ?? generateFakePubKey().key, + chatMessage: generateChatMessage(), + }); +} diff --git a/ts/test/test-utils/utils/pubkey.ts b/ts/test/test-utils/utils/pubkey.ts new file mode 100644 index 000000000..e5805b79c --- /dev/null +++ b/ts/test/test-utils/utils/pubkey.ts @@ -0,0 +1,18 @@ +import * as crypto from 'crypto'; +import { PubKey } from '../../../session/types'; + +export function generateFakePubKey(): PubKey { + // Generates a mock pubkey for testing + const numBytes = PubKey.PUBKEY_LEN / 2 - 1; + const hexBuffer = crypto.randomBytes(numBytes).toString('hex'); + const pubkeyString = `05${hexBuffer}`; + + return new PubKey(pubkeyString); +} + +export function generateFakePubKeys(amount: number): Array { + const numPubKeys = amount > 0 ? Math.floor(amount) : 0; + + // tslint:disable-next-line: no-unnecessary-callback-wrapper + return new Array(numPubKeys).fill(0).map(() => generateFakePubKey()); +} diff --git a/ts/test/test-utils/utils/stubbing.ts b/ts/test/test-utils/utils/stubbing.ts new file mode 100644 index 000000000..9391204d9 --- /dev/null +++ b/ts/test/test-utils/utils/stubbing.ts @@ -0,0 +1,60 @@ +import * as sinon from 'sinon'; +import * as crypto from 'crypto'; +import * as DataShape from '../../../../js/modules/data'; + +const globalAny: any = global; +const sandbox = sinon.createSandbox(); + +// We have to do this in a weird way because Data uses module.exports +// which doesn't play well with sinon or ImportMock +// tslint:disable-next-line: no-require-imports no-var-requires +const Data = require('../../../../js/modules/data'); +type DataFunction = typeof DataShape; + +/** + * Stub a function inside Data. + * + * Note: This uses a custom sandbox. + * Please call `restoreStubs()` or `stub.restore()` to restore original functionality. + */ +export function stubData(fn: K): sinon.SinonStub { + return sandbox.stub(Data, fn); +} + +type WindowValue = Partial | undefined; + +/** + * Stub a window object. + * + * Note: This uses a custom sandbox. + * Please call `restoreStubs()` or `stub.restore()` to restore original functionality. + */ +export function stubWindow( + fn: K, + value: WindowValue +) { + // tslint:disable-next-line: no-typeof-undefined + if (typeof globalAny.window === 'undefined') { + globalAny.window = {}; + } + + const set = (newValue: WindowValue) => { + globalAny.window[fn] = newValue; + }; + + const get = () => { + return globalAny.window[fn] as WindowValue; + }; + + globalAny.window[fn] = value; + + return { + get, + set, + }; +} + +export function restoreStubs() { + globalAny.window = undefined; + sandbox.restore(); +} diff --git a/ts/test/test-utils/timeout.ts b/ts/test/test-utils/utils/timeout.ts similarity index 100% rename from ts/test/test-utils/timeout.ts rename to ts/test/test-utils/utils/timeout.ts