diff --git a/addons/mail/static/src/js/models/threads/document_thread.js b/addons/mail/static/src/js/models/threads/document_thread.js index 88203b3e8d8..831c46939a8 100644 --- a/addons/mail/static/src/js/models/threads/document_thread.js +++ b/addons/mail/static/src/js/models/threads/document_thread.js @@ -60,10 +60,15 @@ var DocumentThread = Thread.extend({ /** * Add this message to this document thread. * + * This is ignored if the message is already linked to this document thread. + * * @override * @param {mail.model.Message} message */ addMessage: function (message) { + if (_.contains(this._messages, message)) { + return; + } // update internal list of messages this._messages.push(message); this._messages = _.sortBy(this._messages, function (msg) { diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js index d07f000b129..e6a770c0f65 100644 --- a/addons/mail/static/tests/chatter_tests.js +++ b/addons/mail/static/tests/chatter_tests.js @@ -1674,6 +1674,79 @@ QUnit.test('does not render and crash when destroyed before chat system is ready def.resolve(); }); +QUnit.test('chatter: do not duplicate messages on (un)star message', function (assert) { + assert.expect(4); + + this.data.partner.records[0].message_ids = [1]; + this.data['mail.message'].records = [{ + author_id: ["1", "John Doe"], + body: "A message", + date: "2016-12-20 09:35:40", + id: 1, + is_note: false, + is_discussion: true, + is_notification: false, + is_starred: false, + model: 'partner', + res_id: 2, + }]; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + services: this.services, + arch: '
', + res_id: 2, + mockRPC: function (route, args) { + if (args.method === 'toggle_message_starred') { + var messageData = _.findWhere( + this.data['mail.message'].records, + { id: args.args[0][0] } + ); + messageData.is_starred = !messageData.is_starred; + // simulate notification received by mail_service from longpoll + var data = { + info: false, + message_ids: [messageData.id], + starred: messageData.is_starred, + type: 'toggle_star', + }; + var notification = [[false, 'res.partner'], data]; + form.call('bus_service', 'trigger', 'notification', [notification]); + return $.when(); + } + return this._super(route, args); + }, + session: {}, + }); + + assert.strictEqual(form.$('.o_thread_message').length, 1, + "there should be a single message in the chatter"); + assert.ok(form.$('.o_thread_message .o_thread_message_star.fa-star-o').length, + "message should not be starred"); + + // star message + form.$('.o_thread_message .o_thread_message_star').click(); + assert.strictEqual(form.$('.o_thread_message').length, 1, + "there should still be a single message in the chatter after starring the message"); + + // unstar message + form.$('.o_thread_message .o_thread_message_star').click(); + assert.strictEqual(form.$('.o_thread_message').length, 1, + "there should still be a single message in the chatter after unstarring the message"); + + //cleanup + form.destroy(); +}); + QUnit.module('FieldMany2ManyTagsEmail', { beforeEach: function () { this.data = {