From 7429c61dfcd2dfda72655e33504159a637227eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 11 Oct 2018 08:41:33 +0000 Subject: [PATCH 1/9] [IMP] tests: add an helper in odoo tests in order to quickly create test users Following great @odony review we decided to add a helper method allowing to quickly create users in tests in a one-liner. It will allow to remove a lot of duplicate code in various test classes and methods. This method basically requires a login and a comma separated list of user groups xml ids. Kwargs are supported to further customize the created user. A custom context can be given to the creation as user creation in odoo can support several options within standard addons, like mailing or signup options. Next commits will propagate the use of this helper in some test classes notably in mail, hr and mass mailing. This commit is linked to task ID 1889703 and PR #27526. --- odoo/tests/common.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/odoo/tests/common.py b/odoo/tests/common.py index 19b77942de0..d1d6b413aab 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -34,6 +34,7 @@ from lxml import etree, html from odoo.models import BaseModel from odoo.osv.expression import normalize_domain from odoo.tools import pycompat +from odoo.tools import single_email_re from odoo.tools.misc import find_in_path from odoo.tools.safe_eval import safe_eval @@ -116,6 +117,50 @@ def post_install(flag): """ return tagged('post_install' if flag else '-post_install') + +def new_test_user(env, login='', groups='base.group_user', context=None, **kwargs): + """ Helper function to create a new test user. It allows to quickly create + users given its login and groups (being a comma separated list of xml ids). + Kwargs are directly propagated to the create to further customize the + created user. + + User creation uses a potentially customized environment using the context + parameter allowing to specify a custom context. It can be used to force a + specific behavior and/or simplify record creation. An example is to use + mail-related context keys in mail tests to speedup record creation. + + Some specific fields are automatically filled to avoid issues + + * groups_id: it is filled using groups function parameter; + * name: "login (groups)" by default as it is required; + * email: it is either the login (if it is a valid email) or a generated + string 'x.x@example.com' (x being the first login letter). This is due + to email being required for most odoo operations; + """ + if not login: + raise ValueError('New users require at least a login') + if not groups: + raise ValueError('New users require at least user groups') + if context is None: + context = {} + + groups_id = [(6, 0, [env.ref(g).id for g in groups.split(',')])] + create_values = dict(kwargs, login=login, groups_id=groups_id) + if not create_values.get('name'): + create_values['name'] = '%s (%s)' % (login, groups) + if not create_values.get('email'): + if single_email_re.match(login): + create_values['email'] = login + else: + create_values['email'] = '%s.%s@example.com' % (login[0], login[0]) + + return env['res.users'].with_context(**context).create(create_values) + +# ------------------------------------------------------------ +# Main classes +# ------------------------------------------------------------ + + class TreeCase(unittest.TestCase): def __init__(self, methodName='runTest'): super(TreeCase, self).__init__(methodName) @@ -315,6 +360,7 @@ class BaseCase(TreeCase, MetaCase('DummyCase', (object,), {})): def assertItemsEqual(self, a, b, msg=None): self.assertCountEqual(a, b, msg=None) + class TransactionCase(BaseCase): """ TestCase in which each test method is run in its own transaction, and with its own cursor. The transaction is rolled back and the cursor From a7b3d1697cad1a9d5801dab1736359e9caa1ba90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 11 Oct 2018 08:41:50 +0000 Subject: [PATCH 2/9] [REF] test_mail: use odoo test helper method to create test users Purpose of this commit is to use the newly introduced helper to create test users in a quick way and reduce code duplication. A mail specific helper tool function is defined based on the standard one defined in test allowing to pass a custom context. It bypasses mailing features in order to speedup the creation. This commit is linked to task ID 1889703 and PR #27526. --- addons/test_mail/tests/common.py | 41 ++++++++----------- addons/test_mail/tests/test_discuss.py | 11 ++--- addons/test_mail/tests/test_invite.py | 2 +- addons/test_mail/tests/test_mail_activity.py | 11 ++--- addons/test_mail/tests/test_mail_channel.py | 20 +++------ addons/test_mail/tests/test_mail_followers.py | 17 ++------ addons/test_mail/tests/test_mail_gateway.py | 5 ++- addons/test_mail/tests/test_mail_mail.py | 7 +--- addons/test_mail/tests/test_mail_message.py | 18 +++----- addons/test_mail/tests/test_mail_resend.py | 27 ++++-------- addons/test_mail/tests/test_mail_template.py | 3 +- .../test_mail/tests/test_message_compose.py | 28 ++++--------- addons/test_mail/tests/test_message_track.py | 2 +- addons/test_mass_mailing/tests/common.py | 2 +- 14 files changed, 61 insertions(+), 133 deletions(-) diff --git a/addons/test_mail/tests/common.py b/addons/test_mail/tests/common.py index d8e8f63dece..531bf4ea225 100644 --- a/addons/test_mail/tests/common.py +++ b/addons/test_mail/tests/common.py @@ -4,39 +4,37 @@ import json from contextlib import contextmanager from email.utils import formataddr +from functools import partial from odoo import api from odoo.addons.bus.models.bus import json_dump -from odoo.tests import common, tagged +from odoo.tests import common, tagged, new_test_user + +mail_new_test_user = partial(new_test_user, context={'mail_create_nolog': True, 'mail_create_nosubscribe': True, 'mail_notrack': True, 'no_reset_password': True}) class BaseFunctionalTest(common.SavepointCase): + _test_context = { + 'mail_create_nolog': True, + 'mail_create_nosubscribe': True, + 'mail_notrack': True, + 'no_reset_password': True + } + @classmethod def setUpClass(cls): super(BaseFunctionalTest, cls).setUpClass() - cls._quick_create_ctx = { - 'mail_create_nolog': True, - 'mail_create_nosubscribe': True, - 'mail_notrack': True, - } - cls._quick_create_user_ctx = dict(cls._quick_create_ctx, no_reset_password=True) - user_group_employee = cls.env.ref('base.group_user') - cls.user_employee = cls.env['res.users'].with_context(cls._quick_create_user_ctx).create({ - 'name': 'Ernest Employee', - 'login': 'ernest', - 'email': 'e.e@example.com', - 'signature': '--\nErnest', - 'notification_type': 'email', - 'groups_id': [(6, 0, [user_group_employee.id])]}) + cls.user_employee = mail_new_test_user(cls.env, login='ernest', groups='base.group_user', signature='--\nErnest', name='Ernest Employee') cls.partner_employee = cls.user_employee.partner_id + cls.user_admin = cls.env.ref('base.user_admin') cls.partner_admin = cls.env.ref('base.partner_admin') - cls.channel_listen = cls.env['mail.channel'].with_context(cls._quick_create_ctx).create({'name': 'Listener'}) + cls.channel_listen = cls.env['mail.channel'].with_context(cls._test_context).create({'name': 'Listener'}) - cls.test_record = cls.env['mail.test.simple'].with_context(cls._quick_create_ctx).create({'name': 'Test', 'email_from': 'ignasse@example.com'}) + cls.test_record = cls.env['mail.test.simple'].with_context(cls._test_context).create({'name': 'Test', 'email_from': 'ignasse@example.com'}) @contextmanager def assertNotifications(self, **counters): @@ -273,7 +271,6 @@ class Moderation(MockEmails, BaseFunctionalTest): def setUpClass(cls): super(Moderation, cls).setUpClass() Channel = cls.env['mail.channel'] - Users = cls.env['res.users'].with_context(cls._quick_create_user_ctx) cls.channel_moderation_1 = Channel.create({ 'name': 'Moderation_1', @@ -290,13 +287,7 @@ class Moderation(MockEmails, BaseFunctionalTest): cls.user_employee.write({'moderation_channel_ids': [(6, 0, [cls.channel_1.id])]}) - cls.user_employee_2 = Users.create({ - 'name': 'Roboute', - 'login': 'roboute', - 'email': 'roboute@guilliman.com', - 'groups_id': [(6, 0, [cls.env.ref('base.group_user').id])], - 'moderation_channel_ids': [(6, 0, [cls.channel_2.id])] - }) + cls.user_employee_2 = mail_new_test_user(cls.env, login='roboute', groups='base.group_user', moderation_channel_ids=[(6, 0, [cls.channel_2.id])]) cls.partner_employee_2 = cls.user_employee_2.partner_id cls.channel_moderation_1.write({'channel_last_seen_partner_ids': [(0, 0, {'partner_id': cls.partner_employee.id})]}) diff --git a/addons/test_mail/tests/test_discuss.py b/addons/test_mail/tests/test_discuss.py index 907f95be0e7..3f27a20f4b0 100644 --- a/addons/test_mail/tests/test_discuss.py +++ b/addons/test_mail/tests/test_discuss.py @@ -2,6 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.addons.test_mail.tests.common import BaseFunctionalTest, TestRecipients, MockEmails +from odoo.addons.test_mail.tests.common import mail_new_test_user class TestChatterTweaks(BaseFunctionalTest, TestRecipients): @@ -77,7 +78,7 @@ class TestNotifications(BaseFunctionalTest, MockEmails): def setUp(self): super(TestNotifications, self).setUp() - self.partner_1 = self.env['res.partner'].with_context(self._quick_create_ctx).create({ + self.partner_1 = self.env['res.partner'].with_context(BaseFunctionalTest._test_context).create({ 'name': 'Valid Lelitre', 'email': 'valid.lelitre@agrolait.com'}) @@ -103,13 +104,7 @@ class TestNotifications(BaseFunctionalTest, MockEmails): message.sudo(self.user_employee).set_message_done() def test_set_message_done_portal(self): - user_portal = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'notification_type': 'inbox', - 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])], - }) + user_portal = mail_new_test_user(self.env, login='chell', groups='base.group_portal', name='Chell Gladys', notification_type='inbox') self.partner_portal = user_portal.partner_id with self.assertNotifications(partner_employee=(1, 'inbox', 'unread'), partner_portal=(1, 'inbox', 'read')): diff --git a/addons/test_mail/tests/test_invite.py b/addons/test_mail/tests/test_invite.py index 4defaf1578b..544276d46b1 100644 --- a/addons/test_mail/tests/test_invite.py +++ b/addons/test_mail/tests/test_invite.py @@ -9,7 +9,7 @@ class TestInvite(common.BaseFunctionalTest, common.MockEmails): @mute_logger('odoo.addons.mail.models.mail_mail') def test_invite_email(self): - test_partner = self.env['res.partner'].with_context(self._quick_create_ctx).create({ + test_partner = self.env['res.partner'].with_context(common.BaseFunctionalTest._test_context).create({ 'name': 'Valid Lelitre', 'email': 'valid.lelitre@agrolait.com'}) diff --git a/addons/test_mail/tests/test_mail_activity.py b/addons/test_mail/tests/test_mail_activity.py index be17922a2a4..da55ebed4f7 100644 --- a/addons/test_mail/tests/test_mail_activity.py +++ b/addons/test_mail/tests/test_mail_activity.py @@ -10,8 +10,8 @@ import pytz from odoo import exceptions, tests from odoo.addons.test_mail.tests.common import BaseFunctionalTest +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.addons.test_mail.models.test_mail_models import MailTestActivity -from odoo.tools import mute_logger class TestActivityCommon(BaseFunctionalTest): @@ -19,7 +19,7 @@ class TestActivityCommon(BaseFunctionalTest): @classmethod def setUpClass(cls): super(TestActivityCommon, cls).setUpClass() - cls.test_record = cls.env['mail.test.activity'].with_context(cls._quick_create_ctx).create({'name': 'Test'}) + cls.test_record = cls.env['mail.test.activity'].with_context(BaseFunctionalTest._test_context).create({'name': 'Test'}) # reset ctx cls.test_record = cls.test_record.with_context( mail_create_nolog=False, @@ -92,12 +92,7 @@ class TestActivityFlow(TestActivityCommon): self.assertEqual(test_record.message_ids[0].subtype_id, self.env.ref('mail.mt_activities')) def test_activity_flow_portal(self): - portal_user = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])], - }) + portal_user = mail_new_test_user(self.env, login='chell', groups='base.group_portal', name='Chell Gladys') with self.sudoAs('chell'): test_record = self.env['mail.test.activity'].browse(self.test_record.id) diff --git a/addons/test_mail/tests/test_mail_channel.py b/addons/test_mail/tests/test_mail_channel.py index 395fbd7b318..74e49ce7de4 100644 --- a/addons/test_mail/tests/test_mail_channel.py +++ b/addons/test_mail/tests/test_mail_channel.py @@ -3,6 +3,7 @@ from email.utils import formataddr from odoo.tests import tagged from odoo.addons.test_mail.tests import common +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.exceptions import AccessError, except_orm, ValidationError, UserError from odoo.tools import mute_logger @@ -12,19 +13,10 @@ class TestChannelAccessRights(common.BaseFunctionalTest, common.MockEmails): @classmethod def setUpClass(cls): super(TestChannelAccessRights, cls).setUpClass() - Channel = cls.env['mail.channel'].with_context(cls._quick_create_ctx) + Channel = cls.env['mail.channel'].with_context(common.BaseFunctionalTest._test_context) - Users = cls.env['res.users'].with_context(cls._quick_create_user_ctx) - cls.user_public = Users.create({ - 'name': 'Bert Tartignole', - 'login': 'bert', - 'email': 'b.t@example.com', - 'groups_id': [(6, 0, [cls.env.ref('base.group_public').id])]}) - cls.user_portal = Users.create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [cls.env.ref('base.group_portal').id])]}) + cls.user_public = mail_new_test_user(cls.env, login='bert', groups='base.group_public', name='Bert Tartignole') + cls.user_portal = mail_new_test_user(cls.env, login='chell', groups='base.group_portal', name='Chell Gladys') # Pigs: base group for tests cls.group_pigs = Channel.create({ @@ -118,13 +110,13 @@ class TestChannelFeatures(common.BaseFunctionalTest, common.MockEmails): @classmethod def setUpClass(cls): super(TestChannelFeatures, cls).setUpClass() - cls.test_channel = cls.env['mail.channel'].with_context(cls._quick_create_ctx).create({ + cls.test_channel = cls.env['mail.channel'].with_context(common.BaseFunctionalTest._test_context).create({ 'name': 'Test', 'description': 'Description', 'alias_name': 'test', 'public': 'public', }) - cls.test_partner = cls.env['res.partner'].with_context(cls._quick_create_ctx).create({ + cls.test_partner = cls.env['res.partner'].with_context(common.BaseFunctionalTest._test_context).create({ 'name': 'Test Partner', 'email': 'test@example.com', }) diff --git a/addons/test_mail/tests/test_mail_followers.py b/addons/test_mail/tests/test_mail_followers.py index 06b0b183197..ad16eff2fee 100644 --- a/addons/test_mail/tests/test_mail_followers.py +++ b/addons/test_mail/tests/test_mail_followers.py @@ -4,6 +4,7 @@ from psycopg2 import IntegrityError from odoo.addons.test_mail.tests import common +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.tools.misc import mute_logger @@ -53,12 +54,7 @@ class BaseFollowersTest(common.BaseFunctionalTest): self.assertEqual(follower.subtype_ids, self.default_group_subtypes) def test_followers_subtypes_default_internal(self): - user_portal = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])] - }) + user_portal = mail_new_test_user(self.env, login='chell', groups='base.group_portal', name='Chell Gladys') test_record = self.test_record.sudo(self.user_employee) test_record.message_subscribe(partner_ids=[user_portal.partner_id.id]) @@ -125,12 +121,7 @@ class AdvancedFollowersTest(common.BaseFunctionalTest): def setUpClass(cls): super(AdvancedFollowersTest, cls).setUpClass() - cls.user_portal = cls.env['res.users'].with_context(cls._quick_create_user_ctx).create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [cls.env.ref('base.group_portal').id])], - }) + cls.user_portal = mail_new_test_user(cls.env, login='chell', groups='base.group_portal', name='Chell Gladys') cls.test_track = cls.env['mail.test.track'].sudo(cls.user_employee).create({ 'name': 'Test', @@ -192,7 +183,7 @@ class AdvancedFollowersTest(common.BaseFunctionalTest): * subscribing to a sub-record as creator applies default subtype values * portal user should not have access to internal subtypes """ - umbrella = self.env['mail.test'].with_context(self._quick_create_ctx).create({ + umbrella = self.env['mail.test'].with_context(common.BaseFunctionalTest._test_context).create({ 'name': 'Project-Like', }) diff --git a/addons/test_mail/tests/test_mail_gateway.py b/addons/test_mail/tests/test_mail_gateway.py index f24ee44fa3e..9a8d9e6411f 100644 --- a/addons/test_mail/tests/test_mail_gateway.py +++ b/addons/test_mail/tests/test_mail_gateway.py @@ -9,6 +9,7 @@ from odoo.addons.test_mail.data.test_mail_data import \ MAIL_TEMPLATE, MAIL_TEMPLATE_PLAINTEXT, MAIL_MULTIPART_MIXED, MAIL_MULTIPART_MIXED_TWO, \ MAIL_MULTIPART_IMAGE, MAIL_SINGLE_BINARY, MAIL_EML_ATTACHMENT, MAIL_XHTML from odoo.addons.test_mail.tests.common import BaseFunctionalTest, MockEmails +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.tools import mute_logger @@ -57,7 +58,7 @@ class TestMailgateway(BaseFunctionalTest, MockEmails): super(TestMailgateway, cls).setUpClass() mail_test_simple_model = cls.env['ir.model']._get('mail.test.simple') - cls.partner_1 = cls.env['res.partner'].with_context(cls._quick_create_ctx).create({ + cls.partner_1 = cls.env['res.partner'].with_context(BaseFunctionalTest._test_context).create({ 'name': 'Valid Lelitre', 'email': 'valid.lelitre@agrolait.com', }) @@ -431,7 +432,7 @@ class TestMailgateway(BaseFunctionalTest, MockEmails): self.assertEqual(self.test_record.message_ids[0].author_id, from_1) self.test_record.message_unsubscribe([from_1.id]) - from_2 = self.env['res.users'].with_context(self._quick_create_user_ctx).create({'name': 'Brice Denisse', 'login': 'B', 'email': 'from.test@example.com'}) + from_2 = mail_new_test_user(self.env, login='B', groups='base.group_user', name='Brice Denisse', email='from.test@example.com') self.format_and_process(MAIL_TEMPLATE, msg_id='<2>', email_from='Brice Denisse ') self.assertEqual(self.test_record.message_ids[0].author_id, from_2.partner_id) diff --git a/addons/test_mail/tests/test_mail_mail.py b/addons/test_mail/tests/test_mail_mail.py index 4debd669874..207cc80d26f 100644 --- a/addons/test_mail/tests/test_mail_mail.py +++ b/addons/test_mail/tests/test_mail_mail.py @@ -15,12 +15,7 @@ class TestMail(common.SavepointCase, mail_common.MockEmails): def setUpClass(cls): super(TestMail, cls).setUpClass() - cls.user_employee = cls.env['res.users'].with_context({ - 'no_reset_password': True, - 'mail_create_nolog': True, - 'mail_create_nosubscribe': True, - 'mail_notrack': True, - }).create({ + cls.user_employee = cls.env['res.users'].with_context(mail_common.BaseFunctionalTest._test_context).create({ 'name': 'Ernest Employee', 'login': 'ernest', 'email': 'e.e@example.com', diff --git a/addons/test_mail/tests/test_mail_message.py b/addons/test_mail/tests/test_mail_message.py index 94540272b4e..ac38d2d00e1 100644 --- a/addons/test_mail/tests/test_mail_message.py +++ b/addons/test_mail/tests/test_mail_message.py @@ -3,6 +3,7 @@ import base64 from odoo.addons.test_mail.tests import common +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.exceptions import AccessError, except_orm from odoo.tools import mute_logger from odoo.tests import tagged @@ -14,7 +15,7 @@ class TestMessageValues(common.BaseFunctionalTest, common.MockEmails): def setUpClass(cls): super(TestMessageValues, cls).setUpClass() - cls.alias_record = cls.env['mail.test'].with_context(cls._quick_create_ctx).create({ + cls.alias_record = cls.env['mail.test'].with_context(common.BaseFunctionalTest._test_context).create({ 'name': 'Pigs', 'alias_name': 'pigs', 'alias_contact': 'followers', @@ -128,19 +129,10 @@ class TestMessageAccess(common.BaseFunctionalTest, common.MockEmails): def setUpClass(cls): super(TestMessageAccess, cls).setUpClass() - Users = cls.env['res.users'].with_context(cls._quick_create_user_ctx) - cls.user_public = Users.create({ - 'name': 'Bert Tartignole', - 'login': 'bert', - 'email': 'b.t@example.com', - 'groups_id': [(6, 0, [cls.env.ref('base.group_public').id])]}) - cls.user_portal = Users.create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [cls.env.ref('base.group_portal').id])]}) + cls.user_public = mail_new_test_user(cls.env, login='bert', groups='base.group_public', name='Bert Tartignole') + cls.user_portal = mail_new_test_user(cls.env, login='chell', groups='base.group_portal', name='Chell Gladys') - Channel = cls.env['mail.channel'].with_context(cls._quick_create_ctx) + Channel = cls.env['mail.channel'].with_context(common.BaseFunctionalTest._test_context) # Pigs: base group for tests cls.group_pigs = Channel.create({ 'name': 'Pigs', diff --git a/addons/test_mail/tests/test_mail_resend.py b/addons/test_mail/tests/test_mail_resend.py index 973212b8611..4ec7e9e6cb5 100644 --- a/addons/test_mail/tests/test_mail_resend.py +++ b/addons/test_mail/tests/test_mail_resend.py @@ -4,11 +4,12 @@ import itertools from unittest.mock import patch -from odoo.addons.test_mail.tests import common -from odoo.tests import tagged -from odoo.tools import mute_logger from odoo import api from odoo.addons.base.models.ir_mail_server import IrMailServer +from odoo.addons.test_mail.tests import common +from odoo.addons.test_mail.tests.common import mail_new_test_user +from odoo.tests import tagged +from odoo.tools import mute_logger @tagged('resend_test') @@ -18,26 +19,14 @@ class TestMailResend(common.BaseFunctionalTest, common.MockEmails): def setUpClass(cls): super(TestMailResend, cls).setUpClass() #Two users - cls.user1 = cls.env['res.users'].with_context(cls._quick_create_user_ctx).create({ - 'name': 'Employee 1', - 'login': 'e1', - 'email': 'e1', # invalid email - 'notification_type': 'email', - 'groups_id': [(6, 0, [cls.env.ref('base.group_user').id])] - }) - cls.user2 = cls.env['res.users'].with_context(cls._quick_create_user_ctx).create({ - 'name': 'Employee 2', - 'login': 'e2', - 'email': 'e2@example.com', - 'notification_type': 'email', - 'groups_id': [(6, 0, [cls.env.ref('base.group_user').id])] - }) + cls.user1 = mail_new_test_user(cls.env, login='e1', groups='base.group_public', name='Employee 1', email='e1') # invalid email + cls.user2 = mail_new_test_user(cls.env, login='e2', groups='base.group_portal', name='Employee 2', email='e2@example.com') #Two partner - cls.partner1 = cls.env['res.partner'].with_context(cls._quick_create_user_ctx).create({ + cls.partner1 = cls.env['res.partner'].with_context(common.BaseFunctionalTest._test_context).create({ 'name': 'Partner 1', 'email': 'p1' # invalid email }) - cls.partner2 = cls.env['res.partner'].with_context(cls._quick_create_user_ctx).create({ + cls.partner2 = cls.env['res.partner'].with_context(common.BaseFunctionalTest._test_context).create({ 'name': 'Partner 2', 'email': 'p2@example.com' }) diff --git a/addons/test_mail/tests/test_mail_template.py b/addons/test_mail/tests/test_mail_template.py index 388e669b730..49a05c44055 100644 --- a/addons/test_mail/tests/test_mail_template.py +++ b/addons/test_mail/tests/test_mail_template.py @@ -5,6 +5,7 @@ import base64 from datetime import datetime, timedelta from odoo.addons.test_mail.tests.common import BaseFunctionalTest, MockEmails, TestRecipients +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.tools import mute_logger, DEFAULT_SERVER_DATETIME_FORMAT @@ -84,7 +85,7 @@ class TestMailTemplate(BaseFunctionalTest, MockEmails, TestRecipients): @mute_logger('odoo.addons.mail.models.mail_mail') def test_composer_w_template_mass_mailing(self): - test_record_2 = self.env['mail.test.simple'].with_context(self._quick_create_ctx).create({'name': 'Test2', 'email_from': 'laurie.poiret@example.com'}) + test_record_2 = self.env['mail.test.simple'].with_context(BaseFunctionalTest._test_context).create({'name': 'Test2', 'email_from': 'laurie.poiret@example.com'}) composer = self.env['mail.compose.message'].sudo(self.user_employee).with_context({ 'default_composition_mode': 'mass_mail', diff --git a/addons/test_mail/tests/test_message_compose.py b/addons/test_mail/tests/test_message_compose.py index 7620f6fa4a4..859dfa2a715 100644 --- a/addons/test_mail/tests/test_message_compose.py +++ b/addons/test_mail/tests/test_message_compose.py @@ -7,6 +7,7 @@ from email.utils import formataddr from unittest.mock import patch from odoo.addons.test_mail.tests.common import BaseFunctionalTest, MockEmails, TestRecipients +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.addons.test_mail.data.test_mail_data import MAIL_TEMPLATE_PLAINTEXT from odoo.addons.test_mail.models.test_mail_models import MailTestSimple from odoo.exceptions import AccessError @@ -152,12 +153,7 @@ class TestMessagePost(BaseFunctionalTest, MockEmails, TestRecipients): @mute_logger('odoo.addons.mail.models.mail_mail') def test_post_portal_ok(self): - portal_user = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])], - }) + portal_user = mail_new_test_user(self.env, login='chell', groups='base.group_portal', name='Chell Gladys') with patch.object(MailTestSimple, 'check_access_rights', return_value=True): self.test_record.message_subscribe((self.partner_1 | self.user_employee.partner_id).ids) @@ -169,12 +165,7 @@ class TestMessagePost(BaseFunctionalTest, MockEmails, TestRecipients): self.assertEmails(portal_user.partner_id, [[self.partner_1], [self.user_employee.partner_id]]) def test_post_portal_crash(self): - portal_user = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])], - }) + portal_user = mail_new_test_user(self.env, login='chell', groups='base.group_portal', name='Chell Gladys') with self.assertRaises(AccessError): self.test_record.sudo(portal_user).message_post( @@ -278,7 +269,7 @@ class TestComposer(BaseFunctionalTest, MockEmails, TestRecipients): @mute_logger('odoo.addons.mail.models.mail_mail') def test_composer_mass_mail(self): - test_record_2 = self.env['mail.test.simple'].with_context(self._quick_create_ctx).create({'name': 'Test2'}) + test_record_2 = self.env['mail.test.simple'].with_context(BaseFunctionalTest._test_context).create({'name': 'Test2'}) composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', @@ -313,7 +304,7 @@ class TestComposer(BaseFunctionalTest, MockEmails, TestRecipients): @mute_logger('odoo.addons.mail.models.mail_mail') def test_composer_mass_mail_active_domain(self): - test_record_2 = self.env['mail.test.simple'].with_context(self._quick_create_ctx).create({'name': 'Test2'}) + test_record_2 = self.env['mail.test.simple'].with_context(BaseFunctionalTest._test_context).create({'name': 'Test2'}) self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', @@ -331,7 +322,7 @@ class TestComposer(BaseFunctionalTest, MockEmails, TestRecipients): @mute_logger('odoo.addons.mail.models.mail_mail') def test_message_compose_mass_mail_no_active_domain(self): - test_record_2 = self.env['mail.test.simple'].with_context(self._quick_create_ctx).create({'name': 'Test2'}) + test_record_2 = self.env['mail.test.simple'].with_context(BaseFunctionalTest._test_context).create({'name': 'Test2'}) self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', @@ -349,12 +340,7 @@ class TestComposer(BaseFunctionalTest, MockEmails, TestRecipients): @mute_logger('odoo.addons.mail.models.mail_mail') def test_message_compose_portal_ok(self): - portal_user = self.env['res.users'].with_context(self._quick_create_ctx).create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])], - }) + portal_user = mail_new_test_user(self.env, login='chell', groups='base.group_portal', name='Chell Gladys') with patch.object(MailTestSimple, 'check_access_rights', return_value=True): ComposerPortal = self.env['mail.compose.message'].sudo(portal_user) diff --git a/addons/test_mail/tests/test_message_track.py b/addons/test_mail/tests/test_message_track.py index faae6afcd57..25cd5a7a3c3 100644 --- a/addons/test_mail/tests/test_message_track.py +++ b/addons/test_mail/tests/test_message_track.py @@ -26,7 +26,7 @@ class TestTracking(common.BaseFunctionalTest, common.MockEmails): def setUp(self): super(TestTracking, self).setUp() - record = self.env['mail.test.full'].sudo(self.user_employee).with_context(self._quick_create_ctx).create({ + record = self.env['mail.test.full'].sudo(self.user_employee).with_context(common.BaseFunctionalTest._test_context).create({ 'name': 'Test', }) self.record = record.with_context(mail_notrack=False) diff --git a/addons/test_mass_mailing/tests/common.py b/addons/test_mass_mailing/tests/common.py index 88a4ceb0735..0933f6eb341 100644 --- a/addons/test_mass_mailing/tests/common.py +++ b/addons/test_mass_mailing/tests/common.py @@ -17,7 +17,7 @@ class MassMailingCase(common.MockEmails, common.BaseFunctionalTest): 'login': 'emp', }) - cls.user_marketing = cls.env['res.users'].with_context(cls._quick_create_user_ctx).create({ + cls.user_marketing = cls.env['res.users'].with_context(cls._create_context('res.users')).create({ 'name': 'Ernest Employee', 'login': 'marketing', 'email': 'e.e@example.com', From dc2ade763a9479da2dfcc5493ab4fe43b2b0a8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 11 Oct 2018 10:30:57 +0000 Subject: [PATCH 3/9] [REF] hr, hr_holidays: use odoo test helper method to create test users Purpose of this commit is to use the newly introduced helper to create test users in a quick way and reduce code duplication. This commit is linked to task ID 1889703 and PR #27526. --- addons/hr/tests/common.py | 16 ++--------- addons/hr_holidays/tests/common.py | 43 +++++++----------------------- 2 files changed, 12 insertions(+), 47 deletions(-) diff --git a/addons/hr/tests/common.py b/addons/hr/tests/common.py index f84b7d85fc3..74aae9fccd0 100644 --- a/addons/hr/tests/common.py +++ b/addons/hr/tests/common.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.tests import common @@ -9,17 +10,4 @@ class TestHrCommon(common.TransactionCase): def setUp(self): super(TestHrCommon, self).setUp() - self._quick_create_ctx = { - 'mail_create_nolog': True, - 'mail_create_nosubscribe': True, - 'mail_notrack': True, - } - self._quick_create_user_ctx = dict(self._quick_create_ctx, no_reset_password=True) - - self.res_users_hr_officer = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ - 'name': 'HR Officer', - 'login': 'hro', - 'email': 'hro@example.com', - 'company_id': self.ref('base.main_company'), - 'groups_id': [(6, 0, [self.ref('base.group_user'), self.ref('hr.group_hr_user')])] - }) + self.res_users_hr_officer = mail_new_test_user(self.env, login='hro', groups='base.group_user,hr.group_hr_user', name='HR Officer', email='hro@example.com') diff --git a/addons/hr_holidays/tests/common.py b/addons/hr_holidays/tests/common.py index 43c5df67181..0f9c6f1cc89 100644 --- a/addons/hr_holidays/tests/common.py +++ b/addons/hr_holidays/tests/common.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.tests import common @@ -9,42 +10,18 @@ class TestHrHolidaysBase(common.TransactionCase): def setUp(self): super(TestHrHolidaysBase, self).setUp() - self._quick_create_ctx = { - 'mail_create_nolog': True, - 'mail_create_nosubscribe': True, - 'mail_notrack': True, - } - self._quick_create_user_ctx = dict(self._quick_create_ctx, no_reset_password=True) - # Test users to use through the various tests - Users = self.env['res.users'].with_context(self._quick_create_user_ctx) - self.user_hruser = Users.create({ - 'name': 'Armande HrUser', - 'login': 'Armande', - 'email': 'armande.hruser@example.com', - 'groups_id': [(6, 0, [self.ref('base.group_user'), self.ref('hr_holidays.group_hr_holidays_user')])] - }) + self.user_hruser = mail_new_test_user(self.env, login='armande', groups='base.group_user,hr_holidays.group_hr_holidays_user') self.user_hruser_id = self.user_hruser.id - self.user_hrmanager = Users.create({ - 'name': 'Bastien HrManager', - 'login': 'bastien', - 'email': 'bastien.hrmanager@example.com', - 'groups_id': [(6, 0, [self.ref('base.group_user'), self.ref('hr_holidays.group_hr_holidays_manager')])] - }).id - self.user_hrmanager_id = self.user_hrmanager - self.user_employee = Users.create({ - 'name': 'David Employee', - 'login': 'david', - 'email': 'david.employee@example.com', - 'groups_id': [(6, 0, [self.ref('base.group_user')])] - }) + + self.user_hrmanager = mail_new_test_user(self.env, login='bastien', groups='base.group_user,hr_holidays.group_hr_holidays_manager') + self.user_hrmanager_id = self.user_hrmanager.id + + self.user_employee = mail_new_test_user(self.env, login='david', groups='base.group_user') self.user_employee_id = self.user_employee.id - self.user_hrmanager_2_id = Users.create({ - 'name': 'Florence HrManager', - 'login': 'florence', - 'email': 'florence.hrmanager@example.com', - 'groups_id': [(6, 0, [self.ref('base.group_user'), self.ref('hr_holidays.group_hr_holidays_manager')])] - }).id + + self.user_hrmanager_2 = mail_new_test_user(self.env, login='florence', groups='base.group_user,hr_holidays.group_hr_holidays_manager') + self.user_hrmanager_2_id = self.user_hrmanager_2.id # Hr Data Department = self.env['hr.department'].with_context(tracking_disable=True) From 397434a75d17dae89dadaac6d028226ceca812ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 11 Oct 2018 08:42:11 +0000 Subject: [PATCH 4/9] [REF] test_mass_mailing: use odoo test helper method to create test users Purpose of this commit is to use the newly introduced helper to create test users in a quick way and reduce code duplication. This commit is linked to task ID 1889703 and PR #27526. --- addons/test_mass_mailing/tests/common.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/addons/test_mass_mailing/tests/common.py b/addons/test_mass_mailing/tests/common.py index 0933f6eb341..b0a7e3985d6 100644 --- a/addons/test_mass_mailing/tests/common.py +++ b/addons/test_mass_mailing/tests/common.py @@ -2,6 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.addons.test_mail.tests import common +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.tests import tagged @@ -17,14 +18,7 @@ class MassMailingCase(common.MockEmails, common.BaseFunctionalTest): 'login': 'emp', }) - cls.user_marketing = cls.env['res.users'].with_context(cls._create_context('res.users')).create({ - 'name': 'Ernest Employee', - 'login': 'marketing', - 'email': 'e.e@example.com', - 'signature': '--\nErnest', - 'notification_type': 'email', - 'groups_id': [ - (6, 0, [cls.env.ref('base.group_user').id]), - (6, 0, [cls.env.ref('mass_mailing.group_mass_mailing_user').id]) - ], - }) + cls.user_marketing = mail_new_test_user( + cls.env, login='marketing', + groups='base.group_user,mass_mailing.group_mass_mailing_user', + name='Martial Marketing', signature='--\nMartial') From 78f14a0aef34c7749a59b3478314242d21e9c2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 3 Oct 2018 12:53:14 +0000 Subject: [PATCH 5/9] [MOV][REF] test_mass_mailing: move and clean blacklist access rights tests Purpose is to continue the move of some tests from mass_mailing to test_mass_mailing done at https://github.com/odoo/odoo/commit/0c37eb272fba1063444f0ec91db1fe543c1beebf. Some additional cases are added in the parsing of blacklist entries to test some corner cases. This commit is linked to task ID 1889703 and PR #27526. --- addons/mass_mailing/tests/__init__.py | 1 - .../tests/test_blacklist_access_rights.py | 142 ------------------ .../test_mass_mailing/tests/test_blacklist.py | 55 ++++++- 3 files changed, 53 insertions(+), 145 deletions(-) delete mode 100644 addons/mass_mailing/tests/test_blacklist_access_rights.py diff --git a/addons/mass_mailing/tests/__init__.py b/addons/mass_mailing/tests/__init__.py index 9c7151327be..d586fa96bc5 100644 --- a/addons/mass_mailing/tests/__init__.py +++ b/addons/mass_mailing/tests/__init__.py @@ -4,6 +4,5 @@ from . import test_mass_mailing_list_merge from . import test_mass_mailing_content from . import test_mail_auto_blacklist -from . import test_blacklist_access_rights from . import test_mass_mailing from . import test_blacklisted_channel_partner diff --git a/addons/mass_mailing/tests/test_blacklist_access_rights.py b/addons/mass_mailing/tests/test_blacklist_access_rights.py deleted file mode 100644 index a9c74bf5c62..00000000000 --- a/addons/mass_mailing/tests/test_blacklist_access_rights.py +++ /dev/null @@ -1,142 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo.exceptions import AccessError -from odoo.tests import common - - -class TestAccessRights(common.TransactionCase): - - def setUp(self): - super(TestAccessRights, self).setUp() - - users = self.env['res.users'].with_context(no_reset_password=True) - partners = self.env['res.partner'].with_context(no_reset_password=True) - mass_mailing_contacts = self.env['mail.mass_mailing.contact'].with_context(no_reset_password=True) - - group_user = self.env.ref('mass_mailing.group_mass_mailing_user') - - # Clear blacklist - blacklist = self.env['mail.blacklist'].sudo().search([]) - i = len(blacklist) - while i != 0: - blacklist[i-1].sudo().unlink() - i -= 1 - - # Create users - self.user_mm_user = users.create({ - 'name': 'Andrew User', - 'login': 'user', - 'email': 'a.m@example.com', - 'groups_id': [(6, 0, [group_user.id])] - }) - self.user_employee = users.create({ - 'name': 'Bert Tartignole', - 'login': 'bert', - 'email': 'b.t@example.com', - 'groups_id': [(6, 0, [self.env.ref('base.group_user').id])] - }) - self.user_portal = users.create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])] - }) - self.contact_blacklisted = mass_mailing_contacts.create({ - 'name': 'Jack Black', - 'email': 'contact@black.list' - }) - self.partner_blacklisted = partners.create({ - 'name': 'Joe Black', - 'email': 'test@black.list' - }) - - # Create a blacklist entry - self.blacklist_entry = self.env['mail.blacklist'].create({ - 'email': 'test@black.list', - }) - self.blacklist_contact_entry = self.env['mail.blacklist'].create({ - 'email': 'contact@black.list', - }) - - def test_access_mass_mailing_user(self): - """ Test Mass Mailing user's access rights """ - # =================== - # Test on res_partner - # =================== - # mass mailing user can see a blacklist entry - self.blacklist_entry.sudo(self.user_mm_user).read() - # mass mailing user can edit a blacklist entry - self.blacklist_entry.sudo(self.user_mm_user).write({'email': 'edit@black.list'}) - # mass mailing user can create a blacklist entry - self.env['mail.blacklist'].sudo(self.user_mm_user).create({ - 'email': 'another@black.list', - }) - self.assertTrue(len(self.env['mail.blacklist'].search([])) == 3, - 'Number of blacklisted address incorrect, should be equals to 3') - # mass mailing user can delete a blacklist entry - self.blacklist_entry.sudo(self.user_mm_user).unlink() - self.assertTrue(len(self.env['mail.blacklist'].search([])) == 2, - 'Number of blacklisted address incorrect, should be equals to 2') - - # mass mailing user can see if user is balcklisted using mixin - self.assertFalse(self.partner_blacklisted.sudo(self.user_mm_user).is_blacklisted, - 'Blacklist state incorrect. Should not be blacklisted.') - - # ============================ - # Test on mass mailing contact - # ============================ - self.blacklist_contact_entry.sudo(self.user_mm_user).read() - self.blacklist_contact_entry.sudo(self.user_mm_user).write({'email': 'edit@black.list'}) - self.env['mail.blacklist'].sudo(self.user_mm_user).create({ - 'email': 'again_another@black.list', - }) - self.assertTrue(len(self.env['mail.blacklist'].search([])) == 3, - 'Number of blacklisted address incorrect, should be equals to 3') - self.blacklist_contact_entry.sudo(self.user_mm_user).unlink() - self.assertTrue(len(self.env['mail.blacklist'].search([])) == 2, - 'Number of blacklisted address incorrect, should be equals to 2') - - def test_access_portal_user(self): - """ Test portal user's access rights """ - # Portal user can't see blacklist entries - with self.assertRaises(AccessError): - self.blacklist_entry.sudo(self.user_portal).read() - # Portal user can't edit a blacklist entry - with self.assertRaises(AccessError): - self.blacklist_entry.sudo(self.user_portal).write({'email': 'test@edit.be'}) - # Portal user can't create a blacklist entry - with self.assertRaises(AccessError): - self.env['mail.blacklist'].sudo(self.user_portal).create({ - 'email': 'another@black.list', - }) - # Portal user can't delete a blacklist entry - with self.assertRaises(AccessError): - self.blacklist_entry.sudo(self.user_portal).unlink() - - # Portal user can't see if user is balcklisted using mixin - with self.assertRaises(AccessError): - self.partner_blacklisted.sudo(self.user_portal).is_blacklisted() - self.assertTrue(len(self.env['mail.blacklist'].search([])) == 2, - 'Number of blacklisted address incorrect, should be equals to 2') - - def test_access_employee(self): - """ Test classic employee's access rights """ - # Employee can't see blacklist entries - with self.assertRaises(AccessError): - self.blacklist_entry.sudo(self.user_employee).read() - # Employee can't edit a blacklist entry - with self.assertRaises(AccessError): - self.blacklist_entry.sudo(self.user_employee).write({'email': 'test@edit.be'}) - # Employee can't create a blacklist entry - with self.assertRaises(AccessError): - self.env['mail.blacklist'].sudo(self.user_employee).create({ - 'email': 'another@black.list', - }) - # Employee can't delete a blacklist entry - with self.assertRaises(AccessError): - self.blacklist_entry.sudo(self.user_employee).unlink() - - # Employee can see if user is balcklisted using mixin - self.assertTrue(self.partner_blacklisted.sudo(self.user_employee).is_blacklisted, - 'Blacklist state incorrect. Should be blacklisted.') diff --git a/addons/test_mass_mailing/tests/test_blacklist.py b/addons/test_mass_mailing/tests/test_blacklist.py index 5032bd1e336..651888653f9 100644 --- a/addons/test_mass_mailing/tests/test_blacklist.py +++ b/addons/test_mass_mailing/tests/test_blacklist.py @@ -2,21 +2,63 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.tests.common import users +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.addons.test_mass_mailing.tests import common from odoo.exceptions import AccessError class TestBLAccessRights(common.MassMailingCase): + def setUp(self): + super(TestBLAccessRights, self).setUp() + self.bl_rec = self.env['mail.blacklist'].create([ + {'email': 'Not A Stark '}, + ]) + + self.user_portal = mail_new_test_user(self.env, login='port', groups='base.group_portal') + + self.bl_previous = self.env['mail.blacklist'].search([]) + @users('emp') - def test_bl_create_employee(self): + def test_bl_crud_employee(self): with self.assertRaises(AccessError): self.env['mail.blacklist'].create([{'email': 'Arya.Stark@example.com'}]) + with self.assertRaises(AccessError): + self.bl_rec.sudo(self.env.user).read([]) + + with self.assertRaises(AccessError): + self.bl_rec.sudo(self.env.user).write({'email': 'jaimie.lannister@example.com'}) + + with self.assertRaises(AccessError): + self.bl_rec.sudo(self.env.user).unlink() + + @users('port') + def test_bl_crud_portal(self): + with self.assertRaises(AccessError): + self.env['mail.blacklist'].create([{'email': 'Arya.Stark@example.com'}]) + + with self.assertRaises(AccessError): + self.bl_rec.sudo(self.env.user).read([]) + + with self.assertRaises(AccessError): + self.bl_rec.sudo(self.env.user).write({'email': 'jaimie.lannister@example.com'}) + + with self.assertRaises(AccessError): + self.bl_rec.sudo(self.env.user).unlink() + @users('marketing') - def test_bl_create_marketing(self): + def test_bl_crud_marketing(self): self.env['mail.blacklist'].create([{'email': 'Arya.Stark@example.com'}]) + read_res = self.bl_rec.sudo(self.env.user).read([]) + self.assertEqual(read_res[0]['id'], self.bl_rec.id) + + self.bl_rec.sudo(self.env.user).write({'email': 'jaimie.lannister@example.com'}) + self.assertEqual(self.bl_rec.email, 'jaimie.lannister@example.com') + + self.bl_rec.sudo(self.env.user).unlink() + class TestBLConsistency(common.MassMailingCase): _base_list = ['Arya.Stark@example.com', 'ned.stark@example.com'] @@ -101,6 +143,15 @@ class TestBLConsistency(common.MassMailingCase): search_res = self.env['mail.blacklist'].search([('email', '=', 'Not A Stark ')]) self.assertEqual(search_res, self.bl_rec) + search_res = self.env['mail.blacklist'].search([('email', '=', '"John J. Snow" ')]) + self.assertEqual(search_res, self.bl_rec) + + search_res = self.env['mail.blacklist'].search([('email', '=', 'Aegon? ')]) + self.assertEqual(search_res, self.bl_rec) + + search_res = self.env['mail.blacklist'].search([('email', '=', '"John; \"You know Nothing\" Snow" ')]) + self.assertEqual(search_res, self.bl_rec) + @users('marketing') def test_bl_search_case(self): search_res = self.env['mail.blacklist'].search([('email', '=', 'john.SNOW@example.COM>')]) From 96fbc1a95773ded0da26900f9621c1c12e777492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 17 Oct 2018 13:06:22 +0000 Subject: [PATCH 6/9] [MOV] (test_)mass_mailing: move not mass-mailing models specific tests Purpose of this commit is to move tests not completely specific to some mass mailing models to test_mass_mailing. Purpose is to allow to write more in-depth tests based on existing ones by using test models instead of some standard odoo ones. This commit is linked to task ID 1889703 and PR #27526. --- addons/mass_mailing/tests/__init__.py | 4 ---- addons/test_mass_mailing/tests/__init__.py | 4 ++++ .../tests/test_composer.py} | 0 .../tests/test_mail_auto_blacklist.py | 0 .../tests/test_mail_channel.py} | 0 .../tests/test_mass_mailing.py | 0 6 files changed, 4 insertions(+), 4 deletions(-) rename addons/{mass_mailing/tests/test_mass_mailing_content.py => test_mass_mailing/tests/test_composer.py} (100%) rename addons/{mass_mailing => test_mass_mailing}/tests/test_mail_auto_blacklist.py (100%) rename addons/{mass_mailing/tests/test_blacklisted_channel_partner.py => test_mass_mailing/tests/test_mail_channel.py} (100%) rename addons/{mass_mailing => test_mass_mailing}/tests/test_mass_mailing.py (100%) diff --git a/addons/mass_mailing/tests/__init__.py b/addons/mass_mailing/tests/__init__.py index d586fa96bc5..b02648f85eb 100644 --- a/addons/mass_mailing/tests/__init__.py +++ b/addons/mass_mailing/tests/__init__.py @@ -2,7 +2,3 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import test_mass_mailing_list_merge -from . import test_mass_mailing_content -from . import test_mail_auto_blacklist -from . import test_mass_mailing -from . import test_blacklisted_channel_partner diff --git a/addons/test_mass_mailing/tests/__init__.py b/addons/test_mass_mailing/tests/__init__.py index 971e2a02ae1..caed78c5432 100644 --- a/addons/test_mass_mailing/tests/__init__.py +++ b/addons/test_mass_mailing/tests/__init__.py @@ -3,3 +3,7 @@ from . import test_blacklist from . import test_blacklist_mixin +from . import test_composer +from . import test_mail_auto_blacklist +from . import test_mail_channel +from . import test_mass_mailing diff --git a/addons/mass_mailing/tests/test_mass_mailing_content.py b/addons/test_mass_mailing/tests/test_composer.py similarity index 100% rename from addons/mass_mailing/tests/test_mass_mailing_content.py rename to addons/test_mass_mailing/tests/test_composer.py diff --git a/addons/mass_mailing/tests/test_mail_auto_blacklist.py b/addons/test_mass_mailing/tests/test_mail_auto_blacklist.py similarity index 100% rename from addons/mass_mailing/tests/test_mail_auto_blacklist.py rename to addons/test_mass_mailing/tests/test_mail_auto_blacklist.py diff --git a/addons/mass_mailing/tests/test_blacklisted_channel_partner.py b/addons/test_mass_mailing/tests/test_mail_channel.py similarity index 100% rename from addons/mass_mailing/tests/test_blacklisted_channel_partner.py rename to addons/test_mass_mailing/tests/test_mail_channel.py diff --git a/addons/mass_mailing/tests/test_mass_mailing.py b/addons/test_mass_mailing/tests/test_mass_mailing.py similarity index 100% rename from addons/mass_mailing/tests/test_mass_mailing.py rename to addons/test_mass_mailing/tests/test_mass_mailing.py From 7edcbfec389da5ba613f7ec0607e05224bc39052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 17 Oct 2018 13:10:33 +0000 Subject: [PATCH 7/9] [REF] test_mass_mailing: use odoo test helper method to create test users Purpose of this commit is to use the newly introduced helper to create test users in a quick way and reduce code duplication. This commit is linked to task ID 1889703 and PR #27526. --- .../test_mass_mailing/tests/test_composer.py | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/addons/test_mass_mailing/tests/test_composer.py b/addons/test_mass_mailing/tests/test_composer.py index 20fa50aeee5..26a16d9dd77 100644 --- a/addons/test_mass_mailing/tests/test_composer.py +++ b/addons/test_mass_mailing/tests/test_composer.py @@ -1,36 +1,27 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.test_mail.tests.common import mail_new_test_user from odoo.tests import common -class TestResponsiveMail(common.SavepointCase): +class TestComposer(common.SavepointCase): - def test_responsive_mail(self): + def test_body_responsive(self): """ Testing mail mailing responsive mail body """ - self.user_employee = self.env['res.users'].with_context({ - 'mail_create_nolog': True, - 'mail_create_nosubscribe': True, - 'mail_notrack': True, - 'no_reset_password': True, - }).create({ - 'name': 'Geraldine Mass Mailing User', - 'login': 'geraldine', - 'email': 'g.g@example.com', - 'groups_id': [(6, 0, [ - self.env.ref('mass_mailing.group_mass_mailing_user').id, - self.env.ref('base.group_partner_manager').id, # TDE FIXME: check if really necessary for mass mailing - ])], - }) + test_user = mail_new_test_user( + self.env, login='geraldine', + groups='mass_mailing.group_mass_mailing_user,base.group_partner_manager' # TDE FIXME: check if really necessary for mass mailing + ) test_record = self.env['res.partner'].create({'name': 'Mass Mail Partner'}) - mass_mail_record = self.env['mail.mass_mailing'].sudo(self.user_employee).create({ + mass_mail_record = self.env['mail.mass_mailing'].sudo(test_user).create({ 'name': 'Test', 'state': 'draft', 'mailing_model_id': self.env.ref('base.model_res_partner').id, }) - composer = self.env['mail.compose.message'].sudo(self.user_employee).with_context({ + composer = self.env['mail.compose.message'].sudo(test_user).with_context({ 'default_composition_mode': 'mass_mail', 'default_model': 'res.partner', 'default_res_id': test_record.id, From dcec209805e58208eda50eb929b5355bc28fc05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 18 Oct 2018 10:51:09 +0000 Subject: [PATCH 8/9] [FIX] mass_mailing: fix tracking link creation in mass mailing When using only mass mailing two issues arise when trying to send mass mailings containing links * a link.tracker is created for each link to shorten; however rights are given currently only in website_links for website designers and not to marketing users that use mass mailing. This commit adds the rights for link.tracker model to those people; * a link.tracker.code is created to hold the shortened versions of the links. As it is a technical model it is now done as superuser as rights on link.tracked model has already been granted and adding rights on such a technical model is not necessary; A test is added that checks what is done with links when sending mass mailings. It helped spotting the hereabove issue. This commit is linked to task ID 1889703 and PR #27526. --- addons/link_tracker/models/link_tracker.py | 2 +- .../mass_mailing/security/ir.model.access.csv | 1 + .../tests/test_mass_mailing.py | 67 ++++++++++++++++++- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/addons/link_tracker/models/link_tracker.py b/addons/link_tracker/models/link_tracker.py index 584894b4322..ae52a6966f2 100644 --- a/addons/link_tracker/models/link_tracker.py +++ b/addons/link_tracker/models/link_tracker.py @@ -185,7 +185,7 @@ class link_tracker(models.Model): link = super(link_tracker, self).create(create_vals) code = self.env['link.tracker.code'].get_random_code_string() - self.env['link.tracker.code'].create({'code': code, 'link_id': link.id}) + self.env['link.tracker.code'].sudo().create({'code': code, 'link_id': link.id}) return link diff --git a/addons/mass_mailing/security/ir.model.access.csv b/addons/mass_mailing/security/ir.model.access.csv index b33aa24d9f7..7e3887ea576 100644 --- a/addons/mass_mailing/security/ir.model.access.csv +++ b/addons/mass_mailing/security/ir.model.access.csv @@ -14,3 +14,4 @@ access_utm_source,access_utm_source,utm.model_utm_source,mass_mailing.group_mass access_ir_mail_server,access_ir_mail_server,base.model_ir_mail_server,mass_mailing.group_mass_mailing_user,1,0,0,0 access_mail_blacklist_mass_mailing_user,access.mail.blacklist.mass_mailing_user,mail.model_mail_blacklist,mass_mailing.group_mass_mailing_user,1,1,1,1 access_mail_mass_mailing_list_contact_rel,access.mail.mass_mailing_list_contact_rel,model_mail_mass_mailing_list_contact_rel,mass_mailing.group_mass_mailing_user,1,1,1,1 +access_link_tracker_mailing,access.link.tracker.mailing,link_tracker.model_link_tracker,mass_mailing.group_mass_mailing_user,1,1,1,1 \ No newline at end of file diff --git a/addons/test_mass_mailing/tests/test_mass_mailing.py b/addons/test_mass_mailing/tests/test_mass_mailing.py index 8a8a2303317..6629be54f9f 100644 --- a/addons/test_mass_mailing/tests/test_mass_mailing.py +++ b/addons/test_mass_mailing/tests/test_mass_mailing.py @@ -1,9 +1,70 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.tests import common + +from unittest.mock import patch +from werkzeug import urls + +from odoo.addons.test_mass_mailing.tests.common import MassMailingCase +from odoo.addons.base.models.ir_config_parameter import IrConfigParameter +from odoo.tests.common import TransactionCase, users +from odoo.tools import mute_logger -class TestAccessRights(common.TransactionCase): +class TestMassMail(MassMailingCase): + + def setUp(self): + """ In this setup we prepare 20 blacklist entries. We therefore add + 20 recipients compared to first test in order to have comparable results. """ + super(TestMassMail, self).setUp() + values = [{ + 'name': 'Recipient %s' % x, + 'email_from': 'Recipient ' % x, + } for x in range(0, 6)] + self.mm_recs = self.env['mass.mail.test.bl'].create(values) + + self.env['mail.blacklist'].create({ + 'email': 'rec.2@example.com' + }) + + self.test_medium = self.env['utm.medium'].create({'name': 'TestMedium'}) + + @users('marketing') + @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') + def test_link_tracker(self): + _url = 'https://www.example.com/foo/bar?baz=qux' + mailing = self.env['mail.mass_mailing'].create({ + 'name': 'TestMailing', + 'medium_id': self.test_medium.id, + 'body_html': '

Hello ${object.name}Unsubscribe

' % _url, + 'reply_to_mode': 'email', + 'mailing_model_id': self.ref('test_mass_mailing.model_mass_mail_test_bl'), + 'mailing_domain': [('id', 'in', self.mm_recs.ids)], + }) + + mailing.send_mail() + + # basic test emails are sent + self.assertEqual(mailing.sent, 5) + self.assertEqual(mailing.delivered, 5) + + # link trackers + links = self.env['link.tracker'].sudo().search([('mass_mailing_id', '=', mailing.id)]) + self.assertEqual(len(links), 1) + self.assertEqual(links.mapped('url'), [_url]) + # check UTMS are correctly set on redirect URL + redirect_url = urls.url_parse(links.redirected_url) + redirect_params = redirect_url.decode_query().to_dict(flat=True) + self.assertEqual(redirect_url.scheme, 'https') + self.assertEqual(redirect_url.decode_netloc(), 'www.example.com') + self.assertEqual(redirect_url.path, '/foo/bar') + self.assertEqual(redirect_params, { + 'utm_source': mailing.name, + 'utm_medium': self.test_medium.name, + 'baz': 'qux', + }) + + +class TestAccessRights(TransactionCase): def test_01_mass_mail_blacklist(self): mass_mailing_contacts = self.env['mail.mass_mailing.contact'] @@ -204,7 +265,7 @@ class TestAccessRights(common.TransactionCase): 'Opt Out ignored email number incorrect, should be equals to 1') -class TestOnResPartner(common.TransactionCase): +class TestOnResPartner(TransactionCase): def test_mass_mail_on_res_partner(self): partners = self.env['res.partner'] From b4b2a042910180907ef1883396bc7f18ac402df1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 8 Oct 2018 14:09:42 +0000 Subject: [PATCH 9/9] [IMP] test_mass_mailing: add performance tests Purpose is to have some basis performance counters when sending a mailing on 100 records, with and without blacklist involved. It will serves as reference when working on mass mailing performance improvements in future tasks. This commit is linked to task ID 1889703 and PR #27526. --- addons/test_mass_mailing/tests/__init__.py | 1 + .../tests/test_performance.py | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 addons/test_mass_mailing/tests/test_performance.py diff --git a/addons/test_mass_mailing/tests/__init__.py b/addons/test_mass_mailing/tests/__init__.py index caed78c5432..4283fdd0861 100644 --- a/addons/test_mass_mailing/tests/__init__.py +++ b/addons/test_mass_mailing/tests/__init__.py @@ -7,3 +7,4 @@ from . import test_composer from . import test_mail_auto_blacklist from . import test_mail_channel from . import test_mass_mailing +from . import test_performance diff --git a/addons/test_mass_mailing/tests/test_performance.py b/addons/test_mass_mailing/tests/test_performance.py new file mode 100644 index 00000000000..b406474e224 --- /dev/null +++ b/addons/test_mass_mailing/tests/test_performance.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.addons.test_mass_mailing.tests import common +from odoo.tests.common import users, warmup +from odoo.tests import tagged +from odoo.tools import mute_logger + + +@tagged('mail_performance') +class TestMassMailPerformance(common.MassMailingCase): + + def setUp(self): + super(TestMassMailPerformance, self).setUp() + values = [{ + 'name': 'Recipient %s' % x, + 'email_from': 'Recipient ' % x, + } for x in range(0, 50)] + self.mm_recs = self.env['mass.mail.test'].create(values) + + @users('__system__', 'marketing') + @warmup + @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') + def test_send_mailing(self): + mailing = self.env['mail.mass_mailing'].create({ + 'name': 'Test', + 'body_html': '

Hello quuxUnsubscribe

', + 'reply_to_mode': 'email', + 'mailing_model_id': self.ref('test_mass_mailing.model_mass_mail_test'), + 'mailing_domain': [('id', 'in', self.mm_recs.ids)], + }) + + with self.assertQueryCount(__system__=2382, marketing=3038): + mailing.send_mail() + + self.assertEqual(mailing.sent, 50) + self.assertEqual(mailing.delivered, 50) + + +@tagged('mail_performance') +class TestMassMailBlPerformance(common.MassMailingCase): + + def setUp(self): + """ In this setup we prepare 20 blacklist entries. We therefore add + 20 recipients compared to first test in order to have comparable results. """ + super(TestMassMailBlPerformance, self).setUp() + values = [{ + 'name': 'Recipient %s' % x, + 'email_from': 'Recipient ' % x, + } for x in range(0, 62)] + self.mm_recs = self.env['mass.mail.test.bl'].create(values) + + for x in range(1, 13): + self.env['mail.blacklist'].create({ + 'email': 'rec.%s@example.com' % (x * 5) + }) + + @users('__system__', 'marketing') + @warmup + @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') + def test_send_mailing_w_bl(self): + mailing = self.env['mail.mass_mailing'].create({ + 'name': 'Test', + 'body_html': '

Hello quuxUnsubscribe

', + 'reply_to_mode': 'email', + 'mailing_model_id': self.ref('test_mass_mailing.model_mass_mail_test_bl'), + 'mailing_domain': [('id', 'in', self.mm_recs.ids)], + }) + + with self.assertQueryCount(__system__=2757, marketing=3509): + mailing.send_mail() + + self.assertEqual(mailing.sent, 50) + self.assertEqual(mailing.delivered, 50)