From dc329668fa189b47147af04193ae43472ce77d0b Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Tue, 18 Apr 2023 10:24:23 +1000 Subject: [PATCH] chore: fix unit tests --- package.json | 9 +- ts/session/apis/snode_api/swarmPolling.ts | 2 +- .../conversations/ConversationController.ts | 7 +- ts/session/utils/job_runners/JobRunner.ts | 5 +- ts/session/utils/sync/syncUtils.ts | 4 +- .../libsession_wrapper_contacts_test.ts | 285 ------------------ .../libsession_wrapper_test.ts | 227 ++------------ .../models/formatRowOfConversation_test.ts | 23 -- .../unit/sending/MessageSender_test.ts | 29 +- ts/test/session/unit/sogsv3/ApiUtil_test.ts | 10 +- .../unit/sogsv3/FetchCapabilities_test.ts | 2 +- .../unit/sogsv3/knownBlindedKeys_test.ts | 11 +- .../unit/swarm_polling/SwarmPolling_test.ts | 227 +------------- ts/test/session/unit/utils/Messages_test.ts | 15 +- .../session/unit/utils/OpenGroupUtils_test.ts | 36 +-- .../unit/utils/job_runner/JobRunner_test.ts | 57 +++- 16 files changed, 143 insertions(+), 806 deletions(-) diff --git a/package.json b/package.json index 9d30434a2..20d1e2cbc 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,8 @@ "format-full": "prettier --list-different --write \"*.{css,js,json,scss,ts,tsx}\" \"./**/*.{css,js,json,scss,ts,tsx}\"", "integration-test": "npx playwright test", "integration-test-snapshots": "npx playwright test -g 'profile picture' --update-snapshots", - "test": "mocha -r jsdom-global/register --recursive --exit --timeout 10000 \"./ts/test/**/*_test.js\"", + "rebuild-libsession-for-unit-tests": "cd node_modules/session_util_wrapper/ && yarn configure && yarn build && cd ../../ ", + "test": "yarn rebuild-libsession-for-unit-tests && mocha -r jsdom-global/register --recursive --exit --timeout 10000 \"./ts/test/**/*_test.js\"", "coverage": "nyc --reporter=html mocha -r jsdom-global/register --recursive --exit --timeout 10000 \"./ts/test/**/*_test.js\"", "build-release": "run-script-os", "build-release-non-linux": "yarn build-everything && cross-env SIGNAL_ENV=production electron-builder --config.extraMetadata.environment=production --publish=never --config.directories.output=release", @@ -274,11 +275,7 @@ "StartupWMClass": "Session" }, "asarUnpack": "node_modules/spellchecker/vendor/hunspell_dictionaries", - "target": [ - "deb", - "rpm", - "freebsd" - ], + "target": ["deb", "rpm", "freebsd"], "icon": "build/icon-linux.icns" }, "asarUnpack": [ diff --git a/ts/session/apis/snode_api/swarmPolling.ts b/ts/session/apis/snode_api/swarmPolling.ts index fca4d5f09..e65fe87d6 100644 --- a/ts/session/apis/snode_api/swarmPolling.ts +++ b/ts/session/apis/snode_api/swarmPolling.ts @@ -269,7 +269,7 @@ export class SwarmPolling { const messages = uniqBy(allNamespacesWithoutUserConfigIfNeeded, x => x.hash); // if all snodes returned an error (null), no need to update the lastPolledTimestamp - if (isGroup && allNamespacesWithoutUserConfigIfNeeded?.length) { + if (isGroup) { window?.log?.info( `Polled for group(${ed25519Str(pubkey.key)}):, got ${messages.length} messages back.` ); diff --git a/ts/session/conversations/ConversationController.ts b/ts/session/conversations/ConversationController.ts index 38661cc64..456ee5752 100644 --- a/ts/session/conversations/ConversationController.ts +++ b/ts/session/conversations/ConversationController.ts @@ -238,12 +238,17 @@ export class ConversationController { // remove from the wrapper the entries before we remove the roomInfos, as we won't have the required community pubkey afterwards try { await SessionUtilUserGroups.removeCommunityFromWrapper(conversation.id, conversation.id); + } catch (e) { + window?.log?.info('SessionUtilUserGroups.removeCommunityFromWrapper failed:', e); + } + + try { await SessionUtilConvoInfoVolatile.removeCommunityFromWrapper( conversation.id, conversation.id ); } catch (e) { - window?.log?.info('SessionUtilUserGroups.removeCommunityFromWrapper failed:', e); + window?.log?.info('SessionUtilConvoInfoVolatile.removeCommunityFromWrapper failed:', e); } const roomInfos = OpenGroupData.getV2OpenGroupRoom(conversation.id); diff --git a/ts/session/utils/job_runners/JobRunner.ts b/ts/session/utils/job_runners/JobRunner.ts index 5d41cc769..d9a2b7b67 100644 --- a/ts/session/utils/job_runners/JobRunner.ts +++ b/ts/session/utils/job_runners/JobRunner.ts @@ -34,7 +34,6 @@ function jobToLogId(jobRunner: JobRunnerType, job * * SyncConfigurationJob is a job which can only be planned once until it is a success. So in the queue on jobs, there can only be one SyncConfigurationJob at all times. * - * */ export class PersistedJobRunner { private isInit = false; @@ -133,6 +132,10 @@ export class PersistedJobRunner { this.currentJob = null; } + public getCurrentJobIdentifier(): string | null { + return this.currentJob?.persistedData?.identifier || null; + } + /** * if we are running a job, this call will await until the job is done and stop the queue */ diff --git a/ts/session/utils/sync/syncUtils.ts b/ts/session/utils/sync/syncUtils.ts index 8318886b4..5d61eafee 100644 --- a/ts/session/utils/sync/syncUtils.ts +++ b/ts/session/utils/sync/syncUtils.ts @@ -30,6 +30,7 @@ import { PubKey } from '../../types'; import { ConfigurationDumpSync } from '../job_runners/jobs/ConfigurationSyncDumpJob'; import { ConfigurationSync } from '../job_runners/jobs/ConfigurationSyncJob'; import { fromBase64ToArray, fromHexToArray } from '../String'; +import { getCompleteUrlFromRoom } from '../../apis/open_group_api/utils/OpenGroupUtils'; const ITEM_ID_LAST_SYNC_TIMESTAMP = 'lastSyncedTimestamp'; @@ -141,8 +142,9 @@ const getActiveOpenGroupV2CompleteUrls = async ( const urls = await Promise.all( openGroupsV2ConvoIds.map(async opengroupConvoId => { const roomInfos = OpenGroupData.getV2OpenGroupRoom(opengroupConvoId); + if (roomInfos) { - return opengroupConvoId; + return getCompleteUrlFromRoom(roomInfos); } return null; }) diff --git a/ts/test/session/unit/libsession_wrapper/libsession_wrapper_contacts_test.ts b/ts/test/session/unit/libsession_wrapper/libsession_wrapper_contacts_test.ts index c13f25a8e..e1cf49951 100644 --- a/ts/test/session/unit/libsession_wrapper/libsession_wrapper_contacts_test.ts +++ b/ts/test/session/unit/libsession_wrapper/libsession_wrapper_contacts_test.ts @@ -1,6 +1,5 @@ import { expect } from 'chai'; -import { from_hex, from_string } from 'libsodium-wrappers-sumo'; import Sinon from 'sinon'; import { ConversationModel } from '../../../../models/conversation'; import { @@ -22,290 +21,6 @@ describe('libsession_contacts', () => { // We have to disable it by filename as nodejs tries to load the module during the import step above, and fails as it is not compiled for nodejs but for electron. - it('libsession_contacts1', () => { - const edSecretKey = from_hex( - '0123456789abcdef0123456789abcdef000000000000000000000000000000004cb76fdc6d32278e3f83dbf608360ecc6b65727934b85d2fb86862ff98c46ab7' - ); - const SessionUtilWrapper = require('session_util_wrapper'); - - // Initialize a brand new, empty config because we have no dump data to deal with. - const contacts = new SessionUtilWrapper.ContactsConfigWrapperInsideWorker(edSecretKey, null); - - // We don't need to push anything, since this is an empty config - expect(contacts.needsPush()).to.be.eql(false); - expect(contacts.needsDump()).to.be.eql(false); - const real_id = '050000000000000000000000000000000000000000000000000000000000000000'; - - // Since it's empty there shouldn't be a get result. - expect(contacts.get(real_id)).to.be.null; - - const created = contacts.getOrCreate(real_id); - - expect(created).to.be.not.null; - - expect(created.id).to.be.eq(real_id); - expect(created.name).to.be.null; - expect(created.nickname).to.be.null; - expect(created.approved).to.be.eq(false); - expect(created.approvedMe).to.be.eq(false); - expect(created.blocked).to.be.eq(false); - expect(created.id).to.be.eq(real_id); - expect(created.profilePicture?.url).to.be.eq(undefined); - expect(created.profilePicture?.key).to.be.eq(undefined); - - expect(contacts.needsPush()).to.be.eql(false); - expect(contacts.needsDump()).to.be.eql(false); - - expect(contacts.push().seqno === 0); - - created.name = 'Joe'; - created.nickname = 'Joey'; - created.approved = true; - created.approvedMe = true; - contacts.set(created); - - const updated = contacts.get(real_id); - expect(updated).to.not.be.null; - expect(updated).to.not.be.undefined; - - expect(updated?.id).to.be.eq(real_id); - expect(updated?.name).to.be.eq('Joe'); - expect(updated?.nickname).to.be.eq('Joey'); - expect(updated?.approved).to.be.true; - expect(updated?.approvedMe).to.be.true; - expect(updated?.blocked).to.be.false; - - expect(updated?.profilePicture).to.be.undefined; - - const plop = new Uint8Array(32).fill(6); - created.profilePicture = { key: plop, url: 'fakeUrl' }; - contacts.set(created); - const updated2 = contacts.get(real_id); - - expect(updated2?.profilePicture?.url).to.be.deep.eq('fakeUrl'); - expect(updated2?.profilePicture?.key).to.be.deep.eq(plop); - - expect(contacts.needsPush()).to.be.eql(true); - expect(contacts.needsDump()).to.be.eql(true); - - let push1 = contacts.push(); - expect(push1.seqno).to.be.eq(1); - - // Pretend we uploaded it - contacts.confirmPushed(push1.seqno); - expect(contacts.needsPush()).to.be.eql(false); - expect(contacts.needsDump()).to.be.eql(true); - - const dump = contacts.dump(); - - const contacts2 = new SessionUtilWrapper.ContactsConfigWrapperInsideWorker(edSecretKey, dump); - - expect(contacts2.needsPush()).to.be.eql(false); - expect(contacts2.needsDump()).to.be.eql(false); - expect(contacts2.push().seqno).to.be.eq(1); - // Because we just called dump() above, to load up - // contacts2. - expect(contacts2.needsDump()).to.be.eql(false); - - const x = contacts2.get(real_id); - expect(x?.id).to.be.eq(real_id); - expect(x?.name).to.be.eq('Joe'); - expect(x?.nickname).to.be.eq('Joey'); - expect(x?.approved).to.be.true; - expect(x?.approvedMe).to.be.true; - expect(x?.blocked).to.be.false; - - const anotherId = '051111111111111111111111111111111111111111111111111111111111111111'; - contacts2.getOrCreate(anotherId); - contacts2.set({ - id: anotherId, - }); - // We're not setting any fields, but we should still keep a record of the session id - expect(contacts2.needsPush()).to.be.true; - - let push2 = contacts2.push(); - push1.seqno = push2.seqno; - push1.data = push2.data; - expect(push1.seqno).to.be.equal(2); - contacts.merge([push1.data]); - - contacts2.confirmPushed(push1.seqno); - expect(contacts.needsPush()).to.be.false; - expect(contacts.push().seqno).to.be.eq(push1.seqno); - - // Iterate through and make sure we got everything we expected - const allContacts = contacts.getAll(); - const session_ids = allContacts.map((m: any) => m.id); - const nicknames = allContacts.map((m: any) => m.nickname || '(N/A)'); - - expect(session_ids.length).to.be.eq(2); - expect(session_ids).to.be.deep.eq([real_id, anotherId]); - expect(nicknames).to.be.deep.eq(['Joey', '(N/A)']); - - // Conflict! Oh no! - - // On client 1 delete a contact: - contacts.erase(real_id); - const shouldBeErased = contacts.get(real_id); - expect(shouldBeErased).to.be.null; - - // Client 2 adds a new friend: - const third_id = '052222222222222222222222222222222222222222222222222222222222222222'; - contacts2.setNickname(third_id, 'Nickname 3'); - contacts2.setApproved(third_id, true); - contacts2.setBlocked(third_id, true); - contacts2.setProfilePicture( - third_id, - 'http://example.com/huge.bmp', - from_string('qwert\0yuio1234567890123456789012') - ); - - expect(contacts.needsPush()).to.be.true; - expect(contacts2.needsPush()).to.be.true; - - push1 = contacts.push(); - push2 = contacts2.push(); - - expect(push1.seqno).to.be.eq(push2.seqno); - expect(push1.data).to.not.be.deep.eq(push2.data); - contacts.confirmPushed(push1.seqno); - contacts2.confirmPushed(push2.seqno); - - contacts.merge([push2.data]); - expect(contacts.needsPush()).to.be.true; - - contacts2.merge([push1.data]); - expect(contacts2.needsPush()).to.be.true; - - push1 = contacts.push(); - expect(push1.seqno).to.be.eq(push2.seqno + 1); - push2 = contacts2.push(); - - expect(push1.seqno).to.be.deep.eq(push2.seqno); - expect(push1.data).to.be.deep.eq(push2.data); - - contacts.confirmPushed(push1.seqno); - contacts2.confirmPushed(push2.seqno); - - expect(contacts.needsPush()).to.be.false; - expect(contacts2.needsPush()).to.be.false; - - const allContacts2 = contacts.getAll(); - const sessionIds2 = allContacts2.map((m: any) => m.id); - const nicknames2 = allContacts2.map((m: any) => m.nickname || '(N/A)'); - - expect(sessionIds2.length).to.be.eq(2); - expect(nicknames2.length).to.be.eq(2); - expect(sessionIds2).to.be.deep.eq([anotherId, third_id]); - expect(nicknames2).to.be.deep.eq(['(N/A)', 'Nickname 3']); - }); - - it('libsession_contacts2_c', () => { - const edSecretKey = from_hex( - '0123456789abcdef0123456789abcdef000000000000000000000000000000004cb76fdc6d32278e3f83dbf608360ecc6b65727934b85d2fb86862ff98c46ab7' - ); - const SessionUtilWrapper = require('session_util_wrapper'); - - // Initialize a brand new, empty config because we have no dump data to deal with. - const contacts = new SessionUtilWrapper.ContactsConfigWrapperInsideWorker(edSecretKey, null); - - const realId = '050000000000000000000000000000000000000000000000000000000000000000'; - - expect(contacts.get(realId)).to.be.null; - const c = contacts.getOrCreate(realId); - expect(c.id).to.be.eq(realId); - expect(c.name).to.be.null; - expect(c.nickname).to.be.null; - expect(c.approved).to.be.false; - expect(c.approvedMe).to.be.false; - expect(c.blocked).to.be.false; - expect(c.profilePicture?.key).to.be.undefined; - expect(c.profilePicture?.url).to.be.undefined; - - c.name = 'Joe'; - c.nickname = 'Joey'; - c.approved = true; - c.approvedMe = true; - contacts.set(c); - - const c2 = contacts.getOrCreate(realId); - expect(c2.name).to.be.eq('Joe'); - expect(c2.nickname).to.be.eq('Joey'); - expect(c2.approved).to.be.true; - expect(c2.approvedMe).to.be.true; - expect(c2.blocked).to.be.false; - expect(c2.profilePicture?.key).to.be.undefined; - expect(c2.profilePicture?.url).to.be.undefined; - - expect(contacts.needsDump()).to.be.true; - expect(contacts.needsPush()).to.be.true; - - const push1 = contacts.push(); - expect(push1.seqno).to.be.equal(1); - - const contacts2 = new SessionUtilWrapper.ContactsConfigWrapperInsideWorker(edSecretKey, null); - - let accepted = contacts2.merge([push1.data]); - expect(accepted).to.be.equal(1); - - contacts.confirmPushed(push1.seqno); - - let c3 = contacts2.getOrCreate(realId); - expect(c3.name).to.be.eq('Joe'); - expect(c3.nickname).to.be.eq('Joey'); - expect(c3.approved).to.be.true; - expect(c3.approvedMe).to.be.true; - expect(c3.blocked).to.be.false; - expect(c3.profilePicture?.key).to.be.undefined; - expect(c3.profilePicture?.url).to.be.undefined; - - const another_id = '051111111111111111111111111111111111111111111111111111111111111111'; - c3 = contacts.getOrCreate(another_id); - expect(c3.name).to.be.null; - expect(c3.nickname).to.be.null; - expect(c3.approved).to.be.false; - expect(c3.approvedMe).to.be.false; - expect(c3.blocked).to.be.false; - - expect(c3.profilePicture?.key).to.be.undefined; - expect(c3.profilePicture?.url).to.be.undefined; - - contacts2.set(c3); - - const push2 = contacts2.push(); - accepted = contacts.merge([push2.data]); - expect(accepted).to.be.equal(1); - - const allContacts2 = contacts.getAll(); - const session_ids2 = allContacts2.map((m: any) => m.id); - const nicknames2 = allContacts2.map((m: any) => m.nickname || '(N/A)'); - - expect(session_ids2.length).to.be.eq(2); - expect(nicknames2.length).to.be.eq(2); - expect(session_ids2).to.be.deep.eq([realId, another_id]); - expect(nicknames2).to.be.deep.eq(['Joey', '(N/A)']); - - // Changing things while iterating: - // no need to support this in JS for now. - - const allContacts3 = contacts.getAll(); - let deletions = 0; - let non_deletions = 0; - allContacts3.forEach((contact: any) => { - if (contact.id !== realId) { - contacts.erase(contact.id); - deletions++; - } else { - non_deletions++; - } - }); - - expect(deletions).to.be.eq(1); - expect(non_deletions).to.be.eq(1); - expect(contacts.get(realId)).to.exist; - expect(contacts.get(another_id)).to.be.null; - }); - describe('filter contacts for wrapper', () => { const ourNumber = '051234567890acbdef'; const validArgs = { diff --git a/ts/test/session/unit/libsession_wrapper/libsession_wrapper_test.ts b/ts/test/session/unit/libsession_wrapper/libsession_wrapper_test.ts index a43d2317a..27c837038 100644 --- a/ts/test/session/unit/libsession_wrapper/libsession_wrapper_test.ts +++ b/ts/test/session/unit/libsession_wrapper/libsession_wrapper_test.ts @@ -1,217 +1,24 @@ import { expect } from 'chai'; - -import { stringToUint8Array } from '../../../../session/utils/String'; -import { from_hex, from_string, to_hex } from 'libsodium-wrappers-sumo'; -import { concatUInt8Array } from '../../../../session/crypto'; - -// tslint:disable: chai-vague-errors no-unused-expression no-http-string no-octal-literal whitespace no-require-imports variable-name - -const fakeKey32 = from_string('secret78901234567890123456789012'); +import { SessionUtilUserProfile } from '../../../../session/utils/libsession/libsession_utils_user_profile'; +import Sinon from 'sinon'; +import { UserUtils } from '../../../../session/utils'; +import { TestUtils } from '../../../test-utils'; describe('libsession_wrapper', () => { - it('libsession_user', () => { - // Note: To run this test, you need to compile the libsession wrapper for node (and not for electron). - // To do this, you can cd to the node_module/libsession_wrapper folder and do - // yarn configure && yarn build - // once that is done, you can rename this file and remove the _skip suffix so that test is run. - - // We have to disable it by filename as nodejs tries to load the module during the import step above, and fails as it is not compiled for nodejs but for electron. - - const edSecretKey = from_hex( - '0123456789abcdef0123456789abcdef000000000000000000000000000000004cb76fdc6d32278e3f83dbf608360ecc6b65727934b85d2fb86862ff98c46ab7' - ); - const SessionUtilWrapper = require('session_util_wrapper'); - - // Initialize a brand new, empty config because we have no dump data to deal with. - const conf = new SessionUtilWrapper.UserConfigWrapperInsideWorker(edSecretKey, null); - - // We don't need to push anything, since this is an empty config - expect(conf.needsPush()).to.be.eql(false); - expect(conf.needsDump()).to.be.eql(false); - - // Since it's empty there shouldn't be a name. - expect(conf.getName()).to.be.null; - - let pushResult = conf.push(); - - expect(pushResult.seqno).to.be.eq(0); - expect(pushResult.data.length).to.be.eq(256); - - expect(conf.storageNamespace()).to.be.eq(2); - expect(to_hex(pushResult.data)).to.be.deep.eq( - '9ffb5347e061ac40d937ae4f1a890031475bdc11653f94c8ae1d516ffda71d9ee9cdaf9fbaeb15d835cdc7b3b6ecc120361f004ff172dd5e757c80ede10e88945536e6841255a7bca73664ab8a0607fcfe2579c05bb3d9d4b34ac1de2921e703783ce39e317a512cb9d4e3b59176cbde47b5ba24a03065bf8fefe3e8ca2609e0ad10c7c9c3f81dc6d3a399bda0c190e8a228d0acb22863ab84c2d0c411be74dac4de1f8bc18539635db01ea1ef7f28e505703d67786cb419690edd4bd8c92926fc1d6449eaccc31d7d9639e1b36222e5672b87d1e34b7860308c3f40b3997f39fecf6ceb889323826fa69e001816307799fc9fed302a90faa1e43f7cd7367c3c' - ); - - // This should also be unset: - const picResult = conf.getProfilePicture(); - expect(picResult.url).to.be.null; - expect(picResult.key).to.be.null; - - // Now let's go set a profile name and picture: - conf.setProfilePicture('http://example.org/omg-pic-123.bmp', new Uint8Array(fakeKey32)); - expect(conf.getProfilePicture().key).to.be.deep.eq(new Uint8Array(fakeKey32)); - - conf.setName('Kallie'); - - // Retrieve them just to make sure they set properly: - const name = conf.getName(); - - expect(name).to.be.not.null; - expect(name).to.be.eq('Kallie'); - - const picture = conf.getProfilePicture(); - - expect(picture.url).to.be.eq('http://example.org/omg-pic-123.bmp'); - expect(picture.key).to.be.deep.eq(new Uint8Array(fakeKey32)); - - // Since we've made changes, we should need to push new config to the swarm, *and* should need - // to dump the updated state: - - expect(conf.needsDump()).to.be.true; - expect(conf.needsPush()).to.be.true; - - // incremented since we made changes (this only increments once between - // dumps; even though we changed two fields here). - pushResult = conf.push(); - expect(pushResult.seqno).to.be.eq(1); - - const expHash0 = from_hex('ea173b57beca8af18c3519a7bbf69c3e7a05d1c049fa9558341d8ebb48b0c965'); - - const expPush1Start = - 'd1:#i1e1:&d1:n6:Kallie1:p34:http://example.org/omg-pic-123.bmp1:q32:secret78901234567890123456789012e1: { + Sinon.restore(); + }); - conf.dump(); - conf2.dump(); - // (store in db) + it('isUserProfileToStoreInWrapper returns true if thats our convo', () => { + const us = TestUtils.generateFakePubKeyStr(); + Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(us); + expect(SessionUtilUserProfile.isUserProfileToStoreInWrapper(us)).to.be.true; + }); - expect(conf.needsPush()).to.be.false; - expect(conf.needsDump()).to.be.false; - expect(conf2.needsPush()).to.be.false; - expect(conf2.needsDump()).to.be.false; + it('isUserProfileToStoreInWrapper returns false if thats NOT our convo', () => { + const us = TestUtils.generateFakePubKeyStr(); + const notUs = TestUtils.generateFakePubKeyStr(); + Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(us); + expect(SessionUtilUserProfile.isUserProfileToStoreInWrapper(notUs)).to.be.false; }); }); diff --git a/ts/test/session/unit/models/formatRowOfConversation_test.ts b/ts/test/session/unit/models/formatRowOfConversation_test.ts index f77cbe65a..4efc4c9b3 100644 --- a/ts/test/session/unit/models/formatRowOfConversation_test.ts +++ b/ts/test/session/unit/models/formatRowOfConversation_test.ts @@ -78,29 +78,6 @@ describe('formatRowOfConversation', () => { }); }); - describe('mentionedUs', () => { - it('initialize mentionedUs if they are not given', () => { - expect(formatRowOfConversation({}, 'test', 0, false)).to.have.deep.property( - 'mentionedUs', - false - ); - }); - - it('do not override mentionedUs if they are set in the row as integer: true', () => { - expect(formatRowOfConversation({ mentionedUs: 1 }, 'test', 0, false)).to.have.deep.property( - 'mentionedUs', - true - ); - }); - - it('do not override mentionedUs if they are set in the row as integer: false', () => { - expect(formatRowOfConversation({ mentionedUs: 0 }, 'test', 0, false)).to.have.deep.property( - 'mentionedUs', - false - ); - }); - }); - describe('isKickedFromGroup', () => { it('initialize isKickedFromGroup if they are not given', () => { expect(formatRowOfConversation({}, 'test', 0, false)).to.have.deep.property( diff --git a/ts/test/session/unit/sending/MessageSender_test.ts b/ts/test/session/unit/sending/MessageSender_test.ts index 237e56b61..110b4cb5c 100644 --- a/ts/test/session/unit/sending/MessageSender_test.ts +++ b/ts/test/session/unit/sending/MessageSender_test.ts @@ -19,15 +19,22 @@ import { MessageUtils, UserUtils } from '../../../../session/utils'; import { TestUtils } from '../../../test-utils'; import { stubCreateObjectUrl, stubData, stubUtilWorker } from '../../../test-utils/utils'; import { TEST_identityKeyPair } from '../crypto/MessageEncrypter_test'; +import { fromBase64ToArrayBuffer } from '../../../../session/utils/String'; describe('MessageSender', () => { afterEach(() => { sinon.restore(); }); - beforeEach(() => { + beforeEach(async () => { TestUtils.stubWindowLog(); TestUtils.stubWindowFeatureFlags(); + getConversationController().reset(); + TestUtils.stubData('getItemById').resolves(); + + stubData('getAllConversations').resolves([]); + stubData('saveConversation').resolves(); + await getConversationController().load(); }); // tslint:disable-next-line: max-func-body-length @@ -114,9 +121,13 @@ describe('MessageSender', () => { await MessageSender.send(rawMessage, 3, 10); const args = sessionMessageAPISendStub.getCall(0).args; - expect(args[0]).to.equal(device.key); + expect(args[1]).to.equal(device.key); + const firstArg = args[0]; + expect(firstArg.length).to.equal(1); // expect(args[3]).to.equal(visibleMessage.timestamp); the timestamp is overwritten on sending by the network clock offset - expect(args[2]).to.equal(visibleMessage.ttl()); + expect(firstArg[0].ttl).to.equal(visibleMessage.ttl()); + expect(firstArg[0].pubkey).to.equal(device.key); + expect(firstArg[0].namespace).to.equal(SnodeNamespaces.UserMessages); }); it('should correctly build the envelope and override the timestamp', async () => { @@ -135,8 +146,10 @@ describe('MessageSender', () => { Sinon.stub(GetNetworkTime, 'getLatestTimestampOffset').returns(offset); await MessageSender.send(rawMessage, 3, 10); - const data = sessionMessageAPISendStub.getCall(0).args[1]; - const webSocketMessage = SignalService.WebSocketMessage.decode(data); + const firstArg = sessionMessageAPISendStub.getCall(0).args[0]; + const { data64 } = firstArg[0]; + const data = fromBase64ToArrayBuffer(data64); + const webSocketMessage = SignalService.WebSocketMessage.decode(new Uint8Array(data)); expect(webSocketMessage.request?.body).to.not.equal( undefined, 'Request body should not be undefined' @@ -187,8 +200,10 @@ describe('MessageSender', () => { ); await MessageSender.send(rawMessage, 3, 10); - const data = sessionMessageAPISendStub.getCall(0).args[1]; - const webSocketMessage = SignalService.WebSocketMessage.decode(data); + const firstArg = sessionMessageAPISendStub.getCall(0).args[0]; + const { data64 } = firstArg[0]; + const data = fromBase64ToArrayBuffer(data64); + const webSocketMessage = SignalService.WebSocketMessage.decode(new Uint8Array(data)); expect(webSocketMessage.request?.body).to.not.equal( undefined, 'Request body should not be undefined' diff --git a/ts/test/session/unit/sogsv3/ApiUtil_test.ts b/ts/test/session/unit/sogsv3/ApiUtil_test.ts index 888cb82c6..68f9464f1 100644 --- a/ts/test/session/unit/sogsv3/ApiUtil_test.ts +++ b/ts/test/session/unit/sogsv3/ApiUtil_test.ts @@ -11,6 +11,8 @@ import { import { getOpenGroupV2ConversationId } from '../../../../session/apis/open_group_api/utils/OpenGroupUtils'; import { getConversationController } from '../../../../session/conversations'; import { stubData, stubOpenGroupData, stubWindowLog } from '../../../test-utils/utils'; +import { UserUtils } from '../../../../session/utils'; +import { TestUtils } from '../../../test-utils'; describe('APIUtils', () => { beforeEach(() => { @@ -115,8 +117,8 @@ describe('APIUtils', () => { it('returns false if there no rooms matching that serverURL with http prefix', () => { expect(hasExistingOpenGroup('http://1.1.1.1', 'roomId')).to.be.false; expect(hasExistingOpenGroup('http://1.1.1.1:4433', 'roomId')).to.be.false; - expect(hasExistingOpenGroup('http://plop.com:4433', 'roomId')).to.be.false; - expect(hasExistingOpenGroup('https://plop.com', 'roomId')).to.be.false; + expect(hasExistingOpenGroup('http://whatever.com:4433', 'roomId')).to.be.false; + expect(hasExistingOpenGroup('https://whatever.com', 'roomId')).to.be.false; }); }); }); @@ -135,6 +137,10 @@ describe('APIUtils', () => { getV2OpenGroupRoomsByServerUrl = stubOpenGroupData('getV2OpenGroupRoomsByServerUrl'); getConversationController().reset(); + Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').returns( + TestUtils.generateFakePubKeyStr() + ); + await getConversationController().load(); const convoOurIp = await getConversationController().getOrCreateAndWait( diff --git a/ts/test/session/unit/sogsv3/FetchCapabilities_test.ts b/ts/test/session/unit/sogsv3/FetchCapabilities_test.ts index 48bb64676..45d138d32 100644 --- a/ts/test/session/unit/sogsv3/FetchCapabilities_test.ts +++ b/ts/test/session/unit/sogsv3/FetchCapabilities_test.ts @@ -33,7 +33,7 @@ describe('FetchCapabilities', () => { }); it('return null if given object without cap field ', () => { - expect(parseCapabilities({ plop: [] })).to.be.deep.eq(null); + expect(parseCapabilities({ invalid: [] })).to.be.deep.eq(null); }); it('return valid if given one cap ', () => { diff --git a/ts/test/session/unit/sogsv3/knownBlindedKeys_test.ts b/ts/test/session/unit/sogsv3/knownBlindedKeys_test.ts index 40a259b50..ec2a9f8e6 100644 --- a/ts/test/session/unit/sogsv3/knownBlindedKeys_test.ts +++ b/ts/test/session/unit/sogsv3/knownBlindedKeys_test.ts @@ -23,6 +23,7 @@ import { getConversationController } from '../../../../session/conversations'; import { LibSodiumWrappers } from '../../../../session/crypto'; import { UserUtils } from '../../../../session/utils'; import { expectAsyncToThrow, stubData, stubWindowLog } from '../../../test-utils/utils'; +import { TestUtils } from '../../../test-utils'; // tslint:disable: chai-vague-errors @@ -72,7 +73,7 @@ describe('knownBlindedKeys', () => { }); it('loadFromDb with invalid json', async () => { - getItemById.resolves({ id: '', value: 'plop invalid json' }); + getItemById.resolves({ id: '', value: 'invalid json content' }); await loadKnownBlindedKeys(); expect(TEST_getCachedBlindedKeys()).to.deep.eq([]); }); @@ -481,14 +482,17 @@ describe('knownBlindedKeys', () => { describe('when not in cache', () => { beforeEach(async () => { getConversationController().reset(); + getItemById.resolves(); stubData('getAllConversations').resolves([]); stubData('saveConversation').resolves(); + Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').returns( + TestUtils.generateFakePubKeyStr() + ); await getConversationController().load(); }); it('does iterate over all the conversations and find the first one matching (fails)', async () => { - getItemById.resolves(); await loadKnownBlindedKeys(); const shouldBeWrittenToDb = { blindedId: knownBlindingMatch.blindedId, @@ -510,7 +514,6 @@ describe('knownBlindedKeys', () => { }); it('does iterate over all the conversations and find the first one matching (passes)', async () => { - getItemById.resolves(); await loadKnownBlindedKeys(); // adding a private conversation with a known match of the blinded pubkey we have await getConversationController().getOrCreateAndWait( @@ -543,7 +546,6 @@ describe('knownBlindedKeys', () => { }); it('does iterate over all the conversations but is not approved so must fail', async () => { - getItemById.resolves(); await loadKnownBlindedKeys(); // adding a private conversation with a known match of the blinded pubkey we have const convo = await getConversationController().getOrCreateAndWait( @@ -562,7 +564,6 @@ describe('knownBlindedKeys', () => { }); it('does iterate over all the conversations but is not private so must fail: group', async () => { - getItemById.resolves(); await loadKnownBlindedKeys(); // adding a private conversation with a known match of the blinded pubkey we have const convo = await getConversationController().getOrCreateAndWait( diff --git a/ts/test/session/unit/swarm_polling/SwarmPolling_test.ts b/ts/test/session/unit/swarm_polling/SwarmPolling_test.ts index 2e804da0f..6060d4ae6 100644 --- a/ts/test/session/unit/swarm_polling/SwarmPolling_test.ts +++ b/ts/test/session/unit/swarm_polling/SwarmPolling_test.ts @@ -295,7 +295,7 @@ describe('SwarmPolling', () => { ConversationTypeEnum.GROUP ); - convo.set('active_at', 1); // really old + convo.set('active_at', 1); // really old, but active const groupConvoPubkey = PubKey.cast(convo.id as string); swarmPolling.addGroupId(groupConvoPubkey); @@ -451,230 +451,5 @@ describe('SwarmPolling', () => { }); }); }); - - describe('group v3', () => { - it('does run for group pubkey on start no matter the recent timestamp ', async () => { - const convo = getConversationController().getOrCreate( - TestUtils.generateFakeClosedGroupV3PkStr(), - ConversationTypeEnum.GROUPV3 - ); - convo.set('active_at', Date.now()); - const groupConvoPubkey = PubKey.cast(convo.id as string); - swarmPolling.addGroupId(groupConvoPubkey); - await swarmPolling.start(true); - - // our pubkey will be polled for, hence the 2 - expect(pollOnceForKeySpy.callCount).to.eq(2); - expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]); - }); - - it('does run for groupv3 pubkey on start no matter the recent timestamp ', async () => { - const convo = getConversationController().getOrCreate( - TestUtils.generateFakeClosedGroupV3PkStr(), - ConversationTypeEnum.GROUPV3 - ); - convo.set('active_at', Date.now()); - const groupConvoPubkey = PubKey.cast(convo.id as string); - swarmPolling.addGroupId(groupConvoPubkey); - await swarmPolling.start(true); - - // our pubkey will be polled for, hence the 2 - expect(pollOnceForKeySpy.callCount).to.eq(2); - expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]); - }); - - it('does only poll from -10 for closed groups if HF >= 19.1 ', async () => { - const convo = getConversationController().getOrCreate( - TestUtils.generateFakeClosedGroupV3PkStr(), - ConversationTypeEnum.GROUPV3 - ); - getItemByIdStub.restore(); - getItemByIdStub = TestUtils.stubData('getItemById'); - getItemByIdStub - .withArgs('hasSeenHardfork190') - .resolves({ id: 'hasSeenHardfork190', value: true }) - .withArgs('hasSeenHardfork191') - .resolves({ id: 'hasSeenHardfork191', value: true }); - - convo.set('active_at', 1); - const groupConvoPubkey = PubKey.cast(convo.id as string); - swarmPolling.addGroupId(groupConvoPubkey); - - await swarmPolling.start(true); - - // our pubkey will be polled for, hence the 2 - expect(pollOnceForKeySpy.callCount).to.eq(2); - expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]); - getItemByIdStub.restore(); - getItemByIdStub = TestUtils.stubData('getItemById'); - - getItemByIdStub.resolves(); - }); - - it('does run for group pubkey on start but not another time if activeAt is old ', async () => { - const convo = getConversationController().getOrCreate( - TestUtils.generateFakeClosedGroupV3PkStr(), - ConversationTypeEnum.GROUPV3 - ); - - convo.set('active_at', 1); // really old - const groupConvoPubkey = PubKey.cast(convo.id as string); - swarmPolling.addGroupId(groupConvoPubkey); - - // this calls the stub 2 times, one for our direct pubkey and one for the group - await swarmPolling.start(true); - - // this should only call the stub one more time: for our direct pubkey but not for the group pubkey - await swarmPolling.pollForAllKeys(); - - expect(pollOnceForKeySpy.callCount).to.eq(3); - expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]); - expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]); - }); - - it('does run twice if activeAt less than one hour ', async () => { - const convo = getConversationController().getOrCreate( - TestUtils.generateFakeClosedGroupV3PkStr(), - ConversationTypeEnum.GROUPV3 - ); - - convo.set('active_at', Date.now()); - const groupConvoPubkey = PubKey.cast(convo.id as string); - swarmPolling.addGroupId(groupConvoPubkey); - await swarmPolling.start(true); - clock.tick(9000); - // no need to do that as the tick will trigger a call in all cases after 5 secs await swarmPolling.pollForAllKeys(); - /** this is not easy to explain, but - * - during the swarmPolling.start, we get two calls to pollOnceForKeySpy (one for our id and one for group od) - * - the clock ticks 9sec, and another call of pollOnceForKeySpy get started, but as we do not await them, this test fails. - * the only fix is to restore the clock and force the a small sleep to let the thing run in bg - */ - clock.restore(); - await sleepFor(10); - - expect(pollOnceForKeySpy.callCount).to.eq(4); - expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]); - expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.getCall(3).args).to.deep.eq([groupConvoPubkey, true, [-10]]); - }); - - it('does run twice if activeAt is inactive and we tick longer than 2 minutes', async () => { - const convo = getConversationController().getOrCreate( - TestUtils.generateFakeClosedGroupV3PkStr(), - ConversationTypeEnum.GROUPV3 - ); - - pollOnceForKeySpy.resetHistory(); - convo.set('active_at', Date.now()); - const groupConvoPubkey = PubKey.cast(convo.id as string); - swarmPolling.addGroupId(groupConvoPubkey); - // this call the stub two times already, one for our direct pubkey and one for the group - await swarmPolling.start(true); - const timeToTick = 3 * 60 * 1000; - swarmPolling.forcePolledTimestamp(groupConvoPubkey, Date.now() - timeToTick); - // more than week old, so inactive group but we have to tick after more than 2 min - convo.set('active_at', Date.now() - 7 * 25 * 3600 * 1000); - clock.tick(timeToTick); - /** this is not easy to explain, but - * - during the swarmPolling.start, we get two calls to pollOnceForKeySpy (one for our id and one for group od) - * - the clock ticks 9sec, and another call of pollOnceForKeySpy get started, but as we do not await them, this test fails. - * the only fix is to restore the clock and force the a small sleep to let the thing run in bg - */ - clock.restore(); - await sleepFor(10); - // we should have two more calls here, so 4 total. - expect(pollOnceForKeySpy.callCount).to.eq(4); - expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]); - expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true, [-10]]); - }); - - it('does run once only if group is inactive and we tick less than 2 minutes ', async () => { - const convo = getConversationController().getOrCreate( - TestUtils.generateFakeClosedGroupV3PkStr(), - ConversationTypeEnum.GROUPV3 - ); - pollOnceForKeySpy.resetHistory(); - - convo.set('active_at', Date.now()); - const groupConvoPubkey = PubKey.cast(convo.id as string); - swarmPolling.addGroupId(groupConvoPubkey); - await swarmPolling.start(true); - - // more than a week old, we should not tick after just 5 seconds - convo.set('active_at', Date.now() - 7 * 24 * 3600 * 1000 - 3600 * 1000); - - clock.tick(1 * 60 * 1000); - - // we should have only one more call here, the one for our direct pubkey fetch - expect(pollOnceForKeySpy.callCount).to.eq(3); - expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]); // this one comes from the swarmPolling.start - expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]); - }); - - describe('multiple runs', () => { - let convo: ConversationModel; - let groupConvoPubkey: PubKey; - - beforeEach(async () => { - convo = getConversationController().getOrCreate( - TestUtils.generateFakeClosedGroupV3PkStr(), - ConversationTypeEnum.GROUPV3 - ); - - convo.set('active_at', Date.now()); - groupConvoPubkey = PubKey.cast(convo.id as string); - swarmPolling.addGroupId(groupConvoPubkey); - await swarmPolling.start(true); - }); - - it('does run twice if activeAt is less than 2 days', async () => { - pollOnceForKeySpy.resetHistory(); - // less than 2 days old, this is an active group - convo.set('active_at', Date.now() - 2 * 24 * 3600 * 1000 - 3600 * 1000); - - const timeToTick = 6 * 1000; - - swarmPolling.forcePolledTimestamp(convo.id, timeToTick); - // we tick more than 5 sec - clock.tick(timeToTick); - - await swarmPolling.pollForAllKeys(); - // we have 4 calls total. 2 for our direct promises run each 5 seconds, and 2 for the group pubkey active (so run every 5 sec too) - expect(pollOnceForKeySpy.callCount).to.eq(4); - // first two calls are our pubkey - expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]); - - expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true, [-10]]); - }); - - it('does run twice if activeAt is more than 2 days old and we tick more than one minute ', async () => { - pollOnceForKeySpy.resetHistory(); - convo.set('active_at', Date.now() - 2 * 25 * 3600 * 1000); // medium active - - const timeToTick = 65 * 1000; - swarmPolling.forcePolledTimestamp(convo.id, timeToTick); - - clock.tick(timeToTick); // should tick twice more (one more our direct pubkey and one for the group) - - await swarmPolling.pollForAllKeys(); - expect(pollOnceForKeySpy.callCount).to.eq(4); - - // first two calls are our pubkey - expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]); - expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]); - expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true, [-10]]); - }); - }); - }); }); }); diff --git a/ts/test/session/unit/utils/Messages_test.ts b/ts/test/session/unit/utils/Messages_test.ts index 9ec200211..0e2822b95 100644 --- a/ts/test/session/unit/utils/Messages_test.ts +++ b/ts/test/session/unit/utils/Messages_test.ts @@ -251,6 +251,9 @@ describe('Message Utils', () => { stubData('getAllConversations').resolves([]); stubData('saveConversation').resolves(); stubOpenGroupData('getAllV2OpenGroupRooms').resolves(); + TestUtils.stubData('getItemById').callsFake(async () => { + return { value: '[]' }; + }); getConversationController().reset(); await getConversationController().load(); @@ -271,8 +274,9 @@ describe('Message Utils', () => { ConversationTypeEnum.PRIVATE ); - const convoId3 = getOpenGroupV2ConversationId('chat-dev2.lokinet.org', 'fish'); - const convoId4 = getOpenGroupV2ConversationId('chat-dev3.lokinet.org', 'fish2'); + const convoId3 = getOpenGroupV2ConversationId('http://chat-dev2.lokinet.org', 'fish'); + const convoId4 = getOpenGroupV2ConversationId('http://chat-dev3.lokinet.org', 'fish2'); + const convoId5 = getOpenGroupV2ConversationId('http://chat-dev3.lokinet.org', 'fish3'); const convo3 = await getConversationController().getOrCreateAndWait( convoId3, @@ -284,7 +288,7 @@ describe('Message Utils', () => { .returns(null) .withArgs(convoId3) .returns({ - serverUrl: 'chat-dev2.lokinet.org', + serverUrl: 'http://chat-dev2.lokinet.org', roomId: 'fish', serverPublicKey: 'serverPublicKey', } as OpenGroupV2Room); @@ -297,7 +301,7 @@ describe('Message Utils', () => { await OpenGroupData.opengroupRoomsLoad(); const convo5 = await getConversationController().getOrCreateAndWait( - convoId4, + convoId5, ConversationTypeEnum.GROUP ); convo5.set({ active_at: 0 }); @@ -308,11 +312,12 @@ describe('Message Utils', () => { ); const convos = getConversationController().getConversations(); + //convoID3 is active but 4 and 5 are not const configMessage = await getCurrentConfigurationMessage(convos); expect(configMessage.activeOpenGroups.length).to.equal(1); expect(configMessage.activeOpenGroups[0]).to.equal( // tslint:disable-next-line: no-http-string - 'chat-dev2.lokinet.org/fish?public_key=serverPublicKey' + 'http://chat-dev2.lokinet.org/fish?public_key=serverPublicKey' ); }); }); diff --git a/ts/test/session/unit/utils/OpenGroupUtils_test.ts b/ts/test/session/unit/utils/OpenGroupUtils_test.ts index a424cc4c8..ecd6b507e 100644 --- a/ts/test/session/unit/utils/OpenGroupUtils_test.ts +++ b/ts/test/session/unit/utils/OpenGroupUtils_test.ts @@ -14,21 +14,21 @@ chai.use(chaiAsPromised as any); describe('OpenGroupUtils', () => { describe('prefixify', () => { it('should just return if http:// is as prefix', () => { - expect(prefixify('http://plop.com')).to.be.equal('http://plop.com'); + expect(prefixify('http://whatever.com')).to.be.equal('http://whatever.com'); }); it('should just return if https:// is as prefix', () => { - expect(prefixify('https://plop.com')).to.be.equal('https://plop.com'); + expect(prefixify('https://whatever.com')).to.be.equal('https://whatever.com'); }); it('should just return if http:// is as prefix ', () => { - expect(prefixify('http://plop.com')).to.be.equal('http://plop.com'); + expect(prefixify('http://whatever.com')).to.be.equal('http://whatever.com'); }); it('should just return if https:// is as prefix', () => { - expect(prefixify('https://plop.com')).to.be.equal('https://plop.com'); + expect(prefixify('https://whatever.com')).to.be.equal('https://whatever.com'); }); it('should prefix with http if ssl is false and no prefix', () => { - expect(prefixify('plop.com')).to.be.equal('http://plop.com'); + expect(prefixify('whatever.com')).to.be.equal('http://whatever.com'); }); }); @@ -37,7 +37,7 @@ describe('OpenGroupUtils', () => { it('throws if roomId is too long 64 ', () => { expect(() => { getOpenGroupV2ConversationId( - 'http://plop.com', + 'http://whatever.com', '012345678901234567890#1234567!89012345678901234567890123456789fg01234' ); }).to.throw('getOpenGroupV2ConversationId: Invalid roomId'); @@ -45,37 +45,37 @@ describe('OpenGroupUtils', () => { it('throws if roomId is too short ', () => { expect(() => { - getOpenGroupV2ConversationId('http://plop.com', ''); + getOpenGroupV2ConversationId('http://whatever.com', ''); }).to.throw('getOpenGroupV2ConversationId: Invalid roomId'); }); it('throws if roomId is has forbidden chars ', () => { expect(() => { - getOpenGroupV2ConversationId('http://plop.com', '1&%^%'); + getOpenGroupV2ConversationId('http://whatever.com', '1&%^%'); }).to.throw('getOpenGroupV2ConversationId: Invalid roomId'); }); }); it('doesnt throw if roomId and serverUrl are valid ', () => { expect(() => { - getOpenGroupV2ConversationId('http://127.0.0.1/', 'plop1234'); + getOpenGroupV2ConversationId('http://127.0.0.1/', 'whatever1234'); }).to.not.throw(); }); it('doesnt throw if roomId and serverUrl are valid with port', () => { expect(() => { - getOpenGroupV2ConversationId('http://127.0.0.1:22/', 'plop1234'); + getOpenGroupV2ConversationId('http://127.0.0.1:22/', 'whatever1234'); }).to.not.throw(); }); it('doesnt throw if roomId and serverUrl are valid with port', () => { expect(() => { - getOpenGroupV2ConversationId('https://opengroup.com/', 'plop1234'); + getOpenGroupV2ConversationId('https://opengroup.com/', 'whatever1234'); }).to.not.throw(); }); it('throw if serverUrl is no url', () => { expect(() => { - getOpenGroupV2ConversationId('opengroup', 'plop1234'); + getOpenGroupV2ConversationId('opengroup', 'whatever1234'); }).to.throw(); }); }); @@ -84,17 +84,17 @@ describe('OpenGroupUtils', () => { it('doesnt throw if roomId and serverUrl are valid with port', () => { expect( getCompleteUrlFromRoom({ - roomId: 'plop1234', + roomId: 'whatever1234', serverPublicKey: '05123456789', serverUrl: 'https://example.org', }) - ).to.be.eq('https://example.org/plop1234?public_key=05123456789'); + ).to.be.eq('https://example.org/whatever1234?public_key=05123456789'); }); it('throws if pubkey is empty', () => { expect(() => getCompleteUrlFromRoom({ - roomId: 'plop1234', + roomId: 'whatever1234', serverPublicKey: '', serverUrl: 'https://example.org', }) @@ -104,7 +104,7 @@ describe('OpenGroupUtils', () => { it('throws if serverUrl is empty', () => { expect(() => getCompleteUrlFromRoom({ - roomId: 'plop1234', + roomId: 'whatever1234', serverPublicKey: '05123456789', serverUrl: '', }) @@ -123,7 +123,7 @@ describe('OpenGroupUtils', () => { it('throws if pubkey is null', () => { expect(() => getCompleteUrlFromRoom({ - roomId: 'plop1234', + roomId: 'whatever1234', serverPublicKey: null as any, serverUrl: 'https://example.org', }) @@ -133,7 +133,7 @@ describe('OpenGroupUtils', () => { it('throws if serverUrl is null', () => { expect(() => getCompleteUrlFromRoom({ - roomId: 'plop1234', + roomId: 'whatever1234', serverPublicKey: '05123456789', serverUrl: null as any, }) diff --git a/ts/test/session/unit/utils/job_runner/JobRunner_test.ts b/ts/test/session/unit/utils/job_runner/JobRunner_test.ts index 6d7004020..75d5dda6a 100644 --- a/ts/test/session/unit/utils/job_runner/JobRunner_test.ts +++ b/ts/test/session/unit/utils/job_runner/JobRunner_test.ts @@ -10,6 +10,7 @@ import { } from '../../../../../session/utils/job_runners/PersistedJob'; import { sleepFor } from '../../../../../session/utils/Promise'; import { stubData } from '../../../../test-utils/utils'; +import { TestUtils } from '../../../../test-utils'; function getFakeSleepForJob(timestamp: number): FakeSleepForJob { const job = new FakeSleepForJob({ @@ -185,28 +186,48 @@ describe('JobRunner', () => { it('two jobs are running sequentially', async () => { await runnerMulti.loadJobsFromDb(); - const job = getFakeSleepForMultiJob({ timestamp: 100 }); + TestUtils.stubWindowLog(); + const job = getFakeSleepForMultiJob({ timestamp: 5 }); const job2 = getFakeSleepForMultiJob({ timestamp: 200 }); runnerMulti.startProcessing(); - clock.tick(110); + clock.tick(100); + // job should be started right away let result = await runnerMulti.addJob(job); expect(result).to.eq('job_started'); result = await runnerMulti.addJob(job2); expect(result).to.eq('job_deferred'); expect(runnerMulti.getJobList()).to.deep.eq([job.serializeJob(), job2.serializeJob()]); - expect(runnerMulti.getJobList()).to.deep.eq([job.serializeJob(), job2.serializeJob()]); + expect(runnerMulti.getCurrentJobIdentifier()).to.be.equal(job.persistedData.identifier); + + console.warn( + 'runnerMulti.getJobList() initial', + runnerMulti.getJobList().map(m => m.identifier), + Date.now() + ); + console.warn('=========== awaiting first job =========='); // each job takes 5s to finish, so let's tick once the first one should be done - clock.tick(5010); - await runnerMulti.waitCurrentJob(); - clock.tick(5010); - await runnerMulti.waitCurrentJob(); + clock.tick(5000); + expect(runnerMulti.getCurrentJobIdentifier()).to.be.equal(job.persistedData.identifier); + let awaited = await runnerMulti.waitCurrentJob(); + expect(awaited).to.eq('await'); + await sleepFor(10); - expect(runnerMulti.getJobList()).to.deep.eq([job2.serializeJob()]); + console.warn('=========== awaited first job =========='); + expect(runnerMulti.getCurrentJobIdentifier()).to.be.equal(job2.persistedData.identifier); + + console.warn('=========== awaiting second job =========='); clock.tick(5000); - await runnerMulti.waitCurrentJob(); + + awaited = await runnerMulti.waitCurrentJob(); + expect(awaited).to.eq('await'); + await sleepFor(10); // those sleep for is just to let the runner the time to finish writing the tests to the DB and exit the handling of the previous test + + console.warn('=========== awaited second job =========='); + + expect(runnerMulti.getCurrentJobIdentifier()).to.eq(null); expect(runnerMulti.getJobList()).to.deep.eq([]); }); @@ -219,24 +240,32 @@ describe('JobRunner', () => { clock.tick(110); // job should be started right away let result = await runnerMulti.addJob(job); + expect(result).to.eq('job_started'); expect(runnerMulti.getJobList()).to.deep.eq([job.serializeJob()]); + expect(runnerMulti.getCurrentJobIdentifier()).to.be.equal(job.persistedData.identifier); - expect(result).to.eq('job_started'); - clock.tick(5010); - await runnerMulti.waitCurrentJob(); - clock.tick(5010); + clock.tick(5000); + console.warn('=========== awaiting first job =========='); + await runnerMulti.waitCurrentJob(); // just give some time for the runnerMulti to pick up a new job - await sleepFor(100); + await sleepFor(10); + expect(runnerMulti.getJobList()).to.deep.eq([]); + expect(runnerMulti.getCurrentJobIdentifier()).to.be.equal(null); + console.warn('=========== awaited first job =========='); // the first job should already be finished now result = await runnerMulti.addJob(job2); expect(result).to.eq('job_started'); expect(runnerMulti.getJobList()).to.deep.eq([job2.serializeJob()]); + console.warn('=========== awaiting second job =========='); + // each job takes 5s to finish, so let's tick once the first one should be done clock.tick(5010); await runnerMulti.waitCurrentJob(); + await sleepFor(10); + console.warn('=========== awaited second job =========='); expect(runnerMulti.getJobList()).to.deep.eq([]); });