diff --git a/djrill/mail/backends/djrill.py b/djrill/mail/backends/djrill.py index a2aac59..66969b3 100644 --- a/djrill/mail/backends/djrill.py +++ b/djrill/mail/backends/djrill.py @@ -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) diff --git a/djrill/tests/test_mandrill_send.py b/djrill/tests/test_mandrill_send.py index 43e9cf4..f547010 100644 --- a/djrill/tests/test_mandrill_send.py +++ b/djrill/tests/test_mandrill_send.py @@ -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""" diff --git a/docs/usage/sending_mail.rst b/docs/usage/sending_mail.rst index 0104082..a7e51c0 100644 --- a/docs/usage/sending_mail.rst +++ b/docs/usage/sending_mail.rst @@ -103,11 +103,21 @@ Some notes and limitations: Mandrill-Specific Options ------------------------- +.. setting:: MANDRILL_SETTINGS + Most of the options from the Mandrill `messages/send API `_ `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