[FIX] test_mail: prepare and fixup tests for alias domains

Some tests are updated to lessen diff in future tests, especially about
aliases. Some tests are fixed as they are somehow incorrect (notably
in gateway testing) but currently passing as mail gateway is quite
permissive.

Add some tests preparing MC / alias domains configuration notably about
company / alias synchronization, which is currently only based on config
parameters.

Also update some tests by using fstrings which are generally more readable.

Finally move some tests to their right file / main testing class to keep
them ordered by main topic.

Prepares Task-36879 (Mail: Support MultiCompany Aliases)

closes odoo/odoo#136318

X-original-commit: odoo/odoo@c18300e225
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Thibault Delavallée
2023-09-22 18:40:25 +00:00
parent 8012722543
commit eb228ac373
7 changed files with 356 additions and 283 deletions
+4
View File
@@ -1250,6 +1250,10 @@ class MailCommon(common.TransactionCase, MailCase):
'name': 'ELIT',
})
cls.user_admin.write({'company_ids': [(4, cls.company_2.id)]})
cls.company_3 = cls.env['res.company'].create({
'email': 'company_3@test.example.com',
'name': 'Company 3',
})
# employee specific to second company
cls.user_employee_c2 = mail_new_test_user(
+70 -23
View File
@@ -9,7 +9,7 @@ from odoo import exceptions
from odoo.addons.mail.tests.common import MailCommon
from odoo.tests import tagged
from odoo.tests.common import users
from odoo.tools import mute_logger
from odoo.tools import formataddr, mute_logger
class TestMailAliasCommon(MailCommon):
@@ -91,24 +91,30 @@ class TestMailAlias(TestMailAliasCommon):
@users('admin')
def test_alias_name_unique(self):
""" Check uniqueness constraint on alias names, at create and update.
Also check conflict management with bounce / catchall aliases. """
alias_model_id = self.env['ir.model']._get('mail.test.gateway').id
catchall_alias = self.env['ir.config_parameter'].sudo().get_param('mail.catchall.alias')
bounce_alias = self.env['ir.config_parameter'].sudo().get_param('mail.bounce.alias')
# test you cannot create aliases matching bounce / catchall
new_mail_alias = self.env['mail.alias'].create({
'alias_model_id': alias_model_id,
'alias_name': 'unused.test.alias',
})
other_alias = self.env['mail.alias'].create({
'alias_model_id': alias_model_id,
'alias_name': 'other.test.alias',
})
# test you cannot create or update aliases matching bounce / catchall
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
self.env['mail.alias'].create({'alias_model_id': alias_model_id, 'alias_name': catchall_alias})
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
self.env['mail.alias'].create({'alias_model_id': alias_model_id, 'alias_name': bounce_alias})
new_mail_alias = self.env['mail.alias'].create({
'alias_model_id': alias_model_id,
'alias_name': 'unused.test.alias'
})
other_alias = self.env['mail.alias'].create({
'alias_model_id': alias_model_id,
'alias_name': 'other.test.alias'
})
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
new_mail_alias.write({'alias_name': catchall_alias})
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
new_mail_alias.write({'alias_name': bounce_alias})
# test that alias names should be unique
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
@@ -124,18 +130,26 @@ class TestMailAlias(TestMailAliasCommon):
}
for alias_name in ('new.alias.1', 'new.alias.2', 'new.alias.1')
])
with self.assertRaises(psycopg2.errors.UniqueViolation), self.cr.savepoint(), mute_logger('odoo.sql_db'):
new_mail_alias.copy({'alias_name': 'unused.test.alias'})
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
other_alias.write({'alias_name': 'unused.test.alias'})
# test that re-using catchall and bounce alias raises UserError
# cannot set catchall / bounce to used alias
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
new_mail_alias.write({'alias_name': catchall_alias})
self.env['ir.config_parameter'].sudo().set_param('mail.catchall.alias', new_mail_alias.alias_name)
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
new_mail_alias.write({'alias_name': bounce_alias})
self.env['ir.config_parameter'].sudo().set_param('mail.bounce.alias', new_mail_alias.alias_name)
new_mail_alias.write({'alias_name': 'another.unused.test.alias'})
@users('admin')
def test_alias_name_unique_copy(self):
""" Check uniqueness constraint check when copying aliases """
alias_model_id = self.env['ir.model']._get('mail.test.gateway').id
new_mail_alias = self.env['mail.alias'].create({
'alias_model_id': alias_model_id,
'alias_name': 'unused.test.alias'
})
with mute_logger('odoo.sql_db'), self.assertRaises(psycopg2.errors.UniqueViolation), self.cr.savepoint():
new_mail_alias.copy({'alias_name': 'unused.test.alias'})
# test that duplicating an alias should have blank name
copy_1 = new_mail_alias.copy()
@@ -148,12 +162,6 @@ class TestMailAlias(TestMailAliasCommon):
with self.assertRaises(exceptions.UserError):
(copy_1 + copy_2).write({'alias_name': 'test.alias.other'})
# cannot set catchall / bounce to used alias
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
self.env['ir.config_parameter'].sudo().set_param('mail.catchall.alias', new_mail_alias.alias_name)
with self.assertRaises(exceptions.UserError), self.cr.savepoint():
self.env['ir.config_parameter'].sudo().set_param('mail.bounce.alias', new_mail_alias.alias_name)
@users('admin')
@mute_logger('odoo.models.unlink')
def test_alias_name_sanitize(self):
@@ -238,6 +246,45 @@ class TestMailAlias(TestMailAliasCommon):
alias.write({'alias_defaults': "{'custom_field': 'validdict'}"})
@tagged('mail_alias', 'multi_company')
class TestAliasCompany(TestMailAliasCommon):
""" Test company / alias domain and configuration synchronization """
def test_assert_initial_values(self):
""" Test initial setup values: currently all companies share the same
alias configuration as it is unique. """
self.assertEqual(self.company_admin.catchall_email, f'{self.alias_catchall}@{self.alias_domain}')
self.assertEqual(
self.company_admin.catchall_formatted,
formataddr((self.company_admin.name, f'{self.alias_catchall}@{self.alias_domain}'))
)
self.assertEqual(self.company_2.catchall_email, f'{self.alias_catchall}@{self.alias_domain}')
self.assertEqual(
self.company_2.catchall_formatted,
formataddr((self.company_2.name, f'{self.alias_catchall}@{self.alias_domain}'))
)
self.assertEqual(self.company_3.catchall_email, f'{self.alias_catchall}@{self.alias_domain}')
self.assertEqual(
self.company_3.catchall_formatted,
formataddr((self.company_3.name, f'{self.alias_catchall}@{self.alias_domain}'))
)
@users('erp_manager')
def test_res_company_creation_alias_domain(self):
""" Test alias domain configuration when creating new companies """
company = self.env['res.company'].create({
'email': '"Super Company" <super.company@test3.mycompany.com>',
'name': 'Super Company',
})
company.flush_recordset()
self.assertEqual(
company.catchall_formatted,
formataddr((company.name, f'{self.alias_catchall}@{self.alias_domain}'))
)
@tagged('mail_gateway', 'mail_alias', 'multi_company')
class TestMailAliasMixin(TestMailAliasCommon):
""" Test alias mixin implementation, synchornization of alias records
@@ -29,6 +29,8 @@ class TestMailComposer(MailCommon, TestRecipients):
@classmethod
def setUpClass(cls):
super(TestMailComposer, cls).setUpClass()
# force 'now' to ease test about schedulers
cls.reference_now = FieldDatetime.from_string('2022-12-24 12:00:00')
cls.env.cr._now = cls.reference_now # force create_date to check schedulers
@@ -1184,6 +1186,72 @@ class TestComposerInternals(TestMailComposer):
self.assertEqual(template.name, "%s: %s" % (self.env['ir.model']._get(self.test_record._name).name, 'Template Subject'))
self.assertEqual(template.body_html, '<p>Template Body</p>', 'email_template incorrect body_html')
@users('erp_manager')
@mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
def test_mail_composer_wtpl_populate_new_recipients_mc(self):
""" Test auto-populate of auto created partner with related record
values when sending a mail with a template, in multi-company environment.
"""
companies = self.company_admin + self.company_2
test_records = self.env['mail.test.ticket.mc'].create([
{
'email_from': f'newpartner{idx}@example.com',
'company_id': companies[idx].id,
'customer_id': False,
'mobile_number': f'+3319900{idx:02d}{idx:02d}',
'name': f'TestRecord{idx}',
'phone_number': False,
'user_id': False,
} for idx in range(2)
])
manual_recipients = test_records.mapped('email_from')
template = self.env['mail.template'].create({
'email_to': '{{ object.email_from }}',
'model_id': self.env['ir.model']._get_id(test_records._name),
'partner_to': False,
})
for composition_mode, batch_mode in product(
('comment', 'mass_mail'),
(True, False)
):
with self.subTest(composition_mode=composition_mode, batch_mode=batch_mode):
test_records = test_records if batch_mode else test_records[0]
self.assertFalse(
self.env['res.partner'].search(
[('email_normalized', 'in', manual_recipients)]
)
)
ctx = {
'default_composition_mode': composition_mode,
'default_model': test_records._name,
'default_res_ids': test_records.ids,
}
composer = self.env['mail.compose.message'].with_context(ctx).create({
'template_id': template.id,
})
with self.mock_mail_gateway():
composer._action_send_mail()
new_partners = self.env['res.partner'].search([('email_normalized', 'in', manual_recipients)],
order='email')
try:
self.assertEqual(
len(new_partners), len(test_records)
)
self.assertEqual(
new_partners.mapped('company_id'),
test_records.mapped('company_id')
)
self.assertEqual(
new_partners.mapped('mobile'),
test_records.mapped('mobile_number')
)
finally:
new_partners.unlink()
@tagged('mail_composer', 'multi_lang')
class TestComposerResultsComment(TestMailComposer, CronMixinCase):
+90 -90
View File
@@ -228,7 +228,7 @@ class TestMailgateway(MailCommon):
record = self.format_and_process(test_mail_data.MAIL_MULTIPART_IMAGE, self.email_from, f'groups@{self.alias_domain}')
message = record.message_ids[0]
for attachment in message.attachment_ids:
self.assertIn('/web/image/%s' % attachment.id, message.body)
self.assertIn(f'/web/image/{attachment.id}', message.body)
self.assertEqual(
set(message.attachment_ids.mapped('name')),
set(['rosaçée.gif', 'verte!µ.gif', 'orangée.gif']))
@@ -323,7 +323,7 @@ class TestMailgateway(MailCommon):
self.assertNotSentEmail() # No notification / bounce should be sent
# Email recognized if partner has a formatted email
self.partner_1.write({'email': '"Valid Lelitre" <%s>' % self.partner_1.email})
self.partner_1.write({'email': f'"Valid Lelitre" <{self.partner_1.email}>'})
record = self.format_and_process(MAIL_TEMPLATE, self.partner_1.email, f'groups@{self.alias_domain}', subject='Test2')
self.assertEqual(record.message_ids[0].author_id, self.partner_1,
@@ -339,7 +339,7 @@ class TestMailgateway(MailCommon):
self.partner_1.write({'email': f'{test_email}, "Valid Lelitre" <another.email@test.example.com>'})
with self.mock_mail_gateway():
record = self.format_and_process(
MAIL_TEMPLATE, f'"Valid Lelitre" <{test_email}>', 'groups@test.com', subject='Test3')
MAIL_TEMPLATE, f'"Valid Lelitre" <{test_email}>', f'groups@{self.alias_domain}', subject='Test3')
self.assertEqual(record.message_ids[0].author_id, self.partner_1,
'message_process: found author based on first found email normalized, even with multi emails')
@@ -349,7 +349,7 @@ class TestMailgateway(MailCommon):
# Email not recognized if partner has a multi-email (source = std email)
with self.mock_mail_gateway():
record = self.format_and_process(
MAIL_TEMPLATE, test_email, 'groups@test.com', subject='Test4')
MAIL_TEMPLATE, test_email, f'groups@{self.alias_domain}', subject='Test4')
self.assertEqual(record.message_ids[0].author_id, self.partner_1,
'message_process: found author based on first found email normalized, even with multi emails')
@@ -394,18 +394,18 @@ class TestMailgateway(MailCommon):
self.assertFalse(record.message_ids[0].author_id)
self.assertEqual(record.message_ids[0].email_from, from_1.email_formatted)
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models')
@mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.addons.mail.models.mail_thread', 'odoo.models')
def test_message_route_alias_owner_author_notify(self):
""" Make sure users are notified when a reply is sent to an alias address.
Alias owner should impact the message creator, but not notifications. """
test_record = self.env['mail.test.ticket'].create({})
author_partner = self.env['res.partner'].create({
'name': 'Author',
'email': 'author-partner@test.com',
'email': f'author-partner@{self.alias_domain}',
})
message = self.env['mail.message'].create({
'body': '<p>test</p>',
'email_from': 'author-partner@test.com', # email sent by author who also has an alias with their email
'email_from': f'author-partner@{self.alias_domain}', # email sent by author who also has an alias with their email
'message_type': 'email',
'model': test_record._name,
'res_id': test_record.id,
@@ -423,7 +423,7 @@ class TestMailgateway(MailCommon):
self.assertFalse(self.user_root.active, 'notification logic relies on odoobot being archived')
test_users = [self.user_employee, self.user_root]
email_tos = ['author-partner@test.com', 'some_non_aliased_email@test.com']
email_tos = [f'author-partner@{self.alias_domain}', f'some_non_aliased_email@{self.alias_domain}']
for email_to, test_user in itertools.product(email_tos, test_users):
with self.subTest(test_user=test_user, email_to=email_to):
with self.mock_mail_gateway(), self.mock_mail_app():
@@ -487,19 +487,19 @@ class TestMailgateway(MailCommon):
self.assertSentEmail(
f'"MAILER-DAEMON" <{self.alias_bounce}@{self.alias_domain}>',
['whatever-2a840@postmaster.twitter.com'],
body_content='<p>Dear Sender,<br /><br />The message below could not be accepted by the address %s' % self.alias.display_name.lower()
body_content=f'<p>Dear Sender,<br /><br />The message below could not be accepted by the address {self.alias.display_name.lower()}',
)
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
def test_message_process_alias_config_bounced_to(self):
""" Check bounce message contains the bouncing alias, not a generic "to" """
self.alias.write({'alias_contact': 'partners'})
bounce_message_with_alias = '<p>Dear Sender,<br /><br />The message below could not be accepted by the address %s' % self.alias.display_name.lower()
bounce_message_with_alias = f'<p>Dear Sender,<br /><br />The message below could not be accepted by the address {self.alias.display_name.lower()}'
# Bounce is To
with self.mock_mail_gateway():
self.format_and_process(
MAIL_TEMPLATE, self.email_from, 'groups@example.com',
MAIL_TEMPLATE, self.email_from, f'groups@{self.alias_domain}',
cc='other@gmail.com', subject='Should Bounce')
self.assertIn(bounce_message_with_alias, self._mails[0].get('body'))
@@ -507,17 +507,17 @@ class TestMailgateway(MailCommon):
with self.mock_mail_gateway():
self.format_and_process(
MAIL_TEMPLATE, self.email_from, 'other@gmail.com',
cc='groups@example.com', subject='Should Bounce')
cc=f'groups@{self.alias_domain}', subject='Should Bounce')
self.assertIn(bounce_message_with_alias, self._mails[0].get('body'))
# Bounce is part of To
with self.mock_mail_gateway():
self.format_and_process(
MAIL_TEMPLATE, self.email_from, 'other@gmail.com, groups@example.com',
MAIL_TEMPLATE, self.email_from, f'other@gmail.com, groups@{self.alias_domain}',
subject='Should Bounce')
self.assertIn(bounce_message_with_alias, self._mails[0].get('body'))
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models', 'odoo.sql_db')
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.addons.mail.models.mail_mail', 'odoo.models', 'odoo.sql_db')
def test_message_process_alias_config_invalid_defaults(self):
"""Sending a mail to a misconfigured alias must change its status to invalid + notify sender and responsible."""
test_model_track = self.env['ir.model']._get('mail.test.track')
@@ -706,7 +706,7 @@ class TestMailgateway(MailCommon):
with self.subTest(partner_email=partner_email):
self.partner_1.write({'email': partner_email})
record = self.format_and_process(
MAIL_TEMPLATE, email_from, 'groups@test.com',
MAIL_TEMPLATE, email_from, f'groups@{self.alias_domain}',
subject=f'Test for {partner_email}')
if passed:
@@ -765,7 +765,10 @@ class TestMailgateway(MailCommon):
self.assertEqual(record.message_ids[0].create_uid, self.user_root)
self.assertEqual(record.message_ids[0].author_id, self.user_employee.partner_id)
record = self.format_and_process(MAIL_TEMPLATE, 'Another name <%s>' % self.user_employee.email, f'groups@{self.alias_domain}', subject='Email OtherName')
record = self.format_and_process(
MAIL_TEMPLATE, f'Another name <{self.user_employee.email}>',
f'groups@{self.alias_domain}',
subject='Email OtherName')
self.assertEqual(record.create_uid, self.user_employee)
self.assertEqual(record.message_ids[0].subject, 'Email OtherName')
self.assertEqual(record.message_ids[0].create_uid, self.user_root)
@@ -828,9 +831,9 @@ class TestMailgateway(MailCommon):
})
new_rec = self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted,
'%s@%s, %s@%s' % (new_alias_2.alias_name, self.alias_domain, self.alias.alias_name, self.alias_domain),
f'{new_alias_2.display_name}, {self.alias.display_name}',
subject='Test Subject',
extra='In-Reply-To:\r\n\t%s\n' % self.fake_email.message_id,
extra=f'In-Reply-To:\r\n\t{self.fake_email.message_id}\n',
target_model=new_alias_2.alias_model_id.model
)
# Forward created a new record in mail.test
@@ -855,9 +858,9 @@ class TestMailgateway(MailCommon):
})
new_rec = self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted,
'%s@%s, %s@%s' % (self.alias.alias_name, self.alias_domain, new_alias_2.alias_name, self.alias_domain),
f'{self.alias.display_name}, {new_alias_2.display_name}',
subject='Test Subject',
extra='In-Reply-To:\r\n\t%s\n' % self.fake_email.message_id,
extra=f'In-Reply-To:\r\n\t{self.fake_email.message_id}\n',
target_model=new_alias_2.alias_model_id.model
)
# Forward created a new record in mail.test
@@ -885,9 +888,9 @@ class TestMailgateway(MailCommon):
})
new_rec = self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted,
'%s@%s, %s@%s' % (new_alias_2.alias_name, self.alias_domain, self.alias.alias_name, self.alias_domain),
f'{new_alias_2.display_name}, {self.alias.display_name}',
subject='Test Subject',
extra='In-Reply-To:\r\n\t%s\n' % self.fake_email.message_id,
extra=f'In-Reply-To:\r\n\t{self.fake_email.message_id}\n',
target_model=new_alias_2.alias_model_id.model
)
# Forward created a new record in mail.test
@@ -911,7 +914,7 @@ class TestMailgateway(MailCommon):
})
new_rec = self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted,
'%s@%s, %s@%s' % (self.alias.alias_name, self.alias_domain, new_alias_2.alias_name, self.alias_domain),
f'{self.alias.display_name}, {new_alias_2.display_name}',
subject='Test Subject',
target_model=new_alias_2.alias_model_id.model
)
@@ -923,44 +926,43 @@ class TestMailgateway(MailCommon):
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models')
def test_message_route_alias_with_allowed_domains(self):
""" Incoming email: check that if domains are set in the
optional system parameter `mail.catchall.domain.allowed`,
only incoming emails from these domains will generate records."""
""" Incoming email: check that if domains are set in the optional system
parameter `mail.catchall.domain.allowed` only incoming emails from these
domains will generate records."""
MailTestGatewayModel = self.env['mail.test.gateway']
MailTestContainerModel = self.env['mail.test.container']
allowed_domain = 'hello.com'
not_allowed_domain = 'bonjour.com'
# test@.. will cause the creation of new mail.test
new_alias_2 = self.env['mail.alias'].create({
'alias_contact': 'everyone',
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_name': 'test',
'alias_user_id': False,
'alias_model_id': self.env['ir.model']._get('mail.test.container').id,
'alias_contact': 'everyone',
})
for subject, gateway_created, container_created, alias2_domain, sys_param in [
# Test with 'mail.catchall.domain.allowed' not set in system parameters
# and with a domain not allowed
('Test Subject 1', True, True, not_allowed_domain, ""),
# Test with 'mail.catchall.domain.allowed' set in system parameters
# and with a domain not allowed
('Test Subject 2', True, False, not_allowed_domain, allowed_domain),
# Test with 'mail.catchall.domain.allowed' set in system parameters
# and with a domain allowed
('Test Subject 3', True, True, allowed_domain, allowed_domain),
]:
with self.subTest(subject=subject, gateway_created=gateway_created,
container_created=container_created, alias2_domain=alias2_domain,
sys_param=sys_param):
self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', sys_param)
allowed_domain = 'hello.com'
for (alias_right_part, allowed_domain), (gateway_created, container_created) in zip(
[
# Test with 'mail.catchall.domain.allowed' not set in system parameters
# and with a domain not allowed
('bonjour.com', ""),
# Test with 'mail.catchall.domain.allowed' set in system parameters
# and with a domain not allowed
('bonjour.com', allowed_domain),
# Test with 'mail.catchall.domain.allowed' set in system parameters
# and with a domain allowed
(allowed_domain, allowed_domain),
], [
(True, True),
(True, False),
(True, True),
]
):
with self.subTest(alias_right_part=alias_right_part, allowed_domain=allowed_domain):
self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', allowed_domain)
email_to = '%s@%s, %s@%s' % (
self.alias.alias_name, self.alias_domain,
new_alias_2.alias_name, alias2_domain,
)
subject = f'Test wigh {alias_right_part}-{allowed_domain}'
email_to = f'{self.alias.alias_name}@{self.alias_domain}, {new_alias_2.alias_name}@{alias_right_part}'
self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted, email_to,
@@ -970,16 +972,8 @@ class TestMailgateway(MailCommon):
res_alias_1 = MailTestGatewayModel.search([('name', '=', subject)])
res_alias_2 = MailTestContainerModel.search([('name', '=', subject)])
self.assertEqual(
bool(res_alias_1), gateway_created,
'message_process (%s): a new mail.test.gateway %s have been created' %
(subject, 'should' if gateway_created else "should not")
)
self.assertEqual(
bool(res_alias_2), container_created,
'message_process (%s): a new mail.test.container %s have been created' %
(subject, 'should' if container_created else "should not")
)
self.assertEqual(bool(res_alias_1), gateway_created)
self.assertEqual(bool(res_alias_2), container_created)
# --------------------------------------------------
# Email Management
@@ -991,7 +985,7 @@ class TestMailgateway(MailCommon):
with self.mock_mail_gateway():
new_recs = self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted,
'%s@%s' % (self.alias_bounce, self.alias_domain),
f'{self.alias_bounce}@{self.alias_domain}',
subject='Should bounce',
)
self.assertFalse(new_recs)
@@ -1003,10 +997,7 @@ class TestMailgateway(MailCommon):
with self.mock_mail_gateway():
new_recs = self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted,
'%s@%s, %s@%s' % (
self.alias.alias_name, self.alias_domain,
self.alias_bounce, self.alias_domain
),
f'{self.alias.alias_name}@{self.alias_domain}, {self.alias_bounce}@{self.alias_domain}',
subject='Should bounce',
)
self.assertFalse(new_recs)
@@ -1019,11 +1010,11 @@ class TestMailgateway(MailCommon):
with self.mock_mail_gateway():
record = self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted,
'"My Super Catchall" <%s@%s>' % (self.alias_catchall, self.alias_domain),
f'"My Super Catchall" <{self.alias_catchall}@{self.alias_domain}',
subject='Should Bounce')
self.assertFalse(record)
self.assertSentEmail(
f'"MAILER-DAEMON" <{self.alias_bounce}@{self.alias_domain}>',
self.mailer_daemon_email,
['whatever-2a840@postmaster.twitter.com'],
subject='Re: Should Bounce'
)
@@ -1035,7 +1026,7 @@ class TestMailgateway(MailCommon):
with self.mock_mail_gateway():
record = self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted,
'%s@%s, %s@%s' % (self.alias_catchall, self.alias_domain, self.alias.alias_name, self.alias_domain),
f'{self.alias_catchall}@{self.alias_domain}, {self.alias.alias_name}@{self.alias_domain}',
subject='Catchall Not Blocking'
)
# Test: one group created
@@ -1050,7 +1041,7 @@ class TestMailgateway(MailCommon):
with self.mock_mail_gateway():
record = self.format_and_process(
MAIL_TEMPLATE, self.partner_1.email_formatted,
'%s@%s, %s@%s' % (self.alias.alias_name, self.alias_domain, self.alias_catchall, self.alias_domain),
f'{self.alias.alias_name}@{self.alias_domain}, {self.alias_catchall}@{self.alias_domain}',
subject='Catchall Not Blocking'
)
# Test: one group created
@@ -1187,10 +1178,10 @@ class TestMailgateway(MailCommon):
def test_message_process_bounce_records_channel(self):
""" Test blacklist allow to multi-bounce and auto update of discuss.channel """
other_record = self.env['mail.test.gateway'].create({
'email_from': 'Another name <%s>' % self.partner_1.email
'email_from': f'Another name <{self.partner_1.email}>'
})
yet_other_record = self.env['mail.test.gateway'].create({
'email_from': 'Yet Another name <%s>' % self.partner_1.email.upper()
'email_from': f'Yet Another name <{self.partner_1.email.upper()}>'
})
test_channel = self.env['discuss.channel'].create({
'name': 'Test',
@@ -1207,7 +1198,11 @@ class TestMailgateway(MailCommon):
extra = self.fake_email.message_id
for i in range(10):
record = self.format_and_process(test_mail_data.MAIL_BOUNCE, 'A third name <%s>' % self.partner_1.email, f'groups@{self.alias_domain}', subject='Undelivered Mail Returned to Sender', extra=extra)
record = self.format_and_process(
test_mail_data.MAIL_BOUNCE, f'A third name <{self.partner_1.email}>',
f'groups@{self.alias_domain}',
subject='Undelivered Mail Returned to Sender',
extra=extra)
self.assertFalse(record)
self.assertEqual(self.partner_1.message_bounce, 10)
self.assertEqual(self.test_record.message_bounce, 0)
@@ -1234,7 +1229,7 @@ class TestMailgateway(MailCommon):
# Thread formation
# --------------------------------------------------
@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_external_notification_reply(self):
"""Ensure responses bot messages are discussions."""
bot_notification_message = self._create_gateway_message(
@@ -1282,7 +1277,7 @@ class TestMailgateway(MailCommon):
init_msg_count = len(self.test_record.message_ids)
self.format_and_process(
MAIL_TEMPLATE, 'valid.other@gmail.com', f'erroneous@{self.alias_domain}',
subject='Re: news', extra='In-Reply-To:\r\n\t%s\n' % self.fake_email.message_id)
subject='Re: news', extra=f'In-Reply-To:\r\n\t{self.fake_email.message_id}\n')
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])
@@ -1293,7 +1288,7 @@ class TestMailgateway(MailCommon):
init_msg_count = len(self.test_record.message_ids)
self.format_and_process(
MAIL_TEMPLATE, self.email_from, f'erroneous@{self.alias_domain}',
extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id)
extra=f'References: <2233@a.com>\r\n\t<3edss_dsa@b.com> {self.fake_email.message_id}')
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])
@@ -1442,7 +1437,7 @@ class TestMailgateway(MailCommon):
init_msg_count = len(self.test_record.message_ids)
self.format_and_process(
MAIL_TEMPLATE, self.email_from, f'erroneous@{self.alias_domain}',
extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id)
extra=f'References: <2233@a.com>\r\n\t<3edss_dsa@b.com> {self.fake_email.message_id}')
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])
@@ -1463,7 +1458,7 @@ class TestMailgateway(MailCommon):
init_msg_count = len(self.test_record.message_ids)
self.format_and_process(
MAIL_TEMPLATE, self.email_from, f'erroneous@{self.alias_domain}',
extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % buggy_message_id)
extra=f'References: <2233@a.com>\r\n\t<3edss_dsa@b.com> {buggy_message_id}')
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])
@@ -1480,7 +1475,8 @@ class TestMailgateway(MailCommon):
init_msg_count = len(self.test_record.message_ids)
res_test = self.format_and_process(
MAIL_TEMPLATE, self.email_from, f'test.alias@{self.alias_domain}',
subject='My Dear Forward', extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id,
subject='My Dear Forward',
extra=f'References: <2233@a.com>\r\n\t<3edss_dsa@b.com> {self.fake_email.message_id}',
target_model='mail.test.container')
self.assertEqual(len(self.test_record.message_ids), init_msg_count)
@@ -1500,7 +1496,8 @@ class TestMailgateway(MailCommon):
init_msg_count = len(self.test_record.message_ids)
res_test = self.format_and_process(
MAIL_TEMPLATE, self.email_from, f'test.alias@{self.alias_domain}',
subject='My Dear Forward', extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id,
subject='My Dear Forward',
extra=f'References: <2233@a.com>\r\n\t<3edss_dsa@b.com> {self.fake_email.message_id}',
target_model='mail.test.container')
self.assertEqual(len(self.test_record.message_ids), init_msg_count + 1)
@@ -1555,7 +1552,7 @@ class TestMailgateway(MailCommon):
msgID = '<this.is.duplicate.test@iron.sky>'
res_test = self.format_and_process(
MAIL_TEMPLATE, self.email_from, record_msg.reply_to, cc='',
subject='Re: Replies to Record', extra='In-Reply-To: %s' % record_msg.message_id,
subject='Re: Replies to Record', extra=f'In-Reply-To: {record_msg.message_id}',
msg_id=msgID, target_model='mail.test.simple')
incoming_msg = self.env['mail.message'].search([('message_id', '=', msgID)])
self.assertFalse(res_test)
@@ -1567,7 +1564,7 @@ class TestMailgateway(MailCommon):
msgID = '<this.is.for.testing@iron.sky>'
res_test = self.format_and_process(
MAIL_TEMPLATE, self.email_from, mail_msg.reply_to, cc='',
subject='Re: Replies to Record', extra='In-Reply-To: %s' % mail_msg.message_id,
subject='Re: Replies to Record', extra=f'In-Reply-To: {mail_msg.message_id}',
msg_id=msgID, target_model='mail.test.gateway')
incoming_msg = self.env['mail.message'].search([('message_id', '=', msgID)])
self.assertEqual(len(res_test), 1)
@@ -1592,7 +1589,7 @@ class TestMailgateway(MailCommon):
})
record = self.format_and_process(
test_mail_data.MAIL_TEMPLATE_EXTRA_HTML, self.email_from,
'%s@%s' % (alias.alias_name, self.alias_catchall),
f'{alias.alias_name}@{self.alias_domain}',
subject='base64 image to alias',
target_model=target_model,
extra_html='<img src="data:image/png;base64,iV/+OkI=">',
@@ -1615,7 +1612,7 @@ class TestMailgateway(MailCommon):
})
record = self.format_and_process(
test_mail_data.MAIL_TEMPLATE_EXTRA_HTML, self.email_from,
'%s@%s' % (alias.alias_name, self.alias_catchall),
f'{alias.alias_name}@{self.alias_domain}',
subject='base64 image to alias',
target_model=target_model,
extra_html='<img src="data:image/png;base64,iV/+OkI=">',
@@ -1635,7 +1632,7 @@ class TestMailgateway(MailCommon):
self.assertRaises(ValueError,
self.format_and_process, MAIL_TEMPLATE,
self.partner_1.email_formatted, f'noone@{self.alias_domain}', subject='spam',
extra='In-Reply-To: <12321321-openerp-%d-mail.test.gateway@%s>' % (self.test_record.id, socket.gethostname()))
extra=f'In-Reply-To: <12321321-openerp-{self.test_record.id}-{self.test_record._name}@{socket.gethostname()}>')
# when 6.1 messages are present, compat mode is available
# Odoo 10 update: compat mode has been removed and should not work anymore
@@ -1645,7 +1642,7 @@ class TestMailgateway(MailCommon):
ValueError,
self.format_and_process, MAIL_TEMPLATE,
self.partner_1.email_formatted, f'noone@{self.alias_domain}>', subject='spam',
extra='In-Reply-To: <12321321-openerp-%d-mail.test.gateway@%s>' % (self.test_record.id, socket.gethostname()))
extra=f'In-Reply-To: <12321321-openerp-{self.test_record.id}-mail.test.gateway@{socket.gethostname()}>')
# Test created messages
self.assertEqual(len(self.test_record.message_ids), 1)
@@ -1707,8 +1704,8 @@ class TestMailgateway(MailCommon):
file_content_b64 = base64.b64encode(file_content.encode(encoding or 'utf-8')).decode()
record = self.format_and_process(test_mail_data.MAIL_FILE_ENCODING,
self.email_from, f'groups@{self.alias_domain}',
subject='Test Charset %s' % encoding or 'Unset',
charset='; charset="%s"' % encoding if encoding else '',
subject=f'Test Charset {encoding or "Unset"}',
charset=f'; charset="{encoding}"' if encoding else '',
content=file_content_b64
)
attachment = record.message_ids.attachment_ids
@@ -1835,6 +1832,7 @@ class TestMailgateway(MailCommon):
# This explains the multiple "�" in the attachment.
self.assertIn("Chauss������e de Bruxelles", record.message_ids.attachment_ids.raw.decode())
@mute_logger('odoo.addons.mail.models.mail_thread')
def test_message_process_file_omitted_charset(self):
""" For incoming email containing an xml attachment with omitted charset and containing an UTF8 payload we
should parse the attachment using UTF-8.
@@ -1843,6 +1841,7 @@ class TestMailgateway(MailCommon):
self.assertEqual(record.message_ids.attachment_ids.name, 'bis3.xml')
self.assertEqual("<Invoice>Chaussée de Bruxelles</Invoice>", record.message_ids.attachment_ids.raw.decode())
@mute_logger('odoo.addons.mail.models.mail_thread')
def test_message_route_reply_model_none(self):
"""
Test the message routing and reply functionality when the model is None.
@@ -1886,10 +1885,11 @@ class TestMailThreadCC(MailCommon):
cls.email_from = 'Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>'
cls.alias = cls.env['mail.alias'].create({
'alias_contact': 'everyone',
'alias_model_id': cls.env['ir.model']._get('mail.test.cc').id,
'alias_name': 'cc_record',
'alias_user_id': False,
'alias_model_id': cls.env['ir.model']._get('mail.test.cc').id,
'alias_contact': 'everyone'})
})
@mute_logger('odoo.addons.mail.models.mail_thread')
def test_message_cc_new(self):
@@ -13,7 +13,7 @@ from odoo.addons.mail.tests.common import MailCommon
from odoo.addons.test_mail.tests.common import TestRecipients
from odoo.exceptions import AccessError
from odoo.tests import tagged, users, HttpCase
from odoo.tools import formataddr, mute_logger
from odoo.tools import mute_logger
class TestMailMCCommon(MailCommon, TestRecipients):
@@ -69,132 +69,6 @@ class TestMailMCCommon(MailCommon, TestRecipients):
@tagged('multi_company')
class TestMultiCompanySetup(TestMailMCCommon):
@users('erp_manager')
@mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
def test_mail_composer_wtpl_populate_new_recipient(self):
""" Test auto-populate of auto created partner with related record
values when sending a mail with a template.
"""
companies = self.company_admin + self.company_2
test_records = self.env['mail.test.ticket.mc'].create([
{
'email_from': f'newpartner{idx}@example.com',
'company_id': companies[idx].id,
'customer_id': False,
'mobile_number': f'+3319900{idx:02d}{idx:02d}',
'name': f'TestRecord{idx}',
'phone_number': False,
'user_id': False,
} for idx in range(2)
])
manual_recipients = test_records.mapped('email_from')
template = self.env['mail.template'].create({
'email_to': '{{ object.email_from }}',
'model_id': self.env['ir.model']._get_id(test_records._name),
'partner_to': False,
})
for composition_mode, batch_mode in product(
('comment', 'mass_mail'),
(True, False)
):
with self.subTest(composition_mode=composition_mode, batch_mode=batch_mode):
test_records = test_records if batch_mode else test_records[0]
self.assertFalse(
self.env['res.partner'].search(
[('email_normalized', 'in', manual_recipients)]
)
)
ctx = {
'default_composition_mode': composition_mode,
'default_model': test_records._name,
'default_res_ids': test_records.ids,
}
composer = self.env['mail.compose.message'].with_context(ctx).create({
'template_id': template.id,
})
with self.mock_mail_gateway():
composer._action_send_mail()
new_partners = self.env['res.partner'].search([('email_normalized', 'in', manual_recipients)],
order='email')
try:
self.assertEqual(
len(new_partners), len(test_records)
)
self.assertEqual(
new_partners.mapped('company_id'),
test_records.mapped('company_id')
)
self.assertEqual(
new_partners.mapped('mobile'),
test_records.mapped('mobile_number')
)
finally:
new_partners.unlink()
@users('employee')
def test_notify_reply_to_computation(self):
test_record = self.env['mail.test.gateway'].browse(self.test_record.ids)
res = test_record._notify_get_reply_to()
self.assertEqual(
res[test_record.id],
formataddr((
"%s %s" % (self.user_employee.company_id.name, test_record.name),
"%s@%s" % (self.alias_catchall, self.alias_domain)))
)
@users('employee_c2')
def test_notify_reply_to_computation_mc(self):
""" Test reply-to computation in multi company mode. Add notably tests
depending on user and records company_id / company_ids. """
# Test1: no company_id field
test_record = self.env['mail.test.gateway'].browse(self.test_record.ids)
res = test_record._notify_get_reply_to()
self.assertEqual(
res[test_record.id],
formataddr((
"%s %s" % (self.user_employee_c2.company_id.name, test_record.name),
"%s@%s" % (self.alias_catchall, self.alias_domain)))
)
# Test2: MC environment get default value from env
self.user_employee_c2.write({'company_ids': [(4, self.user_employee.company_id.id)]})
test_records = self.env['mail.test.multi.company'].create([
{'name': 'Test',
'company_id': self.user_employee.company_id.id},
{'name': 'Test',
'company_id': self.user_employee_c2.company_id.id},
])
res = test_records._notify_get_reply_to()
for test_record in test_records:
self.assertEqual(
res[test_record.id],
formataddr((
"%s %s" % (self.user_employee_c2.company_id.name, test_record.name),
"%s@%s" % (self.alias_catchall, self.alias_domain)))
)
# Test3: get company from record (company_id field)
self.user_employee_c2.write({'company_ids': [(4, self.company_3.id)]})
test_records = self.env['mail.test.multi.company'].create([
{'name': 'Test1',
'company_id': self.company_3.id},
{'name': 'Test2',
'company_id': self.company_3.id},
])
res = test_records._notify_get_reply_to()
for test_record in test_records:
self.assertEqual(
res[test_record.id],
formataddr((
"%s %s" % (self.company_3.name, test_record.name),
"%s@%s" % (self.alias_catchall, self.alias_domain)))
)
@users('employee_c2')
@mute_logger('odoo.addons.base.models.ir_rule')
def test_post_with_read_access(self):
+122 -42
View File
@@ -233,9 +233,9 @@ class TestMailNotifyAPI(TestMessagePostCommon):
# employee: access button and link
self.assertTrue(emp_info['has_button_access'])
for param, value in link_vals.items():
self.assertIn('%s=%s' % (param, value), emp_info['button_access']['url'])
self.assertIn('model=%s' % base_record._name, emp_info['button_access']['url'])
self.assertIn('res_id=%s' % base_record.id, emp_info['button_access']['url'])
self.assertIn(f'{param}={value}', emp_info['button_access']['url'])
self.assertIn(f'model={base_record._name}', emp_info['button_access']['url'])
self.assertIn(f'res_id={base_record.id}', emp_info['button_access']['url'])
self.assertNotIn('body', emp_info['button_access']['url'])
self.assertNotIn('subject', emp_info['button_access']['url'])
@@ -284,6 +284,61 @@ class TestMailNotifyAPI(TestMessagePostCommon):
self.assertFalse(partner_info['has_button_access'])
self.assertFalse(emp_info['has_button_access'])
@users('employee_c2')
def test_notify_reply_to_computation_mc(self):
""" Test reply-to computation in multi company mode. Add notably tests
depending on user and records company_id / company_ids. """
# Test1: no company_id field: depends on current user browsing
test_record = self.test_record.with_env(self.env)
self.assertEqual(
test_record._notify_get_reply_to()[test_record.id],
formataddr((
f"{self.user_employee_c2.company_id.name} {test_record.name}",
f"{self.alias_catchall}@{self.alias_domain}"))
)
test_record_c1 = test_record.with_user(self.user_employee)
self.assertEqual(
test_record_c1._notify_get_reply_to()[test_record_c1.id],
formataddr((
f"{self.user_employee.company_id.name} {test_record_c1.name}",
f"{self.alias_catchall}@{self.alias_domain}"))
)
# Test2: MC environment get default value from env
self.user_employee_c2.write({'company_ids': [(4, self.user_employee.company_id.id)]})
test_records = self.env['mail.test.multi.company'].create([
{'name': 'Test',
'company_id': self.user_employee.company_id.id},
{'name': 'Test',
'company_id': self.user_employee_c2.company_id.id},
])
res = test_records._notify_get_reply_to()
for test_record in test_records:
self.assertEqual(
res[test_record.id],
formataddr((
f"{self.user_employee_c2.company_id.name} {test_record.name}",
f"{self.alias_catchall}@{self.alias_domain}"))
)
# Test3: get company from record (company_id field)
self.user_employee_c2.write({'company_ids': [(4, self.company_3.id)]})
test_records = self.env['mail.test.multi.company'].create([
{'name': 'Test1',
'company_id': self.company_3.id},
{'name': 'Test2',
'company_id': self.company_3.id},
])
res = test_records._notify_get_reply_to()
for test_record in test_records:
self.assertEqual(
res[test_record.id],
formataddr((
f"{self.company_3.name} {test_record.name}",
f"{self.alias_catchall}@{self.alias_domain}"))
)
@tagged('mail_post', 'mail_notify')
class TestMessageNotify(TestMessagePostCommon):
@@ -331,8 +386,8 @@ class TestMessageNotify(TestMessagePostCommon):
self.assertTrue('model=' in admin_mail_body, 'The email sent to admin should contain an access link')
admin_access_link = admin_mail_body[
admin_mail_body.index('model='):admin_mail_body.index('/>', admin_mail_body.index('model=')) - 1]
self.assertIn('model=%s' % self.test_record._name, admin_access_link, 'The access link should contain a valid model argument')
self.assertIn('res_id=%d' % self.test_record.id, admin_access_link, 'The access link should contain a valid res_id argument')
self.assertIn(f'model={self.test_record._name}', admin_access_link, 'The access link should contain a valid model argument')
self.assertIn(f'res_id={self.test_record.id}', admin_access_link, 'The access link should contain a valid res_id argument')
partner_mails = [x for x in self._mails if self.partner_1.name in x.get('email_to')[0]]
self.assertEqual(len(partner_mails), 1, 'There should be exactly one email sent to partner')
@@ -397,38 +452,7 @@ class TestMessageNotify(TestMessagePostCommon):
@users('employee')
@mute_logger('odoo.addons.mail.models.mail_mail')
def test_notify_from_user_id(self):
""" Test notify coming from user_id assignment. """
test_record = self.env['mail.test.track'].create({
'company_id': self.env.user.company_id.id,
'email_from': self.env.user.email_formatted,
'name': 'Test UserId Track',
'user_id': False,
})
self.flush_tracking()
with self.mock_mail_gateway(), self.mock_mail_app():
test_record.write({'user_id': self.user_employee_2.id})
self.flush_tracking()
self.assertEqual(len(self._new_msgs), 2, 'Should have 2 messages: tracking and assignment')
assign_notif = self._new_msgs.filtered(lambda msg: msg.message_type == 'user_notification')
self.assertTrue(assign_notif)
self.assertMessageFields(
assign_notif,
{'author_id': self.partner_employee,
'email_from': formataddr((self.partner_employee.name, self.partner_employee.email_normalized)),
'model': test_record._name,
'notified_partner_ids': self.partner_employee_2,
'res_id': test_record.id,
'subtype_id': self.env.ref('mail.mt_note'),
}
)
self.assertIn('Dear %s' % self.partner_employee_2.name, assign_notif.body)
@users('employee')
@mute_logger('odoo.addons.mail.models.mail_mail')
def test_notify_from_user_id_batch(self):
""" Test notify coming from user_id assignment. """
""" Test notify coming from user_id assignment (in batch) """
test_records, _ = self._create_records_for_batch(
'mail.test.track', 10, {
'company_id': self.env.user.company_id.id,
@@ -682,7 +706,7 @@ class TestMessageLog(TestMessagePostCommon):
'is_internal': True,
'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))),
'reply_to': formataddr((self.company_admin.name, f'{self.alias_catchall}@{self.alias_domain}')),
'res_id': test_record.id,
},
'notif': [],
@@ -718,7 +742,7 @@ class TestMessagePost(TestMessagePostCommon, CronMixinCase):
'message_type': 'comment',
'model': test_record._name,
'notified_partner_ids': self.partner_employee_2,
'reply_to': formataddr(("%s %s" % (self.company_admin.name, test_record.name), '%s@%s' % (self.alias_catchall, self.alias_domain))),
'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_comment'),
},
@@ -739,6 +763,11 @@ class TestMessagePost(TestMessagePostCommon, CronMixinCase):
{'partner': self.partner_1, 'type': 'email'}],
message_info={
'content': 'NewBody',
'email_values': {
'headers': {
'Return-Path': f'{self.alias_bounce}@{self.alias_domain}',
},
},
'message_values': {
'notified_partner_ids': self.partner_1 + self.partner_employee_2,
},
@@ -916,6 +945,57 @@ class TestMessagePost(TestMessagePostCommon, CronMixinCase):
# notifications emails should not have been deleted: one for customers, one for user
self.assertEqual(self.env['mail.mail'].sudo().search_count([('mail_message_id', '=', msg.id)]), 2)
@mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
@users('erp_manager')
def test_message_post_mc(self):
""" Test posting in multi-company environment, notably with aliases """
records = self.env['mail.test.ticket.mc'].create([
{
'name': 'No Specific Company',
}, {
'company_id': self.company_admin.id,
'name': 'Company1',
}, {
'company_id': self.company_2.id,
'name': 'Company2',
},
])
expected_companies = [self.company_2, self.company_admin, self.company_2]
for record, expected_company in zip(records, expected_companies):
with self.subTest(record=record):
with self.assertSinglePostNotifications(
[{'partner': self.partner_employee_2, 'type': 'email'}],
message_info={
'content': 'Body',
'email_values': {
'headers': {
'Return-Path': f'{self.alias_bounce}@{self.alias_domain}',
},
},
'mail_mail_values': {
'headers': repr({
'X-Odoo-Objects': f'{record._name}-{record.id}',
}),
},
'message_values': {
'author_id': self.user_erp_manager.partner_id,
'email_from': formataddr((self.user_erp_manager.name, self.user_erp_manager.email_normalized)),
'is_internal': False,
'notified_partner_ids': self.partner_employee_2,
'reply_to': formataddr(
(f'{expected_company.name} {record.name}', f'{self.alias_catchall}@{self.alias_domain}')
),
},
}
):
_new_message = record.message_post(
body='Body',
message_type='comment',
subtype_xmlid='mail.mt_comment',
partner_ids=[self.partner_employee_2.id],
)
@mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.tests')
def test_message_post_recipients_email_field(self):
""" Test various combinations of corner case / not standard filling of
@@ -1278,7 +1358,7 @@ class TestMessagePost(TestMessagePostCommon, CronMixinCase):
[self.partner_1],
references_content='openerp-%d-mail.test.simple' % self.test_record.id,
# references should be sorted from the oldest to the newest
references='%s %s' % (parent_msg.message_id, msg.message_id),
references=f'{parent_msg.message_id} {msg.message_id}',
)
# post a reply to the reply: check parent is the first one
@@ -1299,7 +1379,7 @@ class TestMessagePost(TestMessagePostCommon, CronMixinCase):
reply_to=msg.reply_to,
subject=self.test_record.name,
references_content='openerp-%d-mail.test.simple' % self.test_record.id,
references='%s %s' % (parent_msg.message_id, new_msg.message_id),
references=f'{parent_msg.message_id} {new_msg.message_id}',
)
@mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.addons.mail.models.mail_thread')
@@ -1323,7 +1403,7 @@ class TestMessagePost(TestMessagePostCommon, CronMixinCase):
self.format_and_process(
MAIL_TEMPLATE_PLAINTEXT, self.user_admin.email, 'not_my_businesss@example.com',
msg_id='<1198923581.41972151344608186800.JavaMail.diff1@agrolait.example.com>',
extra='In-Reply-To:\r\n\t%s\n' % msg.message_id,
extra=f'In-Reply-To:\r\n\t{msg.message_id}\n',
target_model='mail.test.simple')
reply = test_record.message_ids - msg
self.assertTrue(reply)
+1 -1
View File
@@ -18,7 +18,7 @@ class BaseMailPerformance(MailCommon, TransactionCaseWithUserDemo):
def setUpClass(cls):
super(BaseMailPerformance, cls).setUpClass()
# creating partners is required notably witn template usage
# creating partners is required notably with template usage
cls.user_employee.write({'groups_id': [(4, cls.env.ref('base.group_partner_manager').id)]})
cls.user_test = cls.user_test_inbox = cls.env['res.users'].with_context(cls._test_context).create({
'name': 'Paulette Testouille',