diff --git a/addons/im_livechat/models/mail_channel.py b/addons/im_livechat/models/mail_channel.py index 05b8174783d..8f7b9e6dd40 100644 --- a/addons/im_livechat/models/mail_channel.py +++ b/addons/im_livechat/models/mail_channel.py @@ -71,19 +71,6 @@ class MailChannel(models.Model): channel_infos_dict[channel.id]['livechat_visitor'] = channel._channel_get_livechat_visitor_info() return list(channel_infos_dict.values()) - @api.model - def channel_fetch_slot(self): - values = super(MailChannel, self).channel_fetch_slot() - livechat_channels = self.env['mail.channel'].search([ - ('channel_type', '=', 'livechat'), - ('channel_last_seen_partner_ids', 'in', self.env['mail.channel.partner'].sudo()._search([ - ('partner_id', '=', self.env.user.partner_id.id), - ('is_pinned', '=', True)]) - ), - ]) - values['channel_livechat'] = livechat_channels.channel_info() - return values - def _channel_get_livechat_visitor_info(self): self.ensure_one() # remove active test to ensure public partner is taken into account diff --git a/addons/im_livechat/models/res_partner.py b/addons/im_livechat/models/res_partner.py index 4359b77206f..ffc86a5b89d 100644 --- a/addons/im_livechat/models/res_partner.py +++ b/addons/im_livechat/models/res_partner.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import models, api +from odoo import models class Partners(models.Model): @@ -33,3 +33,15 @@ class Partners(models.Model): else: result = super(Partners, self).name_get() return result + + def _get_channels_as_member(self): + values = super()._get_channels_as_member() + livechat_channels = self.env['mail.channel'].search([ + ('channel_type', '=', 'livechat'), + ('channel_last_seen_partner_ids', 'in', self.env['mail.channel.partner'].sudo()._search([ + ('partner_id', '=', self.id), + ('is_pinned', '=', True), + ])), + ]) + values['channel_livechat'] = livechat_channels.channel_info() + return values diff --git a/addons/im_livechat/static/tests/helpers/mock_server.js b/addons/im_livechat/static/tests/helpers/mock_server.js index f0c84c544e6..c67bff03f17 100644 --- a/addons/im_livechat/static/tests/helpers/mock_server.js +++ b/addons/im_livechat/static/tests/helpers/mock_server.js @@ -79,23 +79,6 @@ MockServer.include({ const mailChannel = this._getRecords('mail.channel', [['uuid', '=', uuid]])[0]; this._mockMailChannelNotifyTyping([mailChannel.id], is_typing, context); }, - /** - * @override - */ - _mockRouteMailInitMessaging() { - const initMessaging = this._super(...arguments); - - const livechats = this._getRecords('mail.channel', [ - ['channel_type', '=', 'livechat'], - ['is_pinned', '=', true], - ['members', 'in', this.currentPartnerId], - ]); - initMessaging.channel_slots.channel_livechat = this._mockMailChannelChannelInfo( - livechats.map(channel => channel.id) - ); - - return initMessaging; - }, //-------------------------------------------------------------------------- // Private Mocked Methods @@ -256,4 +239,19 @@ MockServer.include({ this._mockMailChannel_broadcast([mailChannelId], [operator.partner_id]); return this._mockMailChannelChannelInfo([mailChannelId])[0]; }, + /** + * @override + */ + _mockResPartner_GetChannelsAsMember(ids) { + const partner = this._getRecords('res.partner', [['id', 'in', ids]])[0]; + const livechats = this._getRecords('mail.channel', [ + ['channel_type', '=', 'livechat'], + ['is_pinned', '=', true], + ['members', 'in', partner.id], + ]); + return { + channel_livechat: this._mockMailChannelChannelInfo(livechats.map(channel => channel.id)), + ...this._super(ids), + }; + }, }); diff --git a/addons/im_livechat/tests/test_get_mail_channel.py b/addons/im_livechat/tests/test_get_mail_channel.py index 969d10bd528..e7bed715a15 100644 --- a/addons/im_livechat/tests/test_get_mail_channel.py +++ b/addons/im_livechat/tests/test_get_mail_channel.py @@ -99,5 +99,4 @@ class TestGetMailChannel(TransactionCase): self.assertFalse(operator_channel_partner.is_pinned, "channel should not be pinned for operator initially") self.env['mail.channel'].browse(channel_info['id']).message_post(body='cc') self.assertTrue(operator_channel_partner.is_pinned, "channel should be pinned for operator after visitor sent a message") - init_channels = self.env['mail.channel'].with_user(operator_channel_partner.partner_id.user_ids[0]).channel_fetch_slot() - self.assertIn(channel_info['id'], [init_channel_info['id'] for init_channel_info in init_channels['channel_livechat']], "channel should be fetched by operator on new page") + self.assertIn(channel_info['id'], [init_channel_info['id'] for init_channel_info in operator_channel_partner.partner_id._get_channels_as_member()['channel_livechat']], "channel should be fetched by operator on new page") diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py index 2904dd641b8..9934390a005 100644 --- a/addons/mail/controllers/main.py +++ b/addons/mail/controllers/main.py @@ -250,23 +250,11 @@ class MailController(http.Controller): @http.route('/mail/needaction', type='json', auth='user') def needaction(self): - return request.env['res.partner'].get_needaction_count() + return request.env.user.partner_id._get_needaction_count() @http.route('/mail/init_messaging', type='json', auth='user') def mail_init_messaging(self): - values = { - 'needaction_inbox_counter': request.env['res.partner'].get_needaction_count(), - 'starred_counter': request.env['res.partner'].get_starred_count(), - 'channel_slots': request.env['mail.channel'].channel_fetch_slot(), - 'mail_failures': request.env['mail.message'].message_fetch_failed(), - 'shortcodes': request.env['mail.shortcode'].sudo().search_read([], ['source', 'substitution', 'description']), - 'menu_id': request.env['ir.model.data']._xmlid_to_res_id('mail.menu_root_discuss'), - 'partner_root': request.env.ref('base.partner_root').sudo().mail_partner_format(), - 'public_partners': [partner.mail_partner_format() for partner in request.env.ref('base.group_public').sudo().with_context(active_test=False).users.partner_id], - 'current_partner': request.env.user.partner_id.mail_partner_format(), - 'current_user_id': request.env.user.id, - } - return values + return request.env.user._init_messaging() @http.route('/mail/get_partner_info', type='json', auth='user') def message_partner_info_from_emails(self, model, res_ids, emails, link_mail=False): diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index 3a1b101fd47..721e9f4604c 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -822,27 +822,6 @@ class Channel(models.Model): # IM VIEW SPECIFIC (Slack Client Action) # ------------------------------------------------------------ - @api.model - def channel_fetch_slot(self): - """ Return the channels of the user grouped by 'slot' (channel, direct_message or private_group), and - the mapping between partner_id/channel_id for direct_message channels. - :returns dict : the grouped channels and the mapping - """ - values = {} - my_partner_id = self.env.user.partner_id.id - pinned_channels = self.env['mail.channel.partner'].search([('partner_id', '=', my_partner_id), ('is_pinned', '=', True)]).mapped('channel_id') - - # get the group/public channels - values['channel_channel'] = self.search([('channel_type', '=', 'channel'), ('public', 'in', ['public', 'groups']), ('channel_partner_ids', 'in', [my_partner_id])]).channel_info() - - # get the pinned 'direct message' channel - direct_message_channels = self.search([('channel_type', '=', 'chat'), ('id', 'in', pinned_channels.ids)]) - values['channel_direct_message'] = direct_message_channels.channel_info() - - # get the private group - values['channel_private_group'] = self.search([('channel_type', '=', 'channel'), ('public', '=', 'private'), ('channel_partner_ids', 'in', [my_partner_id])]).channel_info() - return values - @api.model def channel_search_to_join(self, name=None, domain=None): """ Return the channel info of the channel the current partner can join diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index e6c9f36da93..88da42103d9 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -6,12 +6,10 @@ import re from collections import defaultdict from binascii import Error as binascii_error -from operator import itemgetter from odoo import _, api, Command, fields, models, modules, tools -from odoo.exceptions import AccessError, UserError +from odoo.exceptions import AccessError from odoo.osv import expression -from odoo.tools import groupby from odoo.tools.misc import clean_context _logger = logging.getLogger(__name__) @@ -682,7 +680,7 @@ class Message(models.Model): ids = [n['mail_message_id'] for n in notifications.read(['mail_message_id'])] - notification = {'type': 'mark_as_read', 'message_ids': [id[0] for id in ids], 'needaction_inbox_counter': self.env.user.partner_id.get_needaction_count()} + notification = {'type': 'mark_as_read', 'message_ids': [id[0] for id in ids], 'needaction_inbox_counter': self.env.user.partner_id._get_needaction_count()} self.env['bus.bus'].sendone((self._cr.dbname, 'res.partner', partner_id), notification) return ids @@ -706,7 +704,7 @@ class Message(models.Model): (self._cr.dbname, 'res.partner', partner_id.id), {'type': 'mark_as_read', 'message_ids': notifications.mapped('mail_message_id').ids, - 'needaction_inbox_counter': self.env.user.partner_id.get_needaction_count() + 'needaction_inbox_counter': self.env.user.partner_id._get_needaction_count(), } ) @@ -800,18 +798,6 @@ class Message(models.Model): return vals_list - def message_fetch_failed(self): - """Returns all messages, sent by the current user, that have errors, in - the format expected by the web client.""" - messages = self.search([ - ('has_error', '=', True), - ('author_id', '=', self.env.user.partner_id.id), - ('res_id', '!=', 0), - ('model', '!=', False), - ('message_type', '!=', 'user_notification') - ]) - return messages._message_notification_format() - @api.model def message_fetch(self, domain, limit=20): """ Get a limited amount of formatted messages with provided domain. diff --git a/addons/mail/models/res_partner.py b/addons/mail/models/res_partner.py index 23dc76897f2..86cdf50011d 100644 --- a/addons/mail/models/res_partner.py +++ b/addons/mail/models/res_partner.py @@ -6,7 +6,6 @@ import logging from odoo import _, api, fields, models, tools from odoo.addons.bus.models.bus_presence import AWAY_TIMER from odoo.addons.bus.models.bus_presence import DISCONNECTION_TIMER -from odoo.exceptions import AccessError from odoo.osv import expression _logger = logging.getLogger(__name__) @@ -87,30 +86,65 @@ class Partner(models.Model): res["is_internal_user"] = not main_user.share return res - @api.model - def get_needaction_count(self): - """ compute the number of needaction of the current user """ - if self.env.user.partner_id: - self.env['mail.notification'].flush(['is_read', 'res_partner_id']) - self.env.cr.execute(""" - SELECT count(*) as needaction_count - FROM mail_notification R - WHERE R.res_partner_id = %s AND (R.is_read = false OR R.is_read IS NULL)""", (self.env.user.partner_id.id,)) - return self.env.cr.dictfetchall()[0].get('needaction_count') - _logger.error('Call to needaction_count without partner_id') - return 0 + def _get_needaction_count(self): + """ compute the number of needaction of the current partner """ + self.ensure_one() + self.env['mail.notification'].flush(['is_read', 'res_partner_id']) + self.env.cr.execute(""" + SELECT count(*) as needaction_count + FROM mail_notification R + WHERE R.res_partner_id = %s AND (R.is_read = false OR R.is_read IS NULL)""", (self.id,)) + return self.env.cr.dictfetchall()[0].get('needaction_count') - @api.model - def get_starred_count(self): - """ compute the number of starred of the current user """ - if self.env.user.partner_id: - self.env.cr.execute(""" - SELECT count(*) as starred_count - FROM mail_message_res_partner_starred_rel R - WHERE R.res_partner_id = %s """, (self.env.user.partner_id.id,)) - return self.env.cr.dictfetchall()[0].get('starred_count') - _logger.error('Call to starred_count without partner_id') - return 0 + def _get_starred_count(self): + """ compute the number of starred of the current partner """ + self.ensure_one() + self.env.cr.execute(""" + SELECT count(*) as starred_count + FROM mail_message_res_partner_starred_rel R + WHERE R.res_partner_id = %s """, (self.id,)) + return self.env.cr.dictfetchall()[0].get('starred_count') + + def _message_fetch_failed(self): + """Returns all messages, sent by the current partner, that have errors, in + the format expected by the web client.""" + self.ensure_one() + messages = self.env['mail.message'].search([ + ('has_error', '=', True), + ('author_id', '=', self.id), + ('res_id', '!=', 0), + ('model', '!=', False), + ('message_type', '!=', 'user_notification') + ]) + return messages._message_notification_format() + + def _get_channels_as_member(self): + """ Return the channels of the partner grouped by 'slot' (channel, direct_message or private_group), and + the mapping between partner_id/channel_id for direct_message channels. + :returns dict : the grouped channels and the mapping + """ + self.ensure_one() + values = {} + pinned_channels = self.env['mail.channel.partner'].search([('partner_id', '=', self.id), ('is_pinned', '=', True)]).mapped('channel_id') + # get the group/public channels + values['channel_channel'] = self.env['mail.channel'].search([ + ('channel_type', '=', 'channel'), + ('public', 'in', ['public', 'groups']), + ('channel_partner_ids', 'in', [self.id]), + ]).channel_info() + # get the pinned 'direct message' channel + direct_message_channels = self.env['mail.channel'].search([ + ('channel_type', '=', 'chat'), + ('id', 'in', pinned_channels.ids), + ]) + values['channel_direct_message'] = direct_message_channels.channel_info() + # get the private group + values['channel_private_group'] = self.env['mail.channel'].search([ + ('channel_type', '=', 'channel'), + ('public', '=', 'private'), + ('channel_partner_ids', 'in', [self.id]), + ]).channel_info() + return values @api.model def search_for_channel_invite(self, search_term, channel_id=None, limit=30): diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index 7146c6ddc44..b1a0350fc3b 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import _, api, exceptions, fields, models, modules, Command +from odoo import _, api, exceptions, fields, models, modules from odoo.addons.base.models.res_users import is_selection_groups @@ -80,6 +80,22 @@ class Users(models.Model): lambda cp: cp.channel_id.public != 'public' and cp.channel_id.channel_type == 'channel' ).unlink() + def _init_messaging(self): + self.ensure_one() + values = { + 'channel_slots': self.partner_id._get_channels_as_member(), + 'current_partner': self.partner_id.mail_partner_format(), + 'current_user_id': self.id, + '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': self.env.ref('base.partner_root').sudo().mail_partner_format(), + 'public_partners': [partner.mail_partner_format() for partner in self.env.ref('base.group_public').sudo().with_context(active_test=False).users.partner_id], + 'shortcodes': self.env['mail.shortcode'].sudo().search_read([], ['source', 'substitution', 'description']), + 'starred_counter': self.partner_id._get_starred_count(), + } + return values + @api.model def systray_get_activities(self): query = """SELECT m.id, count(*), act.res_model as model, diff --git a/addons/mail/static/tests/helpers/mock_server.js b/addons/mail/static/tests/helpers/mock_server.js index ea5bba3159a..09e774260d3 100644 --- a/addons/mail/static/tests/helpers/mock_server.js +++ b/addons/mail/static/tests/helpers/mock_server.js @@ -356,70 +356,7 @@ MockServer.include({ * @returns {Object} */ _mockRouteMailInitMessaging() { - const channels = this._getRecords('mail.channel', [ - ['channel_type', '=', 'channel'], - ['members', 'in', this.currentPartnerId], - ['public', 'in', ['public', 'groups']], - ]); - const channelInfos = this._mockMailChannelChannelInfo(channels.map(channel => channel.id)); - - const directMessages = this._getRecords('mail.channel', [ - ['channel_type', '=', 'chat'], - ['is_pinned', '=', true], - ['members', 'in', this.currentPartnerId], - ]); - const directMessageInfos = this._mockMailChannelChannelInfo(directMessages.map(channel => channel.id)); - - const privateGroups = this._getRecords('mail.channel', [ - ['channel_type', '=', 'channel'], - ['members', 'in', this.currentPartnerId], - ['public', '=', 'private'], - ]); - const privateGroupInfos = this._mockMailChannelChannelInfo(privateGroups.map(channel => channel.id)); - - const partnerRoot = this._getRecords( - 'res.partner', - [['id', '=', this.partnerRootId]], - { active_test: false } - )[0]; - const partnerRootFormat = this._mockResPartnerMailPartnerFormat(partnerRoot.id); - - const publicPartner = this._getRecords( - 'res.partner', - [['id', '=', this.publicPartnerId]], - { active_test: false } - )[0]; - const publicPartnerFormat = this._mockResPartnerMailPartnerFormat(publicPartner.id); - - const currentPartner = this._getRecords('res.partner', [['id', '=', this.currentPartnerId]])[0]; - const currentPartnerFormat = this._mockResPartnerMailPartnerFormat(currentPartner.id); - - const needaction_inbox_counter = this._mockResPartnerGetNeedactionCount(); - - const mailFailures = this._mockMailMessageMessageFetchFailed(); - - const shortcodes = this._getRecords('mail.shortcode', []); - - const starredCounter = this._getRecords('mail.message', [ - ['starred_partner_ids', 'in', this.currentPartnerId], - ]).length; - - return { - channel_slots: { - channel_channel: channelInfos, - channel_direct_message: directMessageInfos, - channel_private_group: privateGroupInfos, - }, - current_partner: currentPartnerFormat, - current_user_id: this.currentUserId, - mail_failures: mailFailures, - menu_id: false, - needaction_inbox_counter, - partner_root: partnerRootFormat, - public_partners: [publicPartnerFormat], - shortcodes, - starred_counter: starredCounter, - }; + return this._mockResUsers_InitMessaging([this.currentUserId]); }, /** * Simulates the `/mail/read_followers` route. @@ -1166,7 +1103,7 @@ MockServer.include({ }, ]); } - const notificationData = { type: 'mark_as_read', message_ids: messageIds, needaction_inbox_counter: this._mockResPartnerGetNeedactionCount() }; + const notificationData = { type: 'mark_as_read', message_ids: messageIds, needaction_inbox_counter: this._mockResPartner_GetNeedactionCount(this.currentPartnerId) }; const notification = [[false, 'res.partner', this.currentPartnerId], notificationData]; this._widget.call('bus_service', 'trigger', 'notification', [notification]); return messageIds; @@ -1189,30 +1126,6 @@ MockServer.include({ messages.length = Math.min(messages.length, limit); return this._mockMailMessageMessageFormat(messages.map(message => message.id)); }, - /** - * Simulates `message_fetch_failed` on `mail.message`. - * - * @private - * @returns {Object[]} - */ - _mockMailMessageMessageFetchFailed() { - const messages = this._getRecords('mail.message', [ - ['author_id', '=', this.currentPartnerId], - ['res_id', '!=', 0], - ['model', '!=', false], - ['message_type', '!=', 'user_notification'], - ]).filter(message => { - // Purpose is to simulate the following domain on mail.message: - // ['notification_ids.notification_status', 'in', ['bounce', 'exception']], - // But it's not supported by _getRecords domain to follow a relation. - const notifications = this._getRecords('mail.notification', [ - ['mail_message_id', '=', message.id], - ['notification_status', 'in', ['bounce', 'exception']], - ]); - return notifications.length > 0; - }); - return this._mockMailMessage_MessageNotificationFormat(messages.map(message => message.id)); - }, /** * Simulates `message_format` on `mail.message`. * @@ -1353,7 +1266,7 @@ MockServer.include({ ), }, ]); - const data = { type: 'mark_as_read', message_ids: [message.id], needaction_inbox_counter: this._mockResPartnerGetNeedactionCount() }; + const data = { type: 'mark_as_read', message_ids: [message.id], needaction_inbox_counter: this._mockResPartner_GetNeedactionCount(this.currentPartnerId) }; const busNotifications = [[[false, 'res.partner', this.currentPartnerId], data]]; this._widget.call('bus_service', 'trigger', 'notification', busNotifications); } @@ -1680,6 +1593,36 @@ MockServer.include({ ]); this._mockUnlink(model, [followers.map(follower => follower.id)]); }, + /** + * Simulates `_get_channels_as_member` on `res.partner`. + * + * @private + * @param {integer[]} ids + * @returns {Object} + */ + _mockResPartner_GetChannelsAsMember(ids) { + const partner = this._getRecords('res.partner', [['id', 'in', ids]])[0]; + const channels = this._getRecords('mail.channel', [ + ['channel_type', '=', 'channel'], + ['members', 'in', partner.id], + ['public', 'in', ['public', 'groups']], + ]); + const directMessages = this._getRecords('mail.channel', [ + ['channel_type', '=', 'chat'], + ['is_pinned', '=', true], + ['members', 'in', partner.id], + ]); + const privateGroups = this._getRecords('mail.channel', [ + ['channel_type', '=', 'channel'], + ['members', 'in', partner.id], + ['public', '=', 'private'], + ]); + return { + channel_channel: this._mockMailChannelChannelInfo(channels.map(channel => channel.id)), + channel_direct_message: this._mockMailChannelChannelInfo(directMessages.map(channel => channel.id)), + channel_private_group: this._mockMailChannelChannelInfo(privateGroups.map(channel => channel.id)), + }; + }, /** * Simulates `get_mention_suggestions` on `res.partner`. * @@ -1738,13 +1681,16 @@ MockServer.include({ return mainMatchingPartners.concat(extraMatchingPartners); }, /** - * Simulates `get_needaction_count` on `res.partner`. + * Simulates `_get_needaction_count` on `res.partner`. * * @private + * @param {integer} id + * @returns {integer} */ - _mockResPartnerGetNeedactionCount() { + _mockResPartner_GetNeedactionCount(id) { + const partner = this._getRecords('res.partner', [['id', '=', id]])[0]; return this._getRecords('mail.notification', [ - ['res_partner_id', '=', this.currentPartnerId], + ['res_partner_id', '=', partner.id], ['is_read', '=', false], ]).length; }, @@ -1815,4 +1761,52 @@ MockServer.include({ "name": partner.name, }; }, + /** + * Simulates `_message_fetch_failed` on `res.partner`. + * + * @private + * @param {integer} id + * @returns {Object[]} + */ + _mockResPartner_MessageFetchFailed(id) { + const partner = this._getRecords('res.partner', [['id', '=', id]])[0]; + const messages = this._getRecords('mail.message', [ + ['author_id', '=', partner.id], + ['res_id', '!=', 0], + ['model', '!=', false], + ['message_type', '!=', 'user_notification'], + ]).filter(message => { + // Purpose is to simulate the following domain on mail.message: + // ['notification_ids.notification_status', 'in', ['bounce', 'exception']], + // But it's not supported by _getRecords domain to follow a relation. + const notifications = this._getRecords('mail.notification', [ + ['mail_message_id', '=', message.id], + ['notification_status', 'in', ['bounce', 'exception']], + ]); + return notifications.length > 0; + }); + return this._mockMailMessage_MessageNotificationFormat(messages.map(message => message.id)); + }, + /** + * Simulates `_init_messaging` on `res.users`. + * + * @private + * @param {integer[]} ids + * @returns {Object} + */ + _mockResUsers_InitMessaging(ids) { + const user = this._getRecords('res.users', [['id', 'in', ids]])[0]; + return { + channel_slots: this._mockResPartner_GetChannelsAsMember(user.partner_id), + current_partner: this._mockResPartnerMailPartnerFormat(user.partner_id), + current_user_id: this.currentUserId, + 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), + public_partners: [this._mockResPartnerMailPartnerFormat(this.publicPartnerId)], + shortcodes: this._getRecords('mail.shortcode', []), + starred_counter: this._getRecords('mail.message', [['starred_partner_ids', 'in', user.partner_id]]).length, + }; + }, }); diff --git a/addons/test_mail/tests/test_mail_thread_internals.py b/addons/test_mail/tests/test_mail_thread_internals.py index 90545d5c2de..a8294921a76 100644 --- a/addons/test_mail/tests/test_mail_thread_internals.py +++ b/addons/test_mail/tests/test_mail_thread_internals.py @@ -141,7 +141,7 @@ class TestDiscuss(TestMailCommon, TestRecipients): 'needaction_inbox_counter': 0} ]): employee_partner.env['mail.message'].mark_all_as_read(domain=[]) - na_count = employee_partner.get_needaction_count() + na_count = employee_partner._get_needaction_count() self.assertEqual(na_count, 0, "mark all as read should conclude all needactions") # mark all as read also clear inaccessible needactions @@ -154,7 +154,7 @@ class TestDiscuss(TestMailCommon, TestRecipients): needaction_length = len(employee_partner.env['mail.message'].search([['needaction', '=', True]])) self.assertEqual(needaction_length, 1, "message should still be readable when notified") - na_count = employee_partner.get_needaction_count() + na_count = employee_partner._get_needaction_count() self.assertEqual(na_count, 1, "message not accessible is currently still counted") self._reset_bus() @@ -166,7 +166,7 @@ class TestDiscuss(TestMailCommon, TestRecipients): 'needaction_inbox_counter': 0} ]): employee_partner.env['mail.message'].mark_all_as_read(domain=[]) - na_count = employee_partner.get_needaction_count() + na_count = employee_partner._get_needaction_count() self.assertEqual(na_count, 0, "mark all read should conclude all needactions even inacessible ones") def test_set_message_done_user(self):