Add Message.createImporter
This commit is contained in:
parent
5a6668e677
commit
bf67254cc5
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -5,6 +5,66 @@ const { stringToArrayBuffer } = require('../../../js/modules/string_to_array_buf
|
|||
|
||||
|
||||
describe('Message', () => {
|
||||
describe('createImporter', () => {
|
||||
it('should ignore messages that didn’t 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('It’s 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('It’s 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 = {
|
||||
|
|
Loading…
Reference in a new issue