added hf switching of poll&store requests + tests

pull/2290/head
Audric Ackermann 3 years ago
parent 363977b358
commit d948045e6a
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -15,7 +15,6 @@ export async function getHasSeenHF190() {
if (hasSeenHardfork190 === undefined) {
// read values from db and cache them as it looks like we did not
const oldHhasSeenHardfork190 = (await getItemById('hasSeenHardfork190'))?.value;
// values do not exist in the db yet. Let's store false for now in the db and update our cached value.
if (oldHhasSeenHardfork190 === undefined) {
await createOrUpdateItem({ id: 'hasSeenHardfork190', value: false });

@ -3,7 +3,7 @@ import * as snodePool from './snodePool';
import { ERROR_CODE_NO_CONNECT, retrieveNextMessages } from './SNodeAPI';
import { SignalService } from '../../../protobuf';
import * as Receiver from '../../../receiver/receiver';
import _ from 'lodash';
import _, { concat } from 'lodash';
import {
getLastHashBySnode,
getSeenMessagesByHashList,
@ -20,6 +20,7 @@ import { perfEnd, perfStart } from '../../utils/Performance';
import { ed25519Str } from '../../onions/onionPath';
import { updateIsOnline } from '../../../state/ducks/onion';
import pRetry from 'p-retry';
import { getHasSeenHF190, getHasSeenHF191 } from './hfHandling';
interface Message {
hash: string;
@ -145,7 +146,10 @@ export class SwarmPolling {
}
// we always poll as often as possible for our pubkey
const ourPubkey = UserUtils.getOurPubKeyFromCache();
const directPromise = this.pollOnceForKey(ourPubkey, false, 0);
const directPromises = Promise.all([
this.pollOnceForKey(ourPubkey, false, 0),
// this.pollOnceForKey(ourPubkey, false, 5), // uncomment, and test me once we store the config messages to the namespace 5
]).then(() => undefined);
const now = Date.now();
const groupPromises = this.groupPolling.map(async group => {
@ -162,6 +166,25 @@ export class SwarmPolling {
window?.log?.info(
`Polling for ${loggingId}; timeout: ${convoPollingTimeout} ; diff: ${diff}`
);
const hardfork190Happened = await getHasSeenHF190();
const hardfork191Happened = await getHasSeenHF191();
if (hardfork190Happened && !hardfork191Happened) {
// during the transition period, we poll from both namespaces (0 and -10) for groups
return Promise.all([
this.pollOnceForKey(group.pubkey, true, 0),
this.pollOnceForKey(group.pubkey, true, -10),
]).then(() => undefined);
}
if (hardfork190Happened && hardfork191Happened) {
// after the transition period, we poll from the namespace -10 only for groups
return this.pollOnceForKey(group.pubkey, true, -10);
}
// before any of those hardforks, we just poll from the default namespace being 0
console.warn('before any of those hardforks');
return this.pollOnceForKey(group.pubkey, true, 0);
}
window?.log?.info(
@ -171,7 +194,7 @@ export class SwarmPolling {
return Promise.resolve();
});
try {
await Promise.all(_.concat(directPromise, groupPromises));
await Promise.all(concat([directPromises], groupPromises));
} catch (e) {
window?.log?.info('pollForAllKeys exception: ', e);
throw e;
@ -193,22 +216,19 @@ export class SwarmPolling {
// If we need more nodes, select randomly from the remaining nodes:
// Use 1 node for now:
const COUNT = 1;
let nodesToPoll = _.sampleSize(alreadyPolled, COUNT);
if (nodesToPoll.length < COUNT) {
// We only poll from a single node.
let nodesToPoll = _.sampleSize(alreadyPolled, 1);
if (nodesToPoll.length < 1) {
const notPolled = _.difference(swarmSnodes, alreadyPolled);
const newNeeded = COUNT - alreadyPolled.length;
const newNodes = _.sampleSize(notPolled, newNeeded);
const newNodes = _.sampleSize(notPolled, 1);
nodesToPoll = _.concat(nodesToPoll, newNodes);
}
// this actually doesn't make much sense as we are at only polling from a single one
const promisesSettled = await Promise.allSettled(
nodesToPoll.map(async (n: Snode) => {
nodesToPoll.map(async n => {
return this.pollNodeForKey(n, pubkey, namespace);
})
);

@ -1,4 +1,3 @@
import { EncryptionType } from '../types/EncryptionType';
import { SignalService } from '../../protobuf';
import { PubKey } from '../types';
import { concatUInt8Array, getSodiumRenderer, MessageEncrypter } from '.';
@ -24,15 +23,15 @@ type EncryptResult = {
export async function encrypt(
device: PubKey,
plainTextBuffer: Uint8Array,
encryptionType: EncryptionType
encryptionType: SignalService.Envelope.Type
): Promise<EncryptResult> {
const { CLOSED_GROUP_MESSAGE, SESSION_MESSAGE } = SignalService.Envelope.Type;
if (encryptionType !== EncryptionType.ClosedGroup && encryptionType !== EncryptionType.Fallback) {
if (encryptionType !== CLOSED_GROUP_MESSAGE && encryptionType !== SESSION_MESSAGE) {
throw new Error(`Invalid encryption type:${encryptionType}`);
}
const encryptForClosedGroup = encryptionType === EncryptionType.ClosedGroup;
const encryptForClosedGroup = encryptionType === CLOSED_GROUP_MESSAGE;
const plainText = addMessagePadding(plainTextBuffer);
if (encryptForClosedGroup) {

@ -75,7 +75,7 @@ export async function send(
): Promise<{ wrappedEnvelope: Uint8Array; effectiveTimestamp: number }> {
return pRetry(
async () => {
const device = PubKey.cast(message.device);
const recipient = PubKey.cast(message.device);
const { encryption, ttl } = message;
const {
@ -84,12 +84,17 @@ export async function send(
} = overwriteOutgoingTimestampWithNetworkTimestamp(message);
const { envelopeType, cipherText } = await MessageEncrypter.encrypt(
device,
recipient,
overRiddenTimestampBuffer,
encryption
);
const envelope = await buildEnvelope(envelopeType, device.key, networkTimestamp, cipherText);
const envelope = await buildEnvelope(
envelopeType,
recipient.key,
networkTimestamp,
cipherText
);
const data = wrapEnvelope(envelope);
// make sure to update the local sent_at timestamp, because sometimes, we will get the just pushed message in the receiver side
@ -102,8 +107,8 @@ export async function send(
found.set({ sent_at: networkTimestamp });
await found.commit();
}
await MessageSender.TEST_sendMessageToSnode(
device.key,
await MessageSender.sendMessageToSnode(
recipient.key,
data,
ttl,
networkTimestamp,
@ -121,7 +126,7 @@ export async function send(
}
// tslint:disable-next-line: function-name
export async function TEST_sendMessageToSnode(
export async function sendMessageToSnode(
pubKey: string,
data: Uint8Array,
ttl: number,

@ -3,7 +3,7 @@ import { getMessageById } from '../../data/data';
import { SignalService } from '../../protobuf';
import { PnServer } from '../apis/push_notification_api';
import { OpenGroupVisibleMessage } from '../messages/outgoing/visibleMessage/OpenGroupVisibleMessage';
import { EncryptionType, RawMessage } from '../types';
import { RawMessage } from '../types';
import { UserUtils } from '../utils';
// tslint:disable-next-line: no-unnecessary-class
@ -58,7 +58,8 @@ export class MessageSentHandler {
// FIXME this is not correct and will cause issues with syncing
// At this point the only way to check for medium
// group is by comparing the encryption type
const isClosedGroupMessage = sentMessage.encryption === EncryptionType.ClosedGroup;
const isClosedGroupMessage =
sentMessage.encryption === SignalService.Envelope.Type.CLOSED_GROUP_MESSAGE;
// We trigger a sync message only when the message is not to one of our devices, AND
// the message is not for an open group (there is no sync for opengroups, each device pulls all messages), AND

@ -1,5 +0,0 @@
export enum EncryptionType {
Signal,
Fallback,
ClosedGroup,
}

@ -1,11 +1,11 @@
import { EncryptionType } from './EncryptionType';
import { SignalService } from '../../protobuf';
export type RawMessage = {
identifier: string;
plainTextBuffer: Uint8Array;
device: string;
ttl: number;
encryption: EncryptionType;
encryption: SignalService.Envelope.Type;
};
// For building RawMessages from JSON

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

@ -1,22 +1,23 @@
import { RawMessage } from '../types/RawMessage';
import { EncryptionType, PubKey } from '../types';
import { PubKey } from '../types';
import { ClosedGroupMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupMessage';
import { ClosedGroupNewMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupNewMessage';
import { ClosedGroupEncryptionPairReplyMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupEncryptionPairReplyMessage';
import { ContentMessage } from '../messages/outgoing';
import { ExpirationTimerUpdateMessage } from '../messages/outgoing/controlMessage/ExpirationTimerUpdateMessage';
import { SignalService } from '../../protobuf';
function getEncryptionTypeFromMessageType(
message: ContentMessage,
isGroup = false
): EncryptionType {
): SignalService.Envelope.Type {
// ClosedGroupNewMessage is sent using established channels, so using fallback
if (
message instanceof ClosedGroupNewMessage ||
message instanceof ClosedGroupEncryptionPairReplyMessage
) {
return EncryptionType.Fallback;
return SignalService.Envelope.Type.SESSION_MESSAGE;
}
// 1. any ClosedGroupMessage which is not a ClosedGroupNewMessage must be encoded with ClosedGroup
@ -26,9 +27,9 @@ function getEncryptionTypeFromMessageType(
(message instanceof ExpirationTimerUpdateMessage && message.groupId) ||
isGroup
) {
return EncryptionType.ClosedGroup;
return SignalService.Envelope.Type.CLOSED_GROUP_MESSAGE;
} else {
return EncryptionType.Fallback;
return SignalService.Envelope.Type.SESSION_MESSAGE;
}
}

@ -2,7 +2,6 @@ import chai, { expect } from 'chai';
import * as crypto from 'crypto';
import Sinon, * as sinon from 'sinon';
import { concatUInt8Array, getSodiumRenderer, MessageEncrypter } from '../../../../session/crypto';
import { EncryptionType } from '../../../../session/types/EncryptionType';
import { TestUtils } from '../../../test-utils';
import { SignalService } from '../../../../protobuf';
@ -120,7 +119,7 @@ describe('MessageEncrypter', () => {
const result = await MessageEncrypter.encrypt(
TestUtils.generateFakePubKey(),
data,
EncryptionType.ClosedGroup
SignalService.Envelope.Type.CLOSED_GROUP_MESSAGE
);
chai
.expect(result.envelopeType)
@ -133,7 +132,7 @@ describe('MessageEncrypter', () => {
const result = await MessageEncrypter.encrypt(
TestUtils.generateFakePubKey(),
data,
EncryptionType.Fallback
SignalService.Envelope.Type.SESSION_MESSAGE
);
chai.expect(result.envelopeType).to.deep.equal(SignalService.Envelope.Type.SESSION_MESSAGE);
});
@ -143,7 +142,7 @@ describe('MessageEncrypter', () => {
return MessageEncrypter.encrypt(
TestUtils.generateFakePubKey(),
data,
EncryptionType.Signal
3 as any
).should.eventually.be.rejectedWith(Error);
});
});
@ -162,7 +161,11 @@ describe('MessageEncrypter', () => {
it('should pass the padded message body to encrypt', async () => {
const data = crypto.randomBytes(10);
const spy = sinon.spy(MessageEncrypter, 'encryptUsingSessionProtocol');
await MessageEncrypter.encrypt(TestUtils.generateFakePubKey(), data, EncryptionType.Fallback);
await MessageEncrypter.encrypt(
TestUtils.generateFakePubKey(),
data,
SignalService.Envelope.Type.SESSION_MESSAGE
);
chai.expect(spy.callCount).to.be.equal(1);
const paddedData = addMessagePadding(data);
const firstArgument = new Uint8Array(spy.args[0][1]);

@ -5,7 +5,6 @@ import { MessageSender } from '../../../../session/sending';
import { TestUtils } from '../../../test-utils';
import { MessageEncrypter } from '../../../../session/crypto';
import { SignalService } from '../../../../protobuf';
import { EncryptionType } from '../../../../session/types/EncryptionType';
import { PubKey, RawMessage } from '../../../../session/types';
import { MessageUtils, UserUtils } from '../../../../session/utils';
import { ApiV2 } from '../../../../session/apis/open_group_api/opengroupV2';
@ -26,10 +25,10 @@ describe('MessageSender', () => {
describe('send', () => {
const ourNumber = '0123456789abcdef';
let sessionMessageAPISendStub: sinon.SinonStub<any>;
let encryptStub: sinon.SinonStub<[PubKey, Uint8Array, EncryptionType]>;
let encryptStub: sinon.SinonStub<[PubKey, Uint8Array, SignalService.Envelope.Type]>;
beforeEach(() => {
sessionMessageAPISendStub = Sinon.stub(MessageSender, 'TEST_sendMessageToSnode').resolves();
sessionMessageAPISendStub = Sinon.stub(MessageSender, 'sendMessageToSnode').resolves();
Sinon.stub(Data, 'getMessageById').resolves();

@ -20,6 +20,8 @@ import {
} from '../../../../models/conversation';
import { PubKey } from '../../../../session/types';
import { generateFakeSnodes } from '../../../test-utils/utils';
import { resetHardForkCachedValues } from '../../../../session/apis/snode_api/hfHandling';
import { sleepFor } from '../../../../session/utils/Promise';
// tslint:disable: chai-vague-errors
chai.use(chaiAsPromised as any);
@ -37,6 +39,7 @@ describe('SwarmPolling', () => {
let pollOnceForKeySpy: Sinon.SinonSpy<any>;
let swarmPolling: SwarmPolling;
let getItemByIdStub: Sinon.SinonStub;
let clock: Sinon.SinonFakeTimers;
beforeEach(async () => {
@ -44,7 +47,7 @@ describe('SwarmPolling', () => {
Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(ourNumber);
Sinon.stub(Data, 'getAllConversations').resolves(new ConversationCollection());
Sinon.stub(DataItem, 'getItemById').resolves();
getItemByIdStub = TestUtils.stubDataItem('getItemById');
Sinon.stub(Data, 'saveConversation').resolves();
Sinon.stub(Data, 'getSwarmNodesForPubkey').resolves();
Sinon.stub(Data, 'getLastHashBySnode').resolves();
@ -70,6 +73,7 @@ describe('SwarmPolling', () => {
Sinon.restore();
getConversationController().reset();
clock.restore();
resetHardForkCachedValues();
});
describe('getPollingTimeout', () => {
@ -130,6 +134,12 @@ describe('SwarmPolling', () => {
});
describe('pollForAllKeys', () => {
beforeEach(() => {
Sinon.stub(DataItem, 'createOrUpdateItem').resolves();
});
afterEach(() => {
Sinon.restore();
});
it('does run for our pubkey even if activeAt is really old ', async () => {
const convo = getConversationController().getOrCreate(
ourNumber,
@ -139,7 +149,19 @@ describe('SwarmPolling', () => {
await swarmPolling.start(true);
expect(pollOnceForKeySpy.callCount).to.eq(1);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
});
it('does run for our pubkey even if activeAt is recent ', async () => {
const convo = getConversationController().getOrCreate(
ourNumber,
ConversationTypeEnum.PRIVATE
);
convo.set('active_at', Date.now());
await swarmPolling.start(true);
expect(pollOnceForKeySpy.callCount).to.eq(1);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
});
it('does run for our pubkey even if activeAt is recent ', async () => {
@ -151,7 +173,7 @@ describe('SwarmPolling', () => {
await swarmPolling.start(true);
expect(pollOnceForKeySpy.callCount).to.eq(1);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
});
it('does run for group pubkey on start no matter the recent timestamp ', async () => {
@ -166,11 +188,11 @@ describe('SwarmPolling', () => {
// our pubkey will be polled for, hence the 2
expect(pollOnceForKeySpy.callCount).to.eq(2);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, 0]);
});
it('does run for group pubkey on start no matter the old timestamp ', async () => {
it('does run for group pubkey on start no matter the old timestamp if HF < 19', async () => {
const convo = getConversationController().getOrCreate(
TestUtils.generateFakePubKeyStr(),
ConversationTypeEnum.GROUP
@ -183,8 +205,67 @@ describe('SwarmPolling', () => {
// our pubkey will be polled for, hence the 2
expect(pollOnceForKeySpy.callCount).to.eq(2);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, 0]);
});
it('does run for group pubkey on start no matter the old timestamp if HF >= 19.0 & < 19.1 ', async () => {
const convo = getConversationController().getOrCreate(
TestUtils.generateFakePubKeyStr(),
ConversationTypeEnum.GROUP
);
getItemByIdStub.restore();
getItemByIdStub = TestUtils.stubDataItem('getItemById');
getItemByIdStub
.withArgs('hasSeenHardfork190')
.resolves({ id: 'hasSeenHardfork190', value: true })
.withArgs('hasSeenHardfork191')
.resolves({ id: 'hasSeenHardfork191', value: false });
convo.set('active_at', 1);
const groupConvoPubkey = PubKey.cast(convo.id as string);
swarmPolling.addGroupId(groupConvoPubkey);
await swarmPolling.start(true);
// our pubkey will be polled for, hence the 2
expect(pollOnceForKeySpy.callCount).to.eq(3);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, 0]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([groupConvoPubkey, true, -10]);
getItemByIdStub.restore();
getItemByIdStub = TestUtils.stubDataItem('getItemById');
getItemByIdStub.resolves();
});
it('does only poll from -10 for closed groups if HF >= 19.1 ', async () => {
const convo = getConversationController().getOrCreate(
TestUtils.generateFakePubKeyStr(),
ConversationTypeEnum.GROUP
);
getItemByIdStub.restore();
getItemByIdStub = TestUtils.stubDataItem('getItemById');
getItemByIdStub
.withArgs('hasSeenHardfork190')
.resolves({ id: 'hasSeenHardfork190', value: true })
.withArgs('hasSeenHardfork191')
.resolves({ id: 'hasSeenHardfork191', value: true });
convo.set('active_at', 1);
const groupConvoPubkey = PubKey.cast(convo.id as string);
swarmPolling.addGroupId(groupConvoPubkey);
await swarmPolling.start(true);
// our pubkey will be polled for, hence the 2
expect(pollOnceForKeySpy.callCount).to.eq(2);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, -10]);
getItemByIdStub.restore();
getItemByIdStub = TestUtils.stubDataItem('getItemById');
getItemByIdStub.resolves();
});
it('does run for group pubkey on start but not another time if activeAt is old ', async () => {
@ -204,9 +285,9 @@ describe('SwarmPolling', () => {
await swarmPolling.pollForAllKeys();
expect(pollOnceForKeySpy.callCount).to.eq(3);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, 0]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, 0]);
});
it('does run twice if activeAt less than one hour ', async () => {
@ -219,14 +300,21 @@ describe('SwarmPolling', () => {
const groupConvoPubkey = PubKey.cast(convo.id as string);
swarmPolling.addGroupId(groupConvoPubkey);
await swarmPolling.start(true);
clock.tick(6000);
// no need to do that as the tick will trigger a call in all cases after 5 secs
// await swarmPolling.pollForAllKeys();
clock.tick(9000);
// no need to do that as the tick will trigger a call in all cases after 5 secs await swarmPolling.pollForAllKeys();
/** this is not easy to explain, but
* - during the swarmPolling.start, we get two calls to pollOnceForKeySpy (one for our id and one for group od)
* - the clock ticks 9sec, and another call of pollOnceForKeySpy get started, but as we do not await them, this test fails.
* the only fix is to restore the clock and force the a small sleep to let the thing run in bg
*/
clock.restore();
await sleepFor(10);
expect(pollOnceForKeySpy.callCount).to.eq(4);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.lastCall.args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, 0]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.getCall(3).args).to.deep.eq([groupConvoPubkey, true, 0]);
});
it('does run twice if activeAt is inactive and we tick longer than 2 minutes', async () => {
@ -246,13 +334,19 @@ describe('SwarmPolling', () => {
// more than week old, so inactive group but we have to tick after more than 2 min
convo.set('active_at', Date.now() - 7 * 25 * 3600 * 1000);
clock.tick(timeToTick);
/** this is not easy to explain, but
* - during the swarmPolling.start, we get two calls to pollOnceForKeySpy (one for our id and one for group od)
* - the clock ticks 9sec, and another call of pollOnceForKeySpy get started, but as we do not await them, this test fails.
* the only fix is to restore the clock and force the a small sleep to let the thing run in bg
*/
clock.restore();
await sleepFor(10);
// we should have two more calls here, so 4 total.
expect(pollOnceForKeySpy.callCount).to.eq(4);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, 0]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true, 0]);
});
it('does run once only if group is inactive and we tick less than 2 minutes ', async () => {
@ -274,8 +368,8 @@ describe('SwarmPolling', () => {
// we should have only one more call here, the one for our direct pubkey fetch
expect(pollOnceForKeySpy.callCount).to.eq(3);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true]); // this one comes from the swarmPolling.start
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true, 0]); // this one comes from the swarmPolling.start
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false, 0]);
});
describe('multiple runs', () => {
@ -309,11 +403,11 @@ describe('SwarmPolling', () => {
// we have 4 calls total. 2 for our direct promises run each 5 seconds, and 2 for the group pubkey active (so run every 5 sec too)
expect(pollOnceForKeySpy.callCount).to.eq(4);
// first two calls are our pubkey
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([groupConvoPubkey, true, 0]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true, 0]);
});
it('does run twice if activeAt is more than 2 days old and we tick more than one minute ', async () => {
@ -329,11 +423,12 @@ describe('SwarmPolling', () => {
expect(pollOnceForKeySpy.callCount).to.eq(4);
// first two calls are our pubkey
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.firstCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([groupConvoPubkey, true, 0]);
expect(pollOnceForKeySpy.secondCall.args).to.deep.eq([ourPubkey, false, 0]);
expect(pollOnceForKeySpy.thirdCall.args).to.deep.eq([ourPubkey, false]);
expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true]);
expect(pollOnceForKeySpy.getCalls()[3].args).to.deep.eq([groupConvoPubkey, true, 0]);
});
});
});

@ -3,7 +3,7 @@
import chai from 'chai';
import { TestUtils } from '../../../test-utils';
import { MessageUtils, UserUtils } from '../../../../session/utils';
import { EncryptionType, PubKey } from '../../../../session/types';
import { PubKey } from '../../../../session/types';
import { ClosedGroupVisibleMessage } from '../../../../session/messages/outgoing/visibleMessage/ClosedGroupVisibleMessage';
import { ConfigurationMessage } from '../../../../session/messages/outgoing/controlMessage/ConfigurationMessage';
@ -73,7 +73,7 @@ describe('Message Utils', () => {
const rawMessage = await MessageUtils.toRawMessage(device, message);
const derivedPubKey = PubKey.from(rawMessage.device);
expect(derivedPubKey).to.exist;
expect(derivedPubKey).to.not.be.eq(undefined, 'should maintain pubkey');
expect(derivedPubKey?.isEqual(device)).to.equal(
true,
'pubkey of message was not converted correctly'
@ -87,7 +87,7 @@ describe('Message Utils', () => {
const message = new ClosedGroupVisibleMessage({ chatMessage, groupId });
const rawMessage = await MessageUtils.toRawMessage(device, message);
expect(rawMessage.encryption).to.equal(EncryptionType.ClosedGroup);
expect(rawMessage.encryption).to.equal(SignalService.Envelope.Type.CLOSED_GROUP_MESSAGE);
});
it('should set encryption to Fallback on other messages', async () => {
@ -95,7 +95,7 @@ describe('Message Utils', () => {
const message = TestUtils.generateVisibleMessage();
const rawMessage = await MessageUtils.toRawMessage(device, message);
expect(rawMessage.encryption).to.equal(EncryptionType.Fallback);
expect(rawMessage.encryption).to.equal(SignalService.Envelope.Type.SESSION_MESSAGE);
});
it('passing ClosedGroupNewMessage returns Fallback', async () => {
@ -112,7 +112,7 @@ describe('Message Utils', () => {
expireTimer: 0,
});
const rawMessage = await MessageUtils.toRawMessage(device, msg);
expect(rawMessage.encryption).to.equal(EncryptionType.Fallback);
expect(rawMessage.encryption).to.equal(SignalService.Envelope.Type.SESSION_MESSAGE);
});
it('passing ClosedGroupNameChangeMessage returns ClosedGroup', async () => {
@ -124,7 +124,7 @@ describe('Message Utils', () => {
groupId: TestUtils.generateFakePubKey().key,
});
const rawMessage = await MessageUtils.toRawMessage(device, msg);
expect(rawMessage.encryption).to.equal(EncryptionType.ClosedGroup);
expect(rawMessage.encryption).to.equal(SignalService.Envelope.Type.CLOSED_GROUP_MESSAGE);
});
it('passing ClosedGroupAddedMembersMessage returns ClosedGroup', async () => {
@ -136,7 +136,7 @@ describe('Message Utils', () => {
groupId: TestUtils.generateFakePubKey().key,
});
const rawMessage = await MessageUtils.toRawMessage(device, msg);
expect(rawMessage.encryption).to.equal(EncryptionType.ClosedGroup);
expect(rawMessage.encryption).to.equal(SignalService.Envelope.Type.CLOSED_GROUP_MESSAGE);
});
it('passing ClosedGroupRemovedMembersMessage returns ClosedGroup', async () => {
@ -148,7 +148,7 @@ describe('Message Utils', () => {
groupId: TestUtils.generateFakePubKey().key,
});
const rawMessage = await MessageUtils.toRawMessage(device, msg);
expect(rawMessage.encryption).to.equal(EncryptionType.ClosedGroup);
expect(rawMessage.encryption).to.equal(SignalService.Envelope.Type.CLOSED_GROUP_MESSAGE);
});
it('passing ClosedGroupEncryptionPairMessage returns ClosedGroup', async () => {
@ -169,7 +169,7 @@ describe('Message Utils', () => {
encryptedKeyPairs: fakeWrappers,
});
const rawMessage = await MessageUtils.toRawMessage(device, msg);
expect(rawMessage.encryption).to.equal(EncryptionType.ClosedGroup);
expect(rawMessage.encryption).to.equal(SignalService.Envelope.Type.CLOSED_GROUP_MESSAGE);
});
it('passing ClosedGroupEncryptionKeyPairReply returns Fallback', async () => {
@ -190,7 +190,7 @@ describe('Message Utils', () => {
encryptedKeyPairs: fakeWrappers,
});
const rawMessage = await MessageUtils.toRawMessage(device, msg);
expect(rawMessage.encryption).to.equal(EncryptionType.Fallback);
expect(rawMessage.encryption).to.equal(SignalService.Envelope.Type.SESSION_MESSAGE);
});
it('passing a ConfigurationMessage returns Fallback', async () => {
@ -204,7 +204,7 @@ describe('Message Utils', () => {
contacts: [],
});
const rawMessage = await MessageUtils.toRawMessage(device, msg);
expect(rawMessage.encryption).to.equal(EncryptionType.Fallback);
expect(rawMessage.encryption).to.equal(SignalService.Envelope.Type.SESSION_MESSAGE);
});
});

Loading…
Cancel
Save