Move conversations to SQLCipher

This commit is contained in:
Scott Nonnenberg 2018-09-20 18:47:19 -07:00
parent 8cd3db0262
commit cd60bdd08a
31 changed files with 1354 additions and 774 deletions

View file

@ -655,8 +655,9 @@ describe('Backup', () => {
verified: 0,
};
console.log({ conversation });
const conversationModel = new Whisper.Conversation(conversation);
await window.wrapDeferred(conversationModel.save());
await window.Signal.Data.saveConversation(conversation, {
Conversation: Whisper.Conversation,
});
console.log(
'Backup test: Ensure that all attachments were saved to disk'
@ -698,8 +699,9 @@ describe('Backup', () => {
assert.deepEqual(attachmentFiles, recreatedAttachmentFiles);
console.log('Backup test: Check messages');
const messageCollection = new Whisper.MessageCollection();
await window.wrapDeferred(messageCollection.fetch());
const messageCollection = await window.Signal.Data.getAllMessages({
MessageCollection: Whisper.MessageCollection,
});
assert.strictEqual(messageCollection.length, MESSAGE_COUNT);
const messageFromDB = removeId(messageCollection.at(0).attributes);
const expectedMessage = omitUndefinedKeys(message);
@ -725,8 +727,11 @@ describe('Backup', () => {
);
console.log('Backup test: Check conversations');
const conversationCollection = new Whisper.ConversationCollection();
await window.wrapDeferred(conversationCollection.fetch());
const conversationCollection = await window.Signal.Data.getAllConversations(
{
ConversationCollection: Whisper.ConversationCollection,
}
);
assert.strictEqual(conversationCollection.length, CONVERSATION_COUNT);
const conversationFromDB = conversationCollection.at(0).attributes;

View file

@ -232,7 +232,9 @@ Whisper.Fixtures = function() {
conversationCollection.saveAll = function() {
return Promise.all(
this.map(async (convo) => {
await wrapDeferred(convo.save());
await window.Signal.Data.saveConversation(convo.attributes, {
Conversation: Whisper.Conversation,
});
await Promise.all(
convo.messageCollection.map(async (message) => {

View file

@ -1,11 +1,23 @@
'use strict';
describe('Fixtures', function() {
before(function() {
before(async function() {
// NetworkStatusView checks this method every five seconds while showing
window.getSocketStatus = function() {
return WebSocket.OPEN;
};
await clearDatabase();
await textsecure.storage.user.setNumberAndDeviceId(
'+17015552000',
2,
'testDevice'
);
await ConversationController.getOrCreateAndWait(
textsecure.storage.user.getNumber(),
'private'
);
});
it('renders', async () => {

View file

@ -20,23 +20,25 @@ describe('KeyChangeListener', function() {
describe('When we have a conversation with this contact', function() {
let convo;
before(function() {
before(async function() {
convo = ConversationController.dangerouslyCreateAndAdd({
id: phoneNumberWithKeyChange,
type: 'private',
});
return convo.save();
await window.Signal.Data.saveConversation(convo.attributes, {
Conversation: Whisper.Conversation,
});
});
after(function() {
convo.destroyMessages();
return convo.destroy();
after(async function() {
await convo.destroyMessages();
await window.Signal.Data.saveConversation(convo.id);
});
it('generates a key change notice in the private conversation with this contact', function(done) {
convo.on('newmessage', async function() {
convo.once('newmessage', async () => {
await convo.fetchMessages();
var message = convo.messageCollection.at(0);
const message = convo.messageCollection.at(0);
assert.strictEqual(message.get('type'), 'keychange');
done();
});
@ -46,23 +48,26 @@ describe('KeyChangeListener', function() {
describe('When we have a group with this contact', function() {
let convo;
before(function() {
before(async function() {
console.log('Creating group with contact', phoneNumberWithKeyChange);
convo = ConversationController.dangerouslyCreateAndAdd({
id: 'groupId',
type: 'group',
members: [phoneNumberWithKeyChange],
});
return convo.save();
await window.Signal.Data.saveConversation(convo.attributes, {
Conversation: Whisper.Conversation,
});
});
after(function() {
convo.destroyMessages();
return convo.destroy();
after(async function() {
await convo.destroyMessages();
await window.Signal.Data.saveConversation(convo.id);
});
it('generates a key change notice in the group conversation with this contact', function(done) {
convo.on('newmessage', async function() {
convo.once('newmessage', async () => {
await convo.fetchMessages();
var message = convo.messageCollection.at(0);
const message = convo.messageCollection.at(0);
assert.strictEqual(message.get('type'), 'keychange');
done();
});

View file

@ -17,50 +17,6 @@
before(clearDatabase);
after(clearDatabase);
it('adds without saving', function(done) {
var convos = new Whisper.ConversationCollection();
convos.add(conversation_attributes);
assert.notEqual(convos.length, 0);
var convos = new Whisper.ConversationCollection();
convos.fetch().then(function() {
assert.strictEqual(convos.length, 0);
done();
});
});
it('saves asynchronously', function(done) {
new Whisper.ConversationCollection()
.add(conversation_attributes)
.save()
.then(done);
});
it('fetches persistent convos', async () => {
var convos = new Whisper.ConversationCollection();
assert.strictEqual(convos.length, 0);
await wrapDeferred(convos.fetch());
var m = convos.at(0).attributes;
_.each(conversation_attributes, function(val, key) {
assert.deepEqual(m[key], val);
});
});
it('destroys persistent convos', function(done) {
var convos = new Whisper.ConversationCollection();
convos.fetch().then(function() {
convos.destroyAll().then(function() {
var convos = new Whisper.ConversationCollection();
convos.fetch().then(function() {
assert.strictEqual(convos.length, 0);
done();
});
});
});
});
it('should be ordered newest to oldest', function() {
var conversations = new Whisper.ConversationCollection();
// Timestamps
@ -85,7 +41,9 @@
var attributes = { type: 'private', id: '+18085555555' };
before(async () => {
var convo = new Whisper.ConversationCollection().add(attributes);
await wrapDeferred(convo.save());
await window.Signal.Data.saveConversation(convo.attributes, {
Conversation: Whisper.Conversation,
});
var message = convo.messageCollection.add({
body: 'hello world',
@ -123,32 +81,28 @@
assert.strictEqual(convo.contactCollection.at('2').get('name'), 'C');
});
it('contains its own messages', function(done) {
it('contains its own messages', async function() {
var convo = new Whisper.ConversationCollection().add({
id: '+18085555555',
});
convo.fetchMessages().then(function() {
assert.notEqual(convo.messageCollection.length, 0);
done();
});
await convo.fetchMessages();
assert.notEqual(convo.messageCollection.length, 0);
});
it('contains only its own messages', function(done) {
it('contains only its own messages', async function() {
var convo = new Whisper.ConversationCollection().add({
id: '+18085556666',
});
convo.fetchMessages().then(function() {
assert.strictEqual(convo.messageCollection.length, 0);
done();
});
await convo.fetchMessages();
assert.strictEqual(convo.messageCollection.length, 0);
});
it('adds conversation to message collection upon leaving group', function() {
it('adds conversation to message collection upon leaving group', async function() {
var convo = new Whisper.ConversationCollection().add({
type: 'group',
id: 'a random string',
});
convo.leaveGroup();
await convo.leaveGroup();
assert.notEqual(convo.messageCollection.length, 0);
});
@ -180,12 +134,6 @@
assert.property(avatar, 'color');
});
it('revokes the avatar URL', function() {
var convo = new Whisper.ConversationCollection().add(attributes);
convo.revokeAvatarUrl();
assert.notOk(convo.avatarUrl);
});
describe('phone number parsing', function() {
after(function() {
storage.remove('regionCode');
@ -228,57 +176,51 @@
describe('Conversation search', function() {
let convo;
beforeEach(function(done) {
beforeEach(async function() {
convo = new Whisper.ConversationCollection().add({
id: '+14155555555',
type: 'private',
name: 'John Doe',
});
convo.save().then(done);
await window.Signal.Data.saveConversation(convo.attributes, {
Conversation: Whisper.Conversation,
});
});
afterEach(clearDatabase);
function testSearch(queries, done) {
return Promise.all(
queries.map(function(query) {
async function testSearch(queries) {
await Promise.all(
queries.map(async function(query) {
var collection = new Whisper.ConversationCollection();
return collection
.search(query)
.then(function() {
assert.isDefined(
collection.get(convo.id),
'no result for "' + query + '"'
);
})
.catch(done);
await collection.search(query);
assert.isDefined(
collection.get(convo.id),
'no result for "' + query + '"'
);
})
).then(function() {
done();
});
}
it('matches by partial phone number', function(done) {
testSearch(
[
'1',
'4',
'+1',
'415',
'4155',
'4155555555',
'14155555555',
'+14155555555',
],
done
);
}
it('matches by partial phone number', function() {
return testSearch([
'1',
'4',
'+1',
'415',
'4155',
'4155555555',
'14155555555',
'+14155555555',
]);
});
it('matches by name', function(done) {
testSearch(['John', 'Doe', 'john', 'doe', 'John Doe', 'john doe'], done);
it('matches by name', function() {
return testSearch(['John', 'Doe', 'john', 'doe', 'John Doe', 'john doe']);
});
it('does not match +', function() {
it('does not match +', async function() {
var collection = new Whisper.ConversationCollection();
return collection.search('+').then(function() {
assert.isUndefined(collection.get(convo.id), 'got result for "+"');
});
await collection.search('+');
assert.isUndefined(collection.get(convo.id), 'got result for "+"');
});
});
})();

View file

@ -28,14 +28,16 @@ describe('ConversationSearchView', function() {
before(() => {
convo = new Whisper.ConversationCollection().add({
id: 'a-left-group',
id: '1-search-view',
name: 'i left this group',
members: [],
type: 'group',
left: true,
});
return wrapDeferred(convo.save());
return window.Signal.Data.saveConversation(convo.attributes, {
Conversation: Whisper.Conversation,
});
});
describe('with no messages', function() {
var input;
@ -60,65 +62,20 @@ describe('ConversationSearchView', function() {
describe('with messages', function() {
var input;
var view;
before(function(done) {
before(async function() {
input = $('<input>');
view = new Whisper.ConversationSearchView({ input: input }).render();
convo.save({ lastMessage: 'asdf' }).then(function() {
view.$input.val('left');
view.filterContacts();
view.typeahead_view.collection.on('reset', function() {
done();
});
});
});
it('should surface left groups with messages', function() {
assert.isDefined(
view.typeahead_view.collection.get(convo.id),
'got left group'
);
});
});
});
describe('Showing all contacts', function() {
let input;
let view;
let convo;
convo.set({ id: '2-search-view', lastMessage: 'asdf' });
before(() => {
input = $('<input>');
view = new Whisper.ConversationSearchView({ input: input }).render();
view.showAllContacts = true;
convo = new Whisper.ConversationCollection().add({
id: 'a-left-group',
name: 'i left this group',
members: [],
type: 'group',
left: true,
});
return wrapDeferred(convo.save());
});
describe('with no messages', function() {
before(function(done) {
view.resetTypeahead();
view.typeahead_view.collection.once('reset', function() {
done();
await window.Signal.Data.saveConversation(convo.attributes, {
Conversation: Whisper.Conversation,
});
});
it('should not surface left groups with no messages', function() {
assert.isUndefined(
view.typeahead_view.collection.get(convo.id),
'got left group'
);
});
});
describe('with messages', function() {
before(done => {
wrapDeferred(convo.save({ lastMessage: 'asdf' })).then(function() {
view.resetTypeahead();
view.typeahead_view.collection.once('reset', function() {
done();
});
view.$input.val('left');
view.filterContacts();
return new Promise(resolve => {
view.typeahead_view.collection.on('reset', resolve);
});
});
it('should surface left groups with messages', function() {

View file

@ -2,7 +2,19 @@ describe('InboxView', function() {
let inboxView;
let conversation;
before(() => {
before(async () => {
try {
await ConversationController.load();
} catch (error) {
console.log(
'InboxView before:',
error && error.stack ? error.stack : error
);
}
await ConversationController.getOrCreateAndWait(
textsecure.storage.user.getNumber(),
'private'
);
inboxView = new Whisper.InboxView({
model: {},
window: window,