2018-04-20 19:11:56 +00:00
|
|
|
/* global Signal: false */
|
2018-04-20 21:55:33 +00:00
|
|
|
/* global Whisper: false */
|
2018-04-20 19:11:56 +00:00
|
|
|
/* global assert: false */
|
2018-04-20 21:55:33 +00:00
|
|
|
/* global textsecure: false */
|
|
|
|
/* global _: false */
|
2018-04-20 19:11:56 +00:00
|
|
|
|
2017-09-07 01:20:42 +00:00
|
|
|
'use strict';
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
describe('Backup', () => {
|
|
|
|
describe('_sanitizeFileName', () => {
|
|
|
|
it('leaves a basic string alone', () => {
|
|
|
|
const initial = 'Hello, how are you #5 (\'fine\' + great).jpg';
|
|
|
|
const expected = initial;
|
2018-03-19 19:42:12 +00:00
|
|
|
assert.strictEqual(Signal.Backup._sanitizeFileName(initial), expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('replaces all unknown characters', () => {
|
|
|
|
const initial = '!@$%^&*=';
|
|
|
|
const expected = '________';
|
2018-03-19 19:42:12 +00:00
|
|
|
assert.strictEqual(Signal.Backup._sanitizeFileName(initial), expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
describe('_trimFileName', () => {
|
|
|
|
it('handles a file with no extension', () => {
|
|
|
|
const initial = '0123456789012345678901234567890123456789';
|
|
|
|
const expected = '012345678901234567890123456789';
|
2018-03-19 19:42:12 +00:00
|
|
|
assert.strictEqual(Signal.Backup._trimFileName(initial), expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('handles a file with a long extension', () => {
|
|
|
|
const initial = '0123456789012345678901234567890123456789.01234567890123456789';
|
|
|
|
const expected = '012345678901234567890123456789';
|
2018-03-19 19:42:12 +00:00
|
|
|
assert.strictEqual(Signal.Backup._trimFileName(initial), expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('handles a file with a normal extension', () => {
|
|
|
|
const initial = '01234567890123456789012345678901234567890123456789.jpg';
|
|
|
|
const expected = '012345678901234567890123.jpg';
|
2018-03-19 19:42:12 +00:00
|
|
|
assert.strictEqual(Signal.Backup._trimFileName(initial), expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
describe('_getExportAttachmentFileName', () => {
|
|
|
|
it('uses original filename if attachment has one', () => {
|
|
|
|
const message = {
|
2018-03-19 19:42:12 +00:00
|
|
|
body: 'something',
|
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const index = 0;
|
|
|
|
const attachment = {
|
|
|
|
fileName: 'blah.jpg',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = 'blah.jpg';
|
2018-03-19 19:42:12 +00:00
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
const actual = Signal.Backup._getExportAttachmentFileName(
|
2018-03-19 19:42:12 +00:00
|
|
|
message,
|
|
|
|
index,
|
|
|
|
attachment
|
|
|
|
);
|
|
|
|
assert.strictEqual(actual, expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('uses attachment id if no filename', () => {
|
|
|
|
const message = {
|
2018-03-19 19:42:12 +00:00
|
|
|
body: 'something',
|
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const index = 0;
|
|
|
|
const attachment = {
|
|
|
|
id: '123',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = '123';
|
2018-03-19 19:42:12 +00:00
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
const actual = Signal.Backup._getExportAttachmentFileName(
|
2018-03-19 19:42:12 +00:00
|
|
|
message,
|
|
|
|
index,
|
|
|
|
attachment
|
|
|
|
);
|
|
|
|
assert.strictEqual(actual, expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('uses filename and contentType if available', () => {
|
|
|
|
const message = {
|
2018-03-19 19:42:12 +00:00
|
|
|
body: 'something',
|
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const index = 0;
|
|
|
|
const attachment = {
|
2017-09-07 01:20:42 +00:00
|
|
|
id: '123',
|
2018-04-20 19:11:56 +00:00
|
|
|
contentType: 'image/jpeg',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = '123.jpeg';
|
2018-03-19 19:42:12 +00:00
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
const actual = Signal.Backup._getExportAttachmentFileName(
|
2018-03-19 19:42:12 +00:00
|
|
|
message,
|
|
|
|
index,
|
|
|
|
attachment
|
|
|
|
);
|
|
|
|
assert.strictEqual(actual, expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('handles strange contentType', () => {
|
|
|
|
const message = {
|
2018-03-19 19:42:12 +00:00
|
|
|
body: 'something',
|
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const index = 0;
|
|
|
|
const attachment = {
|
2017-09-07 01:20:42 +00:00
|
|
|
id: '123',
|
2018-04-20 19:11:56 +00:00
|
|
|
contentType: 'something',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = '123.something';
|
2018-03-19 19:42:12 +00:00
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
const actual = Signal.Backup._getExportAttachmentFileName(
|
2018-03-19 19:42:12 +00:00
|
|
|
message,
|
|
|
|
index,
|
|
|
|
attachment
|
|
|
|
);
|
|
|
|
assert.strictEqual(actual, expected);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
describe('_getAnonymousAttachmentFileName', () => {
|
|
|
|
it('uses message id', () => {
|
|
|
|
const message = {
|
2018-03-19 19:42:12 +00:00
|
|
|
id: 'id-45',
|
|
|
|
body: 'something',
|
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const index = 0;
|
|
|
|
const attachment = {
|
|
|
|
fileName: 'blah.jpg',
|
2018-03-19 19:42:12 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = 'id-45';
|
2018-03-19 19:42:12 +00:00
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
const actual = Signal.Backup._getAnonymousAttachmentFileName(
|
2018-03-19 19:42:12 +00:00
|
|
|
message,
|
|
|
|
index,
|
|
|
|
attachment
|
|
|
|
);
|
|
|
|
assert.strictEqual(actual, expected);
|
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('appends index if it is above zero', () => {
|
|
|
|
const message = {
|
2018-03-19 19:42:12 +00:00
|
|
|
id: 'id-45',
|
|
|
|
body: 'something',
|
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const index = 1;
|
|
|
|
const attachment = {
|
|
|
|
fileName: 'blah.jpg',
|
2018-03-19 19:42:12 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = 'id-45-1';
|
2018-03-19 19:42:12 +00:00
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
const actual = Signal.Backup._getAnonymousAttachmentFileName(
|
2018-03-19 19:42:12 +00:00
|
|
|
message,
|
|
|
|
index,
|
|
|
|
attachment
|
|
|
|
);
|
|
|
|
assert.strictEqual(actual, expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
describe('_getConversationDirName', () => {
|
|
|
|
it('uses name if available', () => {
|
|
|
|
const conversation = {
|
2017-09-07 01:20:42 +00:00
|
|
|
active_at: 123,
|
|
|
|
name: '0123456789012345678901234567890123456789',
|
2018-04-20 19:11:56 +00:00
|
|
|
id: 'id',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = '123 (012345678901234567890123456789 id)';
|
2018-03-19 19:42:12 +00:00
|
|
|
assert.strictEqual(Signal.Backup._getConversationDirName(conversation), expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('uses just id if name is not available', () => {
|
|
|
|
const conversation = {
|
2017-09-07 01:20:42 +00:00
|
|
|
active_at: 123,
|
2018-04-20 19:11:56 +00:00
|
|
|
id: 'id',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = '123 (id)';
|
2018-03-19 19:42:12 +00:00
|
|
|
assert.strictEqual(Signal.Backup._getConversationDirName(conversation), expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('uses inactive for missing active_at', () => {
|
|
|
|
const conversation = {
|
2017-09-07 01:20:42 +00:00
|
|
|
name: 'name',
|
2018-04-20 19:11:56 +00:00
|
|
|
id: 'id',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = 'inactive (name id)';
|
2018-03-19 19:42:12 +00:00
|
|
|
assert.strictEqual(Signal.Backup._getConversationDirName(conversation), expected);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
describe('_getConversationLoggingName', () => {
|
|
|
|
it('uses plain id if conversation is private', () => {
|
|
|
|
const conversation = {
|
2017-09-07 01:20:42 +00:00
|
|
|
active_at: 123,
|
|
|
|
id: 'id',
|
2018-04-20 19:11:56 +00:00
|
|
|
type: 'private',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = '123 (id)';
|
|
|
|
assert.strictEqual(
|
|
|
|
Signal.Backup._getConversationLoggingName(conversation),
|
|
|
|
expected
|
|
|
|
);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('uses just id if name is not available', () => {
|
|
|
|
const conversation = {
|
2017-09-07 01:20:42 +00:00
|
|
|
active_at: 123,
|
|
|
|
id: 'groupId',
|
2018-04-20 19:11:56 +00:00
|
|
|
type: 'group',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = '123 ([REDACTED_GROUP]pId)';
|
|
|
|
assert.strictEqual(
|
|
|
|
Signal.Backup._getConversationLoggingName(conversation),
|
|
|
|
expected
|
|
|
|
);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
|
2018-04-20 19:11:56 +00:00
|
|
|
it('uses inactive for missing active_at', () => {
|
|
|
|
const conversation = {
|
2017-09-07 01:20:42 +00:00
|
|
|
id: 'id',
|
2018-04-20 19:11:56 +00:00
|
|
|
type: 'private',
|
2017-09-07 01:20:42 +00:00
|
|
|
};
|
2018-04-20 19:11:56 +00:00
|
|
|
const expected = 'inactive (id)';
|
|
|
|
assert.strictEqual(
|
|
|
|
Signal.Backup._getConversationLoggingName(conversation),
|
|
|
|
expected
|
|
|
|
);
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|
|
|
|
});
|
2018-04-20 21:55:33 +00:00
|
|
|
|
|
|
|
describe('end-to-end', () => {
|
|
|
|
it('exports then imports to produce the same data we started with', async () => {
|
|
|
|
const {
|
|
|
|
attachmentsPath,
|
|
|
|
fse,
|
|
|
|
glob,
|
|
|
|
path,
|
|
|
|
tmp,
|
|
|
|
} = window.test;
|
|
|
|
const {
|
|
|
|
upgradeMessageSchema,
|
|
|
|
loadAttachmentData,
|
|
|
|
} = window.Signal.Migrations;
|
|
|
|
|
|
|
|
const key = new Uint8Array([
|
|
|
|
1, 3, 4, 5, 6, 7, 8, 11,
|
|
|
|
23, 34, 1, 34, 3, 5, 45, 45,
|
|
|
|
1, 3, 4, 5, 6, 7, 8, 11,
|
|
|
|
23, 34, 1, 34, 3, 5, 45, 45,
|
|
|
|
]);
|
|
|
|
const attachmentsPattern = path.join(attachmentsPath, '**');
|
|
|
|
|
|
|
|
const OUR_NUMBER = '+12025550000';
|
|
|
|
const CONTACT_ONE_NUMBER = '+12025550001';
|
|
|
|
|
|
|
|
async function wrappedLoadAttachment(attachment) {
|
|
|
|
return _.omit(await loadAttachmentData(attachment), ['path']);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function clearAllData() {
|
|
|
|
await textsecure.storage.protocol.removeAllData();
|
|
|
|
await fse.emptyDir(attachmentsPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
function removeId(model) {
|
|
|
|
return _.omit(model, ['id']);
|
|
|
|
}
|
|
|
|
|
2018-04-23 22:36:47 +00:00
|
|
|
// We want to know which paths have two slashes, since that tells us which files
|
|
|
|
// in the attachment fan-out are files vs. directories.
|
|
|
|
const TWO_SLASHES = /[^/]*\/[^/]*\/[^/]*/;
|
2018-04-21 00:29:55 +00:00
|
|
|
// On windows, attachmentsPath has a normal windows path format (\ separators), but
|
|
|
|
// glob returns only /. We normalize to / separators for our manipulations.
|
|
|
|
const normalizedBase = attachmentsPath.replace(/\\/g, '/');
|
2018-04-20 21:55:33 +00:00
|
|
|
function removeDirs(dirs) {
|
|
|
|
return _.filter(dirs, (fullDir) => {
|
2018-04-21 00:29:55 +00:00
|
|
|
const dir = fullDir.replace(normalizedBase, '');
|
2018-04-23 22:36:47 +00:00
|
|
|
return TWO_SLASHES.test(dir);
|
2018-04-20 21:55:33 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function _mapQuotedAttachments(mapper) {
|
|
|
|
return async (message, context) => {
|
|
|
|
if (!message.quote) {
|
|
|
|
return message;
|
|
|
|
}
|
|
|
|
|
|
|
|
const wrappedMapper = async (attachment) => {
|
|
|
|
if (!attachment || !attachment.thumbnail) {
|
|
|
|
return attachment;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Object.assign({}, attachment, {
|
|
|
|
thumbnail: await mapper(attachment.thumbnail, context),
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const quotedAttachments = (message.quote && message.quote.attachments) || [];
|
|
|
|
|
|
|
|
return Object.assign({}, message, {
|
|
|
|
quote: Object.assign({}, message.quote, {
|
|
|
|
attachments: await Promise.all(quotedAttachments.map(wrappedMapper)),
|
|
|
|
}),
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
async function loadAllFilesFromDisk(message) {
|
|
|
|
const loadThumbnails = _mapQuotedAttachments((thumbnail) => {
|
|
|
|
// we want to be bulletproof to thumbnails without data
|
|
|
|
if (!thumbnail.path) {
|
|
|
|
return thumbnail;
|
|
|
|
}
|
|
|
|
|
|
|
|
return wrappedLoadAttachment(thumbnail);
|
|
|
|
});
|
|
|
|
|
|
|
|
const promises = (message.attachments || []).map(attachment =>
|
|
|
|
wrappedLoadAttachment(attachment));
|
|
|
|
|
|
|
|
return Object.assign(
|
|
|
|
{},
|
|
|
|
await loadThumbnails(message),
|
|
|
|
{
|
|
|
|
attachments: await Promise.all(promises),
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
let backupDir;
|
|
|
|
try {
|
|
|
|
const ATTACHMENT_COUNT = 2;
|
|
|
|
const MESSAGE_COUNT = 1;
|
|
|
|
const CONVERSATION_COUNT = 1;
|
|
|
|
|
|
|
|
const messageWithAttachments = {
|
|
|
|
conversationId: CONTACT_ONE_NUMBER,
|
|
|
|
body: 'Totally!',
|
|
|
|
source: OUR_NUMBER,
|
|
|
|
received_at: 1524185933350,
|
|
|
|
timestamp: 1524185933350,
|
|
|
|
errors: [],
|
|
|
|
attachments: [{
|
|
|
|
contentType: 'image/gif',
|
|
|
|
fileName: 'sad_cat.gif',
|
|
|
|
data: new Uint8Array([
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
]).buffer,
|
|
|
|
}],
|
|
|
|
quote: {
|
|
|
|
text: "Isn't it cute?",
|
|
|
|
author: CONTACT_ONE_NUMBER,
|
|
|
|
id: 12345678,
|
|
|
|
attachments: [{
|
|
|
|
contentType: 'audio/mp3',
|
|
|
|
fileName: 'song.mp3',
|
|
|
|
}, {
|
|
|
|
contentType: 'image/gif',
|
|
|
|
fileName: 'happy_cat.gif',
|
|
|
|
thumbnail: {
|
|
|
|
contentType: 'image/png',
|
|
|
|
data: new Uint8Array([
|
|
|
|
2, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
]).buffer,
|
|
|
|
},
|
|
|
|
}],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
console.log('Backup test: Clear all data');
|
|
|
|
await clearAllData();
|
|
|
|
|
|
|
|
console.log('Backup test: Create models, save to db/disk');
|
|
|
|
const message = await upgradeMessageSchema(messageWithAttachments);
|
|
|
|
console.log({ message });
|
|
|
|
const messageModel = new Whisper.Message(message);
|
|
|
|
await window.wrapDeferred(messageModel.save());
|
|
|
|
|
|
|
|
const conversation = {
|
|
|
|
active_at: 1524185933350,
|
|
|
|
color: 'orange',
|
|
|
|
expireTimer: 0,
|
|
|
|
id: CONTACT_ONE_NUMBER,
|
|
|
|
lastMessage: 'Heyo!',
|
|
|
|
name: 'Someone Somewhere',
|
|
|
|
profileAvatar: {
|
|
|
|
contentType: 'image/jpeg',
|
|
|
|
data: new Uint8Array([
|
|
|
|
3, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
]).buffer,
|
|
|
|
size: 64,
|
|
|
|
},
|
|
|
|
profileKey: new Uint8Array([
|
|
|
|
4, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
|
|
]).buffer,
|
|
|
|
profileName: 'Someone! 🤔',
|
|
|
|
profileSharing: true,
|
|
|
|
timestamp: 1524185933350,
|
|
|
|
tokens: [
|
|
|
|
'someone somewhere',
|
|
|
|
'someone',
|
|
|
|
'somewhere',
|
|
|
|
'2025550001',
|
|
|
|
'12025550001',
|
|
|
|
],
|
|
|
|
type: 'private',
|
|
|
|
unreadCount: 0,
|
|
|
|
verified: 0,
|
|
|
|
};
|
|
|
|
console.log({ conversation });
|
|
|
|
const conversationModel = new Whisper.Conversation(conversation);
|
|
|
|
await window.wrapDeferred(conversationModel.save());
|
|
|
|
|
|
|
|
console.log('Backup test: Ensure that all attachments were saved to disk');
|
|
|
|
const attachmentFiles = removeDirs(glob.sync(attachmentsPattern));
|
|
|
|
console.log({ attachmentFiles });
|
|
|
|
assert.strictEqual(ATTACHMENT_COUNT, attachmentFiles.length);
|
|
|
|
|
|
|
|
console.log('Backup test: Export!');
|
|
|
|
backupDir = tmp.dirSync().name;
|
|
|
|
console.log({ backupDir });
|
|
|
|
await Signal.Backup.exportToDirectory(backupDir, { key });
|
|
|
|
|
|
|
|
console.log('Backup test: Ensure that messages.zip exists');
|
|
|
|
const zipPath = path.join(backupDir, 'messages.zip');
|
2018-04-23 22:36:47 +00:00
|
|
|
const messageZipExists = fse.existsSync(zipPath);
|
2018-04-20 21:55:33 +00:00
|
|
|
assert.strictEqual(true, messageZipExists);
|
|
|
|
|
|
|
|
console.log('Backup test: Ensure that all attachments made it to backup dir');
|
|
|
|
const backupAttachmentPattern = path.join(backupDir, 'attachments/*');
|
|
|
|
const backupAttachments = glob.sync(backupAttachmentPattern);
|
|
|
|
console.log({ backupAttachments });
|
|
|
|
assert.strictEqual(ATTACHMENT_COUNT, backupAttachments.length);
|
|
|
|
|
|
|
|
console.log('Backup test: Clear all data');
|
|
|
|
await clearAllData();
|
|
|
|
|
|
|
|
console.log('Backup test: Import!');
|
|
|
|
await Signal.Backup.importFromDirectory(backupDir, { key });
|
|
|
|
|
|
|
|
console.log('Backup test: ensure that all attachments were imported');
|
|
|
|
const recreatedAttachmentFiles = removeDirs(glob.sync(attachmentsPattern));
|
|
|
|
console.log({ recreatedAttachmentFiles });
|
|
|
|
assert.strictEqual(ATTACHMENT_COUNT, recreatedAttachmentFiles.length);
|
|
|
|
assert.deepEqual(attachmentFiles, recreatedAttachmentFiles);
|
|
|
|
|
|
|
|
console.log('Backup test: Check messages');
|
|
|
|
const messageCollection = new Whisper.MessageCollection();
|
|
|
|
await window.wrapDeferred(messageCollection.fetch());
|
|
|
|
assert.strictEqual(messageCollection.length, MESSAGE_COUNT);
|
|
|
|
const messageFromDB = removeId(messageCollection.at(0).attributes);
|
|
|
|
console.log({ messageFromDB, message });
|
|
|
|
assert.deepEqual(messageFromDB, message);
|
|
|
|
|
|
|
|
console.log('Backup test: check that all attachments were successfully imported');
|
|
|
|
const messageWithAttachmentsFromDB = await loadAllFilesFromDisk(messageFromDB);
|
|
|
|
console.log({ messageWithAttachmentsFromDB, messageWithAttachments });
|
|
|
|
assert.deepEqual(
|
|
|
|
_.omit(messageWithAttachmentsFromDB, ['schemaVersion']),
|
|
|
|
messageWithAttachments
|
|
|
|
);
|
|
|
|
|
|
|
|
console.log('Backup test: check conversations');
|
|
|
|
const conversationCollection = new Whisper.ConversationCollection();
|
|
|
|
await window.wrapDeferred(conversationCollection.fetch());
|
|
|
|
assert.strictEqual(conversationCollection.length, CONVERSATION_COUNT);
|
|
|
|
|
|
|
|
const conversationFromDB = conversationCollection.at(0).attributes;
|
|
|
|
console.log({ conversationFromDB, conversation });
|
|
|
|
assert.deepEqual(
|
|
|
|
conversationFromDB,
|
|
|
|
_.omit(conversation, ['profileAvatar'])
|
|
|
|
);
|
|
|
|
|
|
|
|
console.log('Backup test: Clear all data');
|
|
|
|
await clearAllData();
|
|
|
|
|
|
|
|
console.log('Backup test: Complete!');
|
|
|
|
} finally {
|
|
|
|
if (backupDir) {
|
|
|
|
console.log({ backupDir });
|
|
|
|
console.log('Deleting', backupDir);
|
|
|
|
await fse.remove(backupDir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2017-09-07 01:20:42 +00:00
|
|
|
});
|