From c70662b6c6fecc9f3bc148f1f0bd20d0c8328c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 7 Feb 2023 12:47:45 +0000 Subject: [PATCH] [IMP] test_mail_full: add tests for portal inheritance of thread features Purpose is to add tests as there are some broken overrides in mail.thread inheritance mechanism. We see notably that bad override in portal make some override not being called correctly. Task-3175768 (Mail: check inheritances / overrides) Part-of: odoo/odoo#112573 --- addons/mail/tests/common.py | 14 +++- .../models/test_mail_corner_case_models.py | 6 ++ addons/test_mail/models/test_mail_models.py | 12 +++ .../models/test_mail_models_mail.py | 20 +++++ .../security/ir.model.access.csv | 2 + addons/test_mail_full/tests/__init__.py | 1 + .../tests/test_mail_thread_internals.py | 79 +++++++++++++++++++ .../models/test_mail_sms_models.py | 15 ++++ 8 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 addons/test_mail_full/tests/test_mail_thread_internals.py diff --git a/addons/mail/tests/common.py b/addons/mail/tests/common.py index dca9d428702..4605d50513b 100644 --- a/addons/mail/tests/common.py +++ b/addons/mail/tests/common.py @@ -1084,7 +1084,17 @@ class MailCommon(common.TransactionCase, MailCase): } for idx in range(count) ] - if 'customer_id' in cls.env[model]: + partner_fname = False + if 'partner_id' in cls.env[model]: + partner_fname = 'partner_id' + elif hasattr(cls.env[model], '_mail_get_partner_fields'): + partner_fnames = cls.env[model]._mail_get_partner_fields() + if partner_fnames: + partner_fname = partner_fnames[0] + elif 'customer_id' in cls.env[model]: + partner_fname = 'customer_id' + + if partner_fname: partners = cls.env['res.partner'].with_context(**cls._test_context).create([{ 'name': f'Partner_{idx}', 'email': f'{prefix}test_partner_{idx}@example.com', @@ -1092,7 +1102,7 @@ class MailCommon(common.TransactionCase, MailCase): 'mobile': '047500%02d%02d' % (idx, idx) } for idx in range(count)]) for values, partner in zip(base_values, partners): - values['customer_id'] = partner.id + values[partner_fname] = partner.id records = cls.env[model].with_context(**cls._test_context).create(base_values) diff --git a/addons/test_mail/models/test_mail_corner_case_models.py b/addons/test_mail/models/test_mail_corner_case_models.py index 31fd75ca27c..c21719d8b63 100644 --- a/addons/test_mail/models/test_mail_corner_case_models.py +++ b/addons/test_mail/models/test_mail_corner_case_models.py @@ -53,6 +53,9 @@ class MailTestFieldType(models.Model): self = self.with_context(default_type='first') return super(MailTestFieldType, self).create(vals_list) + def _mail_get_partner_fields(self): + return ['customer_id'] + class MailTestLang(models.Model): """ A simple chatter model with lang-based capabilities, allowing to @@ -66,6 +69,9 @@ class MailTestLang(models.Model): customer_id = fields.Many2one('res.partner') lang = fields.Char('Lang') + def _mail_get_partner_fields(self): + return ['customer_id'] + def _notify_get_recipients_groups(self, msg_vals=None): groups = super(MailTestLang, self)._notify_get_recipients_groups(msg_vals=msg_vals) diff --git a/addons/test_mail/models/test_mail_models.py b/addons/test_mail/models/test_mail_models.py index dee3b5da83d..eb3c90bea26 100644 --- a/addons/test_mail/models/test_mail_models.py +++ b/addons/test_mail/models/test_mail_models.py @@ -65,6 +65,9 @@ class MailTestGatewayGroups(models.Model): values['alias_parent_thread_id'] = self.id return values + def _mail_get_partner_fields(self): + return ['customer_id'] + def _message_get_default_recipients(self): return dict( (record.id, { @@ -131,6 +134,9 @@ class MailTestTicket(models.Model): user_id = fields.Many2one('res.users', 'Responsible', tracking=1) container_id = fields.Many2one('mail.test.container', tracking=True) + def _mail_get_partner_fields(self): + return ['customer_id'] + def _message_compute_subject(self): self.ensure_one() return f"Ticket for {self.name} on {self.datetime.strftime('%m/%d/%Y, %H:%M:%S')}" @@ -239,6 +245,9 @@ class MailTestContainer(models.Model): 'mail.alias', 'Alias', delegate=True) + def _mail_get_partner_fields(self): + return ['customer_id'] + def _message_get_default_recipients(self): return dict( (record.id, { @@ -314,3 +323,6 @@ class MailTestComposerSource(models.Model): def _compute_email_from(self): for source in self.filtered(lambda r: r.customer_id and not r.email_from): source.email_from = source.customer_id.email_formatted + + def _mail_get_partner_fields(self): + return ['customer_id'] diff --git a/addons/test_mail_full/models/test_mail_models_mail.py b/addons/test_mail_full/models/test_mail_models_mail.py index a00bdb046a3..dba1e9a5137 100644 --- a/addons/test_mail_full/models/test_mail_models_mail.py +++ b/addons/test_mail_full/models/test_mail_models_mail.py @@ -24,6 +24,23 @@ class MailTestPortal(models.Model): record.access_url = '/my/test_portal/%s' % self.id +class MailTestPortalNoPartner(models.Model): + """ A model inheriting from portal, but without any partner field """ + _description = 'Chatter Model for Portal (no partner field)' + _name = 'mail.test.portal.no.partner' + _inherit = [ + 'mail.thread', + 'portal.mixin', + ] + + name = fields.Char() + + def _compute_access_url(self): + self.access_url = False + for record in self.filtered('id'): + record.access_url = '/my/test_portal_no_partner/%s' % self.id + + class MailTestRating(models.Model): """ A model inheriting from mail.thread with some fields used for SMS gateway, like a partner, a specific mobile phone, ... """ @@ -71,6 +88,9 @@ class MailTestRating(models.Model): elif not rating.phone_nbr: rating.phone_nbr = False + def _mail_get_partner_fields(self): + return ['customer_id'] + def _rating_apply_get_default_subtype_id(self): return self.env['ir.model.data']._xmlid_to_res_id("test_mail_full.mt_mail_test_rating_rating_done") diff --git a/addons/test_mail_full/security/ir.model.access.csv b/addons/test_mail_full/security/ir.model.access.csv index b5fe967c07a..c16510115dd 100644 --- a/addons/test_mail_full/security/ir.model.access.csv +++ b/addons/test_mail_full/security/ir.model.access.csv @@ -1,6 +1,8 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_mail_test_portal_all,mail.test.portal.all,model_mail_test_portal,,0,0,0,0 access_mail_test_portal_user,mail.test.portal.user,model_mail_test_portal,base.group_user,1,1,1,1 +access_mail_test_portal_no_partner_all,mail.test.portal.no.partner.all,model_mail_test_portal_no_partner,,1,0,0,0 +access_mail_test_portal_no_partner_user,mail.test.portal.no.partner.user,model_mail_test_portal_no_partner,base.group_user,1,1,1,1 access_mail_test_rating_all,mail.test.rating.all,model_mail_test_rating,,0,0,0,0 access_mail_test_rating_portal,mail.test.rating.portal,model_mail_test_rating,base.group_portal,1,0,0,0 access_mail_test_rating_user,mail.test.rating.user,model_mail_test_rating,base.group_user,1,1,1,1 diff --git a/addons/test_mail_full/tests/__init__.py b/addons/test_mail_full/tests/__init__.py index 4148bc1250d..283b523e43c 100644 --- a/addons/test_mail_full/tests/__init__.py +++ b/addons/test_mail_full/tests/__init__.py @@ -3,6 +3,7 @@ from . import test_odoobot from . import test_mail_performance +from . import test_mail_thread_internals from . import test_mass_mailing from . import test_portal from . import test_rating diff --git a/addons/test_mail_full/tests/test_mail_thread_internals.py b/addons/test_mail_full/tests/test_mail_thread_internals.py new file mode 100644 index 00000000000..07f351f825d --- /dev/null +++ b/addons/test_mail_full/tests/test_mail_thread_internals.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from werkzeug.urls import url_parse + +from odoo.addons.test_mail_full.tests.common import TestMailFullCommon +from odoo.addons.test_mail_sms.tests.common import TestSMSRecipients +from odoo.tests import tagged, users + + +class TestMailThreadInternalsCommon(TestMailFullCommon, TestSMSRecipients): + + @classmethod + def setUpClass(cls): + super(TestMailThreadInternalsCommon, cls).setUpClass() + + cls.test_portal_records, cls.test_portal_partners = cls._create_records_for_batch( + 'mail.test.portal', + 2, + ) + cls.test_portal_nop_records, _ = cls._create_records_for_batch( + 'mail.test.portal.no.partner', + 2, + ) + cls.test_rating_records, cls.test_rating_partners = cls._create_records_for_batch( + 'mail.test.rating', + 2, + ) + cls.test_simple_records, _ = cls._create_records_for_batch( + 'mail.test.simple', + 2, + ) + + +@tagged('mail_thread', 'portal') +class TestMailThreadInternals(TestMailThreadInternalsCommon): + + @users('employee') + def test_notify_get_recipients_groups(self): + """ Test redirection of portal-enabled records """ + test_records = [ + self.test_portal_records[0].with_env(self.env), + self.test_portal_nop_records[0].with_env(self.env), + self.test_rating_records[0].with_env(self.env), + self.test_simple_records[0].with_env(self.env), + ] + for test_record in test_records: + with self.subTest(test_record=test_record): + is_portal = test_record._name != 'mail.test.simple' + has_customer = test_record._name != 'mail.test.portal.no.partner' + + if is_portal: + self.assertFalse( + test_record.access_token, + 'By default access tokens are False with portal' + ) + + groups = test_record._notify_get_recipients_groups() + portal_customer_group = next( + (group for group in groups if group[0] == 'portal_customer'), + False + ) + + if is_portal and has_customer: + # should have generated the access token, required for portal links + self.assertFalse( + test_record.access_token, + 'TODO: Method not called, access token is not generated' + ) + # check portal_customer content and link + self.assertFalse( + portal_customer_group, + 'TODO: MEthod not called, group is not present' + ) + else: + self.assertFalse( + portal_customer_group, + 'Portal Mixin should not add portal customer notification group' + ) diff --git a/addons/test_mail_sms/models/test_mail_sms_models.py b/addons/test_mail_sms/models/test_mail_sms_models.py index 37ff433b5a7..fe47cfcb8a2 100644 --- a/addons/test_mail_sms/models/test_mail_sms_models.py +++ b/addons/test_mail_sms/models/test_mail_sms_models.py @@ -20,6 +20,9 @@ class MailTestSMS(models.Model): mobile_nbr = fields.Char() customer_id = fields.Many2one('res.partner', 'Customer') + def _mail_get_partner_fields(self): + return ['customer_id'] + def _sms_get_partner_fields(self): return ['customer_id'] @@ -53,6 +56,9 @@ class MailTestSMSBL(models.Model): for phone_record in self.filtered(lambda rec: not rec.phone_nbr and rec.customer_id): phone_record.phone_nbr = phone_record.customer_id.phone + def _mail_get_partner_fields(self): + return ['customer_id'] + def _sms_get_partner_fields(self): return ['customer_id'] @@ -90,6 +96,9 @@ class MailTestSMSOptout(models.Model): customer_id = fields.Many2one('res.partner', 'Customer') opt_out = fields.Boolean() + def _mail_get_partner_fields(self): + return ['customer_id'] + def _mailing_get_opt_out_list_sms(self, mailing): res_ids = mailing._get_recipients() return self.search([ @@ -117,6 +126,9 @@ class MailTestSMSPartner(models.Model): customer_id = fields.Many2one('res.partner', 'Customer') opt_out = fields.Boolean() + def _mail_get_partner_fields(self): + return ['customer_id'] + def _mailing_get_opt_out_list_sms(self, mailing): res_ids = mailing._get_recipients() return self.search([ @@ -143,6 +155,9 @@ class MailTestSMSPartner2Many(models.Model): customer_ids = fields.Many2many('res.partner', string='Customers') opt_out = fields.Boolean() + def _mail_get_partner_fields(self): + return ['customer_ids'] + def _mailing_get_opt_out_list_sms(self, mailing): res_ids = mailing._get_recipients() return self.search([