diff --git a/addons/mail/controllers/discuss.py b/addons/mail/controllers/discuss.py index f061219d581..33fb2f1ffdc 100644 --- a/addons/mail/controllers/discuss.py +++ b/addons/mail/controllers/discuss.py @@ -174,6 +174,10 @@ class DiscussController(http.Controller): return guest.sudo()._init_messaging() raise NotFound() + @http.route('/mail/load_message_failures', methods=['POST'], type='json', auth='user') + def mail_load_message_failures(self, **kwargs): + return request.env.user.partner_id._message_fetch_failed() + # -------------------------------------------------------------------------- # Mailbox # -------------------------------------------------------------------------- diff --git a/addons/mail/models/mail_guest.py b/addons/mail/models/mail_guest.py index 5ecdb4c31e9..c30420a19ef 100644 --- a/addons/mail/models/mail_guest.py +++ b/addons/mail/models/mail_guest.py @@ -89,7 +89,6 @@ class MailGuest(models.Model): 'current_partner': False, 'current_user_id': False, 'current_user_settings': False, - 'mail_failures': [], 'menu_id': False, 'needaction_inbox_counter': False, 'partner_root': { diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index 7824b3618ae..8a4a02309f5 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -151,7 +151,6 @@ class Users(models.Model): 'current_partner': self.partner_id.mail_partner_format().get(self.partner_id), 'current_user_id': self.id, 'current_user_settings': self.env['res.users.settings']._find_or_create_for_user(self)._res_users_settings_format(), - 'mail_failures': self.partner_id._message_fetch_failed(), 'menu_id': self.env['ir.model.data']._xmlid_to_res_id('mail.menu_root_discuss'), 'needaction_inbox_counter': self.partner_id._get_needaction_count(), 'partner_root': partner_root.sudo().mail_partner_format().get(partner_root), diff --git a/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js b/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js index c426d2b552a..6a7ceee591b 100644 --- a/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js +++ b/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js @@ -46,6 +46,9 @@ registerModel({ if (this.messaging.autofetchPartnerImStatus) { this.messaging.models['Partner'].startLoopFetchImStatus(); } + if (this.messaging.currentUser) { + this._loadMessageFailures(); + } }, /** * @private @@ -55,7 +58,6 @@ registerModel({ * @param {Object} param0.current_partner * @param {integer} param0.current_user_id * @param {Object} param0.current_user_settings - * @param {Object} [param0.mail_failures={}] * @param {integer} [param0.needaction_inbox_counter=0] * @param {Object} param0.partner_root * @param {Object[]} param0.public_partners @@ -70,7 +72,6 @@ registerModel({ currentGuest, current_user_id, current_user_settings, - mail_failures = {}, menu_id, needaction_inbox_counter = 0, partner_root, @@ -111,8 +112,6 @@ registerModel({ } // channels when the rest of messaging is ready await this.async(() => this._initChannels(channels)); - // failures after channels - this._initMailFailures(mail_failures); discuss.update({ menu_id }); // company related data this.messaging.update({ companyName }); @@ -197,7 +196,7 @@ registerModel({ }, /** * @private - * @param {Object} mailFailuresData + * @param {Object[]} mailFailuresData */ async _initMailFailures(mailFailuresData) { await executeGracefully(mailFailuresData.map(messageData => () => { @@ -299,5 +298,14 @@ registerModel({ )), }); }, + /** + * @private + */ + async _loadMessageFailures() { + const data = await this.env.services.rpc({ + route: '/mail/load_message_failures', + }, { shadow: true }); + this._initMailFailures(data); + }, }, }); diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js index cd5e117b0e7..15e00865c02 100644 --- a/addons/mail/static/tests/chatter_tests.js +++ b/addons/mail/static/tests/chatter_tests.js @@ -103,7 +103,7 @@ QUnit.module('Chatter', { }); QUnit.test('list activity widget with no activity', async function (assert) { - assert.expect(5); + assert.expect(4); const { widget: list } = await start({ hasView: true, @@ -112,7 +112,9 @@ QUnit.test('list activity widget with no activity', async function (assert) { data: this.data, arch: '', mockRPC: function (route) { - assert.step(route); + if (!['/mail/init_messaging', '/mail/load_message_failures'].includes(route)) { + assert.step(route); + } return this._super(...arguments); }, session: { uid: 2 }, @@ -121,16 +123,13 @@ QUnit.test('list activity widget with no activity', async function (assert) { assert.containsOnce(list, '.o_mail_activity .o_activity_color_default'); assert.strictEqual(list.$('.o_activity_summary').text(), ''); - assert.verifySteps([ - '/web/dataset/search_read', - '/mail/init_messaging', - ]); + assert.verifySteps(['/web/dataset/search_read']); list.destroy(); }); QUnit.test('list activity widget with activities', async function (assert) { - assert.expect(7); + assert.expect(6); const currentUser = this.data['res.users'].records.find(user => user.id === this.data.currentUserId @@ -158,7 +157,9 @@ QUnit.test('list activity widget with activities', async function (assert) { data: this.data, arch: '', mockRPC: function (route) { - assert.step(route); + if (!['/mail/init_messaging', '/mail/load_message_failures'].includes(route)) { + assert.step(route); + } return this._super(...arguments); }, }); @@ -171,16 +172,13 @@ QUnit.test('list activity widget with activities', async function (assert) { assert.containsOnce($secondRow, '.o_mail_activity .o_activity_color_planned.fa-clock-o'); assert.strictEqual($secondRow.find('.o_activity_summary').text(), 'Type 2'); - assert.verifySteps([ - '/web/dataset/search_read', - '/mail/init_messaging', - ]); + assert.verifySteps(['/web/dataset/search_read']); list.destroy(); }); QUnit.test('list activity widget with exception', async function (assert) { - assert.expect(5); + assert.expect(4); const currentUser = this.data['res.users'].records.find(user => user.id === this.data.currentUserId @@ -201,7 +199,9 @@ QUnit.test('list activity widget with exception', async function (assert) { data: this.data, arch: '', mockRPC: function (route) { - assert.step(route); + if (!['/mail/init_messaging', '/mail/load_message_failures'].includes(route)) { + assert.step(route); + } return this._super(...arguments); }, }); @@ -209,16 +209,13 @@ QUnit.test('list activity widget with exception', async function (assert) { assert.containsOnce(list, '.o_activity_color_today.text-warning.fa-warning'); assert.strictEqual(list.$('.o_activity_summary').text(), 'Warning'); - assert.verifySteps([ - '/web/dataset/search_read', - '/mail/init_messaging', - ]); + assert.verifySteps(['/web/dataset/search_read']); list.destroy(); }); QUnit.test('list activity widget: open dropdown', async function (assert) { - assert.expect(10); + assert.expect(9); const currentUser = this.data['res.users'].records.find(user => user.id === this.data.currentUserId @@ -263,7 +260,9 @@ QUnit.test('list activity widget: open dropdown', async function (assert) { `, mockRPC: function (route, args) { - assert.step(args.method || route); + if (!['/mail/init_messaging', '/mail/load_message_failures'].includes(route)) { + assert.step(args.method || route); + } if (args.method === 'action_feedback') { const currentUser = this.data['res.users'].records.find(user => user.id === this.currentUserId @@ -301,7 +300,6 @@ QUnit.test('list activity widget: open dropdown', async function (assert) { assert.verifySteps([ '/web/dataset/search_read', - '/mail/init_messaging', 'switch_view', 'open dropdown', 'activity_format', diff --git a/addons/mail/static/tests/helpers/mock_server.js b/addons/mail/static/tests/helpers/mock_server.js index 0382ca1f6f2..32cd25dcbc0 100644 --- a/addons/mail/static/tests/helpers/mock_server.js +++ b/addons/mail/static/tests/helpers/mock_server.js @@ -100,6 +100,9 @@ MockServer.include({ if (route === '/mail/init_messaging') { return this._mockRouteMailInitMessaging(); } + if (route === '/mail/load_message_failures') { + return this._mockRouteMailLoadMessageFailures(); + } if (route === '/mail/history/messages') { const { min_id, max_id, limit } = args; return this._mockRouteMailMessageHistory(min_id, max_id, limit); @@ -405,6 +408,15 @@ MockServer.include({ _mockRouteMailInitMessaging() { return this._mockResUsers_InitMessaging([this.currentUserId]); }, + /** + * Simulates the `/mail/load_message_failures` route. + * + * @private + * @returns {Object[]} + */ + _mockRouteMailLoadMessageFailures() { + return this._mockResPartner_MessageFetchFailed(this.currentPartnerId); + }, /** * Simulates the `/mail/history/messages` route. * @@ -2151,7 +2163,6 @@ MockServer.include({ current_partner: this._mockResPartnerMailPartnerFormat(user.partner_id).get(user.partner_id), current_user_id: this.currentUserId, current_user_settings: this._mockResUsersSettings_FindOrCreateForUser(user.id), - mail_failures: this._mockResPartner_MessageFetchFailed(user.partner_id), menu_id: false, // not useful in QUnit tests needaction_inbox_counter: this._mockResPartner_GetNeedactionCount(user.partner_id), partner_root: this._mockResPartnerMailPartnerFormat(this.partnerRootId).get(this.partnerRootId), diff --git a/addons/test_discuss_full/tests/test_performance.py b/addons/test_discuss_full/tests/test_performance.py index 7a3fb437f69..ce2b22428fd 100644 --- a/addons/test_discuss_full/tests/test_performance.py +++ b/addons/test_discuss_full/tests/test_performance.py @@ -99,7 +99,7 @@ class TestDiscussFullPerformance(TransactionCase): self.maxDiff = None self.users[0].flush() self.users[0].invalidate_cache() - with self.assertQueryCount(emp=101): + with self.assertQueryCount(emp=98): init_messaging = self.users[0].with_user(self.users[0])._init_messaging() self.assertEqual(init_messaging, { @@ -724,7 +724,6 @@ class TestDiscussFullPerformance(TransactionCase): }, ], 'companyName': 'YourCompany', - 'mail_failures': [], 'shortcodes': [ { 'id': 1,