2020-10-30 20:34:04 +00:00
|
|
|
|
// Copyright 2018-2020 Signal Messenger, LLC
|
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
import { assert } from 'chai';
|
|
|
|
|
import * as sinon from 'sinon';
|
|
|
|
|
|
|
|
|
|
import * as Message from '../../types/Message2';
|
|
|
|
|
import { SignalService } from '../../protobuf';
|
|
|
|
|
import * as Bytes from '../../Bytes';
|
|
|
|
|
import * as MIME from '../../types/MIME';
|
|
|
|
|
|
|
|
|
|
import type { EmbeddedContactType } from '../../types/EmbeddedContact';
|
2022-06-13 21:39:35 +00:00
|
|
|
|
import type { MessageAttributesType } from '../../model-types.d';
|
2022-06-10 01:10:20 +00:00
|
|
|
|
import type { AttachmentType } from '../../types/Attachment';
|
|
|
|
|
import type { LoggerType } from '../../types/Logging';
|
2018-03-14 02:01:23 +00:00
|
|
|
|
|
|
|
|
|
describe('Message', () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const logger: LoggerType = {
|
2018-07-21 19:00:08 +00:00
|
|
|
|
warn: () => null,
|
|
|
|
|
error: () => null,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
fatal: () => null,
|
|
|
|
|
info: () => null,
|
|
|
|
|
debug: () => null,
|
|
|
|
|
trace: () => null,
|
2018-07-21 19:00:08 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
function getDefaultMessage(
|
|
|
|
|
props?: Partial<MessageAttributesType>
|
|
|
|
|
): MessageAttributesType {
|
|
|
|
|
return {
|
|
|
|
|
id: 'some-id',
|
|
|
|
|
type: 'incoming',
|
|
|
|
|
sent_at: 45,
|
|
|
|
|
received_at: 45,
|
|
|
|
|
timestamp: 45,
|
|
|
|
|
conversationId: 'some-conversation-id',
|
|
|
|
|
...props,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getDefaultContext(
|
|
|
|
|
props?: Partial<Message.ContextType>
|
|
|
|
|
): Message.ContextType {
|
|
|
|
|
return {
|
|
|
|
|
getAbsoluteAttachmentPath: (_path: string) =>
|
|
|
|
|
'fake-absolute-attachment-path',
|
|
|
|
|
getAbsoluteStickerPath: (_path: string) => 'fake-absolute-sticker-path',
|
|
|
|
|
getImageDimensions: async (_params: {
|
|
|
|
|
objectUrl: string;
|
|
|
|
|
logger: LoggerType;
|
|
|
|
|
}) => ({
|
|
|
|
|
width: 10,
|
|
|
|
|
height: 20,
|
|
|
|
|
}),
|
|
|
|
|
getRegionCode: () => 'region-code',
|
|
|
|
|
logger,
|
|
|
|
|
makeImageThumbnail: async (_params: {
|
|
|
|
|
size: number;
|
|
|
|
|
objectUrl: string;
|
|
|
|
|
contentType: MIME.MIMEType;
|
|
|
|
|
logger: LoggerType;
|
|
|
|
|
}) => new Blob(),
|
|
|
|
|
makeObjectUrl: (
|
|
|
|
|
_data: Uint8Array | ArrayBuffer,
|
|
|
|
|
_contentType: MIME.MIMEType
|
|
|
|
|
) => 'fake-object-url',
|
|
|
|
|
makeVideoScreenshot: async (_params: {
|
|
|
|
|
objectUrl: string;
|
|
|
|
|
contentType: MIME.MIMEType;
|
|
|
|
|
logger: LoggerType;
|
|
|
|
|
}) => new Blob(),
|
|
|
|
|
revokeObjectUrl: (_objectUrl: string) => undefined,
|
|
|
|
|
writeNewAttachmentData: async (_data: Uint8Array) =>
|
|
|
|
|
'fake-attachment-path',
|
2022-06-13 21:39:35 +00:00
|
|
|
|
writeNewStickerData: async (_data: Uint8Array) => 'fake-sticker-path',
|
2022-06-10 01:10:20 +00:00
|
|
|
|
...props,
|
|
|
|
|
};
|
|
|
|
|
}
|
2022-06-13 21:39:35 +00:00
|
|
|
|
const writeExistingAttachmentData = () => Promise.resolve('path');
|
2022-06-10 01:10:20 +00:00
|
|
|
|
|
2018-04-04 22:57:18 +00:00
|
|
|
|
describe('createAttachmentDataWriter', () => {
|
2018-04-04 01:10:34 +00:00
|
|
|
|
it('should ignore messages that didn’t go through attachment migration', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-04-04 01:10:34 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 2,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-04 01:10:34 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 2,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-04-04 01:10:34 +00:00
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const actual = await Message.createAttachmentDataWriter({
|
|
|
|
|
writeExistingAttachmentData,
|
|
|
|
|
logger,
|
|
|
|
|
})(input);
|
2018-04-04 01:10:34 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should ignore messages without attachments', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-04-04 01:10:34 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 4,
|
|
|
|
|
attachments: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-04 01:10:34 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 4,
|
|
|
|
|
attachments: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-04-04 01:10:34 +00:00
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const actual = await Message.createAttachmentDataWriter({
|
|
|
|
|
writeExistingAttachmentData,
|
|
|
|
|
logger,
|
|
|
|
|
})(input);
|
2018-04-04 01:10:34 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should write attachments to file system on original path', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-04-04 01:10:34 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 4,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.IMAGE_GIF,
|
|
|
|
|
size: 3534,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
path: 'ab/abcdefghi',
|
2021-09-24 00:49:05 +00:00
|
|
|
|
data: Bytes.fromString('It’s easy if you try'),
|
2018-04-27 21:25:04 +00:00
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-04 01:10:34 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 4,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.IMAGE_GIF,
|
|
|
|
|
size: 3534,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
path: 'ab/abcdefghi',
|
|
|
|
|
},
|
|
|
|
|
],
|
2018-04-27 16:32:31 +00:00
|
|
|
|
contact: [],
|
2019-01-16 03:03:56 +00:00
|
|
|
|
preview: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-04-04 01:10:34 +00:00
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
|
|
|
const writeExistingAttachmentData = async (
|
|
|
|
|
attachment: Pick<AttachmentType, 'data' | 'path'>
|
|
|
|
|
) => {
|
2018-04-04 01:10:34 +00:00
|
|
|
|
assert.equal(attachment.path, 'ab/abcdefghi');
|
2021-09-24 00:49:05 +00:00
|
|
|
|
assert.strictEqual(
|
2022-06-10 01:10:20 +00:00
|
|
|
|
Bytes.toString(attachment.data || new Uint8Array()),
|
2021-09-24 00:49:05 +00:00
|
|
|
|
'It’s easy if you try'
|
2018-04-27 21:25:04 +00:00
|
|
|
|
);
|
2022-06-13 21:39:35 +00:00
|
|
|
|
return 'path';
|
2018-04-04 01:10:34 +00:00
|
|
|
|
};
|
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const actual = await Message.createAttachmentDataWriter({
|
|
|
|
|
writeExistingAttachmentData,
|
|
|
|
|
logger,
|
|
|
|
|
})(input);
|
2018-04-04 01:10:34 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
2018-04-20 21:55:33 +00:00
|
|
|
|
|
|
|
|
|
it('should process quote attachment thumbnails', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-04-20 21:55:33 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 4,
|
|
|
|
|
attachments: [],
|
|
|
|
|
quote: {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 3523,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'some-message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
|
|
|
|
thumbnail: {
|
|
|
|
|
path: 'ab/abcdefghi',
|
2021-09-24 00:49:05 +00:00
|
|
|
|
data: Bytes.fromString('It’s easy if you try'),
|
2018-04-27 21:25:04 +00:00
|
|
|
|
},
|
2018-04-20 21:55:33 +00:00
|
|
|
|
},
|
2018-04-27 21:25:04 +00:00
|
|
|
|
],
|
2018-04-20 21:55:33 +00:00
|
|
|
|
},
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-20 21:55:33 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 4,
|
|
|
|
|
attachments: [],
|
|
|
|
|
quote: {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 3523,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'some-message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
|
|
|
|
thumbnail: {
|
|
|
|
|
path: 'ab/abcdefghi',
|
|
|
|
|
},
|
2018-04-20 21:55:33 +00:00
|
|
|
|
},
|
2018-04-27 21:25:04 +00:00
|
|
|
|
],
|
2018-04-20 21:55:33 +00:00
|
|
|
|
},
|
2018-04-27 16:32:31 +00:00
|
|
|
|
contact: [],
|
2019-01-16 03:03:56 +00:00
|
|
|
|
preview: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-04-27 16:32:31 +00:00
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
|
|
|
const writeExistingAttachmentData = async (
|
|
|
|
|
attachment: Pick<AttachmentType, 'data' | 'path'>
|
|
|
|
|
) => {
|
2018-04-27 16:32:31 +00:00
|
|
|
|
assert.equal(attachment.path, 'ab/abcdefghi');
|
2021-09-24 00:49:05 +00:00
|
|
|
|
assert.strictEqual(
|
2022-06-10 01:10:20 +00:00
|
|
|
|
Bytes.toString(attachment.data || new Uint8Array()),
|
2021-09-24 00:49:05 +00:00
|
|
|
|
'It’s easy if you try'
|
2018-04-27 16:32:31 +00:00
|
|
|
|
);
|
2022-06-13 21:39:35 +00:00
|
|
|
|
return 'path';
|
2018-04-27 16:32:31 +00:00
|
|
|
|
};
|
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const actual = await Message.createAttachmentDataWriter({
|
|
|
|
|
writeExistingAttachmentData,
|
|
|
|
|
logger,
|
|
|
|
|
})(input);
|
2018-04-27 16:32:31 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should process contact avatars', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-04-27 16:32:31 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 4,
|
|
|
|
|
attachments: [],
|
|
|
|
|
contact: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
name: { givenName: 'john' },
|
2018-04-27 16:32:31 +00:00
|
|
|
|
avatar: {
|
|
|
|
|
isProfile: false,
|
|
|
|
|
avatar: {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.IMAGE_PNG,
|
|
|
|
|
size: 47,
|
2018-04-27 16:32:31 +00:00
|
|
|
|
path: 'ab/abcdefghi',
|
2021-09-24 00:49:05 +00:00
|
|
|
|
data: Bytes.fromString('It’s easy if you try'),
|
2018-04-27 16:32:31 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-27 16:32:31 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 4,
|
|
|
|
|
attachments: [],
|
|
|
|
|
contact: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
name: { givenName: 'john' },
|
2018-04-27 16:32:31 +00:00
|
|
|
|
avatar: {
|
|
|
|
|
isProfile: false,
|
|
|
|
|
avatar: {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.IMAGE_PNG,
|
|
|
|
|
size: 47,
|
2018-04-27 16:32:31 +00:00
|
|
|
|
path: 'ab/abcdefghi',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
2019-01-16 03:03:56 +00:00
|
|
|
|
preview: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-04-20 21:55:33 +00:00
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
|
|
|
const writeExistingAttachmentData = async (
|
|
|
|
|
attachment: Pick<AttachmentType, 'data' | 'path'>
|
|
|
|
|
) => {
|
2018-04-20 21:55:33 +00:00
|
|
|
|
assert.equal(attachment.path, 'ab/abcdefghi');
|
2021-09-24 00:49:05 +00:00
|
|
|
|
assert.strictEqual(
|
2022-06-10 01:10:20 +00:00
|
|
|
|
Bytes.toString(attachment.data || new Uint8Array()),
|
2021-09-24 00:49:05 +00:00
|
|
|
|
'It’s easy if you try'
|
2018-04-27 21:25:04 +00:00
|
|
|
|
);
|
2022-06-13 21:39:35 +00:00
|
|
|
|
return 'path';
|
2018-04-20 21:55:33 +00:00
|
|
|
|
};
|
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const actual = await Message.createAttachmentDataWriter({
|
|
|
|
|
writeExistingAttachmentData,
|
|
|
|
|
logger,
|
|
|
|
|
})(input);
|
2018-04-20 21:55:33 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
2022-06-13 21:39:35 +00:00
|
|
|
|
return 'path';
|
2018-04-20 21:55:33 +00:00
|
|
|
|
});
|
2018-04-04 01:10:34 +00:00
|
|
|
|
});
|
|
|
|
|
|
2018-03-14 15:45:35 +00:00
|
|
|
|
describe('initializeSchemaVersion', () => {
|
2018-03-14 02:01:23 +00:00
|
|
|
|
it('should ignore messages with previously inherited schema', () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-03-14 02:01:23 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 2,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-03-14 02:01:23 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
schemaVersion: 2,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-03-14 02:01:23 +00:00
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const actual = Message.initializeSchemaVersion({
|
|
|
|
|
message: input,
|
|
|
|
|
logger,
|
|
|
|
|
});
|
2018-03-14 02:01:23 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
context('for message without attachments', () => {
|
|
|
|
|
it('should initialize schema version to zero', () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-03-14 02:01:23 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
attachments: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-03-14 02:01:23 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
|
|
|
|
attachments: [],
|
|
|
|
|
schemaVersion: 0,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-03-14 02:01:23 +00:00
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const actual = Message.initializeSchemaVersion({
|
|
|
|
|
message: input,
|
|
|
|
|
logger,
|
|
|
|
|
});
|
2018-03-14 02:01:23 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
context('for message with attachments', () => {
|
|
|
|
|
it('should inherit existing attachment schema version', () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-03-14 02:01:23 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.IMAGE_JPEG,
|
|
|
|
|
size: 45,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
fileName: 'lennon.jpg',
|
|
|
|
|
schemaVersion: 7,
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-03-14 02:01:23 +00:00
|
|
|
|
body: 'Imagine there is no heaven…',
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.IMAGE_JPEG,
|
|
|
|
|
size: 45,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
fileName: 'lennon.jpg',
|
|
|
|
|
},
|
|
|
|
|
],
|
2018-03-14 02:01:23 +00:00
|
|
|
|
schemaVersion: 7,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-03-14 02:01:23 +00:00
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const actual = Message.initializeSchemaVersion({
|
|
|
|
|
message: input,
|
|
|
|
|
logger,
|
|
|
|
|
});
|
2018-03-14 02:01:23 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
|
|
|
|
describe('upgradeSchema', () => {
|
|
|
|
|
it('should upgrade an unversioned message to the latest version', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.AUDIO_AAC,
|
2018-05-07 19:50:39 +00:00
|
|
|
|
flags: SignalService.AttachmentPointer.Flags.VOICE_MESSAGE,
|
2021-09-24 00:49:05 +00:00
|
|
|
|
data: Bytes.fromString('It’s easy if you try'),
|
2018-04-27 21:25:04 +00:00
|
|
|
|
fileName: 'test\u202Dfig.exe',
|
|
|
|
|
size: 1111,
|
|
|
|
|
},
|
|
|
|
|
],
|
2018-03-14 03:45:19 +00:00
|
|
|
|
schemaVersion: 0,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.AUDIO_AAC,
|
2018-05-07 19:50:39 +00:00
|
|
|
|
flags: 1,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
path: 'abc/abcdefg',
|
|
|
|
|
fileName: 'test\uFFFDfig.exe',
|
|
|
|
|
size: 1111,
|
|
|
|
|
},
|
|
|
|
|
],
|
Index messages with attachments using a boolean
When indexing message attachment metadata using numeric indexes such as:
```javascript
{
conversationId: '+12223334455',
received_at: 123,
attachments: […],
numAttachments: 2,
},
{
conversationId: '+12223334455',
received_at: 456,
attachments: [],
numAttachments: 0,
}
{
conversationId: '+12223334455',
received_at: 789,
attachments: [],
numAttachments: 1,
}
```
It creates an index as follows:
```
[conversationId, received_at, numAttachments]
['+12223334455', 123, 2]
['+12223334455', 456, 0]
['+12223334455', 789, 1]
```
This means a query such as…
```
lowerBound: ['+12223334455', 0, 1 ]
upperBound: ['+12223334455', Number.MAX_VALUE, Number.MAX_VALUE]
```
…will return all three original entries because they span the `received_at`
from `0` through `Number.MAX_VALUE`. One workaround is to index booleans using
`1 | undefined` where `1` is included in the index and `undefined` is not, but
that way we lose the ability to query for the `false` value. Instead, we flip
adjust the index to `[conversationId, hasAttachments, received_at]` and can
then query messages with attachments using
```
[conversationId, 1 /* hasAttachments */, 0 /* received_at */]
[conversationId, 1 /* hasAttachments */, Number.MAX_VALUE /* received_at */]
```
2018-04-14 01:47:06 +00:00
|
|
|
|
hasAttachments: 1,
|
2018-04-25 18:15:06 +00:00
|
|
|
|
hasVisualMediaAttachments: undefined,
|
2018-05-07 19:50:39 +00:00
|
|
|
|
hasFileAttachments: undefined,
|
2018-03-14 03:45:19 +00:00
|
|
|
|
schemaVersion: Message.CURRENT_SCHEMA_VERSION,
|
2018-04-27 16:32:31 +00:00
|
|
|
|
contact: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
2021-09-24 00:49:05 +00:00
|
|
|
|
const expectedAttachmentData = 'It’s easy if you try';
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const context = getDefaultContext({
|
2018-04-27 21:25:04 +00:00
|
|
|
|
writeNewAttachmentData: async attachmentData => {
|
2021-09-24 00:49:05 +00:00
|
|
|
|
assert.strictEqual(
|
|
|
|
|
Bytes.toString(attachmentData),
|
|
|
|
|
expectedAttachmentData
|
|
|
|
|
);
|
2018-03-15 00:45:33 +00:00
|
|
|
|
return 'abc/abcdefg';
|
|
|
|
|
},
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-03-15 00:45:33 +00:00
|
|
|
|
const actual = await Message.upgradeSchema(input, context);
|
2018-03-14 03:45:19 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
context('with multiple upgrade steps', () => {
|
|
|
|
|
it('should return last valid message when any upgrade step fails', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.APPLICATION_JSON,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
fileName: 'test\u202Dfig.exe',
|
|
|
|
|
size: 1111,
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
body: 'start',
|
2018-03-14 03:45:19 +00:00
|
|
|
|
schemaVersion: 0,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.APPLICATION_JSON,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
fileName: 'test\u202Dfig.exe',
|
|
|
|
|
size: 1111,
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
body: 'start +1',
|
2018-03-14 03:45:19 +00:00
|
|
|
|
schemaVersion: 1,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const v1 = async (message: MessageAttributesType) => ({
|
2020-09-09 00:46:29 +00:00
|
|
|
|
...message,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
body: `${message.body} +1`,
|
2020-09-09 00:46:29 +00:00
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
const v2 = async () => {
|
|
|
|
|
throw new Error('boom');
|
|
|
|
|
};
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const v3 = async (message: MessageAttributesType) => ({
|
2020-09-09 00:46:29 +00:00
|
|
|
|
...message,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
body: `${message.body} +3`,
|
2020-09-09 00:46:29 +00:00
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const toVersion1 = Message._withSchemaVersion({
|
|
|
|
|
schemaVersion: 1,
|
|
|
|
|
upgrade: v1,
|
|
|
|
|
});
|
|
|
|
|
const toVersion2 = Message._withSchemaVersion({
|
|
|
|
|
schemaVersion: 2,
|
|
|
|
|
upgrade: v2,
|
|
|
|
|
});
|
|
|
|
|
const toVersion3 = Message._withSchemaVersion({
|
|
|
|
|
schemaVersion: 3,
|
|
|
|
|
upgrade: v3,
|
|
|
|
|
});
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const context = getDefaultContext({ logger });
|
|
|
|
|
const upgradeSchema = async (message: MessageAttributesType) =>
|
2018-07-21 19:00:08 +00:00
|
|
|
|
toVersion3(
|
|
|
|
|
await toVersion2(await toVersion1(message, context), context),
|
|
|
|
|
context
|
|
|
|
|
);
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
|
|
|
|
const actual = await upgradeSchema(input);
|
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should skip out-of-order upgrade steps', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.APPLICATION_JSON,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
fileName: 'test\u202Dfig.exe',
|
|
|
|
|
size: 1111,
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
body: 'start',
|
2018-03-14 03:45:19 +00:00
|
|
|
|
schemaVersion: 0,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
2022-06-10 01:10:20 +00:00
|
|
|
|
contentType: MIME.APPLICATION_JSON,
|
2018-04-27 21:25:04 +00:00
|
|
|
|
fileName: 'test\u202Dfig.exe',
|
|
|
|
|
size: 1111,
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
body: 'start +1 +2',
|
2018-03-14 03:45:19 +00:00
|
|
|
|
schemaVersion: 2,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const v1 = async (message: MessageAttributesType) => ({
|
|
|
|
|
...message,
|
|
|
|
|
body: `${message.body} +1`,
|
2020-09-09 00:46:29 +00:00
|
|
|
|
});
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const v2 = async (message: MessageAttributesType) => ({
|
|
|
|
|
...message,
|
|
|
|
|
body: `${message.body} +2`,
|
2020-09-09 00:46:29 +00:00
|
|
|
|
});
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const v3 = async (message: MessageAttributesType) => ({
|
|
|
|
|
...message,
|
|
|
|
|
body: `${message.body} +3`,
|
2020-09-09 00:46:29 +00:00
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const toVersion1 = Message._withSchemaVersion({
|
|
|
|
|
schemaVersion: 1,
|
|
|
|
|
upgrade: v1,
|
|
|
|
|
});
|
|
|
|
|
const toVersion2 = Message._withSchemaVersion({
|
|
|
|
|
schemaVersion: 2,
|
|
|
|
|
upgrade: v2,
|
|
|
|
|
});
|
|
|
|
|
const toVersion3 = Message._withSchemaVersion({
|
|
|
|
|
schemaVersion: 3,
|
|
|
|
|
upgrade: v3,
|
|
|
|
|
});
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const context = getDefaultContext({ logger });
|
|
|
|
|
const atVersion1 = await toVersion1(input, context);
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
// Note: this will fail to apply and log, since it's jumping two versions up
|
|
|
|
|
const atVersion3 = await toVersion3(atVersion1, context);
|
|
|
|
|
|
|
|
|
|
const actual = await toVersion2(atVersion3, context);
|
2018-03-14 03:45:19 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-03-14 15:45:35 +00:00
|
|
|
|
describe('_withSchemaVersion', () => {
|
2018-03-14 03:45:19 +00:00
|
|
|
|
it('should require a version number', () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const toVersionX = () => null;
|
2018-03-14 03:45:19 +00:00
|
|
|
|
assert.throws(
|
2018-07-21 19:00:08 +00:00
|
|
|
|
() =>
|
2022-06-10 01:10:20 +00:00
|
|
|
|
Message._withSchemaVersion({
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
|
schemaVersion: toVersionX as any,
|
|
|
|
|
upgrade: () => Promise.resolve(getDefaultMessage()),
|
|
|
|
|
}),
|
2018-07-21 19:00:08 +00:00
|
|
|
|
'_withSchemaVersion: schemaVersion is invalid'
|
2018-03-14 03:45:19 +00:00
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should require an upgrade function', () => {
|
|
|
|
|
assert.throws(
|
2022-06-10 01:10:20 +00:00
|
|
|
|
() =>
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
|
Message._withSchemaVersion({ schemaVersion: 2, upgrade: 3 as any }),
|
2018-07-21 19:00:08 +00:00
|
|
|
|
'_withSchemaVersion: upgrade must be a function'
|
2018-03-14 03:45:19 +00:00
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should skip upgrading if message has already been upgraded', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const upgrade = async (message: MessageAttributesType) => ({
|
|
|
|
|
...message,
|
|
|
|
|
foo: true,
|
|
|
|
|
});
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const upgradeWithVersion = Message._withSchemaVersion({
|
|
|
|
|
schemaVersion: 3,
|
|
|
|
|
upgrade,
|
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-03-14 03:45:19 +00:00
|
|
|
|
id: 'guid-guid-guid-guid',
|
|
|
|
|
schemaVersion: 4,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-03-14 03:45:19 +00:00
|
|
|
|
id: 'guid-guid-guid-guid',
|
|
|
|
|
schemaVersion: 4,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const actual = await upgradeWithVersion(
|
|
|
|
|
input,
|
|
|
|
|
getDefaultContext({ logger })
|
|
|
|
|
);
|
2018-03-14 03:45:19 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should return original message if upgrade function throws', async () => {
|
|
|
|
|
const upgrade = async () => {
|
|
|
|
|
throw new Error('boom!');
|
|
|
|
|
};
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const upgradeWithVersion = Message._withSchemaVersion({
|
|
|
|
|
schemaVersion: 3,
|
|
|
|
|
upgrade,
|
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-03-14 03:45:19 +00:00
|
|
|
|
id: 'guid-guid-guid-guid',
|
|
|
|
|
schemaVersion: 0,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-03-14 03:45:19 +00:00
|
|
|
|
id: 'guid-guid-guid-guid',
|
|
|
|
|
schemaVersion: 0,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const actual = await upgradeWithVersion(
|
|
|
|
|
input,
|
|
|
|
|
getDefaultContext({ logger })
|
|
|
|
|
);
|
2018-03-14 03:45:19 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should return original message if upgrade function returns null', async () => {
|
|
|
|
|
const upgrade = async () => null;
|
2018-07-21 19:00:08 +00:00
|
|
|
|
const upgradeWithVersion = Message._withSchemaVersion({
|
|
|
|
|
schemaVersion: 3,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
|
upgrade: upgrade as any,
|
2018-07-21 19:00:08 +00:00
|
|
|
|
});
|
2018-03-14 03:45:19 +00:00
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const input = getDefaultMessage({
|
2018-03-14 03:45:19 +00:00
|
|
|
|
id: 'guid-guid-guid-guid',
|
|
|
|
|
schemaVersion: 0,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-03-14 03:45:19 +00:00
|
|
|
|
id: 'guid-guid-guid-guid',
|
|
|
|
|
schemaVersion: 0,
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const actual = await upgradeWithVersion(
|
|
|
|
|
input,
|
|
|
|
|
getDefaultContext({ logger })
|
|
|
|
|
);
|
2018-03-14 03:45:19 +00:00
|
|
|
|
assert.deepEqual(actual, expected);
|
|
|
|
|
});
|
|
|
|
|
});
|
2018-04-10 22:09:29 +00:00
|
|
|
|
|
|
|
|
|
describe('_mapQuotedAttachments', () => {
|
|
|
|
|
it('handles message with no quote', async () => {
|
2018-04-27 21:25:04 +00:00
|
|
|
|
const upgradeAttachment = sinon
|
|
|
|
|
.stub()
|
|
|
|
|
.throws(new Error("Shouldn't be called"));
|
2018-04-10 22:09:29 +00:00
|
|
|
|
const upgradeVersion = Message._mapQuotedAttachments(upgradeAttachment);
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const message = getDefaultMessage({
|
2018-04-10 22:09:29 +00:00
|
|
|
|
body: 'hey there!',
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const result = await upgradeVersion(message, getDefaultContext());
|
2018-04-10 22:09:29 +00:00
|
|
|
|
assert.deepEqual(result, message);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('handles quote with no attachments', async () => {
|
2018-04-27 21:25:04 +00:00
|
|
|
|
const upgradeAttachment = sinon
|
|
|
|
|
.stub()
|
|
|
|
|
.throws(new Error("Shouldn't be called"));
|
2018-04-10 22:09:29 +00:00
|
|
|
|
const upgradeVersion = Message._mapQuotedAttachments(upgradeAttachment);
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const message = getDefaultMessage({
|
2018-04-10 22:09:29 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
quote: {
|
|
|
|
|
text: 'hey!',
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 34233,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
|
} as any,
|
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-10 22:09:29 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
quote: {
|
|
|
|
|
text: 'hey!',
|
|
|
|
|
attachments: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 34233,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
2018-04-10 22:09:29 +00:00
|
|
|
|
},
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const result = await upgradeVersion(
|
|
|
|
|
message,
|
|
|
|
|
getDefaultContext({ logger })
|
|
|
|
|
);
|
2018-04-10 22:09:29 +00:00
|
|
|
|
assert.deepEqual(result, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('handles zero attachments', async () => {
|
2018-04-27 21:25:04 +00:00
|
|
|
|
const upgradeAttachment = sinon
|
|
|
|
|
.stub()
|
|
|
|
|
.throws(new Error("Shouldn't be called"));
|
2018-04-10 22:09:29 +00:00
|
|
|
|
const upgradeVersion = Message._mapQuotedAttachments(upgradeAttachment);
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const message = getDefaultMessage({
|
2018-04-10 22:09:29 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
quote: {
|
|
|
|
|
text: 'hey!',
|
|
|
|
|
attachments: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 34233,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
2018-04-10 22:09:29 +00:00
|
|
|
|
},
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const result = await upgradeVersion(
|
|
|
|
|
message,
|
|
|
|
|
getDefaultContext({ logger })
|
|
|
|
|
);
|
2018-04-10 22:09:29 +00:00
|
|
|
|
assert.deepEqual(result, message);
|
|
|
|
|
});
|
|
|
|
|
|
2018-04-13 22:45:37 +00:00
|
|
|
|
it('handles attachments with no thumbnail', async () => {
|
2018-04-27 21:25:04 +00:00
|
|
|
|
const upgradeAttachment = sinon
|
|
|
|
|
.stub()
|
|
|
|
|
.throws(new Error("Shouldn't be called"));
|
2018-04-13 22:45:37 +00:00
|
|
|
|
const upgradeVersion = Message._mapQuotedAttachments(upgradeAttachment);
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const message = getDefaultMessage({
|
2018-04-13 22:45:37 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
quote: {
|
|
|
|
|
text: 'hey!',
|
2019-01-30 20:15:07 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
|
|
|
|
fileName: 'manifesto.txt',
|
|
|
|
|
contentType: 'text/plain',
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 34233,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
2018-04-13 22:45:37 +00:00
|
|
|
|
},
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const result = await upgradeVersion(
|
|
|
|
|
message,
|
|
|
|
|
getDefaultContext({ logger })
|
|
|
|
|
);
|
2018-04-13 22:45:37 +00:00
|
|
|
|
assert.deepEqual(result, message);
|
|
|
|
|
});
|
|
|
|
|
|
2019-01-30 20:15:07 +00:00
|
|
|
|
it('does not eliminate thumbnails with missing data field', async () => {
|
2018-04-27 21:25:04 +00:00
|
|
|
|
const upgradeAttachment = sinon
|
|
|
|
|
.stub()
|
2019-01-30 20:15:07 +00:00
|
|
|
|
.returns({ fileName: 'processed!' });
|
2018-04-23 23:43:25 +00:00
|
|
|
|
const upgradeVersion = Message._mapQuotedAttachments(upgradeAttachment);
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const message = getDefaultMessage({
|
2018-04-23 23:43:25 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
quote: {
|
|
|
|
|
text: 'hey!',
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
|
|
|
|
fileName: 'cat.gif',
|
|
|
|
|
contentType: 'image/gif',
|
|
|
|
|
thumbnail: {
|
2019-01-30 20:15:07 +00:00
|
|
|
|
fileName: 'not yet downloaded!',
|
2018-04-27 21:25:04 +00:00
|
|
|
|
},
|
2018-04-23 23:43:25 +00:00
|
|
|
|
},
|
2018-04-27 21:25:04 +00:00
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 34233,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
2018-04-23 23:43:25 +00:00
|
|
|
|
},
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-23 23:43:25 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
quote: {
|
|
|
|
|
text: 'hey!',
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
|
|
|
|
contentType: 'image/gif',
|
|
|
|
|
fileName: 'cat.gif',
|
2019-01-30 20:15:07 +00:00
|
|
|
|
thumbnail: {
|
|
|
|
|
fileName: 'processed!',
|
|
|
|
|
},
|
2018-04-27 21:25:04 +00:00
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 34233,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
2018-04-23 23:43:25 +00:00
|
|
|
|
},
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const result = await upgradeVersion(
|
|
|
|
|
message,
|
|
|
|
|
getDefaultContext({ logger })
|
|
|
|
|
);
|
2018-04-23 23:43:25 +00:00
|
|
|
|
assert.deepEqual(result, expected);
|
|
|
|
|
});
|
|
|
|
|
|
2018-04-10 22:09:29 +00:00
|
|
|
|
it('calls provided async function for each quoted attachment', async () => {
|
2018-04-13 02:02:20 +00:00
|
|
|
|
const upgradeAttachment = sinon.stub().resolves({
|
2018-04-10 22:09:29 +00:00
|
|
|
|
path: '/new/path/on/disk',
|
2018-04-13 02:02:20 +00:00
|
|
|
|
});
|
2018-04-10 22:09:29 +00:00
|
|
|
|
const upgradeVersion = Message._mapQuotedAttachments(upgradeAttachment);
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const message = getDefaultMessage({
|
2018-04-10 22:09:29 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
quote: {
|
|
|
|
|
text: 'hey!',
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
|
|
|
|
thumbnail: {
|
|
|
|
|
data: 'data is here',
|
|
|
|
|
},
|
2018-04-13 22:45:37 +00:00
|
|
|
|
},
|
2018-04-27 21:25:04 +00:00
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 34233,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
2018-04-10 22:09:29 +00:00
|
|
|
|
},
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-10 22:09:29 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
quote: {
|
|
|
|
|
text: 'hey!',
|
2018-04-27 21:25:04 +00:00
|
|
|
|
attachments: [
|
|
|
|
|
{
|
|
|
|
|
thumbnail: {
|
|
|
|
|
path: '/new/path/on/disk',
|
|
|
|
|
},
|
2018-04-13 22:45:37 +00:00
|
|
|
|
},
|
2018-04-27 21:25:04 +00:00
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
id: 34233,
|
|
|
|
|
isViewOnce: false,
|
|
|
|
|
messageId: 'message-id',
|
|
|
|
|
referencedMessageNotFound: false,
|
2018-04-10 22:09:29 +00:00
|
|
|
|
},
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const result = await upgradeVersion(
|
|
|
|
|
message,
|
|
|
|
|
getDefaultContext({ logger })
|
|
|
|
|
);
|
2018-04-10 22:09:29 +00:00
|
|
|
|
assert.deepEqual(result, expected);
|
|
|
|
|
});
|
|
|
|
|
});
|
2018-04-27 16:32:31 +00:00
|
|
|
|
|
|
|
|
|
describe('_mapContact', () => {
|
|
|
|
|
it('handles message with no contact field', async () => {
|
|
|
|
|
const upgradeContact = sinon
|
|
|
|
|
.stub()
|
|
|
|
|
.throws(new Error("Shouldn't be called"));
|
|
|
|
|
const upgradeVersion = Message._mapContact(upgradeContact);
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const message = getDefaultMessage({
|
2018-04-27 16:32:31 +00:00
|
|
|
|
body: 'hey there!',
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-27 16:32:31 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
contact: [],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const result = await upgradeVersion(message, getDefaultContext());
|
2018-04-27 16:32:31 +00:00
|
|
|
|
assert.deepEqual(result, expected);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('handles one contact', async () => {
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const upgradeContact = (contact: EmbeddedContactType) =>
|
|
|
|
|
Promise.resolve(contact);
|
2018-04-27 16:32:31 +00:00
|
|
|
|
const upgradeVersion = Message._mapContact(upgradeContact);
|
|
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
|
const message = getDefaultMessage({
|
2018-04-27 16:32:31 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
contact: [
|
|
|
|
|
{
|
|
|
|
|
name: {
|
|
|
|
|
displayName: 'Someone somewhere',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const expected = getDefaultMessage({
|
2018-04-27 16:32:31 +00:00
|
|
|
|
body: 'hey there!',
|
|
|
|
|
contact: [
|
|
|
|
|
{
|
|
|
|
|
name: {
|
|
|
|
|
displayName: 'Someone somewhere',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
2022-06-10 01:10:20 +00:00
|
|
|
|
});
|
|
|
|
|
const result = await upgradeVersion(message, getDefaultContext());
|
2018-04-27 16:32:31 +00:00
|
|
|
|
assert.deepEqual(result, expected);
|
|
|
|
|
});
|
|
|
|
|
});
|
2018-03-14 02:01:23 +00:00
|
|
|
|
});
|