Rename EmailBackends for Django consistency

* **Future breaking change:**
  Rename all Anymail backends to just `EmailBackend`,
  matching Django's naming convention.
  (E.g., switch to "anymail.backends.mailgun.EmailBackend"
  rather than "anymail.backends.mailgun.MailgunBackend".)

  The old names still work, but will issue a DeprecationWarning
  and will be removed in some future release.

  (Apologies for this change; the old naming convention was
  a holdover from Djrill, and I wanted consistency with
  other Django EmailBackends before hitting 1.0.)

Fixes #49.
This commit is contained in:
medmunds
2017-01-20 15:47:37 -08:00
parent bff01b440a
commit 79288603fb
29 changed files with 190 additions and 71 deletions

View File

@@ -19,11 +19,11 @@ from .utils import AnymailTestMixin
recorded_send_params = []
@override_settings(EMAIL_BACKEND='anymail.backends.test.TestBackend',
ANYMAIL_TEST_SAMPLE_SETTING='sample', # required TestBackend setting
@override_settings(EMAIL_BACKEND='anymail.backends.test.EmailBackend',
ANYMAIL_TEST_SAMPLE_SETTING='sample', # required test EmailBackend setting
ANYMAIL_TEST_RECORDED_SEND_PARAMS=recorded_send_params)
class TestBackendTestCase(SimpleTestCase, AnymailTestMixin):
"""Base TestCase using Anymail's TestBackend"""
"""Base TestCase using Anymail's Test EmailBackend"""
def setUp(self):
super(TestBackendTestCase, self).setUp()
@@ -42,8 +42,8 @@ class TestBackendTestCase(SimpleTestCase, AnymailTestMixin):
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)
@override_settings(EMAIL_BACKEND='anymail.backends.test.EmailBackend') # but no ANYMAIL settings overrides
class BackendSettingsTests(SimpleTestCase, AnymailTestMixin): # (so not TestBackendTestCase)
"""Test settings initializations for Anymail EmailBackends"""
@override_settings(ANYMAIL={'TEST_SAMPLE_SETTING': 'setting_from_anymail_settings'})
@@ -97,7 +97,7 @@ class UnsupportedFeatureTests(TestBackendTestCase):
def test_unsupported_feature(self):
"""Unsupported features raise AnymailUnsupportedFeature"""
# TestBackend doesn't support non-HTML alternative parts
# Test EmailBackend doesn't support non-HTML alternative parts
self.message.attach_alternative(b'FAKE_MP3_DATA', 'audio/mpeg')
with self.assertRaises(AnymailUnsupportedFeature):
self.message.send()
@@ -135,10 +135,10 @@ class SendDefaultsTests(TestBackendTestCase):
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
self.assertEqual(params['globalextra'], 'globalsetting') # Test EmailBackend merges esp_extra into params
@override_settings(ANYMAIL={
'TEST_SEND_DEFAULTS': { # "TEST" is the name of the TestBackend's ESP
'TEST_SEND_DEFAULTS': { # "TEST" is the name of the Test EmailBackend's ESP
'metadata': {'global': 'espvalue'},
'tags': ['esptag'],
'track_opens': False,
@@ -152,7 +152,7 @@ class SendDefaultsTests(TestBackendTestCase):
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
self.assertEqual(params['globalextra'], 'espsetting') # Test EmailBackend merges esp_extra into params
@override_settings(ANYMAIL={
'SEND_DEFAULTS': {
@@ -199,7 +199,7 @@ class SendDefaultsTests(TestBackendTestCase):
'template_id': 'global-template',
'esp_extra': {'globalextra': 'globalsetting'},
},
'TEST_SEND_DEFAULTS': { # "TEST" is the name of the TestBackend's ESP
'TEST_SEND_DEFAULTS': { # "TEST" is the name of the Test EmailBackend's ESP
'merge_global_data': {'esp': 'espmerge'},
'metadata': {'esp': 'espvalue'},
'tags': ['esptag'],

View File

@@ -17,7 +17,7 @@ from .mock_requests_backend import RequestsBackendMockAPITestCase, SessionSharin
from .utils import sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAME, AnymailTestMixin
@override_settings(EMAIL_BACKEND='anymail.backends.mailgun.MailgunBackend',
@override_settings(EMAIL_BACKEND='anymail.backends.mailgun.EmailBackend',
ANYMAIL={'MAILGUN_API_KEY': 'test_api_key'})
class MailgunBackendMockAPITestCase(RequestsBackendMockAPITestCase):
DEFAULT_RAW_RESPONSE = b"""{
@@ -483,7 +483,7 @@ class MailgunBackendSessionSharingTestCase(SessionSharingTestCasesMixin, Mailgun
pass # tests are defined in the mixin
@override_settings(EMAIL_BACKEND="anymail.backends.mailgun.MailgunBackend")
@override_settings(EMAIL_BACKEND="anymail.backends.mailgun.EmailBackend")
class MailgunBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
"""Test ESP backend without required settings in place"""
@@ -494,3 +494,13 @@ class MailgunBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
# Make sure the error mentions MAILGUN_API_KEY and ANYMAIL_MAILGUN_API_KEY
self.assertRegex(errmsg, r'\bMAILGUN_API_KEY\b')
self.assertRegex(errmsg, r'\bANYMAIL_MAILGUN_API_KEY\b')
class MailgunBackendDeprecationTests(MailgunBackendMockAPITestCase):
@override_settings(EMAIL_BACKEND='anymail.backends.mailgun.MailgunBackend')
def test_renamed_backend_warning(self):
# ...mailgun.MailgunBackend --> ...mailgun.EmailBackend
with self.assertWarnsRegex(DeprecationWarning,
r'anymail\.backends\.mailgun\.EmailBackend'):
self.message.send()

View File

@@ -24,7 +24,7 @@ MAILGUN_TEST_DOMAIN = os.getenv('MAILGUN_TEST_DOMAIN')
@override_settings(ANYMAIL={'MAILGUN_API_KEY': MAILGUN_TEST_API_KEY,
'MAILGUN_SENDER_DOMAIN': MAILGUN_TEST_DOMAIN,
'MAILGUN_SEND_DEFAULTS': {'esp_extra': {'o:testmode': 'yes'}}},
EMAIL_BACKEND="anymail.backends.mailgun.MailgunBackend")
EMAIL_BACKEND="anymail.backends.mailgun.EmailBackend")
class MailgunBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
"""Mailgun API integration tests

View File

@@ -19,7 +19,7 @@ from .mock_requests_backend import RequestsBackendMockAPITestCase, SessionSharin
from .utils import sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAME, AnymailTestMixin, decode_att
@override_settings(EMAIL_BACKEND='anymail.backends.mandrill.MandrillBackend',
@override_settings(EMAIL_BACKEND='anymail.backends.mandrill.EmailBackend',
ANYMAIL={'MANDRILL_API_KEY': 'test_api_key'})
class MandrillBackendMockAPITestCase(RequestsBackendMockAPITestCase):
DEFAULT_RAW_RESPONSE = b"""[{
@@ -588,7 +588,7 @@ class MandrillBackendSessionSharingTestCase(SessionSharingTestCasesMixin, Mandri
pass # tests are defined in the mixin
@override_settings(EMAIL_BACKEND="anymail.backends.mandrill.MandrillBackend")
@override_settings(EMAIL_BACKEND="anymail.backends.mandrill.EmailBackend")
class MandrillBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
"""Test backend without required settings"""
@@ -598,3 +598,12 @@ class MandrillBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin)
errmsg = str(cm.exception)
self.assertRegex(errmsg, r'\bMANDRILL_API_KEY\b')
self.assertRegex(errmsg, r'\bANYMAIL_MANDRILL_API_KEY\b')
class MandrillBackendDeprecationTests(MandrillBackendMockAPITestCase):
@override_settings(EMAIL_BACKEND='anymail.backends.mandrill.MandrillBackend')
def test_renamed_backend_warning(self):
# ...mandrill.MandrillBackend --> ...mandrill.EmailBackend
with self.assertWarnsRegex(DeprecationWarning,
r'anymail\.backends\.mandrill\.EmailBackend'):
self.message.send()

View File

@@ -17,7 +17,7 @@ MANDRILL_TEST_API_KEY = os.getenv('MANDRILL_TEST_API_KEY')
@unittest.skipUnless(MANDRILL_TEST_API_KEY,
"Set MANDRILL_TEST_API_KEY environment variable to run integration tests")
@override_settings(MANDRILL_API_KEY=MANDRILL_TEST_API_KEY,
EMAIL_BACKEND="anymail.backends.mandrill.MandrillBackend")
EMAIL_BACKEND="anymail.backends.mandrill.EmailBackend")
class MandrillBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
"""Mandrill API integration tests

View File

@@ -18,7 +18,7 @@ from .mock_requests_backend import RequestsBackendMockAPITestCase, SessionSharin
from .utils import sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAME, AnymailTestMixin, decode_att
@override_settings(EMAIL_BACKEND='anymail.backends.postmark.PostmarkBackend',
@override_settings(EMAIL_BACKEND='anymail.backends.postmark.EmailBackend',
ANYMAIL={'POSTMARK_SERVER_TOKEN': 'test_server_token'})
class PostmarkBackendMockAPITestCase(RequestsBackendMockAPITestCase):
DEFAULT_RAW_RESPONSE = b"""{
@@ -560,7 +560,7 @@ class PostmarkBackendSessionSharingTestCase(SessionSharingTestCasesMixin, Postma
pass # tests are defined in the mixin
@override_settings(EMAIL_BACKEND="anymail.backends.postmark.PostmarkBackend")
@override_settings(EMAIL_BACKEND="anymail.backends.postmark.EmailBackend")
class PostmarkBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
"""Test ESP backend without required settings in place"""
@@ -570,3 +570,12 @@ class PostmarkBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin)
errmsg = str(cm.exception)
self.assertRegex(errmsg, r'\bPOSTMARK_SERVER_TOKEN\b')
self.assertRegex(errmsg, r'\bANYMAIL_POSTMARK_SERVER_TOKEN\b')
class PostmarkBackendDeprecationTests(PostmarkBackendMockAPITestCase):
@override_settings(EMAIL_BACKEND='anymail.backends.postmark.PostmarkBackend')
def test_renamed_backend_warning(self):
# ...postmark.PostmarkBackend --> ...postmark.EmailBackend
with self.assertWarnsRegex(DeprecationWarning,
r'anymail\.backends\.postmark\.EmailBackend'):
self.message.send()

View File

@@ -11,7 +11,7 @@ from .utils import AnymailTestMixin, sample_image_path, RUN_LIVE_TESTS
@unittest.skipUnless(RUN_LIVE_TESTS, "RUN_LIVE_TESTS disabled in this environment")
@override_settings(ANYMAIL_POSTMARK_SERVER_TOKEN="POSTMARK_API_TEST",
EMAIL_BACKEND="anymail.backends.postmark.PostmarkBackend")
EMAIL_BACKEND="anymail.backends.postmark.EmailBackend")
class PostmarkBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
"""Postmark API integration tests

View File

@@ -1,6 +1,6 @@
from django.dispatch import receiver
from anymail.backends.test import TestBackend
from anymail.backends.test import EmailBackend as TestEmailBackend
from anymail.exceptions import AnymailCancelSend, AnymailRecipientsRefused
from anymail.message import AnymailRecipientStatus
from anymail.signals import pre_send, post_send
@@ -16,9 +16,9 @@ class TestPreSendSignal(TestBackendTestCase):
@receiver(pre_send, weak=False)
def handle_pre_send(sender, message, esp_name, **kwargs):
self.assertEqual(self.get_send_count(), 0) # not sent yet
self.assertEqual(sender, TestBackend)
self.assertEqual(sender, TestEmailBackend)
self.assertEqual(message, self.message)
self.assertEqual(esp_name, "Test") # the TestBackend's ESP is named "Test"
self.assertEqual(esp_name, "Test") # the TestEmailBackend's ESP is named "Test"
self.receiver_called = True
self.addCleanup(pre_send.disconnect, receiver=handle_pre_send)
@@ -62,13 +62,13 @@ class TestPostSendSignal(TestBackendTestCase):
@receiver(post_send, weak=False)
def handle_post_send(sender, message, status, esp_name, **kwargs):
self.assertEqual(self.get_send_count(), 1) # already sent
self.assertEqual(sender, TestBackend)
self.assertEqual(sender, TestEmailBackend)
self.assertEqual(message, self.message)
self.assertEqual(status.status, {'sent'})
self.assertEqual(status.message_id, 1) # TestBackend default message_id
self.assertEqual(status.message_id, 1) # TestEmailBackend default message_id
self.assertEqual(status.recipients['to@example.com'].status, 'sent')
self.assertEqual(status.recipients['to@example.com'].message_id, 1)
self.assertEqual(esp_name, "Test") # the TestBackend's ESP is named "Test"
self.assertEqual(esp_name, "Test") # the TestEmailBackend's ESP is named "Test"
self.receiver_called = True
self.addCleanup(post_send.disconnect, receiver=handle_post_send)

View File

@@ -20,7 +20,7 @@ from .mock_requests_backend import RequestsBackendMockAPITestCase, SessionSharin
from .utils import sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAME, AnymailTestMixin
@override_settings(EMAIL_BACKEND='anymail.backends.sendgrid.SendGridBackend',
@override_settings(EMAIL_BACKEND='anymail.backends.sendgrid.EmailBackend',
ANYMAIL={'SENDGRID_API_KEY': 'test_api_key'})
class SendGridBackendMockAPITestCase(RequestsBackendMockAPITestCase):
DEFAULT_RAW_RESPONSE = b"" # SendGrid v3 success responses are empty
@@ -619,7 +619,7 @@ class SendGridBackendSessionSharingTestCase(SessionSharingTestCasesMixin, SendGr
pass # tests are defined in the mixin
@override_settings(EMAIL_BACKEND="anymail.backends.sendgrid.SendGridBackend")
@override_settings(EMAIL_BACKEND="anymail.backends.sendgrid.EmailBackend")
class SendGridBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
"""Test ESP backend without required settings in place"""
@@ -628,7 +628,7 @@ class SendGridBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin)
mail.send_mail('Subject', 'Message', 'from@example.com', ['to@example.com'])
@override_settings(EMAIL_BACKEND="anymail.backends.sendgrid.SendGridBackend")
@override_settings(EMAIL_BACKEND="anymail.backends.sendgrid.EmailBackend")
class SendGridBackendDisallowsV2Tests(SimpleTestCase, AnymailTestMixin):
"""Using v2-API-only features should cause errors with v3 backend"""
@@ -645,3 +645,12 @@ class SendGridBackendDisallowsV2Tests(SimpleTestCase, AnymailTestMixin):
message.esp_extra = {'x-smtpapi': {'asm_group_id': 1}}
with self.assertRaisesRegex(AnymailConfigurationError, r'\bsendgrid_v2\.EmailBackend\b'):
message.send()
class SendGridBackendDeprecationTests(SendGridBackendMockAPITestCase):
@override_settings(EMAIL_BACKEND='anymail.backends.sendgrid.SendGridBackend')
def test_renamed_backend_warning(self):
# ...sendgrid.SendGridBackend --> ...sendgrid.EmailBackend
with self.assertWarnsRegex(DeprecationWarning,
r'anymail\.backends\.sendgrid\.EmailBackend'):
self.message.send()

View File

@@ -22,7 +22,7 @@ SENDGRID_TEST_TEMPLATE_ID = os.getenv('SENDGRID_TEST_TEMPLATE_ID')
ANYMAIL_SENDGRID_SEND_DEFAULTS={"esp_extra": {
"mail_settings": {"sandbox_mode": {"enable": True}},
}},
EMAIL_BACKEND="anymail.backends.sendgrid.SendGridBackend")
EMAIL_BACKEND="anymail.backends.sendgrid.EmailBackend")
class SendGridBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
"""SendGrid v3 API integration tests

View File

@@ -21,7 +21,7 @@ from anymail.message import attach_inline_image_file
from .utils import AnymailTestMixin, decode_att, SAMPLE_IMAGE_FILENAME, sample_image_path, sample_image_content
@override_settings(EMAIL_BACKEND='anymail.backends.sparkpost.SparkPostBackend',
@override_settings(EMAIL_BACKEND='anymail.backends.sparkpost.EmailBackend',
ANYMAIL={'SPARKPOST_API_KEY': 'test_api_key'})
class SparkPostBackendMockAPITestCase(SimpleTestCase, AnymailTestMixin):
"""TestCase that uses SparkPostEmailBackend with a mocked transmissions.send API"""
@@ -559,7 +559,7 @@ class SparkPostBackendRecipientsRefusedTests(SparkPostBackendMockAPITestCase):
self.assertEqual(sent, 1) # refused message is included in sent count
@override_settings(EMAIL_BACKEND="anymail.backends.sparkpost.SparkPostBackend")
@override_settings(EMAIL_BACKEND="anymail.backends.sparkpost.EmailBackend")
class SparkPostBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
"""Test ESP backend without required settings in place"""
@@ -580,3 +580,12 @@ class SparkPostBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin
# Poke into implementation details to verify:
self.assertIsNone(conn.api_key) # Anymail prop
self.assertEqual(conn.sp.api_key, 'key_from_environment') # SparkPost prop
class SparkPostBackendDeprecationTests(SparkPostBackendMockAPITestCase):
@override_settings(EMAIL_BACKEND='anymail.backends.sparkpost.SparkPostBackend')
def test_renamed_backend_warning(self):
# ...sparkpost.SparkPostBackend --> ...sparkpost.EmailBackend
with self.assertWarnsRegex(DeprecationWarning,
r'anymail\.backends\.sparkpost\.EmailBackend'):
self.message.send()

View File

@@ -18,7 +18,7 @@ SPARKPOST_TEST_API_KEY = os.getenv('SPARKPOST_TEST_API_KEY')
"Set SPARKPOST_TEST_API_KEY environment variable "
"to run SparkPost integration tests")
@override_settings(ANYMAIL_SPARKPOST_API_KEY=SPARKPOST_TEST_API_KEY,
EMAIL_BACKEND="anymail.backends.sparkpost.SparkPostBackend")
EMAIL_BACKEND="anymail.backends.sparkpost.EmailBackend")
class SparkPostBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
"""SparkPost API integration tests