diff options
| author | Mike Edmunds <medmunds@gmail.com> | 2026-03-19 13:59:34 -0700 |
|---|---|---|
| committer | Jacob Walls <jacobtylerwalls@gmail.com> | 2026-04-11 08:54:07 -0400 |
| commit | 3ef48ca6c10830914b09abd20ef48a705e1fbfcd (patch) | |
| tree | 945f86ce2aa4d22a30f13a2ebd33608c9457956e /tests | |
| parent | a8ef1a697bbe7b74141cd74c26d15ed35dd7817f (diff) | |
Refs #36953 -- Moved non-backend-dependent BaseEmailBackendTests.
Relocated BaseEmailBackendTests that are _not_ dependent on the email
backend.
- In general, moved test cases to EmailMessageTests or SendMailTests
as appropriate, and changed them to work with the testing outbox.
- Replaced BaseEmailBackendTests.test_send_verbose_name() with
EmailMessageTests.test_unicode_display_name_in_from_email().
(EmailMessageTests.test_address_header_handling() also partly covers
the behavior, as well as Python's own message serialization tests.)
- Removed BaseEmailBackendTests.test_message_cc_header(), which was
already covered by EmailMessageTests.test_cc*() (and Python's own
message serialization tests).
- Replaced BaseEmailBackendTests.test_idn_send() with
EmailMessageTests.test_idn_addresses() to cover from_email and cc.
(EmailMessageTests.test_address_header_handling() already covered to.)
- Removed BaseEmailBackendTests.test_recipient_without_domain(), which
was partly covered by EmailMessageTests.test_localpart_only_address().
Updated the latter to cover a localpart-only from_email.
- Updated docstrings and comments to clarify a few tests that _do_
depend on the email backend.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/mail/tests.py | 596 |
1 files changed, 296 insertions, 300 deletions
diff --git a/tests/mail/tests.py b/tests/mail/tests.py index 902215a3a2..e756e49d6e 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -184,6 +184,20 @@ class MailTestsMixin: "First string doesn't end with the second.", ) + def get_outbox_message(self, index=0, expected_count=1): + """ + Return a (Django) EmailMessage from the locmem outbox. + + If expected_count is not None, first assert that the outbox has exactly + the expected number of messages. + """ + if expected_count is not None: + assert expected_count > index # Require valid args. + self.assertEqual(len(mail.outbox), expected_count) + else: + self.assertGreater(len(mail.outbox), index) + return mail.outbox[index].message() + def get_raw_attachments(self, django_message): """ Return a list of the raw attachment parts in the MIME message generated @@ -1291,6 +1305,39 @@ class EmailMessageTests(MailTestsMixin, SimpleTestCase): s = msg.message().as_bytes() self.assertIn(b"Content-Transfer-Encoding: quoted-printable", s) + def test_long_lines(self): + """ + Email line length is limited to 998 chars by the RFC 5322 Section + 2.1.1. A message body containing longer lines is converted to + quoted-printable or base64 (whichever is shorter), to avoid having to + insert newlines in a way that alters the intended text. + """ + cases = [ + # (body, expected_cte) + ("В южных морях " * 60, "base64"), + ("I de sørlige hav " * 58, "quoted-printable"), + ] + for body, expected_cte in cases: + mail.outbox = [] + with self.subTest(body=f"{body[:10]}…", expected_cte=expected_cte): + # Test precondition: Body is a single line < 998 characters, + # but utf-8 encoding of body is > 998 octets (forcing a CTE + # that avoids inserting newlines). + self.assertLess(len(body), 998) + self.assertGreater(len(body.encode()), 998) + + email = EmailMessage(body=body, to=["to@example.com"]) + email.send() + message = self.get_outbox_message() + self.assertMessageHasHeaders( + message, + { + ("MIME-Version", "1.0"), + ("Content-Type", 'text/plain; charset="utf-8"'), + ("Content-Transfer-Encoding", expected_cte), + }, + ) + def test_address_header_handling(self): # This verifies the modern email API's address header handling. cases = [ @@ -1399,6 +1446,23 @@ class EmailMessageTests(MailTestsMixin, SimpleTestCase): with self.assertRaisesMessage(ValueError, msg): email.message() + def test_idn_addresses(self): + """ + IDNA encoding is applied to non-ASCII domains in address headers + (#14301). + + See also test_address_header_handling() for several variations in the + to field. + """ + email = EmailMessage( + from_email="from@öäü.com", to=["to@öäü.com"], cc=["cc@öäü.com"] + ) + email.send() + message = self.get_outbox_message() + self.assertEqual(message.get("from"), "from@xn--4ca9at.com") + self.assertEqual(message.get("to"), "to@xn--4ca9at.com") + self.assertEqual(message.get("cc"), "cc@xn--4ca9at.com") + def test_localpart_only_address(self): """ Django allows sending to a localpart-only email address @@ -1406,12 +1470,40 @@ class EmailMessageTests(MailTestsMixin, SimpleTestCase): is accepted by some SMTP servers for local delivery. Regression for #15042. """ - email = EmailMessage(to=["localpartonly"]) + email = EmailMessage(from_email="django", to=["localpartonly"]) parsed = message_from_bytes(email.message().as_bytes()) self.assertEqual( + parsed["From"].addresses, (Address(username="django", domain=""),) + ) + self.assertEqual( parsed["To"].addresses, (Address(username="localpartonly", domain=""),) ) + def test_lazy_addresses(self): + """ + Email sending should support lazy email addresses (#24416). + """ + _ = gettext_lazy + email = EmailMessage( + from_email=_("tester"), + to=[_("to1"), _("to2")], + cc=[_("cc1"), _("cc2")], + bcc=[_("bcc")], + reply_to=[_("reply")], + ) + self.assertEqual(email.recipients(), ["to1", "to2", "cc1", "cc2", "bcc"]) + email.send() + message = self.get_outbox_message() + self.assertEqual(message.get("from"), "tester") + self.assertEqual(message.get("to"), "to1, to2") + self.assertEqual(message.get("cc"), "cc1, cc2") + self.assertEqual(message.get("Reply-To"), "reply") + + def test_unicode_display_name_in_from_email(self): + email = EmailMessage(from_email='"Firstname Sürname" <from@example.com>') + parsed = message_from_bytes(email.message().as_bytes()) + self.assertEqual(parsed["From"], "Firstname Sürname <from@example.com>") + def test_email_multi_alternatives_content_mimetype_none(self): email_msg = EmailMultiAlternatives() msg = "Both content and mimetype must be provided." @@ -1748,11 +1840,65 @@ class EmailMessageTests(MailTestsMixin, SimpleTestCase): email.send(fail_silently=True) -class SendMailTests(SimpleTestCase): +class SendMailTests(SimpleTestCase, MailTestsMixin): """ Tests for django.core.mail.send_mail(). """ + def test_plaintext_send_mail(self): + """ + Test send_mail without the html_message + regression test for adding html_message parameter to send_mail() + """ + send_mail("Subject", "Content\n", "sender@example.com", ["nobody@example.com"]) + message = self.get_outbox_message() + + self.assertEqual(message.get("subject"), "Subject") + self.assertEqual(message.get_all("to"), ["nobody@example.com"]) + self.assertFalse(message.is_multipart()) + self.assertEqual(message.get_content(), "Content\n") + self.assertEqual(message.get_content_type(), "text/plain") + + def test_html_send_mail(self): + """Test html_message argument to send_mail""" + send_mail( + "Subject", + "Content\n", + "sender@example.com", + ["nobody@example.com"], + html_message="HTML Content\n", + ) + message = self.get_outbox_message() + + self.assertEqual(message.get("subject"), "Subject") + self.assertEqual(message.get_all("to"), ["nobody@example.com"]) + self.assertTrue(message.is_multipart()) + self.assertEqual(len(message.get_payload()), 2) + self.assertEqual(message.get_payload(0).get_content(), "Content\n") + self.assertEqual(message.get_payload(0).get_content_type(), "text/plain") + self.assertEqual(message.get_payload(1).get_content(), "HTML Content\n") + self.assertEqual(message.get_payload(1).get_content_type(), "text/html") + + def test_idn_addresses(self): + """ + IDNA encoding is applied to non-ASCII domains in address headers + (#14301). + """ + self.assertTrue(send_mail("Subject", "Content", "from@öäü.com", ["to@öäü.com"])) + message = self.get_outbox_message() + self.assertEqual(message.get("from"), "from@xn--4ca9at.com") + self.assertEqual(message.get("to"), "to@xn--4ca9at.com") + + def test_lazy_addresses(self): + """ + Email sending should support lazy email addresses (#24416). + """ + _ = gettext_lazy + self.assertTrue(send_mail("Subject", "Content", _("tester"), [_("django")])) + message = self.get_outbox_message() + self.assertEqual(message.get("from"), "tester") + self.assertEqual(message.get("to"), "django") + def test_connection_arg(self): # Send using non-default connection. connection = mail.get_connection("mail.custombackend.EmailBackend") @@ -1849,11 +1995,152 @@ class SendMassMailTests(SimpleTestCase): ) -class MailAdminsAndManagersTests(SimpleTestCase): +class MailAdminsAndManagersTests(SimpleTestCase, MailTestsMixin): """ Tests for django.core.mail.mail_admins() and mail_managers(). """ + def test_mail_admins_and_managers(self): + tests = ( + # The ADMINS and MANAGERS settings are lists of email strings. + ['"Name, Full" <test@example.com>'], + # Lists and tuples are interchangeable. + ["test@example.com", "other@example.com"], + ("test@example.com", "other@example.com"), + # Lazy strings are supported. + [gettext_lazy("test@example.com")], + ) + for setting, mail_func in ( + ("ADMINS", mail_admins), + ("MANAGERS", mail_managers), + ): + for value in tests: + mail.outbox = [] + with ( + self.subTest(setting=setting, value=value), + self.settings(**{setting: value}), + ): + mail_func("subject", "content") + message = self.get_outbox_message() + expected_to = ", ".join([str(address) for address in value]) + self.assertEqual(message.get_all("to"), [expected_to]) + + @override_settings(MANAGERS=["nobody@example.com"]) + def test_html_mail_managers(self): + """Test html_message argument to mail_managers""" + mail_managers("Subject", "Content\n", html_message="HTML Content\n") + message = self.get_outbox_message() + + self.assertEqual(message.get("subject"), "[Django] Subject") + self.assertEqual(message.get_all("to"), ["nobody@example.com"]) + self.assertTrue(message.is_multipart()) + self.assertEqual(len(message.get_payload()), 2) + self.assertEqual(message.get_payload(0).get_content(), "Content\n") + self.assertEqual(message.get_payload(0).get_content_type(), "text/plain") + self.assertEqual(message.get_payload(1).get_content(), "HTML Content\n") + self.assertEqual(message.get_payload(1).get_content_type(), "text/html") + + @override_settings(ADMINS=["nobody@example.com"]) + def test_html_mail_admins(self): + """Test html_message argument to mail_admins""" + mail_admins("Subject", "Content\n", html_message="HTML Content\n") + message = self.get_outbox_message() + + self.assertEqual(message.get("subject"), "[Django] Subject") + self.assertEqual(message.get_all("to"), ["nobody@example.com"]) + self.assertTrue(message.is_multipart()) + self.assertEqual(len(message.get_payload()), 2) + self.assertEqual(message.get_payload(0).get_content(), "Content\n") + self.assertEqual(message.get_payload(0).get_content_type(), "text/plain") + self.assertEqual(message.get_payload(1).get_content(), "HTML Content\n") + self.assertEqual(message.get_payload(1).get_content_type(), "text/html") + + @override_settings( + ADMINS=["nobody+admin@example.com"], + MANAGERS=["nobody+manager@example.com"], + ) + def test_manager_and_admin_mail_prefix(self): + """ + String prefix + lazy translated subject = bad output + Regression for #13494 + """ + for mail_func in [mail_managers, mail_admins]: + mail.outbox = [] + with self.subTest(mail_func=mail_func): + mail_func(gettext_lazy("Subject"), "Content") + message = self.get_outbox_message() + self.assertEqual(message.get("subject"), "[Django] Subject") + + @override_settings(ADMINS=[], MANAGERS=[]) + def test_empty_admins(self): + """ + mail_admins/mail_managers doesn't connect to the mail server + if there are no recipients (#9383) + """ + for mail_func in [mail_managers, mail_admins]: + mail.outbox = [] + with self.subTest(mail_func=mail_func): + mail_func("hi", "there") + self.assertEqual(mail.outbox, []) + + # RemovedInDjango70Warning. + def test_deprecated_admins_managers_tuples(self): + tests = ( + [("nobody", "nobody@example.com"), ("other", "other@example.com")], + [["nobody", "nobody@example.com"], ["other", "other@example.com"]], + ) + for setting, mail_func in ( + ("ADMINS", mail_admins), + ("MANAGERS", mail_managers), + ): + msg = ( + f"Using (name, address) pairs in the {setting} setting is deprecated." + " Replace with a list of email address strings." + ) + for value in tests: + mail.outbox = [] + with ( + self.subTest(setting=setting, value=value), + self.settings(**{setting: value}), + ): + with self.assertWarnsMessage(RemovedInDjango70Warning, msg): + mail_func("subject", "content") + message = self.get_outbox_message() + expected_to = ", ".join([str(address) for _, address in value]) + self.assertEqual(message.get_all("to"), [expected_to]) + + def test_wrong_admins_managers(self): + tests = ( + "test@example.com", + gettext_lazy("test@example.com"), + # RemovedInDjango70Warning: uncomment these cases when support for + # deprecated (name, address) tuples is removed. + # [ + # ("nobody", "nobody@example.com"), + # ("other", "other@example.com") + # ], + # [ + # ["nobody", "nobody@example.com"], + # ["other", "other@example.com"] + # ], + [("name", "test", "example.com")], + [("Name <test@example.com",)], + [[]], + ) + for setting, mail_func in ( + ("ADMINS", mail_admins), + ("MANAGERS", mail_managers), + ): + msg = f"The {setting} setting must be a list of email address strings." + for value in tests: + mail.outbox = [] + with ( + self.subTest(setting=setting, value=value), + self.settings(**{setting: value}), + ): + with self.assertRaisesMessage(ImproperlyConfigured, msg): + mail_func("subject", "content") + @override_settings(ADMINS=["nobody@example.com"]) def test_connection_arg_mail_admins(self): # Send using non-default connection. @@ -2337,39 +2624,6 @@ class BaseEmailBackendTests(MailTestsMixin): self.assertEqual(message["subject"], "Chère maman") self.assertEqual(message.get_content(), "Je t'aime très fort\n") - def test_send_long_lines(self): - """ - Email line length is limited to 998 chars by the RFC 5322 Section - 2.1.1. A message body containing longer lines is converted to - quoted-printable or base64 (whichever is shorter), to avoid having to - insert newlines in a way that alters the intended text. - """ - cases = [ - # (body, expected_cte) - ("В южных морях " * 60, "base64"), - ("I de sørlige hav " * 58, "quoted-printable"), - ] - for body, expected_cte in cases: - with self.subTest(body=f"{body[:10]}…", expected_cte=expected_cte): - self.flush_mailbox() - # Test precondition: Body is a single line < 998 characters, - # but utf-8 encoding of body is > 998 octets (forcing a CTE - # that avoids inserting newlines). - self.assertLess(len(body), 998) - self.assertGreater(len(body.encode()), 998) - - email = EmailMessage(body=body, to=["to@example.com"]) - email.send() - message = self.get_the_message() - self.assertMessageHasHeaders( - message, - { - ("MIME-Version", "1.0"), - ("Content-Type", 'text/plain; charset="utf-8"'), - ("Content-Transfer-Encoding", expected_cte), - }, - ) - def test_send_many(self): email1 = EmailMessage(to=["to-1@example.com"]) email2 = EmailMessage(to=["to-2@example.com"]) @@ -2385,269 +2639,6 @@ class BaseEmailBackendTests(MailTestsMixin): self.assertEqual(messages[1]["To"], "to-2@example.com") self.flush_mailbox() - def test_send_verbose_name(self): - email = EmailMessage( - from_email='"Firstname Sürname" <from@example.com>', - to=["to@example.com"], - ) - email.send() - message = self.get_the_message() - self.assertEqual(message["from"], "Firstname Sürname <from@example.com>") - - def test_plaintext_send_mail(self): - """ - Test send_mail without the html_message - regression test for adding html_message parameter to send_mail() - """ - send_mail("Subject", "Content\n", "sender@example.com", ["nobody@example.com"]) - message = self.get_the_message() - - self.assertEqual(message.get("subject"), "Subject") - self.assertEqual(message.get_all("to"), ["nobody@example.com"]) - self.assertFalse(message.is_multipart()) - self.assertEqual(message.get_content(), "Content\n") - self.assertEqual(message.get_content_type(), "text/plain") - - def test_html_send_mail(self): - """Test html_message argument to send_mail""" - send_mail( - "Subject", - "Content\n", - "sender@example.com", - ["nobody@example.com"], - html_message="HTML Content\n", - ) - message = self.get_the_message() - - self.assertEqual(message.get("subject"), "Subject") - self.assertEqual(message.get_all("to"), ["nobody@example.com"]) - self.assertTrue(message.is_multipart()) - self.assertEqual(len(message.get_payload()), 2) - self.assertEqual(message.get_payload(0).get_content(), "Content\n") - self.assertEqual(message.get_payload(0).get_content_type(), "text/plain") - self.assertEqual(message.get_payload(1).get_content(), "HTML Content\n") - self.assertEqual(message.get_payload(1).get_content_type(), "text/html") - - def test_mail_admins_and_managers(self): - tests = ( - # The ADMINS and MANAGERS settings are lists of email strings. - ['"Name, Full" <test@example.com>'], - # Lists and tuples are interchangeable. - ["test@example.com", "other@example.com"], - ("test@example.com", "other@example.com"), - # Lazy strings are supported. - [gettext_lazy("test@example.com")], - ) - for setting, mail_func in ( - ("ADMINS", mail_admins), - ("MANAGERS", mail_managers), - ): - for value in tests: - self.flush_mailbox() - with ( - self.subTest(setting=setting, value=value), - self.settings(**{setting: value}), - ): - mail_func("subject", "content") - message = self.get_the_message() - expected_to = ", ".join([str(address) for address in value]) - self.assertEqual(message.get_all("to"), [expected_to]) - - @override_settings(MANAGERS=["nobody@example.com"]) - def test_html_mail_managers(self): - """Test html_message argument to mail_managers""" - mail_managers("Subject", "Content\n", html_message="HTML Content\n") - message = self.get_the_message() - - self.assertEqual(message.get("subject"), "[Django] Subject") - self.assertEqual(message.get_all("to"), ["nobody@example.com"]) - self.assertTrue(message.is_multipart()) - self.assertEqual(len(message.get_payload()), 2) - self.assertEqual(message.get_payload(0).get_content(), "Content\n") - self.assertEqual(message.get_payload(0).get_content_type(), "text/plain") - self.assertEqual(message.get_payload(1).get_content(), "HTML Content\n") - self.assertEqual(message.get_payload(1).get_content_type(), "text/html") - - @override_settings(ADMINS=["nobody@example.com"]) - def test_html_mail_admins(self): - """Test html_message argument to mail_admins""" - mail_admins("Subject", "Content\n", html_message="HTML Content\n") - message = self.get_the_message() - - self.assertEqual(message.get("subject"), "[Django] Subject") - self.assertEqual(message.get_all("to"), ["nobody@example.com"]) - self.assertTrue(message.is_multipart()) - self.assertEqual(len(message.get_payload()), 2) - self.assertEqual(message.get_payload(0).get_content(), "Content\n") - self.assertEqual(message.get_payload(0).get_content_type(), "text/plain") - self.assertEqual(message.get_payload(1).get_content(), "HTML Content\n") - self.assertEqual(message.get_payload(1).get_content_type(), "text/html") - - @override_settings( - ADMINS=["nobody+admin@example.com"], - MANAGERS=["nobody+manager@example.com"], - ) - def test_manager_and_admin_mail_prefix(self): - """ - String prefix + lazy translated subject = bad output - Regression for #13494 - """ - for mail_func in [mail_managers, mail_admins]: - with self.subTest(mail_func=mail_func): - mail_func(gettext_lazy("Subject"), "Content") - message = self.get_the_message() - self.assertEqual(message.get("subject"), "[Django] Subject") - self.flush_mailbox() - - @override_settings(ADMINS=[], MANAGERS=[]) - def test_empty_admins(self): - """ - mail_admins/mail_managers doesn't connect to the mail server - if there are no recipients (#9383) - """ - for mail_func in [mail_managers, mail_admins]: - with self.subTest(mail_func=mail_func): - mail_func("hi", "there") - self.assertEqual(self.get_mailbox_content(), []) - - # RemovedInDjango70Warning. - def test_deprecated_admins_managers_tuples(self): - tests = ( - [("nobody", "nobody@example.com"), ("other", "other@example.com")], - [["nobody", "nobody@example.com"], ["other", "other@example.com"]], - ) - for setting, mail_func in ( - ("ADMINS", mail_admins), - ("MANAGERS", mail_managers), - ): - msg = ( - f"Using (name, address) pairs in the {setting} setting is deprecated." - " Replace with a list of email address strings." - ) - for value in tests: - self.flush_mailbox() - with ( - self.subTest(setting=setting, value=value), - self.settings(**{setting: value}), - ): - with self.assertWarnsMessage(RemovedInDjango70Warning, msg): - mail_func("subject", "content") - message = self.get_the_message() - expected_to = ", ".join([str(address) for _, address in value]) - self.assertEqual(message.get_all("to"), [expected_to]) - - def test_wrong_admins_managers(self): - tests = ( - "test@example.com", - gettext_lazy("test@example.com"), - # RemovedInDjango70Warning: uncomment these cases when support for - # deprecated (name, address) tuples is removed. - # [ - # ("nobody", "nobody@example.com"), - # ("other", "other@example.com") - # ], - # [ - # ["nobody", "nobody@example.com"], - # ["other", "other@example.com"] - # ], - [("name", "test", "example.com")], - [("Name <test@example.com",)], - [[]], - ) - for setting, mail_func in ( - ("ADMINS", mail_admins), - ("MANAGERS", mail_managers), - ): - msg = f"The {setting} setting must be a list of email address strings." - for value in tests: - with ( - self.subTest(setting=setting, value=value), - self.settings(**{setting: value}), - ): - with self.assertRaisesMessage(ImproperlyConfigured, msg): - mail_func("subject", "content") - - def test_message_cc_header(self): - """ - Regression test for #7722 - """ - email = EmailMessage( - "Subject", - "Content", - "from@example.com", - ["to@example.com"], - cc=["cc@example.com"], - ) - mail.get_connection().send_messages([email]) - message = self.get_the_message() - self.assertMessageHasHeaders( - message, - { - ("MIME-Version", "1.0"), - ("Content-Type", 'text/plain; charset="utf-8"'), - ("Content-Transfer-Encoding", "7bit"), - ("Subject", "Subject"), - ("From", "from@example.com"), - ("To", "to@example.com"), - ("Cc", "cc@example.com"), - }, - ) - self.assertIn("\nDate: ", message.as_string()) - - def test_idn_send(self): - """ - Regression test for #14301 - """ - self.assertTrue(send_mail("Subject", "Content", "from@öäü.com", ["to@öäü.com"])) - message = self.get_the_message() - self.assertEqual(message.get("from"), "from@xn--4ca9at.com") - self.assertEqual(message.get("to"), "to@xn--4ca9at.com") - - self.flush_mailbox() - m = EmailMessage( - from_email="from@öäü.com", to=["to@öäü.com"], cc=["cc@öäü.com"] - ) - m.send() - message = self.get_the_message() - self.assertEqual(message.get("from"), "from@xn--4ca9at.com") - self.assertEqual(message.get("to"), "to@xn--4ca9at.com") - self.assertEqual(message.get("cc"), "cc@xn--4ca9at.com") - - def test_recipient_without_domain(self): - """ - Regression test for #15042 - """ - self.assertTrue(send_mail("Subject", "Content", "tester", ["django"])) - message = self.get_the_message() - self.assertEqual(message.get("from"), "tester") - self.assertEqual(message.get("to"), "django") - - def test_lazy_addresses(self): - """ - Email sending should support lazy email addresses (#24416). - """ - _ = gettext_lazy - self.assertTrue(send_mail("Subject", "Content", _("tester"), [_("django")])) - message = self.get_the_message() - self.assertEqual(message.get("from"), "tester") - self.assertEqual(message.get("to"), "django") - - self.flush_mailbox() - m = EmailMessage( - from_email=_("tester"), - to=[_("to1"), _("to2")], - cc=[_("cc1"), _("cc2")], - bcc=[_("bcc")], - reply_to=[_("reply")], - ) - self.assertEqual(m.recipients(), ["to1", "to2", "cc1", "cc2", "bcc"]) - m.send() - message = self.get_the_message() - self.assertEqual(message.get("from"), "tester") - self.assertEqual(message.get("to"), "to1, to2") - self.assertEqual(message.get("cc"), "cc1, cc2") - self.assertEqual(message.get("Reply-To"), "reply") - def test_close_connection(self): """ Connection can be closed (even when not explicitly opened) @@ -2722,7 +2713,8 @@ class LocmemBackendTests(BaseEmailBackendTests, SimpleTestCase): self.assertEqual(len(mail.outbox), 2) def test_validate_multiline_headers(self): - # Ticket #18861 - Validate emails when using the locmem backend + # Headers are validated when using the locmem backend (#18861). + # (See also EmailMessageTests.test_header_injection().) with self.assertRaises(ValueError): send_mail( "Subject\nMultiline", "Content", "from@example.com", ["to@example.com"] @@ -2804,6 +2796,10 @@ class FileBackendTests(BaseEmailBackendTests, SimpleTestCase): class FileBackendPathLibTests(FileBackendTests): + """ + Repeat FileBackendTests cases using a Path object as file_path. + """ + def mkdtemp(self): tmp_dir = super().mkdtemp() return Path(tmp_dir) |
