mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-25 10:58:19 +01:00
eslintify all test files
This commit is contained in:
25
libtextsecure/test/.eslintrc
Normal file
25
libtextsecure/test/.eslintrc
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": false,
|
||||
"mocha": true,
|
||||
},
|
||||
"parserOptions": {
|
||||
"sourceType": "script"
|
||||
},
|
||||
"rules": {
|
||||
"strict": "off",
|
||||
"more/no-then": "off",
|
||||
},
|
||||
"globals": {
|
||||
"assert": true,
|
||||
"assertEqualArrayBuffers": true,
|
||||
"dcodeIO": true,
|
||||
"getString": true,
|
||||
"hexToArrayBuffer": true,
|
||||
"MockServer": true,
|
||||
"MockSocket": true,
|
||||
"PROTO_ROOT": true,
|
||||
"stringToArrayBuffer": true,
|
||||
}
|
||||
}
|
||||
@@ -1,57 +1,59 @@
|
||||
/* global mocha, chai, assert */
|
||||
|
||||
mocha.setup('bdd');
|
||||
window.assert = chai.assert;
|
||||
window.PROTO_ROOT = '../../protos';
|
||||
|
||||
(function() {
|
||||
const OriginalReporter = mocha._reporter;
|
||||
const OriginalReporter = mocha._reporter;
|
||||
|
||||
const SauceReporter = function(runner) {
|
||||
const failedTests = [];
|
||||
const SauceReporter = runner => {
|
||||
const failedTests = [];
|
||||
|
||||
runner.on('end', () => {
|
||||
window.mochaResults = runner.stats;
|
||||
window.mochaResults.reports = failedTests;
|
||||
runner.on('end', () => {
|
||||
window.mochaResults = runner.stats;
|
||||
window.mochaResults.reports = failedTests;
|
||||
});
|
||||
|
||||
runner.on('fail', (test, err) => {
|
||||
const flattenTitles = item => {
|
||||
const titles = [];
|
||||
while (item.parent.title) {
|
||||
titles.push(item.parent.title);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
item = item.parent;
|
||||
}
|
||||
return titles.reverse();
|
||||
};
|
||||
failedTests.push({
|
||||
name: test.title,
|
||||
result: false,
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
titles: flattenTitles(test),
|
||||
});
|
||||
});
|
||||
|
||||
runner.on('fail', (test, err) => {
|
||||
const flattenTitles = function(test) {
|
||||
const titles = [];
|
||||
while (test.parent.title) {
|
||||
titles.push(test.parent.title);
|
||||
test = test.parent;
|
||||
}
|
||||
return titles.reverse();
|
||||
};
|
||||
failedTests.push({
|
||||
name: test.title,
|
||||
result: false,
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
titles: flattenTitles(test),
|
||||
});
|
||||
});
|
||||
// eslint-disable-next-line no-new
|
||||
new OriginalReporter(runner);
|
||||
};
|
||||
|
||||
new OriginalReporter(runner);
|
||||
};
|
||||
SauceReporter.prototype = OriginalReporter.prototype;
|
||||
|
||||
SauceReporter.prototype = OriginalReporter.prototype;
|
||||
|
||||
mocha.reporter(SauceReporter);
|
||||
})();
|
||||
mocha.reporter(SauceReporter);
|
||||
|
||||
/*
|
||||
* global helpers for tests
|
||||
*/
|
||||
function assertEqualArrayBuffers(ab1, ab2) {
|
||||
window.assertEqualArrayBuffers = (ab1, ab2) => {
|
||||
assert.deepEqual(new Uint8Array(ab1), new Uint8Array(ab2));
|
||||
}
|
||||
};
|
||||
|
||||
function hexToArrayBuffer(str) {
|
||||
window.hexToArrayBuffer = str => {
|
||||
const ret = new ArrayBuffer(str.length / 2);
|
||||
const array = new Uint8Array(ret);
|
||||
for (let i = 0; i < str.length / 2; i++)
|
||||
for (let i = 0; i < str.length / 2; i += 1)
|
||||
array[i] = parseInt(str.substr(i * 2, 2), 16);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
window.MockSocket.prototype.addEventListener = function() {};
|
||||
window.MockSocket.prototype.addEventListener = () => null;
|
||||
|
||||
@@ -46,7 +46,7 @@ describe('AccountManager', () => {
|
||||
return accountManager.cleanSignedPreKeys();
|
||||
});
|
||||
|
||||
it('eliminates confirmed keys over a week old, if more than three', () => {
|
||||
it('eliminates confirmed keys over a week old, if more than three', async () => {
|
||||
const now = Date.now();
|
||||
signedPreKeys = [
|
||||
{
|
||||
@@ -77,20 +77,19 @@ describe('AccountManager', () => {
|
||||
];
|
||||
|
||||
let count = 0;
|
||||
window.textsecure.storage.protocol.removeSignedPreKey = function(keyId) {
|
||||
window.textsecure.storage.protocol.removeSignedPreKey = keyId => {
|
||||
if (keyId !== 1 && keyId !== 4) {
|
||||
throw new Error(`Wrong keys were eliminated! ${keyId}`);
|
||||
}
|
||||
|
||||
count++;
|
||||
count += 1;
|
||||
};
|
||||
|
||||
return accountManager.cleanSignedPreKeys().then(() => {
|
||||
assert.strictEqual(count, 2);
|
||||
});
|
||||
await accountManager.cleanSignedPreKeys();
|
||||
assert.strictEqual(count, 2);
|
||||
});
|
||||
|
||||
it('keeps at least three unconfirmed keys if no confirmed', () => {
|
||||
it('keeps at least three unconfirmed keys if no confirmed', async () => {
|
||||
const now = Date.now();
|
||||
signedPreKeys = [
|
||||
{
|
||||
@@ -112,20 +111,19 @@ describe('AccountManager', () => {
|
||||
];
|
||||
|
||||
let count = 0;
|
||||
window.textsecure.storage.protocol.removeSignedPreKey = function(keyId) {
|
||||
window.textsecure.storage.protocol.removeSignedPreKey = keyId => {
|
||||
if (keyId !== 2) {
|
||||
throw new Error(`Wrong keys were eliminated! ${keyId}`);
|
||||
}
|
||||
|
||||
count++;
|
||||
count += 1;
|
||||
};
|
||||
|
||||
return accountManager.cleanSignedPreKeys().then(() => {
|
||||
assert.strictEqual(count, 1);
|
||||
});
|
||||
await accountManager.cleanSignedPreKeys();
|
||||
assert.strictEqual(count, 1);
|
||||
});
|
||||
|
||||
it('if some confirmed keys, keeps unconfirmed to addd up to three total', () => {
|
||||
it('if some confirmed keys, keeps unconfirmed to addd up to three total', async () => {
|
||||
const now = Date.now();
|
||||
signedPreKeys = [
|
||||
{
|
||||
@@ -149,17 +147,16 @@ describe('AccountManager', () => {
|
||||
];
|
||||
|
||||
let count = 0;
|
||||
window.textsecure.storage.protocol.removeSignedPreKey = function(keyId) {
|
||||
window.textsecure.storage.protocol.removeSignedPreKey = keyId => {
|
||||
if (keyId !== 3) {
|
||||
throw new Error(`Wrong keys were eliminated! ${keyId}`);
|
||||
}
|
||||
|
||||
count++;
|
||||
count += 1;
|
||||
};
|
||||
|
||||
return accountManager.cleanSignedPreKeys().then(() => {
|
||||
assert.strictEqual(count, 1);
|
||||
});
|
||||
await accountManager.cleanSignedPreKeys();
|
||||
assert.strictEqual(count, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/* global ContactBuffer, GroupBuffer, textsecure */
|
||||
|
||||
describe('ContactBuffer', () => {
|
||||
function getTestBuffer() {
|
||||
const buffer = new dcodeIO.ByteBuffer();
|
||||
const avatarBuffer = new dcodeIO.ByteBuffer();
|
||||
const avatarLen = 255;
|
||||
for (var i = 0; i < avatarLen; ++i) {
|
||||
for (let i = 0; i < avatarLen; i += 1) {
|
||||
avatarBuffer.writeUint8(i);
|
||||
}
|
||||
avatarBuffer.limit = avatarBuffer.offset;
|
||||
@@ -15,7 +17,7 @@ describe('ContactBuffer', () => {
|
||||
});
|
||||
const contactInfoBuffer = contactInfo.encode().toArrayBuffer();
|
||||
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
for (let i = 0; i < 3; i += 1) {
|
||||
buffer.writeVarint32(contactInfoBuffer.byteLength);
|
||||
buffer.append(contactInfoBuffer);
|
||||
buffer.append(avatarBuffer.clone());
|
||||
@@ -32,14 +34,14 @@ describe('ContactBuffer', () => {
|
||||
let contact = contactBuffer.next();
|
||||
let count = 0;
|
||||
while (contact !== undefined) {
|
||||
count++;
|
||||
count += 1;
|
||||
assert.strictEqual(contact.name, 'Zero Cool');
|
||||
assert.strictEqual(contact.number, '+10000000000');
|
||||
assert.strictEqual(contact.avatar.contentType, 'image/jpeg');
|
||||
assert.strictEqual(contact.avatar.length, 255);
|
||||
assert.strictEqual(contact.avatar.data.byteLength, 255);
|
||||
const avatarBytes = new Uint8Array(contact.avatar.data);
|
||||
for (let j = 0; j < 255; ++j) {
|
||||
for (let j = 0; j < 255; j += 1) {
|
||||
assert.strictEqual(avatarBytes[j], j);
|
||||
}
|
||||
contact = contactBuffer.next();
|
||||
@@ -53,7 +55,7 @@ describe('GroupBuffer', () => {
|
||||
const buffer = new dcodeIO.ByteBuffer();
|
||||
const avatarBuffer = new dcodeIO.ByteBuffer();
|
||||
const avatarLen = 255;
|
||||
for (var i = 0; i < avatarLen; ++i) {
|
||||
for (let i = 0; i < avatarLen; i += 1) {
|
||||
avatarBuffer.writeUint8(i);
|
||||
}
|
||||
avatarBuffer.limit = avatarBuffer.offset;
|
||||
@@ -66,7 +68,7 @@ describe('GroupBuffer', () => {
|
||||
});
|
||||
const groupInfoBuffer = groupInfo.encode().toArrayBuffer();
|
||||
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
for (let i = 0; i < 3; i += 1) {
|
||||
buffer.writeVarint32(groupInfoBuffer.byteLength);
|
||||
buffer.append(groupInfoBuffer);
|
||||
buffer.append(avatarBuffer.clone());
|
||||
@@ -83,7 +85,7 @@ describe('GroupBuffer', () => {
|
||||
let group = groupBuffer.next();
|
||||
let count = 0;
|
||||
while (group !== undefined) {
|
||||
count++;
|
||||
count += 1;
|
||||
assert.strictEqual(group.name, 'Hackers');
|
||||
assertEqualArrayBuffers(
|
||||
group.id.toArrayBuffer(),
|
||||
@@ -94,7 +96,7 @@ describe('GroupBuffer', () => {
|
||||
assert.strictEqual(group.avatar.length, 255);
|
||||
assert.strictEqual(group.avatar.data.byteLength, 255);
|
||||
const avatarBytes = new Uint8Array(group.avatar.data);
|
||||
for (let j = 0; j < 255; ++j) {
|
||||
for (let j = 0; j < 255; j += 1) {
|
||||
assert.strictEqual(avatarBytes[j], j);
|
||||
}
|
||||
group = groupBuffer.next();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* global libsignal, textsecure */
|
||||
|
||||
describe('encrypting and decrypting profile data', () => {
|
||||
const NAME_PADDED_LENGTH = 26;
|
||||
describe('encrypting and decrypting profile names', () => {
|
||||
@@ -61,12 +63,12 @@ describe('encrypting and decrypting profile data', () => {
|
||||
'This is an avatar'
|
||||
).toArrayBuffer();
|
||||
const key = libsignal.crypto.getRandomBytes(32);
|
||||
const bad_key = libsignal.crypto.getRandomBytes(32);
|
||||
const badKey = libsignal.crypto.getRandomBytes(32);
|
||||
|
||||
return textsecure.crypto.encryptProfile(buffer, key).then(encrypted => {
|
||||
assert(encrypted.byteLength === buffer.byteLength + 16 + 12);
|
||||
return textsecure.crypto
|
||||
.decryptProfile(encrypted, bad_key)
|
||||
.decryptProfile(encrypted, badKey)
|
||||
.catch(error => {
|
||||
assert.strictEqual(error.name, 'ProfileDecryptError');
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ const fakeAPI = {
|
||||
// sendMessages: fakeCall,
|
||||
setSignedPreKey: fakeCall,
|
||||
|
||||
getKeysForNumber(number, deviceId) {
|
||||
getKeysForNumber(number) {
|
||||
const res = getKeysForNumberMap[number];
|
||||
if (res !== undefined) {
|
||||
delete getKeysForNumberMap[number];
|
||||
@@ -32,14 +32,14 @@ const fakeAPI = {
|
||||
},
|
||||
|
||||
sendMessages(destination, messageArray) {
|
||||
for (i in messageArray) {
|
||||
for (let i = 0, max = messageArray.length; i < max; i += 1) {
|
||||
const msg = messageArray[i];
|
||||
if (
|
||||
(msg.type != 1 && msg.type != 3) ||
|
||||
(msg.type !== 1 && msg.type !== 3) ||
|
||||
msg.destinationDeviceId === undefined ||
|
||||
msg.destinationRegistrationId === undefined ||
|
||||
msg.body === undefined ||
|
||||
msg.timestamp == undefined ||
|
||||
msg.timestamp === undefined ||
|
||||
msg.relay !== undefined ||
|
||||
msg.destination !== undefined
|
||||
)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
describe('Key generation', function() {
|
||||
/* global libsignal, textsecure */
|
||||
|
||||
describe('Key generation', function thisNeeded() {
|
||||
const count = 10;
|
||||
this.timeout(count * 2000);
|
||||
|
||||
@@ -60,7 +62,7 @@ describe('Key generation', function() {
|
||||
result = res;
|
||||
});
|
||||
});
|
||||
for (let i = 1; i <= count; i++) {
|
||||
for (let i = 1; i <= count; i += 1) {
|
||||
itStoresPreKey(i);
|
||||
}
|
||||
itStoresSignedPreKey(1);
|
||||
@@ -68,12 +70,12 @@ describe('Key generation', function() {
|
||||
it(`result contains ${count} preKeys`, () => {
|
||||
assert.isArray(result.preKeys);
|
||||
assert.lengthOf(result.preKeys, count);
|
||||
for (let i = 0; i < count; i++) {
|
||||
for (let i = 0; i < count; i += 1) {
|
||||
assert.isObject(result.preKeys[i]);
|
||||
}
|
||||
});
|
||||
it('result contains the correct keyIds', () => {
|
||||
for (let i = 0; i < count; i++) {
|
||||
for (let i = 0; i < count; i += 1) {
|
||||
assert.strictEqual(result.preKeys[i].keyId, i + 1);
|
||||
}
|
||||
});
|
||||
@@ -93,7 +95,7 @@ describe('Key generation', function() {
|
||||
result = res;
|
||||
});
|
||||
});
|
||||
for (let i = 1; i <= 2 * count; i++) {
|
||||
for (let i = 1; i <= 2 * count; i += 1) {
|
||||
itStoresPreKey(i);
|
||||
}
|
||||
itStoresSignedPreKey(1);
|
||||
@@ -101,12 +103,12 @@ describe('Key generation', function() {
|
||||
it(`result contains ${count} preKeys`, () => {
|
||||
assert.isArray(result.preKeys);
|
||||
assert.lengthOf(result.preKeys, count);
|
||||
for (let i = 0; i < count; i++) {
|
||||
for (let i = 0; i < count; i += 1) {
|
||||
assert.isObject(result.preKeys[i]);
|
||||
}
|
||||
});
|
||||
it('result contains the correct keyIds', () => {
|
||||
for (let i = 1; i <= count; i++) {
|
||||
for (let i = 1; i <= count; i += 1) {
|
||||
assert.strictEqual(result.preKeys[i - 1].keyId, i + count);
|
||||
}
|
||||
});
|
||||
@@ -126,7 +128,7 @@ describe('Key generation', function() {
|
||||
result = res;
|
||||
});
|
||||
});
|
||||
for (let i = 1; i <= 3 * count; i++) {
|
||||
for (let i = 1; i <= 3 * count; i += 1) {
|
||||
itStoresPreKey(i);
|
||||
}
|
||||
itStoresSignedPreKey(2);
|
||||
@@ -134,12 +136,12 @@ describe('Key generation', function() {
|
||||
it(`result contains ${count} preKeys`, () => {
|
||||
assert.isArray(result.preKeys);
|
||||
assert.lengthOf(result.preKeys, count);
|
||||
for (let i = 0; i < count; i++) {
|
||||
for (let i = 0; i < count; i += 1) {
|
||||
assert.isObject(result.preKeys[i]);
|
||||
}
|
||||
});
|
||||
it('result contains the correct keyIds', () => {
|
||||
for (let i = 1; i <= count; i++) {
|
||||
for (let i = 1; i <= count; i += 1) {
|
||||
assert.strictEqual(result.preKeys[i - 1].keyId, i + 2 * count);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -12,7 +12,6 @@ describe('Helpers', () => {
|
||||
|
||||
describe('stringToArrayBuffer', () => {
|
||||
it('returns ArrayBuffer when passed string', () => {
|
||||
const StaticArrayBufferProto = new ArrayBuffer().__proto__;
|
||||
const anArrayBuffer = new ArrayBuffer(1);
|
||||
const typedArray = new Uint8Array(anArrayBuffer);
|
||||
typedArray[0] = 'a'.charCodeAt(0);
|
||||
|
||||
@@ -36,10 +36,10 @@ SignalProtocolStore.prototype = {
|
||||
|
||||
isTrustedIdentity(identifier, identityKey) {
|
||||
if (identifier === null || identifier === undefined) {
|
||||
throw new error('tried to check identity key for undefined/null key');
|
||||
throw new Error('tried to check identity key for undefined/null key');
|
||||
}
|
||||
if (!(identityKey instanceof ArrayBuffer)) {
|
||||
throw new error('Expected identityKey to be an ArrayBuffer');
|
||||
throw new Error('Expected identityKey to be an ArrayBuffer');
|
||||
}
|
||||
const trusted = this.get(`identityKey${identifier}`);
|
||||
if (trusted === undefined) {
|
||||
@@ -96,9 +96,11 @@ SignalProtocolStore.prototype = {
|
||||
loadSignedPreKeys() {
|
||||
return new Promise(resolve => {
|
||||
const res = [];
|
||||
for (const i in this.store) {
|
||||
if (i.startsWith('25519KeysignedKey')) {
|
||||
res.push(this.store[i]);
|
||||
const keys = Object.keys(this.store);
|
||||
for (let i = 0, max = keys.length; i < max; i += 1) {
|
||||
const key = keys[i];
|
||||
if (key.startsWith('25519KeysignedKey')) {
|
||||
res.push(this.store[key]);
|
||||
}
|
||||
}
|
||||
resolve(res);
|
||||
@@ -127,7 +129,9 @@ SignalProtocolStore.prototype = {
|
||||
},
|
||||
removeAllSessions(identifier) {
|
||||
return new Promise(resolve => {
|
||||
for (key in this.store) {
|
||||
const keys = Object.keys(this.store);
|
||||
for (let i = 0, max = keys.length; i < max; i += 1) {
|
||||
const key = keys[i];
|
||||
if (key.match(RegExp(`^session${identifier.replace('+', '\\+')}.+`))) {
|
||||
delete this.store[key];
|
||||
}
|
||||
@@ -138,9 +142,11 @@ SignalProtocolStore.prototype = {
|
||||
getDeviceIds(identifier) {
|
||||
return new Promise(resolve => {
|
||||
const deviceIds = [];
|
||||
for (key in this.store) {
|
||||
const keys = Object.keys(this.store);
|
||||
for (let i = 0, max = keys.length; i < max; i += 1) {
|
||||
const key = keys[i];
|
||||
if (key.match(RegExp(`^session${identifier.replace('+', '\\+')}.+`))) {
|
||||
deviceIds.push(parseInt(key.split('.')[1]));
|
||||
deviceIds.push(parseInt(key.split('.')[1], 10));
|
||||
}
|
||||
}
|
||||
resolve(deviceIds);
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* global libsignal, textsecure, SignalProtocolStore */
|
||||
|
||||
describe('MessageReceiver', () => {
|
||||
textsecure.storage.impl = new SignalProtocolStore();
|
||||
const WebSocket = window.WebSocket;
|
||||
const { WebSocket } = window;
|
||||
const number = '+19999999999';
|
||||
const deviceId = 1;
|
||||
const signalingKey = libsignal.crypto.getRandomBytes(32 + 20);
|
||||
|
||||
before(() => {
|
||||
window.WebSocket = MockSocket;
|
||||
textsecure.storage.user.setNumberAndDeviceId(number, deviceId, 'name');
|
||||
@@ -15,7 +18,6 @@ describe('MessageReceiver', () => {
|
||||
});
|
||||
|
||||
describe('connecting', () => {
|
||||
const blob = null;
|
||||
const attrs = {
|
||||
type: textsecure.protobuf.Envelope.Type.CIPHERTEXT,
|
||||
source: number,
|
||||
@@ -29,14 +31,12 @@ describe('MessageReceiver', () => {
|
||||
|
||||
before(done => {
|
||||
const signal = new textsecure.protobuf.Envelope(attrs).toArrayBuffer();
|
||||
const data = new textsecure.protobuf.DataMessage({ body: 'hello' });
|
||||
|
||||
const signaling_key = signalingKey;
|
||||
const aes_key = signaling_key.slice(0, 32);
|
||||
const mac_key = signaling_key.slice(32, 32 + 20);
|
||||
const aesKey = signalingKey.slice(0, 32);
|
||||
const macKey = signalingKey.slice(32, 32 + 20);
|
||||
|
||||
window.crypto.subtle
|
||||
.importKey('raw', aes_key, { name: 'AES-CBC' }, false, ['encrypt'])
|
||||
.importKey('raw', aesKey, { name: 'AES-CBC' }, false, ['encrypt'])
|
||||
.then(key => {
|
||||
const iv = libsignal.crypto.getRandomBytes(16);
|
||||
window.crypto.subtle
|
||||
@@ -45,14 +45,14 @@ describe('MessageReceiver', () => {
|
||||
window.crypto.subtle
|
||||
.importKey(
|
||||
'raw',
|
||||
mac_key,
|
||||
macKey,
|
||||
{ name: 'HMAC', hash: { name: 'SHA-256' } },
|
||||
false,
|
||||
['sign']
|
||||
)
|
||||
.then(key => {
|
||||
.then(innerKey => {
|
||||
window.crypto.subtle
|
||||
.sign({ name: 'HMAC', hash: 'SHA-256' }, key, signal)
|
||||
.sign({ name: 'HMAC', hash: 'SHA-256' }, innerKey, signal)
|
||||
.then(mac => {
|
||||
const version = new Uint8Array([1]);
|
||||
const message = dcodeIO.ByteBuffer.concat([
|
||||
@@ -82,14 +82,19 @@ describe('MessageReceiver', () => {
|
||||
|
||||
window.addEventListener('textsecure:message', ev => {
|
||||
const signal = ev.proto;
|
||||
for (const key in attrs) {
|
||||
const keys = Object.keys(attrs);
|
||||
|
||||
for (let i = 0, max = keys.length; i < max; i += 1) {
|
||||
const key = keys[i];
|
||||
assert.strictEqual(attrs[key], signal[key]);
|
||||
}
|
||||
assert.strictEqual(signal.message.body, 'hello');
|
||||
server.close();
|
||||
mockServer.close();
|
||||
|
||||
done();
|
||||
});
|
||||
const messageReceiver = new textsecure.MessageReceiver(
|
||||
|
||||
window.messageReceiver = new textsecure.MessageReceiver(
|
||||
'username',
|
||||
'password',
|
||||
'signalingKey'
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
/* global textsecure */
|
||||
|
||||
describe('Protocol', () => {
|
||||
describe('Unencrypted PushMessageProto "decrypt"', () => {
|
||||
// exclusive
|
||||
it('works', done => {
|
||||
localStorage.clear();
|
||||
|
||||
const text_message = new textsecure.protobuf.DataMessage();
|
||||
text_message.body = 'Hi Mom';
|
||||
const server_message = {
|
||||
const textMessage = new textsecure.protobuf.DataMessage();
|
||||
textMessage.body = 'Hi Mom';
|
||||
const serverMessage = {
|
||||
type: 4, // unencrypted
|
||||
source: '+19999999999',
|
||||
timestamp: 42,
|
||||
message: text_message.encode(),
|
||||
message: textMessage.encode(),
|
||||
};
|
||||
|
||||
return textsecure.protocol_wrapper
|
||||
.handleEncryptedMessage(
|
||||
server_message.source,
|
||||
server_message.source_device,
|
||||
server_message.type,
|
||||
server_message.message
|
||||
serverMessage.source,
|
||||
serverMessage.source_device,
|
||||
serverMessage.type,
|
||||
serverMessage.message
|
||||
)
|
||||
.then(message => {
|
||||
assert.equal(message.body, text_message.body);
|
||||
assert.equal(message.body, textMessage.body);
|
||||
assert.equal(
|
||||
message.attachments.length,
|
||||
text_message.attachments.length
|
||||
textMessage.attachments.length
|
||||
);
|
||||
assert.equal(text_message.attachments.length, 0);
|
||||
assert.equal(textMessage.attachments.length, 0);
|
||||
})
|
||||
.then(done)
|
||||
.catch(done);
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
describe('Protocol Wrapper', function() {
|
||||
/* global libsignal, textsecure */
|
||||
|
||||
describe('Protocol Wrapper', function thisNeeded() {
|
||||
const store = textsecure.storage.protocol;
|
||||
const identifier = '+5558675309';
|
||||
const another_identifier = '+5555590210';
|
||||
let prekeys, identityKey, testKey;
|
||||
|
||||
this.timeout(5000);
|
||||
|
||||
before(done => {
|
||||
localStorage.clear();
|
||||
libsignal.KeyHelper.generateIdentityKeyPair()
|
||||
.then(identityKey =>
|
||||
textsecure.storage.protocol.saveIdentity(identifier, identityKey)
|
||||
)
|
||||
.then(key => textsecure.storage.protocol.saveIdentity(identifier, key))
|
||||
.then(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('processPreKey', () => {
|
||||
it('rejects if the identity key changes', () => {
|
||||
const address = new libsignal.SignalProtocolAddress(identifier, 1);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/* global libsignal, textsecure */
|
||||
|
||||
describe('SignalProtocolStore', () => {
|
||||
before(() => {
|
||||
localStorage.clear();
|
||||
});
|
||||
const store = textsecure.storage.protocol;
|
||||
const identifier = '+5558675309';
|
||||
const another_identifier = '+5555590210';
|
||||
const identityKey = {
|
||||
pubKey: libsignal.crypto.getRandomBytes(33),
|
||||
privKey: libsignal.crypto.getRandomBytes(32),
|
||||
@@ -13,176 +14,121 @@ describe('SignalProtocolStore', () => {
|
||||
pubKey: libsignal.crypto.getRandomBytes(33),
|
||||
privKey: libsignal.crypto.getRandomBytes(32),
|
||||
};
|
||||
it('retrieves my registration id', done => {
|
||||
it('retrieves my registration id', async () => {
|
||||
store.put('registrationId', 1337);
|
||||
store
|
||||
.getLocalRegistrationId()
|
||||
.then(reg => {
|
||||
assert.strictEqual(reg, 1337);
|
||||
})
|
||||
.then(done, done);
|
||||
|
||||
const reg = await store.getLocalRegistrationId();
|
||||
assert.strictEqual(reg, 1337);
|
||||
});
|
||||
it('retrieves my identity key', done => {
|
||||
it('retrieves my identity key', async () => {
|
||||
store.put('identityKey', identityKey);
|
||||
store
|
||||
.getIdentityKeyPair()
|
||||
.then(key => {
|
||||
assertEqualArrayBuffers(key.pubKey, identityKey.pubKey);
|
||||
assertEqualArrayBuffers(key.privKey, identityKey.privKey);
|
||||
const key = await store.getIdentityKeyPair();
|
||||
assertEqualArrayBuffers(key.pubKey, identityKey.pubKey);
|
||||
assertEqualArrayBuffers(key.privKey, identityKey.privKey);
|
||||
});
|
||||
it('stores identity keys', async () => {
|
||||
await store.saveIdentity(identifier, testKey.pubKey);
|
||||
const key = await store.loadIdentityKey(identifier);
|
||||
assertEqualArrayBuffers(key, testKey.pubKey);
|
||||
});
|
||||
it('returns whether a key is trusted', async () => {
|
||||
const newIdentity = libsignal.crypto.getRandomBytes(33);
|
||||
await store.saveIdentity(identifier, testKey.pubKey);
|
||||
|
||||
const trusted = await store.isTrustedIdentity(identifier, newIdentity);
|
||||
if (trusted) {
|
||||
throw new Error('Allowed to overwrite identity key');
|
||||
}
|
||||
});
|
||||
it('returns whether a key is untrusted', async () => {
|
||||
await store.saveIdentity(identifier, testKey.pubKey);
|
||||
const trusted = await store.isTrustedIdentity(identifier, testKey.pubKey);
|
||||
|
||||
if (!trusted) {
|
||||
throw new Error('Allowed to overwrite identity key');
|
||||
}
|
||||
});
|
||||
it('stores prekeys', async () => {
|
||||
await store.storePreKey(1, testKey);
|
||||
|
||||
const key = await store.loadPreKey(1);
|
||||
assertEqualArrayBuffers(key.pubKey, testKey.pubKey);
|
||||
assertEqualArrayBuffers(key.privKey, testKey.privKey);
|
||||
});
|
||||
it('deletes prekeys', async () => {
|
||||
await store.storePreKey(2, testKey);
|
||||
await store.removePreKey(2, testKey);
|
||||
|
||||
const key = await store.loadPreKey(2);
|
||||
assert.isUndefined(key);
|
||||
});
|
||||
it('stores signed prekeys', async () => {
|
||||
await store.storeSignedPreKey(3, testKey);
|
||||
|
||||
const key = await store.loadSignedPreKey(3);
|
||||
assertEqualArrayBuffers(key.pubKey, testKey.pubKey);
|
||||
assertEqualArrayBuffers(key.privKey, testKey.privKey);
|
||||
});
|
||||
it('deletes signed prekeys', async () => {
|
||||
await store.storeSignedPreKey(4, testKey);
|
||||
await store.removeSignedPreKey(4, testKey);
|
||||
|
||||
const key = await store.loadSignedPreKey(4);
|
||||
assert.isUndefined(key);
|
||||
});
|
||||
it('stores sessions', async () => {
|
||||
const testRecord = 'an opaque string';
|
||||
const devices = [1, 2, 3].map(deviceId => [identifier, deviceId].join('.'));
|
||||
|
||||
await Promise.all(
|
||||
devices.map(async encodedNumber => {
|
||||
await store.storeSession(encodedNumber, testRecord + encodedNumber);
|
||||
})
|
||||
.then(done, done);
|
||||
);
|
||||
|
||||
const records = await Promise.all(
|
||||
devices.map(store.loadSession.bind(store))
|
||||
);
|
||||
|
||||
for (let i = 0, max = records.length; i < max; i += 1) {
|
||||
assert.strictEqual(records[i], testRecord + devices[i]);
|
||||
}
|
||||
});
|
||||
it('stores identity keys', done => {
|
||||
store
|
||||
.saveIdentity(identifier, testKey.pubKey)
|
||||
.then(() =>
|
||||
store.loadIdentityKey(identifier).then(key => {
|
||||
assertEqualArrayBuffers(key, testKey.pubKey);
|
||||
})
|
||||
)
|
||||
.then(done, done);
|
||||
});
|
||||
it('returns whether a key is trusted', done => {
|
||||
const newIdentity = libsignal.crypto.getRandomBytes(33);
|
||||
store.saveIdentity(identifier, testKey.pubKey).then(() => {
|
||||
store
|
||||
.isTrustedIdentity(identifier, newIdentity)
|
||||
.then(trusted => {
|
||||
if (trusted) {
|
||||
done(new Error('Allowed to overwrite identity key'));
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
it('returns whether a key is untrusted', done => {
|
||||
const newIdentity = libsignal.crypto.getRandomBytes(33);
|
||||
store.saveIdentity(identifier, testKey.pubKey).then(() => {
|
||||
store
|
||||
.isTrustedIdentity(identifier, testKey.pubKey)
|
||||
.then(trusted => {
|
||||
if (trusted) {
|
||||
done();
|
||||
} else {
|
||||
done(new Error('Allowed to overwrite identity key'));
|
||||
}
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
it('stores prekeys', done => {
|
||||
store
|
||||
.storePreKey(1, testKey)
|
||||
.then(() =>
|
||||
store.loadPreKey(1).then(key => {
|
||||
assertEqualArrayBuffers(key.pubKey, testKey.pubKey);
|
||||
assertEqualArrayBuffers(key.privKey, testKey.privKey);
|
||||
})
|
||||
)
|
||||
.then(done, done);
|
||||
});
|
||||
it('deletes prekeys', done => {
|
||||
before(done => {
|
||||
store.storePreKey(2, testKey).then(done);
|
||||
});
|
||||
store
|
||||
.removePreKey(2, testKey)
|
||||
.then(() =>
|
||||
store.loadPreKey(2).then(key => {
|
||||
assert.isUndefined(key);
|
||||
})
|
||||
)
|
||||
.then(done, done);
|
||||
});
|
||||
it('stores signed prekeys', done => {
|
||||
store
|
||||
.storeSignedPreKey(3, testKey)
|
||||
.then(() =>
|
||||
store.loadSignedPreKey(3).then(key => {
|
||||
assertEqualArrayBuffers(key.pubKey, testKey.pubKey);
|
||||
assertEqualArrayBuffers(key.privKey, testKey.privKey);
|
||||
})
|
||||
)
|
||||
.then(done, done);
|
||||
});
|
||||
it('deletes signed prekeys', done => {
|
||||
before(done => {
|
||||
store.storeSignedPreKey(4, testKey).then(done);
|
||||
});
|
||||
store
|
||||
.removeSignedPreKey(4, testKey)
|
||||
.then(() =>
|
||||
store.loadSignedPreKey(4).then(key => {
|
||||
assert.isUndefined(key);
|
||||
})
|
||||
)
|
||||
.then(done, done);
|
||||
});
|
||||
it('stores sessions', done => {
|
||||
it('removes all sessions for a number', async () => {
|
||||
const testRecord = 'an opaque string';
|
||||
const devices = [1, 2, 3].map(deviceId => [identifier, deviceId].join('.'));
|
||||
let promise = Promise.resolve();
|
||||
devices.forEach(encodedNumber => {
|
||||
promise = promise.then(() =>
|
||||
store.storeSession(encodedNumber, testRecord + encodedNumber)
|
||||
);
|
||||
});
|
||||
promise
|
||||
.then(() =>
|
||||
Promise.all(devices.map(store.loadSession.bind(store))).then(
|
||||
records => {
|
||||
for (const i in records) {
|
||||
assert.strictEqual(records[i], testRecord + devices[i]);
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
.then(done, done);
|
||||
|
||||
await Promise.all(
|
||||
devices.map(async encodedNumber => {
|
||||
await store.storeSession(encodedNumber, testRecord + encodedNumber);
|
||||
})
|
||||
);
|
||||
|
||||
await store.removeAllSessions(identifier);
|
||||
|
||||
const records = await Promise.all(
|
||||
devices.map(store.loadSession.bind(store))
|
||||
);
|
||||
|
||||
for (let i = 0, max = records.length; i < max; i += 1) {
|
||||
assert.isUndefined(records[i]);
|
||||
}
|
||||
});
|
||||
it('removes all sessions for a number', done => {
|
||||
it('returns deviceIds for a number', async () => {
|
||||
const testRecord = 'an opaque string';
|
||||
const devices = [1, 2, 3].map(deviceId => [identifier, deviceId].join('.'));
|
||||
let promise = Promise.resolve();
|
||||
devices.forEach(encodedNumber => {
|
||||
promise = promise.then(() =>
|
||||
store.storeSession(encodedNumber, testRecord + encodedNumber)
|
||||
);
|
||||
});
|
||||
promise
|
||||
.then(() =>
|
||||
store.removeAllSessions(identifier).then(record =>
|
||||
Promise.all(devices.map(store.loadSession.bind(store))).then(
|
||||
records => {
|
||||
for (const i in records) {
|
||||
assert.isUndefined(records[i]);
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
.then(done, done);
|
||||
|
||||
await Promise.all(
|
||||
devices.map(async encodedNumber => {
|
||||
await store.storeSession(encodedNumber, testRecord + encodedNumber);
|
||||
})
|
||||
);
|
||||
|
||||
const deviceIds = await store.getDeviceIds(identifier);
|
||||
assert.sameMembers(deviceIds, [1, 2, 3]);
|
||||
});
|
||||
it('returns deviceIds for a number', done => {
|
||||
const testRecord = 'an opaque string';
|
||||
const devices = [1, 2, 3].map(deviceId => [identifier, deviceId].join('.'));
|
||||
let promise = Promise.resolve();
|
||||
devices.forEach(encodedNumber => {
|
||||
promise = promise.then(() =>
|
||||
store.storeSession(encodedNumber, testRecord + encodedNumber)
|
||||
);
|
||||
});
|
||||
promise
|
||||
.then(() =>
|
||||
store.getDeviceIds(identifier).then(deviceIds => {
|
||||
assert.sameMembers(deviceIds, [1, 2, 3]);
|
||||
})
|
||||
)
|
||||
.then(done, done);
|
||||
it('returns empty array for a number with no device ids', async () => {
|
||||
const deviceIds = await store.getDeviceIds('foo');
|
||||
assert.sameMembers(deviceIds, []);
|
||||
});
|
||||
it('returns empty array for a number with no device ids', () =>
|
||||
store.getDeviceIds('foo').then(deviceIds => {
|
||||
assert.sameMembers(deviceIds, []);
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* global textsecure */
|
||||
|
||||
describe('createTaskWithTimeout', () => {
|
||||
it('resolves when promise resolves', () => {
|
||||
const task = function() {
|
||||
return Promise.resolve('hi!');
|
||||
};
|
||||
const task = () => Promise.resolve('hi!');
|
||||
const taskWithTimeout = textsecure.createTaskWithTimeout(task);
|
||||
|
||||
return taskWithTimeout().then(result => {
|
||||
@@ -11,26 +11,22 @@ describe('createTaskWithTimeout', () => {
|
||||
});
|
||||
it('flows error from promise back', () => {
|
||||
const error = new Error('original');
|
||||
const task = function() {
|
||||
return Promise.reject(error);
|
||||
};
|
||||
const task = () => Promise.reject(error);
|
||||
const taskWithTimeout = textsecure.createTaskWithTimeout(task);
|
||||
|
||||
return taskWithTimeout().catch(flowedError => {
|
||||
assert.strictEqual(error, flowedError);
|
||||
});
|
||||
});
|
||||
it('rejects if promise takes too long (this one logs error to console)', function() {
|
||||
const error = new Error('original');
|
||||
it('rejects if promise takes too long (this one logs error to console)', () => {
|
||||
let complete = false;
|
||||
const task = function() {
|
||||
return new Promise(resolve => {
|
||||
const task = () =>
|
||||
new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
complete = true;
|
||||
resolve();
|
||||
}, 3000);
|
||||
});
|
||||
};
|
||||
const taskWithTimeout = textsecure.createTaskWithTimeout(task, this.name, {
|
||||
timeout: 10,
|
||||
});
|
||||
@@ -45,29 +41,27 @@ describe('createTaskWithTimeout', () => {
|
||||
);
|
||||
});
|
||||
it('resolves if task returns something falsey', () => {
|
||||
const task = function() {};
|
||||
const task = () => {};
|
||||
const taskWithTimeout = textsecure.createTaskWithTimeout(task);
|
||||
return taskWithTimeout();
|
||||
});
|
||||
it('resolves if task returns a non-promise', () => {
|
||||
const task = function() {
|
||||
return 'hi!';
|
||||
};
|
||||
const task = () => 'hi!';
|
||||
const taskWithTimeout = textsecure.createTaskWithTimeout(task);
|
||||
return taskWithTimeout().then(result => {
|
||||
assert.strictEqual(result, 'hi!');
|
||||
});
|
||||
});
|
||||
it('rejects if task throws (and does not log about taking too long)', function() {
|
||||
it('rejects if task throws (and does not log about taking too long)', () => {
|
||||
const error = new Error('Task is throwing!');
|
||||
const task = function() {
|
||||
const task = () => {
|
||||
throw error;
|
||||
};
|
||||
const taskWithTimeout = textsecure.createTaskWithTimeout(task, this.name, {
|
||||
timeout: 10,
|
||||
});
|
||||
return taskWithTimeout().then(
|
||||
result => {
|
||||
() => {
|
||||
throw new Error('Overall task should reject!');
|
||||
},
|
||||
flowedError => {
|
||||
|
||||
@@ -1,208 +1,214 @@
|
||||
(function() {
|
||||
describe('WebSocket-Resource', () => {
|
||||
describe('requests and responses', () => {
|
||||
it('receives requests and sends responses', done => {
|
||||
// mock socket
|
||||
const request_id = '1';
|
||||
const socket = {
|
||||
send(data) {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.RESPONSE
|
||||
);
|
||||
assert.strictEqual(message.response.message, 'OK');
|
||||
assert.strictEqual(message.response.status, 200);
|
||||
assert.strictEqual(message.response.id.toString(), request_id);
|
||||
done();
|
||||
},
|
||||
addEventListener() {},
|
||||
};
|
||||
/* global textsecure, WebSocketResource */
|
||||
|
||||
// actual test
|
||||
const resource = new WebSocketResource(socket, {
|
||||
handleRequest(request) {
|
||||
assert.strictEqual(request.verb, 'PUT');
|
||||
assert.strictEqual(request.path, '/some/path');
|
||||
assertEqualArrayBuffers(
|
||||
request.body.toArrayBuffer(),
|
||||
new Uint8Array([1, 2, 3]).buffer
|
||||
);
|
||||
request.respond(200, 'OK');
|
||||
},
|
||||
});
|
||||
describe('WebSocket-Resource', () => {
|
||||
describe('requests and responses', () => {
|
||||
it('receives requests and sends responses', done => {
|
||||
// mock socket
|
||||
const requestId = '1';
|
||||
const socket = {
|
||||
send(data) {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.RESPONSE
|
||||
);
|
||||
assert.strictEqual(message.response.message, 'OK');
|
||||
assert.strictEqual(message.response.status, 200);
|
||||
assert.strictEqual(message.response.id.toString(), requestId);
|
||||
done();
|
||||
},
|
||||
addEventListener() {},
|
||||
};
|
||||
|
||||
// mock socket request
|
||||
socket.onmessage({
|
||||
data: new Blob([
|
||||
new textsecure.protobuf.WebSocketMessage({
|
||||
type: textsecure.protobuf.WebSocketMessage.Type.REQUEST,
|
||||
request: {
|
||||
id: request_id,
|
||||
verb: 'PUT',
|
||||
path: '/some/path',
|
||||
body: new Uint8Array([1, 2, 3]).buffer,
|
||||
},
|
||||
})
|
||||
.encode()
|
||||
.toArrayBuffer(),
|
||||
]),
|
||||
});
|
||||
// actual test
|
||||
this.resource = new WebSocketResource(socket, {
|
||||
handleRequest(request) {
|
||||
assert.strictEqual(request.verb, 'PUT');
|
||||
assert.strictEqual(request.path, '/some/path');
|
||||
assertEqualArrayBuffers(
|
||||
request.body.toArrayBuffer(),
|
||||
new Uint8Array([1, 2, 3]).buffer
|
||||
);
|
||||
request.respond(200, 'OK');
|
||||
},
|
||||
});
|
||||
|
||||
it('sends requests and receives responses', done => {
|
||||
// mock socket and request handler
|
||||
let request_id;
|
||||
const socket = {
|
||||
send(data) {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.REQUEST
|
||||
);
|
||||
assert.strictEqual(message.request.verb, 'PUT');
|
||||
assert.strictEqual(message.request.path, '/some/path');
|
||||
assertEqualArrayBuffers(
|
||||
message.request.body.toArrayBuffer(),
|
||||
new Uint8Array([1, 2, 3]).buffer
|
||||
);
|
||||
request_id = message.request.id;
|
||||
},
|
||||
addEventListener() {},
|
||||
};
|
||||
|
||||
// actual test
|
||||
const resource = new WebSocketResource(socket);
|
||||
resource.sendRequest({
|
||||
verb: 'PUT',
|
||||
path: '/some/path',
|
||||
body: new Uint8Array([1, 2, 3]).buffer,
|
||||
error: done,
|
||||
success(message, status, request) {
|
||||
assert.strictEqual(message, 'OK');
|
||||
assert.strictEqual(status, 200);
|
||||
done();
|
||||
},
|
||||
});
|
||||
|
||||
// mock socket response
|
||||
socket.onmessage({
|
||||
data: new Blob([
|
||||
new textsecure.protobuf.WebSocketMessage({
|
||||
type: textsecure.protobuf.WebSocketMessage.Type.RESPONSE,
|
||||
response: { id: request_id, message: 'OK', status: 200 },
|
||||
})
|
||||
.encode()
|
||||
.toArrayBuffer(),
|
||||
]),
|
||||
});
|
||||
// mock socket request
|
||||
socket.onmessage({
|
||||
data: new Blob([
|
||||
new textsecure.protobuf.WebSocketMessage({
|
||||
type: textsecure.protobuf.WebSocketMessage.Type.REQUEST,
|
||||
request: {
|
||||
id: requestId,
|
||||
verb: 'PUT',
|
||||
path: '/some/path',
|
||||
body: new Uint8Array([1, 2, 3]).buffer,
|
||||
},
|
||||
})
|
||||
.encode()
|
||||
.toArrayBuffer(),
|
||||
]),
|
||||
});
|
||||
});
|
||||
|
||||
describe('close', () => {
|
||||
before(() => {
|
||||
window.WebSocket = MockSocket;
|
||||
});
|
||||
after(() => {
|
||||
window.WebSocket = WebSocket;
|
||||
});
|
||||
it('closes the connection', done => {
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
mockServer.on('connection', server => {
|
||||
server.on('close', done);
|
||||
});
|
||||
const resource = new WebSocketResource(
|
||||
new WebSocket('ws://localhost:8081')
|
||||
);
|
||||
resource.close();
|
||||
});
|
||||
});
|
||||
it('sends requests and receives responses', done => {
|
||||
// mock socket and request handler
|
||||
let requestId;
|
||||
const socket = {
|
||||
send(data) {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.REQUEST
|
||||
);
|
||||
assert.strictEqual(message.request.verb, 'PUT');
|
||||
assert.strictEqual(message.request.path, '/some/path');
|
||||
assertEqualArrayBuffers(
|
||||
message.request.body.toArrayBuffer(),
|
||||
new Uint8Array([1, 2, 3]).buffer
|
||||
);
|
||||
requestId = message.request.id;
|
||||
},
|
||||
addEventListener() {},
|
||||
};
|
||||
|
||||
describe.skip('with a keepalive config', function() {
|
||||
before(() => {
|
||||
window.WebSocket = MockSocket;
|
||||
});
|
||||
after(() => {
|
||||
window.WebSocket = WebSocket;
|
||||
});
|
||||
this.timeout(60000);
|
||||
it('sends keepalives once a minute', done => {
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
mockServer.on('connection', server => {
|
||||
server.on('message', data => {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.REQUEST
|
||||
);
|
||||
assert.strictEqual(message.request.verb, 'GET');
|
||||
assert.strictEqual(message.request.path, '/v1/keepalive');
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
new WebSocketResource(new WebSocket('ws://localhost:8081'), {
|
||||
keepalive: { path: '/v1/keepalive' },
|
||||
});
|
||||
// actual test
|
||||
const resource = new WebSocketResource(socket);
|
||||
resource.sendRequest({
|
||||
verb: 'PUT',
|
||||
path: '/some/path',
|
||||
body: new Uint8Array([1, 2, 3]).buffer,
|
||||
error: done,
|
||||
success(message, status) {
|
||||
assert.strictEqual(message, 'OK');
|
||||
assert.strictEqual(status, 200);
|
||||
done();
|
||||
},
|
||||
});
|
||||
|
||||
it('uses / as a default path', done => {
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
mockServer.on('connection', server => {
|
||||
server.on('message', data => {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.REQUEST
|
||||
);
|
||||
assert.strictEqual(message.request.verb, 'GET');
|
||||
assert.strictEqual(message.request.path, '/');
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
new WebSocketResource(new WebSocket('ws://localhost:8081'), {
|
||||
keepalive: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('optionally disconnects if no response', function(done) {
|
||||
this.timeout(65000);
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
const socket = new WebSocket('ws://localhost:8081');
|
||||
mockServer.on('connection', server => {
|
||||
server.on('close', done);
|
||||
});
|
||||
new WebSocketResource(socket, { keepalive: true });
|
||||
});
|
||||
|
||||
it('allows resetting the keepalive timer', function(done) {
|
||||
this.timeout(65000);
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
const socket = new WebSocket('ws://localhost:8081');
|
||||
const startTime = Date.now();
|
||||
mockServer.on('connection', server => {
|
||||
server.on('message', data => {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.REQUEST
|
||||
);
|
||||
assert.strictEqual(message.request.verb, 'GET');
|
||||
assert.strictEqual(message.request.path, '/');
|
||||
assert(
|
||||
Date.now() > startTime + 60000,
|
||||
'keepalive time should be longer than a minute'
|
||||
);
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
const resource = new WebSocketResource(socket, { keepalive: true });
|
||||
setTimeout(() => {
|
||||
resource.resetKeepAliveTimer();
|
||||
}, 5000);
|
||||
// mock socket response
|
||||
socket.onmessage({
|
||||
data: new Blob([
|
||||
new textsecure.protobuf.WebSocketMessage({
|
||||
type: textsecure.protobuf.WebSocketMessage.Type.RESPONSE,
|
||||
response: { id: requestId, message: 'OK', status: 200 },
|
||||
})
|
||||
.encode()
|
||||
.toArrayBuffer(),
|
||||
]),
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
describe('close', () => {
|
||||
before(() => {
|
||||
window.WebSocket = MockSocket;
|
||||
});
|
||||
after(() => {
|
||||
window.WebSocket = WebSocket;
|
||||
});
|
||||
it('closes the connection', done => {
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
mockServer.on('connection', server => {
|
||||
server.on('close', done);
|
||||
});
|
||||
const resource = new WebSocketResource(
|
||||
new WebSocket('ws://localhost:8081')
|
||||
);
|
||||
resource.close();
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('with a keepalive config', function thisNeeded() {
|
||||
before(() => {
|
||||
window.WebSocket = MockSocket;
|
||||
});
|
||||
after(() => {
|
||||
window.WebSocket = WebSocket;
|
||||
});
|
||||
this.timeout(60000);
|
||||
it('sends keepalives once a minute', done => {
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
mockServer.on('connection', server => {
|
||||
server.on('message', data => {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.REQUEST
|
||||
);
|
||||
assert.strictEqual(message.request.verb, 'GET');
|
||||
assert.strictEqual(message.request.path, '/v1/keepalive');
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
this.resource = new WebSocketResource(
|
||||
new WebSocket('ws://loc1alhost:8081'),
|
||||
{
|
||||
keepalive: { path: '/v1/keepalive' },
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('uses / as a default path', done => {
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
mockServer.on('connection', server => {
|
||||
server.on('message', data => {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.REQUEST
|
||||
);
|
||||
assert.strictEqual(message.request.verb, 'GET');
|
||||
assert.strictEqual(message.request.path, '/');
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
this.resource = new WebSocketResource(
|
||||
new WebSocket('ws://localhost:8081'),
|
||||
{
|
||||
keepalive: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('optionally disconnects if no response', function thisNeeded1(done) {
|
||||
this.timeout(65000);
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
const socket = new WebSocket('ws://localhost:8081');
|
||||
mockServer.on('connection', server => {
|
||||
server.on('close', done);
|
||||
});
|
||||
this.resource = new WebSocketResource(socket, { keepalive: true });
|
||||
});
|
||||
|
||||
it('allows resetting the keepalive timer', function thisNeeded2(done) {
|
||||
this.timeout(65000);
|
||||
const mockServer = new MockServer('ws://localhost:8081');
|
||||
const socket = new WebSocket('ws://localhost:8081');
|
||||
const startTime = Date.now();
|
||||
mockServer.on('connection', server => {
|
||||
server.on('message', data => {
|
||||
const message = textsecure.protobuf.WebSocketMessage.decode(data);
|
||||
assert.strictEqual(
|
||||
message.type,
|
||||
textsecure.protobuf.WebSocketMessage.Type.REQUEST
|
||||
);
|
||||
assert.strictEqual(message.request.verb, 'GET');
|
||||
assert.strictEqual(message.request.path, '/');
|
||||
assert(
|
||||
Date.now() > startTime + 60000,
|
||||
'keepalive time should be longer than a minute'
|
||||
);
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
const resource = new WebSocketResource(socket, { keepalive: true });
|
||||
setTimeout(() => {
|
||||
resource.resetKeepAliveTimer();
|
||||
}, 5000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* global TextSecureWebSocket */
|
||||
|
||||
describe('TextSecureWebSocket', () => {
|
||||
const RealWebSocket = window.WebSocket;
|
||||
before(() => {
|
||||
@@ -13,19 +15,19 @@ describe('TextSecureWebSocket', () => {
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
var socket = new TextSecureWebSocket('ws://localhost:8080');
|
||||
const socket = new TextSecureWebSocket('ws://localhost:8080');
|
||||
});
|
||||
|
||||
it('sends and receives', done => {
|
||||
const mockServer = new MockServer('ws://localhost:8080');
|
||||
mockServer.on('connection', server => {
|
||||
server.on('message', data => {
|
||||
server.on('message', () => {
|
||||
server.send('ack');
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
const socket = new TextSecureWebSocket('ws://localhost:8080');
|
||||
socket.onmessage = function(response) {
|
||||
socket.onmessage = response => {
|
||||
assert.strictEqual(response.data, 'ack');
|
||||
socket.close();
|
||||
done();
|
||||
@@ -40,20 +42,20 @@ describe('TextSecureWebSocket', () => {
|
||||
server.close();
|
||||
socket.close();
|
||||
});
|
||||
var socket = new TextSecureWebSocket('ws://localhost:8082');
|
||||
socket.onclose = function() {
|
||||
const socket = new TextSecureWebSocket('ws://localhost:8082');
|
||||
socket.onclose = () => {
|
||||
assert.strictEqual(socket.getStatus(), WebSocket.CLOSING);
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
it('reconnects', function(done) {
|
||||
it('reconnects', function thisNeeded(done) {
|
||||
this.timeout(60000);
|
||||
const mockServer = new MockServer('ws://localhost:8082');
|
||||
const socket = new TextSecureWebSocket('ws://localhost:8082');
|
||||
socket.onclose = function() {
|
||||
const mockServer = new MockServer('ws://localhost:8082');
|
||||
mockServer.on('connection', server => {
|
||||
socket.onclose = () => {
|
||||
const secondServer = new MockServer('ws://localhost:8082');
|
||||
secondServer.on('connection', server => {
|
||||
socket.close();
|
||||
server.close();
|
||||
done();
|
||||
|
||||
Reference in New Issue
Block a user