mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Mailgun, SparkPost: support multiple from_email addresses
[RFC-5322 allows](https://tools.ietf.org/html/rfc5322#section-3.6.2) multiple addresses in the From header. Django's SMTP backend supports this, as a single comma-separated string (*not* a list of strings like the recipient params): from_email='one@example.com, two@example.com' to=['one@example.com', 'two@example.com'] Both Mailgun and SparkPost support multiple From addresses (and Postmark accepts them, though truncates to the first one on their end). For compatibility with Django -- and because Anymail attempts to support all ESP features -- Anymail now allows multiple From addresses, too, for ESPs that support it. Note: as a practical matter, deliverability with multiple From addresses is pretty bad. (Google outright rejects them.) This change also reworks Anymail's internal ParsedEmail object, and approach to parsing addresses, for better consistency with Django's SMTP backend and improved error messaging. In particular, Django (and now Anymail) allows multiple email addresses in a single recipient string: to=['one@example.com', 'two@example.com, three@example.com'] len(to) == 2 # but there will be three recipients Fixes #60
This commit is contained in:
@@ -102,7 +102,7 @@ class MailgunBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
|
||||
message = AnymailMessage(
|
||||
subject="Anymail all-options integration test",
|
||||
body="This is the text body",
|
||||
from_email="Test From <from@example.com>",
|
||||
from_email="Test From <from@example.com>, also-from@example.com",
|
||||
to=["to1@example.com", "Recipient 2 <to2@example.com>"],
|
||||
cc=["cc1@example.com", "Copy 2 <cc2@example.com>"],
|
||||
bcc=["bcc1@example.com", "Blind Copy 2 <bcc2@example.com>"],
|
||||
@@ -141,7 +141,7 @@ class MailgunBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
|
||||
'cc2@example.com', 'bcc1@example.com', 'bcc2@example.com'])
|
||||
|
||||
headers = event["message"]["headers"]
|
||||
self.assertEqual(headers["from"], "Test From <from@example.com>")
|
||||
self.assertEqual(headers["from"], "Test From <from@example.com>, also-from@example.com")
|
||||
self.assertEqual(headers["to"], "to1@example.com, Recipient 2 <to2@example.com>")
|
||||
self.assertEqual(headers["subject"], "Anymail all-options integration test")
|
||||
|
||||
@@ -156,13 +156,15 @@ class MailgunBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
|
||||
# (We could try fetching the message from event["storage"]["url"]
|
||||
# to verify content and other headers.)
|
||||
|
||||
def test_invalid_from(self):
|
||||
self.message.from_email = 'webmaster'
|
||||
with self.assertRaises(AnymailAPIError) as cm:
|
||||
self.message.send()
|
||||
err = cm.exception
|
||||
self.assertEqual(err.status_code, 400)
|
||||
self.assertIn("'from' parameter is not a valid address", str(err))
|
||||
# As of Anymail 0.10, this test is no longer possible, because
|
||||
# Anymail now raises AnymailInvalidAddress without even calling Mailgun
|
||||
# def test_invalid_from(self):
|
||||
# self.message.from_email = 'webmaster'
|
||||
# with self.assertRaises(AnymailAPIError) as cm:
|
||||
# self.message.send()
|
||||
# err = cm.exception
|
||||
# self.assertEqual(err.status_code, 400)
|
||||
# self.assertIn("'from' parameter is not a valid address", str(err))
|
||||
|
||||
@override_settings(ANYMAIL={'MAILGUN_API_KEY': "Hey, that's not an API key",
|
||||
'MAILGUN_SENDER_DOMAIN': MAILGUN_TEST_DOMAIN,
|
||||
|
||||
Reference in New Issue
Block a user