diff options
| author | Priyanka Kakadiya <pka@odoo.com> | 2020-07-13 13:22:34 +0000 |
|---|---|---|
| committer | Priyanka Kakadiya <pka@odoo.com> | 2020-08-17 11:56:46 +0000 |
| commit | 2b06be68600b5a15b5c2e3500b2e05394c966535 (patch) | |
| tree | ce9dfcdaf1ac1d5e1fe9f13df17dd688a2037101 | |
| parent | ecb1d732c643a611bf2074755fef57a1da7ab723 (diff) | |
[IMP] mail: improve followers refreshed on thread
PURPOSE
Currently it does two RPCs to refresh followers on thread:
1) To get follower ids
2) To get followers detail
SPECIFICATION
While refreshing followers on the thread, perform only one RPC call.
LINKS
Task-2243180
PR https://github.com/odoo/odoo/pull/54437
closes odoo/odoo#55989
X-original-commit: 1fd445fb55810b97ed7a6dfe694e471891c6a3bc
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
6 files changed, 41 insertions, 39 deletions
diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py index 9a6e288790b..6e1525439c4 100644 --- a/addons/mail/controllers/main.py +++ b/addons/mail/controllers/main.py @@ -127,16 +127,11 @@ class MailController(http.Controller): return werkzeug.utils.redirect(url) @http.route('/mail/read_followers', type='json', auth='user') - def read_followers(self, follower_ids): + def read_followers(self, res_model, res_id): request.env['mail.followers'].check_access_rights("read") - follower_recs = request.env['mail.followers'].sudo().browse(follower_ids) - res_ids = follower_recs.mapped('res_id') - res_models = set(follower_recs.mapped('res_model')) - if len(res_models) > 1: - raise AccessError(_("Can't read followers with different targeted model")) - res_model = res_models.pop() request.env[res_model].check_access_rights("read") - request.env[res_model].browse(res_ids).check_access_rule("read") + request.env[res_model].browse(res_id).check_access_rule("read") + follower_recs = request.env['mail.followers'].search([('res_model', '=', res_model), ('res_id', '=', res_id)]) followers = [] follower_id = None diff --git a/addons/mail/static/src/components/chatter_topbar/chatter_topbar_tests.js b/addons/mail/static/src/components/chatter_topbar/chatter_topbar_tests.js index 3f6462c6dd2..3063b38919b 100644 --- a/addons/mail/static/src/components/chatter_topbar/chatter_topbar_tests.js +++ b/addons/mail/static/src/components/chatter_topbar/chatter_topbar_tests.js @@ -441,15 +441,18 @@ QUnit.test('rendering with multiple partner followers', async function (assert) id: 1, name: "Jean Michang", partner_id: 12, - }, - { + res_id: 100, + res_model: 'res.partner', + }, { // simulate real return from RPC // (the presence of the key and the falsy value need to be handled correctly) channel_id: false, id: 2, name: "Eden Hazard", partner_id: 11, - } + res_id: 100, + res_model: 'res.partner', + }, ); const chatter = this.env.models['mail.chatter'].create({ followerIds: [1, 2], @@ -517,15 +520,18 @@ QUnit.test('rendering with multiple channel followers', async function (assert) // simulate real return from RPC // (the presence of the key and the falsy value need to be handled correctly) partner_id: false, - }, - { + res_id: 100, + res_model: 'res.partner', + }, { channel_id: 12, id: 2, name: "channel armstrong", // simulate real return from RPC // (the presence of the key and the falsy value need to be handled correctly) partner_id: false, - } + res_id: 100, + res_model: 'res.partner', + }, ); const chatter = this.env.models['mail.chatter'].create({ followerIds: [1, 2], diff --git a/addons/mail/static/src/components/follow_button/follow_button_tests.js b/addons/mail/static/src/components/follow_button/follow_button_tests.js index 8405363a4a0..0c4553c6a74 100644 --- a/addons/mail/static/src/components/follow_button/follow_button_tests.js +++ b/addons/mail/static/src/components/follow_button/follow_button_tests.js @@ -99,6 +99,8 @@ QUnit.test('hover following button', async function (assert) { is_active: true, is_editable: true, partner_id: this.data.currentPartnerId, + res_id: 100, + res_model: 'res.partner', }); await this.start(); const thread = this.env.models['mail.thread'].create({ @@ -157,7 +159,7 @@ QUnit.test('hover following button', async function (assert) { }); QUnit.test('click on "follow" button', async function (assert) { - assert.expect(8); + assert.expect(7); this.data['res.partner'].records.push({ id: 100, message_follower_ids: [1] }); this.data['mail.followers'].records.push({ @@ -165,15 +167,15 @@ QUnit.test('click on "follow" button', async function (assert) { is_active: true, is_editable: true, partner_id: this.data.currentPartnerId, + res_id: 100, + res_model: 'res.partner', }); await this.start({ async mockRPC(route, args) { - if (route.includes('res.partner/read')) { - assert.step('rpc:read_follower_ids'); - } else if (route.includes('message_subscribe')) { + if (route.includes('message_subscribe')) { assert.step('rpc:message_subscribe'); } else if (route.includes('mail/read_followers')) { - assert.step('rpc:read_followers_details'); + assert.step('rpc:mail/read_followers'); } return this._super(...arguments); }, @@ -199,8 +201,7 @@ QUnit.test('click on "follow" button', async function (assert) { }); assert.verifySteps([ 'rpc:message_subscribe', - 'rpc:read_follower_ids', - 'rpc:read_followers_details', + 'rpc:mail/read_followers', ]); assert.containsNone( document.body, @@ -223,6 +224,8 @@ QUnit.test('click on "unfollow" button', async function (assert) { is_active: true, is_editable: true, partner_id: this.data.currentPartnerId, + res_id: 100, + res_model: 'res.partner', }); await this.start({ async mockRPC(route, args) { diff --git a/addons/mail/static/src/components/follower_list_menu/follower_list_menu_tests.js b/addons/mail/static/src/components/follower_list_menu/follower_list_menu_tests.js index c9664676dba..894a1b2cef5 100644 --- a/addons/mail/static/src/components/follower_list_menu/follower_list_menu_tests.js +++ b/addons/mail/static/src/components/follower_list_menu/follower_list_menu_tests.js @@ -163,6 +163,8 @@ QUnit.test('click on "add followers" button', async function (assert) { is_active: true, is_editable: true, name: "François Perusse", + res_id: 100, + res_model: 'res.partner', }); await this.start({ env: { bus }, @@ -279,6 +281,8 @@ QUnit.test('click on "add channels" button', async function (assert) { is_active: true, is_editable: true, name: "Supa channel", + res_id: 100, + res_model: 'res.partner', }); await this.start({ env: { bus }, diff --git a/addons/mail/static/src/models/thread/thread.js b/addons/mail/static/src/models/thread/thread.js index 56bdfd36138..92da6ca9197 100644 --- a/addons/mail/static/src/models/thread/thread.js +++ b/addons/mail/static/src/models/thread/thread.js @@ -576,20 +576,14 @@ function factory(dependencies) { this.update({ followers: [['unlink-all']] }); return; } - // FIXME Do that with only one RPC (see task-2243180) - const [{ message_follower_ids: followerIds }] = await this.async(() => this.env.services.rpc({ - model: this.model, - method: 'read', - args: [this.id, ['message_follower_ids']], + const { followers } = await this.async(() => this.env.services.rpc({ + route: '/mail/read_followers', + params: { + res_id: this.id, + res_model: this.model, + }, })); - if (followerIds && followerIds.length > 0) { - const { followers } = await this.async(() => this.env.services.rpc({ - route: '/mail/read_followers', - params: { - follower_ids: followerIds, - context: {}, // FIXME empty context to be overridden in session.js with 'allowed_company_ids' task-2243187 - } - })); + if (followers.length > 0) { this.update({ followers: [['insert-and-replace', followers.map(data => this.env.models['mail.follower'].convertData(data)) diff --git a/addons/mail/static/tests/helpers/mock_server.js b/addons/mail/static/tests/helpers/mock_server.js index 56f8f924d38..d978d8e73f6 100644 --- a/addons/mail/static/tests/helpers/mock_server.js +++ b/addons/mail/static/tests/helpers/mock_server.js @@ -96,8 +96,7 @@ MockServer.include({ return this._mockRouteMailInitMessaging(); } if (route === '/mail/read_followers') { - const follower_ids = args.follower_ids; - return this._mockRouteMailReadFollowers(follower_ids); + return this._mockRouteMailReadFollowers(args); } if (route === '/mail/read_subscription_data') { const follower_id = args.follower_id; @@ -323,9 +322,10 @@ MockServer.include({ * @param {integer[]} follower_ids * @return {Object} one key for list of followers and one for subtypes */ - async _mockRouteMailReadFollowers(follower_ids) { - const ids = follower_ids; // list of followers IDs to read - const followers = this._getRecords('mail.followers', [['id', 'in', ids]]); + async _mockRouteMailReadFollowers(args) { + const res_id = args.res_id; // id of record to read the followers + const res_model = args.res_model; // model of record to read the followers + const followers = this._getRecords('mail.followers', [['res_id', '=', res_id], ['res_model', '=', res_model]]); const currentPartnerFollower = followers.find(follower => follower.id === this.currentPartnerId); const subtypes = currentPartnerFollower ? this._mockRouteMailReadSubscriptionData(currentPartnerFollower.id) |
