diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts index 04de875be..54715e239 100644 --- a/ts/models/conversation.ts +++ b/ts/models/conversation.ts @@ -117,6 +117,7 @@ import { getSubscriberCountOutsideRedux, } from '../state/selectors/sogsRoomInfo'; // decide it it makes sense to move this to a redux slice? +import { v4 } from 'uuid'; import { DisappearingMessages } from '../session/disappearing_messages'; import { DisappearingMessageConversationModeType } from '../session/disappearing_messages/types'; import { FetchMsgExpirySwarm } from '../session/utils/job_runners/jobs/FetchMsgExpirySwarmJob'; @@ -927,6 +928,9 @@ export class ConversationModel extends Backbone.Model { expirationType, expireTimer, }); + if (!message.get('id')) { + message.set({ id: v4() }); + } if (this.isActive()) { this.set('active_at', timestamp); @@ -963,12 +967,12 @@ export class ConversationModel extends Backbone.Model { } await message.commit(); - await cleanUpExpireHistoryFromConvo(this.id, this.isPrivate()); + await Conversation.cleanUpExpireHistoryFromConvo(this.id, this.isPrivate()); return true; } await message.commit(); - await cleanUpExpireHistoryFromConvo(this.id, this.isPrivate()); + await Conversation.cleanUpExpireHistoryFromConvo(this.id, this.isPrivate()); // // Below is the "sending the update to the conversation" part. // We would have returned if that message sending part was not needed @@ -2552,3 +2556,5 @@ async function cleanUpExpireHistoryFromConvo(conversationId: string, isPrivate: messagesDeleted(updateIdsRemoved.map(m => ({ conversationKey: conversationId, messageId: m }))) ); } + +export const Conversation = { cleanUpExpireHistoryFromConvo }; diff --git a/ts/test/session/unit/disappearing_messages/DisappearingMessage_test.ts b/ts/test/session/unit/disappearing_messages/DisappearingMessage_test.ts index 03bc13243..e0b19aa6c 100644 --- a/ts/test/session/unit/disappearing_messages/DisappearingMessage_test.ts +++ b/ts/test/session/unit/disappearing_messages/DisappearingMessage_test.ts @@ -1,7 +1,7 @@ import chai, { expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; import Sinon from 'sinon'; -import { ConversationModel } from '../../../../models/conversation'; +import { Conversation, ConversationModel } from '../../../../models/conversation'; import { ConversationAttributes, ConversationTypeEnum, @@ -454,10 +454,9 @@ describe('DisappearingMessage', () => { expect( expireUpdate?.isLegacyConversationSettingMessage, - 'isLegacyConversationSettingMessage should be undefined' - ).to.be.undefined; - expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be undefined').to.be - .undefined; + 'isLegacyConversationSettingMessage should be false' + ).to.be.false; + expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be false').to.be.false; }); }); @@ -548,13 +547,14 @@ describe('DisappearingMessage', () => { describe('conversation.ts', () => { describe('updateExpireTimer', () => { - it('if the coversation is public it should return false', async () => { + it('if the conversation is public it should throw', async () => { const conversation = new ConversationModel({ ...conversationArgs, }); Sinon.stub(conversation, 'isPublic').returns(true); - const updateSuccess = await conversation.updateExpireTimer({ + + const promise = conversation.updateExpireTimer({ providedDisappearingMode: 'deleteAfterSend', providedExpireTimer: 600, fromSync: false, // if the update comes from a config or sync message @@ -562,10 +562,17 @@ describe('DisappearingMessage', () => { existingMessage: undefined, fromCurrentDevice: false, }); - expect(updateSuccess, 'should be false').to.be.false; + await expect(promise).is.rejectedWith( + "updateExpireTimer() Disappearing messages aren't supported in communities" + ); }); - it('if we receive the same settings we ignore it', async () => { + // we always add a message when we get an update as we remove previous ones and only keep one in the history + it("if we receive the same settings we don't ignore it", async () => { + TestUtils.stubData('saveMessage').resolves(); + TestUtils.stubData('getItemById').resolves(); + TestUtils.stubData('createOrUpdateItem').resolves(); + const conversation = new ConversationModel({ ...conversationArgs, }); @@ -573,6 +580,8 @@ describe('DisappearingMessage', () => { expirationMode: 'deleteAfterRead', expireTimer: 60, }); + Sinon.stub(conversation, 'commit').resolves(); + Sinon.stub(Conversation, 'cleanUpExpireHistoryFromConvo').resolves(); const updateSuccess = await conversation.updateExpireTimer({ providedDisappearingMode: 'deleteAfterRead', @@ -582,9 +591,11 @@ describe('DisappearingMessage', () => { existingMessage: undefined, fromCurrentDevice: false, }); - expect(updateSuccess, 'should be false').to.be.false; + expect(updateSuccess, 'should be true').to.be.true; }); + it("if an update is successful then the conversation should have it's settings updated", async () => { + Sinon.stub(Conversation, 'cleanUpExpireHistoryFromConvo').resolves(); const conversation = new ConversationModel({ ...conversationArgs, });