mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Test without optional packages
Tox: * Add Tox factor for extras (all, none, individual ESP). For now, only break out ESPs that have specific extra dependencies (amazon_ses, sparkpost). * Install most package dependencies (including extras) through the package itself. * Use new runtests.py environment vars to limit test tags when Tox isn't installing all extras. Travis: * Rework matrix to request specific TOXENVs directly; drop tox-travis. Test runner (runtests.py): * Centralize RUN_LIVE_TESTS logic in runtests.py * Add ANYMAIL_ONLY_TEST and ANYMAIL_SKIP_TESTS env vars (comma-separated lists of tags) Test implementations: * Tag all ESP-specific tests with ESP * Tag live tests with "live" * Don't import ESP-specific packages at test module level. (Test discovery imports test modules before tag-based filtering.) Closes #104
This commit is contained in:
@@ -5,13 +5,10 @@ import json
|
||||
from datetime import datetime
|
||||
from email.mime.application import MIMEApplication
|
||||
|
||||
import botocore.config
|
||||
import botocore.exceptions
|
||||
import six
|
||||
from django.core import mail
|
||||
from django.core.mail import BadHeaderError
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
from mock import ANY, patch
|
||||
|
||||
from anymail.exceptions import AnymailAPIError, AnymailUnsupportedFeature
|
||||
@@ -20,6 +17,7 @@ from anymail.message import attach_inline_image_file, AnymailMessage
|
||||
from .utils import AnymailTestMixin, SAMPLE_IMAGE_FILENAME, sample_image_content, sample_image_path
|
||||
|
||||
|
||||
@tag('amazon_ses')
|
||||
@override_settings(EMAIL_BACKEND='anymail.backends.amazon_ses.EmailBackend')
|
||||
class AmazonSESBackendMockAPITestCase(SimpleTestCase, AnymailTestMixin):
|
||||
"""TestCase that uses the Amazon SES EmailBackend with a mocked boto3 client"""
|
||||
@@ -61,8 +59,9 @@ class AmazonSESBackendMockAPITestCase(SimpleTestCase, AnymailTestMixin):
|
||||
return mock_operation.return_value
|
||||
|
||||
def set_mock_failure(self, response, operation_name="send_raw_email"):
|
||||
from botocore.exceptions import ClientError
|
||||
mock_operation = getattr(self.mock_client_instance, operation_name)
|
||||
mock_operation.side_effect = botocore.exceptions.ClientError(response, operation_name=operation_name)
|
||||
mock_operation.side_effect = ClientError(response, operation_name=operation_name)
|
||||
|
||||
def get_session_params(self):
|
||||
if self.mock_session.call_args is None:
|
||||
@@ -111,6 +110,7 @@ class AmazonSESBackendMockAPITestCase(SimpleTestCase, AnymailTestMixin):
|
||||
raise AssertionError(msg or "ESP API was called and shouldn't have been")
|
||||
|
||||
|
||||
@tag('amazon_ses')
|
||||
class AmazonSESBackendStandardEmailTests(AmazonSESBackendMockAPITestCase):
|
||||
"""Test backend support for Django standard email features"""
|
||||
|
||||
@@ -318,6 +318,7 @@ class AmazonSESBackendStandardEmailTests(AmazonSESBackendMockAPITestCase):
|
||||
headers={"X-Header": "custom header value\r\ninjected"}).send()
|
||||
|
||||
|
||||
@tag('amazon_ses')
|
||||
class AmazonSESBackendAnymailFeatureTests(AmazonSESBackendMockAPITestCase):
|
||||
"""Test backend support for Anymail added features"""
|
||||
|
||||
@@ -589,6 +590,7 @@ class AmazonSESBackendAnymailFeatureTests(AmazonSESBackendMockAPITestCase):
|
||||
self.assertEqual(self.message.anymail_status.esp_response, response_content)
|
||||
|
||||
|
||||
@tag('amazon_ses')
|
||||
class AmazonSESBackendConfigurationTests(AmazonSESBackendMockAPITestCase):
|
||||
"""Test configuration options"""
|
||||
|
||||
@@ -635,7 +637,8 @@ class AmazonSESBackendConfigurationTests(AmazonSESBackendMockAPITestCase):
|
||||
|
||||
def test_client_params_in_connection_init(self):
|
||||
"""You can also supply credentials specifically for a particular EmailBackend connection instance"""
|
||||
boto_config = botocore.config.Config(connect_timeout=30)
|
||||
from botocore.config import Config
|
||||
boto_config = Config(connect_timeout=30)
|
||||
conn = mail.get_connection(
|
||||
'anymail.backends.amazon_ses.EmailBackend',
|
||||
client_params={"aws_session_token": "test-session-token", "config": boto_config})
|
||||
|
||||
@@ -5,7 +5,7 @@ from base64 import b64encode
|
||||
from datetime import datetime
|
||||
from textwrap import dedent
|
||||
|
||||
import botocore.exceptions
|
||||
from django.test import tag
|
||||
from django.utils.timezone import utc
|
||||
from mock import ANY, patch
|
||||
|
||||
@@ -18,6 +18,7 @@ from .test_amazon_ses_webhooks import AmazonSESWebhookTestsMixin
|
||||
from .webhook_cases import WebhookTestCase
|
||||
|
||||
|
||||
@tag('amazon_ses')
|
||||
class AmazonSESInboundTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
|
||||
|
||||
def setUp(self):
|
||||
@@ -270,7 +271,8 @@ class AmazonSESInboundTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
|
||||
def test_inbound_s3_failure_message(self):
|
||||
"""Issue a helpful error when S3 download fails"""
|
||||
# Boto's error: "An error occurred (403) when calling the HeadObject operation: Forbidden")
|
||||
self.mock_s3.download_fileobj.side_effect = botocore.exceptions.ClientError(
|
||||
from botocore.exceptions import ClientError
|
||||
self.mock_s3.download_fileobj.side_effect = ClientError(
|
||||
{'Error': {'Code': 403, 'Message': 'Forbidden'}}, operation_name='HeadObject')
|
||||
|
||||
raw_ses_event = {
|
||||
@@ -290,7 +292,7 @@ class AmazonSESInboundTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
|
||||
"Anymail AmazonSESInboundWebhookView couldn't download S3 object 'YourBucket:inbound/the_object_key'"
|
||||
) as cm:
|
||||
self.post_from_sns('/anymail/amazon_ses/inbound/', raw_sns_message)
|
||||
self.assertIsInstance(cm.exception, botocore.exceptions.ClientError) # both Boto and Anymail exception class
|
||||
self.assertIsInstance(cm.exception, ClientError) # both Boto and Anymail exception class
|
||||
self.assertIn("ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden",
|
||||
str(cm.exception)) # original Boto message included
|
||||
|
||||
|
||||
@@ -5,13 +5,12 @@ import os
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import AnymailAPIError
|
||||
from anymail.message import AnymailMessage
|
||||
|
||||
from .utils import AnymailTestMixin, sample_image_path, RUN_LIVE_TESTS
|
||||
from .utils import AnymailTestMixin, sample_image_path
|
||||
|
||||
try:
|
||||
ResourceWarning
|
||||
@@ -24,7 +23,6 @@ AMAZON_SES_TEST_SECRET_ACCESS_KEY = os.getenv("AMAZON_SES_TEST_SECRET_ACCESS_KEY
|
||||
AMAZON_SES_TEST_REGION_NAME = os.getenv("AMAZON_SES_TEST_REGION_NAME", "us-east-1")
|
||||
|
||||
|
||||
@unittest.skipUnless(RUN_LIVE_TESTS, "RUN_LIVE_TESTS disabled in this environment")
|
||||
@unittest.skipUnless(AMAZON_SES_TEST_ACCESS_KEY_ID and AMAZON_SES_TEST_SECRET_ACCESS_KEY,
|
||||
"Set AMAZON_SES_TEST_ACCESS_KEY_ID and AMAZON_SES_TEST_SECRET_ACCESS_KEY "
|
||||
"environment variables to run Amazon SES integration tests")
|
||||
@@ -43,6 +41,7 @@ AMAZON_SES_TEST_REGION_NAME = os.getenv("AMAZON_SES_TEST_REGION_NAME", "us-east-
|
||||
},
|
||||
"AMAZON_SES_CONFIGURATION_SET_NAME": "TestConfigurationSet", # actual config set in Anymail test account
|
||||
})
|
||||
@tag('amazon_ses', 'live')
|
||||
class AmazonSESBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
|
||||
"""Amazon SES API integration tests
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@ import json
|
||||
import warnings
|
||||
from datetime import datetime
|
||||
|
||||
import botocore.exceptions
|
||||
from django.test import override_settings
|
||||
from django.test import override_settings, tag
|
||||
from django.utils.timezone import utc
|
||||
from mock import ANY, patch
|
||||
|
||||
@@ -27,6 +26,7 @@ class AmazonSESWebhookTestsMixin(object):
|
||||
**kwargs)
|
||||
|
||||
|
||||
@tag('amazon_ses')
|
||||
class AmazonSESWebhookSecurityTests(WebhookTestCase, AmazonSESWebhookTestsMixin, WebhookBasicAuthTestsMixin):
|
||||
def call_webhook(self):
|
||||
return self.post_from_sns('/anymail/amazon_ses/tracking/',
|
||||
@@ -43,6 +43,7 @@ class AmazonSESWebhookSecurityTests(WebhookTestCase, AmazonSESWebhookTestsMixin,
|
||||
self.assertEqual(response["WWW-Authenticate"], 'Basic realm="Anymail WEBHOOK_SECRET"')
|
||||
|
||||
|
||||
@tag('amazon_ses')
|
||||
class AmazonSESNotificationsTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
|
||||
def test_bounce_event(self):
|
||||
# This test includes a complete Amazon SES example event. (Later tests omit some payload for brevity.)
|
||||
@@ -404,6 +405,7 @@ class AmazonSESNotificationsTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
|
||||
self.post_from_sns('/anymail/amazon_ses/tracking/', raw_sns_message)
|
||||
|
||||
|
||||
@tag('amazon_ses')
|
||||
class AmazonSESSubscriptionManagementTests(WebhookTestCase, AmazonSESWebhookTestsMixin):
|
||||
# Anymail will automatically respond to SNS subscription notifications
|
||||
# if Anymail is configured to require basic auth via WEBHOOK_SECRET.
|
||||
@@ -450,7 +452,8 @@ class AmazonSESSubscriptionManagementTests(WebhookTestCase, AmazonSESWebhookTest
|
||||
|
||||
def test_sns_subscription_confirmation_failure(self):
|
||||
"""Auto-confirmation allows error through if confirm call fails"""
|
||||
self.mock_client_instance.confirm_subscription.side_effect = botocore.exceptions.ClientError({
|
||||
from botocore.exceptions import ClientError
|
||||
self.mock_client_instance.confirm_subscription.side_effect = ClientError({
|
||||
'Error': {
|
||||
'Type': 'Sender',
|
||||
'Code': 'InternalError',
|
||||
@@ -461,7 +464,7 @@ class AmazonSESSubscriptionManagementTests(WebhookTestCase, AmazonSESWebhookTest
|
||||
'HTTPStatusCode': 500,
|
||||
}
|
||||
}, operation_name="confirm_subscription")
|
||||
with self.assertRaisesMessage(botocore.exceptions.ClientError, "Gremlins!"):
|
||||
with self.assertRaisesMessage(ClientError, "Gremlins!"):
|
||||
self.post_from_sns('/anymail/amazon_ses/tracking/', self.SNS_SUBSCRIPTION_CONFIRMATION)
|
||||
# didn't notify receivers:
|
||||
self.assertEqual(self.tracking_handler.call_count, 0)
|
||||
|
||||
@@ -16,8 +16,7 @@ from email.mime.image import MIMEImage
|
||||
|
||||
from django.core import mail
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
from django.utils.timezone import get_fixed_timezone, override as override_current_timezone
|
||||
|
||||
from anymail.exceptions import (
|
||||
@@ -30,6 +29,7 @@ from .utils import (AnymailTestMixin, sample_email_content,
|
||||
sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAME)
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
@override_settings(EMAIL_BACKEND='anymail.backends.mailgun.EmailBackend',
|
||||
ANYMAIL={'MAILGUN_API_KEY': 'test_api_key'})
|
||||
class MailgunBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
@@ -44,6 +44,7 @@ class MailgunBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
self.message = mail.EmailMultiAlternatives('Subject', 'Text Body', 'from@example.com', ['to@example.com'])
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
class MailgunBackendStandardEmailTests(MailgunBackendMockAPITestCase):
|
||||
"""Test backend support for Django standard email features"""
|
||||
|
||||
@@ -374,6 +375,7 @@ class MailgunBackendStandardEmailTests(MailgunBackendMockAPITestCase):
|
||||
self.assertEqual(sent, 0)
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
class MailgunBackendAnymailFeatureTests(MailgunBackendMockAPITestCase):
|
||||
"""Test backend support for Anymail added features"""
|
||||
|
||||
@@ -563,6 +565,7 @@ class MailgunBackendAnymailFeatureTests(MailgunBackendMockAPITestCase):
|
||||
# (Anything that requests can serialize as a form field will work with Mailgun)
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
class MailgunBackendRecipientsRefusedTests(MailgunBackendMockAPITestCase):
|
||||
"""Should raise AnymailRecipientsRefused when *all* recipients are rejected or invalid"""
|
||||
|
||||
@@ -594,11 +597,13 @@ class MailgunBackendRecipientsRefusedTests(MailgunBackendMockAPITestCase):
|
||||
self.assertEqual(sent, 0)
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
class MailgunBackendSessionSharingTestCase(SessionSharingTestCasesMixin, MailgunBackendMockAPITestCase):
|
||||
"""Requests session sharing tests"""
|
||||
pass # tests are defined in the mixin
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
@override_settings(EMAIL_BACKEND="anymail.backends.mailgun.EmailBackend")
|
||||
class MailgunBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
|
||||
"""Test ESP backend without required settings in place"""
|
||||
|
||||
@@ -3,7 +3,7 @@ from datetime import datetime
|
||||
from textwrap import dedent
|
||||
|
||||
import six
|
||||
from django.test import override_settings
|
||||
from django.test import override_settings, tag
|
||||
from django.utils.timezone import utc
|
||||
from mock import ANY
|
||||
|
||||
@@ -19,6 +19,7 @@ from .utils import sample_image_content, sample_email_content
|
||||
from .webhook_cases import WebhookTestCase
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
@override_settings(ANYMAIL_MAILGUN_API_KEY=TEST_API_KEY)
|
||||
class MailgunInboundTestCase(WebhookTestCase):
|
||||
def test_inbound_basics(self):
|
||||
|
||||
@@ -9,19 +9,18 @@ from datetime import datetime, timedelta
|
||||
from time import mktime, sleep
|
||||
|
||||
import requests
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import AnymailAPIError
|
||||
from anymail.message import AnymailMessage
|
||||
|
||||
from .utils import AnymailTestMixin, sample_image_path, RUN_LIVE_TESTS
|
||||
from .utils import AnymailTestMixin, sample_image_path
|
||||
|
||||
MAILGUN_TEST_API_KEY = os.getenv('MAILGUN_TEST_API_KEY')
|
||||
MAILGUN_TEST_DOMAIN = os.getenv('MAILGUN_TEST_DOMAIN')
|
||||
|
||||
|
||||
@unittest.skipUnless(RUN_LIVE_TESTS, "RUN_LIVE_TESTS disabled in this environment")
|
||||
@tag('mailgun', 'live')
|
||||
@unittest.skipUnless(MAILGUN_TEST_API_KEY and MAILGUN_TEST_DOMAIN,
|
||||
"Set MAILGUN_TEST_API_KEY and MAILGUN_TEST_DOMAIN environment variables "
|
||||
"to run Mailgun integration tests")
|
||||
|
||||
@@ -4,7 +4,7 @@ from datetime import datetime
|
||||
import hashlib
|
||||
import hmac
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import override_settings
|
||||
from django.test import override_settings, tag
|
||||
from django.utils.timezone import utc
|
||||
from mock import ANY
|
||||
|
||||
@@ -59,6 +59,7 @@ def querydict_to_postdict(qd):
|
||||
}
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
class MailgunWebhookSettingsTestCase(WebhookTestCase):
|
||||
def test_requires_api_key(self):
|
||||
with self.assertRaises(ImproperlyConfigured):
|
||||
@@ -66,6 +67,7 @@ class MailgunWebhookSettingsTestCase(WebhookTestCase):
|
||||
data=json.dumps(mailgun_sign_payload({'event-data': {'event': 'delivered'}})))
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
@override_settings(ANYMAIL_MAILGUN_API_KEY=TEST_API_KEY)
|
||||
class MailgunWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin):
|
||||
should_warn_if_no_auth = False # because we check webhook signature
|
||||
@@ -94,6 +96,7 @@ class MailgunWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
@override_settings(ANYMAIL_MAILGUN_API_KEY=TEST_API_KEY)
|
||||
class MailgunTestCase(WebhookTestCase):
|
||||
# Tests for Mailgun's new webhooks (announced 2018-06-29)
|
||||
@@ -445,6 +448,7 @@ class MailgunTestCase(WebhookTestCase):
|
||||
self.assertEqual(event.click_url, "https://example.com/test")
|
||||
|
||||
|
||||
@tag('mailgun')
|
||||
@override_settings(ANYMAIL_MAILGUN_API_KEY=TEST_API_KEY)
|
||||
class MailgunLegacyTestCase(WebhookTestCase):
|
||||
# Tests for Mailgun's "legacy" webhooks
|
||||
|
||||
@@ -7,8 +7,7 @@ from email.mime.image import MIMEImage
|
||||
|
||||
from django.core import mail
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import (AnymailAPIError, AnymailSerializationError,
|
||||
AnymailUnsupportedFeature,
|
||||
@@ -19,6 +18,7 @@ from .mock_requests_backend import RequestsBackendMockAPITestCase, SessionSharin
|
||||
from .utils import sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAME, AnymailTestMixin, decode_att
|
||||
|
||||
|
||||
@tag('mailjet')
|
||||
@override_settings(EMAIL_BACKEND='anymail.backends.mailjet.EmailBackend',
|
||||
ANYMAIL={
|
||||
'MAILJET_API_KEY': '',
|
||||
@@ -64,6 +64,7 @@ class MailjetBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
])
|
||||
|
||||
|
||||
@tag('mailjet')
|
||||
class MailjetBackendStandardEmailTests(MailjetBackendMockAPITestCase):
|
||||
"""Test backend support for Django standard email features"""
|
||||
|
||||
@@ -354,6 +355,7 @@ class MailjetBackendStandardEmailTests(MailjetBackendMockAPITestCase):
|
||||
self.message.send()
|
||||
|
||||
|
||||
@tag('mailjet')
|
||||
class MailjetBackendAnymailFeatureTests(MailjetBackendMockAPITestCase):
|
||||
"""Test backend support for Anymail added features"""
|
||||
|
||||
@@ -623,11 +625,13 @@ class MailjetBackendAnymailFeatureTests(MailjetBackendMockAPITestCase):
|
||||
self.message.send()
|
||||
|
||||
|
||||
@tag('mailjet')
|
||||
class MailjetBackendSessionSharingTestCase(SessionSharingTestCasesMixin, MailjetBackendMockAPITestCase):
|
||||
"""Requests session sharing tests"""
|
||||
pass # tests are defined in the mixin
|
||||
|
||||
|
||||
@tag('mailjet')
|
||||
@override_settings(EMAIL_BACKEND="anymail.backends.mailjet.EmailBackend")
|
||||
class MailjetBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
|
||||
"""Test ESP backend without required settings in place"""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from base64 import b64encode
|
||||
|
||||
from django.test import tag
|
||||
from mock import ANY
|
||||
|
||||
from anymail.inbound import AnymailInboundMessage
|
||||
@@ -11,6 +12,7 @@ from .utils import sample_image_content, sample_email_content
|
||||
from .webhook_cases import WebhookTestCase
|
||||
|
||||
|
||||
@tag('mailjet')
|
||||
class MailjetInboundTestCase(WebhookTestCase):
|
||||
def test_inbound_basics(self):
|
||||
raw_event = {
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import AnymailAPIError
|
||||
from anymail.message import AnymailMessage
|
||||
|
||||
from .utils import AnymailTestMixin, sample_image_path, RUN_LIVE_TESTS
|
||||
from .utils import AnymailTestMixin, sample_image_path
|
||||
|
||||
MAILJET_TEST_API_KEY = os.getenv('MAILJET_TEST_API_KEY')
|
||||
MAILJET_TEST_SECRET_KEY = os.getenv('MAILJET_TEST_SECRET_KEY')
|
||||
|
||||
|
||||
@unittest.skipUnless(RUN_LIVE_TESTS, "RUN_LIVE_TESTS disabled in this environment")
|
||||
@tag('mailjet', 'live')
|
||||
@unittest.skipUnless(MAILJET_TEST_API_KEY and MAILJET_TEST_SECRET_KEY,
|
||||
"Set MAILJET_TEST_API_KEY and MAILJET_TEST_SECRET_KEY "
|
||||
"environment variables to run Mailjet integration tests")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
from django.test import tag
|
||||
from django.utils.timezone import utc
|
||||
from mock import ANY
|
||||
|
||||
@@ -9,6 +10,7 @@ from anymail.webhooks.mailjet import MailjetTrackingWebhookView
|
||||
from .webhook_cases import WebhookBasicAuthTestsMixin, WebhookTestCase
|
||||
|
||||
|
||||
@tag('mailjet')
|
||||
class MailjetWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin):
|
||||
def call_webhook(self):
|
||||
return self.client.post('/anymail/mailjet/tracking/',
|
||||
@@ -17,6 +19,7 @@ class MailjetWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin
|
||||
# Actual tests are in WebhookBasicAuthTestsMixin
|
||||
|
||||
|
||||
@tag('mailjet')
|
||||
class MailjetDeliveryTestCase(WebhookTestCase):
|
||||
|
||||
def test_sent_event(self):
|
||||
|
||||
@@ -7,8 +7,7 @@ from email.mime.image import MIMEImage
|
||||
|
||||
from django.core import mail
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
from django.utils.timezone import get_fixed_timezone, override as override_current_timezone
|
||||
|
||||
from anymail.exceptions import (AnymailAPIError, AnymailRecipientsRefused,
|
||||
@@ -19,6 +18,7 @@ from .mock_requests_backend import RequestsBackendMockAPITestCase, SessionSharin
|
||||
from .utils import sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAME, AnymailTestMixin, decode_att
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
@override_settings(EMAIL_BACKEND='anymail.backends.mandrill.EmailBackend',
|
||||
ANYMAIL={'MANDRILL_API_KEY': 'test_api_key'})
|
||||
class MandrillBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
@@ -35,6 +35,7 @@ class MandrillBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
self.message = mail.EmailMultiAlternatives('Subject', 'Text Body', 'from@example.com', ['to@example.com'])
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
class MandrillBackendStandardEmailTests(MandrillBackendMockAPITestCase):
|
||||
"""Test backend support for Django mail wrappers"""
|
||||
|
||||
@@ -267,6 +268,7 @@ class MandrillBackendStandardEmailTests(MandrillBackendMockAPITestCase):
|
||||
self.message.send()
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
class MandrillBackendAnymailFeatureTests(MandrillBackendMockAPITestCase):
|
||||
"""Test backend support for Anymail added features"""
|
||||
|
||||
@@ -534,6 +536,7 @@ class MandrillBackendAnymailFeatureTests(MandrillBackendMockAPITestCase):
|
||||
self.assertRegex(str(err), r"Decimal.*is not JSON serializable") # original message
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
class MandrillBackendRecipientsRefusedTests(MandrillBackendMockAPITestCase):
|
||||
"""Should raise AnymailRecipientsRefused when *all* recipients are rejected or invalid"""
|
||||
|
||||
@@ -588,11 +591,13 @@ class MandrillBackendRecipientsRefusedTests(MandrillBackendMockAPITestCase):
|
||||
self.assertEqual(sent, 1) # refused message is included in sent count
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
class MandrillBackendSessionSharingTestCase(SessionSharingTestCasesMixin, MandrillBackendMockAPITestCase):
|
||||
"""Requests session sharing tests"""
|
||||
pass # tests are defined in the mixin
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
@override_settings(EMAIL_BACKEND="anymail.backends.mandrill.EmailBackend")
|
||||
class MandrillBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
|
||||
"""Test backend without required settings"""
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
from datetime import date
|
||||
from django.core import mail
|
||||
from django.test import override_settings
|
||||
from django.test import override_settings, tag
|
||||
|
||||
from anymail.exceptions import AnymailSerializationError
|
||||
|
||||
from .test_mandrill_backend import MandrillBackendMockAPITestCase
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
class MandrillBackendDjrillFeatureTests(MandrillBackendMockAPITestCase):
|
||||
"""Test backend support for deprecated features leftover from Djrill"""
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from textwrap import dedent
|
||||
|
||||
from django.test import override_settings
|
||||
from django.test import override_settings, tag
|
||||
from mock import ANY
|
||||
|
||||
from anymail.inbound import AnymailInboundMessage
|
||||
@@ -11,6 +11,7 @@ from .test_mandrill_webhooks import TEST_WEBHOOK_KEY, mandrill_args
|
||||
from .webhook_cases import WebhookTestCase
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
@override_settings(ANYMAIL_MANDRILL_WEBHOOK_KEY=TEST_WEBHOOK_KEY)
|
||||
class MandrillInboundTestCase(WebhookTestCase):
|
||||
def test_inbound_basics(self):
|
||||
|
||||
@@ -2,18 +2,17 @@ import os
|
||||
import unittest
|
||||
|
||||
from django.core import mail
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import AnymailAPIError, AnymailRecipientsRefused
|
||||
from anymail.message import AnymailMessage
|
||||
|
||||
from .utils import AnymailTestMixin, sample_image_path, RUN_LIVE_TESTS
|
||||
from .utils import AnymailTestMixin, sample_image_path
|
||||
|
||||
MANDRILL_TEST_API_KEY = os.getenv('MANDRILL_TEST_API_KEY')
|
||||
|
||||
|
||||
@unittest.skipUnless(RUN_LIVE_TESTS, "RUN_LIVE_TESTS disabled in this environment")
|
||||
@tag('mandrill', 'live')
|
||||
@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,
|
||||
|
||||
@@ -6,7 +6,7 @@ import hashlib
|
||||
import hmac
|
||||
from base64 import b64encode
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import override_settings
|
||||
from django.test import override_settings, tag
|
||||
from django.utils.timezone import utc
|
||||
from mock import ANY
|
||||
|
||||
@@ -48,6 +48,7 @@ def mandrill_args(events=None,
|
||||
}
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
class MandrillWebhookSettingsTestCase(WebhookTestCase):
|
||||
def test_requires_webhook_key(self):
|
||||
with self.assertRaisesRegex(ImproperlyConfigured, r'MANDRILL_WEBHOOK_KEY'):
|
||||
@@ -62,6 +63,7 @@ class MandrillWebhookSettingsTestCase(WebhookTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
@override_settings(ANYMAIL_MANDRILL_WEBHOOK_KEY=TEST_WEBHOOK_KEY)
|
||||
class MandrillWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin):
|
||||
should_warn_if_no_auth = False # because we check webhook signature
|
||||
@@ -127,6 +129,7 @@ class MandrillWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixi
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
|
||||
@tag('mandrill')
|
||||
@override_settings(ANYMAIL_MANDRILL_WEBHOOK_KEY=TEST_WEBHOOK_KEY)
|
||||
class MandrillTrackingTestCase(WebhookTestCase):
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ from email.mime.image import MIMEImage
|
||||
|
||||
from django.core import mail
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import (
|
||||
AnymailAPIError, AnymailSerializationError,
|
||||
@@ -19,6 +18,7 @@ from .mock_requests_backend import RequestsBackendMockAPITestCase, SessionSharin
|
||||
from .utils import sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAME, AnymailTestMixin, decode_att
|
||||
|
||||
|
||||
@tag('postmark')
|
||||
@override_settings(EMAIL_BACKEND='anymail.backends.postmark.EmailBackend',
|
||||
ANYMAIL={'POSTMARK_SERVER_TOKEN': 'test_server_token'})
|
||||
class PostmarkBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
@@ -36,6 +36,7 @@ class PostmarkBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
self.message = mail.EmailMultiAlternatives('Subject', 'Text Body', 'from@example.com', ['to@example.com'])
|
||||
|
||||
|
||||
@tag('postmark')
|
||||
class PostmarkBackendStandardEmailTests(PostmarkBackendMockAPITestCase):
|
||||
"""Test backend support for Django standard email features"""
|
||||
|
||||
@@ -318,6 +319,7 @@ class PostmarkBackendStandardEmailTests(PostmarkBackendMockAPITestCase):
|
||||
self.message.send()
|
||||
|
||||
|
||||
@tag('postmark')
|
||||
class PostmarkBackendAnymailFeatureTests(PostmarkBackendMockAPITestCase):
|
||||
"""Test backend support for Anymail added features"""
|
||||
|
||||
@@ -605,6 +607,7 @@ class PostmarkBackendAnymailFeatureTests(PostmarkBackendMockAPITestCase):
|
||||
self.assertRegex(str(err), r"Decimal.*is not JSON serializable") # original message
|
||||
|
||||
|
||||
@tag('postmark')
|
||||
class PostmarkBackendRecipientsRefusedTests(PostmarkBackendMockAPITestCase):
|
||||
"""Should raise AnymailRecipientsRefused when *all* recipients are rejected or invalid"""
|
||||
|
||||
@@ -699,11 +702,13 @@ class PostmarkBackendRecipientsRefusedTests(PostmarkBackendMockAPITestCase):
|
||||
self.assertEqual(status.recipients['spam@example.com'].status, 'rejected')
|
||||
|
||||
|
||||
@tag('postmark')
|
||||
class PostmarkBackendSessionSharingTestCase(SessionSharingTestCasesMixin, PostmarkBackendMockAPITestCase):
|
||||
"""Requests session sharing tests"""
|
||||
pass # tests are defined in the mixin
|
||||
|
||||
|
||||
@tag('postmark')
|
||||
@override_settings(EMAIL_BACKEND="anymail.backends.postmark.EmailBackend")
|
||||
class PostmarkBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
|
||||
"""Test ESP backend without required settings in place"""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from base64 import b64encode
|
||||
|
||||
from django.test import tag
|
||||
from mock import ANY
|
||||
|
||||
from anymail.exceptions import AnymailConfigurationError
|
||||
@@ -12,6 +13,7 @@ from .utils import sample_image_content, sample_email_content
|
||||
from .webhook_cases import WebhookTestCase
|
||||
|
||||
|
||||
@tag('postmark')
|
||||
class PostmarkInboundTestCase(WebhookTestCase):
|
||||
def test_inbound_basics(self):
|
||||
raw_event = {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import AnymailAPIError
|
||||
from anymail.message import AnymailMessage
|
||||
|
||||
from .utils import AnymailTestMixin, sample_image_path, RUN_LIVE_TESTS
|
||||
from .utils import AnymailTestMixin, sample_image_path
|
||||
|
||||
|
||||
# For most integration tests, Postmark's sandboxed "POSTMARK_API_TEST" token is used.
|
||||
@@ -16,7 +15,7 @@ POSTMARK_TEST_SERVER_TOKEN = os.getenv('POSTMARK_TEST_SERVER_TOKEN')
|
||||
POSTMARK_TEST_TEMPLATE_ID = os.getenv('POSTMARK_TEST_TEMPLATE_ID')
|
||||
|
||||
|
||||
@unittest.skipUnless(RUN_LIVE_TESTS, "RUN_LIVE_TESTS disabled in this environment")
|
||||
@tag('postmark', 'live')
|
||||
@override_settings(ANYMAIL_POSTMARK_SERVER_TOKEN="POSTMARK_API_TEST",
|
||||
EMAIL_BACKEND="anymail.backends.postmark.EmailBackend")
|
||||
class PostmarkBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
from django.test import tag
|
||||
from django.utils.timezone import get_fixed_timezone, utc
|
||||
from mock import ANY
|
||||
|
||||
@@ -10,6 +11,7 @@ from anymail.webhooks.postmark import PostmarkTrackingWebhookView
|
||||
from .webhook_cases import WebhookBasicAuthTestsMixin, WebhookTestCase
|
||||
|
||||
|
||||
@tag('postmark')
|
||||
class PostmarkWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin):
|
||||
def call_webhook(self):
|
||||
return self.client.post('/anymail/postmark/tracking/',
|
||||
@@ -18,6 +20,7 @@ class PostmarkWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixi
|
||||
# Actual tests are in WebhookBasicAuthTestsMixin
|
||||
|
||||
|
||||
@tag('postmark')
|
||||
class PostmarkDeliveryTestCase(WebhookTestCase):
|
||||
def test_bounce_event(self):
|
||||
raw_event = {
|
||||
|
||||
@@ -9,8 +9,7 @@ from email.mime.image import MIMEImage
|
||||
|
||||
import six
|
||||
from django.core import mail
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
from django.utils.timezone import get_fixed_timezone, override as override_current_timezone
|
||||
|
||||
from anymail.exceptions import (AnymailAPIError, AnymailConfigurationError, AnymailSerializationError,
|
||||
@@ -24,6 +23,7 @@ from .utils import sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAM
|
||||
longtype = int if six.PY3 else long # NOQA: F821
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
@override_settings(EMAIL_BACKEND='anymail.backends.sendgrid.EmailBackend',
|
||||
ANYMAIL={'SENDGRID_API_KEY': 'test_api_key'})
|
||||
class SendGridBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
@@ -36,6 +36,7 @@ class SendGridBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
self.message = mail.EmailMultiAlternatives('Subject', 'Text Body', 'from@example.com', ['to@example.com'])
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
class SendGridBackendStandardEmailTests(SendGridBackendMockAPITestCase):
|
||||
"""Test backend support for Django standard email features"""
|
||||
|
||||
@@ -328,6 +329,7 @@ class SendGridBackendStandardEmailTests(SendGridBackendMockAPITestCase):
|
||||
self.message.send()
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
class SendGridBackendAnymailFeatureTests(SendGridBackendMockAPITestCase):
|
||||
"""Test backend support for Anymail added features"""
|
||||
|
||||
@@ -709,6 +711,7 @@ class SendGridBackendAnymailFeatureTests(SendGridBackendMockAPITestCase):
|
||||
{"email": "from@example.com", "name": "Sender, Inc."})
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
class SendGridBackendRecipientsRefusedTests(SendGridBackendMockAPITestCase):
|
||||
"""Should raise AnymailRecipientsRefused when *all* recipients are rejected or invalid"""
|
||||
|
||||
@@ -718,11 +721,13 @@ class SendGridBackendRecipientsRefusedTests(SendGridBackendMockAPITestCase):
|
||||
pass # not applicable to this backend
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
class SendGridBackendSessionSharingTestCase(SessionSharingTestCasesMixin, SendGridBackendMockAPITestCase):
|
||||
"""Requests session sharing tests"""
|
||||
pass # tests are defined in the mixin
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
@override_settings(EMAIL_BACKEND="anymail.backends.sendgrid.EmailBackend")
|
||||
class SendGridBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
|
||||
"""Test ESP backend without required settings in place"""
|
||||
@@ -732,6 +737,7 @@ class SendGridBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin)
|
||||
mail.send_mail('Subject', 'Message', 'from@example.com', ['to@example.com'])
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
@override_settings(EMAIL_BACKEND="anymail.backends.sendgrid.EmailBackend")
|
||||
class SendGridBackendDisallowsV2Tests(SimpleTestCase, AnymailTestMixin):
|
||||
"""Using v2-API-only features should cause errors with v3 backend"""
|
||||
|
||||
@@ -2,6 +2,7 @@ import json
|
||||
from textwrap import dedent
|
||||
|
||||
import six
|
||||
from django.test import tag
|
||||
from mock import ANY
|
||||
|
||||
from anymail.inbound import AnymailInboundMessage
|
||||
@@ -12,6 +13,7 @@ from .utils import sample_image_content, sample_email_content
|
||||
from .webhook_cases import WebhookTestCase
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
class SendgridInboundTestCase(WebhookTestCase):
|
||||
def test_inbound_basics(self):
|
||||
raw_event = {
|
||||
|
||||
@@ -2,19 +2,18 @@ import os
|
||||
import unittest
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import AnymailAPIError
|
||||
from anymail.message import AnymailMessage
|
||||
|
||||
from .utils import AnymailTestMixin, sample_image_path, RUN_LIVE_TESTS
|
||||
from .utils import AnymailTestMixin, sample_image_path
|
||||
|
||||
SENDGRID_TEST_API_KEY = os.getenv('SENDGRID_TEST_API_KEY')
|
||||
SENDGRID_TEST_TEMPLATE_ID = os.getenv('SENDGRID_TEST_TEMPLATE_ID')
|
||||
|
||||
|
||||
@unittest.skipUnless(RUN_LIVE_TESTS, "RUN_LIVE_TESTS disabled in this environment")
|
||||
@tag('sendgrid', 'live')
|
||||
@unittest.skipUnless(SENDGRID_TEST_API_KEY,
|
||||
"Set SENDGRID_TEST_API_KEY environment variable "
|
||||
"to run SendGrid integration tests")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
from django.test import tag
|
||||
from django.utils.timezone import utc
|
||||
from mock import ANY
|
||||
|
||||
@@ -9,6 +10,7 @@ from anymail.webhooks.sendgrid import SendGridTrackingWebhookView
|
||||
from .webhook_cases import WebhookBasicAuthTestsMixin, WebhookTestCase
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
class SendGridWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin):
|
||||
def call_webhook(self):
|
||||
return self.client.post('/anymail/sendgrid/tracking/',
|
||||
@@ -17,6 +19,7 @@ class SendGridWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixi
|
||||
# Actual tests are in WebhookBasicAuthTestsMixin
|
||||
|
||||
|
||||
@tag('sendgrid')
|
||||
class SendGridDeliveryTestCase(WebhookTestCase):
|
||||
|
||||
def test_processed_event(self):
|
||||
|
||||
@@ -10,8 +10,7 @@ from email.mime.image import MIMEImage
|
||||
|
||||
import six
|
||||
from django.core import mail
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
from django.utils.timezone import get_fixed_timezone, override as override_current_timezone
|
||||
|
||||
from anymail.exceptions import (AnymailAPIError, AnymailConfigurationError, AnymailSerializationError,
|
||||
@@ -25,6 +24,7 @@ from .utils import sample_image_content, sample_image_path, SAMPLE_IMAGE_FILENAM
|
||||
longtype = int if six.PY3 else long # NOQA: F821
|
||||
|
||||
|
||||
@tag('sendinblue')
|
||||
@override_settings(EMAIL_BACKEND='anymail.backends.sendinblue.EmailBackend',
|
||||
ANYMAIL={'SENDINBLUE_API_KEY': 'test_api_key'})
|
||||
class SendinBlueBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
@@ -38,6 +38,7 @@ class SendinBlueBackendMockAPITestCase(RequestsBackendMockAPITestCase):
|
||||
self.message = mail.EmailMultiAlternatives('Subject', 'Text Body', 'from@example.com', ['to@example.com'])
|
||||
|
||||
|
||||
@tag('sendinblue')
|
||||
class SendinBlueBackendStandardEmailTests(SendinBlueBackendMockAPITestCase):
|
||||
"""Test backend support for Django standard email features"""
|
||||
|
||||
@@ -274,6 +275,7 @@ class SendinBlueBackendStandardEmailTests(SendinBlueBackendMockAPITestCase):
|
||||
self.message.send()
|
||||
|
||||
|
||||
@tag('sendinblue')
|
||||
class SendinBlueBackendAnymailFeatureTests(SendinBlueBackendMockAPITestCase):
|
||||
"""Test backend support for Anymail added features"""
|
||||
|
||||
@@ -510,6 +512,7 @@ class SendinBlueBackendAnymailFeatureTests(SendinBlueBackendMockAPITestCase):
|
||||
self.assertRegex(str(err), r"Decimal.*is not JSON serializable") # original message
|
||||
|
||||
|
||||
@tag('sendinblue')
|
||||
class SendinBlueBackendRecipientsRefusedTests(SendinBlueBackendMockAPITestCase):
|
||||
"""Should raise AnymailRecipientsRefused when *all* recipients are rejected or invalid"""
|
||||
|
||||
@@ -519,11 +522,13 @@ class SendinBlueBackendRecipientsRefusedTests(SendinBlueBackendMockAPITestCase):
|
||||
pass # not applicable to this backend
|
||||
|
||||
|
||||
@tag('sendinblue')
|
||||
class SendinBlueBackendSessionSharingTestCase(SessionSharingTestCasesMixin, SendinBlueBackendMockAPITestCase):
|
||||
"""Requests session sharing tests"""
|
||||
pass # tests are defined in the mixin
|
||||
|
||||
|
||||
@tag('sendinblue')
|
||||
@override_settings(EMAIL_BACKEND="anymail.backends.sendinblue.EmailBackend")
|
||||
class SendinBlueBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin):
|
||||
"""Test ESP backend without required settings in place"""
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import AnymailAPIError
|
||||
from anymail.message import AnymailMessage
|
||||
|
||||
from .utils import AnymailTestMixin, RUN_LIVE_TESTS
|
||||
from .utils import AnymailTestMixin
|
||||
|
||||
SENDINBLUE_TEST_API_KEY = os.getenv('SENDINBLUE_TEST_API_KEY')
|
||||
|
||||
|
||||
@unittest.skipUnless(RUN_LIVE_TESTS, "RUN_LIVE_TESTS disabled in this environment")
|
||||
@tag('sendinblue', 'live')
|
||||
@unittest.skipUnless(SENDINBLUE_TEST_API_KEY,
|
||||
"Set SENDINBLUE_TEST_API_KEY environment variable "
|
||||
"to run SendinBlue integration tests")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
from django.test import tag
|
||||
from django.utils.timezone import utc
|
||||
from mock import ANY
|
||||
|
||||
@@ -9,6 +10,7 @@ from anymail.webhooks.sendinblue import SendinBlueTrackingWebhookView
|
||||
from .webhook_cases import WebhookBasicAuthTestsMixin, WebhookTestCase
|
||||
|
||||
|
||||
@tag('sendinblue')
|
||||
class SendinBlueWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin):
|
||||
def call_webhook(self):
|
||||
return self.client.post('/anymail/sendinblue/tracking/',
|
||||
@@ -17,6 +19,7 @@ class SendinBlueWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMi
|
||||
# Actual tests are in WebhookBasicAuthTestsMixin
|
||||
|
||||
|
||||
@tag('sendinblue')
|
||||
class SendinBlueDeliveryTestCase(WebhookTestCase):
|
||||
# SendinBlue's webhook payload data doesn't seem to be documented anywhere.
|
||||
# There's a list of webhook events at https://apidocs.sendinblue.com/webhooks/#3.
|
||||
|
||||
@@ -8,11 +8,9 @@ import os
|
||||
import requests
|
||||
import six
|
||||
from django.core import mail
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
from django.utils.timezone import get_fixed_timezone, override as override_current_timezone, utc
|
||||
from mock import patch
|
||||
from sparkpost.exceptions import SparkPostAPIException
|
||||
|
||||
from anymail.exceptions import (AnymailAPIError, AnymailUnsupportedFeature, AnymailRecipientsRefused,
|
||||
AnymailConfigurationError, AnymailInvalidAddress)
|
||||
@@ -21,6 +19,7 @@ from anymail.message import attach_inline_image_file
|
||||
from .utils import AnymailTestMixin, decode_att, SAMPLE_IMAGE_FILENAME, sample_image_path, sample_image_content
|
||||
|
||||
|
||||
@tag('sparkpost')
|
||||
@override_settings(EMAIL_BACKEND='anymail.backends.sparkpost.EmailBackend',
|
||||
ANYMAIL={'SPARKPOST_API_KEY': 'test_api_key'})
|
||||
class SparkPostBackendMockAPITestCase(SimpleTestCase, AnymailTestMixin):
|
||||
@@ -48,6 +47,7 @@ class SparkPostBackendMockAPITestCase(SimpleTestCase, AnymailTestMixin):
|
||||
return self.mock_send.return_value
|
||||
|
||||
def set_mock_failure(self, status_code=400, raw=b'{"errors":[{"message":"test error"}]}', encoding='utf-8'):
|
||||
from sparkpost.exceptions import SparkPostAPIException
|
||||
# Need to build a real(-ish) requests.Response for SparkPostAPIException
|
||||
response = requests.Response()
|
||||
response.status_code = status_code
|
||||
@@ -82,6 +82,7 @@ class SparkPostBackendMockAPITestCase(SimpleTestCase, AnymailTestMixin):
|
||||
raise AssertionError(msg or "ESP API was called and shouldn't have been")
|
||||
|
||||
|
||||
@tag('sparkpost')
|
||||
class SparkPostBackendStandardEmailTests(SparkPostBackendMockAPITestCase):
|
||||
"""Test backend support for Django standard email features"""
|
||||
|
||||
@@ -325,6 +326,7 @@ class SparkPostBackendStandardEmailTests(SparkPostBackendMockAPITestCase):
|
||||
self.message.send()
|
||||
|
||||
|
||||
@tag('sparkpost')
|
||||
class SparkPostBackendAnymailFeatureTests(SparkPostBackendMockAPITestCase):
|
||||
"""Test backend support for Anymail added features"""
|
||||
|
||||
@@ -545,6 +547,7 @@ class SparkPostBackendAnymailFeatureTests(SparkPostBackendMockAPITestCase):
|
||||
# modify those errors.
|
||||
|
||||
|
||||
@tag('sparkpost')
|
||||
class SparkPostBackendRecipientsRefusedTests(SparkPostBackendMockAPITestCase):
|
||||
"""Should raise AnymailRecipientsRefused when *all* recipients are rejected or invalid"""
|
||||
|
||||
@@ -586,6 +589,7 @@ class SparkPostBackendRecipientsRefusedTests(SparkPostBackendMockAPITestCase):
|
||||
self.assertEqual(sent, 1) # refused message is included in sent count
|
||||
|
||||
|
||||
@tag('sparkpost')
|
||||
@override_settings(EMAIL_BACKEND="anymail.backends.sparkpost.EmailBackend")
|
||||
class SparkPostBackendConfigurationTests(SimpleTestCase, AnymailTestMixin):
|
||||
"""Test various SparkPost client options"""
|
||||
|
||||
@@ -2,6 +2,7 @@ import json
|
||||
from base64 import b64encode
|
||||
from textwrap import dedent
|
||||
|
||||
from django.test import tag
|
||||
from mock import ANY
|
||||
|
||||
from anymail.inbound import AnymailInboundMessage
|
||||
@@ -12,6 +13,7 @@ from .utils import sample_image_content, sample_email_content
|
||||
from .webhook_cases import WebhookTestCase
|
||||
|
||||
|
||||
@tag('sparkpost')
|
||||
class SparkpostInboundTestCase(WebhookTestCase):
|
||||
def test_inbound_basics(self):
|
||||
event = {
|
||||
|
||||
@@ -2,18 +2,17 @@ import os
|
||||
import unittest
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.test import SimpleTestCase, override_settings, tag
|
||||
|
||||
from anymail.exceptions import AnymailAPIError
|
||||
from anymail.message import AnymailMessage
|
||||
|
||||
from .utils import AnymailTestMixin, sample_image_path, RUN_LIVE_TESTS
|
||||
from .utils import AnymailTestMixin, sample_image_path
|
||||
|
||||
SPARKPOST_TEST_API_KEY = os.getenv('SPARKPOST_TEST_API_KEY')
|
||||
|
||||
|
||||
@unittest.skipUnless(RUN_LIVE_TESTS, "RUN_LIVE_TESTS disabled in this environment")
|
||||
@tag('sparkpost', 'live')
|
||||
@unittest.skipUnless(SPARKPOST_TEST_API_KEY,
|
||||
"Set SPARKPOST_TEST_API_KEY environment variable "
|
||||
"to run SparkPost integration tests")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
from django.test import tag
|
||||
from django.utils.timezone import utc
|
||||
from mock import ANY
|
||||
|
||||
@@ -10,6 +11,7 @@ from anymail.webhooks.sparkpost import SparkPostTrackingWebhookView
|
||||
from .webhook_cases import WebhookBasicAuthTestsMixin, WebhookTestCase
|
||||
|
||||
|
||||
@tag('sparkpost')
|
||||
class SparkPostWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin):
|
||||
def call_webhook(self):
|
||||
return self.client.post('/anymail/sparkpost/tracking/',
|
||||
@@ -18,6 +20,7 @@ class SparkPostWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMix
|
||||
# Actual tests are in WebhookBasicAuthTestsMixin
|
||||
|
||||
|
||||
@tag('sparkpost')
|
||||
class SparkPostDeliveryTestCase(WebhookTestCase):
|
||||
|
||||
def test_ping_event(self):
|
||||
|
||||
@@ -8,32 +8,12 @@ import uuid
|
||||
import warnings
|
||||
from base64 import b64decode
|
||||
from contextlib import contextmanager
|
||||
from distutils.util import strtobool
|
||||
|
||||
import six
|
||||
from django.test import Client
|
||||
from six.moves import StringIO
|
||||
|
||||
|
||||
def envbool(var, default=False):
|
||||
"""Returns value of environment variable var as a bool, or default if not set.
|
||||
|
||||
Converts `'true'` to `True`, and `'false'` to `False`.
|
||||
See :func:`~distutils.util.strtobool` for full list of allowable values.
|
||||
"""
|
||||
val = os.getenv(var, None)
|
||||
if val is None:
|
||||
return default
|
||||
else:
|
||||
return strtobool(val)
|
||||
|
||||
|
||||
# RUN_LIVE_TESTS: whether to run live API integration tests.
|
||||
# True by default, except in CONTINUOUS_INTEGRATION job.
|
||||
# (See comments and overrides in .travis.yml.)
|
||||
RUN_LIVE_TESTS = envbool('RUN_LIVE_TESTS', default=not envbool('CONTINUOUS_INTEGRATION'))
|
||||
|
||||
|
||||
def decode_att(att):
|
||||
"""Returns the original data from base64-encoded attachment content"""
|
||||
return b64decode(att.encode('ascii'))
|
||||
|
||||
Reference in New Issue
Block a user