diff --git a/addons/account/wizard/account_invoice_send.py b/addons/account/wizard/account_invoice_send.py
index ccf4863cdcb..b1d64c971e9 100644
--- a/addons/account/wizard/account_invoice_send.py
+++ b/addons/account/wizard/account_invoice_send.py
@@ -31,23 +31,23 @@ class AccountInvoiceSend(models.TransientModel):
readonly=True)
@api.model
- def default_get(self, fields):
- res = super(AccountInvoiceSend, self).default_get(fields)
- res_ids = self._context.get('active_ids')
+ def default_get(self, fields_list):
+ result = super().default_get(fields_list)
+ res_ids = self.env.context.get('active_ids')
invoices = self.env['account.move'].browse(res_ids).filtered(lambda move: move.is_invoice(include_receipts=True))
if not invoices:
raise UserError(_("You can only send invoices."))
- composer = self.env['mail.compose.message'].create({
- 'composition_mode': 'comment' if len(res_ids) == 1 else 'mass_mail',
- 'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'),
- })
- res.update({
- 'invoice_ids': res_ids,
- 'composer_id': composer.id,
- })
- return res
+ if 'invoice_ids' in fields_list and not result.get('invoice_ids'):
+ result['invoice_ids'] = res_ids
+ if 'composer_id' in fields_list and not result.get('composer_id'):
+ composer = self.env['mail.compose.message'].create({
+ 'composition_mode': 'comment' if len(res_ids) == 1 else 'mass_mail',
+ 'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'),
+ })
+ result['composer_id'] = composer.id
+ return result
@api.onchange('invoice_ids')
def _compute_composition_mode(self):
@@ -78,7 +78,6 @@ class AccountInvoiceSend(models.TransientModel):
if wizard.composer_id:
wizard.composer_id.template_id = wizard.template_id.id
wizard._compute_composition_mode()
- wizard.composer_id._onchange_template_id_wrapper()
@api.onchange('is_email')
def onchange_is_email(self):
@@ -94,7 +93,6 @@ class AccountInvoiceSend(models.TransientModel):
self.composer_id.composition_mode = 'comment' if len(res_ids) == 1 else 'mass_mail'
self.composer_id.template_id = self.template_id.id
self._compute_composition_mode()
- self.composer_id._onchange_template_id_wrapper()
@api.onchange('is_email')
def _compute_invoice_without_email(self):
diff --git a/addons/account/wizard/account_invoice_send_views.xml b/addons/account/wizard/account_invoice_send_views.xml
index f37c5006cf4..002b85482af 100644
--- a/addons/account/wizard/account_invoice_send_views.xml
+++ b/addons/account/wizard/account_invoice_send_views.xml
@@ -14,14 +14,23 @@
Hello! Could you send us your address ?
%s
' % content self.applicant_id.message_post(body=body) return super().action_invite() - - -class SurveyUserInput(models.Model): - _inherit = "survey.user_input" - - applicant_id = fields.One2many('hr.applicant', 'response_id', string='Applicant') - - def _mark_done(self): - odoobot = self.env.ref('base.partner_root') - for user_input in self: - if user_input.applicant_id: - body = _('The applicant "%s" has finished the survey.', user_input.applicant_id.partner_name) - user_input.applicant_id.message_post(body=body, author_id=odoobot.id) - return super()._mark_done() - - @api.model_create_multi - def create(self, values_list): - if 'default_applicant_id' in self.env.context: - self = self.with_context(default_applicant_id=False) - return super().create(values_list) diff --git a/addons/im_livechat/tests/test_message.py b/addons/im_livechat/tests/test_message.py index 3957660a45c..79a8a2c4b7d 100644 --- a/addons/im_livechat/tests/test_message.py +++ b/addons/im_livechat/tests/test_message.py @@ -73,6 +73,7 @@ class TestImLivechatMessage(TransactionCase): 'recipients': [], 'record_name': "test1 Ernest Employee", 'res_id': channel_livechat_1.id, + 'scheduledDatetime': False, 'sms_ids': [], 'starred_partner_ids': [], 'subject': False, diff --git a/addons/l10n_generic_coa/tests/test_mail_performance.py b/addons/l10n_generic_coa/tests/test_mail_performance.py index 716e3d8d491..b52914c6597 100644 --- a/addons/l10n_generic_coa/tests/test_mail_performance.py +++ b/addons/l10n_generic_coa/tests/test_mail_performance.py @@ -61,7 +61,7 @@ class BaseMailAccountPerformance(AccountTestInvoicingCommon, MailCommon): ]) ], 'login': 'user_account', - 'name': 'Ernest Employee', + 'name': 'Ernest Employee Account', 'notification_type': 'inbox', 'signature': '--\nErnest', }) @@ -77,7 +77,7 @@ class BaseMailAccountPerformance(AccountTestInvoicingCommon, MailCommon): ]) ], 'login': 'user_account_other', - 'name': 'Eglantine Employee', + 'name': 'Eglantine Employee AccountOther', 'notification_type': 'inbox', 'signature': '--\nEglantine', }) @@ -134,6 +134,19 @@ class BaseMailAccountPerformance(AccountTestInvoicingCommon, MailCommon): class TestAccountComposerPerformance(BaseMailAccountPerformance): """ Test performance of custom composer for moves. """ + def test_assert_initial_values(self): + """ Test initial values to ease understanding of results and notifications """ + for move in self.test_account_moves: + with self.subTest(move=move): + self.assertEqual( + move.invoice_user_id, + self.user_account_other, + ) + self.assertEqual( + move.message_partner_ids, + self.user_accountman.partner_id, + ) + @users('user_account') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') @@ -269,10 +282,8 @@ class TestAccountComposerPerformance(BaseMailAccountPerformance): self.assertEqual(len(print_msg.attachment_ids), 3) self.assertNotIn(self.attachments, print_msg.attachment_ids, 'Attachments should be duplicated, not just linked') - self.assertEqual(print_msg.author_id, self.env.user.partner_id, - 'TODO: not synchronized with email_from choice') - # self.assertEqual(print_msg.author_id, self.user_account_other.partner_id, - # 'Should take invoice_user_id partner') + self.assertEqual(print_msg.author_id, self.user_account_other.partner_id, + 'Should take invoice_user_id partner') self.assertEqual(print_msg.email_from, self.user_account_other.email_formatted, 'Should take invoice_user_id email') self.assertEqual(print_msg.notified_partner_ids, test_customer + self.user_accountman.partner_id) @@ -285,7 +296,7 @@ class TestAccountComposerPerformance(BaseMailAccountPerformance): self.assertMailMail( test_customer, 'sent', - author=self.user_account.partner_id, # author: current user, not synchronized with email_from of template + author=self.user_account_other.partner_id, # author: synchronized with email_from of template content=f'TemplateBody for {test_move.name}', email_values={ 'attachments_info': [ @@ -302,7 +313,7 @@ class TestAccountComposerPerformance(BaseMailAccountPerformance): )), }, fields_values={ - 'auto_delete': False, + 'auto_delete': True, 'email_from': self.user_account_other.email_formatted, 'is_notification': True, # should keep logs by default 'mail_server_id': self.mail_server_global, @@ -373,10 +384,8 @@ class TestAccountComposerPerformance(BaseMailAccountPerformance): self.assertEqual(len(print_msg.attachment_ids), 3) self.assertNotIn(self.attachments, print_msg.attachment_ids, 'Attachments should be duplicated, not just linked') - self.assertEqual(print_msg.author_id, self.env.user.partner_id, - 'TODO: not synchronized with email_from choice') - # self.assertEqual(print_msg.author_id, self.user_account_other.partner_id, - # 'Should take invoice_user_id partner') + self.assertEqual(print_msg.author_id, self.user_account_other.partner_id, + 'Should take invoice_user_id partner') self.assertEqual(print_msg.email_from, self.user_account_other.email_formatted, 'Should take invoice_user_id email') self.assertEqual(print_msg.notified_partner_ids, test_customer + self.user_accountman.partner_id) @@ -389,7 +398,7 @@ class TestAccountComposerPerformance(BaseMailAccountPerformance): self.assertMailMail( test_customer, 'sent', - author=self.user_account.partner_id, # author: current user, not synchronized with email_from of template + author=self.user_account_other.partner_id, # author: synchronized with email_from of template content=f'SpanishBody for {test_move.name}', # translated version email_values={ 'attachments_info': [ @@ -406,7 +415,7 @@ class TestAccountComposerPerformance(BaseMailAccountPerformance): )), }, fields_values={ - 'auto_delete': False, + 'auto_delete': True, 'email_from': self.user_account_other.email_formatted, 'is_notification': True, # should keep logs by default 'mail_server_id': self.mail_server_global, diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index e7c97a9d361..4ef8133eaef 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -346,6 +346,7 @@ class Message(models.Model): """ Access rules of mail.message: - read: if - author_id == pid, uid is the author OR + - create_uid == uid, uid is the creator OR - uid is in the recipients (partner_ids) OR - uid has been notified (needaction) OR - uid have read access to the related document if model, res_id @@ -399,12 +400,13 @@ class Message(models.Model): # Read mail_message.ids to have their values message_values = dict((message_id, {}) for message_id in self.ids) - self.flush_recordset(['model', 'res_id', 'author_id', 'parent_id', 'message_type', 'partner_ids']) + self.flush_recordset(['model', 'res_id', 'author_id', 'create_uid', 'parent_id', 'message_type', 'partner_ids']) self.env['mail.notification'].flush_model(['mail_message_id', 'res_partner_id']) if operation == 'read': self._cr.execute(""" - SELECT DISTINCT m.id, m.model, m.res_id, m.author_id, m.parent_id, + SELECT DISTINCT m.id, m.model, m.res_id, m.author_id, m.create_uid, + m.parent_id, COALESCE(partner_rel.res_partner_id, needaction_rel.res_partner_id), m.message_type as message_type FROM "%s" m @@ -413,11 +415,12 @@ class Message(models.Model): LEFT JOIN "mail_notification" needaction_rel ON needaction_rel.mail_message_id = m.id AND needaction_rel.res_partner_id = %%(pid)s WHERE m.id = ANY (%%(ids)s)""" % self._table, dict(pid=self.env.user.partner_id.id, ids=self.ids)) - for mid, rmod, rid, author_id, parent_id, partner_id, message_type in self._cr.fetchall(): + for mid, rmod, rid, author_id, create_uid, parent_id, partner_id, message_type in self._cr.fetchall(): message_values[mid] = { 'model': rmod, 'res_id': rid, 'author_id': author_id, + 'create_uid': create_uid, 'parent_id': parent_id, 'notified': any((message_values[mid].get('notified'), partner_id)), 'message_type': message_type, @@ -459,7 +462,14 @@ class Message(models.Model): author_ids = [] if operation == 'read': author_ids = [mid for mid, message in message_values.items() - if message.get('author_id') and message.get('author_id') == self.env.user.partner_id.id] + if ( + message.get('author_id') and + message.get('author_id') == self.env.user.partner_id.id + ) or ( + message.get('create_uid') and + message.get('create_uid') == self.env.uid + ) + ] elif operation == 'write': author_ids = [mid for mid, message in message_values.items() if message.get('author_id') == self.env.user.partner_id.id] elif operation == 'create': @@ -894,10 +904,17 @@ class Message(models.Model): domain = expression.AND([domain, [('id', '>', min_id)]]) return self.search(domain, limit=limit) - def message_format(self, format_reply=True): - """ Get the message values in the format for web client. Since message values can be broadcasted, - computed fields MUST NOT BE READ and broadcasted. - :returns list(dict). + def message_format(self, format_reply=True, msg_vals=None): + """ Get the message values in the format for web client. Since message + values can be broadcasted, computed fields MUST NOT BE READ and + broadcasted. + + :param msg_vals: dictionary of values used to create the message. If + given it may be used to access values related to ``message`` without + accessing it directly. It lessens query count in some optimized use + cases by avoiding access message content in db; + + :returns list(dict). Example : { 'body': HTML content of the message @@ -948,6 +965,19 @@ class Message(models.Model): com_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment') note_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note') + + # fetch scheduled notifications once, only if msg_vals is not given to + # avoid useless queries when notifying Inbox right after a message_post + scheduled_dt_by_msg_id = {} + if msg_vals: + scheduled_dt_by_msg_id = {msg.id: msg_vals.get('scheduled_date') for msg in self} + elif self: + schedulers = self.env['mail.message.schedule'].sudo().search([ + ('mail_message_id', 'in', self.ids) + ]) + for scheduler in schedulers: + scheduled_dt_by_msg_id[scheduler.mail_message_id.id] = scheduler.scheduled_datetime + for vals in vals_list: message_sudo = self.browse(vals['id']).sudo().with_prefetch(self.ids) notifs = message_sudo.notification_ids.filtered(lambda n: n.res_partner_id) @@ -959,6 +989,7 @@ class Message(models.Model): 'subtype_description': message_sudo.subtype_id.description, 'is_notification': vals['message_type'] == 'user_notification', 'recipients': [{'id': p.id, 'name': p.name} for p in message_sudo.partner_ids], + 'scheduledDatetime': scheduled_dt_by_msg_id.get(vals['id'], False), }) if vals['model'] and self.env[vals['model']]._original_module: vals['module_icon'] = modules.module.get_module_icon(self.env[vals['model']]._original_module) diff --git a/addons/mail/models/mail_template.py b/addons/mail/models/mail_template.py index bccd11d813c..9101525f99f 100644 --- a/addons/mail/models/mail_template.py +++ b/addons/mail/models/mail_template.py @@ -68,7 +68,7 @@ class MailTemplate(models.Model): 'ir.actions.report', relation='mail_template_ir_actions_report_rel', column1='mail_template_id', column2='ir_actions_report_id', - string='Reports to print and attach', + string='Dynamic Reports', domain="[('model', '=', model)]") # options mail_server_id = fields.Many2one('ir.mail_server', 'Outgoing Mail Server', readonly=False, diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index f6f0351d8b5..dd60edc395a 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -1927,9 +1927,25 @@ class MailThread(models.AbstractModel): ) # attachement_ids, body new_message = self._message_create([msg_values]) - if msg_values['author_id'] and msg_values['message_type'] != 'notification' and not self._context.get('mail_create_nosubscribe'): - if self.env['res.partner'].browse(msg_values['author_id']).active: # we dont want to add odoobot/inactive as a follower - self._message_subscribe(partner_ids=[msg_values['author_id']]) + # subscribe author(s) so that they receive answers; do it only when it is + # a manual post by the author (aka not a system notification, not a message + # posted 'in behalf of', and if still active). + author_subscribe = (not self._context.get('mail_create_nosubscribe') and + msg_values['message_type'] != 'notification') + if author_subscribe: + real_author_id = False + # if current user is active, they are the one doing the action and should + # be notified of answers. If they are inactive they are posting on behalf + # of someone else (a custom, mailgateway, ...) and the real author is the + # message author + if self.env.user.active: + real_author_id = self.env.user.partner_id.id + elif msg_values['author_id']: + author = self.env['res.partner'].browse(msg_values['author_id']) + if author.active: + real_author_id = author.id + if real_author_id: + self._message_subscribe(partner_ids=[real_author_id]) self._message_post_after_hook(new_message, msg_values) self._notify_thread(new_message, msg_values, **notif_kwargs) @@ -2177,18 +2193,7 @@ class MailThread(models.AbstractModel): composer = self.env['mail.compose.message'].with_context( **composer_ctx ).create(composer_values) - # Simulate the onchange (like trigger in form the view) only - # when having a template in single-email mode - if template: - update_values = composer._onchange_template_id( - template.id, - 'mass_mail', - self._name, - subset.ids, - )['value'] - composer.write(update_values) - - mails_as_sudo, _messages_as_sudo = composer._action_send_mail(auto_commit=auto_commit) + mails_as_sudo, _messages = composer._action_send_mail(auto_commit=auto_commit) mails_su += mails_as_sudo return mails_su @@ -2246,7 +2251,7 @@ class MailThread(models.AbstractModel): if not subtype_id: subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note') - messages = self.env['mail.message'] + messages_all = self.env['mail.message'] for record in self: if template: composer = self.env['mail.compose.message'].with_context( @@ -2259,26 +2264,16 @@ class MailThread(models.AbstractModel): 'subtype_id': subtype_id, **kwargs, }) - - # Simulate the onchange (like trigger in form the view) to do the - # rendering in mono-record mode - update_values = composer._onchange_template_id( - template.id, - 'comment', - self._name, - record.ids, - )['value'] - composer.write(update_values) - _mails_as_sudo, messages_as_sudo = composer._action_send_mail() - messages += messages_as_sudo + _mails_as_sudo, messages = composer._action_send_mail() + messages_all += messages else: - messages += record.message_post( + messages_all += record.message_post( body=bodies[record.id], message_type=message_type, subtype_id=subtype_id, **kwargs ) - return messages + return messages_all @api.returns('mail.message', lambda value: value.id) def message_notify(self, *, @@ -2286,6 +2281,7 @@ class MailThread(models.AbstractModel): author_id=None, email_from=None, model=False, res_id=False, subtype_xmlid=None, subtype_id=False, partner_ids=False, + attachments=None, attachment_ids=None, **kwargs): """ Shortcut allowing to notify partners of messages that should not be displayed on a document. It pushes notifications on inbox or by email @@ -2311,7 +2307,13 @@ class MailThread(models.AbstractModel): :param int subtype_id: subtype_id of the message, used mainly for followers notification mechanism; :param list(int) partner_ids: partner_ids to notify in addition to partners - computed based on subtype / followers matching; + computed based on subtype / followers matching; + :param list(tuple(str,str), tuple(str,str, dict)) attachments : list of attachment + tuples in the form ``(name,content)`` or ``(name,content, info)`` where content + is NOT base64 encoded; + :param list attachment_ids: list of existing attachments to link to this message + Should not be a list of commands. Attachment records attached to mail + composer will be attached to the related document. Extra keyword arguments will be used either * as default column values for the new mail.message record if they match @@ -2331,6 +2333,23 @@ class MailThread(models.AbstractModel): set(kwargs.keys()), forbidden_names={'message_id', 'message_type', 'parent_id'} ) + if attachments: + # attachments should be a list (or tuples) of 3-elements list (or tuple) + format_error = not tools.is_list_of(attachments, list) and not tools.is_list_of(attachments, tuple) + if not format_error: + format_error = not all(len(attachment) in {2, 3} for attachment in attachments) + if format_error: + raise ValueError( + _('Notification should receive attachments as a list of list or tuples (received %(aids)s)', + aids=repr(attachment_ids), + ) + ) + if attachment_ids and not tools.is_list_of(attachment_ids, int): + raise ValueError( + _('Notification should receive attachments records as a list of IDs (received %(aids)s)', + aids=repr(attachment_ids), + ) + ) if not tools.is_list_of(partner_ids, int): raise ValueError( _('Notification should receive partners given as a list of IDs (received %(pids)s)', @@ -2379,6 +2398,10 @@ class MailThread(models.AbstractModel): if 'reply_to' not in msg_values: msg_values['reply_to'] = self._notify_get_reply_to(default=email_from)[self.id if self else False] + msg_values.update( + self._process_attachments_for_post(attachments, attachment_ids, msg_values) + ) # attachement_ids, body + new_message = self._message_create([msg_values]) self._fallback_lang()._notify_thread(new_message, msg_values, **notif_kwargs) return new_message @@ -2671,6 +2694,7 @@ class MailThread(models.AbstractModel): 'force_send', 'mail_auto_delete', 'model_description', + 'notify_author', 'resend_existing', 'scheduled_date', 'send_after_commit', @@ -2833,7 +2857,7 @@ class MailThread(models.AbstractModel): } for pid in inbox_pids] self.env['mail.notification'].sudo().create(notif_create_values) - message_format_values = message.message_format()[0] + message_format_values = message.message_format(msg_vals=msg_vals)[0] for partner_id in inbox_pids: bus_notifications.append((self.env['res.partner'].browse(partner_id), 'mail.message/inbox', dict(message_format_values))) self.env['bus.bus'].sudo()._sendmany(bus_notifications) @@ -3159,6 +3183,10 @@ class MailThread(models.AbstractModel): methods. See those methods for more details about supported parameters. Specific kwargs used in this method: + * ``notify_author``: allows to notify the author, which is False by + default as we don't want people to receive their own content. It is + used notably when impersonating partners or having automated + notifications send by current user, targeting current user; * ``skip_existing``: check existing notifications and skip them in order to avoid having several notifications / partner as it would make constraints crash. This is disabled by default to optimize speed; @@ -3185,9 +3213,19 @@ class MailThread(models.AbstractModel): if not res: return recipients_data - author_id = msg_vals.get('author_id') or message.author_id.id + # notify author of its own messages, False by default + notify_author = kwargs.get('notify_author') or self.env.context.get('mail_notify_author') + real_author_id = False + if not notify_author: + if self.env.user.active: + real_author_id = self.env.user.partner_id.id + elif msg_vals.get('author_id'): + real_author_id = msg_vals['author_id'] + else: + real_author_id = message.author_id.id + for pid, pdata in res.items(): - if pid and pid == author_id and not self.env.context.get('mail_notify_author'): # do not notify the author of its own messages + if pid and pid == real_author_id: continue if pdata['active'] is False: continue diff --git a/addons/mail/static/src/components/message/message.xml b/addons/mail/static/src/components/message/message.xml index ed5c98dfcfd..e96eef8fa04 100644 --- a/addons/mail/static/src/components/message/message.xml +++ b/addons/mail/static/src/components/message/message.xml @@ -76,6 +76,11 @@ onTemplateBody
') self.assertFalse(composer_form.composition_batch) @@ -290,11 +323,12 @@ class TestComposerForm(TestMailComposer): @users('employee') def test_mail_composer_mass(self): + """ Test composer called in mass mailing mode. """ composer_form = Form(self.env['mail.compose.message'].with_context( self._get_web_context(self.test_records, add_web=True) )) self.assertFalse(composer_form.auto_delete) - self.assertTrue(composer_form.auto_delete_keep_log) + self.assertFalse(composer_form.auto_delete_keep_log, 'MailComposer: if emails are kept, logs are automatically kept') self.assertEqual(composer_form.author_id, self.env.user.partner_id) self.assertFalse(composer_form.body) self.assertTrue(composer_form.composition_batch) @@ -309,11 +343,13 @@ class TestComposerForm(TestMailComposer): self.assertEqual(sorted(literal_eval(composer_form.res_ids)), sorted(self.test_records.ids)) self.assertFalse(composer_form.scheduled_date) self.assertFalse(composer_form.subject, 'MailComposer: mass mode should have void default subject if no template') - self.assertEqual(composer_form.subtype_id, self.env.ref('mail.mt_comment')) - self.assertFalse(composer_form.subtype_is_log) + self.assertFalse(composer_form.subtype_id, 'MailComposer: subtype is not used in mail mode') + self.assertFalse(composer_form.subtype_is_log, 'MailComposer: subtype is log has no meaning in mail mode') @users('employee') def test_mail_composer_mass_wtpl(self): + """ Test composer called in mass mailing mode with a template. It globally + takes the template value raw (aka not rendered). """ composer_form = Form(self.env['mail.compose.message'].with_context( self._get_web_context(self.test_records, add_web=True, default_template_id=self.template.id) )) @@ -336,8 +372,41 @@ class TestComposerForm(TestMailComposer): self.assertEqual(composer_form.scheduled_date, self.template.scheduled_date) self.assertEqual(composer_form.subject, self.template.subject, 'MailComposer: mass mode should have template raw subject if template') - self.assertEqual(composer_form.subtype_id, self.env.ref('mail.mt_comment')) - self.assertFalse(composer_form.subtype_is_log) + self.assertFalse(composer_form.subtype_id, 'MailComposer: subtype is not used in mail mode') + self.assertFalse(composer_form.subtype_is_log, 'MailComposer: subtype is log has no meaning in mail mode') + + @users('employee') + def test_mail_composer_mass_wtpl_domain(self): + """ Same as test_mail_composer_mass_wtpl, but using a domain instead + of res_ids, to check support of domain. """ + composer_form = Form(self.env['mail.compose.message'].with_context( + default_composition_mode='mass_mail', + default_model=self.test_records._name, + default_res_domain=[('id', 'in', self.test_records.ids)], + default_template_id=self.template.id, + )) + self.assertTrue(composer_form.auto_delete, 'Should take composer value') + self.assertTrue(composer_form.auto_delete_keep_log) + self.assertEqual(composer_form.author_id, self.env.user.partner_id) + self.assertEqual(composer_form.body, self.template.body_html, + 'MailComposer: mass mode should have template raw body if template') + self.assertTrue(composer_form.composition_batch) + self.assertEqual(composer_form.composition_mode, 'mass_mail') + self.assertEqual(composer_form.email_from, self.template.email_from, + 'MailComposer: mass mode should have template raw email_from if template') + self.assertTrue(composer_form.force_send, 'MailComposer: mass mode sends emails right away') + self.assertEqual(composer_form.mail_server_id, self.mail_server_domain) + self.assertEqual(composer_form.model, self.test_records._name) + self.assertFalse(composer_form.record_name, 'MailComposer: mass mode should have void record name') + self.assertEqual(composer_form.reply_to, self.template.reply_to) + self.assertFalse(composer_form.reply_to_force_new) + self.assertFalse(composer_form.res_ids) + self.assertEqual(literal_eval(composer_form.res_domain), [('id', 'in', self.test_records.ids)]) + self.assertEqual(composer_form.scheduled_date, self.template.scheduled_date) + self.assertEqual(composer_form.subject, self.template.subject, + 'MailComposer: mass mode should have template raw subject if template') + self.assertFalse(composer_form.subtype_id, 'MailComposer: subtype is not used in mail mode') + self.assertFalse(composer_form.subtype_is_log, 'MailComposer: subtype is log has no meaning in mail mode') @users('employee') def test_mail_composer_mass_wtpl_norecords(self): @@ -367,8 +436,8 @@ class TestComposerForm(TestMailComposer): self.assertEqual(composer_form.scheduled_date, self.template.scheduled_date) self.assertEqual(composer_form.subject, self.template.subject, 'MailComposer: mass mode should have template raw subject if template') - self.assertEqual(composer_form.subtype_id, self.env.ref('mail.mt_comment')) - self.assertFalse(composer_form.subtype_is_log) + self.assertFalse(composer_form.subtype_id, 'MailComposer: subtype is not used in mail mode') + self.assertFalse(composer_form.subtype_is_log, 'MailComposer: subtype is log has no meaning in mail mode') @tagged('mail_composer') @@ -397,21 +466,24 @@ class TestComposerInternals(TestMailComposer): 'res_id': False, }) - for composition_mode, batch in (('comment', False), ('comment', True), - ('mass_mail', False), ('mass_mail', True)): - with self.subTest(composition_mode=composition_mode, batch=batch): + for composition_mode, batch_mode in product(('comment', 'mass_mail'), + (False, True, 'domain')): + with self.subTest(composition_mode=composition_mode, batch_mode=batch_mode): + batch = bool(batch_mode) test_records = self.test_records if batch else self.test_record - ctx = self._get_web_context( - test_records, add_web=False, - default_composition_mode=composition_mode, - default_template_id=self.template.id - ) + ctx = { + 'default_model': test_records._name, + 'default_composition_mode': composition_mode, + 'default_template_id': self.template.id, + } + if batch_mode == 'domain': + ctx['default_res_domain'] = [('id', 'in', test_records.ids)] + else: + ctx['default_res_ids'] = test_records.ids composer = self.env['mail.compose.message'].with_context(ctx).create({ 'body': 'Test Body
', }) - # currently onchange necessary - composer._onchange_template_id_wrapper() # values coming from template: attachment_ids + report in comment if composition_mode == 'comment' and not batch: @@ -441,29 +513,22 @@ class TestComposerInternals(TestMailComposer): else: self.assertEqual(composer.attachment_ids, attachs + extra_attach) - # update with template with void values: values are kept + # update with template with void values: values are kept, void + # value is not forced in rendering mode as well as when copying + # template values composer.write({'template_id': template_void.id}) - # currently onchange necessary - composer._onchange_template_id_wrapper() if composition_mode == 'comment' and not batch: - self.assertEqual(composer.attachment_ids, attachs + extra_attach + generated, - 'TODO: Values are kept (should be reset ?)') + self.assertEqual(composer.attachment_ids, attachs + extra_attach + generated) else: - self.assertEqual(composer.attachment_ids, attachs + extra_attach, - 'TODO: Values are kept (should be reset ?)') + self.assertEqual(composer.attachment_ids, attachs + extra_attach) - # reset template: values are kept + # reset template: values are reset composer.write({'template_id': False}) - # currently onchange necessary - composer._onchange_template_id_wrapper() - if composition_mode == 'comment' and not batch: - self.assertEqual(composer.attachment_ids, attachs + extra_attach + generated, - 'TODO: Values are kept (should be reset ?)') + self.assertFalse(composer.attachment_ids) else: - self.assertEqual(composer.attachment_ids, attachs + extra_attach, - 'TODO: Values are kept (should be reset ?)') + self.assertFalse(composer.attachment_ids) @users('employee') @mute_logger('odoo.addons.mail.models.mail_mail') @@ -474,14 +539,19 @@ class TestComposerInternals(TestMailComposer): 'email_from': False, }) - for composition_mode, batch in (('comment', False), ('comment', True), - ('mass_mail', False), ('mass_mail', True)): - with self.subTest(composition_mode=composition_mode, batch=batch): + for composition_mode, batch_mode in product(('comment', 'mass_mail'), + (False, True, 'domain')): + with self.subTest(composition_mode=composition_mode, batch_mode=batch_mode): + batch = bool(batch_mode) test_records = self.test_records if batch else self.test_record - ctx = self._get_web_context( - test_records, add_web=False, - default_composition_mode=composition_mode - ) + ctx = { + 'default_model': test_records._name, + 'default_composition_mode': composition_mode, + } + if batch_mode == 'domain': + ctx['default_res_domain'] = [('id', 'in', test_records.ids)] + else: + ctx['default_res_ids'] = test_records.ids composer = self.env['mail.compose.message'].with_context(ctx).create({ 'body': 'Test Body
', @@ -492,51 +562,64 @@ class TestComposerInternals(TestMailComposer): self.assertEqual(composer.composition_mode, composition_mode) self.assertEqual(composer.email_from, self.env.user.email_formatted) - # author values reset email (FIXME: currently not synchronized) + # author update should reset email (FIXME: currently not synchronized) composer.write({'author_id': self.partner_1}) self.assertEqual(composer.author_id, self.partner_1) - self.assertEqual(composer.email_from, self.env.user.email_formatted) + self.assertEqual(composer.email_from, self.env.user.email_formatted, + 'MailComposer: TODO: author / email_from are not synchronized') # self.assertEqual(composer.email_from, self.partner_1.email_formatted) # changing template should update its email_from - composer.write({'template_id': self.template.id, 'author_id': self.env.user.partner_id}) - # currently onchange necessary - composer._onchange_template_id_wrapper() - self.assertEqual(composer.author_id, self.env.user.partner_id, - 'MailComposer: should take value given by user') - if composition_mode == 'comment' and not batch: - self.assertEqual(composer.email_from, self.test_record.user_id.email_formatted, - f'MailComposer: should take email_from rendered from template ({composition_mode}-{batch})') - else: - self.assertEqual(composer.email_from, self.template.email_from, - f'MailComposer: should take email_from raw from template ({composition_mode}-{batch})') + composer.write({'template_id': self.template.id}) - # manual values are kept over template values + if composition_mode == 'comment' and not batch: + self.assertEqual(composer.author_id, self.test_record.user_id.partner_id, + f'MailComposer: should try to link in rendered mode: {composer.author_id.name}, expected {self.env.user.name}') + self.assertEqual(composer.email_from, self.test_record.user_id.email_formatted, + 'MailComposer: should take email_from rendered from template') + else: + self.assertEqual(composer.author_id, self.env.user.partner_id, + f'MailComposer: should reset to current user in raw mode: {composer.author_id.name}, expected {self.env.user.name}') + self.assertEqual(composer.email_from, self.template.email_from, + 'MailComposer: should take email_from raw from template') + + # manual values are kept over template values; if email does not + # match any author, reset author composer.write({'email_from': self.test_from}) - self.assertEqual(composer.author_id, self.env.user.partner_id) - self.assertEqual(composer.email_from, self.test_from) + if composition_mode == 'comment' and not batch: + self.assertEqual(composer.author_id, self.test_record.user_id.partner_id, + 'MailComposer: TODO: compute not called') + self.assertEqual(composer.email_from, self.test_from, + 'MailComposer: manual values should be kept') + else: + self.assertEqual(composer.author_id, self.env.user.partner_id, + 'MailComposer: TODO: compute not called') + self.assertEqual(composer.email_from, self.test_from, + 'MailComposer: manual values should be kept') # update with template with void values: void value is not forced in # rendering mode as well as when copying template values composer.write({'template_id': template_void.id}) - # currently onchange necessary - composer._onchange_template_id_wrapper() + if composition_mode == 'comment' and not batch: - self.assertEqual(composer.author_id, self.env.user.partner_id) + self.assertEqual(composer.author_id, self.env.user.partner_id, + 'MailComposer: TODO: author / email_from are not synchronized') self.assertEqual(composer.email_from, self.test_from) else: - self.assertEqual(composer.author_id, self.env.user.partner_id) + self.assertEqual(composer.author_id, self.env.user.partner_id, + 'MailComposer: TODO: author / email_from are not synchronized') self.assertEqual(composer.email_from, self.test_from) # reset template: values are reset due to call to default_get composer.write({'template_id': False}) - # currently onchange necessary - composer._onchange_template_id_wrapper() + if composition_mode == 'comment' and not batch: - self.assertEqual(composer.author_id, self.env.user.partner_id) + self.assertEqual(composer.author_id, self.env.user.partner_id, + 'MailComposer: TODO: author / email_from are not synchronized') self.assertEqual(composer.email_from, self.env.user.email_formatted) else: - self.assertEqual(composer.author_id, self.env.user.partner_id) + self.assertEqual(composer.author_id, self.env.user.partner_id, + 'MailComposer: TODO: author / email_from are not synchronized') self.assertEqual(composer.email_from, self.env.user.email_formatted) @users('employee') @@ -548,14 +631,19 @@ class TestComposerInternals(TestMailComposer): 'auto_delete': False, }) - for composition_mode, batch in (('comment', False), ('comment', True), - ('mass_mail', False), ('mass_mail', True)): - with self.subTest(composition_mode=composition_mode, batch=batch): + for composition_mode, batch_mode in product(('comment', 'mass_mail'), + (False, True, 'domain')): + with self.subTest(composition_mode=composition_mode, batch_mode=batch_mode): + batch = bool(batch_mode) test_records = self.test_records if batch else self.test_record - ctx = self._get_web_context( - test_records, add_web=False, - default_composition_mode=composition_mode - ) + ctx = { + 'default_model': test_records._name, + 'default_composition_mode': composition_mode, + } + if batch_mode == 'domain': + ctx['default_res_domain'] = [('id', 'in', test_records.ids)] + else: + ctx['default_res_ids'] = test_records.ids # 1. check without template (default values) + template update composer = self.env['mail.compose.message'].with_context(ctx).create({ @@ -565,23 +653,23 @@ class TestComposerInternals(TestMailComposer): # default creation values if composition_mode == 'comment': self.assertTrue(composer.auto_delete, 'By default, remove notification emails') + self.assertFalse(composer.auto_delete_keep_log, 'Not used in comment mode') + self.assertEqual(composer.subtype_id, self.env.ref('mail.mt_comment')) else: self.assertFalse(composer.auto_delete, 'By default, keep mailing emails') - self.assertTrue(composer.auto_delete_keep_log) + self.assertFalse(composer.auto_delete_keep_log, 'Emails are not unlinked, logs are already kept') + self.assertFalse(composer.subtype_id) self.assertTrue(composer.email_add_signature) self.assertEqual(composer.email_layout_xmlid, 'mail.test_layout') self.assertEqual(composer.message_type, 'comment') - self.assertEqual(composer.subtype_id, self.env.ref('mail.mt_comment')) # changing template should update its content composer.write({'template_id': self.template.id}) - # currently onchange necessary - composer._onchange_template_id_wrapper() # values come from template if composition_mode == 'comment': self.assertTrue(composer.auto_delete) - self.assertTrue(composer.auto_delete_keep_log) + self.assertFalse(composer.auto_delete_keep_log, 'Not used in comment mode') self.assertTrue(composer.email_add_signature, 'TODO: should be False as template negates this config') self.assertEqual(composer.email_layout_xmlid, 'mail.test_layout') self.assertEqual(composer.message_type, 'comment') @@ -592,7 +680,7 @@ class TestComposerInternals(TestMailComposer): self.assertTrue(composer.email_add_signature, 'TODO: should be False as template negates this config') self.assertEqual(composer.email_layout_xmlid, 'mail.test_layout') self.assertEqual(composer.message_type, 'comment') - self.assertEqual(composer.subtype_id, self.env.ref('mail.mt_comment')) + self.assertFalse(composer.subtype_id) # manual update composer.write({ @@ -606,18 +694,14 @@ class TestComposerInternals(TestMailComposer): # update with template with void values: void value is forced for # booleans, cannot distinguish composer.write({'template_id': template_falsy.id}) - # currently onchange necessary - composer._onchange_template_id_wrapper() if composition_mode == 'comment': - # self.assertFalse(composer.auto_delete, 'TODO: should be updated') - self.assertTrue(composer.auto_delete) + self.assertFalse(composer.auto_delete) self.assertEqual(composer.message_type, 'notification') self.assertEqual(composer.subtype_id, self.env.ref('mail.mt_note')) self.assertTrue(composer.subtype_is_log) else: - # self.assertFalse(composer.auto_delete, 'TODO: should be updated') - self.assertTrue(composer.auto_delete) + self.assertFalse(composer.auto_delete) self.assertEqual(composer.message_type, 'notification') self.assertEqual(composer.subtype_id, self.env.ref('mail.mt_note')) self.assertTrue(composer.subtype_is_log) @@ -634,14 +718,19 @@ class TestComposerInternals(TestMailComposer): 'subject': False, }) - for composition_mode, batch in (('comment', False), ('comment', True), - ('mass_mail', False), ('mass_mail', True)): - with self.subTest(composition_mode=composition_mode, batch=batch): + for composition_mode, batch_mode in product(('comment', 'mass_mail'), + (False, True, 'domain')): + with self.subTest(composition_mode=composition_mode, batch_mode=batch_mode): + batch = bool(batch_mode) test_records = self.test_records if batch else self.test_record - ctx = self._get_web_context( - test_records, add_web=False, - default_composition_mode=composition_mode - ) + ctx = { + 'default_model': test_records._name, + 'default_composition_mode': composition_mode, + } + if batch_mode == 'domain': + ctx['default_res_domain'] = [('id', 'in', test_records.ids)] + else: + ctx['default_res_ids'] = test_records.ids # 1. check without template + template update composer = self.env['mail.compose.message'].with_context(ctx).create({ @@ -663,8 +752,6 @@ class TestComposerInternals(TestMailComposer): # changing template should update its content composer.write({'template_id': self.template.id}) - # currently onchange necessary - composer._onchange_template_id_wrapper() # values come from template if composition_mode == 'comment' and not batch: @@ -698,8 +785,6 @@ class TestComposerInternals(TestMailComposer): # update with template with void values: void value is not forced in # rendering mode as well as in raw mode composer.write({'template_id': template_void.id}) - # currently onchange necessary - composer._onchange_template_id_wrapper() if composition_mode == 'comment' and not batch: self.assertEqual(composer.body, 'Back to my amazing body
You have received a notification
', + partner_ids=(self.partner_1 + self.partner_employee).ids, + subject='This should be a subject', + ) + + self.assertEqual(new_notification.notified_partner_ids, self.partner_1) + + with self.mock_mail_gateway(): + new_notification = test_record.message_notify( + body='You have received a notification
', + notify_author=True, + partner_ids=(self.partner_1 + self.partner_employee).ids, + subject='This should be a subject', + ) + + self.assertEqual( + new_notification.notified_partner_ids, + self.partner_1 + self.partner_employee, + 'Notify: notify_author parameter skips the author restriction' + ) + + with self.mock_mail_gateway(): + new_notification = test_record.with_context(mail_notify_author=True).message_notify( + body='You have received a notification
', + partner_ids=(self.partner_1 + self.partner_employee).ids, + subject='This should be a subject', + ) + + self.assertEqual( + new_notification.notified_partner_ids, + self.partner_1 + self.partner_employee, + 'Notify: mail_notify_author context key skips the author restriction' + ) + @users('employee') def test_notify_batch(self): """ Test notify in batch. Currently not supported. """ @@ -616,6 +659,61 @@ class TestMessagePost(TestMessagePostCommon, CronMixinCase): partner_ids=self.partner_portal.ids, ) + @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') + @users('employee') + def test_message_post_author(self): + """ Test author recognition """ + test_record = self.test_record.with_env(self.env) + + # when a user spoofs the author: the actual author is the current user + # and not the message author + with self.assertSinglePostNotifications( + [{'partner': self.partner_admin, 'type': 'email'}], + {'content': 'Body'} + ): + new_message = test_record.message_post( + author_id=self.partner_employee_2.id, + body='Body', + message_type='comment', + subtype_xmlid='mail.mt_comment', + partner_ids=[self.partner_admin.id], + ) + + self.assertMessageFields( + new_message, + {'author_id': self.partner_employee_2, + 'email_from': formataddr((self.partner_employee_2.name, self.partner_employee_2.email_normalized)), + 'message_type': 'comment', + 'notified_partner_ids': self.partner_admin, + 'subtype_id': self.env.ref('mail.mt_comment'), + } + ) + self.assertEqual(test_record.message_partner_ids, self.partner_employee, + 'Real author is added in followers, not message author') + + # should be skipped with notifications + test_record.message_unsubscribe(partner_ids=self.partner_employee.ids) + _new_message = test_record.message_post( + author_id=self.partner_employee_2.id, + body='Body', + message_type='notification', + subtype_xmlid='mail.mt_comment', + partner_ids=[self.partner_admin.id], + ) + self.assertFalse(test_record.message_partner_ids, 'Notification should not add author in followers') + + # inactive users are not considered as authors + self.env.user.with_user(self.user_admin).active = False + _new_message = test_record.message_post( + author_id=self.partner_employee_2.id, + body='Body', + message_type='comment', + subtype_xmlid='mail.mt_comment', + partner_ids=[self.partner_admin.id], + ) + self.assertEqual(test_record.message_partner_ids, self.partner_employee_2, + 'Author is the message author when user is inactive, and shoud be added in followers') + @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') @users('employee') def test_message_post_defaults(self): @@ -1133,7 +1231,7 @@ class TestMessagePostHelpers(TestMessagePostCommon): fields_values={ 'auto_delete': False, 'is_internal': False, - 'is_notification': True, # auto_delete_keep_log -> keep underlying mail.message + 'is_notification': False, # no to_delete -> no keep_log 'message_type': 'email', 'model': test_record._name, 'notified_partner_ids': self.env['res.partner'], diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py index 191f078b116..ba1b99a8ecd 100644 --- a/addons/test_mail/tests/test_performance.py +++ b/addons/test_mail/tests/test_performance.py @@ -147,14 +147,14 @@ class TestBaseMailPerformance(BaseMailPerformance): } ]) - @users('__system__', 'demo') + @users('admin', 'demo') @warmup def test_read_mail(self): """ Read records inheriting from 'mail.thread'. """ records = self.env['mail.performance.thread'].search([]) self.assertEqual(len(records), 5) - with self.assertQueryCount(__system__=2, demo=2): + with self.assertQueryCount(admin=2, demo=2): # without cache for record in records: record.partner_id.country_id.name @@ -169,27 +169,27 @@ class TestBaseMailPerformance(BaseMailPerformance): for record in records: record.value_pc - @users('__system__', 'demo') + @users('admin', 'demo') @warmup def test_write_mail(self): """ Write records inheriting from 'mail.thread' (no recomputation). """ records = self.env['mail.performance.thread'].search([]) self.assertEqual(len(records), 5) - with self.assertQueryCount(__system__=2, demo=2): + with self.assertQueryCount(admin=2, demo=2): records.write({'name': 'X'}) - @users('__system__', 'demo') + @users('admin', 'demo') @warmup def test_write_mail_with_recomputation(self): """ Write records inheriting from 'mail.thread' (with recomputation). """ records = self.env['mail.performance.thread'].search([]) self.assertEqual(len(records), 5) - with self.assertQueryCount(__system__=2, demo=2): + with self.assertQueryCount(admin=2, demo=2): records.write({'value': 42}) - @users('__system__', 'demo') + @users('admin', 'demo') @warmup def test_write_mail_with_tracking(self): """ Write records inheriting from 'mail.thread' (with field tracking). """ @@ -200,42 +200,42 @@ class TestBaseMailPerformance(BaseMailPerformance): 'partner_id': self.res_partner_12.id, }) - with self.assertQueryCount(__system__=3, demo=3): + with self.assertQueryCount(admin=3, demo=3): record.track = 'X' - @users('__system__', 'demo') + @users('admin', 'demo') @warmup def test_create_mail(self): """ Create records inheriting from 'mail.thread' (without field tracking). """ model = self.env['mail.performance.thread'] - with self.assertQueryCount(__system__=2, demo=2): + with self.assertQueryCount(admin=2, demo=2): model.with_context(tracking_disable=True).create({'name': 'X'}) - @users('__system__', 'demo') + @users('admin', 'demo') @warmup def test_create_mail_with_tracking(self): """ Create records inheriting from 'mail.thread' (with field tracking). """ - with self.assertQueryCount(__system__=8, demo=8): + with self.assertQueryCount(admin=7, demo=7): self.env['mail.performance.thread'].create({'name': 'X'}) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_create_mail_simple(self): - with self.assertQueryCount(__system__=7, employee=7): + with self.assertQueryCount(admin=6, employee=6): self.env['mail.test.simple'].create({'name': 'Test'}) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_create_mail_simple_multi(self): - with self.assertQueryCount(__system__=7, employee=7): + with self.assertQueryCount(admin=6, employee=6): self.env['mail.test.simple'].create([{'name': 'Test'}] * 5) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_write_mail_simple(self): rec = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=1, employee=1): + with self.assertQueryCount(admin=1, employee=1): rec.write({ 'name': 'Test2', 'email_from': 'test@test.com', @@ -251,15 +251,15 @@ class TestMailAPIPerformance(BaseMailPerformance): # automatically follow activities, for backward compatibility concerning query count self.env.ref('mail.mt_activities').write({'default': True}) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_adv_activity(self): model = self.env['mail.test.activity'] - with self.assertQueryCount(__system__=7, employee=7): + with self.assertQueryCount(admin=6, employee=6): model.create({'name': 'Test'}) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.models.unlink') def test_adv_activity_full(self): @@ -268,7 +268,7 @@ class TestMailAPIPerformance(BaseMailPerformance): 'default_res_model': 'mail.test.activity', }) - with self.assertQueryCount(__system__=6, employee=6): + with self.assertQueryCount(admin=6, employee=6): activity = MailActivity.create({ 'summary': 'Test Activity', 'res_id': record.id, @@ -278,16 +278,16 @@ class TestMailAPIPerformance(BaseMailPerformance): # voip module read activity_type during create leading to one less query in enterprise on action_feedback _category = activity.activity_type_id.category - with self.assertQueryCount(__system__=12, employee=13): + with self.assertQueryCount(admin=13, employee=13): activity.action_feedback(feedback='Zizisse Done !') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.models.unlink') def test_adv_activity_mixin(self): record = self.env['mail.test.activity'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=6, employee=6): + with self.assertQueryCount(admin=6, employee=6): activity = record.action_start('Test Start') # read activity_type to normalize cache between enterprise and community # voip module read activity_type during create leading to one less query in enterprise on action_close @@ -295,12 +295,12 @@ class TestMailAPIPerformance(BaseMailPerformance): record.write({'name': 'Dupe write'}) - with self.assertQueryCount(__system__=13, employee=15): + with self.assertQueryCount(admin=15, employee=15): record.action_close('Dupe feedback') self.assertEqual(record.activity_ids, self.env['mail.activity']) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.models.unlink') def test_adv_activity_mixin_w_attachments(self): @@ -313,7 +313,7 @@ class TestMailAPIPerformance(BaseMailPerformance): for values in self.test_attachments_vals ]) - with self.assertQueryCount(__system__=6, employee=6): + with self.assertQueryCount(admin=6, employee=6): activity = record.action_start('Test Start') #read activity_type to normalize cache between enterprise and community #voip module read activity_type during create leading to one less query in enterprise on action_close @@ -321,7 +321,7 @@ class TestMailAPIPerformance(BaseMailPerformance): record.write({'name': 'Dupe write'}) - with self.assertQueryCount(__system__=16, employee=19): # com+tm 15/18 + with self.assertQueryCount(admin=18, employee=18): # com+tm 17/17 record.action_close('Dupe feedback', attachment_ids=attachments.ids) # notifications @@ -331,13 +331,13 @@ class TestMailAPIPerformance(BaseMailPerformance): set(['AttFileName_00.txt', 'AttFileName_01.txt', 'AttFileName_02.txt']) ) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer(self): test_record, _test_template = self._create_test_records() customer_id = self.customer.id - with self.assertQueryCount(__system__=2, employee=2): + with self.assertQueryCount(admin=3, employee=3): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, @@ -347,17 +347,17 @@ class TestMailAPIPerformance(BaseMailPerformance): 'partner_ids': [(4, customer_id)], }) - with self.assertQueryCount(__system__=26, employee=32): + with self.assertQueryCount(admin=29, employee=29): composer._action_send_mail() - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_attachments(self): test_record, _test_template = self._create_test_records() customer = self.env['res.partner'].browse(self.customer.ids) attachments = self.env['ir.attachment'].with_user(self.env.user).create(self.test_attachments_vals) - with self.assertQueryCount(__system__=3, employee=3): + with self.assertQueryCount(admin=3, employee=3): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, @@ -368,17 +368,17 @@ class TestMailAPIPerformance(BaseMailPerformance): 'partner_ids': [(4, customer.id)], }) - with self.assertQueryCount(__system__=29, employee=37): + with self.assertQueryCount(admin=33, employee=33): composer._action_send_mail() - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_form_attachments(self): test_record, _test_template = self._create_test_records() customer = self.env['res.partner'].browse(self.customer.ids) attachments = self.env['ir.attachment'].with_user(self.env.user).create(self.test_attachments_vals) - with self.assertQueryCount(__system__=13, employee=13): # tm 12/12 + with self.assertQueryCount(admin=11, employee=11): composer_form = Form( self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', @@ -392,7 +392,7 @@ class TestMailAPIPerformance(BaseMailPerformance): composer_form.attachment_ids.add(attachment) composer = composer_form.save() - with self.assertQueryCount(__system__=39, employee=47): # tm+com 38/46 + with self.assertQueryCount(admin=43, employee=43): # tm+com 42/42 composer._action_send_mail() # notifications @@ -400,33 +400,32 @@ class TestMailAPIPerformance(BaseMailPerformance): self.assertEqual(message.attachment_ids, attachments) self.assertEqual(message.notified_partner_ids, customer + self.user_test.partner_id) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_mass_w_template(self): _partners, test_records, test_template = self._create_test_records_for_batch() - with self.assertQueryCount(__system__=3, employee=3): + with self.assertQueryCount(admin=3, employee=3): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', 'default_model': test_records._name, 'default_res_ids': test_records.ids, 'default_template_id': test_template.id, }).create({}) - composer._onchange_template_id_wrapper() - with self.assertQueryCount(__system__=108, employee=141), self.mock_mail_gateway(): + with self.assertQueryCount(admin=118, employee=121), self.mock_mail_gateway(): composer._action_send_mail() self.assertEqual(len(self._new_mails), 10) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_nodelete(self): test_record, _test_template = self._create_test_records() customer_id = self.customer.id - with self.assertQueryCount(__system__=2, employee=2): + with self.assertQueryCount(admin=3, employee=3): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, @@ -437,26 +436,25 @@ class TestMailAPIPerformance(BaseMailPerformance): 'partner_ids': [(4, customer_id)], }) - with self.assertQueryCount(__system__=26, employee=32): + with self.assertQueryCount(admin=29, employee=29): composer._action_send_mail() - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_w_template(self): test_record, test_template = self._create_test_records() test_template.write({'attachment_ids': [(5, 0)]}) - with self.assertQueryCount(__system__=23, employee=24): # tm 13/14 / com 22/23 + with self.assertQueryCount(admin=25, employee=25): # tm 15/15 / com 24/24 composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, 'default_res_ids': test_record.ids, 'default_template_id': test_template.id, }).create({}) - composer._onchange_template_id_wrapper() - with self.assertQueryCount(__system__=25, employee=31): + with self.assertQueryCount(admin=28, employee=28): composer._action_send_mail() # notifications @@ -466,22 +464,21 @@ class TestMailAPIPerformance(BaseMailPerformance): # remove created partner to ensure tests are the same each run self.env['res.partner'].sudo().search([('email', '=', 'nopartner.test@example.com')]).unlink() - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_w_template_attachments(self): test_record, test_template = self._create_test_records() - with self.assertQueryCount(__system__=24, employee=25): # tm 14/15 / com 23/24 + with self.assertQueryCount(admin=25, employee=25): # tm 15/15 / com 24/24 composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, 'default_res_ids': test_record.ids, 'default_template_id': test_template.id, }).create({}) - composer._onchange_template_id_wrapper() - with self.assertQueryCount(__system__=33, employee=44): + with self.assertQueryCount(admin=39, employee=39): composer._action_send_mail() # notifications @@ -494,7 +491,7 @@ class TestMailAPIPerformance(BaseMailPerformance): # remove created partner to ensure tests are the same each run self.env['res.partner'].sudo().search([('email', '=', 'nopartner.test@example.com')]).unlink() - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_w_template_form(self): @@ -502,7 +499,7 @@ class TestMailAPIPerformance(BaseMailPerformance): test_template.write({'attachment_ids': [(5, 0)]}) customer = self.env['res.partner'].browse(self.customer.ids) - with self.assertQueryCount(__system__=35, employee=37): # tm 24/26 / com 34/36 + with self.assertQueryCount(admin=37, employee=37): # tm 27/27 / com 36/36 composer_form = Form( self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', @@ -513,7 +510,7 @@ class TestMailAPIPerformance(BaseMailPerformance): ) composer = composer_form.save() - with self.assertQueryCount(__system__=35, employee=41): + with self.assertQueryCount(admin=38, employee=38): composer._action_send_mail() # notifications @@ -525,14 +522,14 @@ class TestMailAPIPerformance(BaseMailPerformance): # remove created partner to ensure tests are the same each run new_partner.unlink() - @users('__system__', 'employee') + @users('admin', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_w_template_form_attachments(self): test_record, test_template = self._create_test_records() customer = self.env['res.partner'].browse(self.customer.ids) - with self.assertQueryCount(__system__=36, employee=38): # tm 25/27 / com 35/37 + with self.assertQueryCount(admin=37, employee=37): # tm 27/27 / com 36/36 composer_form = Form( self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', @@ -543,7 +540,7 @@ class TestMailAPIPerformance(BaseMailPerformance): ) composer = composer_form.save() - with self.assertQueryCount(__system__=47, employee=64): + with self.assertQueryCount(admin=59, employee=59): composer._action_send_mail() # notifications @@ -559,7 +556,7 @@ class TestMailAPIPerformance(BaseMailPerformance): new_partner.unlink() @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_assignation_email(self): # Changing the `notification_type` of a user adds or removes him a group @@ -570,31 +567,31 @@ class TestMailAPIPerformance(BaseMailPerformance): # use another user already pre-defined with the email notification type, # so the ormcache is preserved. record = self.env['mail.test.track'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=27, employee=28): + with self.assertQueryCount(admin=25, employee=25): record.write({ 'user_id': self.user_test_email.id, }) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_assignation_inbox(self): record = self.env['mail.test.track'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=18, employee=20): + with self.assertQueryCount(admin=18, employee=18): record.write({ 'user_id': self.user_test_inbox.id, }) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_log(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=1, employee=1): + with self.assertQueryCount(admin=1, employee=1): record._message_log( body='Test _message_log
', message_type='comment') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_log_batch(self): records = self.env['mail.test.simple'].create([ @@ -602,7 +599,7 @@ class TestMailAPIPerformance(BaseMailPerformance): for idx in range(10) ]) - with self.assertQueryCount(__system__=1, employee=1): + with self.assertQueryCount(admin=1, employee=1): records._message_log_batch( bodies=dict( (record.id, 'Test _message_log
') @@ -610,7 +607,7 @@ class TestMailAPIPerformance(BaseMailPerformance): ), message_type='comment') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_log_with_view(self): records = self.env['mail.test.simple'].create([ @@ -618,29 +615,29 @@ class TestMailAPIPerformance(BaseMailPerformance): for idx in range(10) ]) - with self.assertQueryCount(__system__=2, employee=2): + with self.assertQueryCount(admin=2, employee=2): records._message_log_with_view( 'test_mail.mail_template_simple_test', render_values={'partner': self.customer.with_env(self.env)} ) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_log_with_post(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=4, employee=7): + with self.assertQueryCount(admin=7, employee=7): record.message_post( body='Test message_post as log
', subtype_xmlid='mail.mt_note', message_type='comment') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_post_no_notification(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=4, employee=7): + with self.assertQueryCount(admin=7, employee=7): record.message_post( body='Test Post Performances basic
', partner_ids=[], @@ -648,24 +645,24 @@ class TestMailAPIPerformance(BaseMailPerformance): subtype_xmlid='mail.mt_comment') @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_post_one_email_notification(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=23, employee=26): + with self.assertQueryCount(admin=24, employee=24): record.message_post( body='Test Post Performances with an email ping
', partner_ids=self.customer.ids, message_type='comment', subtype_xmlid='mail.mt_comment') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_post_one_inbox_notification(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=14, employee=18): + with self.assertQueryCount(admin=17, employee=17): record.message_post( body='Test Post Performances with an inbox ping
', partner_ids=self.user_test.partner_id.ids, @@ -673,47 +670,47 @@ class TestMailAPIPerformance(BaseMailPerformance): subtype_xmlid='mail.mt_comment') @mute_logger('odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_subscribe_default(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=6, employee=6): + with self.assertQueryCount(admin=5, employee=5): record.message_subscribe(partner_ids=self.user_test.partner_id.ids) - with self.assertQueryCount(__system__=3, employee=3): + with self.assertQueryCount(admin=3, employee=3): record.message_subscribe(partner_ids=self.user_test.partner_id.ids) @mute_logger('odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_subscribe_subtypes(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) subtype_ids = (self.env.ref('test_mail.st_mail_test_simple_external') | self.env.ref('mail.mt_comment')).ids - with self.assertQueryCount(__system__=5, employee=5): + with self.assertQueryCount(admin=4, employee=4): record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids) - with self.assertQueryCount(__system__=2, employee=2): + with self.assertQueryCount(admin=2, employee=2): record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids) @mute_logger('odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_message_track(self): record = self.env['mail.performance.tracking'].create({'name': 'Zizizatestname'}) - with self.assertQueryCount(__system__=3, employee=3): + with self.assertQueryCount(admin=3, employee=3): record.write({'name': 'Zizizanewtestname'}) - with self.assertQueryCount(__system__=3, employee=3): + with self.assertQueryCount(admin=3, employee=3): record.write({'field_%s' % (i): 'Tracked Char Fields %s' % (i) for i in range(3)}) - with self.assertQueryCount(__system__=4, employee=4): + with self.assertQueryCount(admin=4, employee=4): record.write({'field_%s' % (i): 'Field Without Cache %s' % (i) for i in range(3)}) record.flush_recordset() record.write({'field_%s' % (i): 'Field With Cache %s' % (i) for i in range(3)}) - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_notification_reply_to_batch(self): test_records_sudo = self.env['mail.test.container'].sudo().create([ @@ -723,7 +720,7 @@ class TestMailAPIPerformance(BaseMailPerformance): } for index in range(10) ]) - with self.assertQueryCount(__system__=1, employee=1): + with self.assertQueryCount(admin=1, employee=1): test_records = self.env['mail.test.container'].browse(test_records_sudo.ids) reply_to = test_records._notify_get_reply_to( default=self.env.user.email_formatted @@ -772,7 +769,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.env.flush_all() @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_mail_mail_send(self): message = self.env['mail.message'].sudo().create({ @@ -795,11 +792,11 @@ class TestMailComplexPerformance(BaseMailPerformance): 'mail_message_id': message.id, 'recipient_ids': [(4, pid) for pid in self.partners.ids], }) - with self.assertQueryCount(__system__=9, employee=9): + with self.assertQueryCount(admin=9, employee=9): self.env['mail.mail'].sudo().browse(mail.ids).send() @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_mail_mail_send_batch_complete(self): """ A more complete use case: 10 mails, attachments, servers, ... And @@ -828,7 +825,7 @@ class TestMailComplexPerformance(BaseMailPerformance): } for idx in range(12)]) mails[-2].write({'email_cc': False, 'email_to': 'strange@example¢¡.com', 'recipient_ids': [(5, 0)]}) mails[-1].write({'email_cc': False, 'email_to': 'void', 'recipient_ids': [(5, 0)]}) - with self.assertQueryCount(__system__=43, employee=43): + with self.assertQueryCount(admin=43, employee=43): self.env['mail.mail'].sudo().browse(mails.ids).send() for mail in mails[:-2]: @@ -840,14 +837,14 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertTrue(mails[-1].to_delete, 'Mail: mails with invalid recipient are also to be unlinked') @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_message_post(self): self.container.message_subscribe(self.user_portal.partner_id.ids) record = self.container.with_user(self.env.user) # about 20 (19?) queries per additional customer group - with self.assertQueryCount(__system__=35, employee=36): + with self.assertQueryCount(admin=35, employee=34): record.message_post( body='Test Post Performances
', message_type='comment', @@ -857,7 +854,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(record.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id) @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_message_post_template(self): self.container.message_subscribe(self.user_portal.partner_id.ids) @@ -865,7 +862,7 @@ class TestMailComplexPerformance(BaseMailPerformance): template = self.env.ref('test_mail.mail_test_container_tpl') # about 20 (19 ?) queries per additional customer group - with self.assertQueryCount(__system__=43, employee=44): + with self.assertQueryCount(admin=42, employee=41): record.message_post_with_source( template, message_type='comment', @@ -876,21 +873,20 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(record.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id | self.customer) @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_message_post_view(self): _partners, test_records, test_template = self._create_test_records_for_batch() - with self.assertQueryCount(__system__=3, employee=3): - composer = self.env['mail.compose.message'].with_context({ + with self.assertQueryCount(admin=3, employee=3): + _composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', 'default_model': test_records._name, 'default_res_ids': test_records.ids, 'default_template_id': test_template.id, }).create({}) - composer._onchange_template_id_wrapper() - with self.assertQueryCount(__system__=111, employee=131): + with self.assertQueryCount(admin=131, employee=131): messages_as_sudo = test_records.message_post_with_source( 'test_mail.mail_template_simple_test', render_values={'partner': self.user_test.partner_id}, @@ -900,7 +896,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(len(messages_as_sudo), 10) @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_message_subscribe(self): pids = self.partners.ids @@ -917,7 +913,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id) # subscribe new followers with forced given subtypes - with self.assertQueryCount(__system__=4, employee=4): + with self.assertQueryCount(admin=3, employee=3): rec.message_subscribe( partner_ids=pids[:4], subtype_ids=subtype_ids @@ -926,7 +922,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id | self.partners[:4]) # subscribe existing and new followers with force=False, meaning only some new followers will be added - with self.assertQueryCount(__system__=5, employee=5): + with self.assertQueryCount(admin=4, employee=4): rec.message_subscribe( partner_ids=pids[:6], subtype_ids=None @@ -935,7 +931,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id | self.partners[:6]) # subscribe existing and new followers with force=True, meaning all will have the same subtypes - with self.assertQueryCount(__system__=4, employee=4): + with self.assertQueryCount(admin=3, employee=3): rec.message_subscribe( partner_ids=pids, subtype_ids=subtype_ids @@ -944,7 +940,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id | self.partners) @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_tracking_assignation(self): """ Assignation performance test on already-created record """ @@ -956,7 +952,7 @@ class TestMailComplexPerformance(BaseMailPerformance): }) rec1 = rec.with_context(active_test=False) # to see inactive records self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id) - with self.assertQueryCount(__system__=25, employee=26): + with self.assertQueryCount(admin=23, employee=23): rec.write({'user_id': self.user_portal.id}) self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id) # write tracking message @@ -968,7 +964,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(len(rec1.message_ids), 2) @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_tracking_subscription_create(self): """ Creation performance test involving auto subscription, assignation, tracking with subtype and template send. """ @@ -976,7 +972,7 @@ class TestMailComplexPerformance(BaseMailPerformance): customer_id = self.customer.id user_id = self.user_portal.id - with self.assertQueryCount(__system__=57, employee=58): # tm 57/58 + with self.assertQueryCount(admin=52, employee=52): rec = self.env['mail.test.ticket'].create({ 'name': 'Test', 'container_id': container_id, @@ -992,7 +988,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(len(rec1.message_ids), 1) @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_tracking_subscription_subtype(self): """ Write performance test involving auto subscription, tracking with subtype """ @@ -1005,7 +1001,7 @@ class TestMailComplexPerformance(BaseMailPerformance): rec1 = rec.with_context(active_test=False) # to see inactive records self.assertEqual(rec1.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id) self.assertEqual(len(rec1.message_ids), 1) - with self.assertQueryCount(__system__=36, employee=36): + with self.assertQueryCount(admin=33, employee=33): rec.write({ 'name': 'Test2', 'container_id': self.container.id, @@ -1021,7 +1017,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(len(rec1.message_ids), 2) @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_tracking_subscription_write(self): """ Write performance test involving auto subscription, tracking with subtype and template send """ @@ -1042,7 +1038,7 @@ class TestMailComplexPerformance(BaseMailPerformance): rec1 = rec.with_context(active_test=False) # to see inactive records self.assertEqual(rec1.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id) - with self.assertQueryCount(__system__=36, employee=36): + with self.assertQueryCount(admin=33, employee=33): rec.write({ 'name': 'Test2', 'container_id': container_id, @@ -1059,7 +1055,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(len(rec1.message_ids), 2) @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - @users('__system__', 'employee') + @users('admin', 'employee') @warmup def test_complex_tracking_template(self): """ Write performance test involving assignation, tracking with template """ @@ -1075,7 +1071,7 @@ class TestMailComplexPerformance(BaseMailPerformance): rec1 = rec.with_context(active_test=False) # to see inactive records self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id) - with self.assertQueryCount(__system__=20, employee=21): + with self.assertQueryCount(admin=21, employee=21): rec.write({ 'name': 'Test2', 'customer_id': customer_id, @@ -1191,7 +1187,7 @@ class TestMailComplexPerformance(BaseMailPerformance): ] }]) - with self.assertQueryCount(employee=6): + with self.assertQueryCount(employee=7): res = messages.message_format() self.assertEqual(len(res), 2) for message in res: @@ -1200,7 +1196,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.env.flush_all() self.env.invalidate_all() - with self.assertQueryCount(employee=19): + with self.assertQueryCount(employee=20): res = messages.message_format() self.assertEqual(len(res), 2) for message in res: @@ -1221,14 +1217,14 @@ class TestMailComplexPerformance(BaseMailPerformance): 'res_id': record.id } for record in records]) - with self.assertQueryCount(employee=5): + with self.assertQueryCount(employee=6): res = messages.message_format() self.assertEqual(len(res), 6) self.env.flush_all() self.env.invalidate_all() - with self.assertQueryCount(employee=14): + with self.assertQueryCount(employee=15): res = messages.message_format() self.assertEqual(len(res), 6) @@ -1305,7 +1301,7 @@ class TestMailHeavyPerformancePost(BaseMailPerformance): attachments = self.env['ir.attachment'].with_user(self.env.user).create(self.test_attachments_vals) # enable_logging = self.cr._enable_logging() if self.warm else nullcontext() # with self.assertQueryCount(employee=49), enable_logging: - with self.assertQueryCount(employee=49): + with self.assertQueryCount(employee=45): record_container.with_context({}).message_post( body='Test body