You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
7.7 KiB
TypeScript
260 lines
7.7 KiB
TypeScript
import { expect } from 'chai';
|
|
import * as _ from 'lodash';
|
|
import { MessageUtils } from '../../../session/utils';
|
|
import { TestUtils } from '../../../test/test-utils';
|
|
import { PendingMessageCache } from '../../../session/sending/PendingMessageCache';
|
|
|
|
// Equivalent to Data.StorageItem
|
|
interface StorageItem {
|
|
id: string;
|
|
value: any;
|
|
}
|
|
|
|
describe('PendingMessageCache', () => {
|
|
// Initialize new stubbed cache
|
|
let data: StorageItem;
|
|
let pendingMessageCacheStub: PendingMessageCache;
|
|
|
|
beforeEach(async () => {
|
|
// Stub out methods which touch the database
|
|
const storageID = 'pendingMessages';
|
|
data = {
|
|
id: storageID,
|
|
value: '[]',
|
|
};
|
|
|
|
TestUtils.stubData('getItemById')
|
|
.withArgs('pendingMessages')
|
|
.callsFake(async () => {
|
|
return data;
|
|
});
|
|
|
|
TestUtils.stubData('createOrUpdateItem').callsFake((item: StorageItem) => {
|
|
if (item.id === storageID) {
|
|
data = item;
|
|
}
|
|
});
|
|
|
|
pendingMessageCacheStub = new PendingMessageCache();
|
|
await pendingMessageCacheStub.isReady;
|
|
});
|
|
|
|
afterEach(() => {
|
|
TestUtils.restoreStubs();
|
|
});
|
|
|
|
it('can initialize cache', async () => {
|
|
const cache = pendingMessageCacheStub.getAllPending();
|
|
|
|
// We expect the cache to initialise as an empty array
|
|
expect(cache).to.be.instanceOf(Array);
|
|
expect(cache).to.have.length(0);
|
|
});
|
|
|
|
it('can add to cache', async () => {
|
|
const device = TestUtils.generateFakePubkey();
|
|
const message = TestUtils.generateChatMessage();
|
|
const rawMessage = MessageUtils.toRawMessage(device, message);
|
|
|
|
await pendingMessageCacheStub.add(device, message);
|
|
|
|
// Verify that the message is in the cache
|
|
const finalCache = pendingMessageCacheStub.getAllPending();
|
|
|
|
expect(finalCache).to.have.length(1);
|
|
|
|
const addedMessage = finalCache[0];
|
|
expect(addedMessage.device).to.deep.equal(rawMessage.device);
|
|
expect(addedMessage.timestamp).to.deep.equal(rawMessage.timestamp);
|
|
});
|
|
|
|
it('can remove from cache', async () => {
|
|
const device = TestUtils.generateFakePubkey();
|
|
const message = TestUtils.generateChatMessage();
|
|
const rawMessage = MessageUtils.toRawMessage(device, message);
|
|
|
|
await pendingMessageCacheStub.add(device, message);
|
|
|
|
const initialCache = pendingMessageCacheStub.getAllPending();
|
|
expect(initialCache).to.have.length(1);
|
|
|
|
// Remove the message
|
|
await pendingMessageCacheStub.remove(rawMessage);
|
|
|
|
const finalCache = pendingMessageCacheStub.getAllPending();
|
|
|
|
// Verify that the message was removed
|
|
expect(finalCache).to.have.length(0);
|
|
});
|
|
|
|
it('can get devices', async () => {
|
|
const cacheItems = [
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
];
|
|
|
|
cacheItems.forEach(async item => {
|
|
await pendingMessageCacheStub.add(item.device, item.message);
|
|
});
|
|
|
|
const cache = pendingMessageCacheStub.getAllPending();
|
|
expect(cache).to.have.length(cacheItems.length);
|
|
|
|
// Get list of devices
|
|
const devicesKeys = cacheItems.map(item => item.device.key);
|
|
const pulledDevices = pendingMessageCacheStub.getDevices();
|
|
const pulledDevicesKeys = pulledDevices.map(d => d.key);
|
|
|
|
// Verify that device list from cache is equivalent to devices added
|
|
expect(pulledDevicesKeys).to.have.members(devicesKeys);
|
|
});
|
|
|
|
it('can get pending for device', async () => {
|
|
const cacheItems = [
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
];
|
|
|
|
cacheItems.forEach(async item => {
|
|
await pendingMessageCacheStub.add(item.device, item.message);
|
|
});
|
|
|
|
const initialCache = pendingMessageCacheStub.getAllPending();
|
|
expect(initialCache).to.have.length(cacheItems.length);
|
|
|
|
// Get pending for each specific device
|
|
cacheItems.forEach(item => {
|
|
const pendingForDevice = pendingMessageCacheStub.getForDevice(
|
|
item.device
|
|
);
|
|
expect(pendingForDevice).to.have.length(1);
|
|
expect(pendingForDevice[0].device).to.equal(item.device.key);
|
|
});
|
|
});
|
|
|
|
it('can find nothing when empty', async () => {
|
|
const device = TestUtils.generateFakePubkey();
|
|
const message = TestUtils.generateChatMessage();
|
|
const rawMessage = MessageUtils.toRawMessage(device, message);
|
|
|
|
const foundMessage = pendingMessageCacheStub.find(rawMessage);
|
|
expect(foundMessage, 'a message was found in empty cache').to.be.undefined;
|
|
});
|
|
|
|
it('can find message in cache', async () => {
|
|
const device = TestUtils.generateFakePubkey();
|
|
const message = TestUtils.generateChatMessage();
|
|
const rawMessage = MessageUtils.toRawMessage(device, message);
|
|
|
|
await pendingMessageCacheStub.add(device, message);
|
|
|
|
const finalCache = pendingMessageCacheStub.getAllPending();
|
|
expect(finalCache).to.have.length(1);
|
|
|
|
const foundMessage = pendingMessageCacheStub.find(rawMessage);
|
|
expect(foundMessage, 'message not found in cache').to.be.ok;
|
|
foundMessage && expect(foundMessage.device).to.equal(device.key);
|
|
});
|
|
|
|
it('can clear cache', async () => {
|
|
const cacheItems = [
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
];
|
|
|
|
cacheItems.forEach(async item => {
|
|
await pendingMessageCacheStub.add(item.device, item.message);
|
|
});
|
|
|
|
const initialCache = pendingMessageCacheStub.getAllPending();
|
|
expect(initialCache).to.have.length(cacheItems.length);
|
|
|
|
// Clear cache
|
|
await pendingMessageCacheStub.clear();
|
|
|
|
const finalCache = pendingMessageCacheStub.getAllPending();
|
|
expect(finalCache).to.have.length(0);
|
|
});
|
|
|
|
it('can restore from db', async () => {
|
|
const cacheItems = [
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
{
|
|
device: TestUtils.generateFakePubkey(),
|
|
message: TestUtils.generateChatMessage(),
|
|
},
|
|
];
|
|
|
|
cacheItems.forEach(async item => {
|
|
await pendingMessageCacheStub.add(item.device, item.message);
|
|
});
|
|
|
|
const addedMessages = pendingMessageCacheStub.getAllPending();
|
|
expect(addedMessages).to.have.length(cacheItems.length);
|
|
|
|
// Rebuild from DB
|
|
const freshCache = new PendingMessageCache();
|
|
await freshCache.isReady;
|
|
|
|
// Verify messages
|
|
const rebuiltMessages = freshCache.getAllPending();
|
|
|
|
rebuiltMessages.forEach((message, index) => {
|
|
const addedMessage = addedMessages[index];
|
|
|
|
// Pull out plainTextBuffer for a separate check
|
|
const buffersCompare =
|
|
Buffer.compare(
|
|
message.plainTextBuffer,
|
|
addedMessage.plainTextBuffer
|
|
) === 0;
|
|
expect(buffersCompare).to.equal(
|
|
true,
|
|
'buffers were not loaded properly from database'
|
|
);
|
|
|
|
// Compare all other valures
|
|
const trimmedAdded = _.omit(addedMessage, ['plainTextBuffer']);
|
|
const trimmedRebuilt = _.omit(message, ['plainTextBuffer']);
|
|
|
|
expect(_.isEqual(trimmedAdded, trimmedRebuilt)).to.equal(
|
|
true,
|
|
'cached messages were not rebuilt properly'
|
|
);
|
|
});
|
|
});
|
|
});
|