mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
chore: fix unit tests for userconfig changes
This commit is contained in:
parent
10f6f9c892
commit
6676bf77f9
24 changed files with 104 additions and 271 deletions
|
@ -84,7 +84,7 @@ export class LeftPaneMessageSection extends React.Component<Props> {
|
|||
throw new Error('renderRow: conversations selector returned element containing falsy value.');
|
||||
}
|
||||
|
||||
return <MemoConversationListItemWithDetails key={key} style={style} {...conversation} />;
|
||||
return <MemoConversationListItemWithDetails key={key} style={style} {...conversation} />; // TODO there should not be a need for the ...conversation here?
|
||||
};
|
||||
|
||||
public renderList(): JSX.Element {
|
||||
|
|
|
@ -34,7 +34,7 @@ const MessageRequestList = () => {
|
|||
return (
|
||||
<MessageRequestListContainer>
|
||||
{conversationRequests.map(conversation => {
|
||||
return <MemoConversationListItemWithDetails key={conversation.id} {...conversation} />;
|
||||
return <MemoConversationListItemWithDetails key={conversation.id} {...conversation} />; // TODO there should not be a need for the ...conversation here?
|
||||
})}
|
||||
</MessageRequestListContainer>
|
||||
);
|
||||
|
|
|
@ -1000,9 +1000,7 @@ async function handleConfigurationMessageLegacy(
|
|||
}
|
||||
|
||||
await handleOurProfileUpdateLegacy(envelope.timestamp, configurationMessage);
|
||||
|
||||
await handleGroupsAndContactsFromConfigMessageLegacy(envelope, configurationMessage);
|
||||
|
||||
await removeFromCache(envelope);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ async function handlePollInfoResponse(
|
|||
read,
|
||||
write,
|
||||
upload,
|
||||
active_users: active_users,
|
||||
active_users,
|
||||
details: pick(
|
||||
details,
|
||||
'admins',
|
||||
|
|
|
@ -16,7 +16,7 @@ export enum SnodeNamespaces {
|
|||
*/
|
||||
UserContacts = 3,
|
||||
/**
|
||||
* This is the namespace used to sync our contacts
|
||||
* This is the namespace used to sync our volatile info (currently read status only)
|
||||
*/
|
||||
ConvoInfoVolatile = 4,
|
||||
|
||||
|
@ -94,9 +94,9 @@ function namespacePriority(namespace: SnodeNamespaces): number {
|
|||
|
||||
default:
|
||||
try {
|
||||
assertUnreachable(namespace, `isUserConfigNamespace case not handled: ${namespace}`);
|
||||
assertUnreachable(namespace, `namespacePriority case not handled: ${namespace}`);
|
||||
} catch (e) {
|
||||
window.log.warn(`isUserConfigNamespace case not handled: ${namespace}: ${e.message}`);
|
||||
window.log.warn(`namespacePriority case not handled: ${namespace}: ${e.message}`);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,7 +172,6 @@ export class SwarmPolling {
|
|||
getConversationController()
|
||||
.get(group.pubkey.key)
|
||||
?.idForLogging() || group.pubkey.key;
|
||||
|
||||
if (diff >= convoPollingTimeout) {
|
||||
window?.log?.debug(
|
||||
`Polling for ${loggingId}; timeout: ${convoPollingTimeout}; diff: ${diff} `
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
// import { SignalService } from '../../../../../../protobuf';
|
||||
// import { isArray } from 'lodash';
|
||||
// import { GroupMessage, GroupMessageParams } from './GroupMessage';
|
||||
// // import { PubKey } from '../../../../../types';
|
||||
// // import { from_hex } from 'libsodium-wrappers-sumo';
|
||||
|
||||
// interface GroupAdminMessageParams extends GroupMessageParams {
|
||||
// /*
|
||||
// * A proof that we are an admin (a proof that we have access to the private key of the closed group).
|
||||
// * this field is needed for all types of admin messages so that every member can make
|
||||
// */
|
||||
// groupSignature: Uint8Array;
|
||||
// }
|
||||
|
||||
// interface GroupAdminMessageParams extends GroupMessageParams {
|
||||
// /**
|
||||
// * hex string of the members to delete the group from.
|
||||
// * a single '*' is allowed too and means 'every members'
|
||||
// *
|
||||
// */
|
||||
// members: Array<string>;
|
||||
// }
|
||||
|
||||
// export class GroupAdminGroupMessage extends GroupMessage {
|
||||
// // private readonly members: Array<string>;
|
||||
|
||||
// constructor(params: GroupAdminMessageParams) {
|
||||
// super(params);
|
||||
|
||||
// if (!params.members || !isArray(params.members) || !params.members.length) {
|
||||
// throw new Error('members parameter must be set');
|
||||
// }
|
||||
|
||||
// // if (params.members.length === 1 && params.members[0] === '*') {
|
||||
// // this.members = params.members;
|
||||
// // } else {
|
||||
// // const allAreValid = params.members.every(PubKey.isValidGroupPubkey);
|
||||
// // if (!allAreValid) {
|
||||
// // throw new Error('One of the members is not a `isValidGroupPubkey`');
|
||||
// // }
|
||||
|
||||
// // this.members = params.members;
|
||||
// // }
|
||||
// throw new Error('TODO and add tests');
|
||||
// }
|
||||
|
||||
// public dataProto(): SignalService.DataMessage {
|
||||
// const dataMessage = new SignalService.DataMessage();
|
||||
// dataMessage.groupMessage = super.groupMessage();
|
||||
// dataMessage.groupMessage.adminMessage = new SignalService.GroupAdminMessage();
|
||||
// // dataMessage.groupMessage.members = this.members.map(from_hex);
|
||||
|
||||
// return dataMessage;
|
||||
// }
|
||||
// }
|
|
@ -1,48 +0,0 @@
|
|||
// import { SignalService } from '../../../../../../protobuf';
|
||||
// import { isEmpty, isString } from 'lodash';
|
||||
// import { GroupMessage, GroupMessageParams } from './GroupMessage';
|
||||
// import { PubKey } from '../../../../../types';
|
||||
// import { from_hex } from 'libsodium-wrappers-sumo';
|
||||
|
||||
// export interface GroupInviteMessageParams extends GroupMessageParams {
|
||||
// name: string;
|
||||
// /**
|
||||
// * hex string of that member private key
|
||||
// */
|
||||
// memberPrivateKey: string;
|
||||
// }
|
||||
|
||||
// export class GroupInviteMessage extends GroupMessage {
|
||||
// private readonly name: string;
|
||||
// private readonly memberPrivateKey: string;
|
||||
|
||||
// constructor(params: GroupInviteMessageParams) {
|
||||
// super(params);
|
||||
|
||||
// if (!params.name || isEmpty(params.name) || !isString(params.name)) {
|
||||
// throw new Error('name parameter must be valid');
|
||||
// }
|
||||
|
||||
// if (
|
||||
// !params.memberPrivateKey ||
|
||||
// isEmpty(params.memberPrivateKey) ||
|
||||
// !isString(params.memberPrivateKey) ||
|
||||
// !PubKey.isHexOnly(params.memberPrivateKey)
|
||||
// ) {
|
||||
// throw new Error('memberPrivateKey parameter must be valid');
|
||||
// }
|
||||
|
||||
// this.name = params.name;
|
||||
// this.memberPrivateKey = params.memberPrivateKey;
|
||||
// }
|
||||
|
||||
// public dataProto(): SignalService.DataMessage {
|
||||
// const dataMessage = new SignalService.DataMessage();
|
||||
// dataMessage.groupMessage = super.groupMessage();
|
||||
// dataMessage.groupMessage.inviteMessage = new SignalService.GroupInviteMessage();
|
||||
// dataMessage.groupMessage.inviteMessage.name = this.name;
|
||||
// dataMessage.groupMessage.inviteMessage.memberPrivateKey = from_hex(this.memberPrivateKey);
|
||||
|
||||
// return dataMessage;
|
||||
// }
|
||||
// }
|
|
@ -1,18 +0,0 @@
|
|||
// import { SignalService } from '../../../../../../protobuf';
|
||||
// import { GroupMessage, GroupMessageParams } from './GroupMessage';
|
||||
|
||||
// interface GroupMemberLeftMessageParams extends GroupMessageParams {}
|
||||
|
||||
// export class GroupMemberLeftMessage extends GroupMessage {
|
||||
// constructor(params: GroupMemberLeftMessageParams) {
|
||||
// super(params);
|
||||
// }
|
||||
|
||||
// public dataProto(): SignalService.DataMessage {
|
||||
// const dataMessage = new SignalService.DataMessage();
|
||||
// dataMessage.groupMessage = super.groupMessage();
|
||||
// dataMessage.groupMessage.memberLeftMessage = new SignalService.GroupMemberLeftMessage();
|
||||
|
||||
// return dataMessage;
|
||||
// }
|
||||
// }
|
|
@ -1,18 +0,0 @@
|
|||
// import { SignalService } from '../../../../../../protobuf';
|
||||
// import { DataMessage } from '../../../DataMessage';
|
||||
// import { MessageParams } from '../../../Message';
|
||||
|
||||
// export interface GroupMessageParams extends MessageParams {}
|
||||
|
||||
// export abstract class GroupMessage extends DataMessage {
|
||||
// constructor(params: GroupMessageParams) {
|
||||
// super({
|
||||
// timestamp: params.timestamp,
|
||||
// identifier: params.identifier,
|
||||
// });
|
||||
// }
|
||||
|
||||
// protected groupMessage() {
|
||||
// return new SignalService.GroupMessage();
|
||||
// }
|
||||
// }
|
|
@ -1,34 +0,0 @@
|
|||
// import { SignalService } from '../../../../../../protobuf';
|
||||
// import { isEmpty } from 'lodash';
|
||||
// import { GroupMessage, GroupMessageParams } from './GroupMessage';
|
||||
// import { from_hex } from 'libsodium-wrappers-sumo';
|
||||
|
||||
// export interface GroupPromoteMessageParams extends GroupMessageParams {
|
||||
// /**
|
||||
// * hex string of the group private key
|
||||
// */
|
||||
// privateKey: string;
|
||||
// }
|
||||
|
||||
// export class GroupPromoteMessage extends GroupMessage {
|
||||
// private readonly privateKey: string;
|
||||
|
||||
// constructor(params: GroupPromoteMessageParams) {
|
||||
// super(params);
|
||||
|
||||
// if (!params.privateKey || isEmpty(params.privateKey)) {
|
||||
// throw new Error('privateKey parameter must be set');
|
||||
// }
|
||||
|
||||
// this.privateKey = params.privateKey;
|
||||
// }
|
||||
|
||||
// public dataProto(): SignalService.DataMessage {
|
||||
// const dataMessage = new SignalService.DataMessage();
|
||||
// dataMessage.groupMessage = super.groupMessage();
|
||||
// dataMessage.groupMessage.promoteMessage = new SignalService.GroupPromoteMessage();
|
||||
// dataMessage.groupMessage.promoteMessage.privateKey = from_hex(this.privateKey);
|
||||
|
||||
// return dataMessage;
|
||||
// }
|
||||
// }
|
|
@ -1,6 +1,5 @@
|
|||
export type JobRunnerType =
|
||||
| 'ConfigurationSyncJob'
|
||||
| 'ConfigurationSyncDumpJob'
|
||||
| 'FakeSleepForJob'
|
||||
| 'FakeSleepForMultiJob'
|
||||
| 'AvatarDownloadJob';
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
clickOnMatchingText,
|
||||
clickOnTestIdWithText,
|
||||
waitForMatchingText,
|
||||
waitForTestIdWithText
|
||||
waitForTestIdWithText,
|
||||
} from './utilities/utils';
|
||||
|
||||
// tslint:disable: no-console
|
||||
|
@ -20,9 +20,9 @@ sessionTestTwoWindows('Disappearing messages', async ([windowA, windowB]) => {
|
|||
// Create User
|
||||
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
|
||||
// Create Contact
|
||||
await createContact(windowA, windowB, userA, userB)
|
||||
await createContact(windowA, windowB, userA, userB);
|
||||
// Click on user's avatar to open conversation options
|
||||
await clickOnTestIdWithText(windowA, 'conversation-options-avatar')
|
||||
await clickOnTestIdWithText(windowA, 'conversation-options-avatar');
|
||||
// Select disappearing messages drop down
|
||||
await clickOnMatchingText(windowA, 'Disappearing messages');
|
||||
// Select 5 seconds
|
||||
|
@ -74,7 +74,7 @@ sessionTestTwoWindows('Disappearing messages', async ([windowA, windowB]) => {
|
|||
`${userA.userName} set the disappearing message timer to 5 seconds`
|
||||
);
|
||||
// Wait 5 seconds
|
||||
await sleepFor(5000)
|
||||
await sleepFor(5000);
|
||||
await waitForMatchingText(windowB, `${userA.userName} has turned off disappearing messages.`);
|
||||
// verify message is deleted in windowB
|
||||
const errorDesc2 = 'Should not be found';
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
typeIntoInput,
|
||||
waitForMatchingText,
|
||||
waitForTestIdWithText,
|
||||
waitForTextMessage
|
||||
waitForTextMessage,
|
||||
} from './utilities/utils';
|
||||
|
||||
const windows: Array<Page> = [];
|
||||
|
|
|
@ -27,14 +27,14 @@ function cleanUpOtherTest() {
|
|||
const parentFolderOfAllDataPath = isMacOS()
|
||||
? '~/Library/Application Support/'
|
||||
: isLinux()
|
||||
? homedir() + '/.config/'
|
||||
? `${homedir()}/.config/`
|
||||
: null;
|
||||
if (!parentFolderOfAllDataPath) {
|
||||
throw new Error('Only macOS is currrently supported ');
|
||||
}
|
||||
|
||||
if (!parentFolderOfAllDataPath || parentFolderOfAllDataPath.length < 9) {
|
||||
throw new Error('parentFolderOfAllDataPath not found or invalid:' + parentFolderOfAllDataPath);
|
||||
throw new Error(`parentFolderOfAllDataPath not found or invalid: ${parentFolderOfAllDataPath}`);
|
||||
}
|
||||
console.info('cleaning other tests leftovers...', parentFolderOfAllDataPath);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N
|
|||
|
||||
type CountWindows = 1 | 2 | 3 | 4 | 5;
|
||||
|
||||
async function sessionTest<T extends CountWindows, N extends Tuple<Page, T>>(
|
||||
function sessionTest<T extends CountWindows, N extends Tuple<Page, T>>(
|
||||
testName: string,
|
||||
testCallback: (windows: N) => Promise<void>,
|
||||
count: T
|
||||
|
@ -43,35 +43,35 @@ async function sessionTest<T extends CountWindows, N extends Tuple<Page, T>>(
|
|||
});
|
||||
}
|
||||
|
||||
export async function sessionTestOneWindow(
|
||||
export function sessionTestOneWindow(
|
||||
testName: string,
|
||||
testCallback: (windows: Tuple<Page, 1>) => Promise<void>
|
||||
) {
|
||||
return sessionTest(testName, testCallback, 1);
|
||||
}
|
||||
|
||||
export async function sessionTestTwoWindows(
|
||||
export function sessionTestTwoWindows(
|
||||
testName: string,
|
||||
testCallback: ([windowA, windowB]: [Page, Page]) => Promise<void>
|
||||
) {
|
||||
return sessionTest(testName, testCallback, 2);
|
||||
}
|
||||
|
||||
export async function sessionTestThreeWindows(
|
||||
export function sessionTestThreeWindows(
|
||||
testName: string,
|
||||
testCallback: ([windowA, windowB, windowC]: [Page, Page, Page]) => Promise<void>
|
||||
) {
|
||||
return sessionTest(testName, testCallback, 3);
|
||||
}
|
||||
|
||||
export async function sessionTestFourWindows(
|
||||
export function sessionTestFourWindows(
|
||||
testName: string,
|
||||
testCallback: ([windowA, windowB, windowC, windowD]: [Page, Page, Page, Page]) => Promise<void>
|
||||
) {
|
||||
return sessionTest(testName, testCallback, 4);
|
||||
}
|
||||
|
||||
export async function sessionTestFiveWindows(
|
||||
export function sessionTestFiveWindows(
|
||||
testName: string,
|
||||
testCallback: ([windowA, windowB, windowC, windowD]: [Page, Page, Page, Page, Page]) => Promise<
|
||||
void
|
||||
|
|
10
ts/test/automation/tslint.json
Normal file
10
ts/test/automation/tslint.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": ["../tslint.json"],
|
||||
"rules": {
|
||||
"no-empty": false,
|
||||
"array-type": false,
|
||||
"no-console": false,
|
||||
"no-void-expression": false
|
||||
}
|
||||
}
|
|
@ -94,11 +94,4 @@ describe('filterDuplicatesFromDbAndIncomingV4', () => {
|
|||
expect(filtered[0]).to.be.deep.eq(msg1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('filters duplicated message from database', () => {
|
||||
//sadly better-sqlite3 does not allow us to easily create an in memory db for now (issues with sqlite binary)
|
||||
// so testing this part is not easy as all the logic is made in sqlite
|
||||
// tslint:disable-next-line: no-empty
|
||||
it.skip('in memory database', () => {});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// tslint:disable: no-implicit-dependencies
|
||||
|
||||
import { SignalService } from '../../../../protobuf';
|
||||
import chai from 'chai';
|
||||
import { SignalService } from '../../../../protobuf';
|
||||
|
||||
import { ConfigurationMessage } from '../../../../session/messages/outgoing/controlMessage/ConfigurationMessage';
|
||||
import { UserUtils } from '../../../../session/utils';
|
||||
|
@ -13,13 +13,15 @@ import { EnvelopePlus } from '../../../../receiver/types';
|
|||
|
||||
import chaiAsPromised from 'chai-as-promised';
|
||||
import { ConfigMessageHandler } from '../../../../receiver/configMessage';
|
||||
import { ConfigurationSync } from '../../../../session/utils/job_runners/jobs/ConfigurationSyncJob';
|
||||
import { ReleasedFeatures } from '../../../../util/releaseFeature';
|
||||
import { stubData } from '../../../test-utils/utils';
|
||||
chai.use(chaiAsPromised as any);
|
||||
chai.should();
|
||||
|
||||
const { expect } = chai;
|
||||
|
||||
describe('ConfigurationMessage_receiving', () => {
|
||||
describe('handleConfigurationMessageLegacy_receiving', () => {
|
||||
let createOrUpdateStub: Sinon.SinonStub<any>;
|
||||
let getItemByIdStub: Sinon.SinonStub<any>;
|
||||
let sender: string;
|
||||
|
@ -39,6 +41,8 @@ describe('ConfigurationMessage_receiving', () => {
|
|||
displayName: 'displayName',
|
||||
contacts: [],
|
||||
});
|
||||
Sinon.stub(ConfigurationSync, 'queueNewJobIfNeeded').resolves();
|
||||
TestUtils.stubWindow('setSettingValue', () => undefined);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -46,18 +50,26 @@ describe('ConfigurationMessage_receiving', () => {
|
|||
});
|
||||
|
||||
it('should not be processed if we do not have a pubkey', async () => {
|
||||
TestUtils.stubWindowLog();
|
||||
Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').resolves(undefined);
|
||||
|
||||
envelope = TestUtils.generateEnvelopePlus(sender);
|
||||
|
||||
const proto = config.contentProto();
|
||||
createOrUpdateStub = stubData('createOrUpdateItem').resolves();
|
||||
getItemByIdStub = stubData('getItemById').resolves();
|
||||
const checkIsUserConfigFeatureReleasedStub = Sinon.stub(
|
||||
ReleasedFeatures,
|
||||
'checkIsUserConfigFeatureReleased'
|
||||
).resolves(false);
|
||||
await ConfigMessageHandler.handleConfigurationMessageLegacy(
|
||||
envelope,
|
||||
proto.configurationMessage as SignalService.ConfigurationMessage
|
||||
);
|
||||
|
||||
expect(createOrUpdateStub.callCount).to.equal(0);
|
||||
expect(getItemByIdStub.callCount).to.equal(0);
|
||||
expect(checkIsUserConfigFeatureReleasedStub.callCount).to.be.eq(1); // should only have the one as part of the global legacy check, but none for the smaller handlers
|
||||
});
|
||||
|
||||
describe('with ourNumber set', () => {
|
||||
|
@ -71,7 +83,7 @@ describe('ConfigurationMessage_receiving', () => {
|
|||
const proto = config.contentProto();
|
||||
// sender !== ourNumber
|
||||
envelope = TestUtils.generateEnvelopePlus(sender);
|
||||
|
||||
Sinon.stub(ReleasedFeatures, 'checkIsUserConfigFeatureReleased').resolves(false);
|
||||
createOrUpdateStub = stubData('createOrUpdateItem').resolves();
|
||||
getItemByIdStub = stubData('getItemById').resolves();
|
||||
await ConfigMessageHandler.handleConfigurationMessageLegacy(
|
||||
|
@ -81,15 +93,5 @@ describe('ConfigurationMessage_receiving', () => {
|
|||
expect(createOrUpdateStub.callCount).to.equal(0);
|
||||
expect(getItemByIdStub.callCount).to.equal(0);
|
||||
});
|
||||
|
||||
// it('should be processed if the message is coming from our number', async () => {
|
||||
// const proto = config.contentProto();
|
||||
// envelope = TestUtils.generateEnvelopePlus(ourNumber);
|
||||
|
||||
// createOrUpdateStub = sandbox.stub(data, 'createOrUpdateItem').resolves();
|
||||
// getItemByIdStub = sandbox.stub(data, 'getItemById').resolves();
|
||||
// await handleConfigurationMessageLegacy(envelope, proto.configurationMessage as SignalService.ConfigurationMessage);
|
||||
// expect(getItemByIdStub.callCount).to.equal(1);
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,7 +15,9 @@ import { SWARM_POLLING_TIMEOUT } from '../../../../session/constants';
|
|||
import { getConversationController } from '../../../../session/conversations';
|
||||
import { PubKey } from '../../../../session/types';
|
||||
import { UserUtils } from '../../../../session/utils';
|
||||
import { ConfigurationSync } from '../../../../session/utils/job_runners/jobs/ConfigurationSyncJob';
|
||||
import { sleepFor } from '../../../../session/utils/Promise';
|
||||
import { UserGroupsWrapperActions } from '../../../../webworker/workers/browser/libsession_worker_interface';
|
||||
import { TestUtils } from '../../../test-utils';
|
||||
import { generateFakeSnodes, stubData } from '../../../test-utils/utils';
|
||||
// tslint:disable: chai-vague-errors
|
||||
|
@ -41,6 +43,8 @@ describe('SwarmPolling', () => {
|
|||
beforeEach(async () => {
|
||||
getConversationController().reset();
|
||||
TestUtils.stubWindowFeatureFlags();
|
||||
Sinon.stub(ConfigurationSync, 'queueNewJobIfNeeded').resolves();
|
||||
|
||||
// Utils Stubs
|
||||
Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(ourNumber);
|
||||
|
||||
|
@ -75,6 +79,9 @@ describe('SwarmPolling', () => {
|
|||
});
|
||||
|
||||
describe('getPollingTimeout', () => {
|
||||
beforeEach(() => {
|
||||
TestUtils.stubLibSessionWorker(undefined);
|
||||
});
|
||||
it('returns INACTIVE for non existing convo', () => {
|
||||
const fakeConvo = TestUtils.generateFakePubKey();
|
||||
|
||||
|
@ -200,7 +207,7 @@ describe('SwarmPolling', () => {
|
|||
await swarmPolling.start(true);
|
||||
|
||||
expect(pollOnceForKeySpy.callCount).to.eq(1);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
});
|
||||
|
||||
it('does run for our pubkey even if activeAt is recent ', async () => {
|
||||
|
@ -212,27 +219,16 @@ describe('SwarmPolling', () => {
|
|||
await swarmPolling.start(true);
|
||||
|
||||
expect(pollOnceForKeySpy.callCount).to.eq(1);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
});
|
||||
|
||||
it('does run for our pubkey even if activeAt is recent ', async () => {
|
||||
const convo = getConversationController().getOrCreate(
|
||||
ourNumber,
|
||||
ConversationTypeEnum.PRIVATE
|
||||
);
|
||||
convo.set('active_at', Date.now());
|
||||
await swarmPolling.start(true);
|
||||
|
||||
expect(pollOnceForKeySpy.callCount).to.eq(1);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
});
|
||||
|
||||
describe('legacy group', () => {
|
||||
it('does run for group pubkey on start no matter the recent timestamp ', async () => {
|
||||
it('does run for group pubkey on start no matter the recent timestamp', async () => {
|
||||
const convo = getConversationController().getOrCreate(
|
||||
TestUtils.generateFakePubKeyStr(),
|
||||
ConversationTypeEnum.GROUP
|
||||
);
|
||||
TestUtils.stubLibSessionWorker(undefined);
|
||||
convo.set('active_at', Date.now());
|
||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||
swarmPolling.addGroupId(groupConvoPubkey);
|
||||
|
@ -240,23 +236,7 @@ describe('SwarmPolling', () => {
|
|||
|
||||
// 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.generateFakePubKeyStr(),
|
||||
ConversationTypeEnum.GROUP
|
||||
);
|
||||
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.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||
});
|
||||
|
||||
|
@ -265,6 +245,7 @@ describe('SwarmPolling', () => {
|
|||
TestUtils.generateFakePubKeyStr(),
|
||||
ConversationTypeEnum.GROUP
|
||||
);
|
||||
TestUtils.stubLibSessionWorker(undefined);
|
||||
getItemByIdStub.restore();
|
||||
getItemByIdStub = TestUtils.stubData('getItemById');
|
||||
getItemByIdStub
|
||||
|
@ -281,7 +262,7 @@ describe('SwarmPolling', () => {
|
|||
|
||||
// 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.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||
getItemByIdStub.restore();
|
||||
getItemByIdStub = TestUtils.stubData('getItemById');
|
||||
|
@ -294,6 +275,7 @@ describe('SwarmPolling', () => {
|
|||
TestUtils.generateFakePubKeyStr(),
|
||||
ConversationTypeEnum.GROUP
|
||||
);
|
||||
TestUtils.stubLibSessionWorker(undefined);
|
||||
|
||||
convo.set('active_at', 1); // really old, but active
|
||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||
|
@ -306,9 +288,9 @@ describe('SwarmPolling', () => {
|
|||
await swarmPolling.pollForAllKeys();
|
||||
|
||||
expect(pollOnceForKeySpy.callCount).to.eq(3);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
});
|
||||
|
||||
it('does run twice if activeAt less than one hour ', async () => {
|
||||
|
@ -317,27 +299,31 @@ describe('SwarmPolling', () => {
|
|||
ConversationTypeEnum.GROUP
|
||||
);
|
||||
|
||||
// fake that the group is part of the wrapper otherwise we stop tracking it after the first polling event
|
||||
Sinon.stub(UserGroupsWrapperActions, 'getLegacyGroup').resolves({} as any);
|
||||
|
||||
convo.set('active_at', Date.now());
|
||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||
swarmPolling.addGroupId(groupConvoPubkey);
|
||||
await swarmPolling.start(true);
|
||||
expect(pollOnceForKeySpy.callCount).to.eq(2);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||
pollOnceForKeySpy.resetHistory();
|
||||
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 id)
|
||||
* - 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
|
||||
*/
|
||||
|
||||
await sleepFor(10);
|
||||
|
||||
expect(pollOnceForKeySpy.callCount).to.eq(4);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
expect(pollOnceForKeySpy.callCount).to.eq(2);
|
||||
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
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 () => {
|
||||
|
@ -345,7 +331,8 @@ describe('SwarmPolling', () => {
|
|||
TestUtils.generateFakePubKeyStr(),
|
||||
ConversationTypeEnum.GROUP
|
||||
);
|
||||
|
||||
// fake that the group is part of the wrapper otherwise we stop tracking it after the first polling event
|
||||
Sinon.stub(UserGroupsWrapperActions, 'getLegacyGroup').resolves({} as any);
|
||||
pollOnceForKeySpy.resetHistory();
|
||||
convo.set('active_at', Date.now());
|
||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||
|
@ -365,9 +352,9 @@ describe('SwarmPolling', () => {
|
|||
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.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||
});
|
||||
|
||||
|
@ -377,7 +364,7 @@ describe('SwarmPolling', () => {
|
|||
ConversationTypeEnum.GROUP
|
||||
);
|
||||
pollOnceForKeySpy.resetHistory();
|
||||
|
||||
TestUtils.stubLibSessionWorker(undefined);
|
||||
convo.set('active_at', Date.now());
|
||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||
swarmPolling.addGroupId(groupConvoPubkey);
|
||||
|
@ -392,7 +379,7 @@ describe('SwarmPolling', () => {
|
|||
// 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]]);
|
||||
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
});
|
||||
|
||||
describe('multiple runs', () => {
|
||||
|
@ -404,6 +391,7 @@ describe('SwarmPolling', () => {
|
|||
TestUtils.generateFakePubKeyStr(),
|
||||
ConversationTypeEnum.GROUP
|
||||
);
|
||||
TestUtils.stubLibSessionWorker({});
|
||||
|
||||
convo.set('active_at', Date.now());
|
||||
groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||
|
@ -411,6 +399,13 @@ describe('SwarmPolling', () => {
|
|||
await swarmPolling.start(true);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
Sinon.restore();
|
||||
getConversationController().reset();
|
||||
clock.restore();
|
||||
resetHardForkCachedValues();
|
||||
});
|
||||
|
||||
it('does run twice if activeAt is less than 2 days', async () => {
|
||||
pollOnceForKeySpy.resetHistory();
|
||||
// less than 2 days old, this is an active group
|
||||
|
@ -426,29 +421,33 @@ describe('SwarmPolling', () => {
|
|||
// 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.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||
|
||||
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
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 () => {
|
||||
it('does run twice if activeAt is more than 2 days old and we tick more than one minute', async () => {
|
||||
pollOnceForKeySpy.resetHistory();
|
||||
TestUtils.stubWindowLog();
|
||||
convo.set('active_at', Date.now() - 2 * 25 * 3600 * 1000); // medium active
|
||||
// fake that the group is part of the wrapper otherwise we stop tracking it after the first polling event
|
||||
|
||||
const timeToTick = 65 * 1000;
|
||||
const timeToTick = 65 * 1000; // more than one minute
|
||||
swarmPolling.forcePolledTimestamp(convo.id, timeToTick);
|
||||
|
||||
clock.tick(timeToTick); // should tick twice more (one more our direct pubkey and one for the group)
|
||||
|
||||
// fake that the group is part of the wrapper otherwise we stop tracking it after the first polling event
|
||||
|
||||
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.firstCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0]]);
|
||||
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, [0, 2, 3, 5, 4]]);
|
||||
expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@ import { OpenGroupData } from '../../../data/opengroups';
|
|||
import { ConfigDumpData } from '../../../data/configDump/configDump';
|
||||
|
||||
import * as utilWorker from '../../../webworker/workers/browser/util_worker_interface';
|
||||
import * as libsessionWorker from '../../../webworker/workers/browser/libsession_worker_interface';
|
||||
|
||||
const globalAny: any = global;
|
||||
|
||||
|
@ -38,6 +39,11 @@ export function stubUtilWorker(fnName: string, returnedValue: any): sinon.SinonS
|
|||
.withArgs(fnName as any)
|
||||
.resolves(returnedValue);
|
||||
}
|
||||
|
||||
export function stubLibSessionWorker(value: any) {
|
||||
Sinon.stub(libsessionWorker, 'callLibSessionWorker').resolves(value);
|
||||
}
|
||||
|
||||
export function stubCreateObjectUrl() {
|
||||
// tslint:disable-next-line: no-empty no-function-expression
|
||||
(global as any).URL = function() {};
|
||||
|
|
|
@ -7,5 +7,3 @@ export type RenderTextCallbackType = (options: {
|
|||
}) => JSX.Element;
|
||||
|
||||
export type LocalizerType = (key: LocalizerKeys, values?: Array<string>) => string;
|
||||
|
||||
export type FixedLengthArray<T, Length extends number> = Array<T> & { length: Length };
|
||||
|
|
|
@ -314,6 +314,8 @@ export const ConvoInfoVolatileWrapperActions: ConvoInfoVolatileWrapperActionsCal
|
|||
]) as Promise<ReturnType<ConvoInfoVolatileWrapperActionsCalls['eraseCommunityByFullUrl']>>,
|
||||
};
|
||||
|
||||
const callLibSessionWorker = async (callToMake: LibSessionWorkerFunctions): Promise<unknown> => {
|
||||
export const callLibSessionWorker = async (
|
||||
callToMake: LibSessionWorkerFunctions
|
||||
): Promise<unknown> => {
|
||||
return internalCallLibSessionWorker(callToMake);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue