Add Message.createImporter

This commit is contained in:
Daniel Gasienica 2018-04-03 21:10:34 -04:00
parent 5a6668e677
commit bf67254cc5
3 changed files with 111 additions and 1 deletions

View file

@ -1,4 +1,4 @@
const { isFunction } = require('lodash');
const { isFunction, isString, omit } = require('lodash');
const Attachment = require('./attachment');
const Errors = require('./errors');
@ -176,3 +176,50 @@ exports.upgradeSchema = async (message, { writeNewAttachmentData } = {}) => {
{ writeNewAttachmentData }
);
};
// createImporter :: (RelativePath -> IO Unit)
// Message ->
// IO (Promise Message)
exports.createImporter = (writeExistingAttachmentData) => {
if (!isFunction(writeExistingAttachmentData)) {
throw new TypeError('"writeExistingAttachmentData" must be a function');
}
return async (message) => {
if (!exports.isValid(message)) {
throw new TypeError('"message" is not valid');
}
const { attachments } = message;
const hasAttachments = attachments && attachments.length > 0;
if (!hasAttachments) {
return message;
}
const lastVersionWithAttachmentDataInMemory = 2;
const willHaveAttachmentsSavedOnFileSystemDuringUpgrade =
message.schemaVersion <= lastVersionWithAttachmentDataInMemory;
if (willHaveAttachmentsSavedOnFileSystemDuringUpgrade) {
return message;
}
attachments.forEach((attachment) => {
if (!Attachment.hasData(attachment)) {
throw new TypeError('"attachment.data" is required during message import');
}
if (!isString(attachment.path)) {
throw new TypeError('"attachment.path" is required');
}
});
const messageWithoutAttachmentData = Object.assign({}, message, {
attachments: await Promise.all(attachments.map(async (attachment) => {
await writeExistingAttachmentData(attachment);
return omit(attachment, ['data']);
})),
});
return messageWithoutAttachmentData;
};
};

View file

@ -114,6 +114,7 @@ const attachmentsPath = Attachments.getPath(app.getPath('userData'));
const deleteAttachmentData = Attachments.createDeleter(attachmentsPath);
const readAttachmentData = Attachments.createReader(attachmentsPath);
const writeNewAttachmentData = Attachments.createWriterForNew(attachmentsPath);
const writeExistingAttachmentData = Attachments.createWriterForExisting(attachmentsPath);
// Injected context functions to keep `Message` agnostic from Electron:
const upgradeSchemaContext = {
@ -137,6 +138,8 @@ window.Signal.Migrations = {};
window.Signal.Migrations.deleteAttachmentData =
Attachment.deleteData(deleteAttachmentData);
window.Signal.Migrations.getPlaceholderMigrations = getPlaceholderMigrations;
window.Signal.Migrations.importMessage =
Message.createImporter(writeExistingAttachmentData);
window.Signal.Migrations.loadAttachmentData = Attachment.loadData(readAttachmentData);
window.Signal.Migrations.Migrations0DatabaseWithAttachmentData =
require('./js/modules/migrations/migrations_0_database_with_attachment_data');

View file

@ -5,6 +5,66 @@ const { stringToArrayBuffer } = require('../../../js/modules/string_to_array_buf
describe('Message', () => {
describe('createImporter', () => {
it('should ignore messages that didnt go through attachment migration', async () => {
const input = {
body: 'Imagine there is no heaven…',
schemaVersion: 2,
};
const expected = {
body: 'Imagine there is no heaven…',
schemaVersion: 2,
};
const writeExistingAttachmentData = () => {};
const actual = await Message.createImporter(writeExistingAttachmentData)(input);
assert.deepEqual(actual, expected);
});
it('should ignore messages without attachments', async () => {
const input = {
body: 'Imagine there is no heaven…',
schemaVersion: 4,
attachments: [],
};
const expected = {
body: 'Imagine there is no heaven…',
schemaVersion: 4,
attachments: [],
};
const writeExistingAttachmentData = () => {};
const actual = await Message.createImporter(writeExistingAttachmentData)(input);
assert.deepEqual(actual, expected);
});
it('should write attachments to file system on original path', async () => {
const input = {
body: 'Imagine there is no heaven…',
schemaVersion: 4,
attachments: [{
path: 'ab/abcdefghi',
data: stringToArrayBuffer('Its easy if you try'),
}],
};
const expected = {
body: 'Imagine there is no heaven…',
schemaVersion: 4,
attachments: [{
path: 'ab/abcdefghi',
}],
};
const writeExistingAttachmentData = (attachment) => {
assert.equal(attachment.path, 'ab/abcdefghi');
assert.deepEqual(attachment.data, stringToArrayBuffer('Its easy if you try'));
};
const actual = await Message.createImporter(writeExistingAttachmentData)(input);
assert.deepEqual(actual, expected);
});
});
describe('initializeSchemaVersion', () => {
it('should ignore messages with previously inherited schema', () => {
const input = {