mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 11:51:05 -05:00
Allow html from any EmailMultiAlternatives (not just DjrillMessage)
Includes type-checking on alternative message part, and switches to ValueError (rather than ImproperlyConfigured) for unacceptable alternatives. [Also fixes bug where fail_silently=True wasn't respected.] Cherry-picked from: medmunds/Djrill@faf53a1a0 (and parts of medmunds/Djrill@62d48c5f)
This commit is contained in:
@@ -26,7 +26,7 @@ class DjrillBackend(BaseEmailBackend):
|
||||
Mandrill API Email Backend
|
||||
"""
|
||||
|
||||
def __init__(self, fail_silently=False, **kwargs):
|
||||
def __init__(self, **kwargs):
|
||||
"""
|
||||
Set the API key, API url and set the action url.
|
||||
"""
|
||||
@@ -71,8 +71,13 @@ class DjrillBackend(BaseEmailBackend):
|
||||
if getattr(message, "alternative_subtype", None):
|
||||
if message.alternative_subtype == "mandrill":
|
||||
self._build_advanced_message_dict(message)
|
||||
if message.alternatives:
|
||||
self._add_alternatives(message)
|
||||
try:
|
||||
if getattr(message, 'alternatives', None):
|
||||
self._add_alternatives(message)
|
||||
except ValueError:
|
||||
if not self.fail_silently:
|
||||
raise
|
||||
return False
|
||||
|
||||
djrill_it = requests.post(self.api_action, data=json.dumps({
|
||||
"key": self.api_key,
|
||||
@@ -121,23 +126,29 @@ class DjrillBackend(BaseEmailBackend):
|
||||
"from_name": message.from_name,
|
||||
"tags": message.tags,
|
||||
"track_opens": message.track_opens,
|
||||
"track_clicks": message.track_clicks
|
||||
})
|
||||
|
||||
|
||||
def _add_alternatives(self, message):
|
||||
"""
|
||||
There can be only one! ... alternative attachment.
|
||||
There can be only one! ... alternative attachment, and it must be text/html.
|
||||
|
||||
Since mandrill does not accept image attachments or anything other
|
||||
than HTML, the assumption is the only thing you are attaching is
|
||||
the HTML output for your email.
|
||||
"""
|
||||
if len(message.alternatives) > 1:
|
||||
raise ImproperlyConfigured(
|
||||
"Mandrill only accepts plain text and html emails. Please "
|
||||
"check the alternatives you have attached to your message.")
|
||||
raise ValueError(
|
||||
"Too many alternatives attached to the message. "
|
||||
"Mandrill only accepts plain text and html emails.")
|
||||
|
||||
(content, mimetype) = message.alternatives[0]
|
||||
if mimetype != 'text/html':
|
||||
raise ValueError("Invalid alternative mimetype '%s'. "
|
||||
"Mandrill only accepts plain text and html emails."
|
||||
% mimetype)
|
||||
|
||||
self.msg_dict.update({
|
||||
"html": message.alternatives[0][0],
|
||||
"track_clicks": message.track_clicks
|
||||
"html": message.alternatives[0][0]
|
||||
})
|
||||
|
||||
@@ -92,6 +92,42 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase):
|
||||
self.assertEqual(data['message']['to'][4]['email'], "bcc1@example.com")
|
||||
self.assertEqual(data['message']['to'][5]['email'], "bcc2@example.com")
|
||||
|
||||
def test_html_message(self):
|
||||
text_content = 'This is an important message.'
|
||||
html_content = '<p>This is an <strong>important</strong> message.</p>'
|
||||
email = mail.EmailMultiAlternatives('Subject', text_content,
|
||||
'from@example.com', ['to@example.com'])
|
||||
email.attach_alternative(html_content, "text/html")
|
||||
email.send()
|
||||
data = self.get_api_call_data()
|
||||
self.assertEqual(data['message']['text'], text_content)
|
||||
self.assertEqual(data['message']['html'], html_content)
|
||||
|
||||
def test_alternative_errors(self):
|
||||
# Multiple alternatives not allowed
|
||||
email = mail.EmailMultiAlternatives('Subject', 'Body',
|
||||
'from@example.com', ['to@example.com'])
|
||||
email.attach_alternative("<p>First html is OK</p>", "text/html")
|
||||
email.attach_alternative("<p>But not second html</p>", "text/html")
|
||||
with self.assertRaises(ValueError):
|
||||
email.send()
|
||||
|
||||
# Only html alternatives allowed
|
||||
email = mail.EmailMultiAlternatives('Subject', 'Body',
|
||||
'from@example.com', ['to@example.com'])
|
||||
email.attach_alternative("{'not': 'allowed'}", "application/json")
|
||||
with self.assertRaises(ValueError):
|
||||
email.send()
|
||||
|
||||
# Make sure fail_silently is respected
|
||||
email = mail.EmailMultiAlternatives('Subject', 'Body',
|
||||
'from@example.com', ['to@example.com'])
|
||||
email.attach_alternative("{'not': 'allowed'}", "application/json")
|
||||
sent = email.send(fail_silently=True)
|
||||
self.assertFalse(self.mock_post.called,
|
||||
msg="Mandrill API should not be called when send fails silently")
|
||||
self.assertEqual(sent, 0)
|
||||
|
||||
|
||||
class DjrillMessageTests(TestCase):
|
||||
def setUp(self):
|
||||
|
||||
Reference in New Issue
Block a user