fix link device test and lint

pull/1287/head
Audric Ackermann 5 years ago
parent e2a42d1b61
commit fec0ead1de
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -1,4 +1,4 @@
/* global textsecure, WebAPI, libsignal, window, libloki, _, libsession */ /* global textsecure, WebAPI, window, libloki, _, libsession */
/* eslint-disable more/no-then, no-bitwise */ /* eslint-disable more/no-then, no-bitwise */
@ -192,174 +192,6 @@ function MessageSender() {
MessageSender.prototype = { MessageSender.prototype = {
constructor: MessageSender, constructor: MessageSender,
// makeAttachmentPointer :: Attachment -> Promise AttachmentPointerProto
async makeAttachmentPointer(attachment, publicServer = null, options = {}) {
const { isRaw = false, isAvatar = false } = options;
if (typeof attachment !== 'object' || attachment == null) {
return Promise.resolve(undefined);
}
if (
!(attachment.data instanceof ArrayBuffer) &&
!ArrayBuffer.isView(attachment.data)
) {
return Promise.reject(
new TypeError(
`\`attachment.data\` must be an \`ArrayBuffer\` or \`ArrayBufferView\`; got: ${typeof attachment.data}`
)
);
}
const proto = new textsecure.protobuf.AttachmentPointer();
let attachmentData;
const server = publicServer || this.server;
if (publicServer || isRaw) {
attachmentData = attachment.data;
} else {
proto.key = libsignal.crypto.getRandomBytes(64);
const iv = libsignal.crypto.getRandomBytes(16);
const result = await textsecure.crypto.encryptAttachment(
attachment.data,
proto.key,
iv
);
proto.digest = result.digest;
attachmentData = result.ciphertext;
}
const result = isAvatar
? await server.putAvatar(attachmentData)
: await server.putAttachment(attachmentData);
if (!result) {
return Promise.reject(
new Error('Failed to upload data to attachment fileserver')
);
}
const { url, id } = result;
proto.id = id;
proto.url = url;
proto.contentType = attachment.contentType;
if (attachment.size) {
proto.size = attachment.size;
}
if (attachment.fileName) {
proto.fileName = attachment.fileName;
}
if (attachment.flags) {
proto.flags = attachment.flags;
}
if (attachment.width) {
proto.width = attachment.width;
}
if (attachment.height) {
proto.height = attachment.height;
}
if (attachment.caption) {
proto.caption = attachment.caption;
}
return proto;
},
queueJobForNumber(number, runJob) {
const taskWithTimeout = textsecure.createTaskWithTimeout(
runJob,
`queueJobForNumber ${number}`
);
const runPrevious = this.pendingMessages[number] || Promise.resolve();
this.pendingMessages[number] = runPrevious.then(
taskWithTimeout,
taskWithTimeout
);
const runCurrent = this.pendingMessages[number];
runCurrent.then(() => {
if (this.pendingMessages[number] === runCurrent) {
delete this.pendingMessages[number];
}
});
},
uploadAttachments(message, publicServer) {
return Promise.all(
message.attachments.map(attachment =>
this.makeAttachmentPointer(attachment, publicServer)
)
)
.then(attachmentPointers => {
// eslint-disable-next-line no-param-reassign
message.attachmentPointers = attachmentPointers;
})
.catch(error => {
if (error instanceof Error && error.name === 'HTTPError') {
throw new textsecure.MessageError(message, error);
} else {
throw error;
}
});
},
async uploadLinkPreviews(message, publicServer) {
try {
const preview = await Promise.all(
(message.preview || []).map(async item => ({
...item,
image: await this.makeAttachmentPointer(item.image, publicServer),
}))
);
// eslint-disable-next-line no-param-reassign
message.preview = preview;
} catch (error) {
if (error instanceof Error && error.name === 'HTTPError') {
throw new textsecure.MessageError(message, error);
} else {
throw error;
}
}
},
uploadThumbnails(message, publicServer) {
const makePointer = this.makeAttachmentPointer.bind(this);
const { quote } = message;
if (!quote || !quote.attachments || quote.attachments.length === 0) {
return Promise.resolve();
}
return Promise.all(
quote.attachments.map(attachment => {
const { thumbnail } = attachment;
if (!thumbnail) {
return null;
}
return makePointer(thumbnail, publicServer).then(pointer => {
// eslint-disable-next-line no-param-reassign
attachment.attachmentPointer = pointer;
});
})
).catch(error => {
if (error instanceof Error && error.name === 'HTTPError') {
throw new textsecure.MessageError(message, error);
} else {
throw error;
}
});
},
uploadAvatar(attachment) {
// isRaw is true since the data is already encrypted
// and doesn't need to be encrypted again
return this.makeAttachmentPointer(attachment, null, {
isRaw: true,
isAvatar: true,
});
},
async sendContactSyncMessage(convos) { async sendContactSyncMessage(convos) {
let convosToSync; let convosToSync;
if (!convos) { if (!convos) {
@ -516,7 +348,6 @@ textsecure.MessageSender = function MessageSenderWrapper(username, password) {
this.sendOpenGroupsSyncMessage = sender.sendOpenGroupsSyncMessage.bind( this.sendOpenGroupsSyncMessage = sender.sendOpenGroupsSyncMessage.bind(
sender sender
); );
this.uploadAvatar = sender.uploadAvatar.bind(sender);
this.syncReadMessages = sender.syncReadMessages.bind(sender); this.syncReadMessages = sender.syncReadMessages.bind(sender);
this.syncVerification = sender.syncVerification.bind(sender); this.syncVerification = sender.syncVerification.bind(sender);
this.makeProxiedRequest = sender.makeProxiedRequest.bind(sender); this.makeProxiedRequest = sender.makeProxiedRequest.bind(sender);

@ -264,7 +264,9 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
} }
public setOptionsSetting(settingID: string) { public setOptionsSetting(settingID: string) {
const selectedValue = ($(`#${settingID} .session-radio input:checked`) as any).val(); const selectedValue = ($(
`#${settingID} .session-radio input:checked`
) as any).val();
window.setSettingValue(settingID, selectedValue); window.setSettingValue(settingID, selectedValue);
} }
@ -668,7 +670,9 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
} }
private async onKeyUp(event: any) { private async onKeyUp(event: any) {
const lockPasswordFocussed = ($('#password-lock-input') as any).is(':focus'); const lockPasswordFocussed = ($('#password-lock-input') as any).is(
':focus'
);
if (event.key === 'Enter' && lockPasswordFocussed) { if (event.key === 'Enter' && lockPasswordFocussed) {
await this.validatePasswordLock(); await this.validatePasswordLock();

@ -30,7 +30,9 @@ export class SettingsHeader extends React.Component<Props, any> {
} }
public focusSearch() { public focusSearch() {
($('.left-pane-setting-section .session-search-input input') as any).focus(); ($(
'.left-pane-setting-section .session-search-input input'
) as any).focus();
} }
public showAddLinkedDeviceModal() { public showAddLinkedDeviceModal() {

@ -29,228 +29,249 @@ chai.config.includeStack = true;
const STUB_SNODE_SERVER_PORT = 3000; const STUB_SNODE_SERVER_PORT = 3000;
const ENABLE_LOG = false; const ENABLE_LOG = false;
// tslint:disable-next-line: no-unnecessary-class // tslint:disable-next-line: no-unnecessary-class
export class Common { export class Common {
/* ************** USERS ****************** */ /* ************** USERS ****************** */
public static readonly TEST_MNEMONIC1 = public static readonly TEST_MNEMONIC1 =
'faxed mechanic mocked agony unrest loincloth pencil eccentric boyfriend oasis speedy ribbon faxed'; 'faxed mechanic mocked agony unrest loincloth pencil eccentric boyfriend oasis speedy ribbon faxed';
public static readonly TEST_PUBKEY1 = public static readonly TEST_PUBKEY1 =
'0552b85a43fb992f6bdb122a5a379505a0b99a16f0628ab8840249e2a60e12a413'; '0552b85a43fb992f6bdb122a5a379505a0b99a16f0628ab8840249e2a60e12a413';
public static readonly TEST_DISPLAY_NAME1 = 'tester_Alice'; public static readonly TEST_DISPLAY_NAME1 = 'tester_Alice';
public static readonly TEST_MNEMONIC2 = public static readonly TEST_MNEMONIC2 =
'guide inbound jerseys bays nouns basin sulking awkward stockpile ostrich ascend pylons ascend'; 'guide inbound jerseys bays nouns basin sulking awkward stockpile ostrich ascend pylons ascend';
public static readonly TEST_PUBKEY2 = public static readonly TEST_PUBKEY2 =
'054e1ca8681082dbd9aad1cf6fc89a32254e15cba50c75b5a73ac10a0b96bcbd2a'; '054e1ca8681082dbd9aad1cf6fc89a32254e15cba50c75b5a73ac10a0b96bcbd2a';
public static readonly TEST_DISPLAY_NAME2 = 'tester_Bob'; public static readonly TEST_DISPLAY_NAME2 = 'tester_Bob';
public static readonly TEST_MNEMONIC3 = public static readonly TEST_MNEMONIC3 =
'alpine lukewarm oncoming blender kiwi fuel lobster upkeep vogue simplest gasp fully simplest'; 'alpine lukewarm oncoming blender kiwi fuel lobster upkeep vogue simplest gasp fully simplest';
public static readonly TEST_PUBKEY3 = public static readonly TEST_PUBKEY3 =
'05f8662b6e83da5a31007cc3ded44c601f191e07999acb6db2314a896048d9036c'; '05f8662b6e83da5a31007cc3ded44c601f191e07999acb6db2314a896048d9036c';
public static readonly TEST_DISPLAY_NAME3 = 'tester_Charlie'; public static readonly TEST_DISPLAY_NAME3 = 'tester_Charlie';
/* ************** OPEN GROUPS ****************** */ /* ************** OPEN GROUPS ****************** */
public static readonly VALID_GROUP_URL = 'https://chat.getsession.org'; public static readonly VALID_GROUP_URL = 'https://chat.getsession.org';
public static readonly VALID_GROUP_URL2 = 'https://chat-dev.lokinet.org'; public static readonly VALID_GROUP_URL2 = 'https://chat-dev.lokinet.org';
public static readonly VALID_GROUP_NAME = 'Session Public Chat'; public static readonly VALID_GROUP_NAME = 'Session Public Chat';
public static readonly VALID_GROUP_NAME2 = 'Loki Dev Chat'; public static readonly VALID_GROUP_NAME2 = 'Loki Dev Chat';
/* ************** CLOSED GROUPS ****************** */ /* ************** CLOSED GROUPS ****************** */
public static readonly VALID_CLOSED_GROUP_NAME1 = 'Closed Group 1'; public static readonly VALID_CLOSED_GROUP_NAME1 = 'Closed Group 1';
public static USER_DATA_ROOT_FOLDER = ''; public static USER_DATA_ROOT_FOLDER = '';
private static stubSnode: any; private static stubSnode: any;
private static messages: any; private static messages: any;
private static fileServer: any; private static fileServer: any;
// tslint:disable: await-promise // tslint:disable: await-promise
// tslint:disable: no-console // tslint:disable: no-console
public static async timeout(ms: number) { public static async timeout(ms: number) {
// tslint:disable-next-line: no-string-based-set-timeout // tslint:disable-next-line: no-string-based-set-timeout
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
public static async closeToast(app: Application) { public static async closeToast(app: Application) {
app.client.element(CommonPage.toastCloseButton).click(); app.client.element(CommonPage.toastCloseButton).click();
} }
// a wrapper to work around electron/spectron bug // a wrapper to work around electron/spectron bug
public static async setValueWrapper(app: Application, selector: any, value: string) { public static async setValueWrapper(
app: Application,
selector: any,
value: string
) {
// keys, setValue and addValue hang on certain platforms // keys, setValue and addValue hang on certain platforms
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
await app.client.execute( await app.client.execute(
(slctr, val) => { (slctr, val) => {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const iter = document.evaluate( const iter = document.evaluate(
slctr, slctr,
document, document,
null, null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE, XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null null
); );
const elem = iter.iterateNext() as any; const elem = iter.iterateNext() as any;
if (elem) { if (elem) {
elem.value = val; elem.value = val;
} else { } else {
console.error('Cant find', slctr, elem, iter); console.error('Cant find', slctr, elem, iter);
} }
}, },
selector, selector,
value value
); );
// let session js detect the text change // let session js detect the text change
await app.client.element(selector).click(); await app.client.element(selector).click();
} else { } else {
// Linux & Windows don't require wrapper // Linux & Windows don't require wrapper
await app.client.element(selector).setValue(value); await app.client.element(selector).setValue(value);
} }
} }
public static async startApp(environment = 'test-integration-session') {
const env = environment.startsWith('test-integration')
? 'test-integration'
: environment;
const instance = environment.replace('test-integration-', '');
const app1 = new Application({
path: path.join(__dirname, '..', '..', '..', '..', 'node_modules', '.bin', 'electron'),
args: ['.'],
env: {
NODE_ENV: env,
NODE_APP_INSTANCE: instance,
USE_STUBBED_NETWORK: true,
ELECTRON_ENABLE_LOGGING: true,
ELECTRON_ENABLE_STACK_DUMPING: true,
ELECTRON_DISABLE_SANDBOX: 1,
},
requireName: 'electronRequire',
// chromeDriverLogPath: '../chromedriverlog.txt',
chromeDriverArgs: [
`remote-debugging-port=${Math.floor(
// tslint:disable-next-line: insecure-random
Math.random() * (9999 - 9000) + 9000
)}`,
],
});
// FIXME audric
// chaiAsPromised.transferPromiseness = app1.transferPromiseness;
await app1.start();
await app1.client.waitUntilWindowLoaded();
return app1;
}
public static async startApp2() { public static async startApp(environment = 'test-integration-session') {
const app2 = await Common.startApp('test-integration-session-2'); const env = environment.startsWith('test-integration')
return app2; ? 'test-integration'
} : environment;
const instance = environment.replace('test-integration-', '');
const app1 = new Application({
path: path.join(
__dirname,
'..',
'..',
'..',
'..',
'node_modules',
'.bin',
'electron'
),
args: ['.'],
env: {
NODE_ENV: env,
NODE_APP_INSTANCE: instance,
USE_STUBBED_NETWORK: true,
ELECTRON_ENABLE_LOGGING: true,
ELECTRON_ENABLE_STACK_DUMPING: true,
ELECTRON_DISABLE_SANDBOX: 1,
},
requireName: 'electronRequire',
// chromeDriverLogPath: '../chromedriverlog.txt',
chromeDriverArgs: [
`remote-debugging-port=${Math.floor(
// tslint:disable-next-line: insecure-random
Math.random() * (9999 - 9000) + 9000
)}`,
],
});
// FIXME audric
// chaiAsPromised.transferPromiseness = app1.transferPromiseness;
await app1.start();
await app1.client.waitUntilWindowLoaded();
return app1;
}
public static async stopApp(app1: Application) { public static async startApp2() {
if (app1 && app1.isRunning()) { const app2 = await Common.startApp('test-integration-session-2');
await app1.stop(); return app2;
} }
}
public static async killallElectron() { public static async stopApp(app1: Application) {
// rtharp - my 2nd client on MacOs needs: pkill -f "node_modules/.bin/electron" if (app1 && app1.isRunning()) {
// node_modules/electron/dist/electron is node_modules/electron/dist/Electron.app on MacOS await app1.stop();
const killStr =
process.platform === 'win32'
? 'taskkill /im electron.exe /t /f'
: 'pkill -f "node_modules/electron/dist/electron" | pkill -f "node_modules/.bin/electron"';
return new Promise(resolve => {
exec(killStr, (_err, stdout, stderr) => {
resolve({ stdout, stderr });
});
});
} }
}
public static async rmFolder(folder: string) { public static async killallElectron() {
await fse.remove(folder); // rtharp - my 2nd client on MacOs needs: pkill -f "node_modules/.bin/electron"
} // node_modules/electron/dist/electron is node_modules/electron/dist/Electron.app on MacOS
const killStr =
process.platform === 'win32'
? 'taskkill /im electron.exe /t /f'
: 'pkill -f "node_modules/electron/dist/electron" | pkill -f "node_modules/.bin/electron"';
return new Promise(resolve => {
exec(killStr, (_err, stdout, stderr) => {
resolve({ stdout, stderr });
});
});
}
public static async startAndAssureCleanedApp2() { public static async rmFolder(folder: string) {
const app2 = await Common.startAndAssureCleanedApp( await fse.remove(folder);
'test-integration-session-2' }
);
return app2;
}
public static async startAndAssureCleanedApp(env = 'test-integration-session') { public static async startAndAssureCleanedApp2() {
const userData = path.join(Common.USER_DATA_ROOT_FOLDER, `Session-${env}`); const app2 = await Common.startAndAssureCleanedApp(
'test-integration-session-2'
);
return app2;
}
await Common.rmFolder(userData); public static async startAndAssureCleanedApp(
env = 'test-integration-session'
) {
const userData = path.join(Common.USER_DATA_ROOT_FOLDER, `Session-${env}`);
const app1 = await Common.startApp(env); await Common.rmFolder(userData);
await app1.client.waitForExist(
RegistrationPage.registrationTabSignIn,
4000
);
return app1; const app1 = await Common.startApp(env);
} await app1.client.waitForExist(
RegistrationPage.registrationTabSignIn,
4000
);
public static async startAndStub({ return app1;
mnemonic, }
displayName,
env = 'test-integration-session',
}: {
mnemonic: string;
displayName: string;
env?: string;
}) {
const app = await Common.startAndAssureCleanedApp(env);
await Common.startStubSnodeServer();
if (mnemonic && displayName) {
await Common.restoreFromMnemonic(app, mnemonic, displayName);
// not sure we need Common - rtharp.
await Common.timeout(2000);
}
return app; public static async startAndStub({
mnemonic,
displayName,
env = 'test-integration-session',
}: {
mnemonic: string;
displayName: string;
env?: string;
}) {
const app = await Common.startAndAssureCleanedApp(env);
await Common.startStubSnodeServer();
if (mnemonic && displayName) {
await Common.restoreFromMnemonic(app, mnemonic, displayName);
// not sure we need Common - rtharp.
await Common.timeout(2000);
} }
public static async startAndStubN(props: any, n: number) { return app;
// Make app with stub as number n }
const appN = await Common.startAndStub({
env: `test-integration-session-${n}`,
...props,
});
return appN; public static async startAndStubN(props: any, n: number) {
} // Make app with stub as number n
const appN = await Common.startAndStub({
env: `test-integration-session-${n}`,
...props,
});
public static async restoreFromMnemonic(app: Application, mnemonic: string, displayName: string) { return appN;
await app.client.element(RegistrationPage.registrationTabSignIn).click(); }
await app.client.element(RegistrationPage.restoreFromSeedMode).click();
await Common.setValueWrapper(
app,
RegistrationPage.recoveryPhraseInput,
mnemonic
);
await Common.setValueWrapper( public static async restoreFromMnemonic(
app, app: Application,
RegistrationPage.displayNameInput, mnemonic: string,
displayName displayName: string
); ) {
await app.client.element(RegistrationPage.registrationTabSignIn).click();
await app.client.element(RegistrationPage.restoreFromSeedMode).click();
await Common.setValueWrapper(
app,
RegistrationPage.recoveryPhraseInput,
mnemonic
);
// await app.client.element(RegistrationPage.continueSessionButton).click(); await Common.setValueWrapper(
await app.client.keys('Enter'); app,
RegistrationPage.displayNameInput,
displayName
);
await app.client.waitForExist( // await app.client.element(RegistrationPage.continueSessionButton).click();
RegistrationPage.conversationListContainer, await app.client.keys('Enter');
4000
);
}
public static async makeFriends(app1: Application, client2: [Application, string]) { await app.client.waitForExist(
RegistrationPage.conversationListContainer,
4000
);
}
public static async makeFriends(
app1: Application,
client2: [Application, string]
) {
const [app2, pubkey2] = client2; const [app2, pubkey2] = client2;
/** add each other as friends */ /** add each other as friends */
@ -259,7 +280,11 @@ export class Common {
await app1.client.element(ConversationPage.contactsButtonSection).click(); await app1.client.element(ConversationPage.contactsButtonSection).click();
await app1.client.element(ConversationPage.addContactButton).click(); await app1.client.element(ConversationPage.addContactButton).click();
await Common.setValueWrapper(app1, ConversationPage.sessionIDInput, pubkey2); await Common.setValueWrapper(
app1,
ConversationPage.sessionIDInput,
pubkey2
);
await app1.client.element(ConversationPage.nextButton).click(); await app1.client.element(ConversationPage.nextButton).click();
await app1.client.waitForExist( await app1.client.waitForExist(
ConversationPage.sendFriendRequestTextarea, ConversationPage.sendFriendRequestTextarea,
@ -331,7 +356,10 @@ export class Common {
return [app1, app2]; return [app1, app2];
} }
public static async addFriendToNewClosedGroup(members: Array<Application>, useSenderKeys?: boolean) { public static async addFriendToNewClosedGroup(
members: Array<Application>,
useSenderKeys?: boolean
) {
const [app, ...others] = members; const [app, ...others] = members;
await app.client await app.client
@ -433,7 +461,11 @@ export class Common {
); );
} }
public static async linkApp2ToApp(app1: Application, app2: Application, app1Pubkey: string) { public static async linkApp2ToApp(
app1: Application,
app2: Application,
app1Pubkey: string
) {
// app needs to be logged in as user1 and app2 needs to be logged out // app needs to be logged in as user1 and app2 needs to be logged out
// start the pairing dialog for the first app // start the pairing dialog for the first app
await app1.client.element(SettingsPage.settingsButtonSection).click(); await app1.client.element(SettingsPage.settingsButtonSection).click();
@ -497,7 +529,10 @@ export class Common {
.should.eventually.be.equal(app1Pubkey); .should.eventually.be.equal(app1Pubkey);
} }
public static async triggerUnlinkApp2FromApp(app1: Application, app2: Application) { public static async triggerUnlinkApp2FromApp(
app1: Application,
app2: Application
) {
// check app2 is loggedin // check app2 is loggedin
await app2.client.isExisting(RegistrationPage.conversationListContainer) await app2.client.isExisting(RegistrationPage.conversationListContainer)
.should.eventually.be.true; .should.eventually.be.true;
@ -541,7 +576,11 @@ export class Common {
} }
} }
public static async sendMessage(app: Application, messageText: string, fileLocation?: string) { public static async sendMessage(
app: Application,
messageText: string,
fileLocation?: string
) {
await Common.setValueWrapper( await Common.setValueWrapper(
app, app,
ConversationPage.sendMessageTextarea, ConversationPage.sendMessageTextarea,
@ -567,7 +606,7 @@ export class Common {
} }
public static generateSendMessageText(): string { public static generateSendMessageText(): string {
return `Test message from integration tests ${Date.now()}`; return `Test message from integration tests ${Date.now()}`;
} }
public static async startStubSnodeServer() { public static async startStubSnodeServer() {
@ -584,17 +623,17 @@ export class Common {
return; return;
} }
if (Array.isArray(pubkey)) { if (Array.isArray(pubkey)) {
console.error('pubkey cannot be an array'); console.error('pubkey cannot be an array');
response.writeHead(400, { 'Content-Type': 'text/html' }); response.writeHead(400, { 'Content-Type': 'text/html' });
response.end(); response.end();
return; return;
} }
if (Array.isArray(data)) { if (Array.isArray(data)) {
console.error('data cannot be an array'); console.error('data cannot be an array');
response.writeHead(400, { 'Content-Type': 'text/html' }); response.writeHead(400, { 'Content-Type': 'text/html' });
response.end(); response.end();
return; return;
} }
if (request.method === 'POST') { if (request.method === 'POST') {
@ -647,7 +686,11 @@ export class Common {
} }
} }
public static async joinOpenGroup(app: Application, openGroupUrl: string, name: string) { public static async joinOpenGroup(
app: Application,
openGroupUrl: string,
name: string
) {
await app.client await app.client
.element(ConversationPage.conversationButtonSection) .element(ConversationPage.conversationButtonSection)
.click(); .click();
@ -699,7 +742,11 @@ export class Common {
* @param str the string to search (not regex) * @param str the string to search (not regex)
* Note: getRenderProcessLogs() clears the app logs each calls. * Note: getRenderProcessLogs() clears the app logs each calls.
*/ */
public static async logsContains(renderLogs: Array<{message: string}>, str: string, count?: number) { public static async logsContains(
renderLogs: Array<{ message: string }>,
str: string,
count?: number
) {
const foundLines = renderLogs.filter(log => log.message.includes(str)); const foundLines = renderLogs.filter(log => log.message.includes(str));
// tslint:disable-next-line: no-unused-expression // tslint:disable-next-line: no-unused-expression

@ -1,16 +1,7 @@
// import { expect } from 'chai';
// import * as sinon from 'sinon';
// import { TestUtils } from '../../test-utils';
// import { PairingAuthorisation } from '../../../../js/modules/data';
// import { MultiDeviceProtocol } from '../../../session/protocols';
// import { PubKey } from '../../../session/types';
// import { UserUtil } from '../../../util';
// import { StringUtils } from '../../../session/utils';
import { Common } from './common'; import { Common } from './common';
// tslint:disable: no-import-side-effect // tslint:disable: no-import-side-effect
// tslint:disable: await-promise
import './registration_test'; import './registration_test';
import './open_group_test'; import './open_group_test';
@ -26,9 +17,7 @@ before(async () => {
// start the app once before all tests to get the platform-dependent // start the app once before all tests to get the platform-dependent
// path of user data and store it to common.USER_DATA_ROOT_FOLDER // path of user data and store it to common.USER_DATA_ROOT_FOLDER
const app1 = await Common.startApp(); const app1 = await Common.startApp();
const ret = await app1.electron.remote.app.getPath( const ret = (await app1.electron.remote.app.getPath('appData')) as any;
'appData'
) as any;
Common.USER_DATA_ROOT_FOLDER = ret; Common.USER_DATA_ROOT_FOLDER = ret;
await Common.stopApp(app1); await Common.stopApp(app1);

@ -3,9 +3,13 @@
/* eslint-disable func-names */ /* eslint-disable func-names */
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
// tslint:disable: no-implicit-dependencies // tslint:disable: no-implicit-dependencies
// tslint:disable: await-promise
import { afterEach, beforeEach, describe, it } from 'mocha'; import { afterEach, beforeEach, describe, it } from 'mocha';
import { Common } from './common'; import { Common } from './common';
import { Application } from 'spectron'; import { Application } from 'spectron';
import * as TestUtils from '../../test-utils/utils/stubbing';
import { expect } from 'chai';
describe('Link Device', function() { describe('Link Device', function() {
let app: Application; let app: Application;
@ -44,27 +48,34 @@ describe('Link Device', function() {
}); });
it('linkDevice:sync no groups, closed group, nor open groups', async () => { it('linkDevice:sync no groups, closed group, nor open groups', async () => {
await TestUtils.spyMessageQueueSend(app);
await TestUtils.spyMessageQueueSend(app2);
await Common.linkApp2ToApp(app, app2, Common.TEST_PUBKEY1); await Common.linkApp2ToApp(app, app2, Common.TEST_PUBKEY1);
await Common.timeout(10000); await Common.timeout(10000);
const allMessagesSentApp = await TestUtils.getAllMessagesSent(app);
const allMessagesSentApp2 = await TestUtils.getAllMessagesSent(app2);
// get logs at this stage (getRenderProcessLogs() clears the app logs) expect(allMessagesSentApp2[0][1]).to.have.property('requestSignature');
const secondaryRenderLogs = await app2.client.getRenderProcessLogs(); expect(allMessagesSentApp2[0][1]).to.have.property(
// pairing request message sent from secondary to primary pubkey 'primaryDevicePubKey',
await Common.logsContains( Common.TEST_PUBKEY1
secondaryRenderLogs,
`Sending pairing-request:pairing-request message to ${Common.TEST_PUBKEY1}`
); );
expect(allMessagesSentApp2[0][1]).to.have.property('secondaryDevicePubKey');
const primaryRenderLogs = await app.client.getRenderProcessLogs(); expect(allMessagesSentApp[1][1]).to.have.property('requestSignature');
// primary grant pairing request expect(allMessagesSentApp[1][1]).to.have.property('grantSignature');
await Common.logsContains( expect(allMessagesSentApp[1][1]).to.have.property(
primaryRenderLogs, 'displayName',
'Sending pairing-request:pairing-request message to OUR SECONDARY PUBKEY' Common.TEST_DISPLAY_NAME1
);
expect(allMessagesSentApp[1][1]).to.have.property(
'primaryDevicePubKey',
Common.TEST_PUBKEY1
); );
expect(allMessagesSentApp[1][1]).to.have.property('secondaryDevicePubKey');
// no friends, no closed groups, no open groups. we should see those message sync in the log // one message for session establishment, one for grant authorization. No group or anything to sync
await Common.logsContains(primaryRenderLogs, 'No closed group to sync.', 1); expect(allMessagesSentApp.length).to.be.equal(2);
await Common.logsContains(primaryRenderLogs, 'No open groups to sync', 1);
await Common.logsContains(primaryRenderLogs, 'No contacts to sync.', 1);
}); });
}); });

@ -17,7 +17,8 @@ export = {
textAreaWithClass: (classname: string) => textAreaWithClass: (classname: string) =>
`//textarea[contains(@class, "${classname}")]`, `//textarea[contains(@class, "${classname}")]`,
byId: (id: string) => `//*[@id="${id}"]`, byId: (id: string) => `//*[@id="${id}"]`,
divWithClass: (classname: string) => `//div[contains(@class, "${classname}")]`, divWithClass: (classname: string) =>
`//div[contains(@class, "${classname}")]`,
divWithClassAndText: (classname: string, text: string) => divWithClassAndText: (classname: string, text: string) =>
module.exports.objWithClassAndText('div', classname, text), module.exports.objWithClassAndText('div', classname, text),
spanWithClassAndText: (classname: string, text: string) => spanWithClassAndText: (classname: string, text: string) =>

@ -1,6 +1,5 @@
import commonPage from './common.page'; import commonPage from './common.page';
export = { export = {
registrationTabSignIn: registrationTabSignIn:
'//div[contains(string(), "Sign In")][contains(@class, "session-registration__tab")][contains(@role, "tab")]', '//div[contains(string(), "Sign In")][contains(@class, "session-registration__tab")][contains(@role, "tab")]',
@ -36,6 +35,11 @@ export = {
), ),
linkDeviceTriggerButton: commonPage.divRoleButtonWithText('Link Device'), linkDeviceTriggerButton: commonPage.divRoleButtonWithText('Link Device'),
toastWrapper: '//*[contains(@class,"session-toast-wrapper")]', toastWrapper: '//*[contains(@class,"session-toast-wrapper")]',
secretWordsText: '//div[contains(@class,"session-registration__content__secret-words")]/div[contains(@class,"subtle")]', secretWordsText:
linkWithThisDevice: commonPage.objWithClassAndText('h4', 'device-pairing-dialog__desc', 'Allow linking with this device?'), '//div[contains(@class,"session-registration__content__secret-words")]/div[contains(@class,"subtle")]',
linkWithThisDevice: commonPage.objWithClassAndText(
'h4',
'device-pairing-dialog__desc',
'Allow linking with this device?'
),
}; };

@ -5,7 +5,8 @@ export = {
settingsRowWithText: (text: string) => settingsRowWithText: (text: string) =>
`//*[contains(@class, "left-pane-setting-category-list-item")][contains(string(), '${text}')]`, `//*[contains(@class, "left-pane-setting-category-list-item")][contains(string(), '${text}')]`,
leftPaneSettingsButton: '//*[contains(@class,"session-icon-button") and .//*[contains(@class, "gear")]]', leftPaneSettingsButton:
'//*[contains(@class,"session-icon-button") and .//*[contains(@class, "gear")]]',
settingToggleWithText: (text: string) => settingToggleWithText: (text: string) =>
`//div[contains(@class, 'session-settings-item') and contains(string(), '${text}')]//*[contains(@class, 'session-toggle')]`, `//div[contains(@class, 'session-settings-item') and contains(string(), '${text}')]//*[contains(@class, 'session-toggle')]`,
@ -15,7 +16,7 @@ export = {
`//div[contains(@class, 'left-pane-setting-category-list-item') and contains(string(), '${text}')]`, `//div[contains(@class, 'left-pane-setting-category-list-item') and contains(string(), '${text}')]`,
// Confirm is a boolean. Selects confirmation input // Confirm is a boolean. Selects confirmation input
passwordSetModalInput: (_confirm: boolean|undefined) => passwordSetModalInput: (_confirm: boolean | undefined) =>
`//input[@id = 'password-modal-input${_confirm ? '-confirm' : ''}']`, `//input[@id = 'password-modal-input${_confirm ? '-confirm' : ''}']`,
secretWordsTextInDialog: secretWordsTextInDialog:

@ -12,7 +12,6 @@ import SettingsPage from './page-objects/settings.page';
import RegistrationPage from './page-objects/registration.page'; import RegistrationPage from './page-objects/registration.page';
import ConversationPage from './page-objects/conversation.page'; import ConversationPage from './page-objects/conversation.page';
describe('Window Test and Login', function() { describe('Window Test and Login', function() {
let app: Application; let app: Application;
this.timeout(20000); this.timeout(20000);

@ -1,11 +1,7 @@
import chai from 'chai'; import chai from 'chai';
import * as sinon from 'sinon'; import * as sinon from 'sinon';
import _ from 'lodash'; import _ from 'lodash';
import { import { GroupUtils, PromiseUtils } from '../../../session/utils';
GroupUtils,
PromiseUtils,
SyncMessageUtils,
} from '../../../session/utils';
import { Stubs, TestUtils } from '../../../test/test-utils'; import { Stubs, TestUtils } from '../../../test/test-utils';
import { MessageQueue } from '../../../session/sending/MessageQueue'; import { MessageQueue } from '../../../session/sending/MessageQueue';
import { import {

Loading…
Cancel
Save