Merge pull request #1177 from vincentbavitz/message-queue-test

Message Queue Tests
pull/1186/head
Vince 5 years ago committed by GitHub
commit fe7aaa0aaa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -512,7 +512,7 @@ export async function handleDataMessage(
const pubKey = new PubKey(device);
const allDevices = await MultiDeviceProtocol.getAllDevices(pubKey);
return allDevices.some(d => PubKey.isEqual(d, pubKey));
return allDevices.some(d => d.isEqual(pubKey));
};
const ownDevice = await isOwnDevice(source);

@ -1,11 +1,6 @@
import { Message, MessageParams } from './Message';
import { AttachmentPointer, Preview, Quote } from './content';
interface OpenGroup {
server: string;
channel: number;
conversationId: string;
}
import { OpenGroup } from '../../types/OpenGroup';
interface OpenGroupMessageParams extends MessageParams {
group: OpenGroup;
@ -20,7 +15,7 @@ export class OpenGroupMessage extends Message {
public readonly body?: string;
public readonly attachments: Array<AttachmentPointer>;
public readonly quote?: Quote;
public readonly preview: Array<Preview>;
public readonly preview?: Array<Preview>;
constructor({
timestamp,

@ -152,4 +152,11 @@ export class ChatMessage extends DataMessage {
return dataMessage;
}
public isEqual(comparator: ChatMessage): boolean {
return (
this.identifier === comparator.identifier &&
this.timestamp === comparator.timestamp
);
}
}

@ -214,7 +214,7 @@ export class MultiDeviceProtocol {
try {
const ourDevices = await this.getOurDevices();
return ourDevices.some(d => PubKey.isEqual(d, pubKey));
return ourDevices.some(d => d.isEqual(pubKey));
} catch (e) {
return false;
}

@ -61,7 +61,7 @@ export class MessageQueue implements MessageQueueInterface {
// Remove our devices from currentDevices
currentDevices = currentDevices.filter(device =>
ourDevices.some(d => PubKey.isEqual(d, device))
ourDevices.some(d => device.isEqual(d))
);
}
}
@ -74,15 +74,8 @@ export class MessageQueue implements MessageQueueInterface {
}
public async sendToGroup(
message: OpenGroupMessage | ContentMessage
message: OpenGroupMessage | ClosedGroupMessage
): Promise<boolean> {
if (
!(message instanceof OpenGroupMessage) &&
!(message instanceof ClosedGroupMessage)
) {
return false;
}
// Closed groups
if (message instanceof ClosedGroupMessage) {
// Get devices in closed group
@ -92,23 +85,27 @@ export class MessageQueue implements MessageQueueInterface {
}
const recipients = await GroupUtils.getGroupMembers(groupPubKey);
await this.sendMessageToDevices(recipients, message);
return true;
if (recipients.length) {
await this.sendMessageToDevices(recipients, message);
return true;
}
}
// Open groups
if (message instanceof OpenGroupMessage) {
// No queue needed for Open Groups; send directly
try {
await MessageSender.sendToOpenGroup(message);
this.events.emit('success', message);
return true;
} catch (e) {
this.events.emit('fail', message, e);
}
return true;
return false;
}
}
return false;
@ -163,7 +160,9 @@ export class MessageQueue implements MessageQueueInterface {
}
private async process(device: PubKey, message?: ContentMessage) {
if (!message) {
// Don't send to ourselves
const currentDevice = await UserUtil.getCurrentDevicePubKey();
if (!message || (currentDevice && device.isEqual(currentDevice))) {
return;
}

@ -93,7 +93,7 @@ export class PendingMessageCache {
await this.saveToDB();
}
public async loadFromDB() {
private async loadFromDB() {
const messages = await this.getFromStorage();
this.cache = messages;
}

@ -2,5 +2,6 @@
import * as MessageSender from './MessageSender';
export { MessageSender };
export * from './PendingMessageCache';
export * from './MessageQueue';
export * from './MessageQueueInterface';

@ -0,0 +1,82 @@
// This is the Open Group equivalent to the PubKey type.
interface OpenGroupParams {
server: string;
channel: number;
conversationId: string;
}
export class OpenGroup {
private static readonly serverRegex = new RegExp(
'^([\\w-]{2,}.){1,2}[\\w-]{2,}$'
);
private static readonly groupIdRegex = new RegExp(
'^publicChat:[0-9]*@([\\w-]{2,}.){1,2}[\\w-]{2,}$'
);
public readonly server: string;
public readonly channel: number;
public readonly groupId?: string;
public readonly conversationId: string;
constructor(params: OpenGroupParams) {
const strippedServer = params.server.replace('https://', '');
this.server = strippedServer;
// Validate server format
const isValid = OpenGroup.serverRegex.test(this.server);
if (!isValid) {
throw Error('an invalid server or groupId was provided');
}
this.channel = params.channel;
this.conversationId = params.conversationId;
this.groupId = OpenGroup.getGroupId(this.server, this.channel);
}
public static from(
groupId: string,
conversationId: string
): OpenGroup | undefined {
// Returns a new instance from a groupId if it's valid
// eg. groupId = 'publicChat:1@chat.getsession.org'
const server = this.getServer(groupId);
const channel = this.getChannel(groupId);
// Was groupId successfully utilized?
if (!server || !channel) {
return;
}
const openGroupParams = {
server,
channel,
groupId,
conversationId,
} as OpenGroupParams;
if (this.serverRegex.test(server)) {
return;
}
return new OpenGroup(openGroupParams);
}
private static getServer(groupId: string): string | undefined {
const isValid = this.groupIdRegex.test(groupId);
return isValid ? groupId.split('@')[1] : undefined;
}
private static getChannel(groupId: string): number | undefined {
const isValid = this.groupIdRegex.test(groupId);
const channelMatch = groupId.match(/^.*\:([0-9]*)\@.*$/);
return channelMatch && isValid ? Number(channelMatch[1]) : undefined;
}
private static getGroupId(server: string, channel: number): string {
// server is already validated in constructor; no need to re-check
return `publicChat:${channel}@${server}`;
}
}

@ -27,8 +27,10 @@ export class PubKey {
return false;
}
public static isEqual(key: PubKey, comparator: PubKey) {
return key.key === comparator.key;
public isEqual(comparator: PubKey | string) {
return comparator instanceof PubKey
? this.key === comparator.key
: this.key === comparator;
}
}

@ -1,3 +1,4 @@
export * from './EncryptionType';
export * from './RawMessage';
export * from './PubKey';
export * from './OpenGroup';

@ -6,8 +6,8 @@ export function toRawMessage(
device: PubKey,
message: ContentMessage
): RawMessage {
const ttl = message.ttl();
const timestamp = message.timestamp;
const ttl = message.ttl();
const plainTextBuffer = message.plainTextBuffer();
// tslint:disable-next-line: no-unnecessary-local-variable

@ -1,5 +1,5 @@
import * as _ from 'lodash';
import * as UserUtils from '../../util/user';
import { UserUtil } from '../../util/';
import { getAllConversations } from '../../../js/modules/data';
import { ContentMessage, SyncMessage } from '../messages/outgoing';
import { MultiDeviceProtocol } from '../protocols';
@ -11,7 +11,7 @@ export function from(message: ContentMessage): SyncMessage | undefined {
return undefined;
}
export async function canSync(message: ContentMessage): Promise<boolean> {
export function canSync(message: ContentMessage): boolean {
// This function should be agnostic to the device; it shouldn't need
// to know about the recipient
@ -20,7 +20,7 @@ export async function canSync(message: ContentMessage): Promise<boolean> {
}
export async function getSyncContacts(): Promise<Array<any> | undefined> {
const thisDevice = await UserUtils.getCurrentDevicePubKey();
const thisDevice = await UserUtil.getCurrentDevicePubKey();
if (!thisDevice) {
return [];

@ -300,10 +300,7 @@ async function queryConversationsAndContacts(
const primaryDevice = resultPrimaryDevices[i];
if (primaryDevice) {
if (
isSecondaryDevice &&
PubKey.isEqual(primaryDevice, ourPrimaryDevice)
) {
if (isSecondaryDevice && primaryDevice.isEqual(ourPrimaryDevice)) {
conversations.push(ourNumber);
} else {
conversations.push(primaryDevice.key);

@ -5,13 +5,14 @@ import {
OpenGroupMessage,
} from '../../../session/messages/outgoing';
import * as MIME from '../../../../ts/types/MIME';
import { OpenGroup } from '../../../session/types';
describe('OpenGroupMessage', () => {
const group = {
server: 'server',
const group = new OpenGroup({
server: 'chat.example.server',
channel: 1,
conversationId: '0',
};
});
it('can create empty message with just a timestamp and group', () => {
const message = new OpenGroupMessage({

@ -43,7 +43,7 @@ describe('MultiDeviceProtocol', () => {
'getPairingAuthorisationsFor'
).resolves([]);
await MultiDeviceProtocol.getPairingAuthorisations(
TestUtils.generateFakePubkey()
TestUtils.generateFakePubKey()
);
expect(fetchPairingStub.called).to.equal(true, 'Pairing is not fetched.');
expect(fetchPairingStub.calledBefore(dataStub)).to.equal(
@ -53,8 +53,8 @@ describe('MultiDeviceProtocol', () => {
});
it('should return the authorisations from the database', async () => {
const device1 = TestUtils.generateFakePubkey();
const device2 = TestUtils.generateFakePubkey();
const device1 = TestUtils.generateFakePubKey();
const device2 = TestUtils.generateFakePubKey();
const pairing: PairingAuthorisation = {
primaryDevicePubKey: device1.key,
secondaryDevicePubKey: device2.key,
@ -75,7 +75,7 @@ describe('MultiDeviceProtocol', () => {
TestUtils.stubWindow('lokiFileServerAPI', undefined);
expect(
MultiDeviceProtocol.fetchPairingAuthorisations(
TestUtils.generateFakePubkey()
TestUtils.generateFakePubKey()
)
).to.be.rejectedWith('lokiFileServerAPI is not initialised.');
});
@ -101,7 +101,7 @@ describe('MultiDeviceProtocol', () => {
});
const authorisations = await MultiDeviceProtocol.fetchPairingAuthorisations(
TestUtils.generateFakePubkey()
TestUtils.generateFakePubKey()
);
expect(authorisations.length).to.equal(1);
@ -140,8 +140,8 @@ describe('MultiDeviceProtocol', () => {
fetchPairingAuthorisationStub = sandbox
.stub(MultiDeviceProtocol, 'fetchPairingAuthorisations')
.resolves([]);
currentDevice = TestUtils.generateFakePubkey();
device = TestUtils.generateFakePubkey();
currentDevice = TestUtils.generateFakePubKey();
device = TestUtils.generateFakePubKey();
sandbox
.stub(UserUtil, 'getCurrentDevicePubKey')
.resolves(currentDevice.key);
@ -236,7 +236,7 @@ describe('MultiDeviceProtocol', () => {
describe('getAllDevices', () => {
it('should return all devices', async () => {
const primary = TestUtils.generateFakePubkey();
const primary = TestUtils.generateFakePubKey();
const otherDevices = TestUtils.generateFakePubKeys(2);
const authorisations = generateFakeAuthorisations(primary, otherDevices);
sandbox
@ -254,7 +254,7 @@ describe('MultiDeviceProtocol', () => {
describe('getPrimaryDevice', () => {
it('should return the primary device', async () => {
const primary = TestUtils.generateFakePubkey();
const primary = TestUtils.generateFakePubKey();
const otherDevices = TestUtils.generateFakePubKeys(2);
const authorisations = generateFakeAuthorisations(primary, otherDevices);
sandbox
@ -271,7 +271,7 @@ describe('MultiDeviceProtocol', () => {
describe('getSecondaryDevices', () => {
it('should return the secondary devices', async () => {
const primary = TestUtils.generateFakePubkey();
const primary = TestUtils.generateFakePubKey();
const otherDevices = TestUtils.generateFakePubKeys(2);
const authorisations = generateFakeAuthorisations(primary, otherDevices);
sandbox

@ -0,0 +1,386 @@
import { expect } from 'chai';
import * as sinon from 'sinon';
import * as _ from 'lodash';
import { GroupUtils, SyncMessageUtils } from '../../../session/utils';
import { Stubs, TestUtils } from '../../../test/test-utils';
import { MessageQueue } from '../../../session/sending/MessageQueue';
import {
ChatMessage,
ClosedGroupMessage,
ContentMessage,
OpenGroupMessage,
} from '../../../session/messages/outgoing';
import { PubKey, RawMessage } from '../../../session/types';
import { UserUtil } from '../../../util';
import { MessageSender, PendingMessageCache } from '../../../session/sending';
import { toRawMessage } from '../../../session/utils/Messages';
import {
MultiDeviceProtocol,
SessionProtocol,
} from '../../../session/protocols';
// Equivalent to Data.StorageItem
interface StorageItem {
id: string;
value: any;
}
// Helper function to force sequential on events checks
async function tick() {
return new Promise(resolve => {
// tslint:disable-next-line: no-string-based-set-timeout
setTimeout(resolve, 0);
});
}
describe('MessageQueue', () => {
// Initialize new stubbed cache
let data: StorageItem;
const sandbox = sinon.createSandbox();
const ourDevice = TestUtils.generateFakePubKey();
const ourNumber = ourDevice.key;
const pairedDevices = TestUtils.generateFakePubKeys(2);
// Initialize new stubbed queue
let messageQueueStub: MessageQueue;
// Spies
let sendMessageToDevicesSpy: sinon.SinonSpy<
[Array<PubKey>, ContentMessage],
Promise<Array<void>>
>;
let sendSyncMessageSpy: sinon.SinonSpy<
[ContentMessage, Array<PubKey>],
Promise<Array<void>>
>;
let sendToGroupSpy: sinon.SinonSpy<
[OpenGroupMessage | ClosedGroupMessage],
Promise<boolean>
>;
// Message Sender Stubs
let sendStub: sinon.SinonStub<[RawMessage, (number | undefined)?]>;
let sendToOpenGroupStub: sinon.SinonStub<[OpenGroupMessage]>;
// Utils Stubs
let groupMembersStub: sinon.SinonStub;
let canSyncStub: sinon.SinonStub<[ContentMessage], boolean>;
// Session Protocol Stubs
let hasSessionStub: sinon.SinonStub<[PubKey]>;
let sendSessionRequestIfNeededStub: sinon.SinonStub<[PubKey], Promise<void>>;
beforeEach(async () => {
// Stub out methods which touch the database
const storageID = 'pendingMessages';
data = {
id: storageID,
value: '[]',
};
// Pending Message Cache Data Stubs
TestUtils.stubData('getItemById')
.withArgs('pendingMessages')
.resolves(data);
TestUtils.stubData('createOrUpdateItem').callsFake((item: StorageItem) => {
if (item.id === storageID) {
data = item;
}
});
// Utils Stubs
canSyncStub = sandbox.stub(SyncMessageUtils, 'canSync');
canSyncStub.returns(false);
sandbox.stub(UserUtil, 'getCurrentDevicePubKey').resolves(ourNumber);
sandbox.stub(MultiDeviceProtocol, 'getAllDevices').resolves(pairedDevices);
TestUtils.stubWindow('libsignal', {
SignalProtocolAddress: sandbox.stub(),
SessionCipher: Stubs.SessionCipherStub,
} as any);
// Message Sender Stubs
sendStub = sandbox.stub(MessageSender, 'send').resolves();
sendToOpenGroupStub = sandbox
.stub(MessageSender, 'sendToOpenGroup')
.resolves(true);
// Group Utils Stubs
sandbox.stub(GroupUtils, 'isMediumGroup').returns(false);
groupMembersStub = sandbox
.stub(GroupUtils, 'getGroupMembers' as any)
.resolves(TestUtils.generateFakePubKeys(10));
// Session Protocol Stubs
sandbox.stub(SessionProtocol, 'sendSessionRequest').resolves();
hasSessionStub = sandbox.stub(SessionProtocol, 'hasSession').resolves(true);
sendSessionRequestIfNeededStub = sandbox
.stub(SessionProtocol, 'sendSessionRequestIfNeeded')
.resolves();
// Pending Mesage Cache Stubs
const chatMessages = Array.from(
{ length: 10 },
TestUtils.generateChatMessage
);
const rawMessage = toRawMessage(
TestUtils.generateFakePubKey(),
TestUtils.generateChatMessage()
);
sandbox.stub(PendingMessageCache.prototype, 'add').resolves(rawMessage);
sandbox.stub(PendingMessageCache.prototype, 'remove').resolves();
sandbox
.stub(PendingMessageCache.prototype, 'getDevices')
.returns(TestUtils.generateFakePubKeys(10));
sandbox
.stub(PendingMessageCache.prototype, 'getForDevice')
.returns(
chatMessages.map(m => toRawMessage(TestUtils.generateFakePubKey(), m))
);
// Spies
sendSyncMessageSpy = sandbox.spy(MessageQueue.prototype, 'sendSyncMessage');
sendMessageToDevicesSpy = sandbox.spy(
MessageQueue.prototype,
'sendMessageToDevices'
);
sendToGroupSpy = sandbox.spy(MessageQueue.prototype, 'sendToGroup');
// Init Queue
messageQueueStub = new MessageQueue();
});
afterEach(() => {
TestUtils.restoreStubs();
sandbox.restore();
});
describe('send', () => {
it('can send to a single device', async () => {
const device = TestUtils.generateFakePubKey();
const message = TestUtils.generateChatMessage();
const promise = messageQueueStub.send(device, message);
await expect(promise).to.be.fulfilled;
});
it('can send sync message', async () => {
const devices = TestUtils.generateFakePubKeys(3);
const message = TestUtils.generateChatMessage();
const promise = messageQueueStub.sendSyncMessage(message, devices);
expect(promise).to.be.fulfilled;
});
});
describe('processPending', () => {
it('will send session request message if no session', async () => {
hasSessionStub.resolves(false);
const device = TestUtils.generateFakePubKey();
const promise = messageQueueStub.processPending(device);
await expect(promise).to.be.fulfilled;
expect(sendSessionRequestIfNeededStub.callCount).to.equal(1);
});
it('will send message if session exists', async () => {
const device = TestUtils.generateFakePubKey();
const hasSession = await hasSessionStub(device);
const promise = messageQueueStub.processPending(device);
await expect(promise).to.be.fulfilled;
expect(hasSession).to.equal(true, 'session does not exist');
expect(sendSessionRequestIfNeededStub.callCount).to.equal(0);
});
});
describe('sendUsingMultiDevice', () => {
it('can send using multidevice', async () => {
const device = TestUtils.generateFakePubKey();
const message = TestUtils.generateChatMessage();
const promise = messageQueueStub.sendUsingMultiDevice(device, message);
await expect(promise).to.be.fulfilled;
// Ensure the arguments passed into sendMessageToDevices are correct
const previousArgs = sendMessageToDevicesSpy.lastCall.args as [
Array<PubKey>,
ChatMessage
];
// Check that instances are equal
expect(previousArgs).to.have.length(2);
const argsPairedDevices = previousArgs[0];
const argsChatMessage = previousArgs[1];
expect(argsChatMessage instanceof ChatMessage).to.equal(
true,
'message passed into sendMessageToDevices was not a valid ChatMessage'
);
expect(argsChatMessage.isEqual(message)).to.equal(
true,
'message passed into sendMessageToDevices has been mutated'
);
argsPairedDevices.forEach((argsPaired: PubKey, index: number) => {
expect(argsPaired instanceof PubKey).to.equal(
true,
'a device passed into sendMessageToDevices was not a PubKey'
);
expect(argsPaired.isEqual(pairedDevices[index])).to.equal(
true,
'a device passed into sendMessageToDevices did not match MessageDeviceProtocol.getAllDevices'
);
});
});
});
describe('sendMessageToDevices', () => {
it('can send to many devices', async () => {
const devices = TestUtils.generateFakePubKeys(10);
const message = TestUtils.generateChatMessage();
const promise = messageQueueStub.sendMessageToDevices(devices, message);
await expect(promise).to.be.fulfilled;
});
it('can send sync message and confirm canSync is valid', async () => {
canSyncStub.returns(true);
const devices = TestUtils.generateFakePubKeys(3);
const message = TestUtils.generateChatMessage();
const pairedDeviceKeys = pairedDevices.map(device => device.key);
const promise = messageQueueStub.sendMessageToDevices(devices, message);
await expect(promise).to.be.fulfilled;
// Check sendSyncMessage parameters
const previousArgs = sendSyncMessageSpy.lastCall.args as [
ChatMessage,
Array<PubKey>
];
expect(sendSyncMessageSpy.callCount).to.equal(1);
// Check that instances are equal
expect(previousArgs).to.have.length(2);
const argsChatMessage = previousArgs[0];
const argsPairedKeys = [...previousArgs[1]].map(d => d.key);
expect(argsChatMessage instanceof ChatMessage).to.equal(
true,
'message passed into sendMessageToDevices was not a valid ChatMessage'
);
expect(argsChatMessage.isEqual(message)).to.equal(
true,
'message passed into sendMessageToDevices has been mutated'
);
// argsPairedKeys and pairedDeviceKeys should contain the same values
const keyArgsValid = _.isEmpty(_.xor(argsPairedKeys, pairedDeviceKeys));
expect(keyArgsValid).to.equal(
true,
'devices passed into sendSyncMessage were invalid'
);
});
});
describe('sendToGroup', () => {
it('can send to closed group', async () => {
const message = TestUtils.generateClosedGroupMessage();
const success = await messageQueueStub.sendToGroup(message);
expect(success).to.equal(true, 'sending to group failed');
});
it('uses correct parameters for sendToGroup with ClosedGroupMessage', async () => {
const message = TestUtils.generateClosedGroupMessage();
const success = await messageQueueStub.sendToGroup(message);
expect(success).to.equal(true, 'sending to group failed');
// Check parameters
const previousArgs = sendMessageToDevicesSpy.lastCall.args as [
Array<PubKey>,
ClosedGroupMessage
];
expect(previousArgs).to.have.length(2);
const argsClosedGroupMessage = previousArgs[1];
expect(argsClosedGroupMessage instanceof ClosedGroupMessage).to.equal(
true,
'message passed into sendMessageToDevices was not a ClosedGroupMessage'
);
});
it("won't send to invalid groupId", async () => {
const message = TestUtils.generateClosedGroupMessage('invalid-group-id');
const success = await messageQueueStub.sendToGroup(message);
// Ensure message parameter passed into sendToGroup is as expected
expect(success).to.equal(
false,
'an invalid groupId was treated as valid'
);
expect(sendToGroupSpy.callCount).to.equal(1);
const argsMessage = sendToGroupSpy.lastCall.args[0];
expect(argsMessage instanceof ClosedGroupMessage).to.equal(
true,
'message passed into sendToGroup was not a ClosedGroupMessage'
);
expect(success).to.equal(
false,
'invalid ClosedGroupMessage was propogated through sendToGroup'
);
});
it('wont send message to empty closed group', async () => {
groupMembersStub.resolves(TestUtils.generateFakePubKeys(0));
const message = TestUtils.generateClosedGroupMessage();
const response = await messageQueueStub.sendToGroup(message);
expect(response).to.equal(
false,
'sendToGroup send a message to an empty group'
);
});
it('can send to open group', async () => {
const message = TestUtils.generateOpenGroupMessage();
const success = await messageQueueStub.sendToGroup(message);
expect(success).to.equal(true, 'sending to group failed');
});
});
describe('events', () => {
it('can send events on message sending success', async () => {
const successSpy = sandbox.spy();
messageQueueStub.events.on('success', successSpy);
const device = TestUtils.generateFakePubKey();
const promise = messageQueueStub.processPending(device);
await expect(promise).to.be.fulfilled;
await tick();
expect(successSpy.callCount).to.equal(1);
});
it('can send events on message sending failure', async () => {
sendStub.throws(new Error('Failed to send message.'));
const failureSpy = sandbox.spy();
messageQueueStub.events.on('fail', failureSpy);
const device = TestUtils.generateFakePubKey();
const promise = messageQueueStub.processPending(device);
await expect(promise).to.be.fulfilled;
await tick();
expect(failureSpy.callCount).to.equal(1);
});
});
});

@ -52,7 +52,7 @@ describe('PendingMessageCache', () => {
});
it('can add to cache', async () => {
const device = TestUtils.generateFakePubkey();
const device = TestUtils.generateFakePubKey();
const message = TestUtils.generateChatMessage();
const rawMessage = MessageUtils.toRawMessage(device, message);
@ -69,7 +69,7 @@ describe('PendingMessageCache', () => {
});
it('can remove from cache', async () => {
const device = TestUtils.generateFakePubkey();
const device = TestUtils.generateFakePubKey();
const message = TestUtils.generateChatMessage();
const rawMessage = MessageUtils.toRawMessage(device, message);
@ -90,15 +90,15 @@ describe('PendingMessageCache', () => {
it('can get devices', async () => {
const cacheItems = [
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
];
@ -122,11 +122,11 @@ describe('PendingMessageCache', () => {
it('can get pending for device', async () => {
const cacheItems = [
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
];
@ -149,7 +149,7 @@ describe('PendingMessageCache', () => {
});
it('can find nothing when empty', async () => {
const device = TestUtils.generateFakePubkey();
const device = TestUtils.generateFakePubKey();
const message = TestUtils.generateChatMessage();
const rawMessage = MessageUtils.toRawMessage(device, message);
@ -158,7 +158,7 @@ describe('PendingMessageCache', () => {
});
it('can find message in cache', async () => {
const device = TestUtils.generateFakePubkey();
const device = TestUtils.generateFakePubKey();
const message = TestUtils.generateChatMessage();
const rawMessage = MessageUtils.toRawMessage(device, message);
@ -175,15 +175,15 @@ describe('PendingMessageCache', () => {
it('can clear cache', async () => {
const cacheItems = [
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
];
@ -205,15 +205,15 @@ describe('PendingMessageCache', () => {
it('can restore from db', async () => {
const cacheItems = [
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
{
device: TestUtils.generateFakePubkey(),
device: TestUtils.generateFakePubKey(),
message: TestUtils.generateChatMessage(),
},
];

@ -5,7 +5,12 @@ import * as DataShape from '../../../js/modules/data';
import { v4 as uuid } from 'uuid';
import { PubKey } from '../../../ts/session/types';
import { ChatMessage } from '../../session/messages/outgoing';
import {
ChatMessage,
ClosedGroupChatMessage,
OpenGroupMessage,
} from '../../session/messages/outgoing';
import { OpenGroup } from '../../session/types/OpenGroup';
const globalAny: any = global;
const sandbox = sinon.createSandbox();
@ -64,7 +69,7 @@ export function restoreStubs() {
sandbox.restore();
}
export function generateFakePubkey(): PubKey {
export function generateFakePubKey(): PubKey {
// Generates a mock pubkey for testing
const numBytes = PubKey.PUBKEY_LEN / 2 - 1;
const hexBuffer = crypto.randomBytes(numBytes).toString('hex');
@ -74,8 +79,10 @@ export function generateFakePubkey(): PubKey {
}
export function generateFakePubKeys(amount: number): Array<PubKey> {
const numPubKeys = amount > 0 ? Math.floor(amount) : 0;
// tslint:disable-next-line: no-unnecessary-callback-wrapper
return new Array(amount).fill(0).map(() => generateFakePubkey());
return new Array(numPubKeys).fill(0).map(() => generateFakePubKey());
}
export function generateChatMessage(): ChatMessage {
@ -90,3 +97,30 @@ export function generateChatMessage(): ChatMessage {
preview: undefined,
});
}
export function generateOpenGroupMessage(): OpenGroupMessage {
const group = new OpenGroup({
server: 'chat.example.server',
channel: 0,
conversationId: '0',
});
return new OpenGroupMessage({
timestamp: Date.now(),
group,
attachments: undefined,
preview: undefined,
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
quote: undefined,
});
}
export function generateClosedGroupMessage(
groupId?: string
): ClosedGroupChatMessage {
return new ClosedGroupChatMessage({
identifier: uuid(),
groupId: groupId ?? generateFakePubKey().key,
chatMessage: generateChatMessage(),
});
}

Loading…
Cancel
Save