Files
odoo_source/addons/mail/tests/test_mail_composer.py
T
Sébastien Theys 5455bfcfdc [FIX] mail: fix test failing at "Write something in composer"
The issue is not easy to reproduce, so the fix is not a guaranteed one.

Estimation: the click on the "send message" buttons happens too early,
and it is either doing nothing, or being immediately reset by another
action that happens at page load.

Adding a little bit of extra delay (in particular waiting for messages
to be loaded) might resolve the issue.

Also back-port code allowing to use contains in tours.

runbot-27847

closes odoo/odoo#144435

X-original-commit: 3b261b6856e935f8fe9d4e23cfddc09df8ff7fdf
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-12-04 17:47:31 +00:00

289 lines
12 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.mail.tests.common import MailCommon
from odoo.exceptions import AccessError
from odoo.tests import Form, HttpCase, tagged, users
from odoo.tools import mute_logger
@tagged('mail_composer')
class TestMailComposer(MailCommon):
@classmethod
def setUpClass(cls):
super(TestMailComposer, cls).setUpClass()
cls.env['ir.config_parameter'].set_param('mail.restrict.template.rendering', True)
cls.user_employee.groups_id -= cls.env.ref('mail.group_mail_template_editor')
cls.test_record = cls.env['res.partner'].with_context(cls._test_context).create({
'name': 'Test',
})
cls.body_html = """<div>
<h1>Hello sir!</h1>
<p>Here! <a href="https://www.example.com">
<!--[if mso]>
<i style="letter-spacing: 25px; mso-font-width: -100%; mso-text-raise: 30pt;">&nbsp;</i>
<![endif]-->
A link for you! <!-- my favorite example -->
<!--[if mso]>
<i style="letter-spacing: 25px; mso-font-width: -100%;">&nbsp;</i>
<![endif]-->
</a> Make good use of it.</p>
</div>"""
cls.mail_template = cls.env['mail.template'].create({
'auto_delete': True,
'body_html': cls.body_html,
'lang': '{{ object.lang }}',
'model_id': cls.env['ir.model']._get_id('res.partner'),
'subject': 'MSO FTW',
'name': 'Test template with mso conditionals',
})
@tagged('mail_composer')
class TestMailComposerForm(TestMailComposer):
""" Test mail composer form view usage. """
@classmethod
def setUpClass(cls):
super(TestMailComposerForm, cls).setUpClass()
cls.other_company = cls.env['res.company'].create({'name': 'Other Company'})
cls.user_employee.write({
'groups_id': [(4, cls.env.ref('base.group_partner_manager').id)],
'company_ids': [(4, cls.other_company.id)]
})
cls.partner_private, cls.partner_private_2, cls.partner_classic = cls.env['res.partner'].create([
{
'email': 'private.customer@text.example.com',
'phone': '0032455112233',
'name': 'Private Customer',
'company_id': cls.other_company.id,
},
{
'email': 'private.customer.2@test.example.com',
'phone': '0032455445566',
'name': 'Private Customer 2',
'company_id': cls.other_company.id,
},
{
'email': 'not.private@test.example.com',
'phone': '0032455778899',
'name': 'Classic Customer',
'type': 'contact',
}
])
@mute_logger('odoo.addons.mail.models.mail_mail')
@users('employee')
def test_composer_default_recipients(self):
""" Test usage of a private partner in composer, as default value """
partner_classic = self.partner_classic.with_env(self.env)
test_record = self.test_record.with_env(self.env)
form = Form(self.env['mail.compose.message'].with_context({
'default_partner_ids': partner_classic.ids,
'default_model': test_record._name,
'default_res_ids': test_record.ids,
}))
form.body = '<p>Hello</p>'
self.assertEqual(
form.partner_ids.ids, partner_classic.ids,
'Default populates the field'
)
saved_form = form.save()
self.assertEqual(
saved_form.partner_ids, partner_classic,
'Default value is kept at save'
)
with self.mock_mail_gateway():
saved_form._action_send_mail()
message = self.test_record.message_ids[0]
self.assertEqual(message.body, '<p>Hello</p>')
self.assertEqual(message.partner_ids, partner_classic)
self.assertEqual(message.subject, f'{test_record.name}')
@mute_logger('odoo.addons.mail.models.mail_mail')
@users('employee')
def test_composer_default_recipients_private(self):
""" Test usage of a private partner in composer, as default value """
partner_private = self.partner_private.with_env(self.env)
partner_classic = self.partner_classic.with_env(self.env)
test_record = self.test_record.with_env(self.env)
form = Form(self.env['mail.compose.message'].with_context({
'default_partner_ids': (partner_private + partner_classic).ids,
'default_model': test_record._name,
'default_res_ids': test_record.ids,
}))
form.body = '<p>Hello</p>'
self.assertEqual(
sorted(form.partner_ids.ids),
sorted((partner_private + partner_classic).ids),
'Default populates the field'
)
saved_form = form.save()
self.assertEqual(
saved_form.partner_ids, partner_private + partner_classic,
'Default value is kept at save'
)
with self.mock_mail_gateway():
saved_form._action_send_mail()
message = self.test_record.message_ids[0]
self.assertEqual(message.body, '<p>Hello</p>')
self.assertEqual(message.partner_ids, partner_private + partner_classic)
self.assertEqual(message.subject, f'{test_record.name}')
@mute_logger('odoo.addons.base.models.ir_rule', 'odoo.addons.mail.models.mail_mail')
@users('employee')
def test_composer_default_recipients_private_norights(self):
""" Test usage of a private partner in composer when not having the
rights to see them, as default value """
self.user_employee.write({'company_ids': [
(3, self.other_company.id),
]})
with self.assertRaises(AccessError):
_name = self.partner_private.with_env(self.env).name
partner_classic = self.partner_classic.with_env(self.env)
test_record = self.test_record.with_env(self.env)
with self.assertRaises(AccessError):
_form = Form(self.env['mail.compose.message'].with_context({
'default_partner_ids': (self.partner_private + partner_classic).ids,
'default_model': test_record._name,
'default_res_ids': test_record.ids,
}))
@mute_logger('odoo.addons.mail.models.mail_mail')
@users('employee')
def test_composer_template_recipients_private(self):
""" Test usage of a private partner in composer, coming from template
value """
email_to_new = 'new.customer@test.example.com'
self.mail_template.write({
'email_to': f'{self.partner_private_2.email_formatted}, {email_to_new}',
'partner_to': f'{self.partner_private.id},{self.partner_classic.id}',
})
template = self.mail_template.with_env(self.env)
partner_private = self.partner_private.with_env(self.env)
partner_private_2 = self.partner_private_2.with_env(self.env)
partner_classic = self.partner_classic.with_env(self.env)
test_record = self.test_record.with_env(self.env)
form = Form(self.env['mail.compose.message'].with_context({
'default_model': test_record._name,
'default_res_ids': test_record.ids,
'default_template_id': template.id,
}))
# transformation from email_to into partner_ids: find or create
existing_partner = self.env['res.partner'].search(
[('email_normalized', '=', self.partner_private_2.email_normalized)]
)
self.assertEqual(existing_partner, partner_private_2, 'Should find existing private contact')
new_partner = self.env['res.partner'].search(
[('email_normalized', '=', email_to_new)]
)
self.assertEqual(new_partner.type, 'contact', 'Should create a new contact')
self.assertEqual(
sorted(form.partner_ids.ids),
sorted((partner_private + partner_classic + partner_private_2 + new_partner).ids),
'Template populates the field with both email_to and partner_to'
)
saved_form = form.save()
self.assertEqual(
saved_form.partner_ids, partner_private + partner_classic + partner_private_2 + new_partner,
'Template value is kept at save'
)
with self.mock_mail_gateway():
saved_form._action_send_mail()
message = self.test_record.message_ids[0]
self.assertIn('<h1>Hello sir!</h1>', message.body)
# self.assertEqual(message.partner_ids, partner_private + partner_classic + partner_private_2 + new_partner)
self.assertEqual(
message.partner_ids, partner_private + partner_classic + partner_private_2 + new_partner,
'Should not loosing unreadable partners'
)
self.assertEqual(message.subject, 'MSO FTW')
@tagged('mail_composer')
class TestMailComposerRendering(TestMailComposer):
""" Test rendering and support of various html tweaks in composer """
@users('employee')
def test_mail_mass_mode_template_with_mso(self):
mail_compose_message = self.env['mail.compose.message'].create({
'composition_mode': 'mass_mail',
'model': 'res.partner',
'template_id': self.mail_template.id,
'subject': 'MSO FTW',
})
values = mail_compose_message._prepare_mail_values(self.partner_employee.ids)
self.assertIn(
self.body_html,
values[self.partner_employee.id]['body_html'],
'We must preserve (mso) comments in email html'
)
@mute_logger('odoo.addons.mail.models.mail_mail')
@users('employee')
def test_mail_mass_mode_compose_with_mso(self):
composer = self.env['mail.compose.message'].with_context({
'default_model': self.test_record._name,
'default_composition_mode': 'mass_mail',
'active_ids': [self.test_record.id],
'active_model': self.test_record._name,
'active_id': self.test_record.id
}).create({
'body': self.body_html,
'partner_ids': [(4, self.partner_employee.id)],
'composition_mode': 'mass_mail',
})
with self.mock_mail_gateway(mail_unlink_sent=True):
composer._action_send_mail()
values = composer._prepare_mail_values(self.partner_employee.ids)
self.assertIn(
self.body_html,
values[self.partner_employee.id]['body_html'],
'We must preserve (mso) comments in email html'
)
@tagged("mail_composer", "-at_install", "post_install")
class TestMailComposerUI(MailCommon, HttpCase):
def test_mail_composer_test_tour(self):
self.env['mail.template'].create({
'auto_delete': True,
'lang': '{{ object.lang }}',
'model_id': self.env['ir.model']._get_id('res.partner'),
'name': 'Test template',
'partner_to': '{{ object.id }}',
})
self.user_employee.write({
'groups_id': [(4, self.env.ref('base.group_partner_manager').id)],
})
partner = self.env["res.partner"].create({"name": "Jane", "email": "jane@example.com"})
user = self.env["res.users"].create({"name": "Not A Demo User", "login": "nadu"})
with self.mock_mail_app():
self.start_tour(
f"/web#id={partner.id}&model=res.partner",
"mail/static/tests/tours/mail_composer_test_tour.js",
login=self.user_employee.login
)
message = self._new_msgs.filtered(lambda message: message.author_id == self.user_employee.partner_id)
self.assertEqual(len(message), 1)
self.assertIn(user.partner_id, message.partner_ids)