diff --git a/addons/mail/tests/common.py b/addons/mail/tests/common.py index 004b2a959ae..26fbd22c4d3 100644 --- a/addons/mail/tests/common.py +++ b/addons/mail/tests/common.py @@ -501,12 +501,22 @@ class MockEmail(common.BaseCase, MockSmtplibCase): expected['email_to'] = email_to_list # fetch mail - sent_mail = next( - (mail for mail in self._mails - if set(mail['email_to']) == set(expected['email_to']) and mail['email_from'] == expected['email_from'] - ), False) - debug_info = '-'.join('From: %s-To: %s' % (mail['email_from'], mail['email_to']) for mail in self._mails) if not bool(sent_mail) else '' - self.assertTrue(bool(sent_mail), 'Expected mail from %s to %s not found in %s' % (expected['email_from'], expected['email_to'], debug_info)) + sent_mails = [ + mail for mail in self._mails + if set(mail['email_to']) == set(expected['email_to']) and mail['email_from'] == expected['email_from'] + ] + if len(sent_mails) > 1 and values.get('subject'): + # try to better filter + sent_mail = next((mail for mail in sent_mails if mail['subject'] == values['subject']), False) + else: + sent_mail = sent_mails[0] if sent_mails else False + debug_info = '' + if not sent_mail: + debug_info = '-'.join('From: %s-To: %s' % (mail['email_from'], mail['email_to']) for mail in self._mails) + self.assertTrue( + bool(sent_mail), + 'Expected mail from %s to %s not found in %s' % (expected['email_from'], expected['email_to'], debug_info) + ) # assert values for val in direct_check: diff --git a/addons/test_mail/data/mail_template_data.xml b/addons/test_mail/data/mail_template_data.xml index 45452973061..944a1b7a95f 100644 --- a/addons/test_mail/data/mail_template_data.xml +++ b/addons/test_mail/data/mail_template_data.xml @@ -34,7 +34,7 @@ diff --git a/addons/test_mail/models/test_mail_models.py b/addons/test_mail/models/test_mail_models.py index 6b3222b6d89..8b3eec16f95 100644 --- a/addons/test_mail/models/test_mail_models.py +++ b/addons/test_mail/models/test_mail_models.py @@ -50,6 +50,16 @@ class MailTestGatewayGroups(models.Model): values['alias_parent_thread_id'] = self.id return values + def _message_get_default_recipients(self): + return dict( + (record.id, { + 'email_cc': False, + 'email_to': record.email_from if not record.customer_id.ids else False, + 'partner_ids': record.customer_id.ids, + }) + for record in self + ) + class MailTestStandard(models.Model): """ This model can be used in tests when automatic subscription and simple @@ -105,6 +115,16 @@ class MailTestTicket(models.Model): user_id = fields.Many2one('res.users', 'Responsible', tracking=1) container_id = fields.Many2one('mail.test.container', tracking=True) + def _message_get_default_recipients(self): + return dict( + (record.id, { + 'email_cc': False, + 'email_to': record.email_from if not record.customer_id.ids else False, + 'partner_ids': record.customer_id.ids, + }) + for record in self + ) + def _notify_get_recipients_groups(self, msg_vals=None): """ Activate more groups to test query counters notably (and be backward compatible for tests). """ @@ -163,6 +183,16 @@ class MailTestContainer(models.Model): 'mail.alias', 'Alias', delegate=True) + def _message_get_default_recipients(self): + return dict( + (record.id, { + 'email_cc': False, + 'email_to': False, + 'partner_ids': record.customer_id.ids, + }) + for record in self + ) + def _notify_get_recipients_groups(self, msg_vals=None): """ Activate more groups to test query counters notably (and be backward compatible for tests). """ diff --git a/addons/test_mail/tests/test_message_post.py b/addons/test_mail/tests/test_message_post.py index 102191babb5..7341c9fd44a 100644 --- a/addons/test_mail/tests/test_message_post.py +++ b/addons/test_mail/tests/test_message_post.py @@ -412,12 +412,20 @@ class TestMessageNotify(TestMessagePostCommon): @tagged('mail_post') -class TestMessagePost(TestMessagePostCommon, CronMixinCase): +class TestMessageLog(TestMessagePostCommon): - def test_initial_values(self): - self.assertFalse(self.test_record.message_ids) - self.assertFalse(self.test_record.message_follower_ids) - self.assertFalse(self.test_record.message_partner_ids) + @classmethod + def setUpClass(cls): + super(TestMessageLog, cls).setUpClass() + # ensure employee can create partners, necessary for templates + cls.user_employee.write({ + 'groups_id': [(4, cls.env.ref('base.group_partner_manager').id)], + }) + + cls.test_records, cls.test_partners = cls._create_records_for_batch( + 'mail.test.ticket', + 10, + ) @users('employee') def test_message_log(self): @@ -442,6 +450,67 @@ class TestMessagePost(TestMessagePostCommon, CronMixinCase): } ) + @users('employee') + def test_message_log_batch(self): + test_records = self.test_records.with_env(self.env) + test_records.message_subscribe(self.partner_employee_2.ids) + + new_notes = test_records._message_log_batch( + bodies=dict( + (test_record.id, '

Test _message_log_batch

') + for test_record in test_records + ), + ) + for test_record, new_note in zip(test_records, new_notes): + self.assertMessageFields( + new_note, + {'author_id': self.partner_employee, + 'body': '

Test _message_log_batch

', + 'email_from': formataddr((self.partner_employee.name, self.partner_employee.email_normalized)), + 'is_internal': True, + 'message_type': 'notification', + 'model': test_record._name, + 'notified_partner_ids': self.env['res.partner'], + 'reply_to': formataddr((self.company_admin.name, '%s@%s' % (self.alias_catchall, self.alias_domain))), + 'res_id': test_record.id, + 'subtype_id': self.env.ref('mail.mt_note'), + } + ) + + @users('employee') + def test_message_log_with_view(self): + test_records = self.test_records.with_env(self.env) + test_records.message_subscribe(self.partner_employee_2.ids) + + new_notes = test_records._message_log_with_view( + 'test_mail.mail_template_simple_test', + values={'partner': self.user_employee.partner_id} + ) + for test_record, new_note in zip(test_records, new_notes): + self.assertMessageFields( + new_note, + {'author_id': self.partner_employee, + 'body': f'

Hello {self.user_employee.name}, this comes from {test_record.name}.

', + 'email_from': formataddr((self.partner_employee.name, self.partner_employee.email_normalized)), + 'is_internal': True, + 'message_type': 'notification', + 'model': test_record._name, + 'notified_partner_ids': self.env['res.partner'], + 'reply_to': formataddr((self.company_admin.name, '%s@%s' % (self.alias_catchall, self.alias_domain))), + 'res_id': test_record.id, + 'subtype_id': self.env.ref('mail.mt_note'), + } + ) + + +@tagged('mail_post') +class TestMessagePost(TestMessagePostCommon, CronMixinCase): + + def test_initial_values(self): + self.assertFalse(self.test_record.message_ids) + self.assertFalse(self.test_record.message_follower_ids) + self.assertFalse(self.test_record.message_partner_ids) + @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') @users('employee') def test_message_post(self): @@ -508,6 +577,37 @@ 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_defaults(self): + """ Test default values when posting a classic message. """ + test_record = self.env['mail.test.simple'].create([{'name': 'Defaults'}]) + creation_msg = test_record.message_ids + self.assertEqual(len(creation_msg), 1) + + with self.mock_mail_app(): + new_message = test_record.message_post( + body='Body', + partner_ids=[self.partner_employee_2.id], + ) + + self.assertMessageFields( + new_message, + {'author_id': self.partner_employee, + 'body': '

Body

', + 'email_from': formataddr((self.partner_employee.name, self.partner_employee.email_normalized)), + 'is_internal': False, + 'message_type': 'notification', + 'model': test_record._name, + 'notified_partner_ids': self.partner_employee_2, + 'parent_id': creation_msg, + 'record_name': test_record.name, + 'reply_to': formataddr((f'{self.company_admin.name} {test_record.name}', f'{self.alias_catchall}@{self.alias_domain}')), + 'res_id': test_record.id, + 'subtype_id': self.env.ref('mail.mt_note'), + } + ) + @users('employee') def test_message_post_inactive_follower(self): """ Test posting with inactive followers does not notify them (e.g. odoobot) """ @@ -854,100 +954,202 @@ class TestMessagePostHelpers(TestMessagePostCommon): 'groups_id': [(4, cls.env.ref('base.group_partner_manager').id)], }) + cls.user_employee.write({ + 'groups_id': [(4, cls.env.ref('base.group_partner_manager').id)], + }) + + cls.test_records, cls.test_partners = cls._create_records_for_batch( + 'mail.test.ticket', + 10, + ) + @users('employee') - def test_message_log_with_view(self): - test_record = self.env['mail.test.simple'].browse(self.test_record.ids) - new_note = test_record._message_log_with_view( - 'test_mail.mail_template_simple_test', - values={'partner': self.user_employee.partner_id} - ) - self.assertMessageFields( - new_note, - {'author_id': self.partner_employee, - 'body': '

Hello %s,

' % self.user_employee.name, - 'email_from': formataddr((self.partner_employee.name, self.partner_employee.email_normalized)), - 'is_internal': True, - 'message_type': 'notification', - 'model': test_record._name, - 'notified_partner_ids': self.env['res.partner'], - 'reply_to': formataddr((self.company_admin.name, '%s@%s' % (self.alias_catchall, self.alias_domain))), - 'res_id': test_record.id, - 'subtype_id': self.env.ref('mail.mt_note'), - } - ) - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_message_post_w_template(self): - test_record = self.env['mail.test.simple'].with_context(self._test_context).create({'name': 'Test', 'email_from': 'ignasse@example.com'}) - + def test_message_mail_with_template(self): + """ Test sending mass mail on documents based on a template """ _attachments = self._generate_attachments_data(count=2, res_id=0, res_model='mail.template') email_1 = 'test1@example.com' email_2 = 'test2@example.com' - email_3 = self.partner_1.email - template = self._create_template('mail.test.simple', { + template = self._create_template('mail.test.ticket', { 'attachment_ids': [(0, 0, attach_vals) for attach_vals in _attachments], - 'partner_to': '%s,%s' % (self.partner_2.id, self.user_admin.partner_id.id), - 'email_to': '%s, %s' % (email_1, email_2), - 'email_cc': '%s' % email_3, + 'auto_delete': True, + # After the HTML sanitizer, it will become "

Body for: link

" + 'body_html': 'Body for: link', + 'email_cc': self.partner_1.email, + 'email_to': f'{email_1}, {email_2}', + 'partner_to': '{{ object.customer_id.id }},%s' % self.partner_2.id, }) template.attachment_ids.write({'res_id': template.id}) - # admin should receive emails - self.user_admin.write({'notification_type': 'email'}) + test_records = self.test_records.with_env(self.env) + with self.mock_mail_gateway(): + _new_mails, _new_messages = test_records.with_user(self.user_employee).message_post_with_template( + template.id, + composition_mode='mass_mail', + ) + + # created partners from inline email addresses + new_partners = self.env['res.partner'].search([('email', 'in', (email_1, email_2))]) + self.assertEqual(len(new_partners), 2, + 'Post with template: should have created partners based on template emails') + + # sent emails (mass mail mode) + for test_record in test_records: + self.assertMailMail( + new_partners + self.partner_1 + self.partner_2 + test_record.customer_id, + 'sent', + author=self.user_employee.partner_id, + email_values={ + 'attachments': [ + ('AttFileName_00.txt', b'AttContent_00', 'text/plain'), + ('AttFileName_01.txt', b'AttContent_01', 'text/plain'), + ], + 'subject': f'About {test_record.name}', + 'body_content': test_record.name, + }, + fields_values={ + 'auto_delete': True, + 'is_internal': False, + 'is_notification': True, # not auto_delete_message -> keep underlying mail.message + 'message_type': 'email', + 'model': test_record._name, + 'notified_partner_ids': self.env['res.partner'], + 'to_delete': True, + 'subtype_id': self.env['mail.message.subtype'], + 'reply_to': formataddr((f'{self.company_admin.name} {test_record.name}', f'{self.alias_catchall}@{self.alias_domain}')), + 'res_id': test_record.id, + } + ) + + @users('employee') + @mute_logger('odoo.addons.mail.models.mail_mail') + def test_message_mail_with_view(self): + """ Test sending a mass mailing on documents based on a view """ + test_records = self.test_records.with_env(self.env) + for test_record in test_records: + test_record.message_subscribe(test_record.customer_id.ids) + + with self.mock_mail_gateway(): + res_messages = test_records.message_post_with_view( + 'test_mail.mail_template_simple_test', + values={'partner': self.user_employee.partner_id}, + composition_mode='mass_mail', + subject='About mass mailing', + ) + self.assertEqual(len(res_messages), 0) + self.assertEqual(len(self._new_mails), 10) + + # sent emails (mass mail mode) + for test_record in test_records: + self.assertMailMail( + [test_record.customer_id], 'sent', + author=self.user_employee.partner_id, + email_values={ + 'body_content': f'

Hello {self.user_employee.partner_id.name}, this comes from {test_record.name}.

', + 'subject': 'About mass mailing', + }, + fields_values={ + 'auto_delete': False, + 'is_internal': False, + 'is_notification': True, # not auto_delete_message -> keep underlying mail.message + 'message_type': 'email', + 'model': test_record._name, + 'notified_partner_ids': self.env['res.partner'], + 'recipient_ids': test_record.customer_id, + 'to_delete': False, + 'subtype_id': self.env['mail.message.subtype'], + 'reply_to': formataddr((f'{self.company_admin.name} {test_record.name}', f'{self.alias_catchall}@{self.alias_domain}')), + 'res_id': test_record.id, + } + ) + + @users('employee') + @mute_logger('odoo.addons.mail.models.mail_mail') + def test_message_post_with_template(self): + """ Test posting on a document based on a template content """ + _attachments = self._generate_attachments_data(count=2, res_id=0, res_model='mail.template') + email_1 = 'test1@example.com' + email_2 = 'test2@example.com' + template = self._create_template('mail.test.ticket', { + 'attachment_ids': [(0, 0, attach_vals) for attach_vals in _attachments], + 'auto_delete': True, + 'email_cc': self.partner_1.email, + 'email_to': f'{email_1}, {email_2}', + 'partner_to': '{{ object.customer_id.id }},%s' % self.partner_2.id, + }) + template.attachment_ids.write({'res_id': template.id}) # Force the attachments of the template to be in the natural order. self.email_template.invalidate_recordset(['attachment_ids']) + test_record = self.test_records.with_env(self.env)[0] + test_record.message_subscribe(test_record.customer_id.ids) with self.mock_mail_gateway(): - test_record.with_user(self.user_employee).message_post_with_template(self.email_template.id, composition_mode='comment') + _new_mail, new_message = test_record.with_user(self.user_employee).message_post_with_template( + self.email_template.id, + composition_mode='comment' + ) + # created partners from inline email addresses new_partners = self.env['res.partner'].search([('email', 'in', [email_1, email_2])]) - for r in [self.partner_1, self.partner_2, new_partners[0], new_partners[1], self.partner_admin]: - self.assertSentEmail( - self.user_employee.partner_id, - [r], - subject='About %s' % test_record.name, - body_content=test_record.name, - attachments=[ - ('AttFileName_00.txt', b'AttContent_00', 'text/plain'), - ('AttFileName_01.txt', b'AttContent_01', 'text/plain'), - ] - ) + self.assertEqual(len(new_partners), 2, + 'Post with template: should have created partners based on template emails') - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_message_post_w_template_mass_mode(self): - test_record = self.env['mail.test.simple'].with_context(self._test_context).create({'name': 'Test', 'email_from': 'ignasse@example.com'}) - self.user_employee.write({ - 'groups_id': [(4, self.env.ref('base.group_partner_manager').id)], - }) + # check notifications have been sent + self.assertMailNotifications(new_message, [{ + 'content': f'

Hello {test_record.name}

', + 'message_type': 'notification', + 'notif': [ + {'partner': self.partner_1, 'type': 'email'}, + {'partner': self.partner_2, 'type': 'email'}, + {'partner': new_partners[0], 'type': 'email'}, + {'partner': new_partners[1], 'type': 'email'}, + {'partner': test_record.customer_id, 'type': 'email'}, + ], + 'subtype': 'mail.mt_comment', + }]) + self.assertMessageFields( + new_message, + {'author_id': self.partner_employee, + 'email_from': formataddr((self.partner_employee.name, self.partner_employee.email_normalized)), + 'is_internal': False, + 'model': test_record._name, + 'reply_to': formataddr((f'{self.company_admin.name} {test_record.name}', f'{self.alias_catchall}@{self.alias_domain}')), + 'res_id': test_record.id, + } + ) - _attachments = self._generate_attachments_data(count=2, res_id=0, res_model='mail.template') - template = self._create_template('mail.test.simple', { - 'attachment_ids': [(0, 0, attach_vals) for attach_vals in _attachments], - # After the HTML sanitizer, it will become "

Body for: link

" - 'body_html': 'Body for: link', - 'email_to': 'test@example.com', - 'email_cc': self.partner_1.email, - 'partner_to': '%s,%s' % (self.partner_2.id, self.user_admin.partner_id.id), - }) - template.attachment_ids.write({'res_id': template.id}) + @users('employee') + @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.tests') + def test_message_post_with_view(self): + """ Test posting on documents based on a view """ + test_record = self.test_records.with_env(self.env)[0] + test_record.message_subscribe(test_record.customer_id.ids) with self.mock_mail_gateway(): - test_record.with_user(self.user_employee).message_post_with_template( - template.id, - composition_mode='mass_mail' + new_message = test_record.message_post_with_view( + 'test_mail.mail_template_simple_test', + values={'partner': self.user_employee.partner_id} ) - new_partner = self.env['res.partner'].search([('email', '=', 'test@example.com')]) - - self.assertSentEmail( - self.user_employee.partner_id, - [new_partner], - subject='About %s' % test_record.name, - body_content=test_record.name, - attachments=[ - ('AttFileName_00.txt', b'AttContent_00', 'text/plain'), - ('AttFileName_01.txt', b'AttContent_01', 'text/plain'), - ] + # check notifications have been sent + self.assertMailNotifications(new_message, [{ + 'content': f'

Hello {self.user_employee.partner_id.name}, this comes from {test_record.name}.

', + 'message_type': 'notification', + 'notif': [ + {'partner': test_record.customer_id, 'type': 'email'}, + ], + 'subtype': 'mail.mt_comment', + }]) + self.assertMessageFields( + new_message, + {'author_id': self.partner_employee, + 'email_from': formataddr((self.partner_employee.name, self.partner_employee.email_normalized)), + 'is_internal': False, + 'message_type': 'notification', + 'model': test_record._name, + 'reply_to': formataddr((f'{self.company_admin.name} {test_record.name}', f'{self.alias_catchall}@{self.alias_domain}')), + 'res_id': test_record.id, + } ) diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py index a4f74b4ba6f..2d3d8ef92bc 100644 --- a/addons/test_mail/tests/test_performance.py +++ b/addons/test_mail/tests/test_performance.py @@ -19,6 +19,13 @@ class BaseMailPerformance(MailCommon, TransactionCaseWithUserDemo): # creating partners is required notably witn template usage cls.user_employee.write({'groups_id': [(4, cls.env.ref('base.group_partner_manager').id)]}) + cls.user_test = cls.env['res.users'].with_context(cls._test_context).create({ + 'name': 'Paulette Testouille', + 'login': 'paul', + 'email': 'user.test.paulette@example.com', + 'notification_type': 'inbox', + 'groups_id': [(6, 0, [cls.env.ref('base.group_user').id])], + }) cls.customer = cls.env['res.partner'].with_context(cls._test_context).create({ 'country_id': cls.env.ref('base.be').id, @@ -37,6 +44,57 @@ class BaseMailPerformance(MailCommon, TransactionCaseWithUserDemo): self.patch(self.env.registry, 'ready', True) self.flush_tracking() + def _create_test_records(self): + test_record_full = self.env['mail.test.ticket'].with_context(self._test_context).create({ + 'name': 'TestRecord', + 'customer_id': self.customer.id, + 'user_id': self.user_test.id, + 'email_from': 'nopartner.test@example.com', + }) + test_template_full = self.env['mail.template'].create({ + 'name': 'TestTemplate', + 'model_id': self.env['ir.model']._get('mail.test.ticket').id, + 'subject': 'About {{ object.name }}', + 'body_html': '

Hello

', + 'email_from': '{{ object.user_id.email_formatted }}', + 'partner_to': '{{ object.customer_id.id }}', + 'email_to': '{{ ("%s Customer <%s>" % (object.name, object.email_from)) }}', + 'attachment_ids': [ + (0, 0, dict(attachment, res_model='mail.template')) + for attachment in self.test_attachments_vals + ], + }) + self.flush_tracking() + return test_record_full, test_template_full + + def _create_test_records_for_batch(self): + test_partners = self.env['res.partner'].create([{ + 'phone': f'0485{idx}{idx}1122', + 'email': f'test.customer.{idx}@test.example.com', + 'name': f'Test Customer {idx}', + } for idx in range(0, 10)]) + test_records = self.env['mail.test.ticket'].create([{ + 'customer_id': test_partners[idx].id, + 'email_from': test_partners[idx].email_formatted, + 'name': f'Test Ticket {idx}', + 'user_id': self.user_test.id, + } for idx in range(0, 10)]) + test_template_full = self.env['mail.template'].create({ + 'name': 'TestTemplate', + 'model_id': self.env['ir.model']._get('mail.test.ticket').id, + 'subject': 'About {{ object.name }}', + 'body_html': '

Hello

', + 'email_from': '{{ object.user_id.email_formatted }}', + 'partner_to': '{{ object.customer_id.id }}', + 'email_to': '{{ ("%s Customer <%s>" % (object.name, object.email_from)) }}', + 'attachment_ids': [ + (0, 0, dict(attachment, res_model='mail.template')) + for attachment in self.test_attachments_vals + ], + }) + self.flush_tracking() + return test_partners, test_records, test_template_full + @tagged('mail_performance', 'post_install', '-at_install') class TestBaseMailPerformance(BaseMailPerformance): @@ -184,38 +242,10 @@ class TestMailAPIPerformance(BaseMailPerformance): def setUp(self): super(TestMailAPIPerformance, self).setUp() - self.user_test = self.env['res.users'].with_context(self._test_context).create({ - 'name': 'Paulette Testouille', - 'login': 'paul', - 'email': 'user.test.paulette@example.com', - 'notification_type': 'inbox', - 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])], - }) # automatically follow activities, for backward compatibility concerning query count self.env.ref('mail.mt_activities').write({'default': True}) - def _create_test_records(self): - self.test_record_full = self.env['mail.test.ticket'].with_context(self._test_context).create({ - 'name': 'TestRecord', - 'customer_id': self.customer.id, - 'user_id': self.user_test.id, - 'email_from': 'nopartner.test@example.com', - }) - self.test_template_full = self.env['mail.template'].create({ - 'name': 'TestTemplate', - 'model_id': self.env['ir.model']._get('mail.test.ticket').id, - 'subject': 'About {{ object.name }}', - 'body_html': '

Hello

', - 'email_from': '{{ object.user_id.email_formatted }}', - 'partner_to': '{{ object.customer_id.id }}', - 'email_to': '{{ ("%s Customer <%s>" % (object.name, object.email_from)) }}', - 'attachment_ids': [ - (0, 0, dict(attachment, res_model='mail.template')) - for attachment in self.test_attachments_vals - ], - }) - @users('__system__', 'employee') @warmup def test_adv_activity(self): @@ -300,8 +330,7 @@ class TestMailAPIPerformance(BaseMailPerformance): @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer(self): - self._create_test_records() - test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id) + test_record, _test_template = self._create_test_records() customer_id = self.customer.id with self.assertQueryCount(__system__=2, employee=2): composer = self.env['mail.compose.message'].with_context({ @@ -320,8 +349,7 @@ class TestMailAPIPerformance(BaseMailPerformance): @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_attachments(self): - self._create_test_records() - test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id) + 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): @@ -342,11 +370,10 @@ class TestMailAPIPerformance(BaseMailPerformance): @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_form_attachments(self): - self._create_test_records() - test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id) + 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__=18, employee=18): # tm+com 16/16 + with self.assertQueryCount(__system__=12, employee=12): composer_form = Form( self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', @@ -368,12 +395,31 @@ class TestMailAPIPerformance(BaseMailPerformance): self.assertEqual(message.attachment_ids, attachments) self.assertEqual(message.notified_partner_ids, customer + self.user_test.partner_id) + @users('__system__', '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): + composer = self.env['mail.compose.message'].with_context({ + 'active_ids': test_records.ids, + 'default_composition_mode': 'mass_mail', + 'default_model': test_records._name, + 'default_template_id': test_template.id, + }).create({}) + composer._onchange_template_id_wrapper() + + with self.assertQueryCount(__system__=126, employee=159), self.mock_mail_gateway(): + composer._action_send_mail() + + self.assertEqual(len(self._new_mails), 10) + @users('__system__', 'employee') @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_nodelete(self): - self._create_test_records() - test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id) + test_record, _test_template = self._create_test_records() customer_id = self.customer.id with self.assertQueryCount(__system__=2, employee=2): composer = self.env['mail.compose.message'].with_context({ @@ -393,11 +439,8 @@ class TestMailAPIPerformance(BaseMailPerformance): @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_w_template(self): - self._create_test_records() - self.test_template_full.write({'attachment_ids': [(5, 0)]}) - - test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id) - test_template = self.env['mail.template'].browse(self.test_template_full.id) + 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 composer = self.env['mail.compose.message'].with_context({ @@ -422,10 +465,8 @@ class TestMailAPIPerformance(BaseMailPerformance): @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_w_template_attachments(self): - self._create_test_records() + test_record, test_template = self._create_test_records() - test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id) - test_template = self.env['mail.template'].browse(self.test_template_full.id) with self.assertQueryCount(__system__=24, employee=25): # tm 14/15 / com 23/24 composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', @@ -452,13 +493,11 @@ class TestMailAPIPerformance(BaseMailPerformance): @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_w_template_form(self): - self._create_test_records() - self.test_template_full.write({'attachment_ids': [(5, 0)]}) + test_record, test_template = self._create_test_records() + test_template.write({'attachment_ids': [(5, 0)]}) - test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id) - test_template = self.env['mail.template'].browse(self.test_template_full.id) customer = self.env['res.partner'].browse(self.customer.ids) - with self.assertQueryCount(__system__=40, employee=42): # tm 28/30 / com 37/39 + with self.assertQueryCount(__system__=34, employee=36): # tm 24/26 / com 33/35 composer_form = Form( self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', @@ -485,12 +524,10 @@ class TestMailAPIPerformance(BaseMailPerformance): @warmup @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink', 'odoo.tests') def test_mail_composer_w_template_form_attachments(self): - self._create_test_records() + test_record, test_template = self._create_test_records() - test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id) - test_template = self.env['mail.template'].browse(self.test_template_full.id) customer = self.env['res.partner'].browse(self.customer.ids) - with self.assertQueryCount(__system__=41, employee=43): # tm 29/31 / com 38/40 + with self.assertQueryCount(__system__=35, employee=37): # tm 25/27 / com 34/36 composer_form = Form( self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', @@ -546,6 +583,36 @@ class TestMailAPIPerformance(BaseMailPerformance): body='

Test _message_log

', message_type='comment') + @users('__system__', 'employee') + @warmup + def test_message_log_batch(self): + records = self.env['mail.test.simple'].create([ + {'name': f'Test_{idx}'} + for idx in range(10) + ]) + + with self.assertQueryCount(__system__=1, employee=1): + records._message_log_batch( + bodies=dict( + (record.id, '

Test _message_log

') + for record in records + ), + message_type='comment') + + @users('__system__', 'employee') + @warmup + def test_message_log_with_view(self): + records = self.env['mail.test.simple'].create([ + {'name': f'Test_{idx}'} + for idx in range(10) + ]) + + with self.assertQueryCount(__system__=11, employee=11): + records._message_log_with_view( + 'test_mail.mail_template_simple_test', + values={'partner': self.customer.with_env(self.env)} + ) + @users('__system__', 'employee') @warmup def test_message_log_with_post(self): @@ -575,7 +642,7 @@ class TestMailAPIPerformance(BaseMailPerformance): def test_message_post_one_email_notification(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(__system__=24, employee=28): + with self.assertQueryCount(__system__=24, employee=27): record.message_post( body='

Test Post Performances with an email ping

', partner_ids=self.customer.ids, @@ -793,6 +860,29 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(record.message_ids[0].body, '

Adding stuff on %s

' % record.name) 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') + @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({ + 'active_ids': test_records.ids, + 'default_composition_mode': 'mass_mail', + 'default_model': test_records._name, + 'default_template_id': test_template.id, + }).create({}) + composer._onchange_template_id_wrapper() + + with self.assertQueryCount(__system__=121, employee=141): + messages_as_sudo = test_records.message_post_with_view( + 'test_mail.mail_template_simple_test', + values={'partner': self.user_test.partner_id}, + ) + + self.assertEqual(len(messages_as_sudo), 10) + @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') @users('__system__', 'employee') @warmup