diff --git a/addons/mail/tests/common.py b/addons/mail/tests/common.py index b3c9244b2b8..853ceb611be 100644 --- a/addons/mail/tests/common.py +++ b/addons/mail/tests/common.py @@ -329,18 +329,19 @@ class MockEmail(common.BaseCase, MockSmtplibCase): # GATEWAY ASSERTS # ------------------------------------------------------------ - def assertMailMail(self, recipients, status, - mail_message=None, author=None, - content=None, fields_values=None, email_values=None): - """ Assert mail.mail records are created and maybe sent as emails. Allow + def _assertMailMail(self, mail, recipients_list, + status, author=None, + content=None, fields_values=None, email_values=None): + """ Assert mail.mail record values and maybe related emails. Allow asserting their content. Records to check are the one generated when - using mock (mail.mail and outgoing emails). This method takes partners - as source of record fetch and assert. + using mock (mail.mail and outgoing emails). - :param recipients: a ``res.partner`` recordset. See ``_find_mail_mail_wpartners``; + :param mail: a ``mail.mail`` record; + :param recipients_list: an ``res.partner`` recordset or a list of + emails (both are supported, see ``_find_mail_mail_wpartners`` and + ``_find_mail_mail_wemail``); :param status: mail.mail state used to filter mails. If ``sent`` this method also check that emails have been sent trough gateway; - :param mail_message: see ``_find_mail_mail_wpartners``; :param author: see ``_find_mail_mail_wpartners``; :param content: if given, check it is contained within mail html body; :param fields_values: if given, should be a dictionary of field names / @@ -350,52 +351,89 @@ class MockEmail(common.BaseCase, MockSmtplibCase): allowing to check sent email additional values (if any). See ``assertSentEmail``; """ + self.assertTrue(bool(mail)) + if content: + self.assertIn(content, mail.body_html) + for fname, fvalue in (fields_values or {}).items(): + with self.subTest(fname=fname, fvalue=fvalue): + self.assertEqual( + mail[fname], fvalue, + 'Mail: expected %s for %s, got %s' % (fvalue, fname, mail[fname]) + ) + if status == 'sent': + for recipient in recipients_list: + with self.subTest(recipient=recipient): + self.assertSentEmail( + email_values['email_from'] if email_values and email_values.get('email_from') else author, + [recipient], + **(email_values or {}) + ) + + def assertMailMail(self, recipients, status, + mail_message=None, author=None, + content=None, fields_values=None, email_values=None): + """ Assert mail.mail records are created and maybe sent as emails. This + method takes partners as source to find mails and check their content. + See '_assertMailMail' for more details. + + :param recipients: a ``res.partner`` recordset. See + ``_find_mail_mail_wpartners``; + :param mail_message: used to find the related email; + + See '_assertMailMail' for more details about other parameters. + """ found_mail = self._find_mail_mail_wpartners(recipients, status, mail_message=mail_message, author=author) self.assertTrue(bool(found_mail)) - if content: - self.assertIn(content, found_mail.body_html) - for fname, fvalue in (fields_values or {}).items(): - self.assertEqual( - found_mail[fname], fvalue, - 'Mail: expected %s for %s, got %s' % (fvalue, fname, found_mail[fname])) - if status == 'sent': - for recipient in recipients: - self.assertSentEmail(email_values['email_from'] if email_values and email_values.get('email_from') else author, [recipient], **(email_values or {})) + self._assertMailMail( + found_mail, recipients, + status, author=author, + content=content, fields_values=fields_values, email_values=email_values, + ) def assertMailMailWEmails(self, emails, status, mail_message=None, author=None, content=None, fields_values=None, email_values=None): - """ Assert mail.mail records are created and maybe sent as emails. Allow - asserting their content. Records to check are the one generated when - using mock (mail.mail and outgoing emails). This method takes emails - as source of record fetch and assert. + """ Assert mail.mail records are created and maybe sent as emails. This + method takes emails as source to find mails and check their content. + See '_assertMailMail' for more details. :param emails: a list of emails. See ``_find_mail_mail_wemail``; - :param status: mail.mail state used to filter mails. If ``sent`` this method - also check that emails have been sent trough gateway; - :param mail_message: see ``_find_mail_mail_wemail``; - :param author: see ``_find_mail_mail_wemail``;; - :param content: if given, check it is contained within mail html body; - :param fields_values: if given, should be a dictionary of field names / - values allowing to check ``mail.mail`` additional values (subject, - reply_to, ...); - :param email_values: if given, should be a dictionary of keys / values - allowing to check sent email additional values (if any). - See ``assertSentEmail``; + :param mail_message: used to find the related email; + + See '_assertMailMail' for more details about other parameters. """ for email_to in emails: found_mail = self._find_mail_mail_wemail(email_to, status, mail_message=mail_message, author=author) - if content: - self.assertIn(content, found_mail.body_html) - for fname, fvalue in (fields_values or {}).items(): - self.assertEqual( - found_mail[fname], fvalue, - 'Mail: expected %s for %s, got %s' % (fvalue, fname, found_mail[fname])) - if status == 'sent': - for email_to in emails: - self.assertSentEmail(email_values['email_from'] if email_values and email_values.get('email_from') else author, [email_to], **(email_values or {})) + self.assertTrue(bool(found_mail)) + self._assertMailMail( + found_mail, [email_to], + status, author=author, + content=content, fields_values=fields_values, email_values=email_values, + ) + + def assertMailMailWRecord(self, record, recipients, status, + mail_message=None, author=None, + content=None, fields_values=None, email_values=None): + """ Assert mail.mail records are created and maybe sent as emails. This + method takes a record as source to find mails and check their content + using model / res_id. See '_assertMailMail' for more details. + + :param record: a record used to find emails sent related on it. + See ``_find_mail_mail_wrecord``; + :param mail_message: used to find the related email; + + See '_assertMailMail' for more details about other parameters. + """ + found_mail = self._find_mail_mail_wrecord(record, mail_message=mail_message, author=author) + self.assertTrue(bool(found_mail)) + self._assertMailMail( + found_mail, recipients, + status, author=author, + content=content, fields_values=fields_values, email_values=email_values, + ) def assertMailMailWId(self, mail_id, status, + author=None, content=None, fields_values=None): """ Assert mail.mail records are created and maybe sent as emails. Allow asserting their content. Records to check are the one generated when @@ -403,32 +441,27 @@ class MockEmail(common.BaseCase, MockSmtplibCase): as source of record fetch and assert. :param mail_id: a ``mail.mail`` DB ID. See ``_find_mail_mail_wid``; - :param status: mail.mail state to check upon found mail; - :param content: if given, check it is contained within mail html body; - :param fields_values: if given, should be a dictionary of field names / - values allowing to check ``mail.mail`` additional values (subject, - reply_to, ...); + + For other parameters, see ``_assertMailMail``. """ found_mail = self._find_mail_mail_wid(mail_id) self.assertTrue(bool(found_mail)) - if status: - self.assertEqual(found_mail.state, status) - if content: - self.assertIn(content, found_mail.body_html) - for fname, fvalue in (fields_values or {}).items(): - self.assertEqual( - found_mail[fname], fvalue, - 'Mail: expected %s for %s, got %s' % (fvalue, fname, found_mail[fname])) + self._assertMailMail( + found_mail, [], # generally used when recipients are Falsy + status, author=author, + content=content, fields_values=fields_values, + ) def assertMessageFields(self, message, fields_values): """ Just a quick helper to check a mail.message content by giving directly a dict for fields. Allows to hide a lot of assertEqual under a simple call with a dictionary of expected values. """ for fname, fvalue in fields_values.items(): - self.assertEqual( - message[fname], fvalue, - 'Message: expected %s for %s, got %s' % (fvalue, fname, message[fname]) - ) + with self.subTest(fname=fname, fvalue=fvalue): + self.assertEqual( + message[fname], fvalue, + f'Message: expected {fvalue} for {fname}, got {message[fname]}', + ) def assertNoMail(self, recipients, mail_message=None, author=None): """ Check no mail.mail and email was generated during gateway mock. """ @@ -1030,22 +1063,22 @@ class MailCommon(common.TransactionCase, MailCase): return cls.user_portal @classmethod - def _create_records_for_batch(cls, model, count, additional_values=None): + def _create_records_for_batch(cls, model, count, additional_values=None, prefix=None): additional_values = additional_values or {} records = cls.env[model] partners = cls.env['res.partner'] country_id = cls.env.ref('base.be').id base_values = [ - {'name': 'Test_%s' % idx, + {'name': f'{prefix}Test_{idx}', **additional_values, } for idx in range(count) ] if 'customer_id' in cls.env[model]: partners = cls.env['res.partner'].with_context(**cls._test_context).create([{ - 'name': 'Partner_%s' % idx, - 'email': '_test_partner_%s@example.com' % idx, + 'name': f'Partner_{idx}', + 'email': f'{prefix}test_partner_{idx}@example.com', 'country_id': country_id, 'mobile': '047500%02d%02d' % (idx, idx) } for idx in range(count)]) diff --git a/addons/mass_mailing/tests/common.py b/addons/mass_mailing/tests/common.py index 6e160bb84a9..ca5c2671bbf 100644 --- a/addons/mass_mailing/tests/common.py +++ b/addons/mass_mailing/tests/common.py @@ -127,7 +127,7 @@ class MassMailCase(MailCase, MockLinkTracker): self.assertMailMail(partner, state_mapping[status], author=author, content=content, fields_values=fields_values) # specific if email is False -> could have troubles finding it if several falsy traces elif not email and status in ('cancel', 'bounce'): - self.assertMailMailWId(recipient_trace.mail_mail_id_int, state_mapping[status], content=content, fields_values=fields_values) + self.assertMailMailWId(recipient_trace.mail_mail_id_int, state_mapping[status], author=author, content=content, fields_values=fields_values) else: self.assertMailMailWEmails([email], state_mapping[status], author=author, content=content, fields_values=fields_values) diff --git a/addons/test_mail/tests/test_mail_composer.py b/addons/test_mail/tests/test_mail_composer.py index 631e4bc9177..73dc63e27e7 100644 --- a/addons/test_mail/tests/test_mail_composer.py +++ b/addons/test_mail/tests/test_mail_composer.py @@ -49,7 +49,7 @@ class TestMailComposer(TestMailCommon, TestRecipients): }) cls.test_records, cls.test_partners = cls._create_records_for_batch( 'mail.test.ticket', 2, - additional_values={'user_id': cls.user_employee_2.id} + additional_values={'user_id': cls.user_employee_2.id}, ) cls.test_report = cls.env['ir.actions.report'].create({