diff options
| author | Alexandre Kühn <aku@odoo.com> | 2019-08-09 10:53:36 +0000 |
|---|---|---|
| committer | Alexandre Kühn <aku@odoo.com> | 2019-08-12 08:31:15 +0000 |
| commit | a72b23f6b5fbcf637d5de16f9f05ba00552cc186 (patch) | |
| tree | 7282014e40e9faff8b07a6cdce8da52a80e4523b /addons/mail/static/tests/thread_window/basic_thread_window_tests.js | |
| parent | 452a4497c1abe316314f794e5299bb976e3104f4 (diff) | |
[FIX] mail: register thread window after append in DOM
Before this commit, we may have the following error:
`TypeError: Cannot read property 'html' of undefined`
This happened in the following scenario:
Terminology:
- in multi-tab environment, there is a master tab and slave tabs
- master tab fetches notifications from the server and forwards them
to slave tabs
State:
- 2 logged-in users: Michell & Marc
- Mitchell has open 2 browser tabs
- Mitchell has a pinned private conversation with Marc
Steps:
- Mitchell has focus on a slave tab
- Marc posts several messages to Mitchell in very quick succession
=> Mitchell gets crash error above.
This issue is caused by chat window being registered in mail manager
while it has not been mounted to DOM. On receiving 2nd new message,
it has to re-render chat window header in order to update displayed
unread counter. However, this fails due to chat window having no DOM
node yet.
This commit solves the issue by mounting chat window to DOM before
being registered in mail manager. That way, on receiving 2nd new
message, it does not trigger a re-render on chat window that
is about to be mounted to DOM, since it has not been registered yet.
Note that the displayed unread counter will be correct, because it
uses the up-to-date unread counter on mount.
Task-ID 2050108
closes odoo/odoo#35601
Signed-off-by: Martin Geubelle (mge) <mge@openerp.com>
Diffstat (limited to 'addons/mail/static/tests/thread_window/basic_thread_window_tests.js')
| -rw-r--r-- | addons/mail/static/tests/thread_window/basic_thread_window_tests.js | 337 |
1 files changed, 174 insertions, 163 deletions
diff --git a/addons/mail/static/tests/thread_window/basic_thread_window_tests.js b/addons/mail/static/tests/thread_window/basic_thread_window_tests.js index 7c3cfbdc793..3200ae38d85 100644 --- a/addons/mail/static/tests/thread_window/basic_thread_window_tests.js +++ b/addons/mail/static/tests/thread_window/basic_thread_window_tests.js @@ -16,6 +16,29 @@ QUnit.module('Basic', { // define channel to link to chat window this.data = { + 'mail.channel': { + fields: { + name: { + string: "Name", + type: "char", + required: true, + }, + channel_type: { + string: "Channel Type", + type: "selection", + }, + channel_message_ids: { + string: "Messages", + type: "many2many", + relation: 'mail.message' + }, + message_unread_counter: { + string: "Amount of Unread Messages", + type: "integer" + }, + }, + records: [], + }, 'mail.message': { fields: {}, records: [], @@ -292,34 +315,12 @@ QUnit.test('do not increment unread counter with focus on thread window', async QUnit.test('do not mark as read the newly open thread window from received message', async function (assert) { assert.expect(5); - this.data['mail.channel'] = { - fields: { - name: { - string: "Name", - type: "char", - required: true, - }, - channel_type: { - string: "Channel Type", - type: "selection", - }, - channel_message_ids: { - string: "Messages", - type: "many2many", - relation: 'mail.message' - }, - message_unread_counter: { - string: "Amount of Unread Messages", - type: "integer" - }, - }, - records: [{ - id: 2, - name: "DM", - channel_type: "chat", - message_unread_counter: 0, - }], - }; + this.data['mail.channel'].records = [{ + id: 2, + name: "DM", + channel_type: "chat", + message_unread_counter: 0, + }]; var parent = this.createParent({ data: this.data, @@ -371,33 +372,11 @@ QUnit.test('do not mark as read the newly open thread window from received messa QUnit.test('show document link of message linked to a document', async function (assert) { assert.expect(6); - this.data['mail.channel'] = { - fields: { - name: { - string: "Name", - type: "char", - required: true, - }, - channel_type: { - string: "Channel Type", - type: "selection", - }, - channel_message_ids: { - string: "Messages", - type: "many2many", - relation: 'mail.message' - }, - message_unread_counter: { - string: "Amount of Unread Messages", - type: "integer" - }, - }, - records: [{ - id: 2, - name: "R&D Tasks", - channel_type: "channel", - }], - }; + this.data['mail.channel'].records = [{ + id: 2, + name: "R&D Tasks", + channel_type: "channel", + }]; this.data['mail.message'].records.push({ author_id: [5, "Someone else"], body: "<p>Test message</p>", @@ -460,35 +439,13 @@ QUnit.test('do not autofocus chat window on receiving new direct message', async }], }; - this.data['mail.channel'] = { - fields: { - name: { - string: "Name", - type: "char", - required: true, - }, - channel_type: { - string: "Channel Type", - type: "selection", - }, - channel_message_ids: { - string: "Messages", - type: "many2many", - relation: 'mail.message' - }, - message_unread_counter: { - string: "Amount of Unread Messages", - type: "integer" - }, - }, - records: [{ - id: 2, - name: "DM", - channel_type: "chat", - message_unread_counter: 0, - direct_partner: [{ id: 666, name: 'DemoUser1', im_status: '' }], - }], - }; + this.data['mail.channel'].records = [{ + id: 2, + name: "DM", + channel_type: "chat", + message_unread_counter: 0, + direct_partner: [{ id: 666, name: 'DemoUser1', im_status: '' }], + }]; var form = await testUtils.createView({ View: FormView, @@ -543,37 +500,15 @@ QUnit.test('do not auto-focus chat window on receiving new message from new DM', assert.expect(10); var self = this; - this.data['mail.channel'] = { - fields: { - name: { - string: "Name", - type: "char", - required: true, - }, - channel_type: { - string: "Channel Type", - type: "selection", - }, - channel_message_ids: { - string: "Messages", - type: "many2many", - relation: 'mail.message' - }, - message_unread_counter: { - string: "Amount of Unread Messages", - type: "integer" - }, - }, - records: [{ - id: 2, - name: "DM", - channel_type: "chat", - message_unread_counter: 1, - direct_partner: [{ id: 666, name: 'DemoUser1', im_status: '' }], - is_minimized: false, - state: 'open', - }], - }; + this.data['mail.channel'].records = [{ + id: 2, + name: "DM", + channel_type: "chat", + message_unread_counter: 1, + direct_partner: [{ id: 666, name: 'DemoUser1', im_status: '' }], + is_minimized: false, + state: 'open', + }]; var parent = this.createParent({ data: this.data, @@ -654,21 +589,15 @@ QUnit.test('do not auto-focus chat window on receiving new message from new DM', QUnit.test('out-of-office status in thread window', async function (assert) { assert.expect(1); - this.data = { - 'mail.message': { - fields: {}, - records: [], - }, - initMessaging: { - channel_slots: { - channel_channel: [{ - id: 1, - name: "DM", - channel_type: "chat", - message_unread_counter: 0, - direct_partner: [{ id: 666, name: 'DemoUser1', im_status: 'online', out_of_office_message: 'Please don\'t disturb'}], - }], - }, + this.data.initMessaging = { + channel_slots: { + channel_channel: [{ + id: 1, + name: "DM", + channel_type: "chat", + message_unread_counter: 0, + direct_partner: [{ id: 666, name: 'DemoUser1', im_status: 'online', out_of_office_message: 'Please don\'t disturb'}], + }], }, }; var parent = this.createParent({ @@ -691,21 +620,15 @@ QUnit.test('out-of-office status in thread window', async function (assert) { QUnit.test('no out-of-office status in thread window', async function (assert) { assert.expect(1); - this.data = { - 'mail.message': { - fields: {}, - records: [], - }, - initMessaging: { - channel_slots: { - channel_channel: [{ - id: 1, - name: "DM", - channel_type: "chat", - message_unread_counter: 0, - direct_partner: [{ id: 666, name: 'DemoUser1', im_status: 'online'}], - }], - }, + this.data.initMessaging = { + channel_slots: { + channel_channel: [{ + id: 1, + name: "DM", + channel_type: "chat", + message_unread_counter: 0, + direct_partner: [{ id: 666, name: 'DemoUser1', im_status: 'online'}], + }], }, }; var parent = this.createParent({ @@ -734,25 +657,19 @@ QUnit.test('auto-update out-of-office info on im_status change', async function var timeoutMock = mailTestUtils.patchMailTimeouts(); var step = 0; - this.data = { - 'mail.message': { - fields: {}, - records: [], - }, - initMessaging: { - channel_slots: { - channel_channel: [{ - id: 1, - name: "DM", - channel_type: "chat", - message_unread_counter: 0, - direct_partner: [{ - id: 666, - name: 'DemoUser1', - im_status: 'online', - }], + this.data.initMessaging = { + channel_slots: { + channel_channel: [{ + id: 1, + name: "DM", + channel_type: "chat", + message_unread_counter: 0, + direct_partner: [{ + id: 666, + name: 'DemoUser1', + im_status: 'online', }], - }, + }], }, }; @@ -839,6 +756,100 @@ QUnit.test('auto-update out-of-office info on im_status change', async function parent.destroy(); }); +QUnit.test('receive 2 new DM messages in quick succession (no chat window initially)', async function (assert) { + assert.expect(3); + + const self = this; + this.data['mail.channel'].records = [{ + channel_type: "chat", + direct_partner: [{ + id: 5, + name: 'Someone else', + im_status: 'online', + }], + id: 10, + is_minimized: false, + message_unread_counter: 1, + name: "DM", + state: 'open', + }]; + + this.data.initMessaging.channel_slots = { + channel_direct_message: [{ + channel_type: 'chat', + direct_partner: [{ + id: 5, + name: 'Someone else', + im_status: 'online', + }], + id: 10, + message_unread_counter: 0, + name: "DM", + }], + }; + + const parent = this.createParent({ + data: this.data, + mockRPC(route, args) { + if (args.method === 'channel_minimize') { + Object.assign(self.data['mail.channel'].records[0], { + is_minimized: true, + state: 'open', + }); + } + return this._super(...arguments); + }, + services: this.services, + session: { + partner_id: 3, + }, + }); + + await testUtils.nextTick(); + assert.containsNone( + $, + '.o_thread_window', + "should not have any DM window open"); + + // simulate receiving 2 new messages from someone else in quick succession + const messageData1 = { + author_id: [5, "Someone else"], + body: "<p>Test message1</p>", + channel_ids: [10], + id: 2, + model: 'mail.channel', + res_id: 10, + }; + this.data['mail.message'].records.push(messageData1); + const notification1 = [[false, 'mail.channel', 2], messageData1]; + parent.call('bus_service', 'trigger', 'notification', [notification1]); + // simulate short delay for receiving new message + await testUtils.nextMicrotaskTick(); + const messageData2 = { + author_id: [5, "Someone else"], + body: "<p>Test message2</p>", + channel_ids: [10], + id: 3, + model: 'mail.channel', + res_id: 10, + }; + this.data['mail.message'].records.push(messageData2); + const notification2 = [[false, 'mail.channel', 2], messageData2]; + parent.call('bus_service', 'trigger', 'notification', [notification2]); + await testUtils.nextTick(); + assert.containsOnce( + $, + '.o_thread_window', + "should have DM window open"); + assert.containsN( + $('.o_thread_window'), + '.o_thread_message', + 2, + "should have 2 messages in chat window"); + + parent.destroy(); +}); + }); }); }); |
