You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
6.0 KiB

  1. # Copyright 2019 Komit <https://komit-consulting.com>
  2. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
  3. from unittest.mock import patch
  4. from odoo.exceptions import UserError, ValidationError
  5. from odoo.tests.common import SavepointCase
  6. from odoo.tools.misc import mute_logger
  7. class TestPartnerEmailCheck(SavepointCase):
  8. @classmethod
  9. def setUpClass(cls):
  10. super().setUpClass()
  11. cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
  12. cls.test_partner = cls.env["res.partner"].create({"name": "test"})
  13. cls.env.company.partner_email_check_syntax = True
  14. cls.env.company.partner_email_check_filter_duplicates = False
  15. cls.env.company.partner_email_check_check_deliverability = False
  16. def test_bad_email(self):
  17. """Test rejection of bad emails."""
  18. with self.assertRaises(ValidationError):
  19. self.test_partner.email = "bad@email@domain..com"
  20. def test_good_email(self):
  21. """Test acceptance of good"""
  22. self.test_partner.email = "goodemail@domain.com"
  23. self.assertTrue(self.test_partner.email)
  24. def test_bad_emails(self):
  25. """Test rejection of bad emails."""
  26. with self.assertRaises(ValidationError):
  27. self.test_partner.email = "good@domain.com,bad@email@domain..com"
  28. def test_good_emails(self):
  29. """Test acceptance of good"""
  30. self.test_partner.email = "goodemail@domain.com,goodemail2@domain.com"
  31. self.assertTrue(self.test_partner.email)
  32. def test_email_domain_normalization(self):
  33. """Test normalization of email domain names, including punycode."""
  34. self.test_partner.write({"email": "goodemail@xn--xamPle-9ua.com"})
  35. self.assertEqual(self.test_partner.email, "goodemail@éxample.com")
  36. def test_multi_email_domain_normalization(self):
  37. """Test normalization of email domain names of multiple addresses."""
  38. self.test_partner.write(
  39. {"email": "goodemail@doMAIN.com,othergood@xn--xample-9ua.com"}
  40. )
  41. self.assertEqual(
  42. self.test_partner.email, "goodemail@domain.com,othergood@éxample.com"
  43. )
  44. def test_email_local_normalization(self):
  45. """Test normalization of the local part of email addresses."""
  46. self.test_partner.write({"email": "Me@mail.org"})
  47. # .lower() is locale-dependent, so don't hardcode the result
  48. self.assertEqual(self.test_partner.email, "Me".lower() + "@mail.org")
  49. def test_multi_email_local_normalization(self):
  50. """Test normalization of the local part of multiple addresses."""
  51. self.test_partner.write({"email": "You@mAiL.net,mE@mail.com"})
  52. self.assertEqual(
  53. self.test_partner.email,
  54. "You".lower() + "@mail.net," + "mE".lower() + "@mail.com",
  55. )
  56. def disallow_duplicates(self):
  57. self.env.company.partner_email_check_filter_duplicates = True
  58. def test_duplicate_addresses_disallowed(self):
  59. self.disallow_duplicates()
  60. self.test_partner.write({"email": "email@domain.tld"})
  61. with self.assertRaises(UserError):
  62. self.env["res.partner"].create(
  63. {"name": "alsotest", "email": "email@domain.tld"}
  64. )
  65. def test_duplicate_after_normalization_addresses_disallowed(self):
  66. self.disallow_duplicates()
  67. self.env["res.partner"].create(
  68. {"name": "alsotest", "email": "email@doMAIN.tld"}
  69. )
  70. with self.assertRaises(UserError):
  71. self.test_partner.email = "email@domain.tld"
  72. def test_multiple_addresses_disallowed_when_duplicates_filtered(self):
  73. self.disallow_duplicates()
  74. with self.assertRaises(UserError):
  75. self.test_partner.email = "foo@bar.org,email@domain.tld"
  76. def test_duplicate_addresses_disallowed_copy_partner(self):
  77. self.disallow_duplicates()
  78. self.test_partner.write({"email": "email@domain.tld"})
  79. partner_copy = self.test_partner.copy()
  80. self.assertFalse(partner_copy.email)
  81. def test_duplicate_addresses_allowed_by_default(self):
  82. self.env["res.partner"].create(
  83. {"name": "alsotest", "email": "email@domain.tld"}
  84. )
  85. self.test_partner.email = "email@domain.tld"
  86. def check_deliverability(self):
  87. self.env.company.partner_email_check_check_deliverability = True
  88. def test_deliverable_addresses_allowed(self):
  89. self.check_deliverability()
  90. # We only need a resolving domain, not a real user
  91. self.test_partner.email = "gooddomain-icraglusrk@gmail.com"
  92. self.assertTrue(self.test_partner.email)
  93. def test_nondeliverable_addresses_not_allowed(self):
  94. self.check_deliverability()
  95. with self.assertRaises(ValidationError):
  96. # This domain may resolve by mistake on certain network setups
  97. # At least until a new version of email-validator is released
  98. # See https://github.com/JoshData/python-email-validator/pull/30
  99. self.test_partner.email = "cezrik@acoa.nrdkt"
  100. @mute_logger("odoo.addons.partner_email_check.models.res_partner")
  101. def test_lacking_dependency_does_not_halt_execution(self):
  102. with patch(
  103. "odoo.addons.partner_email_check.models.res_partner." "validate_email", None
  104. ):
  105. self.test_partner.email = "notatallvalid@@domain"
  106. @mute_logger("odoo.addons.partner_email_check.models.res_partner")
  107. def test_lacking_dependency_keeps_uniqueness_constraint_working(self):
  108. self.disallow_duplicates()
  109. with patch(
  110. "odoo.addons.partner_email_check.models.res_partner." "validate_email", None
  111. ):
  112. self.env["res.partner"].create(
  113. {"name": "alsotest", "email": "email@domain.tld"}
  114. )
  115. with self.assertRaises(UserError):
  116. self.test_partner.email = "email@domain.tld"
  117. def test_invalid_email_addresses_allowed(self):
  118. self.env.company.partner_email_check_syntax = False
  119. self.test_partner.email = "bad@email@domain..com"
  120. self.assertTrue(self.test_partner.email)