From aa70ad6731f0cc7cb89dc2864bee9ad1247fc696 Mon Sep 17 00:00:00 2001 From: Quentin Groulard Date: Thu, 15 Oct 2020 17:43:07 +0200 Subject: [PATCH] [MIG] partner_email_check: Migration to 13.0 --- partner_email_check/__manifest__.py | 28 ++--- .../i18n/partner_email_check.pot | 2 +- .../models/res_config_settings.py | 25 ++-- partner_email_check/models/res_partner.py | 70 +++++------ .../tests/test_partner_email_check.py | 110 ++++++++---------- .../views/base_config_view.xml | 10 +- 6 files changed, 115 insertions(+), 130 deletions(-) diff --git a/partner_email_check/__manifest__.py b/partner_email_check/__manifest__.py index b275a6b70..b2445e46d 100644 --- a/partner_email_check/__manifest__.py +++ b/partner_email_check/__manifest__.py @@ -2,20 +2,16 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { - 'name': 'Email Format Checker', - 'version': '12.0.1.0.0', - 'summary': 'Validate email address field', - 'author': "Komit, Odoo Community Association (OCA)", - 'website': 'https://github.com/OCA/partner-contact', - 'category': 'Tools', - 'depends': ['base_setup'], - 'installable': True, - 'application': False, - 'license': 'AGPL-3', - 'external_dependencies': { - 'python': ['email_validator'] - }, - 'data': [ - 'views/base_config_view.xml', - ] + "name": "Email Format Checker", + "version": "13.0.1.0.0", + "summary": "Validate email address field", + "author": "Komit, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/partner-contact", + "category": "Tools", + "depends": ["base_setup"], + "installable": True, + "application": False, + "license": "AGPL-3", + "external_dependencies": {"python": ["email-validator"]}, + "data": ["views/base_config_view.xml"], } diff --git a/partner_email_check/i18n/partner_email_check.pot b/partner_email_check/i18n/partner_email_check.pot index 8e0ba1a70..f9923d992 100644 --- a/partner_email_check/i18n/partner_email_check.pot +++ b/partner_email_check/i18n/partner_email_check.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" +"Project-Id-Version: Odoo Server 13.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: <>\n" "Language-Team: \n" diff --git a/partner_email_check/models/res_config_settings.py b/partner_email_check/models/res_config_settings.py index 405677809..07e8b6769 100644 --- a/partner_email_check/models/res_config_settings.py +++ b/partner_email_check/models/res_config_settings.py @@ -2,7 +2,7 @@ from odoo import api, fields, models class ResConfigSettings(models.TransientModel): - _inherit = 'res.config.settings' + _inherit = "res.config.settings" partner_email_check_filter_duplicates = fields.Boolean( string="Filter duplicate partner email addresses", @@ -17,26 +17,27 @@ class ResConfigSettings(models.TransientModel): @api.model def get_values(self): res = super(ResConfigSettings, self).get_values() - conf = self.env['ir.config_parameter'].sudo() + conf = self.env["ir.config_parameter"].sudo() res.update( partner_email_check_filter_duplicates=conf.get_param( - 'partner_email_check_filter_duplicates', 'False' - ) == 'True', + "partner_email_check_filter_duplicates", "False" + ) + == "True", partner_email_check_check_deliverability=conf.get_param( - 'partner_email_check_check_deliverability', 'False' - ) == 'True', + "partner_email_check_check_deliverability", "False" + ) + == "True", ) return res - @api.multi def set_values(self): super(ResConfigSettings, self).set_values() - conf = self.env['ir.config_parameter'].sudo() + conf = self.env["ir.config_parameter"].sudo() conf.set_param( - 'partner_email_check_filter_duplicates', - self.partner_email_check_filter_duplicates + "partner_email_check_filter_duplicates", + self.partner_email_check_filter_duplicates, ) conf.set_param( - 'partner_email_check_check_deliverability', - self.partner_email_check_check_deliverability + "partner_email_check_check_deliverability", + self.partner_email_check_check_deliverability, ) diff --git a/partner_email_check/models/res_partner.py b/partner_email_check/models/res_partner.py index 65da60194..d0b0eede4 100644 --- a/partner_email_check/models/res_partner.py +++ b/partner_email_check/models/res_partner.py @@ -2,7 +2,8 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import logging -from odoo import api, models, _ + +from odoo import _, api, models from odoo.exceptions import UserError, ValidationError from odoo.tools import config @@ -21,29 +22,31 @@ except ImportError: class ResPartner(models.Model): - _inherit = 'res.partner' + _inherit = "res.partner" @api.model def email_check(self, emails): - if (config['test_enable'] and - not self.env.context.get('test_partner_email_check')): + if config["test_enable"] and not self.env.context.get( + "test_partner_email_check" + ): return emails - return ','.join(self._normalize_email(email.strip()) - for email in emails.split(',')) + return ",".join( + self._normalize_email(email.strip()) for email in emails.split(",") + ) - @api.constrains('email') + @api.constrains("email") def _check_email_unique(self): if self._should_filter_duplicates(): for rec in self.filtered("email"): - if ',' in rec.email: + if "," in rec.email: raise UserError( - _("Field contains multiple email addresses. This is " - "not supported when duplicate email addresses are " - "not allowed.") + _( + "Field contains multiple email addresses. This is " + "not supported when duplicate email addresses are " + "not allowed." + ) ) - if self.search_count( - [('email', '=', rec.email), ('id', '!=', rec.id)] - ): + if self.search_count([("email", "=", rec.email), ("id", "!=", rec.id)]): raise UserError( _("Email '%s' is already in use.") % rec.email.strip() ) @@ -51,45 +54,46 @@ class ResPartner(models.Model): def _normalize_email(self, email): if validate_email is None: _logger.warning( - 'Can not validate email, ' - 'python dependency required "email_validator"') + "Can not validate email, " + 'python dependency required "email_validator"' + ) return email try: result = validate_email( - email, - check_deliverability=self._should_check_deliverability(), + email, check_deliverability=self._should_check_deliverability(), ) except EmailSyntaxError: - raise ValidationError( - _("%s is an invalid email") % email.strip() - ) + raise ValidationError(_("%s is an invalid email") % email.strip()) except EmailUndeliverableError: raise ValidationError( _("Cannot deliver to email address %s") % email.strip() ) - return result['local'].lower() + '@' + result['domain_i18n'] + return result["local"].lower() + "@" + result["domain_i18n"] def _should_filter_duplicates(self): - conf = self.env['ir.config_parameter'].sudo().get_param( - 'partner_email_check_filter_duplicates', 'False' + conf = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("partner_email_check_filter_duplicates", "False") ) - return conf == 'True' + return conf == "True" def _should_check_deliverability(self): - conf = self.env['ir.config_parameter'].sudo().get_param( - 'partner_email_check_check_deliverability', 'False' + conf = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("partner_email_check_check_deliverability", "False") ) - return conf == 'True' + return conf == "True" @api.model def create(self, vals): - if vals.get('email'): - vals['email'] = self.email_check(vals['email']) + if vals.get("email"): + vals["email"] = self.email_check(vals["email"]) return super(ResPartner, self).create(vals) - @api.multi def write(self, vals): - if vals.get('email'): - vals['email'] = self.email_check(vals['email']) + if vals.get("email"): + vals["email"] = self.email_check(vals["email"]) return super(ResPartner, self).write(vals) diff --git a/partner_email_check/tests/test_partner_email_check.py b/partner_email_check/tests/test_partner_email_check.py index 0b4d72d17..ef6f8a508 100644 --- a/partner_email_check/tests/test_partner_email_check.py +++ b/partner_email_check/tests/test_partner_email_check.py @@ -3,7 +3,7 @@ from unittest.mock import patch -from odoo.exceptions import ValidationError +from odoo.exceptions import UserError, ValidationError from odoo.tests.common import TransactionCase from odoo.tools.misc import mute_logger @@ -12,13 +12,11 @@ class TestPartnerEmailCheck(TransactionCase): def setUp(self): super(TestPartnerEmailCheck, self).setUp() # Checks are disabled during tests unless this key is set - self.res_partner = self.env['res.partner'].with_context( + self.res_partner = self.env["res.partner"].with_context( test_partner_email_check=True ) - self.test_partner = self.res_partner.create({ - 'name': 'test', - }) - self.wizard = self.env['res.config.settings'].create({}) + self.test_partner = self.res_partner.create({"name": "test"}) + self.wizard = self.env["res.config.settings"].create({}) self.wizard.partner_email_check_filter_duplicates = False self.wizard.partner_email_check_check_deliverability = False self.wizard.set_values() @@ -26,50 +24,49 @@ class TestPartnerEmailCheck(TransactionCase): def test_bad_email(self): """Test rejection of bad emails.""" with self.assertRaises(ValidationError): - self.test_partner.email = 'bad@email@domain..com' + self.test_partner.email = "bad@email@domain..com" def test_good_email(self): """Test acceptance of good""" - self.test_partner.email = 'goodemail@domain.com' + self.test_partner.email = "goodemail@domain.com" self.assertTrue(self.test_partner.email) def test_bad_emails(self): """Test rejection of bad emails.""" with self.assertRaises(ValidationError): - self.test_partner.email = 'good@domain.com,bad@email@domain..com' + self.test_partner.email = "good@domain.com,bad@email@domain..com" def test_good_emails(self): """Test acceptance of good""" - self.test_partner.email = 'goodemail@domain.com,goodemail2@domain.com' + self.test_partner.email = "goodemail@domain.com,goodemail2@domain.com" self.assertTrue(self.test_partner.email) def test_email_domain_normalization(self): """Test normalization of email domain names, including punycode.""" - self.test_partner.write({'email': 'goodemail@xn--xamPle-9ua.com'}) - self.assertEqual(self.test_partner.email, u'goodemail@éxample.com') + self.test_partner.write({"email": "goodemail@xn--xamPle-9ua.com"}) + self.assertEqual(self.test_partner.email, u"goodemail@éxample.com") def test_multi_email_domain_normalization(self): """Test normalization of email domain names of multiple addresses.""" - self.test_partner.write({ - 'email': 'goodemail@doMAIN.com,othergood@xn--xample-9ua.com' - }) + self.test_partner.write( + {"email": "goodemail@doMAIN.com,othergood@xn--xample-9ua.com"} + ) self.assertEqual( - self.test_partner.email, - u'goodemail@domain.com,othergood@éxample.com' + self.test_partner.email, u"goodemail@domain.com,othergood@éxample.com" ) def test_email_local_normalization(self): """Test normalization of the local part of email addresses.""" - self.test_partner.write({'email': 'Me@mail.org'}) + self.test_partner.write({"email": "Me@mail.org"}) # .lower() is locale-dependent, so don't hardcode the result - self.assertEqual(self.test_partner.email, 'Me'.lower() + '@mail.org') + self.assertEqual(self.test_partner.email, "Me".lower() + "@mail.org") def test_multi_email_local_normalization(self): """Test normalization of the local part of multiple addresses.""" - self.test_partner.write({'email': 'You@mAiL.net,mE@mail.com'}) + self.test_partner.write({"email": "You@mAiL.net,mE@mail.com"}) self.assertEqual( self.test_partner.email, - 'You'.lower() + '@mail.net,' + 'mE'.lower() + '@mail.com' + "You".lower() + "@mail.net," + "mE".lower() + "@mail.com", ) def disallow_duplicates(self): @@ -78,33 +75,24 @@ class TestPartnerEmailCheck(TransactionCase): def test_duplicate_addresses_disallowed(self): self.disallow_duplicates() - self.test_partner.write({'email': 'email@domain.tld'}) - with self.assertRaises(ValidationError): - self.res_partner.create({ - 'name': 'alsotest', - 'email': 'email@domain.tld' - }) + self.test_partner.write({"email": "email@domain.tld"}) + with self.assertRaises(UserError): + self.res_partner.create({"name": "alsotest", "email": "email@domain.tld"}) def test_duplicate_after_normalization_addresses_disallowed(self): self.disallow_duplicates() - self.res_partner.create({ - 'name': 'alsotest', - 'email': 'email@doMAIN.tld' - }) - with self.assertRaises(ValidationError): - self.test_partner.email = 'email@domain.tld' + self.res_partner.create({"name": "alsotest", "email": "email@doMAIN.tld"}) + with self.assertRaises(UserError): + self.test_partner.email = "email@domain.tld" def test_multiple_addresses_disallowed_when_duplicates_filtered(self): self.disallow_duplicates() - with self.assertRaises(ValidationError): - self.test_partner.email = 'foo@bar.org,email@domain.tld' + with self.assertRaises(UserError): + self.test_partner.email = "foo@bar.org,email@domain.tld" def test_duplicate_addresses_allowed_by_default(self): - self.res_partner.create({ - 'name': 'alsotest', - 'email': 'email@domain.tld', - }) - self.test_partner.email = 'email@domain.tld' + self.res_partner.create({"name": "alsotest", "email": "email@domain.tld"}) + self.test_partner.email = "email@domain.tld" def check_deliverability(self): self.wizard.partner_email_check_check_deliverability = True @@ -113,7 +101,7 @@ class TestPartnerEmailCheck(TransactionCase): def test_deliverable_addresses_allowed(self): self.check_deliverability() # We only need a resolving domain, not a real user - self.test_partner.email = 'gooddomain-icraglusrk@gmail.com' + self.test_partner.email = "gooddomain-icraglusrk@gmail.com" self.assertTrue(self.test_partner.email) def test_nondeliverable_addresses_not_allowed(self): @@ -122,40 +110,38 @@ class TestPartnerEmailCheck(TransactionCase): # This domain may resolve by mistake on certain network setups # At least until a new version of email-validator is released # See https://github.com/JoshData/python-email-validator/pull/30 - self.test_partner.email = 'cezrik@acoa.nrdkt' + self.test_partner.email = "cezrik@acoa.nrdkt" def test_config_getters(self): - other_wizard = self.env['res.config.settings'].create({}) + other_wizard = self.env["res.config.settings"].create({}) self.assertFalse(other_wizard.partner_email_check_check_deliverability) self.assertFalse(other_wizard.partner_email_check_filter_duplicates) self.disallow_duplicates() self.check_deliverability() - other_wizard = self.env['res.config.settings'].create({}) + other_wizard = self.env["res.config.settings"].create({}) self.assertTrue(other_wizard.partner_email_check_check_deliverability) self.assertTrue(other_wizard.partner_email_check_filter_duplicates) - @mute_logger('odoo.addons.partner_email_check.models.res_partner') + @mute_logger("odoo.addons.partner_email_check.models.res_partner") def test_lacking_dependency_does_not_halt_execution(self): - with patch('odoo.addons.partner_email_check.models.res_partner.' - 'validate_email', None): - self.test_partner.email = 'notatallvalid@@domain' + with patch( + "odoo.addons.partner_email_check.models.res_partner." "validate_email", None + ): + self.test_partner.email = "notatallvalid@@domain" - @mute_logger('odoo.addons.partner_email_check.models.res_partner') + @mute_logger("odoo.addons.partner_email_check.models.res_partner") def test_lacking_dependency_keeps_uniqueness_constraint_working(self): self.disallow_duplicates() - with patch('odoo.addons.partner_email_check.models.res_partner.' - 'validate_email', None): - self.res_partner.create({ - 'name': 'alsotest', - 'email': 'email@domain.tld' - }) - with self.assertRaises(ValidationError): - self.test_partner.email = 'email@domain.tld' + with patch( + "odoo.addons.partner_email_check.models.res_partner." "validate_email", None + ): + self.res_partner.create({"name": "alsotest", "email": "email@domain.tld"}) + with self.assertRaises(UserError): + self.test_partner.email = "email@domain.tld" def test_invalid_email_addresses_allowed_during_tests(self): # Note: testing without test_partner_email_check in the context - new_partner = self.env['res.partner'].create({ - 'name': 'invalidly emailed', - 'email': 'invalid' - }) - self.assertEqual('invalid', new_partner.email) + new_partner = self.env["res.partner"].create( + {"name": "invalidly emailed", "email": "invalid"} + ) + self.assertEqual("invalid", new_partner.email) diff --git a/partner_email_check/views/base_config_view.xml b/partner_email_check/views/base_config_view.xml index 3bc93e759..1829b4490 100644 --- a/partner_email_check/views/base_config_view.xml +++ b/partner_email_check/views/base_config_view.xml @@ -1,15 +1,13 @@ - + partner_email_check res.config.settings - + - +

Email validation

-
+