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
|
@ -84,7 +84,7 @@ export class LeftPaneMessageSection extends React.Component<Props> {
|
||||||
throw new Error('renderRow: conversations selector returned element containing falsy value.');
|
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 {
|
public renderList(): JSX.Element {
|
||||||
|
|
|
@ -34,7 +34,7 @@ const MessageRequestList = () => {
|
||||||
return (
|
return (
|
||||||
<MessageRequestListContainer>
|
<MessageRequestListContainer>
|
||||||
{conversationRequests.map(conversation => {
|
{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>
|
</MessageRequestListContainer>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1000,9 +1000,7 @@ async function handleConfigurationMessageLegacy(
|
||||||
}
|
}
|
||||||
|
|
||||||
await handleOurProfileUpdateLegacy(envelope.timestamp, configurationMessage);
|
await handleOurProfileUpdateLegacy(envelope.timestamp, configurationMessage);
|
||||||
|
|
||||||
await handleGroupsAndContactsFromConfigMessageLegacy(envelope, configurationMessage);
|
await handleGroupsAndContactsFromConfigMessageLegacy(envelope, configurationMessage);
|
||||||
|
|
||||||
await removeFromCache(envelope);
|
await removeFromCache(envelope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ async function handlePollInfoResponse(
|
||||||
read,
|
read,
|
||||||
write,
|
write,
|
||||||
upload,
|
upload,
|
||||||
active_users: active_users,
|
active_users,
|
||||||
details: pick(
|
details: pick(
|
||||||
details,
|
details,
|
||||||
'admins',
|
'admins',
|
||||||
|
|
|
@ -16,7 +16,7 @@ export enum SnodeNamespaces {
|
||||||
*/
|
*/
|
||||||
UserContacts = 3,
|
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,
|
ConvoInfoVolatile = 4,
|
||||||
|
|
||||||
|
@ -94,9 +94,9 @@ function namespacePriority(namespace: SnodeNamespaces): number {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
try {
|
try {
|
||||||
assertUnreachable(namespace, `isUserConfigNamespace case not handled: ${namespace}`);
|
assertUnreachable(namespace, `namespacePriority case not handled: ${namespace}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
window.log.warn(`isUserConfigNamespace case not handled: ${namespace}: ${e.message}`);
|
window.log.warn(`namespacePriority case not handled: ${namespace}: ${e.message}`);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,6 @@ export class SwarmPolling {
|
||||||
getConversationController()
|
getConversationController()
|
||||||
.get(group.pubkey.key)
|
.get(group.pubkey.key)
|
||||||
?.idForLogging() || group.pubkey.key;
|
?.idForLogging() || group.pubkey.key;
|
||||||
|
|
||||||
if (diff >= convoPollingTimeout) {
|
if (diff >= convoPollingTimeout) {
|
||||||
window?.log?.debug(
|
window?.log?.debug(
|
||||||
`Polling for ${loggingId}; timeout: ${convoPollingTimeout}; diff: ${diff} `
|
`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 =
|
export type JobRunnerType =
|
||||||
| 'ConfigurationSyncJob'
|
| 'ConfigurationSyncJob'
|
||||||
| 'ConfigurationSyncDumpJob'
|
|
||||||
| 'FakeSleepForJob'
|
| 'FakeSleepForJob'
|
||||||
| 'FakeSleepForMultiJob'
|
| 'FakeSleepForMultiJob'
|
||||||
| 'AvatarDownloadJob';
|
| 'AvatarDownloadJob';
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
clickOnMatchingText,
|
clickOnMatchingText,
|
||||||
clickOnTestIdWithText,
|
clickOnTestIdWithText,
|
||||||
waitForMatchingText,
|
waitForMatchingText,
|
||||||
waitForTestIdWithText
|
waitForTestIdWithText,
|
||||||
} from './utilities/utils';
|
} from './utilities/utils';
|
||||||
|
|
||||||
// tslint:disable: no-console
|
// tslint:disable: no-console
|
||||||
|
@ -20,9 +20,9 @@ sessionTestTwoWindows('Disappearing messages', async ([windowA, windowB]) => {
|
||||||
// Create User
|
// Create User
|
||||||
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
|
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
|
||||||
// Create Contact
|
// Create Contact
|
||||||
await createContact(windowA, windowB, userA, userB)
|
await createContact(windowA, windowB, userA, userB);
|
||||||
// Click on user's avatar to open conversation options
|
// 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
|
// Select disappearing messages drop down
|
||||||
await clickOnMatchingText(windowA, 'Disappearing messages');
|
await clickOnMatchingText(windowA, 'Disappearing messages');
|
||||||
// Select 5 seconds
|
// Select 5 seconds
|
||||||
|
@ -74,7 +74,7 @@ sessionTestTwoWindows('Disappearing messages', async ([windowA, windowB]) => {
|
||||||
`${userA.userName} set the disappearing message timer to 5 seconds`
|
`${userA.userName} set the disappearing message timer to 5 seconds`
|
||||||
);
|
);
|
||||||
// Wait 5 seconds
|
// Wait 5 seconds
|
||||||
await sleepFor(5000)
|
await sleepFor(5000);
|
||||||
await waitForMatchingText(windowB, `${userA.userName} has turned off disappearing messages.`);
|
await waitForMatchingText(windowB, `${userA.userName} has turned off disappearing messages.`);
|
||||||
// verify message is deleted in windowB
|
// verify message is deleted in windowB
|
||||||
const errorDesc2 = 'Should not be found';
|
const errorDesc2 = 'Should not be found';
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {
|
||||||
typeIntoInput,
|
typeIntoInput,
|
||||||
waitForMatchingText,
|
waitForMatchingText,
|
||||||
waitForTestIdWithText,
|
waitForTestIdWithText,
|
||||||
waitForTextMessage
|
waitForTextMessage,
|
||||||
} from './utilities/utils';
|
} from './utilities/utils';
|
||||||
|
|
||||||
const windows: Array<Page> = [];
|
const windows: Array<Page> = [];
|
||||||
|
|
|
@ -27,14 +27,14 @@ function cleanUpOtherTest() {
|
||||||
const parentFolderOfAllDataPath = isMacOS()
|
const parentFolderOfAllDataPath = isMacOS()
|
||||||
? '~/Library/Application Support/'
|
? '~/Library/Application Support/'
|
||||||
: isLinux()
|
: isLinux()
|
||||||
? homedir() + '/.config/'
|
? `${homedir()}/.config/`
|
||||||
: null;
|
: null;
|
||||||
if (!parentFolderOfAllDataPath) {
|
if (!parentFolderOfAllDataPath) {
|
||||||
throw new Error('Only macOS is currrently supported ');
|
throw new Error('Only macOS is currrently supported ');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parentFolderOfAllDataPath || parentFolderOfAllDataPath.length < 9) {
|
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);
|
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;
|
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,
|
testName: string,
|
||||||
testCallback: (windows: N) => Promise<void>,
|
testCallback: (windows: N) => Promise<void>,
|
||||||
count: T
|
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,
|
testName: string,
|
||||||
testCallback: (windows: Tuple<Page, 1>) => Promise<void>
|
testCallback: (windows: Tuple<Page, 1>) => Promise<void>
|
||||||
) {
|
) {
|
||||||
return sessionTest(testName, testCallback, 1);
|
return sessionTest(testName, testCallback, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sessionTestTwoWindows(
|
export function sessionTestTwoWindows(
|
||||||
testName: string,
|
testName: string,
|
||||||
testCallback: ([windowA, windowB]: [Page, Page]) => Promise<void>
|
testCallback: ([windowA, windowB]: [Page, Page]) => Promise<void>
|
||||||
) {
|
) {
|
||||||
return sessionTest(testName, testCallback, 2);
|
return sessionTest(testName, testCallback, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sessionTestThreeWindows(
|
export function sessionTestThreeWindows(
|
||||||
testName: string,
|
testName: string,
|
||||||
testCallback: ([windowA, windowB, windowC]: [Page, Page, Page]) => Promise<void>
|
testCallback: ([windowA, windowB, windowC]: [Page, Page, Page]) => Promise<void>
|
||||||
) {
|
) {
|
||||||
return sessionTest(testName, testCallback, 3);
|
return sessionTest(testName, testCallback, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sessionTestFourWindows(
|
export function sessionTestFourWindows(
|
||||||
testName: string,
|
testName: string,
|
||||||
testCallback: ([windowA, windowB, windowC, windowD]: [Page, Page, Page, Page]) => Promise<void>
|
testCallback: ([windowA, windowB, windowC, windowD]: [Page, Page, Page, Page]) => Promise<void>
|
||||||
) {
|
) {
|
||||||
return sessionTest(testName, testCallback, 4);
|
return sessionTest(testName, testCallback, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sessionTestFiveWindows(
|
export function sessionTestFiveWindows(
|
||||||
testName: string,
|
testName: string,
|
||||||
testCallback: ([windowA, windowB, windowC, windowD]: [Page, Page, Page, Page, Page]) => Promise<
|
testCallback: ([windowA, windowB, windowC, windowD]: [Page, Page, Page, Page, Page]) => Promise<
|
||||||
void
|
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);
|
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
|
// tslint:disable: no-implicit-dependencies
|
||||||
|
|
||||||
import { SignalService } from '../../../../protobuf';
|
|
||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
|
import { SignalService } from '../../../../protobuf';
|
||||||
|
|
||||||
import { ConfigurationMessage } from '../../../../session/messages/outgoing/controlMessage/ConfigurationMessage';
|
import { ConfigurationMessage } from '../../../../session/messages/outgoing/controlMessage/ConfigurationMessage';
|
||||||
import { UserUtils } from '../../../../session/utils';
|
import { UserUtils } from '../../../../session/utils';
|
||||||
|
@ -13,13 +13,15 @@ import { EnvelopePlus } from '../../../../receiver/types';
|
||||||
|
|
||||||
import chaiAsPromised from 'chai-as-promised';
|
import chaiAsPromised from 'chai-as-promised';
|
||||||
import { ConfigMessageHandler } from '../../../../receiver/configMessage';
|
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';
|
import { stubData } from '../../../test-utils/utils';
|
||||||
chai.use(chaiAsPromised as any);
|
chai.use(chaiAsPromised as any);
|
||||||
chai.should();
|
chai.should();
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('ConfigurationMessage_receiving', () => {
|
describe('handleConfigurationMessageLegacy_receiving', () => {
|
||||||
let createOrUpdateStub: Sinon.SinonStub<any>;
|
let createOrUpdateStub: Sinon.SinonStub<any>;
|
||||||
let getItemByIdStub: Sinon.SinonStub<any>;
|
let getItemByIdStub: Sinon.SinonStub<any>;
|
||||||
let sender: string;
|
let sender: string;
|
||||||
|
@ -39,6 +41,8 @@ describe('ConfigurationMessage_receiving', () => {
|
||||||
displayName: 'displayName',
|
displayName: 'displayName',
|
||||||
contacts: [],
|
contacts: [],
|
||||||
});
|
});
|
||||||
|
Sinon.stub(ConfigurationSync, 'queueNewJobIfNeeded').resolves();
|
||||||
|
TestUtils.stubWindow('setSettingValue', () => undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -46,18 +50,26 @@ describe('ConfigurationMessage_receiving', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be processed if we do not have a pubkey', async () => {
|
it('should not be processed if we do not have a pubkey', async () => {
|
||||||
|
TestUtils.stubWindowLog();
|
||||||
Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').resolves(undefined);
|
Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').resolves(undefined);
|
||||||
|
|
||||||
envelope = TestUtils.generateEnvelopePlus(sender);
|
envelope = TestUtils.generateEnvelopePlus(sender);
|
||||||
|
|
||||||
const proto = config.contentProto();
|
const proto = config.contentProto();
|
||||||
createOrUpdateStub = stubData('createOrUpdateItem').resolves();
|
createOrUpdateStub = stubData('createOrUpdateItem').resolves();
|
||||||
getItemByIdStub = stubData('getItemById').resolves();
|
getItemByIdStub = stubData('getItemById').resolves();
|
||||||
|
const checkIsUserConfigFeatureReleasedStub = Sinon.stub(
|
||||||
|
ReleasedFeatures,
|
||||||
|
'checkIsUserConfigFeatureReleased'
|
||||||
|
).resolves(false);
|
||||||
await ConfigMessageHandler.handleConfigurationMessageLegacy(
|
await ConfigMessageHandler.handleConfigurationMessageLegacy(
|
||||||
envelope,
|
envelope,
|
||||||
proto.configurationMessage as SignalService.ConfigurationMessage
|
proto.configurationMessage as SignalService.ConfigurationMessage
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(createOrUpdateStub.callCount).to.equal(0);
|
expect(createOrUpdateStub.callCount).to.equal(0);
|
||||||
expect(getItemByIdStub.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', () => {
|
describe('with ourNumber set', () => {
|
||||||
|
@ -71,7 +83,7 @@ describe('ConfigurationMessage_receiving', () => {
|
||||||
const proto = config.contentProto();
|
const proto = config.contentProto();
|
||||||
// sender !== ourNumber
|
// sender !== ourNumber
|
||||||
envelope = TestUtils.generateEnvelopePlus(sender);
|
envelope = TestUtils.generateEnvelopePlus(sender);
|
||||||
|
Sinon.stub(ReleasedFeatures, 'checkIsUserConfigFeatureReleased').resolves(false);
|
||||||
createOrUpdateStub = stubData('createOrUpdateItem').resolves();
|
createOrUpdateStub = stubData('createOrUpdateItem').resolves();
|
||||||
getItemByIdStub = stubData('getItemById').resolves();
|
getItemByIdStub = stubData('getItemById').resolves();
|
||||||
await ConfigMessageHandler.handleConfigurationMessageLegacy(
|
await ConfigMessageHandler.handleConfigurationMessageLegacy(
|
||||||
|
@ -81,15 +93,5 @@ describe('ConfigurationMessage_receiving', () => {
|
||||||
expect(createOrUpdateStub.callCount).to.equal(0);
|
expect(createOrUpdateStub.callCount).to.equal(0);
|
||||||
expect(getItemByIdStub.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 { getConversationController } from '../../../../session/conversations';
|
||||||
import { PubKey } from '../../../../session/types';
|
import { PubKey } from '../../../../session/types';
|
||||||
import { UserUtils } from '../../../../session/utils';
|
import { UserUtils } from '../../../../session/utils';
|
||||||
|
import { ConfigurationSync } from '../../../../session/utils/job_runners/jobs/ConfigurationSyncJob';
|
||||||
import { sleepFor } from '../../../../session/utils/Promise';
|
import { sleepFor } from '../../../../session/utils/Promise';
|
||||||
|
import { UserGroupsWrapperActions } from '../../../../webworker/workers/browser/libsession_worker_interface';
|
||||||
import { TestUtils } from '../../../test-utils';
|
import { TestUtils } from '../../../test-utils';
|
||||||
import { generateFakeSnodes, stubData } from '../../../test-utils/utils';
|
import { generateFakeSnodes, stubData } from '../../../test-utils/utils';
|
||||||
// tslint:disable: chai-vague-errors
|
// tslint:disable: chai-vague-errors
|
||||||
|
@ -41,6 +43,8 @@ describe('SwarmPolling', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
getConversationController().reset();
|
getConversationController().reset();
|
||||||
TestUtils.stubWindowFeatureFlags();
|
TestUtils.stubWindowFeatureFlags();
|
||||||
|
Sinon.stub(ConfigurationSync, 'queueNewJobIfNeeded').resolves();
|
||||||
|
|
||||||
// Utils Stubs
|
// Utils Stubs
|
||||||
Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(ourNumber);
|
Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(ourNumber);
|
||||||
|
|
||||||
|
@ -75,6 +79,9 @@ describe('SwarmPolling', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getPollingTimeout', () => {
|
describe('getPollingTimeout', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestUtils.stubLibSessionWorker(undefined);
|
||||||
|
});
|
||||||
it('returns INACTIVE for non existing convo', () => {
|
it('returns INACTIVE for non existing convo', () => {
|
||||||
const fakeConvo = TestUtils.generateFakePubKey();
|
const fakeConvo = TestUtils.generateFakePubKey();
|
||||||
|
|
||||||
|
@ -200,7 +207,7 @@ describe('SwarmPolling', () => {
|
||||||
await swarmPolling.start(true);
|
await swarmPolling.start(true);
|
||||||
|
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(1);
|
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 () => {
|
it('does run for our pubkey even if activeAt is recent ', async () => {
|
||||||
|
@ -212,27 +219,16 @@ describe('SwarmPolling', () => {
|
||||||
await swarmPolling.start(true);
|
await swarmPolling.start(true);
|
||||||
|
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(1);
|
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 () => {
|
|
||||||
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]]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('legacy group', () => {
|
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(
|
const convo = getConversationController().getOrCreate(
|
||||||
TestUtils.generateFakePubKeyStr(),
|
TestUtils.generateFakePubKeyStr(),
|
||||||
ConversationTypeEnum.GROUP
|
ConversationTypeEnum.GROUP
|
||||||
);
|
);
|
||||||
|
TestUtils.stubLibSessionWorker(undefined);
|
||||||
convo.set('active_at', Date.now());
|
convo.set('active_at', Date.now());
|
||||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||||
swarmPolling.addGroupId(groupConvoPubkey);
|
swarmPolling.addGroupId(groupConvoPubkey);
|
||||||
|
@ -240,23 +236,7 @@ describe('SwarmPolling', () => {
|
||||||
|
|
||||||
// our pubkey will be polled for, hence the 2
|
// our pubkey will be polled for, hence the 2
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(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]]);
|
|
||||||
});
|
|
||||||
|
|
||||||
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.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -265,6 +245,7 @@ describe('SwarmPolling', () => {
|
||||||
TestUtils.generateFakePubKeyStr(),
|
TestUtils.generateFakePubKeyStr(),
|
||||||
ConversationTypeEnum.GROUP
|
ConversationTypeEnum.GROUP
|
||||||
);
|
);
|
||||||
|
TestUtils.stubLibSessionWorker(undefined);
|
||||||
getItemByIdStub.restore();
|
getItemByIdStub.restore();
|
||||||
getItemByIdStub = TestUtils.stubData('getItemById');
|
getItemByIdStub = TestUtils.stubData('getItemById');
|
||||||
getItemByIdStub
|
getItemByIdStub
|
||||||
|
@ -281,7 +262,7 @@ describe('SwarmPolling', () => {
|
||||||
|
|
||||||
// our pubkey will be polled for, hence the 2
|
// our pubkey will be polled for, hence the 2
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(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]]);
|
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||||
getItemByIdStub.restore();
|
getItemByIdStub.restore();
|
||||||
getItemByIdStub = TestUtils.stubData('getItemById');
|
getItemByIdStub = TestUtils.stubData('getItemById');
|
||||||
|
@ -294,6 +275,7 @@ describe('SwarmPolling', () => {
|
||||||
TestUtils.generateFakePubKeyStr(),
|
TestUtils.generateFakePubKeyStr(),
|
||||||
ConversationTypeEnum.GROUP
|
ConversationTypeEnum.GROUP
|
||||||
);
|
);
|
||||||
|
TestUtils.stubLibSessionWorker(undefined);
|
||||||
|
|
||||||
convo.set('active_at', 1); // really old, but active
|
convo.set('active_at', 1); // really old, but active
|
||||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||||
|
@ -306,9 +288,9 @@ describe('SwarmPolling', () => {
|
||||||
await swarmPolling.pollForAllKeys();
|
await swarmPolling.pollForAllKeys();
|
||||||
|
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(3);
|
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.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 () => {
|
it('does run twice if activeAt less than one hour ', async () => {
|
||||||
|
@ -317,27 +299,31 @@ describe('SwarmPolling', () => {
|
||||||
ConversationTypeEnum.GROUP
|
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());
|
convo.set('active_at', Date.now());
|
||||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||||
swarmPolling.addGroupId(groupConvoPubkey);
|
swarmPolling.addGroupId(groupConvoPubkey);
|
||||||
await swarmPolling.start(true);
|
await swarmPolling.start(true);
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(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]]);
|
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||||
|
pollOnceForKeySpy.resetHistory();
|
||||||
clock.tick(9000);
|
clock.tick(9000);
|
||||||
|
|
||||||
// no need to do that as the tick will trigger a call in all cases after 5 secs await swarmPolling.pollForAllKeys();
|
// 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
|
/** 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)
|
* - 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 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
|
* the only fix is to restore the clock and force the a small sleep to let the thing run in bg
|
||||||
*/
|
*/
|
||||||
|
|
||||||
await sleepFor(10);
|
await sleepFor(10);
|
||||||
|
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(4);
|
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]]);
|
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 () => {
|
it('does run twice if activeAt is inactive and we tick longer than 2 minutes', async () => {
|
||||||
|
@ -345,7 +331,8 @@ describe('SwarmPolling', () => {
|
||||||
TestUtils.generateFakePubKeyStr(),
|
TestUtils.generateFakePubKeyStr(),
|
||||||
ConversationTypeEnum.GROUP
|
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();
|
pollOnceForKeySpy.resetHistory();
|
||||||
convo.set('active_at', Date.now());
|
convo.set('active_at', Date.now());
|
||||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||||
|
@ -365,9 +352,9 @@ describe('SwarmPolling', () => {
|
||||||
await sleepFor(10);
|
await sleepFor(10);
|
||||||
// we should have two more calls here, so 4 total.
|
// we should have two more calls here, so 4 total.
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(4);
|
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.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]]);
|
expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true, [-10]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -377,7 +364,7 @@ describe('SwarmPolling', () => {
|
||||||
ConversationTypeEnum.GROUP
|
ConversationTypeEnum.GROUP
|
||||||
);
|
);
|
||||||
pollOnceForKeySpy.resetHistory();
|
pollOnceForKeySpy.resetHistory();
|
||||||
|
TestUtils.stubLibSessionWorker(undefined);
|
||||||
convo.set('active_at', Date.now());
|
convo.set('active_at', Date.now());
|
||||||
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
const groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||||
swarmPolling.addGroupId(groupConvoPubkey);
|
swarmPolling.addGroupId(groupConvoPubkey);
|
||||||
|
@ -392,7 +379,7 @@ describe('SwarmPolling', () => {
|
||||||
// we should have only one more call here, the one for our direct pubkey fetch
|
// we should have only one more call here, the one for our direct pubkey fetch
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(3);
|
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.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', () => {
|
describe('multiple runs', () => {
|
||||||
|
@ -404,6 +391,7 @@ describe('SwarmPolling', () => {
|
||||||
TestUtils.generateFakePubKeyStr(),
|
TestUtils.generateFakePubKeyStr(),
|
||||||
ConversationTypeEnum.GROUP
|
ConversationTypeEnum.GROUP
|
||||||
);
|
);
|
||||||
|
TestUtils.stubLibSessionWorker({});
|
||||||
|
|
||||||
convo.set('active_at', Date.now());
|
convo.set('active_at', Date.now());
|
||||||
groupConvoPubkey = PubKey.cast(convo.id as string);
|
groupConvoPubkey = PubKey.cast(convo.id as string);
|
||||||
|
@ -411,6 +399,13 @@ describe('SwarmPolling', () => {
|
||||||
await swarmPolling.start(true);
|
await swarmPolling.start(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
Sinon.restore();
|
||||||
|
getConversationController().reset();
|
||||||
|
clock.restore();
|
||||||
|
resetHardForkCachedValues();
|
||||||
|
});
|
||||||
|
|
||||||
it('does run twice if activeAt is less than 2 days', async () => {
|
it('does run twice if activeAt is less than 2 days', async () => {
|
||||||
pollOnceForKeySpy.resetHistory();
|
pollOnceForKeySpy.resetHistory();
|
||||||
// less than 2 days old, this is an active group
|
// 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)
|
// 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);
|
expect(pollOnceForKeySpy.callCount).to.eq(4);
|
||||||
// first two calls are our pubkey
|
// 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.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]]);
|
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();
|
pollOnceForKeySpy.resetHistory();
|
||||||
|
TestUtils.stubWindowLog();
|
||||||
convo.set('active_at', Date.now() - 2 * 25 * 3600 * 1000); // medium active
|
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);
|
swarmPolling.forcePolledTimestamp(convo.id, timeToTick);
|
||||||
|
|
||||||
clock.tick(timeToTick); // should tick twice more (one more our direct pubkey and one for the group)
|
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();
|
await swarmPolling.pollForAllKeys();
|
||||||
|
|
||||||
expect(pollOnceForKeySpy.callCount).to.eq(4);
|
expect(pollOnceForKeySpy.callCount).to.eq(4);
|
||||||
|
|
||||||
// first two calls are our pubkey
|
// 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.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]]);
|
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 { ConfigDumpData } from '../../../data/configDump/configDump';
|
||||||
|
|
||||||
import * as utilWorker from '../../../webworker/workers/browser/util_worker_interface';
|
import * as utilWorker from '../../../webworker/workers/browser/util_worker_interface';
|
||||||
|
import * as libsessionWorker from '../../../webworker/workers/browser/libsession_worker_interface';
|
||||||
|
|
||||||
const globalAny: any = global;
|
const globalAny: any = global;
|
||||||
|
|
||||||
|
@ -38,6 +39,11 @@ export function stubUtilWorker(fnName: string, returnedValue: any): sinon.SinonS
|
||||||
.withArgs(fnName as any)
|
.withArgs(fnName as any)
|
||||||
.resolves(returnedValue);
|
.resolves(returnedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function stubLibSessionWorker(value: any) {
|
||||||
|
Sinon.stub(libsessionWorker, 'callLibSessionWorker').resolves(value);
|
||||||
|
}
|
||||||
|
|
||||||
export function stubCreateObjectUrl() {
|
export function stubCreateObjectUrl() {
|
||||||
// tslint:disable-next-line: no-empty no-function-expression
|
// tslint:disable-next-line: no-empty no-function-expression
|
||||||
(global as any).URL = function() {};
|
(global as any).URL = function() {};
|
||||||
|
|
|
@ -7,5 +7,3 @@ export type RenderTextCallbackType = (options: {
|
||||||
}) => JSX.Element;
|
}) => JSX.Element;
|
||||||
|
|
||||||
export type LocalizerType = (key: LocalizerKeys, values?: Array<string>) => string;
|
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']>>,
|
]) as Promise<ReturnType<ConvoInfoVolatileWrapperActionsCalls['eraseCommunityByFullUrl']>>,
|
||||||
};
|
};
|
||||||
|
|
||||||
const callLibSessionWorker = async (callToMake: LibSessionWorkerFunctions): Promise<unknown> => {
|
export const callLibSessionWorker = async (
|
||||||
|
callToMake: LibSessionWorkerFunctions
|
||||||
|
): Promise<unknown> => {
|
||||||
return internalCallLibSessionWorker(callToMake);
|
return internalCallLibSessionWorker(callToMake);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue