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.
643 lines
26 KiB
TypeScript
643 lines
26 KiB
TypeScript
import chai, { expect } from 'chai';
|
|
import chaiAsPromised from 'chai-as-promised';
|
|
import Sinon from 'sinon';
|
|
import { ConversationModel } from '../../../../models/conversation';
|
|
import {
|
|
ConversationAttributes,
|
|
ConversationTypeEnum,
|
|
} from '../../../../models/conversationAttributes';
|
|
import { GetNetworkTime } from '../../../../session/apis/snode_api/getNetworkTime';
|
|
import { DisappearingMessages } from '../../../../session/disappearing_messages';
|
|
import {
|
|
DisappearingMessageConversationModeType,
|
|
DisappearingMessageType,
|
|
} from '../../../../session/disappearing_messages/types';
|
|
import { UserUtils } from '../../../../session/utils';
|
|
import { isValidUnixTimestamp } from '../../../../session/utils/Timestamps';
|
|
import { ReleasedFeatures } from '../../../../util/releaseFeature';
|
|
import { TestUtils } from '../../../test-utils';
|
|
import {
|
|
generateDisappearingVisibleMessage,
|
|
generateFakeExpirationTimerUpdate,
|
|
generateFakeIncomingPrivateMessage,
|
|
generateFakeOutgoingPrivateMessage,
|
|
generateVisibleMessage,
|
|
} from '../../../test-utils/utils';
|
|
|
|
chai.use(chaiAsPromised as any);
|
|
|
|
const testPubkey = TestUtils.generateFakePubKeyStr();
|
|
|
|
describe('DisappearingMessage', () => {
|
|
const getLatestTimestampOffset = 200000;
|
|
const ourNumber = TestUtils.generateFakePubKeyStr();
|
|
const conversationArgs = {
|
|
id: testPubkey,
|
|
type: ConversationTypeEnum.PRIVATE,
|
|
isApproved: true,
|
|
active_at: 123,
|
|
didApproveMe: true,
|
|
} as ConversationAttributes;
|
|
|
|
beforeEach(() => {
|
|
Sinon.stub(GetNetworkTime, 'getLatestTimestampOffset').returns(getLatestTimestampOffset);
|
|
Sinon.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(ourNumber);
|
|
});
|
|
|
|
afterEach(() => {
|
|
Sinon.restore();
|
|
});
|
|
|
|
describe('setExpirationStartTimestamp', () => {
|
|
it('returns a valid unix timestamp for deleteAfterRead', async () => {
|
|
const mode: DisappearingMessageConversationModeType = 'deleteAfterRead';
|
|
const expirationStartTimestamp = DisappearingMessages.setExpirationStartTimestamp(mode);
|
|
|
|
expect(expirationStartTimestamp, 'it should return a number').to.be.is.a('number');
|
|
expect(isValidUnixTimestamp(expirationStartTimestamp!), 'it should be a valid unix timestamp')
|
|
.to.be.true;
|
|
});
|
|
it('returns a valid unix timestamp for deleteAfterSend', async () => {
|
|
const mode: DisappearingMessageConversationModeType = 'deleteAfterSend';
|
|
const expirationStartTimestamp = DisappearingMessages.setExpirationStartTimestamp(mode);
|
|
|
|
expect(expirationStartTimestamp, 'it should return a number').to.be.is.a('number');
|
|
expect(isValidUnixTimestamp(expirationStartTimestamp!), 'it should be a valid unix timestamp')
|
|
.to.be.true;
|
|
});
|
|
it('returns undefined when disappearing messages is off', async () => {
|
|
const mode: DisappearingMessageConversationModeType = 'off';
|
|
const expirationStartTimestamp = DisappearingMessages.setExpirationStartTimestamp(mode);
|
|
|
|
expect(expirationStartTimestamp, 'it should return undefined').to.be.undefined;
|
|
});
|
|
it('if we give it a timestamp it returns the older timestamp for deleteAfterRead', async () => {
|
|
const mode: DisappearingMessageConversationModeType = 'deleteAfterRead';
|
|
const timestamp = new Date().valueOf();
|
|
const expirationStartTimestamp = DisappearingMessages.setExpirationStartTimestamp(
|
|
mode,
|
|
timestamp
|
|
);
|
|
|
|
expect(expirationStartTimestamp, 'it should return a number').to.be.is.a('number');
|
|
expect(isValidUnixTimestamp(expirationStartTimestamp!), 'it should be a valid unix timestamp')
|
|
.to.be.true;
|
|
expect(
|
|
expirationStartTimestamp,
|
|
'expirationStartTimestamp should be less than the input timestamp'
|
|
).to.be.lessThan(timestamp);
|
|
});
|
|
it('if we give it a timestamp it returns the older timestamp for deleteAfterSend', async () => {
|
|
const mode: DisappearingMessageConversationModeType = 'deleteAfterSend';
|
|
const timestamp = new Date().valueOf();
|
|
const expirationStartTimestamp = DisappearingMessages.setExpirationStartTimestamp(
|
|
mode,
|
|
timestamp
|
|
);
|
|
|
|
expect(expirationStartTimestamp, 'it should return a number').to.be.is.a('number');
|
|
expect(isValidUnixTimestamp(expirationStartTimestamp!), 'it should be a valid unix timestamp')
|
|
.to.be.true;
|
|
expect(
|
|
expirationStartTimestamp,
|
|
'expirationStartTimestamp should be less than the input timestamp'
|
|
).to.be.lessThan(timestamp);
|
|
});
|
|
it('if we give it an invalid timestamp it returns undefined', async () => {
|
|
const mode: DisappearingMessageConversationModeType = 'deleteAfterSend';
|
|
const timestamp = -1;
|
|
const expirationStartTimestamp = DisappearingMessages.setExpirationStartTimestamp(
|
|
mode,
|
|
timestamp
|
|
);
|
|
|
|
expect(expirationStartTimestamp, 'it should return undefined').to.be.undefined;
|
|
});
|
|
});
|
|
|
|
describe('changeToDisappearingMessageType', () => {
|
|
it("if it's a Private Conversation and the expirationMode is off and expireTimer = 0 then the message's expirationType is unknown", async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
const expireTimer = 0; // seconds
|
|
const expirationMode = 'off';
|
|
const messageExpirationType = DisappearingMessages.changeToDisappearingMessageType(
|
|
conversation,
|
|
expireTimer,
|
|
expirationMode
|
|
);
|
|
|
|
expect(messageExpirationType, 'returns unknown').to.be.eq('unknown');
|
|
});
|
|
it("if it's a Private Conversation and the expirationMode is deleteAfterRead and expireTimer > 0 then the message's expirationType is deleteAfterRead", async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
const expireTimer = 60; // seconds
|
|
const expirationMode = 'deleteAfterRead';
|
|
const messageExpirationType = DisappearingMessages.changeToDisappearingMessageType(
|
|
conversation,
|
|
expireTimer,
|
|
expirationMode
|
|
);
|
|
|
|
expect(messageExpirationType, 'returns deleteAfterRead').to.be.eq('deleteAfterRead');
|
|
});
|
|
it("if it's a Private Conversation and the expirationMode is deleteAfterSend and expireTimer > 0 then the message's expirationType is deleteAfterSend", async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
const expireTimer = 60; // seconds
|
|
const expirationMode = 'deleteAfterSend';
|
|
const messageExpirationType = DisappearingMessages.changeToDisappearingMessageType(
|
|
conversation,
|
|
expireTimer,
|
|
expirationMode
|
|
);
|
|
|
|
expect(messageExpirationType, 'returns deleteAfterSend').to.be.eq('deleteAfterSend');
|
|
});
|
|
it("if it's a Note to Self Conversation and expireTimer > 0 then the message's expirationType is always deleteAfterSend", async () => {
|
|
const ourConversation = new ConversationModel({
|
|
...conversationArgs,
|
|
id: ourNumber,
|
|
});
|
|
const expireTimer = 60; // seconds
|
|
const expirationMode = 'deleteAfterRead'; // not correct
|
|
const messageExpirationType = DisappearingMessages.changeToDisappearingMessageType(
|
|
ourConversation,
|
|
expireTimer,
|
|
expirationMode
|
|
);
|
|
|
|
expect(messageExpirationType, 'returns deleteAfterSend').to.be.eq('deleteAfterSend');
|
|
});
|
|
it("if it's a Group Conversation and expireTimer > 0 then the message's expirationType is always deleteAfterSend", async () => {
|
|
const ourConversation = new ConversationModel({
|
|
...conversationArgs,
|
|
type: ConversationTypeEnum.GROUP,
|
|
// TODO update to 03 prefix when we release new groups
|
|
id: '05123456564',
|
|
});
|
|
const expireTimer = 60; // seconds
|
|
const expirationMode = 'deleteAfterRead'; // not correct
|
|
const messageExpirationType = DisappearingMessages.changeToDisappearingMessageType(
|
|
ourConversation,
|
|
expireTimer,
|
|
expirationMode
|
|
);
|
|
|
|
expect(messageExpirationType, 'returns deleteAfterSend').to.be.eq('deleteAfterSend');
|
|
});
|
|
// TODO legacy messages support will be removed in a future release
|
|
it("if it's a Private Conversation and the expirationMode is legacy and expireTimer = 0 then the message's expirationType is unknown", async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
const expireTimer = 0; // seconds
|
|
const expirationMode = 'legacy';
|
|
const messageExpirationType = DisappearingMessages.changeToDisappearingMessageType(
|
|
conversation,
|
|
expireTimer,
|
|
expirationMode
|
|
);
|
|
|
|
expect(messageExpirationType, 'returns unknown').to.be.eq('unknown');
|
|
});
|
|
it("if it's a Private Conversation and the expirationMode is undefined and expireTimer > 0 then the message's expirationType is unknown", async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
const expireTimer = 0; // seconds
|
|
const messageExpirationType = DisappearingMessages.changeToDisappearingMessageType(
|
|
conversation,
|
|
expireTimer
|
|
);
|
|
|
|
expect(messageExpirationType, 'returns unknown').to.be.eq('unknown');
|
|
});
|
|
});
|
|
|
|
describe('changeToDisappearingConversationMode', () => {
|
|
it("if it's a Note to Self Conversation and expireTimer > 0 then the conversation mode is always deleteAfterSend", async () => {
|
|
const ourConversation = new ConversationModel({
|
|
...conversationArgs,
|
|
id: ourNumber,
|
|
});
|
|
const expirationType = 'deleteAfterRead'; // not correct
|
|
const expireTimer = 60; // seconds
|
|
const conversationMode = DisappearingMessages.changeToDisappearingConversationMode(
|
|
ourConversation,
|
|
expirationType,
|
|
expireTimer
|
|
);
|
|
|
|
expect(conversationMode, 'returns deleteAfterSend').to.be.eq('deleteAfterSend');
|
|
});
|
|
it("if it's a Group Conversation and expireTimer > 0 then the conversation mode is always deleteAfterSend", async () => {
|
|
const ourConversation = new ConversationModel({
|
|
...conversationArgs,
|
|
type: ConversationTypeEnum.GROUP,
|
|
// TODO update to 03 prefix when we release new groups
|
|
id: '05123456564',
|
|
});
|
|
const expirationType = 'deleteAfterRead'; // not correct
|
|
const expireTimer = 60; // seconds
|
|
const conversationMode = DisappearingMessages.changeToDisappearingConversationMode(
|
|
ourConversation,
|
|
expirationType,
|
|
expireTimer
|
|
);
|
|
|
|
expect(conversationMode, 'returns deleteAfterSend').to.be.eq('deleteAfterSend');
|
|
});
|
|
it("if it's a Private Conversation and expirationType is deleteAfterRead and expireTimer > 0 then the conversation mode stays as deleteAfterRead", async () => {
|
|
const ourConversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
const expirationType = 'deleteAfterRead';
|
|
const expireTimer = 60; // seconds
|
|
const conversationMode = DisappearingMessages.changeToDisappearingConversationMode(
|
|
ourConversation,
|
|
expirationType,
|
|
expireTimer
|
|
);
|
|
|
|
expect(conversationMode, 'returns deleteAfterRead').to.be.eq('deleteAfterRead');
|
|
});
|
|
it("if it's a Private Conversation and expirationType is deleteAfterSend and expireTimer > 0 then the conversation mode stays as deleteAfterSend", async () => {
|
|
const ourConversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
const expirationType = 'deleteAfterSend';
|
|
const expireTimer = 60; // seconds
|
|
const conversationMode = DisappearingMessages.changeToDisappearingConversationMode(
|
|
ourConversation,
|
|
expirationType,
|
|
expireTimer
|
|
);
|
|
|
|
expect(conversationMode, 'returns deleteAfterSend').to.be.eq('deleteAfterSend');
|
|
});
|
|
it('if the type is unknown and expireTimer = 0 then the conversation mode is off', async () => {
|
|
const conversation = new ConversationModel({ ...conversationArgs });
|
|
const expirationType: DisappearingMessageType = 'unknown';
|
|
const expireTimer = 0; // seconds
|
|
const conversationMode = DisappearingMessages.changeToDisappearingConversationMode(
|
|
conversation,
|
|
expirationType,
|
|
expireTimer
|
|
);
|
|
|
|
expect(conversationMode, 'returns off').to.be.eq('off');
|
|
});
|
|
it('if the type is undefined and expireTimer = 0 then the conversation mode is off', async () => {
|
|
const conversation = new ConversationModel({ ...conversationArgs });
|
|
const expireTimer = 0; // seconds
|
|
const conversationMode = DisappearingMessages.changeToDisappearingConversationMode(
|
|
conversation,
|
|
undefined,
|
|
expireTimer
|
|
);
|
|
|
|
expect(conversationMode, 'returns off').to.be.eq('off');
|
|
});
|
|
it('if the type and expireTimer are undefined then the conversation mode is off', async () => {
|
|
const conversation = new ConversationModel({ ...conversationArgs });
|
|
const conversationMode = DisappearingMessages.changeToDisappearingConversationMode(
|
|
conversation
|
|
);
|
|
|
|
expect(conversationMode, 'returns off').to.be.eq('off');
|
|
});
|
|
// TODO legacy messages support will be removed in a future release
|
|
it('if the type is unknown and expireTimer > 0 then the conversation mode is legacy', async () => {
|
|
const conversation = new ConversationModel({ ...conversationArgs });
|
|
const expirationType: DisappearingMessageType = 'unknown';
|
|
const expireTimer = 60; // seconds
|
|
const conversationMode = DisappearingMessages.changeToDisappearingConversationMode(
|
|
conversation,
|
|
expirationType,
|
|
expireTimer
|
|
);
|
|
|
|
expect(conversationMode, 'returns legacy').to.be.eq('legacy');
|
|
});
|
|
it('if the type is undefined and expireTimer > 0 then the conversation mode is legacy', async () => {
|
|
const conversation = new ConversationModel({ ...conversationArgs });
|
|
const expireTimer = 60; // seconds
|
|
const conversationMode = DisappearingMessages.changeToDisappearingConversationMode(
|
|
conversation,
|
|
undefined,
|
|
expireTimer
|
|
);
|
|
|
|
expect(conversationMode, 'returns legacy').to.be.eq('legacy');
|
|
});
|
|
});
|
|
|
|
describe('checkForExpireUpdateInContentMessage', () => {
|
|
it('if we receive a regular message then it returns falsy values', async () => {
|
|
const visibleMessage = generateVisibleMessage();
|
|
const convoToUpdate = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
// TODO legacy messages support will be removed in a future release
|
|
Sinon.stub(ReleasedFeatures, 'checkIsDisappearMessageV2FeatureReleased').resolves(true);
|
|
|
|
const expireUpdate = await DisappearingMessages.checkForExpireUpdateInContentMessage(
|
|
visibleMessage.contentProto(),
|
|
convoToUpdate,
|
|
null
|
|
);
|
|
|
|
expect(expireUpdate?.expirationType, 'expirationType should be unknown').to.equal('unknown');
|
|
expect(expireUpdate?.expirationTimer, 'expirationTimer should be 0').to.equal(0);
|
|
|
|
expect(
|
|
expireUpdate?.isLegacyConversationSettingMessage,
|
|
'isLegacyConversationSettingMessage should be false'
|
|
).to.be.false;
|
|
expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be false').to.be.false;
|
|
});
|
|
it('if we receive a deleteAfterRead message after 1 minute then it returns those values', async () => {
|
|
const disappearingMessage = generateDisappearingVisibleMessage({
|
|
expirationType: 'deleteAfterRead',
|
|
expireTimer: 60,
|
|
});
|
|
|
|
const convoToUpdate = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
// TODO legacy messages support will be removed in a future release
|
|
Sinon.stub(ReleasedFeatures, 'checkIsDisappearMessageV2FeatureReleased').resolves(true);
|
|
|
|
const expireUpdate = await DisappearingMessages.checkForExpireUpdateInContentMessage(
|
|
disappearingMessage.contentProto(),
|
|
convoToUpdate,
|
|
null
|
|
);
|
|
|
|
expect(expireUpdate?.expirationType, 'expirationType should be deleteAfterRead').to.equal(
|
|
'deleteAfterRead'
|
|
);
|
|
expect(expireUpdate?.expirationTimer, 'expirationTimer should be 60').to.equal(60);
|
|
|
|
expect(
|
|
expireUpdate?.isLegacyConversationSettingMessage,
|
|
'isLegacyConversationSettingMessage should be false'
|
|
).to.be.false;
|
|
expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be false').to.be.false;
|
|
});
|
|
it('if we receive an ExpirationTimerUpdate message for deleteAfterSend after 5 minutes then it returns those values', async () => {
|
|
const expirationTimerUpdateMessage = generateDisappearingVisibleMessage({
|
|
expirationType: 'deleteAfterSend',
|
|
expireTimer: 300,
|
|
expirationTimerUpdate: {
|
|
expirationType: 'deleteAfterSend',
|
|
expireTimer: 300,
|
|
source: testPubkey,
|
|
},
|
|
});
|
|
|
|
const convoToUpdate = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
// TODO legacy messages support will be removed in a future release
|
|
Sinon.stub(ReleasedFeatures, 'checkIsDisappearMessageV2FeatureReleased').resolves(true);
|
|
|
|
const expireUpdate = await DisappearingMessages.checkForExpireUpdateInContentMessage(
|
|
expirationTimerUpdateMessage.contentProto(),
|
|
convoToUpdate,
|
|
null
|
|
);
|
|
|
|
expect(expireUpdate?.expirationType, 'expirationType should be deleteAfterSend').to.equal(
|
|
'deleteAfterSend'
|
|
);
|
|
expect(expireUpdate?.expirationTimer, 'expirationTimer should be 300').to.equal(300);
|
|
|
|
expect(
|
|
expireUpdate?.isLegacyConversationSettingMessage,
|
|
'isLegacyConversationSettingMessage should be false'
|
|
).to.be.false;
|
|
expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be false').to.be.false;
|
|
});
|
|
it('if we receive an outdated ExpirationTimerUpdate message then it should be ignored and is outdated', async () => {
|
|
const expirationTimerUpdateMessage = generateDisappearingVisibleMessage({
|
|
expirationType: 'deleteAfterSend',
|
|
expireTimer: 300,
|
|
expirationTimerUpdate: {
|
|
expirationType: 'deleteAfterSend',
|
|
expireTimer: 300,
|
|
source: testPubkey,
|
|
},
|
|
});
|
|
|
|
const convoToUpdate = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
// TODO legacy messages support will be removed in a future release
|
|
Sinon.stub(ReleasedFeatures, 'checkIsDisappearMessageV2FeatureReleased').resolves(true);
|
|
|
|
const expireUpdate = await DisappearingMessages.checkForExpireUpdateInContentMessage(
|
|
expirationTimerUpdateMessage.contentProto(),
|
|
convoToUpdate,
|
|
null
|
|
);
|
|
|
|
expect(expireUpdate?.expirationType, 'expirationType should be deleteAfterSend').to.equal(
|
|
'deleteAfterSend'
|
|
);
|
|
expect(expireUpdate?.expirationTimer, 'expirationTimer should be 300').to.equal(300);
|
|
|
|
expect(
|
|
expireUpdate?.isLegacyConversationSettingMessage,
|
|
'isLegacyConversationSettingMessage should be undefined'
|
|
).to.be.undefined;
|
|
expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be undefined').to.be
|
|
.undefined;
|
|
});
|
|
});
|
|
|
|
describe('checkForExpiringInOutgoingMessage', () => {
|
|
it('if the message is supposed to disappear then the expirationStartTimestamp should be set to the sent_at value', async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
id: ourNumber,
|
|
});
|
|
const message = generateFakeOutgoingPrivateMessage(conversation.get('id'));
|
|
message.set({
|
|
expirationType: 'deleteAfterRead',
|
|
expireTimer: 300,
|
|
sent_at: GetNetworkTime.getNowWithNetworkOffset(),
|
|
});
|
|
Sinon.stub(message, 'getConversation').returns(conversation);
|
|
|
|
DisappearingMessages.checkForExpiringOutgoingMessage(message, 'unit tests');
|
|
|
|
expect(message.getExpirationStartTimestamp(), 'it should be defined').to.not.be.undefined;
|
|
expect(
|
|
isValidUnixTimestamp(message.getExpirationStartTimestamp()),
|
|
'it should be a valid unix timestamp'
|
|
).to.be.true;
|
|
expect(message.getExpirationStartTimestamp(), 'it should equal the sent_at value').to.equal(
|
|
message.get('sent_at')
|
|
);
|
|
});
|
|
it('if there is no expireTimer then the expirationStartTimestamp should be undefined', async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
id: ourNumber,
|
|
});
|
|
const message = generateFakeOutgoingPrivateMessage(conversation.get('id'));
|
|
message.set({
|
|
expirationType: 'deleteAfterRead',
|
|
sent_at: GetNetworkTime.getNowWithNetworkOffset(),
|
|
});
|
|
Sinon.stub(message, 'getConversation').returns(conversation);
|
|
|
|
DisappearingMessages.checkForExpiringOutgoingMessage(message, 'unit tests');
|
|
|
|
expect(message.getExpirationStartTimestamp(), 'it should be undefined').to.be.undefined;
|
|
});
|
|
it('if there is no expirationType then the expirationStartTimestamp should be undefined', async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
id: ourNumber,
|
|
});
|
|
const message = generateFakeOutgoingPrivateMessage(conversation.get('id'));
|
|
message.set({
|
|
expireTimer: 300,
|
|
sent_at: GetNetworkTime.getNowWithNetworkOffset(),
|
|
});
|
|
Sinon.stub(message, 'getConversation').returns(conversation);
|
|
|
|
DisappearingMessages.checkForExpiringOutgoingMessage(message, 'unit tests');
|
|
|
|
expect(message.getExpirationStartTimestamp(), 'it should be undefined').to.be.undefined;
|
|
});
|
|
it('if expirationStartTimestamp is already defined then it should not have changed', async () => {
|
|
const now = GetNetworkTime.getNowWithNetworkOffset();
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
id: ourNumber,
|
|
});
|
|
const message = generateFakeOutgoingPrivateMessage(conversation.get('id'));
|
|
message.set({
|
|
expirationType: 'deleteAfterRead',
|
|
expireTimer: 300,
|
|
sent_at: now,
|
|
expirationStartTimestamp: now + 10000,
|
|
});
|
|
Sinon.stub(message, 'getConversation').returns(conversation);
|
|
|
|
DisappearingMessages.checkForExpiringOutgoingMessage(message, 'unit tests');
|
|
|
|
expect(message.getExpirationStartTimestamp(), 'it should be defined').to.not.be.undefined;
|
|
expect(
|
|
isValidUnixTimestamp(message.getExpirationStartTimestamp()),
|
|
'it should be a valid unix timestamp'
|
|
).to.be.true;
|
|
expect(message.getExpirationStartTimestamp(), 'it should equal its original value').to.equal(
|
|
now + 10000
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('conversation.ts', () => {
|
|
describe('updateExpireTimer', () => {
|
|
it('if the coversation is public it should return false', async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
|
|
Sinon.stub(conversation, 'isPublic').returns(true);
|
|
const updateSuccess = await conversation.updateExpireTimer({
|
|
providedDisappearingMode: 'deleteAfterSend',
|
|
providedExpireTimer: 600,
|
|
fromSync: false, // if the update comes from a config or sync message
|
|
shouldCommitConvo: false,
|
|
existingMessage: undefined,
|
|
fromCurrentDevice: false,
|
|
});
|
|
expect(updateSuccess, 'should be false').to.be.false;
|
|
});
|
|
|
|
it('if we receive the same settings we ignore it', async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
conversation.set({
|
|
expirationMode: 'deleteAfterRead',
|
|
expireTimer: 60,
|
|
});
|
|
|
|
const updateSuccess = await conversation.updateExpireTimer({
|
|
providedDisappearingMode: 'deleteAfterRead',
|
|
providedExpireTimer: 60,
|
|
fromSync: false,
|
|
shouldCommitConvo: false,
|
|
existingMessage: undefined,
|
|
fromCurrentDevice: false,
|
|
});
|
|
expect(updateSuccess, 'should be false').to.be.false;
|
|
});
|
|
it("if an update is successful then the conversation should have it's settings updated", async () => {
|
|
const conversation = new ConversationModel({
|
|
...conversationArgs,
|
|
});
|
|
Sinon.stub(conversation, 'addSingleOutgoingMessage').resolves();
|
|
Sinon.stub(conversation, 'commit').resolves();
|
|
TestUtils.stubData('saveMessage').resolves();
|
|
|
|
// NOTE we pretend its a sync message so that we can avoiding sending a sync message during testing
|
|
const updateSuccess = await conversation.updateExpireTimer({
|
|
providedDisappearingMode: 'deleteAfterSend',
|
|
providedExpireTimer: 600,
|
|
providedSource: testPubkey,
|
|
receivedAt: GetNetworkTime.getNowWithNetworkOffset(),
|
|
fromSync: true,
|
|
shouldCommitConvo: false,
|
|
existingMessage: undefined,
|
|
fromCurrentDevice: false,
|
|
});
|
|
expect(updateSuccess, 'should be true').to.be.true;
|
|
expect(
|
|
conversation.getExpirationMode(),
|
|
'expirationMode should be deleteAfterSend'
|
|
).to.equal('deleteAfterSend');
|
|
expect(conversation.getExpireTimer(), 'expireTimer should be 5 minutes').to.equal(600);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('message.ts', () => {
|
|
describe('isExpirationTimerUpdate', () => {
|
|
it('should return true if the message is an expirationTimerUpdate', async () => {
|
|
const expirationTimerUpdateMessage = generateFakeExpirationTimerUpdate({
|
|
expirationType: 'deleteAfterSend',
|
|
expireTimer: 300,
|
|
source: testPubkey,
|
|
});
|
|
|
|
expect(expirationTimerUpdateMessage.get('flags'), 'flags should be 2').to.equal(2);
|
|
expect(
|
|
expirationTimerUpdateMessage.getExpirationTimerUpdate(),
|
|
'expirationTimerUpdate should not be empty'
|
|
).to.not.be.empty;
|
|
expect(
|
|
expirationTimerUpdateMessage.getExpirationTimerUpdate(),
|
|
'expirationTimerUpdate should not be empty'
|
|
).to.not.be.empty;
|
|
expect(expirationTimerUpdateMessage.isExpirationTimerUpdate(), 'should be true').to.be.true;
|
|
});
|
|
it('should return false if the message is not an expirationTimerUpdate', async () => {
|
|
const message = generateFakeIncomingPrivateMessage();
|
|
expect(message.isExpirationTimerUpdate(), 'should be false').to.be.false;
|
|
});
|
|
});
|
|
});
|
|
});
|