From 71c58a7e936f5cc3e350b4ab5cfc239d942e00fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 31 Jul 2023 09:23:29 +0000 Subject: [PATCH] [MOV] test_mail: move alias tests in their own file Move alias-specific tests in their own file. This model deserves its own test file containing unit tests for both alias model and alias mixin. This helps improving and debugging the model, instead of having them mixed with gateway-specific tests. Activate multi-company in setup, preparing multi-company support for aliases and alias domains. Task-3453577 (TestMail: Update Alias/Gateway tests for MC) Prepares Task-36879 (Mail: Support MultiCompany Aliases) Part-of: odoo/odoo#130768 --- addons/test_mail/tests/__init__.py | 1 + addons/test_mail/tests/test_mail_alias.py | 154 ++++++++++++++++++++ addons/test_mail/tests/test_mail_gateway.py | 135 ----------------- 3 files changed, 155 insertions(+), 135 deletions(-) create mode 100644 addons/test_mail/tests/test_mail_alias.py diff --git a/addons/test_mail/tests/__init__.py b/addons/test_mail/tests/__init__.py index 80cd71ffd88..29b8297d59d 100644 --- a/addons/test_mail/tests/__init__.py +++ b/addons/test_mail/tests/__init__.py @@ -3,6 +3,7 @@ from . import test_invite from . import test_ir_actions from . import test_mail_activity +from . import test_mail_alias from . import test_mail_composer from . import test_mail_composer_mixin from . import test_mail_followers diff --git a/addons/test_mail/tests/test_mail_alias.py b/addons/test_mail/tests/test_mail_alias.py new file mode 100644 index 00000000000..46c90d94b2d --- /dev/null +++ b/addons/test_mail/tests/test_mail_alias.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +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 + + +class TestMailAliasCommon(MailCommon): + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls._activate_multi_company() + + +@tagged('mail_gateway', 'mail_alias', 'multi_company') +class TestMailAlias(TestMailAliasCommon): + """ Test alias model features, constraints and behavior. """ + + def test_alias_domain_allowed_validation(self): + """ Check the validation of `mail.catchall.domain.allowed` system parameter""" + for value in [',', ',,', ', ,']: + with self.assertRaises(exceptions.ValidationError, + msg="The value '%s' should not be allowed" % value): + self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', value) + + for value, expected in [ + ('', False), + ('hello.com', 'hello.com'), + ('hello.com,,', 'hello.com'), + ('hello.com,bonjour.com', 'hello.com,bonjour.com'), + ('hello.COM, BONJOUR.com', 'hello.com,bonjour.com'), + ]: + self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', value) + self.assertEqual(self.env['ir.config_parameter'].get_param('mail.catchall.domain.allowed'), expected) + + def test_alias_name_unique(self): + 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 + 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' + }) + + # test that re-using catchall and bounce alias raises UserError + 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 + }) + + new_mail_alias.write({'alias_name': 'another.unused.test.alias'}) + + # test that duplicating an alias should have blank name + copy_new_mail_alias = new_mail_alias.copy() + self.assertFalse(copy_new_mail_alias.alias_name) + + # 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) + + def test_alias_name_sanitize(self): + alias = self.env['mail.alias'].create({ + 'alias_model_id': self.env['ir.model']._get('mail.test.container').id, + 'alias_name': 'bidule...inc.', + }) + self.assertEqual(alias.alias_name, 'bidule.inc', 'Emails cannot start or end with a dot, there cannot be a sequence of dots.') + + def test_alias_setup(self): + alias = self.env['mail.alias'].create({ + 'alias_model_id': self.env['ir.model']._get('mail.test.container').id, + 'alias_name': 'b4r+_#_R3wl$$', + }) + self.assertEqual(alias.alias_name, 'b4r+_-_r3wl-', 'Disallowed chars should be replaced by hyphens') + + with self.assertRaises(exceptions.ValidationError): + alias.write({'alias_defaults': "{'custom_field': brokendict"}) + + +@tagged('mail_gateway', 'mail_alias', 'multi_company') +class TestMailAliasMixin(TestMailAliasCommon): + """ Test alias mixin implementation, synchornization of alias records + based on owner records. """ + + @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', + 'alias_name': 'alias.test', + 'alias_contact': 'followers', + }) + self.assertEqual(record.alias_id.alias_model_id, self.env['ir.model']._get('mail.test.container')) + self.assertEqual(record.alias_id.alias_force_thread_id, record.id) + self.assertEqual(record.alias_id.alias_parent_model_id, self.env['ir.model']._get('mail.test.container')) + self.assertEqual(record.alias_id.alias_parent_thread_id, record.id) + self.assertEqual(record.alias_id.alias_name, 'alias.test') + self.assertEqual(record.alias_id.alias_contact, 'followers') + + record.write({ + 'alias_name': 'better.alias.test', + 'alias_defaults': "{'default_name': 'defaults'}" + }) + self.assertEqual(record.alias_id.alias_name, 'better.alias.test') + self.assertEqual(record.alias_id.alias_defaults, "{'default_name': 'defaults'}") + + with self.assertRaises(exceptions.AccessError): + record.write({ + 'alias_force_thread_id': 0, + }) + + with self.assertRaises(exceptions.AccessError): + record.write({ + 'alias_model_id': self.env['ir.model']._get('mail.test.gateway').id, + }) + + with self.assertRaises(exceptions.ValidationError): + record.write({'alias_defaults': "{'custom_field': brokendict"}) + + @users('employee') + def test_alias_mixin_copy_content(self): + self.assertFalse(self.env.user.has_group('base.group_system'), 'Test user should not have Administrator access') + + record = self.env['mail.test.container'].create({ + 'name': 'Test Record', + 'alias_name': 'test.record', + 'alias_contact': 'followers', + 'alias_bounced_content': False, + }) + self.assertFalse(record.alias_bounced_content) + record_copy = record.copy() + self.assertFalse(record_copy.alias_bounced_content) + + new_content = '

Bounced Content

' + record_copy.write({'alias_bounced_content': new_content}) + self.assertEqual(record_copy.alias_bounced_content, new_content) + record_copy2 = record_copy.copy() + self.assertEqual(record_copy2.alias_bounced_content, new_content) diff --git a/addons/test_mail/tests/test_mail_gateway.py b/addons/test_mail/tests/test_mail_gateway.py index 40857f8ef19..049e0d003a2 100644 --- a/addons/test_mail/tests/test_mail_gateway.py +++ b/addons/test_mail/tests/test_mail_gateway.py @@ -16,7 +16,6 @@ from odoo.addons.test_mail.data.test_mail_data import MAIL_TEMPLATE from odoo.addons.test_mail.models.test_mail_models import MailTestGateway from odoo.sql_db import Cursor from odoo.tests import tagged -from odoo.tests.common import users from odoo.tools import email_split_and_format, formataddr, mute_logger @@ -139,140 +138,6 @@ class TestEmailParsing(MailCommon): # Test that the parsing of XHTML mails does not fail self.env['mail.thread'].message_parse(self.from_string(test_mail_data.MAIL_XHTML)) -@tagged('mail_gateway') -class TestMailAlias(MailCommon): - - @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', - 'alias_name': 'alias.test', - 'alias_contact': 'followers', - }) - self.assertEqual(record.alias_id.alias_model_id, self.env['ir.model']._get('mail.test.container')) - self.assertEqual(record.alias_id.alias_force_thread_id, record.id) - self.assertEqual(record.alias_id.alias_parent_model_id, self.env['ir.model']._get('mail.test.container')) - self.assertEqual(record.alias_id.alias_parent_thread_id, record.id) - self.assertEqual(record.alias_id.alias_name, 'alias.test') - self.assertEqual(record.alias_id.alias_contact, 'followers') - - record.write({ - 'alias_name': 'better.alias.test', - 'alias_defaults': "{'default_name': 'defaults'}" - }) - self.assertEqual(record.alias_id.alias_name, 'better.alias.test') - self.assertEqual(record.alias_id.alias_defaults, "{'default_name': 'defaults'}") - - with self.assertRaises(exceptions.AccessError): - record.write({ - 'alias_force_thread_id': 0, - }) - - with self.assertRaises(exceptions.AccessError): - record.write({ - 'alias_model_id': self.env['ir.model']._get('mail.test.gateway').id, - }) - - with self.assertRaises(exceptions.ValidationError): - record.write({'alias_defaults': "{'custom_field': brokendict"}) - - def test_alias_domain_allowed_validation(self): - """ Check the validation of `mail.catchall.domain.allowed` system parameter""" - for value in [',', ',,', ', ,']: - with self.assertRaises(exceptions.ValidationError, - msg="The value '%s' should not be allowed" % value): - self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', value) - - for value, expected in [ - ('', False), - ('hello.com', 'hello.com'), - ('hello.com,,', 'hello.com'), - ('hello.com,bonjour.com', 'hello.com,bonjour.com'), - ('hello.COM, BONJOUR.com', 'hello.com,bonjour.com'), - ]: - self.env['ir.config_parameter'].set_param('mail.catchall.domain.allowed', value) - self.assertEqual(self.env['ir.config_parameter'].get_param('mail.catchall.domain.allowed'), expected) - - def test_alias_sanitize(self): - alias = self.env['mail.alias'].create({ - 'alias_model_id': self.env['ir.model']._get('mail.test.container').id, - 'alias_name': 'bidule...inc.', - }) - self.assertEqual(alias.alias_name, 'bidule.inc', 'Emails cannot start or end with a dot, there cannot be a sequence of dots.') - - def test_alias_setup(self): - alias = self.env['mail.alias'].create({ - 'alias_model_id': self.env['ir.model']._get('mail.test.container').id, - 'alias_name': 'b4r+_#_R3wl$$', - }) - self.assertEqual(alias.alias_name, 'b4r+_-_r3wl-', 'Disallowed chars should be replaced by hyphens') - - with self.assertRaises(exceptions.ValidationError): - alias.write({'alias_defaults': "{'custom_field': brokendict"}) - - def test_alias_name_unique(self): - 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 - 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' - }) - - # test that re-using catchall and bounce alias raises UserError - 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 - }) - - new_mail_alias.write({'alias_name': 'another.unused.test.alias'}) - - # test that duplicating an alias should have blank name - copy_new_mail_alias = new_mail_alias.copy() - self.assertFalse(copy_new_mail_alias.alias_name) - - # 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) - - -@tagged('mail_gateway') -class TestMailAliasMixin(MailCommon): - - @users('employee') - def test_alias_mixin_copy_content(self): - self.assertFalse(self.env.user.has_group('base.group_system'), 'Test user should not have Administrator access') - - record = self.env['mail.test.container'].create({ - 'name': 'Test Record', - 'alias_name': 'test.record', - 'alias_contact': 'followers', - 'alias_bounced_content': False, - }) - self.assertFalse(record.alias_bounced_content) - record_copy = record.copy() - self.assertFalse(record_copy.alias_bounced_content) - - new_content = '

Bounced Content

' - record_copy.write({'alias_bounced_content': new_content}) - self.assertEqual(record_copy.alias_bounced_content, new_content) - record_copy2 = record_copy.copy() - self.assertEqual(record_copy2.alias_bounced_content, new_content) - @tagged('mail_gateway') class TestMailgateway(MailCommon):