diff --git a/addons/mail/models/mail_mail.py b/addons/mail/models/mail_mail.py index 80d1ece80f38fe6783f6594da854ff52dca33a3e..399f82722beb491ffe0617c47b6304d5730e8924 100644 --- a/addons/mail/models/mail_mail.py +++ b/addons/mail/models/mail_mail.py @@ -206,7 +206,14 @@ class MailMail(models.Model): body = self._send_prepare_body() body_alternative = tools.html2plaintext(body) if partner: - email_to = [tools.formataddr((partner.name or 'False', partner.email or 'False'))] + emails_normalized = tools.email_normalize_all(partner.email) + if emails_normalized: + email_to = [ + tools.formataddr((partner.name or "False", email or "False")) + for email in emails_normalized + ] + else: + email_to = [tools.formataddr((partner.name or "False", partner.email or "False"))] else: email_to = tools.email_split_and_format(self.email_to) res = { diff --git a/addons/test_mail/tests/test_mail_composer.py b/addons/test_mail/tests/test_mail_composer.py index 99b6664fa6b70b03b8c38008bfaf503889c0468e..807b8f1000a7fb44810188b0af22a6247b352ee8 100644 --- a/addons/test_mail/tests/test_mail_composer.py +++ b/addons/test_mail/tests/test_mail_composer.py @@ -734,6 +734,10 @@ class TestComposerResultsComment(TestMailComposer): self.assertMailMail( self.partner_1 + self.partner_2 + mailed_new_partners, 'sent', author=self.partner_employee, + email_to_recipients=[ + [self.partner_1.email_formatted], + [f'"{self.partner_2.name}" <valid.other.1@agrolait.com>', f'"{self.partner_2.name}" <valid.other.cc@agrolait.com>'], + ] + [[email] for email in mailed_new_partners.mapped('email_formatted')], email_values={ 'body_content': f'TemplateBody {self.test_record.name}', 'email_from': formataddr((self.user_employee.name, 'email.from.1@test.example.com,email.from.2@test.example.com')), @@ -1165,6 +1169,10 @@ class TestComposerResultsMass(TestMailComposer): self.partner_1 + self.partner_2 + mailed_new_partners, 'sent', author=self.partner_employee, + email_to_recipients=[ + [self.partner_1.email_formatted], + [f'"{self.partner_2.name}" <valid.other.1@agrolait.com>', f'"{self.partner_2.name}" <valid.other.cc@agrolait.com>'], + ] + [[email] for email in mailed_new_partners.mapped('email_formatted')], email_values={ 'body_content': f'TemplateBody {record.name}', # currently holding multi-email 'email_from' diff --git a/addons/test_mail/tests/test_mail_mail.py b/addons/test_mail/tests/test_mail_mail.py index 9cc292c6dfd94eee37e5758cf97d24af1f21bd88..194baa3688acaa6fb82c71930328d12e8c38a79f 100644 --- a/addons/test_mail/tests/test_mail_mail.py +++ b/addons/test_mail/tests/test_mail_mail.py @@ -95,9 +95,9 @@ class TestMailMail(TestMailCommon): sorted(sorted(_mail['email_to']) for _mail in self._mails), sorted([sorted(['"Raoul, le Grand" <test.email.1@test.example.com>', '"Micheline, l\'immense" <test.email.2@test.example.com>']), [tools.formataddr((self.user_employee.name, self.user_employee.email_normalized))], - [tools.formataddr(("Tony Customer", '"Formatted Emails" <tony.customer@test.example.com>'))] + [tools.formataddr(("Tony Customer", 'tony.customer@test.example.com'))] ]), - 'Mail (FIXME): double encapsulation of emails ("Tony" <"Formatted" <tony@e.com>>)' + 'Mail: formatting issues should have been removed as much as possible' ) # Currently broken: CC are added to ALL emails (spammy) self.assertEqual( @@ -127,9 +127,11 @@ class TestMailMail(TestMailCommon): sorted(sorted(_mail['email_to']) for _mail in self._mails), sorted([sorted(['test.email.1@test.example.com', 'test.email.2@test.example.com']), [tools.formataddr((self.user_employee.name, self.user_employee.email_normalized))], - [tools.formataddr(("Tony Customer", 'tony.customer@test.example.com, norbert.customer@test.example.com'))] + sorted([tools.formataddr(("Tony Customer", 'tony.customer@test.example.com')), + tools.formataddr(("Tony Customer", 'norbert.customer@test.example.com'))]), ]), - 'Mail: currenty broken (multi email in a single address) but supported by some providers ("Tony" <tony@e.com, tony2@e.com>)' + 'Mail: formatting issues should have been removed as much as possible (multi emails in a single address are managed ' + 'like separate emails when sending with recipient_ids' ) # Currently broken: CC are added to ALL emails (spammy) self.assertEqual( @@ -155,9 +157,11 @@ class TestMailMail(TestMailCommon): sorted(sorted(_mail['email_to']) for _mail in self._mails), sorted([sorted(['test.email.1@test.example.com', 'test.email.2@test.example.com']), [tools.formataddr((self.user_employee.name, self.user_employee.email_normalized))], - [tools.formataddr(("Tony Customer", 'tony.customer@test.example.com, "Norbert Customer" <norbert.customer@test.example.com>'))] + sorted([tools.formataddr(("Tony Customer", 'tony.customer@test.example.com')), + tools.formataddr(("Tony Customer", 'norbert.customer@test.example.com'))]), ]), - 'Mail: currently broken, double encapsulation with formatting ("Tony" <tony@e.com, "Tony2" <tony2@e.com>>)' + 'Mail: formatting issues should have been removed as much as possible (multi emails in a single address are managed ' + 'like separate emails when sending with recipient_ids (and partner name is always used as name part)' ) # Currently broken: CC are added to ALL emails (spammy) self.assertEqual( diff --git a/addons/test_mail/tests/test_message_post.py b/addons/test_mail/tests/test_message_post.py index d2b450100a9c7cdee23e3cf8e75f02bbe5d07a07..cabdbadef694e882439a4e8f26d96ed67677b530 100644 --- a/addons/test_mail/tests/test_message_post.py +++ b/addons/test_mail/tests/test_message_post.py @@ -249,10 +249,11 @@ class TestMessagePost(TestMailCommon, TestRecipients): False, '', ' ', # falsy ] expected_tos = [ - # Currently semi-broken: sending to an incorrect email "Name" <address1, address2> - [f'"{self.partner_1.name}" <valid.lelitre@agrolait.com, valid.lelitre.cc@agrolait.com>',], - # Currently broken: sending to an incorrect email "Name" <"Name" <address>> - [f'"{self.partner_1.name}" <"Valid Lelitre" <valid.lelitre@agrolait.com>>',], + # Sends multi-emails + [f'"{self.partner_1.name}" <valid.lelitre@agrolait.com>', + f'"{self.partner_1.name}" <valid.lelitre.cc@agrolait.com>',], + # Avoid double encapsulation + [f'"{self.partner_1.name}" <valid.lelitre@agrolait.com>',], # sent "normally": formats email based on wrong / falsy email [f'"{self.partner_1.name}" <@wrong>',], [f'"{self.partner_1.name}" <@False>',], diff --git a/addons/test_mass_mailing/tests/test_mailing.py b/addons/test_mass_mailing/tests/test_mailing.py index 83c6bb2838043272e3e919b7ab4d74988b92a299..ae4de93985c5d674d6b9b5b12122e24bd538fcf3 100644 --- a/addons/test_mass_mailing/tests/test_mailing.py +++ b/addons/test_mass_mailing/tests/test_mailing.py @@ -211,6 +211,8 @@ class TestMassMailing(TestMassMailCommon): 'partner': customer_mult, 'state': 'ignored'}, {'email': 'test.customer.format@example.com', + # mail to avoids double encapsulation + 'email_to_recipients': [[f'"{customer_fmt.name}" <test.customer.format@example.com>']], 'failure_type': False, 'partner': customer_fmt, 'state': 'sent'},