2021-02-09 07:00:54 +01:00
|
|
|
// tslint:disable: no-implicit-dependencies max-func-body-length no-unused-expression
|
|
|
|
|
2020-06-19 02:33:02 +02:00
|
|
|
import chai from 'chai';
|
2020-06-17 09:06:31 +02:00
|
|
|
import * as sinon from 'sinon';
|
2020-06-19 08:46:42 +02:00
|
|
|
import _ from 'lodash';
|
2020-08-03 03:45:02 +02:00
|
|
|
import { describe } from 'mocha';
|
|
|
|
|
2021-01-21 03:46:01 +01:00
|
|
|
import { GroupUtils, PromiseUtils, UserUtils } from '../../../../session/utils';
|
|
|
|
import { TestUtils } from '../../../../test/test-utils';
|
2020-08-03 03:45:02 +02:00
|
|
|
import { MessageQueue } from '../../../../session/sending/MessageQueue';
|
2020-06-17 05:12:20 +02:00
|
|
|
import {
|
2020-06-17 08:49:20 +02:00
|
|
|
ContentMessage,
|
2020-06-17 05:12:20 +02:00
|
|
|
OpenGroupMessage,
|
2020-08-03 03:45:02 +02:00
|
|
|
} from '../../../../session/messages/outgoing';
|
2021-01-21 03:46:01 +01:00
|
|
|
import { PubKey, RawMessage } from '../../../../session/types';
|
2020-08-03 03:45:02 +02:00
|
|
|
import { MessageSender } from '../../../../session/sending';
|
|
|
|
import { PendingMessageCacheStub } from '../../../test-utils/stubs';
|
2021-01-28 02:06:51 +01:00
|
|
|
import { ClosedGroupMessage } from '../../../../session/messages/outgoing/content/data/group/ClosedGroupMessage';
|
2020-06-14 20:35:10 +02:00
|
|
|
|
2021-02-09 07:00:54 +01:00
|
|
|
import chaiAsPromised from 'chai-as-promised';
|
|
|
|
chai.use(chaiAsPromised as any);
|
2021-02-09 23:30:56 +01:00
|
|
|
chai.should();
|
2020-06-19 02:33:02 +02:00
|
|
|
|
|
|
|
const { expect } = chai;
|
2020-06-18 03:14:03 +02:00
|
|
|
|
2020-09-08 02:49:59 +02:00
|
|
|
// tslint:disable-next-line: max-func-body-length
|
2020-06-11 00:19:44 +02:00
|
|
|
describe('MessageQueue', () => {
|
2020-06-16 00:33:53 +02:00
|
|
|
// Initialize new stubbed cache
|
2020-06-14 23:00:02 +02:00
|
|
|
const sandbox = sinon.createSandbox();
|
2020-06-18 05:46:58 +02:00
|
|
|
const ourDevice = TestUtils.generateFakePubKey();
|
2020-06-17 05:12:20 +02:00
|
|
|
const ourNumber = ourDevice.key;
|
2020-06-15 23:44:37 +02:00
|
|
|
|
2020-06-16 08:53:10 +02:00
|
|
|
// Initialize new stubbed queue
|
2020-06-19 02:33:02 +02:00
|
|
|
let pendingMessageCache: PendingMessageCacheStub;
|
2020-06-14 20:35:10 +02:00
|
|
|
let messageQueueStub: MessageQueue;
|
2020-06-16 08:53:10 +02:00
|
|
|
|
2020-06-15 23:44:37 +02:00
|
|
|
// Message Sender Stubs
|
2020-06-14 23:00:02 +02:00
|
|
|
let sendStub: sinon.SinonStub<[RawMessage, (number | undefined)?]>;
|
2020-06-16 08:53:10 +02:00
|
|
|
|
2021-02-09 07:00:54 +01:00
|
|
|
beforeEach(() => {
|
2020-06-16 00:33:53 +02:00
|
|
|
// Utils Stubs
|
2021-01-29 01:29:24 +01:00
|
|
|
sandbox.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(ourNumber);
|
2020-06-18 05:24:53 +02:00
|
|
|
|
2020-06-14 23:00:02 +02:00
|
|
|
TestUtils.stubWindow('libsignal', {
|
|
|
|
SignalProtocolAddress: sandbox.stub(),
|
|
|
|
} as any);
|
|
|
|
|
2020-06-15 23:44:37 +02:00
|
|
|
// Message Sender Stubs
|
|
|
|
sendStub = sandbox.stub(MessageSender, 'send').resolves();
|
2020-06-14 23:00:02 +02:00
|
|
|
|
2020-06-16 08:53:10 +02:00
|
|
|
// Init Queue
|
2020-06-19 02:33:02 +02:00
|
|
|
pendingMessageCache = new PendingMessageCacheStub();
|
|
|
|
messageQueueStub = new MessageQueue(pendingMessageCache);
|
2020-06-14 20:35:10 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
TestUtils.restoreStubs();
|
2020-06-14 23:00:02 +02:00
|
|
|
sandbox.restore();
|
2020-06-15 23:44:37 +02:00
|
|
|
});
|
|
|
|
|
2020-06-17 07:59:12 +02:00
|
|
|
describe('processPending', () => {
|
2021-01-18 00:58:34 +01:00
|
|
|
it('will send messages', async () => {
|
2020-06-18 05:46:58 +02:00
|
|
|
const device = TestUtils.generateFakePubKey();
|
2021-01-18 00:58:34 +01:00
|
|
|
await pendingMessageCache.add(device, TestUtils.generateChatMessage());
|
2020-06-14 20:35:10 +02:00
|
|
|
|
2021-01-18 00:58:34 +01:00
|
|
|
const successPromise = PromiseUtils.waitForTask(done => {
|
|
|
|
messageQueueStub.events.once('sendSuccess', done);
|
|
|
|
});
|
2020-06-19 02:33:02 +02:00
|
|
|
await messageQueueStub.processPending(device);
|
2021-02-09 07:00:54 +01:00
|
|
|
// tslint:disable-next-line: no-unused-expression
|
|
|
|
expect(successPromise).to.eventually.be.fulfilled;
|
2020-06-19 02:33:02 +02:00
|
|
|
});
|
2020-06-16 08:53:10 +02:00
|
|
|
|
2020-06-19 02:33:02 +02:00
|
|
|
it('should remove message from cache', async () => {
|
2020-11-25 02:26:42 +01:00
|
|
|
const events = ['sendSuccess', 'sendFail'];
|
2020-06-19 02:33:02 +02:00
|
|
|
for (const event of events) {
|
2020-11-25 02:26:42 +01:00
|
|
|
if (event === 'sendSuccess') {
|
2020-06-19 02:33:02 +02:00
|
|
|
sendStub.resolves();
|
|
|
|
} else {
|
|
|
|
sendStub.throws(new Error('fail'));
|
|
|
|
}
|
|
|
|
|
|
|
|
const device = TestUtils.generateFakePubKey();
|
|
|
|
await pendingMessageCache.add(device, TestUtils.generateChatMessage());
|
|
|
|
|
|
|
|
const initialMessages = await pendingMessageCache.getForDevice(device);
|
|
|
|
expect(initialMessages).to.have.length(1);
|
|
|
|
await messageQueueStub.processPending(device);
|
|
|
|
|
2020-06-19 08:46:42 +02:00
|
|
|
const promise = PromiseUtils.waitUntil(async () => {
|
2020-06-19 02:33:02 +02:00
|
|
|
const messages = await pendingMessageCache.getForDevice(device);
|
|
|
|
return messages.length === 0;
|
|
|
|
});
|
2021-02-09 07:00:54 +01:00
|
|
|
return promise.should.be.fulfilled;
|
2020-06-19 02:33:02 +02:00
|
|
|
}
|
2020-06-22 01:10:57 +02:00
|
|
|
}).timeout(15000);
|
2020-06-16 08:53:10 +02:00
|
|
|
|
2020-06-19 02:33:02 +02:00
|
|
|
describe('events', () => {
|
|
|
|
it('should send a success event if message was sent', async () => {
|
|
|
|
const device = TestUtils.generateFakePubKey();
|
|
|
|
const message = TestUtils.generateChatMessage();
|
|
|
|
await pendingMessageCache.add(device, message);
|
2020-06-16 09:59:20 +02:00
|
|
|
|
2020-06-19 08:46:42 +02:00
|
|
|
const eventPromise = PromiseUtils.waitForTask<
|
|
|
|
RawMessage | OpenGroupMessage
|
|
|
|
>(complete => {
|
2020-11-25 02:26:42 +01:00
|
|
|
messageQueueStub.events.once('sendSuccess', complete);
|
2020-06-19 02:33:02 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
await messageQueueStub.processPending(device);
|
|
|
|
|
|
|
|
const rawMessage = await eventPromise;
|
|
|
|
expect(rawMessage.identifier).to.equal(message.identifier);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should send a fail event if something went wrong while sending', async () => {
|
|
|
|
sendStub.throws(new Error('failure'));
|
|
|
|
|
|
|
|
const spy = sandbox.spy();
|
2020-11-25 02:26:42 +01:00
|
|
|
messageQueueStub.events.on('sendFail', spy);
|
2020-06-19 02:33:02 +02:00
|
|
|
|
|
|
|
const device = TestUtils.generateFakePubKey();
|
|
|
|
const message = TestUtils.generateChatMessage();
|
|
|
|
await pendingMessageCache.add(device, message);
|
|
|
|
|
2020-06-19 08:46:42 +02:00
|
|
|
const eventPromise = PromiseUtils.waitForTask<
|
|
|
|
[RawMessage | OpenGroupMessage, Error]
|
|
|
|
>(complete => {
|
2020-11-25 02:26:42 +01:00
|
|
|
messageQueueStub.events.once('sendFail', (...args) => {
|
2020-06-19 02:33:02 +02:00
|
|
|
complete(args);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
await messageQueueStub.processPending(device);
|
|
|
|
|
|
|
|
const [rawMessage, error] = await eventPromise;
|
|
|
|
expect(rawMessage.identifier).to.equal(message.identifier);
|
|
|
|
expect(error.message).to.equal('failure');
|
2020-06-16 09:59:20 +02:00
|
|
|
});
|
2020-06-16 05:58:15 +02:00
|
|
|
});
|
2020-06-12 03:19:19 +02:00
|
|
|
});
|
|
|
|
|
2021-01-20 06:58:59 +01:00
|
|
|
describe('sendToPubKey', () => {
|
|
|
|
it('should send the message to the device', async () => {
|
2021-02-11 04:04:08 +01:00
|
|
|
const device = TestUtils.generateFakePubKey();
|
|
|
|
const stub = sandbox.stub(messageQueueStub as any, 'process').resolves();
|
2020-06-19 02:33:02 +02:00
|
|
|
|
|
|
|
const message = TestUtils.generateChatMessage();
|
2021-02-11 04:04:08 +01:00
|
|
|
await messageQueueStub.sendToPubKey(device, message);
|
2020-06-19 02:33:02 +02:00
|
|
|
|
|
|
|
const args = stub.lastCall.args as [Array<PubKey>, ContentMessage];
|
2021-02-11 04:04:08 +01:00
|
|
|
expect(args[0]).to.be.equal(device);
|
2020-06-19 02:33:02 +02:00
|
|
|
expect(args[1]).to.equal(message);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('sendToGroup', () => {
|
2021-02-09 07:00:54 +01:00
|
|
|
it('should throw an error if invalid non-group message was passed', () => {
|
2021-01-12 06:11:05 +01:00
|
|
|
// const chatMessage = TestUtils.generateChatMessage();
|
|
|
|
// await expect(
|
|
|
|
// messageQueueStub.sendToGroup(chatMessage)
|
|
|
|
// ).to.be.rejectedWith('Invalid group message passed in sendToGroup.');
|
|
|
|
// Cannot happen with typescript as this function only accept group message now
|
2020-06-24 05:03:38 +02:00
|
|
|
});
|
|
|
|
|
2021-02-09 07:00:54 +01:00
|
|
|
describe('closed groups', () => {
|
2020-06-19 02:33:02 +02:00
|
|
|
it('can send to closed group', async () => {
|
|
|
|
const members = TestUtils.generateFakePubKeys(4).map(
|
2021-01-20 06:58:59 +01:00
|
|
|
p => new PubKey(p.key)
|
2020-06-19 02:33:02 +02:00
|
|
|
);
|
|
|
|
sandbox.stub(GroupUtils, 'getGroupMembers').resolves(members);
|
2020-06-17 09:06:31 +02:00
|
|
|
|
2021-01-14 00:44:15 +01:00
|
|
|
const send = sandbox.stub(messageQueueStub, 'send').resolves();
|
2020-06-14 23:00:02 +02:00
|
|
|
|
2020-06-19 02:33:02 +02:00
|
|
|
const message = TestUtils.generateClosedGroupMessage();
|
2020-06-24 05:03:38 +02:00
|
|
|
await messageQueueStub.sendToGroup(message);
|
2021-01-14 00:44:15 +01:00
|
|
|
expect(send.callCount).to.equal(1);
|
2020-06-14 23:00:02 +02:00
|
|
|
|
2021-01-14 00:44:15 +01:00
|
|
|
const arg = send.getCall(0).args;
|
2021-01-28 02:06:51 +01:00
|
|
|
expect(arg[1] instanceof ClosedGroupMessage).to.equal(
|
2020-06-19 02:33:02 +02:00
|
|
|
true,
|
2021-01-28 02:06:51 +01:00
|
|
|
'message sent to group member was not a ClosedGroupMessage'
|
2020-06-19 02:33:02 +02:00
|
|
|
);
|
|
|
|
});
|
2020-06-14 20:35:10 +02:00
|
|
|
|
2021-02-09 07:00:54 +01:00
|
|
|
describe('open groups', () => {
|
2021-01-20 06:58:59 +01:00
|
|
|
let sendToOpenGroupStub: sinon.SinonStub<
|
|
|
|
[OpenGroupMessage],
|
|
|
|
Promise<{ serverId: number; serverTimestamp: number }>
|
|
|
|
>;
|
|
|
|
beforeEach(() => {
|
|
|
|
sendToOpenGroupStub = sandbox
|
|
|
|
.stub(MessageSender, 'sendToOpenGroup')
|
|
|
|
.resolves({ serverId: -1, serverTimestamp: -1 });
|
|
|
|
});
|
2020-06-18 03:14:03 +02:00
|
|
|
|
2021-01-20 06:58:59 +01:00
|
|
|
it('can send to open group', async () => {
|
|
|
|
const message = TestUtils.generateOpenGroupMessage();
|
|
|
|
await messageQueueStub.sendToGroup(message);
|
|
|
|
expect(sendToOpenGroupStub.callCount).to.equal(1);
|
|
|
|
});
|
2020-06-17 07:59:12 +02:00
|
|
|
|
2021-01-20 06:58:59 +01:00
|
|
|
it('should emit a success event when send was successful', async () => {
|
2021-01-21 03:46:01 +01:00
|
|
|
sendToOpenGroupStub.resolves({
|
|
|
|
serverId: 5125,
|
|
|
|
serverTimestamp: 5125,
|
|
|
|
});
|
2020-07-31 03:03:52 +02:00
|
|
|
|
2021-01-20 06:58:59 +01:00
|
|
|
const message = TestUtils.generateOpenGroupMessage();
|
|
|
|
const eventPromise = PromiseUtils.waitForTask(complete => {
|
|
|
|
messageQueueStub.events.once('sendSuccess', complete);
|
|
|
|
}, 2000);
|
2020-06-17 07:59:12 +02:00
|
|
|
|
2021-01-20 06:58:59 +01:00
|
|
|
await messageQueueStub.sendToGroup(message);
|
2021-02-09 07:00:54 +01:00
|
|
|
return eventPromise.should.be.fulfilled;
|
2021-01-20 06:58:59 +01:00
|
|
|
});
|
2020-06-17 07:59:12 +02:00
|
|
|
|
2021-01-20 06:58:59 +01:00
|
|
|
it('should emit a fail event if something went wrong', async () => {
|
|
|
|
sendToOpenGroupStub.resolves({ serverId: -1, serverTimestamp: -1 });
|
|
|
|
const message = TestUtils.generateOpenGroupMessage();
|
|
|
|
const eventPromise = PromiseUtils.waitForTask(complete => {
|
|
|
|
messageQueueStub.events.once('sendFail', complete);
|
|
|
|
}, 2000);
|
2020-06-18 03:14:03 +02:00
|
|
|
|
2021-01-20 06:58:59 +01:00
|
|
|
await messageQueueStub.sendToGroup(message);
|
2021-02-09 07:00:54 +01:00
|
|
|
return eventPromise.should.be.fulfilled;
|
2021-01-20 06:58:59 +01:00
|
|
|
});
|
2020-06-19 02:33:02 +02:00
|
|
|
});
|
2020-06-17 08:49:20 +02:00
|
|
|
});
|
2020-06-17 07:59:12 +02:00
|
|
|
});
|
2021-01-21 03:46:01 +01:00
|
|
|
});
|