From 94ab6963cf00bbd788bc11d261deae1d9fb96791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 2 Nov 2021 11:22:51 +0000 Subject: [PATCH] [IMP] test_mail: add and improve tests for composer PURPOSE Cleanup and improve composer-related tests. As composer will soon be improved better ensure we don't break flows. SPECIFCIATIONS Cleanup existing tests: rename, make it use tools, reoder them. Add some tests about composer in order to better spot changes and differences as well as to help debugging mail composer code update. Notably add tests with Form tool, add tests for reply-to computation, auto-delete, mail server. Performance tests about composer are added, notably using the Form tool. This helps determining differences between creating / manipulating a composer in code and in UI. Indeed notably onchange and some side effects may lead to different query counters, which is the case as highlighted here. Tests involving attachments are also added to see their impact on posting process. Task-2673913 (TestMail: Cleanup and improve test coverage) Part-of: odoo/odoo#86393 --- addons/mail/tests/test_mail_composer.py | 16 +- addons/mail/wizard/mail_compose_message.py | 2 +- addons/test_mail/tests/test_mail_composer.py | 459 ++++++++++++++----- addons/test_mail/tests/test_performance.py | 255 +++++++++-- 4 files changed, 587 insertions(+), 145 deletions(-) diff --git a/addons/mail/tests/test_mail_composer.py b/addons/mail/tests/test_mail_composer.py index 11bde11084c..9b573efb5be 100644 --- a/addons/mail/tests/test_mail_composer.py +++ b/addons/mail/tests/test_mail_composer.py @@ -1,11 +1,13 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.tests import users from odoo.addons.mail.tests.common import MailCommon +from odoo.tests import tagged, users +@tagged('mail_composer') class TestMailComposer(MailCommon): + @classmethod def setUpClass(cls): super(TestMailComposer, cls).setUpClass() @@ -47,9 +49,11 @@ class TestMailComposer(MailCommon): values = mail_compose_message.get_mail_values(self.partner_employee.ids) - self.assertIn(self.body_html, + self.assertIn( + self.body_html, values[self.partner_employee.id]['body_html'], - 'We must preserve (mso) comments in email html') + 'We must preserve (mso) comments in email html' + ) @users('employee') def test_mail_mass_mode_compose_with_mso(self): @@ -69,6 +73,8 @@ class TestMailComposer(MailCommon): values = composer.get_mail_values(self.partner_employee.ids) - self.assertIn(self.body_html, + self.assertIn( + self.body_html, values[self.partner_employee.id]['body_html'], - 'We must preserve (mso) comments in email html') + 'We must preserve (mso) comments in email html' + ) diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index ce079a23cae..3fca30f5caf 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -545,7 +545,7 @@ class MailComposer(models.TransientModel): elif template_id: values = self.generate_email_for_composer( template_id, [res_id], - ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'mail_server_id'] + ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids', 'mail_server_id'] )[res_id] # transform attachments into attachment_ids; not attached to the document because this will # be done further in the posting process, allowing to clean database if email not send diff --git a/addons/test_mail/tests/test_mail_composer.py b/addons/test_mail/tests/test_mail_composer.py index 8037497ca0d..c9ad9faf0e4 100644 --- a/addons/test_mail/tests/test_mail_composer.py +++ b/addons/test_mail/tests/test_mail_composer.py @@ -11,6 +11,7 @@ from odoo.tests import tagged from odoo.tests.common import users, Form from odoo.tools import mute_logger + @tagged('mail_composer') class TestMailComposer(TestMailCommon, TestRecipients): """ Test Composer internals """ @@ -46,7 +47,10 @@ class TestMailComposer(TestMailCommon, TestRecipients): 'customer_id': cls.partner_1.id, 'user_id': cls.user_employee_2.id, }) - cls.test_records, cls.test_partners = cls._create_records_for_batch('mail.test.ticket', 2) + cls.test_records, cls.test_partners = cls._create_records_for_batch( + 'mail.test.ticket', 2, + additional_values={'user_id': cls.user_employee_2.id} + ) cls.test_report = cls.env['ir.actions.report'].create({ 'name': 'Test Report on mail test ticket', @@ -58,24 +62,17 @@ class TestMailComposer(TestMailCommon, TestRecipients): cls.test_from = '"John Doe" ' - cls.mail_server = cls.env['ir.mail_server'].create({ - 'name': 'Dummy Test Server', - 'smtp_host': 'smtp.pizza.moc', - 'smtp_port': 17, - 'smtp_encryption': 'ssl', - 'sequence': 666, - }) - cls.template = cls.env['mail.template'].create({ + 'auto_delete': True, 'name': 'TestTemplate', 'subject': 'TemplateSubject {{ object.name }}', 'body_html': '

TemplateBody

', 'partner_to': '{{ object.customer_id.id if object.customer_id else "" }}', 'email_to': '{{ (object.email_from if not object.customer_id else "") }}', 'email_from': '{{ (object.user_id.email_formatted or user.email_formatted) }}', + 'mail_server_id': cls.mail_server_domain.id, 'model_id': cls.env['ir.model']._get('mail.test.ticket').id, - 'mail_server_id': cls.mail_server.id, - 'auto_delete': True, + 'reply_to': '{{ ctx.get("custom_reply_to") or "info@test.example.com" }}', }) def _get_web_context(self, records, add_web=True, **values): @@ -107,15 +104,28 @@ class TestComposerForm(TestMailComposer): @users('employee') def test_mail_composer_comment(self): - composer_form = Form(self.env['mail.compose.message'].with_context(self._get_web_context(self.test_record, add_web=True))) + composer_form = Form(self.env['mail.compose.message'].with_context( + self._get_web_context(self.test_record, add_web=True) + )) + # auto_delete not displayed currently in view + # self.assertFalse(composer_form.auto_delete) + # self.assertFalse(composer_form.auto_delete_message) + # author_id not displayed currently in view + # self.assertEqual(composer_form.author_id, self.env.user.partner_id) + self.assertFalse(composer_form.body) + self.assertEqual(composer_form.composition_mode, 'comment') + self.assertEqual(composer_form.email_from, self.env.user.email_formatted) + self.assertFalse(composer_form.mail_server_id) + self.assertEqual(composer_form.model, self.test_record._name) + self.assertFalse(composer_form.partner_ids) + # record name not displayed currently in view + # self.assertEqual(composer_form.record_name, self.test_record.name, 'MailComposer: comment mode should compute record name') + self.assertFalse(composer_form.reply_to) + self.assertFalse(composer_form.reply_to_force_new) + self.assertEqual(composer_form.res_id, self.test_record.id) self.assertEqual( composer_form.subject, 'Re: %s' % self.test_record.name, 'MailComposer: comment mode should have default subject Re: record_name') - # record name not displayed currently in view - # self.assertEqual(composer_form.record_name, self.test_record.name, 'MailComposer: comment mode should compute record name') - self.assertFalse(composer_form.reply_to_force_new) - self.assertEqual(composer_form.composition_mode, 'comment') - self.assertEqual(composer_form.model, self.test_record._name) @users('employee') def test_mail_composer_comment_attachments(self): @@ -155,7 +165,7 @@ class TestComposerForm(TestMailComposer): report_attachments = [att for att in composer_form.attachment_ids if att not in template_1_attachments] self.assertEqual(len(report_attachments), 1) tpl_attachments = composer_form.attachment_ids[:] - report_attachments[0] - self.assertEqual(tpl_attachments, self.env['ir.attachment']) + self.assertFalse(tpl_attachments) # change back to template 1 composer_form.template_id = template_1 @@ -169,29 +179,77 @@ class TestComposerForm(TestMailComposer): composer_form.template_id = self.env['mail.template'] self.assertEqual(len(composer_form.attachment_ids), 0) + @users('employee') + def test_mail_composer_comment_wtpl(self): + composer_form = Form(self.env['mail.compose.message'].with_context( + self._get_web_context(self.test_record, add_web=True, default_template_id=self.template.id) + )) + # auto_delete not displayed currently in view + # self.assertTrue(composer_form.auto_delete) + # self.assertFalse(composer_form.auto_delete_message) + # author_id not displayed currently in view + # self.assertEqual(composer_form.author_id, self.env.user.partner_id) + self.assertEqual(composer_form.body, '

TemplateBody %s

' % self.test_record.name) + self.assertEqual(composer_form.composition_mode, 'comment') + self.assertEqual(composer_form.email_from, self.user_employee_2.email_formatted) + self.assertEqual(composer_form.mail_server_id, self.mail_server_domain) + self.assertEqual(composer_form.model, self.test_record._name) + self.assertEqual(composer_form.partner_ids[:], self.partner_1) + # record name not displayed currently in view + # self.assertEqual(composer_form.record_name, self.test_record.name, 'MailComposer: comment mode should compute record name') + self.assertEqual(composer_form.reply_to, 'info@test.example.com') + self.assertFalse(composer_form.reply_to_force_new) + self.assertEqual(composer_form.res_id, self.test_record.id) + self.assertEqual(composer_form.subject, 'TemplateSubject %s' % self.test_record.name) + @users('employee') def test_mail_composer_mass(self): - composer_form = Form(self.env['mail.compose.message'].with_context(self._get_web_context(self.test_records, add_web=True))) - self.assertFalse(composer_form.subject, 'MailComposer: mass mode should have void default subject if no template') + composer_form = Form(self.env['mail.compose.message'].with_context( + self._get_web_context(self.test_records, add_web=True) + )) + # auto_delete not displayed currently in view + # self.assertFalse(composer_form.auto_delete) + # self.assertFalse(composer_form.auto_delete_message) + # author_id not displayed currently in view + # self.assertEqual(composer_form.author_id, self.env.user.partner_id) + self.assertFalse(composer_form.body) + self.assertEqual(composer_form.composition_mode, 'mass_mail') + self.assertEqual(composer_form.email_from, self.env.user.email_formatted) + self.assertFalse(composer_form.mail_server_id) + self.assertEqual(composer_form.model, self.test_records._name) # record name not displayed currently in view # self.assertFalse(composer_form.record_name, 'MailComposer: mass mode should have void record name') + self.assertFalse(composer_form.reply_to) self.assertFalse(composer_form.reply_to_force_new) - self.assertEqual(composer_form.composition_mode, 'mass_mail') - self.assertEqual(composer_form.model, self.test_records._name) + self.assertEqual(composer_form.res_id, self.test_records[0].id, + 'MailComposer: even in mass mode web active_id presence may add a res_id') + self.assertFalse(composer_form.subject, 'MailComposer: mass mode should have void default subject if no template') @users('employee') def test_mail_composer_mass_wtpl(self): - ctx = self._get_web_context(self.test_records, add_web=True, default_template_id=self.template.id) - composer_form = Form(self.env['mail.compose.message'].with_context(ctx)) - self.assertEqual(composer_form.subject, self.template.subject, - 'MailComposer: mass mode should have template raw subject if template') + 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) + )) + # auto_delete not displayed currently in view + # self.assertTrue(composer_form.auto_delete) + # self.assertFalse(composer_form.auto_delete_message) + # author_id not displayed currently in view + # 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.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.assertEqual(composer_form.mail_server_id, self.mail_server_domain) + self.assertEqual(composer_form.model, self.test_records._name) # record name not displayed currently in view # 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.assertEqual(composer_form.composition_mode, 'mass_mail') - self.assertEqual(composer_form.model, self.test_records._name) + self.assertEqual(composer_form.res_id, self.test_records[0].id, + 'MailComposer: even in mass mode web active_id presence may add a res_id') + self.assertEqual(composer_form.subject, self.template.subject, + 'MailComposer: mass mode should have template raw subject if template') @tagged('mail_composer') @@ -293,6 +351,10 @@ class TestComposerInternals(TestMailComposer): self.assertEqual(composer.subject, 'My amazing subject') self.assertEqual(composer.body, '

Test Body

') self.assertEqual(composer.mail_server_id.id, False) + if composition_mode == 'comment': + self.assertEqual(composer.record_name, self.test_record.name) + else: + self.assertFalse(composer.record_name) # changing template should update its content composer.write({'template_id': self.template.id}) @@ -304,10 +366,12 @@ class TestComposerInternals(TestMailComposer): self.assertEqual(composer.subject, 'TemplateSubject %s' % self.test_record.name) self.assertEqual(composer.body, '

TemplateBody %s

' % self.test_record.name) self.assertEqual(composer.mail_server_id, self.template.mail_server_id) + self.assertEqual(composer.record_name, self.test_record.name) else: self.assertEqual(composer.subject, self.template.subject) self.assertEqual(composer.body, self.template.body_html) self.assertEqual(composer.mail_server_id, self.template.mail_server_id) + self.assertFalse(composer.record_name) # manual values is kept over template composer.write({'subject': 'Back to my amazing subject'}) @@ -321,17 +385,19 @@ class TestComposerInternals(TestMailComposer): # values are reset if composition_mode == 'comment': self.assertEqual(composer.subject, 'Re: %s' % self.test_record.name) - self.assertEqual(composer.body, '') + self.assertFalse(composer.body) # TDE FIXME: server id is kept, not sure why # self.assertFalse(composer.mail_server_id.id) self.assertEqual(composer.mail_server_id, self.template.mail_server_id) + self.assertEqual(composer.record_name, self.test_record.name) else: # values are reset TDE FIXME: strange for subject self.assertEqual(composer.subject, 'Back to my amazing subject') - self.assertEqual(composer.body, '') + self.assertFalse(composer.body) # TDE FIXME: server id is kept, not sure why # self.assertFalse(composer.mail_server_id.id) self.assertEqual(composer.mail_server_id, self.template.mail_server_id) + self.assertFalse(composer.record_name) # 2. check with default ctx['default_template_id'] = self.template.id @@ -346,10 +412,12 @@ class TestComposerInternals(TestMailComposer): self.assertEqual(composer.subject, 'TemplateSubject %s' % self.test_record.name) self.assertEqual(composer.body, '

TemplateBody %s

' % self.test_record.name) self.assertEqual(composer.mail_server_id, self.template.mail_server_id) + self.assertEqual(composer.record_name, self.test_record.name) else: self.assertEqual(composer.subject, self.template.subject) self.assertEqual(composer.body, self.template.body_html) self.assertEqual(composer.mail_server_id, self.template.mail_server_id) + self.assertFalse(composer.record_name) # 3. check at create ctx.pop('default_template_id') @@ -364,10 +432,12 @@ class TestComposerInternals(TestMailComposer): self.assertEqual(composer.subject, 'TemplateSubject %s' % self.test_record.name) self.assertEqual(composer.body, '

TemplateBody %s

' % self.test_record.name) self.assertEqual(composer.mail_server_id, self.template.mail_server_id) + self.assertEqual(composer.record_name, self.test_record.name) else: self.assertEqual(composer.subject, self.template.subject) self.assertEqual(composer.body, self.template.body_html) self.assertEqual(composer.mail_server_id, self.template.mail_server_id) + self.assertFalse(composer.record_name) # 4. template + user input ctx['default_template_id'] = self.template.id @@ -375,15 +445,155 @@ class TestComposerInternals(TestMailComposer): 'subject': 'My amazing subject', 'body': '

Test Body

', 'mail_server_id': False, + 'record_name': 'CustomName', }) # creation values are taken self.assertEqual(composer.subject, 'My amazing subject') self.assertEqual(composer.body, '

Test Body

') self.assertEqual(composer.mail_server_id.id, False) + self.assertEqual(composer.record_name, 'CustomName') @users('employee') - @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail') + @mute_logger('odoo.models.unlink') + def test_mail_composer_recipients(self): + """ Test content management (partner_ids, reply_to) in both comment and + mass mailing mode. Template update is also tested. Add some tests for + partner creation based on unknown emails as this is part of the process. """ + base_recipients = self.partner_1 + self.partner_2 + self.template.write({ + 'email_cc': 'test.cc.1@test.example.com, test.cc.2@test.example.com' + }) + + for composition_mode in ['comment', 'mass_mail']: + self.assertFalse( + self.env['res.partner'].search([ + ('email_normalized', 'in', ['test.cc.1@test.example.com', + 'test.cc.2@test.example.com']) + ]) + ) + if composition_mode == 'comment': + ctx = self._get_web_context(self.test_record, add_web=False) + else: + ctx = self._get_web_context(self.test_records, add_web=False) + + # 1. check without template + template update + composer = self.env['mail.compose.message'].with_context(ctx).create({ + 'body': '

Test Body

', + 'partner_ids': base_recipients.ids, + 'reply_to': False, + 'subject': 'My amazing subject', + }) + + # creation values are taken + self.assertEqual(composer.partner_ids, base_recipients) + self.assertFalse(composer.reply_to) + self.assertFalse(composer.reply_to_force_new) + self.assertEqual(composer.reply_to_mode, 'update') + + # changing template should update its content + composer.write({'template_id': self.template.id}) + # currently onchange necessary + composer._onchange_template_id_wrapper() + new_partners = self.env['res.partner'].search( + [('email_normalized', 'in', ['test.cc.1@test.example.com', + 'test.cc.2@test.example.com']) + ] + ) + + # values come from template + if composition_mode == 'comment': + self.assertEqual(len(new_partners), 2) + self.assertEqual(composer.partner_ids, self.partner_1 + new_partners, 'Template took customer_id as set on record') + self.assertEqual(composer.reply_to, 'info@test.example.com', 'Template was rendered') + self.assertFalse(composer.reply_to_force_new) # should not change in comment mode + else: + self.assertEqual(len(new_partners), 0) + self.assertEqual(composer.partner_ids, base_recipients, 'Mass mode: kept original values') + self.assertEqual(composer.reply_to, self.template.reply_to, 'Mass mode: raw template value') + self.assertFalse(composer.reply_to_force_new) # should probably become True, not supported currently + + # manual values is kept over template + composer.write({'partner_ids': [(5, 0), (4, self.partner_admin.id)]}) + self.assertEqual(composer.partner_ids, self.partner_admin) + + # reset template should reset values + composer.write({'template_id': False}) + # currently onchange necessary + composer._onchange_template_id_wrapper() + + # values are kepts, not sure why + if composition_mode == 'comment': + self.assertEqual(composer.partner_ids, self.partner_admin, 'Values are kept, not sure why') + self.assertEqual(composer.reply_to, 'info@test.example.com', 'Values are kept') + self.assertFalse(composer.reply_to_force_new) + else: + self.assertEqual(composer.partner_ids, self.partner_admin, 'Mass mode: kept current value') + self.assertEqual(composer.reply_to, '{{ ctx.get("custom_reply_to") or "info@test.example.com" }}', 'Mass mode: kept current value') + self.assertFalse(composer.reply_to_force_new) + + # 2. check with default + ctx['default_template_id'] = self.template.id + composer = self.env['mail.compose.message'].with_context(ctx).create({ + 'template_id': self.template.id, + }) + # currently onchange necessary + composer._onchange_template_id_wrapper() + + # values come from template + if composition_mode == 'comment': + self.assertEqual(composer.partner_ids, self.partner_1 + new_partners) + else: + self.assertFalse(composer.partner_ids) + if composition_mode == 'comment': + self.assertEqual(composer.reply_to, "info@test.example.com") + else: + self.assertEqual(composer.reply_to, self.template.reply_to) + self.assertFalse(composer.reply_to_force_new) # note: this should be updated with reply-to + self.assertEqual(composer.reply_to_mode, 'update') # note: this should be updated with reply-to + + # 3. check at create + ctx.pop('default_template_id') + composer = self.env['mail.compose.message'].with_context(ctx).create({ + 'template_id': self.template.id, + }) + # currently onchange necessary + composer._onchange_template_id_wrapper() + + # values come from template + if composition_mode == 'comment': + self.assertEqual(composer.partner_ids, self.partner_1 + new_partners) + else: + self.assertFalse(composer.partner_ids) + if composition_mode == 'comment': + self.assertEqual(composer.reply_to, "info@test.example.com") + else: + self.assertEqual(composer.reply_to, self.template.reply_to) + self.assertFalse(composer.reply_to_force_new) + self.assertEqual(composer.reply_to_mode, 'update') + + # 4. template + user input + ctx['default_template_id'] = self.template.id + composer = self.env['mail.compose.message'].with_context(ctx).create({ + 'body': '

Test Body

', + 'partner_ids': base_recipients.ids, + 'subject': 'My amazing subject', + 'reply_to': False, + }) + + # creation values are taken + self.assertEqual(composer.partner_ids, base_recipients) + self.assertFalse(composer.reply_to) + self.assertFalse(composer.reply_to_force_new) + self.assertEqual(composer.reply_to_mode, 'update') + + self.env['res.partner'].search([ + ('email_normalized', 'in', ['test.cc.1@test.example.com', + 'test.cc.2@test.example.com']) + ]).unlink() + + @users('employee') + @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') def test_mail_composer_parent(self): """ Test specific management in comment mode when having parent_id set: record_name, subject, parent's partners. """ @@ -396,11 +606,13 @@ class TestComposerInternals(TestMailComposer): }) # creation values taken from parent - self.assertEqual(composer.subject, 'Re: %s' % self.test_record.name) self.assertEqual(composer.body, '

Test Body

') self.assertEqual(composer.partner_ids, self.partner_1 + self.partner_2) + self.assertEqual(composer.record_name, self.test_record.name) + self.assertEqual(composer.subject, 'Re: %s' % self.test_record.name) @users('user_rendering_restricted') + @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') def test_mail_composer_rights_attachments(self): """ Ensure a user without write access to a template can send an email""" template_1 = self.template.copy({ @@ -436,6 +648,7 @@ class TestComposerInternals(TestMailComposer): sorted(self.test_record.message_ids[0].attachment_ids.mapped('name')), sorted(template_1_attachment_name)) + @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') def test_mail_composer_rights_portal(self): portal_user = self._create_portal_user() # give read access to the record to portal (for check access rule) @@ -489,7 +702,7 @@ class TestComposerResultsComment(TestMailComposer): notification and emails generated during this process. """ @users('employee') - @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail') + @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') def test_mail_composer_notifications_delete(self): """ Notifications are correctly deleted once sent """ composer = self.env['mail.compose.message'].with_context( @@ -506,9 +719,29 @@ class TestComposerResultsComment(TestMailComposer): self.assertEqual(message.notified_partner_ids, self.partner_employee_2 + self.partner_1 + self.partner_2) # global outgoing - self.assertEqual(len(self._new_mails), 2, 'Should have created 2 mail.mail (1 for users, 1 for customers)') self.assertEqual(len(self._mails), 3, 'Should have sent an email each recipient') - self.assertEqual(self._new_mails.exists(), self.env['mail.mail'], 'Should have deleted mail.mail records') + self.assertEqual(len(self._new_mails), 2, 'Should have created 2 mail.mail (1 for users, 1 for customers)') + self.assertFalse(self._new_mails.exists(), 'Should have deleted mail.mail records') + + # Check ``auto_delete`` field usage (note: currently not correctly managed) + composer = self.env['mail.compose.message'].with_context( + self._get_web_context(self.test_record), + ).create({ + 'auto_delete': False, + 'body': '

Test Body

', + 'partner_ids': [(4, self.partner_1.id), (4, self.partner_2.id)] + }) + with self.mock_mail_gateway(mail_unlink_sent=True): + composer._action_send_mail() + + # notifications + message = self.test_record.message_ids[0] + self.assertEqual(message.notified_partner_ids, self.partner_employee_2 + self.partner_1 + self.partner_2) + + # global outgoing + self.assertEqual(len(self._mails), 3, 'Should have sent an email each recipient') + self.assertEqual(len(self._new_mails), 2, 'Should have created 2 mail.mail (1 for users, 1 for customers)') + self.assertEqual(len(self._new_mails.exists()), 0, 'To fix: does not respect auto_delete') # ensure ``mail_auto_delete`` context key allow to override this behavior composer = self.env['mail.compose.message'].with_context( @@ -526,12 +759,12 @@ class TestComposerResultsComment(TestMailComposer): self.assertEqual(message.notified_partner_ids, self.partner_employee_2 + self.partner_1 + self.partner_2) # global outgoing - self.assertEqual(len(self._new_mails), 2, 'Should have created 2 mail.mail (1 for users, 1 for customers)') self.assertEqual(len(self._mails), 3, 'Should have sent an email each recipient') + self.assertEqual(len(self._new_mails), 2, 'Should have created 2 mail.mail (1 for users, 1 for customers)') self.assertEqual(len(self._new_mails.exists()), 2, 'Should not have deleted mail.mail records') @users('employee') - @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail') + @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') def test_mail_composer_recipients(self): """ Test partner_ids given to composer are given to the final message. """ composer = self.env['mail.compose.message'].with_context( @@ -543,8 +776,8 @@ class TestComposerResultsComment(TestMailComposer): composer._action_send_mail() message = self.test_record.message_ids[0] - self.assertEqual(message.body, '

Test Body

') self.assertEqual(message.author_id, self.user_employee.partner_id) + self.assertEqual(message.body, '

Test Body

') self.assertEqual(message.subject, 'Re: %s' % self.test_record.name) self.assertEqual(message.subtype_id, self.env.ref('mail.mt_comment')) self.assertEqual(message.partner_ids, self.partner_1 | self.partner_2) @@ -609,6 +842,7 @@ class TestComposerResultsComment(TestMailComposer): email_values={ 'body_content': 'TemplateBody %s' % self.test_record.name, 'email_from': self.test_record.user_id.email_formatted, # set by template + 'mail_server_id': self.mail_server_domain, 'subject': 'TemplateSubject %s' % self.test_record.name, 'attachments_info': [ {'name': 'AttFileName_00.txt', 'raw': b'AttContent_00', 'type': 'text/plain'}, @@ -624,6 +858,7 @@ class TestComposerResultsComment(TestMailComposer): email_values={ 'body_content': 'TemplateBody %s' % self.test_record.name, 'email_from': self.test_record.user_id.email_formatted, # set by template + 'mail_server_id': self.mail_server_domain, 'subject': 'TemplateSubject %s' % self.test_record.name, 'attachments_info': [ {'name': 'AttFileName_00.txt', 'raw': b'AttContent_00', 'type': 'text/plain'}, @@ -658,10 +893,73 @@ class TestComposerResultsMass(TestMailComposer): 'groups_id': [(4, cls.env.ref('base.group_partner_manager').id)], }) + + @users('employee') + @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') + def test_mail_composer_delete(self): + """ Check mail / msg delete support """ + # ensure initial data + self.assertTrue(self.template.auto_delete) + self.assertEqual(self.test_records.user_id, self.user_employee_2) + self.assertEqual(self.test_records.message_partner_ids, self.partner_employee_2) + + 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) + )) + composer = composer_form.save() + with self.mock_mail_gateway(mail_unlink_sent=True), self.mock_mail_app(): + composer._action_send_mail() + + self.assertEqual(len(self._mails), 2, 'Should have sent 1 email per record') + self.assertEqual(len(self._new_mails), 2, 'Should have created 1 mail.mail per record') + self.assertFalse(self._new_mails.exists(), 'Should have deleted mail.mail records') + self.assertEqual(len(self._new_msgs), 2, 'Should have created 1 mail.mail per record') + self.assertEqual(self._new_msgs.exists(), self._new_msgs, 'Should not have deleted mail.message records') + + # force composer auto_delete field + 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) + )) + composer = composer_form.save() + composer.auto_delete = False + with self.mock_mail_gateway(mail_unlink_sent=True), self.mock_mail_app(): + composer._action_send_mail() + + self.assertEqual(len(self._mails), 2, 'Should have sent 1 email per record') + self.assertEqual(len(self._new_mails), 2, 'Should have created 1 mail.mail per record') + # self.assertEqual(self._new_mails.exists(), self._new_mails, 'Should not have deleted mail.mail records') + self.assertFalse(self._new_mails.exists(), 'Template is forced over composer value, which is not correct') + self.assertEqual(len(self._new_msgs), 2, 'Should have created 1 mail.mail per record') + self.assertEqual(self._new_msgs.exists(), self._new_msgs, 'Should not have deleted mail.message records') + + # check composer auto_delete_message + 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) + )) + composer = composer_form.save() + composer.auto_delete_message = True + with self.mock_mail_gateway(mail_unlink_sent=True), self.mock_mail_app(): + composer._action_send_mail() + + # global outgoing + self.assertEqual(len(self._mails), 2, 'Should have sent 1 email per record') + self.assertEqual(len(self._new_mails), 2, 'Should have created 1 mail.mail per record') + self.assertFalse(self._new_mails.exists(), 'Should have deleted mail.mail records') + self.assertEqual(len(self._new_msgs), 2, 'Should have created 1 mail.mail per record') + self.assertFalse(self._new_msgs.exists(), 'Should have deleted mail.message records') + @users('employee') @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_mail_composer_wtpl(self): self.template.auto_delete = False # keep sent emails to check content + + # ensure initial data + self.assertEqual(self.test_records.user_id, self.user_employee_2) + self.assertEqual(self.test_records.message_partner_ids, self.partner_employee_2) + 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) @@ -681,15 +979,18 @@ class TestComposerResultsMass(TestMailComposer): # template is sent directly using customer field, meaning we have recipients self.assertMailMail(record.customer_id, 'sent', mail_message=message, - author=self.partner_employee) + author=self.partner_employee, + email_values={ + 'email_from': self.partner_employee_2.email_formatted, + }) # message content self.assertEqual(message.subject, 'TemplateSubject %s' % record.name) self.assertEqual(message.body, '

TemplateBody %s

' % record.name) self.assertEqual(message.author_id, self.user_employee.partner_id) # post-related fields are void - self.assertEqual(message.subtype_id, self.env['mail.message.subtype']) - self.assertEqual(message.partner_ids, self.env['res.partner']) + self.assertFalse(message.subtype_id) + self.assertFalse(message.partner_ids) @users('employee') @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') @@ -714,8 +1015,8 @@ class TestComposerResultsMass(TestMailComposer): self.assertEqual(len(attachs), 2) # ensure initial data - self.assertEqual(self.test_records.user_id, self.env['res.users']) - self.assertEqual(self.test_records.message_partner_ids, self.env['res.partner']) + self.assertEqual(self.test_records.user_id, self.user_employee_2) + self.assertEqual(self.test_records.message_partner_ids, self.partner_employee_2) # launch composer in mass mode composer_form = Form(self.env['mail.compose.message'].with_context( @@ -754,72 +1055,17 @@ class TestComposerResultsMass(TestMailComposer): author=self.partner_employee, email_values={ 'body_content': 'TemplateBody %s' % record.name, + 'email_from': self.partner_employee_2.email_formatted, + 'mail_server_id': self.mail_server_global.id, 'subject': 'TemplateSubject %s' % record.name, - # 'attachments': [ - # ('00.txt', b'Att00', 'text/plain'), - # ('01.txt', b'Att01', 'text/plain'), - # ('report.test_mail.mail_test_ticket_test_template.html', b'My second attachment', 'text/plain') - # ] + 'attachments_info': [ + {'name': 'AttFileName_00.txt', 'raw': b'AttContent_00', 'type': 'text/plain'}, + {'name': 'AttFileName_01.txt', 'raw': b'AttContent_01', 'type': 'text/plain'}, + {'name': 'TestReport for %s.html' % record.name, 'type': 'text/plain'}, + ] } ) - @users('employee') - @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') - def test_mail_composer_wtpl_delete(self): - self.template.auto_delete = True - 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) - )) - composer = composer_form.save() - with self.mock_mail_gateway(mail_unlink_sent=True): - composer._action_send_mail() - - # global outgoing - self.assertEqual(len(self._new_mails), 2, 'Should have created 1 mail.mail per record') - self.assertEqual(len(self._mails), 2, 'Should have sent 1 email per record') - self.assertEqual(self._new_mails.exists(), self.env['mail.mail'], 'Should have deleted mail.mail records') - - for record in self.test_records: - # message copy is kept - message = record.message_ids[0] - - # template is sent directly using customer field - self.assertSentEmail(self.partner_employee, record.customer_id) - - # message content - self.assertEqual(message.subject, 'TemplateSubject %s' % record.name) - self.assertEqual(message.body, '

TemplateBody %s

' % record.name) - self.assertEqual(message.author_id, self.user_employee.partner_id) - # post-related fields are void - self.assertEqual(message.subtype_id, self.env['mail.message.subtype']) - self.assertEqual(message.partner_ids, self.env['res.partner']) - - @users('employee') - @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') - def test_mail_composer_wtpl_delete_notif(self): - self.template.auto_delete = True - 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, - default_auto_delete_message=True) - )) - composer = composer_form.save() - with self.mock_mail_gateway(mail_unlink_sent=True): - composer._action_send_mail() - - # global outgoing - self.assertEqual(len(self._new_mails), 2, 'Should have created 1 mail.mail per record') - self.assertEqual(len(self._mails), 2, 'Should have sent 1 email per record') - self.assertEqual(self._new_mails.exists(), self.env['mail.mail'], 'Should have deleted mail.mail records') - - for record in self.test_records: - # message copy is unlinked - self.assertEqual(record.message_ids, self.env['mail.message'], 'Should have deleted mail.message records') - - # template is sent directly using customer field - self.assertSentEmail(self.partner_employee, record.customer_id) - @users('employee') @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_mail_composer_wtpl_recipients(self): @@ -843,7 +1089,8 @@ class TestComposerResultsMass(TestMailComposer): for record in self.test_records: # template is sent directly using customer field - self.assertSentEmail(self.partner_employee, record.customer_id) + self.assertSentEmail(self.partner_employee_2.email_formatted, record.customer_id, + author_id=self.partner_employee) # 2: active_domain not taken into account if use_active_domain is False composer_form = Form(self.env['mail.compose.message'].with_context( diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py index d02a2ef0006..43721eef50e 100644 --- a/addons/test_mail/tests/test_performance.py +++ b/addons/test_mail/tests/test_performance.py @@ -5,7 +5,7 @@ import base64 from odoo.addons.base.tests.common import TransactionCaseWithUserDemo from odoo.addons.mail.tests.common import MailCommon -from odoo.tests.common import users, warmup +from odoo.tests.common import users, warmup, Form from odoo.tests import tagged from odoo.tools import mute_logger, formataddr @@ -27,6 +27,10 @@ class BaseMailPerformance(MailCommon, TransactionCaseWithUserDemo): 'mobile': '0456123456', }) + cls.test_attachments_vals = cls._generate_attachments_data( + cls, 3, res_model='mail.compose.message', res_id=0 + ) + def setUp(self): super(BaseMailPerformance, self).setUp() # patch registry to simulate a ready environment @@ -206,6 +210,10 @@ class TestMailAPIPerformance(BaseMailPerformance): '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') @@ -231,9 +239,9 @@ class TestMailAPIPerformance(BaseMailPerformance): 'res_id': record.id, 'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id, }) - #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_feedback - category = activity.activity_type_id.category + # 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_feedback + _category = activity.activity_type_id.category with self.assertQueryCount(__system__=17, employee=19): activity.action_feedback(feedback='Zizisse Done !') @@ -246,9 +254,9 @@ class TestMailAPIPerformance(BaseMailPerformance): with self.assertQueryCount(__system__=8, employee=8): 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 - category = activity.activity_type_id.category + # 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 + _category = activity.activity_type_id.category record.write({'name': 'Dupe write'}) @@ -259,7 +267,38 @@ class TestMailAPIPerformance(BaseMailPerformance): @users('__system__', 'employee') @warmup - @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') + @mute_logger('odoo.models.unlink') + def test_adv_activity_mixin_w_attachments(self): + record = self.env['mail.test.activity'].create({'name': 'Test'}) + + attachments = self.env['ir.attachment'].create([ + dict(values, + res_model='mail.activity', + res_id=0) + for values in self.test_attachments_vals + ]) + + with self.assertQueryCount(__system__=8, employee=8): + 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 + _category = activity.activity_type_id.category + + record.write({'name': 'Dupe write'}) + + with self.assertQueryCount(__system__=20, employee=24): + record.action_close('Dupe feedback', attachment_ids=attachments.ids) + + # notifications + message = record.message_ids[0] + self.assertEqual( + set(message.attachment_ids.mapped('name')), + set(['AttFileName_00.txt', 'AttFileName_01.txt', 'AttFileName_02.txt']) + ) + + @users('__system__', 'employee') + @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) @@ -279,7 +318,59 @@ class TestMailAPIPerformance(BaseMailPerformance): @users('__system__', 'employee') @warmup - @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail') + @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) + 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): + composer = self.env['mail.compose.message'].with_context({ + 'default_composition_mode': 'comment', + 'default_model': test_record._name, + 'default_res_id': test_record.id, + }).create({ + 'attachment_ids': attachments.ids, + 'body': '

Test Body

', + 'partner_ids': [(4, customer.id)], + }) + + with self.assertQueryCount(__system__=36, employee=44): + composer._action_send_mail() + + @users('__system__', 'employee') + @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) + 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__=15, employee=15): + composer_form = Form( + self.env['mail.compose.message'].with_context({ + 'default_composition_mode': 'comment', + 'default_model': test_record._name, + 'default_res_id': test_record.id, + }) + ) + composer_form.body = '

Test Body

' + composer_form.partner_ids.add(customer) + for attachment in attachments: + composer_form.attachment_ids.add(attachment) + composer = composer_form.save() + + with self.assertQueryCount(__system__=44, employee=52): + composer._action_send_mail() + + # notifications + message = test_record.message_ids[0] + 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_nodelete(self): self._create_test_records() test_record = self.env['mail.test.ticket'].browse(self.test_record_full.id) @@ -300,11 +391,14 @@ class TestMailAPIPerformance(BaseMailPerformance): @users('__system__', 'employee') @warmup - @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') + @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) + with self.assertQueryCount(__system__=11, employee=12): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', @@ -317,9 +411,111 @@ class TestMailAPIPerformance(BaseMailPerformance): with self.assertQueryCount(__system__=33, employee=39): composer._action_send_mail() + # notifications + message = test_record.message_ids[0] + self.assertFalse(message.attachment_ids) + # 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') + @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 = 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__=12, employee=13): + composer = self.env['mail.compose.message'].with_context({ + 'default_composition_mode': 'comment', + 'default_model': test_record._name, + 'default_res_id': test_record.id, + 'default_template_id': test_template.id, + }).create({}) + composer._onchange_template_id_wrapper() + + with self.assertQueryCount(__system__=41, employee=52): + composer._action_send_mail() + + # notifications + message = test_record.message_ids[0] + self.assertEqual( + set(message.attachment_ids.mapped('name')), + set(['AttFileName_00.txt', 'AttFileName_01.txt', 'AttFileName_02.txt']) + ) + + # 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') + @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 = 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__=33, employee=33): + composer_form = Form( + self.env['mail.compose.message'].with_context({ + 'default_composition_mode': 'comment', + 'default_model': test_record._name, + 'default_res_id': test_record.id, + 'default_template_id': test_template.id, + }) + ) + composer = composer_form.save() + + with self.assertQueryCount(__system__=41, employee=47): + composer._action_send_mail() + + # notifications + new_partner = self.env['res.partner'].sudo().search([('email', '=', 'nopartner.test@example.com')]) + message = test_record.message_ids[0] + self.assertFalse(message.attachment_ids) + self.assertEqual(message.notified_partner_ids, customer + self.user_test.partner_id + new_partner) + + # remove created partner to ensure tests are the same each run + new_partner.unlink() + + @users('__system__', 'employee') + @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 = 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__=34, employee=34): + composer_form = Form( + self.env['mail.compose.message'].with_context({ + 'default_composition_mode': 'comment', + 'default_model': test_record._name, + 'default_res_id': test_record.id, + 'default_template_id': test_template.id, + }) + ) + composer = composer_form.save() + + with self.assertQueryCount(__system__=53, employee=70): + composer._action_send_mail() + + # notifications + new_partner = self.env['res.partner'].sudo().search([('email', '=', 'nopartner.test@example.com')]) + message = test_record.message_ids[0] + self.assertEqual( + set(message.attachment_ids.mapped('name')), + set(['AttFileName_00.txt', 'AttFileName_01.txt', 'AttFileName_02.txt']) + ) + self.assertEqual(message.notified_partner_ids, customer + self.user_test.partner_id + new_partner) + + # remove created partner to ensure tests are the same each run + new_partner.unlink() + @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') @users('__system__', 'employee') @warmup @@ -885,7 +1081,7 @@ class TestMailComplexPerformance(BaseMailPerformance): messages.flush() messages.invalidate_cache() - with self.assertQueryCount(employee=13): + with self.assertQueryCount(employee=13): # tm only: 12 res = messages.message_format() self.assertEqual(len(res), 6) @@ -897,7 +1093,7 @@ class TestMailHeavyPerformancePost(BaseMailPerformance): super(TestMailHeavyPerformancePost, self).setUp() # record - self.record = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({ + self.record_container = self.env['mail.test.container'].with_context(mail_create_nosubscribe=True).create({ 'name': 'Test record', 'customer_id': self.customer.id, 'alias_name': 'test-alias', @@ -921,7 +1117,7 @@ class TestMailHeavyPerformancePost(BaseMailPerformance): 'name': 'partner_follower', 'email': 'partner_follower@example.com', }) - self.record.message_subscribe([ + self.record_container.message_subscribe([ self.partner_follower.id, self.user_follower_inbox.partner_id.id, self.user_follower_email.partner_id.id @@ -946,45 +1142,38 @@ class TestMailHeavyPerformancePost(BaseMailPerformance): 'name': 'partner', 'email': 'partner@example.com', }) - self.vals = [{ - 'datas': base64.b64encode(bytes("attachement content %s" % i, 'utf-8')), - 'name': 'fileText_test%s.txt' % i, - 'mimetype': 'text/plain', - 'res_model': 'mail.compose.message', - 'res_id': 0, - } for i in range(3)] @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') @users('employee') @warmup def test_complete_message_post(self): # aims to cover as much features of message_post as possible - partner_ids = [self.user_inbox.partner_id.id, self.user_email.partner_id.id, self.partner.id] - record = self.record.with_user(self.env.user) - attachements = [ # not linear on number of attachements + recipients = self.user_inbox.partner_id + self.user_email.partner_id + self.partner + record_container = self.record_container.with_user(self.env.user) + attachments_vals = [ # not linear on number of attachments_vals ('attach tuple 1', "attachement tupple content 1"), ('attach tuple 2', "attachement tupple content 2", {'cid': 'cid1'}), ('attach tuple 3', "attachement tupple content 3", {'cid': 'cid2'}), ] - self.attachements = self.env['ir.attachment'].with_user(self.env.user).create(self.vals) - attachement_ids = self.attachements.ids + attachments = self.env['ir.attachment'].with_user(self.env.user).create(self.test_attachments_vals) with self.assertQueryCount(employee=68): self.cr.sql_log = self.warm and self.cr.sql_log_count - record.with_context({}).message_post( + record_container.with_context({}).message_post( body='

Test body

', subject='Test Subject', message_type='notification', subtype_xmlid=None, - partner_ids=partner_ids, + partner_ids=recipients.ids, parent_id=False, - attachments=attachements, - attachment_ids=attachement_ids, + attachments=attachments_vals, + attachment_ids=attachments.ids, email_add_signature=True, model_description=False, mail_auto_delete=True ) self.cr.sql_log = False - self.assertTrue(record.message_ids[0].body.startswith('

Test body