Use generic TestBackend for base functionality tests

* Create generic TestBackend that simply collects
  send parameters
* Change BackendSettingsTests to TestBackend,
  and add some missing cases
* Add UnsupportedFeatureTests
* Replace repetitive per-backend SEND_DEFAULTS
  test cases with single (and more comprehensive)
  SendDefaultsTests
This commit is contained in:
medmunds
2016-05-12 17:18:48 -07:00
parent a0b92bee7a
commit c60790fb52
6 changed files with 313 additions and 244 deletions

121
anymail/backends/test.py Normal file
View File

@@ -0,0 +1,121 @@
from anymail.exceptions import AnymailAPIError
from anymail.message import AnymailRecipientStatus
from .base import AnymailBaseBackend, BasePayload
from ..utils import get_anymail_setting
class TestBackend(AnymailBaseBackend):
"""
Anymail backend that doesn't do anything.
Used for testing Anymail common backend functionality.
"""
def __init__(self, *args, **kwargs):
# Init options from Django settings
esp_name = self.esp_name
self.sample_setting = get_anymail_setting('sample_setting', esp_name=esp_name,
kwargs=kwargs, allow_bare=True)
self.recorded_send_params = get_anymail_setting('recorded_send_params', default=[],
esp_name=esp_name, kwargs=kwargs)
super(TestBackend, self).__init__(*args, **kwargs)
def build_message_payload(self, message, defaults):
return TestPayload(backend=self, message=message, defaults=defaults)
def post_to_esp(self, payload, message):
# Keep track of the send params (for test-case access)
self.recorded_send_params.append(payload.params)
try:
# Tests can supply their own message.test_response:
response = message.test_response
if isinstance(response, AnymailAPIError):
raise response
except AttributeError:
# Default is to return 'sent' for each recipient
status = AnymailRecipientStatus(message_id=1, status='sent')
response = {
'recipient_status': {email: status for email in payload.recipient_emails}
}
return response
def parse_recipient_status(self, response, payload, message):
try:
return response['recipient_status']
except KeyError:
raise AnymailAPIError('Unparsable test response')
class TestPayload(BasePayload):
# For test purposes, just keep a dict of the params we've received.
# (This approach is also useful for native API backends -- think of
# payload.params as collecting kwargs for esp_native_api.send().)
def init_payload(self):
self.params = {}
self.recipient_emails = []
def set_from_email(self, email):
self.params['from'] = email
def set_to(self, emails):
self.params['to'] = emails
self.recipient_emails += [email.email for email in emails]
def set_cc(self, emails):
self.params['cc'] = emails
self.recipient_emails += [email.email for email in emails]
def set_bcc(self, emails):
self.params['bcc'] = emails
self.recipient_emails += [email.email for email in emails]
def set_subject(self, subject):
self.params['subject'] = subject
def set_reply_to(self, emails):
self.params['reply_to'] = emails
def set_extra_headers(self, headers):
self.params['extra_headers'] = headers
def set_text_body(self, body):
self.params['text_body'] = body
def set_html_body(self, body):
self.params['html_body'] = body
def add_alternative(self, content, mimetype):
self.unsupported_feature("alternative part with type '%s'" % mimetype)
def add_attachment(self, attachment):
self.params.setdefault('attachments', []).append(attachment)
def set_metadata(self, metadata):
self.params['metadata'] = metadata
def set_send_at(self, send_at):
self.params['send_at'] = send_at
def set_tags(self, tags):
self.params['tags'] = tags
def set_track_clicks(self, track_clicks):
self.params['track_clicks'] = track_clicks
def set_track_opens(self, track_opens):
self.params['track_opens'] = track_opens
def set_template_id(self, template_id):
self.params['template_id'] = template_id
def set_merge_data(self, merge_data):
self.params['merge_data'] = merge_data
def set_merge_global_data(self, merge_global_data):
self.params['merge_global_data'] = merge_global_data
def set_esp_extra(self, extra):
# Merge extra into params
self.params.update(extra)

View File

@@ -1,35 +1,208 @@
from django.core.mail import get_connection from datetime import datetime
from django.core.exceptions import ImproperlyConfigured
from django.core.mail import get_connection, send_mail
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils.timezone import utc
from anymail.exceptions import AnymailConfigurationError, AnymailUnsupportedFeature
from anymail.message import AnymailMessage
from .utils import AnymailTestMixin from .utils import AnymailTestMixin
class BackendSettingsTests(SimpleTestCase, AnymailTestMixin): recorded_send_params = []
@override_settings(EMAIL_BACKEND='anymail.backends.test.TestBackend',
ANYMAIL_TEST_SAMPLE_SETTING='sample', # required TestBackend setting
ANYMAIL_TEST_RECORDED_SEND_PARAMS=recorded_send_params)
class TestBackendTestCase(SimpleTestCase, AnymailTestMixin):
"""Base TestCase using Anymail's TestBackend"""
def setUp(self):
super(TestBackendTestCase, self).setUp()
del recorded_send_params[:] # empty the list from previous tests
# Simple message useful for many tests
self.message = AnymailMessage('Subject', 'Text Body', 'from@example.com', ['to@example.com'])
@staticmethod
def get_send_params():
return recorded_send_params[-1]
@override_settings(EMAIL_BACKEND='anymail.backends.test.TestBackend') # but no ANYMAIL settings overrides
class BackendSettingsTests(SimpleTestCase, AnymailTestMixin): # (so not TestBackendTestCase)
"""Test settings initializations for Anymail EmailBackends""" """Test settings initializations for Anymail EmailBackends"""
# We should add a "GenericBackend" or something basic for testing. @override_settings(ANYMAIL={'TEST_SAMPLE_SETTING': 'setting_from_anymail_settings'})
# For now, we just access real backends directly. def test_anymail_setting(self):
"""ESP settings usually come from ANYMAIL settings dict"""
backend = get_connection()
self.assertEqual(backend.sample_setting, 'setting_from_anymail_settings')
@override_settings(ANYMAIL={'MAILGUN_API_KEY': 'api_key_from_settings'}) @override_settings(TEST_SAMPLE_SETTING='setting_from_bare_settings')
def test_bare_setting(self):
"""ESP settings are also usually allowed at root of settings file"""
backend = get_connection()
self.assertEqual(backend.sample_setting, 'setting_from_bare_settings')
@override_settings(ANYMAIL={'TEST_SAMPLE_SETTING': 'setting_from_settings'})
def test_connection_kwargs_overrides_settings(self): def test_connection_kwargs_overrides_settings(self):
connection = get_connection('anymail.backends.mailgun.MailgunBackend') """Can override settings file in get_connection"""
self.assertEqual(connection.api_key, 'api_key_from_settings') backend = get_connection()
self.assertEqual(backend.sample_setting, 'setting_from_settings')
connection = get_connection('anymail.backends.mailgun.MailgunBackend', backend = get_connection(sample_setting='setting_from_kwargs')
api_key='api_key_from_kwargs') self.assertEqual(backend.sample_setting, 'setting_from_kwargs')
self.assertEqual(connection.api_key, 'api_key_from_kwargs')
def test_missing_setting(self):
"""Settings without defaults must be provided"""
with self.assertRaises(AnymailConfigurationError) as cm:
get_connection()
self.assertIsInstance(cm.exception, ImproperlyConfigured) # Django consistency
errmsg = str(cm.exception)
self.assertRegex(errmsg, r'\bTEST_SAMPLE_SETTING\b')
self.assertRegex(errmsg, r'\bANYMAIL_TEST_SAMPLE_SETTING\b')
@override_settings(ANYMAIL={'SENDGRID_USERNAME': 'username_from_settings', @override_settings(ANYMAIL={'SENDGRID_USERNAME': 'username_from_settings',
'SENDGRID_PASSWORD': 'password_from_settings'}) 'SENDGRID_PASSWORD': 'password_from_settings'})
def test_username_password_kwargs_overrides(self): def test_username_password_kwargs_overrides(self):
# Additional checks for username and password, which are special-cased """Overrides for 'username' and 'password' should work like other overrides"""
# because of Django core mail function defaults. # These are special-cased because of default args in Django core mail functions.
connection = get_connection('anymail.backends.sendgrid.SendGridBackend') # (Use the SendGrid backend, which has settings named 'username' and 'password'.)
self.assertEqual(connection.username, 'username_from_settings') backend = get_connection('anymail.backends.sendgrid.SendGridBackend')
self.assertEqual(connection.password, 'password_from_settings') self.assertEqual(backend.username, 'username_from_settings')
self.assertEqual(backend.password, 'password_from_settings')
connection = get_connection('anymail.backends.sendgrid.SendGridBackend', backend = get_connection('anymail.backends.sendgrid.SendGridBackend',
username='username_from_kwargs', password='password_from_kwargs') username='username_from_kwargs', password='password_from_kwargs')
self.assertEqual(connection.username, 'username_from_kwargs') self.assertEqual(backend.username, 'username_from_kwargs')
self.assertEqual(connection.password, 'password_from_kwargs') self.assertEqual(backend.password, 'password_from_kwargs')
class UnsupportedFeatureTests(TestBackendTestCase):
"""Tests mail features not supported by backend are handled properly"""
def test_unsupported_feature(self):
"""Unsupported features raise AnymailUnsupportedFeature"""
# TestBackend doesn't support non-HTML alternative parts
self.message.attach_alternative(b'FAKE_MP3_DATA', 'audio/mpeg')
with self.assertRaises(AnymailUnsupportedFeature):
self.message.send()
@override_settings(ANYMAIL={
'IGNORE_UNSUPPORTED_FEATURES': True
})
def test_ignore_unsupported_features(self):
"""Setting prevents exception"""
self.message.attach_alternative(b'FAKE_MP3_DATA', 'audio/mpeg')
self.message.send() # should not raise exception
class SendDefaultsTests(TestBackendTestCase):
"""Tests backend support for global SEND_DEFAULTS and <ESP>_SEND_DEFAULTS"""
@override_settings(ANYMAIL={
'SEND_DEFAULTS': {
# This isn't an exhaustive list of Anymail message attrs; just one of each type
'metadata': {'global': 'globalvalue'},
'send_at': datetime(2016, 5, 12, 4, 17, 0, tzinfo=utc),
'tags': ['globaltag'],
'template_id': 'my-template',
'track_clicks': True,
'esp_extra': {'globalextra': 'globalsetting'},
}
})
def test_send_defaults(self):
"""Test that (non-esp-specific) send defaults are applied"""
self.message.send()
params = self.get_send_params()
# All these values came from ANYMAIL_SEND_DEFAULTS:
self.assertEqual(params['metadata'], {'global': 'globalvalue'})
self.assertEqual(params['send_at'], datetime(2016, 5, 12, 4, 17, 0, tzinfo=utc))
self.assertEqual(params['tags'], ['globaltag'])
self.assertEqual(params['template_id'], 'my-template')
self.assertEqual(params['track_clicks'], True)
self.assertEqual(params['globalextra'], 'globalsetting') # TestBackend merges esp_extra into params
@override_settings(ANYMAIL={
'TEST_SEND_DEFAULTS': { # "TEST" is the name of the TestBackend's ESP
'metadata': {'global': 'espvalue'},
'tags': ['esptag'],
'track_opens': False,
'esp_extra': {'globalextra': 'espsetting'},
}
})
def test_esp_send_defaults(self):
"""Test that esp-specific send defaults are applied"""
self.message.send()
params = self.get_send_params()
self.assertEqual(params['metadata'], {'global': 'espvalue'})
self.assertEqual(params['tags'], ['esptag'])
self.assertEqual(params['track_opens'], False)
self.assertEqual(params['globalextra'], 'espsetting') # TestBackend merges esp_extra into params
@override_settings(ANYMAIL={
'SEND_DEFAULTS': {
'metadata': {'global': 'globalvalue', 'other': 'othervalue'},
'tags': ['globaltag'],
'track_clicks': True,
'track_opens': False,
'esp_extra': {'globalextra': 'globalsetting'},
}
})
def test_send_defaults_combine_with_message(self):
"""Individual message settings are *merged into* the global send defaults"""
self.message.metadata = {'message': 'messagevalue', 'other': 'override'}
self.message.tags = ['messagetag']
self.message.track_clicks = False
self.message.esp_extra = {'messageextra': 'messagesetting'}
self.message.send()
params = self.get_send_params()
self.assertEqual(params['metadata'], { # metadata merged
'global': 'globalvalue', # global default preserved
'message': 'messagevalue', # message setting added
'other': 'override'}) # message setting overrides global default
self.assertEqual(params['tags'], ['globaltag', 'messagetag']) # tags concatenated
self.assertEqual(params['track_clicks'], False) # message overrides
self.assertEqual(params['track_opens'], False) # (no message setting)
self.assertEqual(params['globalextra'], 'globalsetting')
self.assertEqual(params['messageextra'], 'messagesetting')
# Send another message to make sure original SEND_DEFAULTS unchanged
send_mail('subject', 'body', 'from@example.com', ['to@example.com'])
params = self.get_send_params()
self.assertEqual(params['metadata'], {'global': 'globalvalue', 'other': 'othervalue'})
self.assertEqual(params['tags'], ['globaltag'])
self.assertEqual(params['track_clicks'], True)
self.assertEqual(params['track_opens'], False)
self.assertEqual(params['globalextra'], 'globalsetting')
@override_settings(ANYMAIL={
'SEND_DEFAULTS': {
# This isn't an exhaustive list of Anymail message attrs; just one of each type
'metadata': {'global': 'globalvalue'},
'tags': ['globaltag'],
'template_id': 'global-template',
'esp_extra': {'globalextra': 'globalsetting'},
},
'TEST_SEND_DEFAULTS': { # "TEST" is the name of the TestBackend's ESP
'merge_global_data': {'esp': 'espmerge'},
'metadata': {'esp': 'espvalue'},
'tags': ['esptag'],
'esp_extra': {'espextra': 'espsetting'},
}
})
def test_esp_send_defaults_override_globals(self):
"""ESP-specific send defaults override *individual* global defaults"""
self.message.send()
params = self.get_send_params()
self.assertEqual(params['merge_global_data'], {'esp': 'espmerge'}) # esp-defaults only
self.assertEqual(params['metadata'], {'esp': 'espvalue'})
self.assertEqual(params['tags'], ['esptag'])
self.assertEqual(params['template_id'], 'global-template') # global-defaults only
self.assertEqual(params['espextra'], 'espsetting')
self.assertNotIn('globalextra', params) # entire esp_extra is overriden by esp-send-defaults

View File

@@ -468,65 +468,6 @@ class MailgunBackendSessionSharingTestCase(SessionSharingTestCasesMixin, Mailgun
pass # tests are defined in the mixin pass # tests are defined in the mixin
@override_settings(ANYMAIL_SEND_DEFAULTS={
'metadata': {'global': 'globalvalue', 'other': 'othervalue'},
'tags': ['globaltag'],
'track_clicks': True,
'track_opens': True,
'esp_extra': {'o:globaloption': 'globalsetting'},
})
class MailgunBackendSendDefaultsTests(MailgunBackendMockAPITestCase):
"""Tests backend support for global SEND_DEFAULTS"""
def test_send_defaults(self):
"""Test that global send defaults are applied"""
self.message.send()
data = self.get_api_call_data()
# All these values came from ANYMAIL_SEND_DEFAULTS:
self.assertEqual(data['v:global'], 'globalvalue')
self.assertEqual(data['v:other'], 'othervalue')
self.assertEqual(data['o:tag'], ['globaltag'])
self.assertEqual(data['o:tracking-clicks'], 'yes')
self.assertEqual(data['o:tracking-opens'], 'yes')
self.assertEqual(data['o:globaloption'], 'globalsetting')
def test_merge_message_with_send_defaults(self):
"""Test that individual message settings are *merged into* the global send defaults"""
self.message.metadata = {'message': 'messagevalue', 'other': 'override'}
self.message.tags = ['messagetag']
self.message.track_clicks = False
self.message.esp_extra = {'o:messageoption': 'messagesetting'}
self.message.send()
data = self.get_api_call_data()
# All these values came from ANYMAIL_SEND_DEFAULTS + message.*:
self.assertEqual(data['v:global'], 'globalvalue')
self.assertEqual(data['v:message'], 'messagevalue') # additional metadata
self.assertEqual(data['v:other'], 'override') # override global value
self.assertEqual(data['o:tag'], ['globaltag', 'messagetag']) # tags concatenated
self.assertEqual(data['o:tracking-clicks'], 'no') # message overrides
self.assertEqual(data['o:tracking-opens'], 'yes')
self.assertEqual(data['o:globaloption'], 'globalsetting')
self.assertEqual(data['o:messageoption'], 'messagesetting') # additional esp_extra
@override_settings(ANYMAIL_MAILGUN_SEND_DEFAULTS={
'tags': ['esptag'],
'metadata': {'esp': 'espvalue'},
'track_opens': False,
})
def test_esp_send_defaults(self):
"""Test that ESP-specific send defaults override individual global defaults"""
self.message.send()
data = self.get_api_call_data()
# All these values came from ANYMAIL_SEND_DEFAULTS plus ANYMAIL_MAILGUN_SEND_DEFAULTS:
self.assertNotIn('v:global', data) # entire metadata overridden
self.assertEqual(data['v:esp'], 'espvalue')
self.assertEqual(data['o:tag'], ['esptag']) # entire tags overridden
self.assertEqual(data['o:tracking-clicks'], 'yes') # we didn't override the global track_clicks
self.assertEqual(data['o:tracking-opens'], 'no')
self.assertEqual(data['o:globaloption'], 'globalsetting') # we didn't override the global esp_extra
@override_settings(EMAIL_BACKEND="anymail.backends.mailgun.MailgunBackend") @override_settings(EMAIL_BACKEND="anymail.backends.mailgun.MailgunBackend")
class MailgunBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin): class MailgunBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
"""Test ESP backend without required settings in place""" """Test ESP backend without required settings in place"""

View File

@@ -592,62 +592,6 @@ class MandrillBackendSessionSharingTestCase(SessionSharingTestCasesMixin, Mandri
pass # tests are defined in the mixin pass # tests are defined in the mixin
@override_settings(ANYMAIL_SEND_DEFAULTS={
'metadata': {'global': 'globalvalue', 'other': 'othervalue'},
'tags': ['globaltag'],
'track_clicks': True,
'track_opens': True,
# 'esp_extra': {'globaloption': 'globalsetting'}, # Mandrill doesn't support esp_extra yet
})
class MandrillBackendSendDefaultsTests(MandrillBackendMockAPITestCase):
"""Tests backend support for global SEND_DEFAULTS"""
def test_send_defaults(self):
"""Test that global send defaults are applied"""
self.message.send()
data = self.get_api_call_json()
# All these values came from ANYMAIL_SEND_DEFAULTS:
self.assertEqual(data['message']['metadata'], {'global': 'globalvalue', 'other': 'othervalue'})
self.assertEqual(data['message']['tags'], ['globaltag'])
self.assertEqual(data['message']['track_clicks'], True)
self.assertEqual(data['message']['track_opens'], True)
# self.assertEqual(data['globaloption'], 'globalsetting')
def test_merge_message_with_send_defaults(self):
"""Test that individual message settings are *merged into* the global send defaults"""
self.message.metadata = {'message': 'messagevalue', 'other': 'override'}
self.message.tags = ['messagetag']
self.message.track_clicks = False
# self.message.esp_extra = {'messageoption': 'messagesetting'}
self.message.send()
data = self.get_api_call_json()
# All these values came from ANYMAIL_SEND_DEFAULTS + message.*:
self.assertEqual(data['message']['metadata'],
{'global': 'globalvalue', 'message': 'messagevalue', 'other': 'override'}) # merged
self.assertEqual(data['message']['tags'], ['globaltag', 'messagetag']) # tags concatenated
self.assertEqual(data['message']['track_clicks'], False) # message overrides
self.assertEqual(data['message']['track_opens'], True)
# self.assertEqual(data['globaloption'], 'globalsetting')
# self.assertEqual(data['messageoption'], 'messagesetting') # additional esp_extra
@override_settings(ANYMAIL_MANDRILL_SEND_DEFAULTS={
'tags': ['esptag'],
'metadata': {'esp': 'espvalue'},
'track_opens': False,
})
def test_esp_send_defaults(self):
"""Test that ESP-specific send defaults override individual global defaults"""
self.message.send()
data = self.get_api_call_json()
# All these values came from ANYMAIL_SEND_DEFAULTS plus ANYMAIL_MAILGUN_SEND_DEFAULTS:
self.assertEqual(data['message']['metadata'], {'esp': 'espvalue'}) # entire metadata overridden
self.assertEqual(data['message']['tags'], ['esptag']) # entire tags overridden
self.assertEqual(data['message']['track_clicks'], True) # we didn't override the global track_clicks
self.assertEqual(data['message']['track_opens'], False)
# self.assertEqual(data['globaloption'], 'globalsetting') # we didn't override the global esp_extra
@override_settings(EMAIL_BACKEND="anymail.backends.mandrill.MandrillBackend") @override_settings(EMAIL_BACKEND="anymail.backends.mandrill.MandrillBackend")
class MandrillBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin): class MandrillBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
"""Test backend without required settings""" """Test backend without required settings"""

View File

@@ -546,51 +546,6 @@ class PostmarkBackendSessionSharingTestCase(SessionSharingTestCasesMixin, Postma
pass # tests are defined in the mixin pass # tests are defined in the mixin
@override_settings(ANYMAIL_SEND_DEFAULTS={
'tags': ['globaltag'],
'track_opens': True,
'esp_extra': {'globaloption': 'globalsetting'},
})
class PostmarkBackendSendDefaultsTests(PostmarkBackendMockAPITestCase):
"""Tests backend support for global SEND_DEFAULTS"""
def test_send_defaults(self):
"""Test that global send defaults are applied"""
self.message.send()
data = self.get_api_call_json()
# All these values came from ANYMAIL_SEND_DEFAULTS:
self.assertEqual(data['Tag'], 'globaltag')
self.assertEqual(data['TrackOpens'], True)
self.assertEqual(data['globaloption'], 'globalsetting')
def test_merge_message_with_send_defaults(self):
"""Test that individual message settings are *merged into* the global send defaults"""
self.message.tags = None # can't really append (since only one tag), but can suppress it
self.message.track_opens = False
self.message.esp_extra = {'messageoption': 'messagesetting'}
self.message.send()
data = self.get_api_call_json()
# All these values came from ANYMAIL_SEND_DEFAULTS + message.*:
self.assertNotIn('Tag', data)
self.assertEqual(data['TrackOpens'], False)
self.assertEqual(data['globaloption'], 'globalsetting')
self.assertEqual(data['messageoption'], 'messagesetting') # additional esp_extra
@override_settings(ANYMAIL_POSTMARK_SEND_DEFAULTS={
'tags': ['esptag'],
'track_opens': False,
})
def test_esp_send_defaults(self):
"""Test that ESP-specific send defaults override individual global defaults"""
self.message.send()
data = self.get_api_call_json()
# All these values came from ANYMAIL_SEND_DEFAULTS plus ANYMAIL_SENDGRID_SEND_DEFAULTS:
self.assertEqual(data['Tag'], 'esptag') # entire tags overridden
self.assertEqual(data['TrackOpens'], False) # esp override
self.assertEqual(data['globaloption'], 'globalsetting') # we didn't override the global esp_extra
@override_settings(EMAIL_BACKEND="anymail.backends.postmark.PostmarkBackend") @override_settings(EMAIL_BACKEND="anymail.backends.postmark.PostmarkBackend")
class PostmarkBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin): class PostmarkBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
"""Test ESP backend without required settings in place""" """Test ESP backend without required settings in place"""

View File

@@ -597,71 +597,6 @@ class SendGridBackendSessionSharingTestCase(SessionSharingTestCasesMixin, SendGr
pass # tests are defined in the mixin pass # tests are defined in the mixin
@override_settings(ANYMAIL_SEND_DEFAULTS={
'metadata': {'global': 'globalvalue', 'other': 'othervalue'},
'tags': ['globaltag'],
'track_clicks': True,
'track_opens': True,
'esp_extra': {'globaloption': 'globalsetting'},
})
class SendGridBackendSendDefaultsTests(SendGridBackendMockAPITestCase):
"""Tests backend support for global SEND_DEFAULTS"""
def test_send_defaults(self):
"""Test that global send defaults are applied"""
self.message.send()
data = self.get_api_call_data()
smtpapi = self.get_smtpapi()
# All these values came from ANYMAIL_SEND_DEFAULTS:
smtpapi['unique_args'].pop('smtp-id', None) # remove Message-ID we added as tracking workaround
self.assertEqual(smtpapi['unique_args'], {'global': 'globalvalue', 'other': 'othervalue'})
self.assertEqual(smtpapi['category'], ['globaltag'])
self.assertEqual(smtpapi['filters']['clicktrack']['settings']['enable'], 1)
self.assertEqual(smtpapi['filters']['opentrack']['settings']['enable'], 1)
self.assertEqual(data['globaloption'], 'globalsetting')
def test_merge_message_with_send_defaults(self):
"""Test that individual message settings are *merged into* the global send defaults"""
self.message.metadata = {'message': 'messagevalue', 'other': 'override'}
self.message.tags = ['messagetag']
self.message.track_clicks = False
self.message.esp_extra = {'messageoption': 'messagesetting'}
self.message.send()
data = self.get_api_call_data()
smtpapi = self.get_smtpapi()
# All these values came from ANYMAIL_SEND_DEFAULTS + message.*:
smtpapi['unique_args'].pop('smtp-id', None) # remove Message-ID we added as tracking workaround
self.assertEqual(smtpapi['unique_args'], {
'global': 'globalvalue',
'message': 'messagevalue', # additional metadata
'other': 'override', # override global value
})
self.assertCountEqual(smtpapi['category'], ['globaltag', 'messagetag']) # tags concatenated
self.assertEqual(smtpapi['filters']['clicktrack']['settings']['enable'], 0) # message overrides
self.assertEqual(smtpapi['filters']['opentrack']['settings']['enable'], 1)
self.assertEqual(data['globaloption'], 'globalsetting')
self.assertEqual(data['messageoption'], 'messagesetting') # additional esp_extra
@override_settings(ANYMAIL_SENDGRID_SEND_DEFAULTS={
'tags': ['esptag'],
'metadata': {'esp': 'espvalue'},
'track_opens': False,
})
def test_esp_send_defaults(self):
"""Test that ESP-specific send defaults override individual global defaults"""
self.message.send()
data = self.get_api_call_data()
smtpapi = self.get_smtpapi()
# All these values came from ANYMAIL_SEND_DEFAULTS plus ANYMAIL_SENDGRID_SEND_DEFAULTS:
smtpapi['unique_args'].pop('smtp-id', None) # remove Message-ID we added as tracking workaround
self.assertEqual(smtpapi['unique_args'], {'esp': 'espvalue'}) # entire metadata overridden
self.assertCountEqual(smtpapi['category'], ['esptag']) # entire tags overridden
self.assertEqual(smtpapi['filters']['clicktrack']['settings']['enable'], 1) # no override
self.assertEqual(smtpapi['filters']['opentrack']['settings']['enable'], 0) # esp override
self.assertEqual(data['globaloption'], 'globalsetting') # we didn't override the global esp_extra
@override_settings(EMAIL_BACKEND="anymail.backends.sendgrid.SendGridBackend") @override_settings(EMAIL_BACKEND="anymail.backends.sendgrid.SendGridBackend")
class SendGridBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin): class SendGridBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
"""Test ESP backend without required settings in place""" """Test ESP backend without required settings in place"""