[IMP] mail, *: move init messaging in models and avoid self.env.user
* = im_livechat, test_mail The goal of moving it in models and making it independent of current user is to be able to test it easily in future commits. Part of task-2622462
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user