Allow Mandrill specific options to be set globally in the settings file.

This is useful to set options such as tracking_domain etc per instance when using subaccounts with Mandrill.
This commit is contained in:
William Hector
2015-07-12 01:19:59 +01:00
parent bac85511b5
commit 883b23362c
3 changed files with 140 additions and 0 deletions

View File

@@ -63,6 +63,12 @@ class DjrillBackend(BaseEmailBackend):
self.api_key = getattr(settings, "MANDRILL_API_KEY", None)
self.api_url = MANDRILL_API_URL
self.session = None
self.global_settings = {}
for setting_key in getattr(settings, "MANDRILL_SETTINGS", {}):
if not isinstance(settings.MANDRILL_SETTINGS, dict):
raise ImproperlyConfigured("MANDRILL_SETTINGS must be a dict "
"in the settings.py file.")
self.global_settings[setting_key] = settings.MANDRILL_SETTINGS[setting_key]
self.subaccount = getattr(settings, "MANDRILL_SUBACCOUNT", None)
@@ -233,6 +239,8 @@ class DjrillBackend(BaseEmailBackend):
'async', 'ip_pool'
]
for attr in mandrill_attrs:
if attr in self.global_settings:
api_params[attr] = self.global_settings[attr]
if hasattr(message, attr):
api_params[attr] = getattr(message, attr)
@@ -270,11 +278,16 @@ class DjrillBackend(BaseEmailBackend):
msg_dict['subaccount'] = self.subaccount
for attr in mandrill_attrs:
if attr in self.global_settings:
msg_dict[attr] = self.global_settings[attr]
if hasattr(message, attr):
msg_dict[attr] = getattr(message, attr)
# Allow simple python dicts in place of Mandrill
# [{name:name, value:value},...] arrays...
if 'global_merge_vars' in self.global_settings:
msg_dict['global_merge_vars'] = self._expand_merge_vars(
self.global_settings['global_merge_vars'])
if hasattr(message, 'global_merge_vars'):
msg_dict['global_merge_vars'] = \
self._expand_merge_vars(message.global_merge_vars)

View File

@@ -540,6 +540,123 @@ class DjrillMandrillFeatureTests(DjrillBackendMockAPITestCase):
self.message.send()
@override_settings(MANDRILL_SETTINGS={
'from_name': 'Djrill Test',
'important': True,
'track_opens': True,
'track_clicks': True,
'auto_text': True,
'auto_html': True,
'inline_css': True,
'url_strip_qs': True,
'tags': ['djrill'],
'preserve_recipients': True,
'view_content_link': True,
'tracking_domain': 'example.com',
'signing_domain': 'example.com',
'return_path_domain': 'example.com',
'google_analytics_domains': ['example.com/test'],
'google_analytics_campaign': ['UA-00000000-1'],
'metadata': ['djrill'],
'merge_language': 'mailchimp',
'global_merge_vars': {'TEST': 'djrill'},
'async': False,
'ip_pool': 'Pool1',
'invalid': 'invalid',
})
class DjrillMandrillGlobalFeatureTests(DjrillBackendMockAPITestCase):
"""Test Djrill backend support for global ovveride Mandrill-specific features"""
def setUp(self):
super(DjrillMandrillGlobalFeatureTests, self).setUp()
self.message = mail.EmailMessage('Subject', 'Text Body',
'from@example.com', ['to@example.com'])
def test_global_options(self):
"""Test that any global settings get passed through
"""
self.message.send()
self.assert_mandrill_called("/messages/send.json")
data = self.get_api_call_data()
self.assertEqual(data['message']['from_name'], 'Djrill Test')
self.assertTrue(data['message']['important'], True)
self.assertTrue(data['message']['track_opens'], True)
self.assertTrue(data['message']['track_clicks'], True)
self.assertTrue(data['message']['auto_text'], True)
self.assertTrue(data['message']['auto_html'], True)
self.assertTrue(data['message']['inline_css'], True)
self.assertTrue(data['message']['url_strip_qs'], True)
self.assertEqual(data['message']['tags'], ['djrill'])
self.assertTrue(data['message']['preserve_recipients'], True)
self.assertTrue(data['message']['view_content_link'], True)
self.assertEqual(data['message']['tracking_domain'], 'example.com')
self.assertEqual(data['message']['signing_domain'], 'example.com')
self.assertEqual(data['message']['return_path_domain'], 'example.com')
self.assertEqual(data['message']['google_analytics_domains'], ['example.com/test'])
self.assertEqual(data['message']['google_analytics_campaign'], ['UA-00000000-1'])
self.assertEqual(data['message']['metadata'], ['djrill'])
self.assertEqual(data['message']['merge_language'], 'mailchimp')
self.assertEqual(data['message']['global_merge_vars'],
[{'name': 'TEST', 'content': 'djrill'}])
self.assertFalse('merge_vars' in data['message'])
self.assertFalse('recipient_metadata' in data['message'])
# Options at top level of api params (not in message dict):
self.assertFalse('send_at' in data)
self.assertEqual(data['async'], False)
self.assertEqual(data['ip_pool'], 'Pool1')
# Option that shouldn't be added
self.assertFalse('invalid' in data['message'])
def test_global_options_override(self):
"""Test that manually settings options overrides global settings
"""
self.message.important = True
self.message.auto_text = True
self.message.auto_html = True
self.message.inline_css = True
self.message.preserve_recipients = True
self.message.view_content_link = False
self.message.tracking_domain = "click.example.com"
self.message.signing_domain = "example.com"
self.message.return_path_domain = "support.example.com"
self.message.subaccount = "marketing-dept"
self.message.async = True
self.message.ip_pool = "Bulk Pool"
self.message.send()
data = self.get_api_call_data()
self.assertEqual(data['message']['important'], True)
self.assertEqual(data['message']['auto_text'], True)
self.assertEqual(data['message']['auto_html'], True)
self.assertEqual(data['message']['inline_css'], True)
self.assertEqual(data['message']['preserve_recipients'], True)
self.assertEqual(data['message']['view_content_link'], False)
self.assertEqual(data['message']['tracking_domain'], "click.example.com")
self.assertEqual(data['message']['signing_domain'], "example.com")
self.assertEqual(data['message']['return_path_domain'], "support.example.com")
self.assertEqual(data['message']['subaccount'], "marketing-dept")
self.assertEqual(data['async'], True)
self.assertEqual(data['ip_pool'], "Bulk Pool")
def test_global_options_override_tracking(self):
"""Test that manually settings options overrides global settings
"""
self.message.track_opens = False
self.message.track_clicks = False
self.message.url_strip_qs = False
self.message.send()
data = self.get_api_call_data()
self.assertEqual(data['message']['track_opens'], False)
self.assertEqual(data['message']['track_clicks'], False)
self.assertEqual(data['message']['url_strip_qs'], False)
def test_global_merge(self):
self.message.global_merge_vars = {'GREETING': "Hello"}
self.message.send()
data = self.get_api_call_data()
self.assertEqual(data['message']['global_merge_vars'],
[{'name': "GREETING", 'content': "Hello"}])
@override_settings(EMAIL_BACKEND="djrill.mail.backends.djrill.DjrillBackend")
class DjrillImproperlyConfiguredTests(TestCase):
"""Test Djrill backend without Djrill-specific settings in place"""

View File

@@ -103,11 +103,21 @@ Some notes and limitations:
Mandrill-Specific Options
-------------------------
.. setting:: MANDRILL_SETTINGS
Most of the options from the Mandrill
`messages/send API <https://mandrillapp.com/api/docs/messages.html#method=send>`_
`message` struct can be set directly on an :class:`~django.core.mail.EmailMessage`
(or subclass) object:
Most of these options can be globally set in your project's :file:`settings.py`
using :setting:`MANDRILL_SETTINGS`. For Example::
MANDRILL_SETTINGS = {
'tracking_domain': 'example.com',
'track_opens': True,
}
.. These attributes are in the same order as they appear in the Mandrill API docs...
.. attribute:: important