From df2fa3c7b10199acf32c3f2915b532d64518d5a2 Mon Sep 17 00:00:00 2001
From: Josh Perez <60019601+josh-signal@users.noreply.github.com>
Date: Tue, 20 Oct 2020 19:26:58 -0400
Subject: [PATCH] updateLastMessage: Use MessageController for latest data
---
test/index.html | 1 +
test/models/conversations_test.js | 70 +++++++++++++++++++++++++++++++
ts/models/conversations.ts | 19 ++++++++-
3 files changed, 89 insertions(+), 1 deletion(-)
create mode 100644 test/models/conversations_test.js
diff --git a/test/index.html b/test/index.html
index 5b3edb4716..fb41bf32ed 100644
--- a/test/index.html
+++ b/test/index.html
@@ -376,6 +376,7 @@
+
diff --git a/test/models/conversations_test.js b/test/models/conversations_test.js
new file mode 100644
index 0000000000..7889bd2810
--- /dev/null
+++ b/test/models/conversations_test.js
@@ -0,0 +1,70 @@
+describe('Conversations', () => {
+ it('updates lastMessage even in race conditions with db', async () => {
+ // Creating a fake conversation
+ const conversation = new window.Whisper.Conversation({
+ id: '8c45efca-67a4-4026-b990-9537d5d1a08f',
+ e164: '+15551234567',
+ uuid: '2f2734aa-f69d-4c1c-98eb-50eb0fc512d7',
+ type: 'private',
+ });
+
+ const destinationE164 = '+15557654321';
+
+ // Creating a fake message
+ const now = Date.now();
+ let message = new window.Whisper.Message({
+ attachments: [],
+ body: 'bananas',
+ conversationId: conversation.id,
+ delivered: 1,
+ delivered_to: [destinationE164],
+ destination: destinationE164,
+ expirationStartTimestamp: now,
+ hasAttachments: 0,
+ hasFileAttachments: 0,
+ hasVisualMediaAttachments: 0,
+ id: 'd8f2b435-e2ef-46e0-8481-07e68af251c6',
+ received_at: now,
+ recipients: [destinationE164],
+ sent: true,
+ sent_at: now,
+ sent_to: [destinationE164],
+ timestamp: now,
+ type: 'outgoing',
+ });
+
+ // Saving to db and updating the convo's last message
+ await window.Signal.Data.saveMessage(message.attributes, {
+ forceSave: true,
+ Message: window.Whisper.Message,
+ });
+ message = window.MessageController.register(message.id, message);
+ await window.Signal.Data.saveConversation(conversation.attributes, {
+ Conversation: window.Whisper.Conversation,
+ });
+ await conversation.updateLastMessage();
+
+ // Should be set to bananas because that's the last message sent.
+ assert.strictEqual(conversation.get('lastMessage'), 'bananas');
+
+ // Erasing message contents (DOE)
+ message.set({
+ isErased: true,
+ body: '',
+ bodyRanges: undefined,
+ attachments: [],
+ quote: null,
+ contact: [],
+ sticker: null,
+ preview: [],
+ });
+
+ // Not saving the message to db on purpose
+ // to simulate that a save hasn't taken place yet.
+
+ // Updating convo's last message, should pick it up from memory
+ await conversation.updateLastMessage();
+
+ assert.strictEqual(conversation.get('lastMessage'), '');
+ });
+});
diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts
index e4d8e4214b..f31298ecd7 100644
--- a/ts/models/conversations.ts
+++ b/ts/models/conversations.ts
@@ -2874,7 +2874,7 @@ export class ConversationModel extends window.Backbone.Model<
return;
}
- const [previewMessage, activityMessage] = await Promise.all([
+ let [previewMessage, activityMessage] = await Promise.all([
window.Signal.Data.getLastConversationPreview(this.id, {
Message: window.Whisper.Message,
}),
@@ -2883,6 +2883,23 @@ export class ConversationModel extends window.Backbone.Model<
}),
]);
+ // Register the message with MessageController so that if it already exists
+ // in memory we use that data instead of the data from the db which may
+ // be out of date.
+ if (previewMessage) {
+ previewMessage = window.MessageController.register(
+ previewMessage.id,
+ previewMessage
+ );
+ }
+
+ if (activityMessage) {
+ activityMessage = window.MessageController.register(
+ activityMessage.id,
+ activityMessage
+ );
+ }
+
if (
this.hasDraft() &&
this.get('draftTimestamp') &&