Feature: Add envelope_sender

New EmailMessage attribute `envelope_sender` controls ESP's sender,
sending domain, or return path where supported:

* Mailgun: overrides SENDER_DOMAIN on individual message
  (domain portion only)
* Mailjet: becomes `Sender` API param
* Mandrill: becomes `return_path_domain` API param
  (domain portion only)
* SparkPost: becomes `return_path` API param
* Other ESPs: not believed to be supported

Also support undocumented Django SMTP backend behavior, where envelope
sender is given by `message.from_email` when
`message.extra_headers["From"]` is set. Fixes #91.
This commit is contained in:
medmunds
2018-02-26 18:42:19 -08:00
parent bd9d92f5a0
commit 07fbeac6bd
27 changed files with 246 additions and 28 deletions

View File

@@ -351,3 +351,23 @@ class SpecialHeaderTests(TestBackendTestCase):
params = self.get_send_params()
self.assertEqual(flatten_emails(params['reply_to']), ["header@example.com"])
self.assertEqual(params['extra_headers'], {"X-Extra": "extra"}) # Reply-To no longer there
def test_envelope_sender(self):
"""Django treats message.from_email as envelope-sender if messsage.extra_headers['From'] is set"""
# Using Anymail's envelope_sender extension
self.message.from_email = "Header From <header@example.com>"
self.message.envelope_sender = "Envelope From <envelope@bounces.example.com>" # Anymail extension
self.message.send()
params = self.get_send_params()
self.assertEqual(params['from'].address, "Header From <header@example.com>")
self.assertEqual(params['envelope_sender'], "envelope@bounces.example.com")
# Using Django's undocumented message.extra_headers['From'] extension
# (see https://code.djangoproject.com/ticket/9214)
self.message.from_email = "Envelope From <envelope@bounces.example.com>"
self.message.extra_headers = {"From": "Header From <header@example.com>"}
self.message.send()
params = self.get_send_params()
self.assertEqual(params['from'].address, "Header From <header@example.com>")
self.assertEqual(params['envelope_sender'], "envelope@bounces.example.com")
self.assertNotIn("From", params.get('extra_headers', {})) # From was removed from extra-headers