[IMP] mail: add tests for private partners in composer
Add tests showing current behavior of partner_ids fields on composer when
dealing with private partners. Some use cases are added as unit tests
* default_partner_ids: coming notably from suggested recipients;
* template usage adding a partner (e.g. partner_to);
* when not having the rights to see private partners, access error should
be raised;
* mail gateway when a private partner sends an email;
X-original-commit: 2153eec790b730761fe50d6bea5cd4bacedce97a
Part-of: odoo/odoo#109522
Co-authored-by: Robin Engels <roen@odoo.com>
This commit is contained in:
co-authored by
Robin Engels
parent
73b1aad8fb
commit
a45afdd830
@@ -2,7 +2,9 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.mail.tests.common import MailCommon
|
||||
from odoo.tests import tagged, users
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.tests import Form, tagged, users
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
@tagged('mail_composer')
|
||||
@@ -30,14 +32,199 @@ class TestMailComposer(MailCommon):
|
||||
</div>"""
|
||||
|
||||
cls.mail_template = cls.env['mail.template'].create({
|
||||
'name': 'Test template with mso conditionals',
|
||||
'subject': 'MSO FTW',
|
||||
'auto_delete': True,
|
||||
'body_html': cls.body_html,
|
||||
'lang': '{{ object.lang }}',
|
||||
'auto_delete': True,
|
||||
'model_id': cls.env.ref('base.model_res_partner').id,
|
||||
'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.user_employee.write({'groups_id': [
|
||||
(4, cls.env.ref('base.group_private_addresses').id),
|
||||
(4, cls.env.ref('base.group_partner_manager').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',
|
||||
'type': 'private',
|
||||
},
|
||||
{
|
||||
'email': 'private.customer.2@test.example.com',
|
||||
'phone': '0032455445566',
|
||||
'name': 'Private Customer 2',
|
||||
'type': 'private',
|
||||
},
|
||||
{
|
||||
'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_id': test_record.id,
|
||||
}))
|
||||
form.body = '<p>Hello</p>'
|
||||
self.assertEqual(
|
||||
form.partner_ids._get_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_id': test_record.id,
|
||||
}))
|
||||
form.body = '<p>Hello</p>'
|
||||
self.assertEqual(
|
||||
sorted(form.partner_ids._get_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,
|
||||
saved_form.partner_ids, partner_classic,
|
||||
'Default value is kept at save (FIXME: loosing private partner)'
|
||||
)
|
||||
|
||||
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.partner_ids, partner_classic,
|
||||
'FIXME: loosing private partner'
|
||||
)
|
||||
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({'groups_id': [
|
||||
(3, self.env.ref('base.group_private_addresses').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_id': test_record.id,
|
||||
}))
|
||||
|
||||
@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, comint 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_id': test_record.id,
|
||||
'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._get_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,
|
||||
saved_form.partner_ids, partner_classic + new_partner,
|
||||
'Template value is kept at save (FIXME: loosing private partner)'
|
||||
)
|
||||
|
||||
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_classic + new_partner,
|
||||
'FIXME: loosing private partner'
|
||||
)
|
||||
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({
|
||||
@@ -55,6 +242,7 @@ class TestMailComposer(MailCommon):
|
||||
'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({
|
||||
|
||||
@@ -118,6 +118,7 @@ class TestEmailParsing(TestMailCommon):
|
||||
class TestMailAlias(TestMailCommon):
|
||||
|
||||
@users('employee')
|
||||
@mute_logger('odoo.addons.base.models.ir_model')
|
||||
def test_alias_creation(self):
|
||||
record = self.env['mail.test.container'].create({
|
||||
'name': 'Test Record',
|
||||
@@ -309,7 +310,24 @@ class TestMailgateway(TestMailCommon):
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread')
|
||||
def test_message_process_followers(self):
|
||||
""" Incoming email: recognized author not archived and not odoobot: added as follower """
|
||||
""" Incoming email: recognized author not archived and not odoobot:
|
||||
added as follower. Also test corner cases: archived, private. """
|
||||
partner_archived, partner_private = self.env['res.partner'].create([
|
||||
{
|
||||
'active': False,
|
||||
'email': 'archived.customer@text.example.com',
|
||||
'phone': '0032455112233',
|
||||
'name': 'Archived Customer',
|
||||
'type': 'contact',
|
||||
},
|
||||
{
|
||||
'email': 'private.customer@text.example.com',
|
||||
'phone': '0032455112233',
|
||||
'name': 'Private Customer',
|
||||
'type': 'private',
|
||||
},
|
||||
])
|
||||
|
||||
with self.mock_mail_gateway():
|
||||
record = self.format_and_process(MAIL_TEMPLATE, self.partner_1.email_formatted, 'groups@test.com')
|
||||
|
||||
@@ -335,20 +353,17 @@ class TestMailgateway(TestMailCommon):
|
||||
'message_process: unrecognized email -> no follower')
|
||||
|
||||
# archived partner -> no follower
|
||||
self.partner_1.active = False
|
||||
self.partner_1.flush_recordset()
|
||||
with self.mock_mail_gateway():
|
||||
record3 = self.format_and_process(
|
||||
MAIL_TEMPLATE, self.partner_1.email_formatted, 'groups@test.com',
|
||||
subject='Yet Another Email')
|
||||
MAIL_TEMPLATE, partner_archived.email_formatted, 'groups@test.com',
|
||||
subject='Archived Partner')
|
||||
|
||||
self.assertEqual(record3.message_ids[0].author_id, self.env['res.partner'])
|
||||
self.assertEqual(record3.message_ids[0].email_from, self.partner_1.email_formatted)
|
||||
self.assertEqual(record3.message_ids[0].email_from, partner_archived.email_formatted)
|
||||
self.assertEqual(record3.message_follower_ids.partner_id, self.env['res.partner'],
|
||||
'message_process: unrecognized email -> no follower')
|
||||
'message_process: archived partner -> no follower')
|
||||
self.assertEqual(record3.message_partner_ids, self.env['res.partner'],
|
||||
'message_process: unrecognized email -> no follower')
|
||||
|
||||
'message_process: archived partner -> no follower')
|
||||
|
||||
# partner_root -> never again
|
||||
odoobot = self.env.ref('base.partner_root')
|
||||
@@ -362,9 +377,22 @@ class TestMailgateway(TestMailCommon):
|
||||
self.assertEqual(record4.message_ids[0].author_id, odoobot)
|
||||
self.assertEqual(record4.message_ids[0].email_from, odoobot.email_formatted)
|
||||
self.assertEqual(record4.message_follower_ids.partner_id, self.env['res.partner'],
|
||||
'message_process: unrecognized email -> no follower')
|
||||
'message_process: odoobot -> no follower')
|
||||
self.assertEqual(record4.message_partner_ids, self.env['res.partner'],
|
||||
'message_process: unrecognized email -> no follower')
|
||||
'message_process: odoobot -> no follower')
|
||||
|
||||
# private partner
|
||||
with self.mock_mail_gateway():
|
||||
record5 = self.format_and_process(
|
||||
MAIL_TEMPLATE, partner_private.email_formatted, 'groups@test.com',
|
||||
subject='Private Partner')
|
||||
|
||||
self.assertEqual(record5.message_ids[0].author_id, partner_private)
|
||||
self.assertEqual(record5.message_ids[0].email_from, partner_private.email_formatted)
|
||||
self.assertEqual(record5.message_follower_ids.partner_id, partner_private,
|
||||
'message_process: private partner is recognized')
|
||||
self.assertEqual(record5.message_partner_ids, partner_private,
|
||||
'message_process: private partner is recognized')
|
||||
|
||||
# --------------------------------------------------
|
||||
# Author recognition
|
||||
@@ -399,7 +427,7 @@ class TestMailgateway(TestMailCommon):
|
||||
self.assertEqual(record.message_ids[0].email_from, self.partner_1.email)
|
||||
self.assertNotSentEmail() # No notification / bounce should be sent
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models')
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink')
|
||||
def test_message_process_email_partner_find(self):
|
||||
""" Finding the partner based on email, based on partner / user / follower """
|
||||
self.alias.write({'alias_force_thread_id': self.test_record.id})
|
||||
@@ -720,7 +748,7 @@ class TestMailgateway(TestMailCommon):
|
||||
self.assertEqual(record.message_ids[0].create_uid, self.user_employee)
|
||||
self.assertEqual(record.message_ids[0].author_id, self.user_employee.partner_id)
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread')
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink')
|
||||
def test_message_process_create_uid_email_follower(self):
|
||||
self.alias.write({
|
||||
'alias_parent_model_id': self.test_model.id,
|
||||
@@ -1017,7 +1045,7 @@ class TestMailgateway(TestMailCommon):
|
||||
self.assertEqual(self.partner_1.message_bounce, 0)
|
||||
self.assertEqual(self.test_record.message_bounce, 1)
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread')
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink')
|
||||
def test_message_process_bounce_records_channel(self):
|
||||
""" Test blacklist allow to multi-bounce and auto update of mail.channel """
|
||||
other_record = self.env['mail.test.gateway'].create({
|
||||
@@ -1090,7 +1118,7 @@ class TestMailgateway(TestMailCommon):
|
||||
self.assertEqual(len(self.test_record.message_ids), init_msg_count + 1)
|
||||
self.assertEqual(self.fake_email.child_ids, self.test_record.message_ids[0])
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink', 'odoo.addons.mail.models.mail_mail', 'odoo.tests')
|
||||
def test_message_process_references_multi_parent(self):
|
||||
""" Incoming email with multiple references """
|
||||
reply1 = self._create_gateway_message(
|
||||
@@ -1149,7 +1177,7 @@ class TestMailgateway(TestMailCommon):
|
||||
self.assertEqual(new_msg.parent_id, self.fake_email, 'Mail: flattening attach to original message')
|
||||
self.assertEqual(new_msg.subtype_id, self.env.ref('mail.mt_comment'), 'Mail: parent should be a comment (before flattening)')
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink', 'odoo.addons.mail.models.mail_mail', 'odoo.tests')
|
||||
def test_message_process_references_multi_parent_notflat(self):
|
||||
""" Incoming email with multiple references with ``_mail_flat_thread``
|
||||
being False (mail.group/mail.channel behavior like). """
|
||||
|
||||
Reference in New Issue
Block a user