diff options
Diffstat (limited to 'addons/mail/static')
9 files changed, 199 insertions, 4 deletions
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 b4f1df097cf..0ef02e5f57a 100644 --- a/addons/mail/static/src/js/models/threads/document_thread.js +++ b/addons/mail/static/src/js/models/threads/document_thread.js @@ -97,7 +97,6 @@ var DocumentThread = Thread.extend({ fetchMessages: function (options) { var self = this; return this._fetchMessages(options).then(function () { - self.call('mail_service', 'markMessagesAsRead', self._messageIDs); return self._messages; }); }, diff --git a/addons/mail/static/src/js/services/mail_manager.js b/addons/mail/static/src/js/services/mail_manager.js index 4a20d24af8d..3ed4031abeb 100644 --- a/addons/mail/static/src/js/services/mail_manager.js +++ b/addons/mail/static/src/js/services/mail_manager.js @@ -85,7 +85,7 @@ var MailManager = AbstractService.extend({ addMessage: function (data, options) { options = options || {}; var message = this.getMessage(data.id); - var prom = Promise.resolve(); + var prom; if (!message) { prom = this._addNewMessage(data, options); } else { @@ -95,6 +95,7 @@ var MailManager = AbstractService.extend({ }); } this._addMessageToThreads(message, options); + prom = Promise.resolve(message); } return prom; }, diff --git a/addons/mail/static/src/js/services/mail_window_manager.js b/addons/mail/static/src/js/services/mail_window_manager.js index 5cc965b5c7a..a832b0b0793 100644 --- a/addons/mail/static/src/js/services/mail_window_manager.js +++ b/addons/mail/static/src/js/services/mail_window_manager.js @@ -106,7 +106,7 @@ MailManager.include({ // This may happen due to concurrent calls to this method from // messaging menu preview click and handling of longpolling chat // window state. - return; + return Promise.resolve(); } var threadWindow = this._getThreadWindow(threadID); var prom = Promise.resolve(); diff --git a/addons/mail/static/src/js/systray/systray_activity_menu.js b/addons/mail/static/src/js/systray/systray_activity_menu.js index fae95a78c2f..641ff4be1bc 100644 --- a/addons/mail/static/src/js/systray/systray_activity_menu.js +++ b/addons/mail/static/src/js/systray/systray_activity_menu.js @@ -108,6 +108,7 @@ var ActivityMenu = Widget.extend({ */ _onActivityActionClick: function (ev) { ev.stopPropagation(); + this.$('.dropdown-toggle').dropdown('toggle'); var targetAction = $(ev.currentTarget); var actionXmlid = targetAction.data('action_xmlid'); if (actionXmlid) { diff --git a/addons/mail/static/src/scss/discuss.scss b/addons/mail/static/src/scss/discuss.scss index 6092ab733fc..8284fdc70b5 100644 --- a/addons/mail/static/src/scss/discuss.scss +++ b/addons/mail/static/src/scss/discuss.scss @@ -110,6 +110,7 @@ } .o_mail_thread { + position: relative; flex: 1 0 0; overflow: auto; -webkit-overflow-scrolling: touch; // smooth scrolling in iOS app (Safari) diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js index bed4d682d10..4c9d55fcb75 100644 --- a/addons/mail/static/tests/chatter_tests.js +++ b/addons/mail/static/tests/chatter_tests.js @@ -1144,6 +1144,71 @@ QUnit.test('chatter: access document with some notifs', async function (assert) form.destroy(); }); +QUnit.test('chatter: new message notification from document', async function (assert) { + // when receiving new messages from a document that is open, it should + // not mark the messages are read + assert.expect(4); + + var form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + services: this.services, + arch: '<form string="Partners">' + + '<sheet>' + + '<field name="foo"/>' + + '</sheet>' + + '<div class="oe_chatter">' + + '<field name="message_ids" widget="mail_thread"/>' + + '</div>' + + '</form>', + res_id: 2, + session: { + partner_id: 3, + }, + mockRPC: function (route, args) { + if (args.method === 'set_message_done') { + throw new Error("should not mark message as read"); + } + return this._super.apply(this, arguments); + }, + }); + + var thread = form.call('mail_service', 'getDocumentThread', 'partner', 2); + assert.strictEqual( + thread.getUnreadCounter(), + 0, + "document thread should have no unread messages initially"); + assert.containsNone( + form, + '.o_thread_message', + "should have no message in the chatter"); + + // Simulate received needaction`` message on this document + var message = { + author_id: [1, "Me"], + body: '<p>test</p>', + channel_ids: [], + id: 2, + model: 'partner', + needaction_partner_ids: [3], + res_id: 2, + }; + const notifications = [ [['myDB', 'ir.needaction'], message] ]; + form.call('bus_service', 'trigger', 'notification', notifications); + await testUtils.nextTick(); + assert.strictEqual( + thread.getUnreadCounter(), + 1, + "document thread should have one unread message (not marked as read)"); + assert.containsOnce( + form, + '.o_thread_message', + "should have one message in the chatter"); + + form.destroy(); +}); + QUnit.test('chatter: post a message and switch in edit mode', async function (assert) { assert.expect(5); diff --git a/addons/mail/static/tests/discuss_tests.js b/addons/mail/static/tests/discuss_tests.js index 8c65266a392..226fd1e398a 100644 --- a/addons/mail/static/tests/discuss_tests.js +++ b/addons/mail/static/tests/discuss_tests.js @@ -59,6 +59,7 @@ QUnit.module('Discuss', { type: 'integer', }, }, + records: [], }, 'res.partner': { fields: { @@ -1490,6 +1491,70 @@ QUnit.test('custom-named DM conversation', async function (assert) { discuss.destroy(); }); +QUnit.test('receive channel message notification then delayed needaction notification', async function (assert) { + assert.expect(3); + + const message = { + author_id: [5, 'Demo User'], + body: '<p>test</p>', + channel_ids: [1], + id: 100, + model: 'mail.channel', + needaction: true, + needaction_partner_ids: [3], + res_id: 1, + }; + this.data.initMessaging = { + channel_slots: { + channel_channel: [{ + id: 1, + channel_type: 'channel', + name: "general", + }], + }, + }; + + const discuss = await createDiscuss({ + context: {}, + params: {}, + data: this.data, + services: this.services, + session: { + partner_id: 3 + }, + }); + + const $inbox = discuss.$('.o_mail_discuss_item[data-thread-id="mailbox_inbox"]'); + assert.hasClass( + $inbox, + 'o_active', + "'Inbox' should be the currently active thread"); + assert.containsNone( + discuss, + '.o_thread_message', + "inbox should contain no messages initially"); + + // simulate new needaction message posted on channnel + this.data['mail.message'].records.push(message); + // simulate receiving channel notification + discuss.call('bus_service', 'trigger', 'notification', [ + [['myDB', 'mail.channel', 1], message] + ]); + // short delay after receiving needaction notification + await testUtils.nextTick(); + // simulate receiving needaction message notification after a short delay + discuss.call('bus_service', 'trigger', 'notification', [ + [['myDB', 'ir.needaction', 3], message] + ]); + await testUtils.nextTick(); + assert.containsOnce( + discuss, + '.o_thread_message', + "inbox should contain one message"); + + discuss.destroy(); +}); + QUnit.test('input not cleared on unresolved message_post rpc', async function (assert) { assert.expect(2); diff --git a/addons/mail/static/tests/systray/systray_activity_menu_tests.js b/addons/mail/static/tests/systray/systray_activity_menu_tests.js index b2f76feb832..7d24b5e05a4 100644 --- a/addons/mail/static/tests/systray/systray_activity_menu_tests.js +++ b/addons/mail/static/tests/systray/systray_activity_menu_tests.js @@ -153,7 +153,7 @@ QUnit.test('activity menu widget: activity menu with 3 records', async function }); QUnit.test('activity menu widget: activity view icon', async function (assert) { - assert.expect(10); + assert.expect(12); var self = this; var activityMenu = new ActivityMenu(); testUtils.mock.addMockEnvironment(activityMenu, { @@ -193,9 +193,15 @@ QUnit.test('activity menu widget: activity view icon', async function (assert) { // click on the "Issue" activity icon await testUtils.dom.click(activityMenu.$('.dropdown-toggle')); + assert.hasClass(activityMenu.$('.dropdown-menu'), 'show', + "dropdown should be expanded"); + await testUtils.dom.click(activityMenu.$(".o_mail_activity_action[data-model_name='Issue']")); + assert.doesNotHaveClass(activityMenu.$('.dropdown-menu'), 'show', + "dropdown should be collapsed"); // click on the "Note" activity icon + await testUtils.dom.click(activityMenu.$('.dropdown-toggle')); await testUtils.dom.click(activityMenu.$(".o_mail_activity_action[data-model_name='Note']")); assert.verifySteps([ diff --git a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js index b31b12f15b3..610e689ae4a 100644 --- a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js +++ b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js @@ -920,5 +920,62 @@ QUnit.test('messaging menu widget: expand on thread preview', async function (as messagingMenu.destroy(); }); +QUnit.test('messaging menu widget: click twice preview on slow message_fetch should open chat window once', async function (assert) { + // This test assumes that a condition for opening chat window is to + // successfully fetch messages beforehand. + assert.expect(1); + + const self = this; + // Used to pause `message_fetch` after opening the messaging menu. + // This is necessary `message_fetch` on mailbox_inbox is required to + // display the previews. + let lockMessageFetch = false; + const messageFetchProm = testUtils.makeTestPromise(); + + const messagingMenu = new MessagingMenu(); + testUtils.addMockEnvironment(messagingMenu, { + services: this.services, + data: this.data, + session: { partner_id: 1 }, + async mockRPC(route, args) { + if (args.method === 'message_fetch' && lockMessageFetch) { + const _super = this._super.bind(this); + await messageFetchProm; + return _super(route, args); + } + if (args.method === 'channel_minimize') { + // called to detach thread in chat window + // simulate longpolling response with new chat window state + const channelInfo = { + ...self.data['mail.channel'].records[0], + is_minimized: true, + state: 'open', + }; + const notifications = [ [['myDB', 'res.partner'], channelInfo] ]; + messagingMenu.call('bus_service', 'trigger', 'notification', notifications); + } + return this._super(...arguments); + }, + }); + await messagingMenu.appendTo($('#qunit-fixture')); + + // Opening chat window 1st time from messaging menu (pending from `messageFetchDef`) + await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); + lockMessageFetch = true; + await testUtils.dom.click(messagingMenu.$('.o_mail_preview')); + // Click again on preview to open chat window + await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); + await testUtils.dom.click(messagingMenu.$('.o_mail_preview')); + messageFetchProm.resolve(); + await testUtils.nextTick(); + + assert.containsOnce( + $, + '.o_thread_window', + "should only display a single chat window"); + + messagingMenu.destroy(); +}); + }); }); |
