mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 11:51:05 -05:00
Tests: break apart tests.py into tests directory
This commit is contained in:
@@ -161,7 +161,7 @@ object, so you can use them with many other apps that add Django mail
|
|||||||
functionality (such as Django template-based messages).
|
functionality (such as Django template-based messages).
|
||||||
|
|
||||||
If you have any questions about the python syntax for any of these properties,
|
If you have any questions about the python syntax for any of these properties,
|
||||||
see ``DjrillMandrillFeatureTests`` in tests.py for examples.
|
see ``DjrillMandrillFeatureTests`` in tests/test_mandrill_send.py for examples.
|
||||||
|
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
@@ -180,11 +180,11 @@ calls, without actually calling Mandrill or sending any email. So the tests
|
|||||||
don't require a Mandrill API key, but they *do* require mock_
|
don't require a Mandrill API key, but they *do* require mock_
|
||||||
(``pip install mock``). To run the tests, either::
|
(``pip install mock``). To run the tests, either::
|
||||||
|
|
||||||
python setup.py test
|
python -Wall setup.py test
|
||||||
|
|
||||||
or::
|
or::
|
||||||
|
|
||||||
python runtests.py
|
python -Wall runtests.py
|
||||||
|
|
||||||
|
|
||||||
Release Notes
|
Release Notes
|
||||||
|
|||||||
3
djrill/tests/__init__.py
Normal file
3
djrill/tests/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from test_admin import *
|
||||||
|
from test_legacy import *
|
||||||
|
from test_mandrill_send import *
|
||||||
44
djrill/tests/mock_backend.py
Normal file
44
djrill/tests/mock_backend.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
from mock import patch
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.utils import simplejson as json
|
||||||
|
|
||||||
|
class DjrillBackendMockAPITestCase(TestCase):
|
||||||
|
"""TestCase that uses Djrill EmailBackend with a mocked Mandrill API"""
|
||||||
|
|
||||||
|
class MockResponse:
|
||||||
|
"""requests.post return value mock sufficient for DjrillBackend"""
|
||||||
|
def __init__(self, status_code=200, content="{}"):
|
||||||
|
self.status_code = status_code
|
||||||
|
self.content = content
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.patch = patch('requests.post')
|
||||||
|
self.mock_post = self.patch.start()
|
||||||
|
self.mock_post.return_value = self.MockResponse()
|
||||||
|
|
||||||
|
settings.MANDRILL_API_KEY = "FAKE_API_KEY_FOR_TESTING"
|
||||||
|
|
||||||
|
# Django TestCase sets up locmem EmailBackend; override it here
|
||||||
|
self.original_email_backend = settings.EMAIL_BACKEND
|
||||||
|
settings.EMAIL_BACKEND = "djrill.mail.backends.djrill.DjrillBackend"
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.patch.stop()
|
||||||
|
settings.EMAIL_BACKEND = self.original_email_backend
|
||||||
|
|
||||||
|
def get_api_call_data(self):
|
||||||
|
"""Returns the data posted to the Mandrill API.
|
||||||
|
|
||||||
|
Fails test if API wasn't called.
|
||||||
|
"""
|
||||||
|
if self.mock_post.call_args is None:
|
||||||
|
raise AssertionError("Mandrill API was not called")
|
||||||
|
(args, kwargs) = self.mock_post.call_args
|
||||||
|
if 'data' not in kwargs:
|
||||||
|
raise AssertionError("requests.post was called without data kwarg "
|
||||||
|
"-- Maybe tests need to be updated for backend changes?")
|
||||||
|
return json.loads(kwargs['data'])
|
||||||
|
|
||||||
|
|
||||||
72
djrill/tests/test_admin.py
Normal file
72
djrill/tests/test_admin.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from djrill.tests.mock_backend import DjrillBackendMockAPITestCase
|
||||||
|
|
||||||
|
|
||||||
|
def reset_admin_site():
|
||||||
|
"""Return the Django admin globals to their original state"""
|
||||||
|
admin.site = admin.AdminSite() # restore default
|
||||||
|
if 'djrill.admin' in sys.modules:
|
||||||
|
del sys.modules['djrill.admin'] # force autodiscover to re-import
|
||||||
|
|
||||||
|
|
||||||
|
class DjrillAdminTests(DjrillBackendMockAPITestCase):
|
||||||
|
"""Test the Djrill admin site"""
|
||||||
|
|
||||||
|
# These tests currently just verify that the admin site pages load
|
||||||
|
# without error -- they don't test any Mandrill-supplied content.
|
||||||
|
# (Future improvements could mock the Mandrill responses.)
|
||||||
|
|
||||||
|
# These urls set up the DjrillAdminSite as suggested in the readme
|
||||||
|
urls = 'djrill.tests.admin_urls'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
# Other test cases may muck with the Django admin site globals,
|
||||||
|
# so return it to the default state before loading test_admin_urls
|
||||||
|
reset_admin_site()
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(DjrillAdminTests, self).setUp()
|
||||||
|
# Must be authenticated staff to access admin site...
|
||||||
|
admin = User.objects.create_user('admin', 'admin@example.com', 'secret')
|
||||||
|
admin.is_staff = True
|
||||||
|
admin.save()
|
||||||
|
self.client.login(username='admin', password='secret')
|
||||||
|
|
||||||
|
def test_admin_senders(self):
|
||||||
|
response = self.client.get('/admin/djrill/senders/')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertContains(response, "Senders")
|
||||||
|
|
||||||
|
def test_admin_status(self):
|
||||||
|
response = self.client.get('/admin/djrill/status/')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertContains(response, "Status")
|
||||||
|
|
||||||
|
def test_admin_tags(self):
|
||||||
|
response = self.client.get('/admin/djrill/tags/')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertContains(response, "Tags")
|
||||||
|
|
||||||
|
def test_admin_urls(self):
|
||||||
|
response = self.client.get('/admin/djrill/urls/')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertContains(response, "URLs")
|
||||||
|
|
||||||
|
def test_admin_index(self):
|
||||||
|
"""Make sure Djrill section is included in the admin index page"""
|
||||||
|
response = self.client.get('/admin/')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertContains(response, "Djrill")
|
||||||
|
|
||||||
|
|
||||||
|
class DjrillNoAdminTests(TestCase):
|
||||||
|
def test_admin_autodiscover_without_djrill(self):
|
||||||
|
"""Make sure autodiscover doesn't die without DjrillAdminSite"""
|
||||||
|
reset_admin_site()
|
||||||
|
admin.autodiscover() # test: this shouldn't error
|
||||||
74
djrill/tests/test_legacy.py
Normal file
74
djrill/tests/test_legacy.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# Tests deprecated Djrill features
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from djrill.mail import DjrillMessage
|
||||||
|
|
||||||
|
|
||||||
|
class DjrillMessageTests(TestCase):
|
||||||
|
"""Test the DjrillMessage class (deprecated as of Djrill v0.2.0)
|
||||||
|
|
||||||
|
Maintained for compatibility with older code.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.subject = "Djrill baby djrill."
|
||||||
|
self.from_name = "Tarzan"
|
||||||
|
self.from_email = "test@example"
|
||||||
|
self.to = ["King Kong <kingkong@example.com>",
|
||||||
|
"Cheetah <cheetah@example.com", "bubbles@example.com"]
|
||||||
|
self.text_content = "Wonderful fallback text content."
|
||||||
|
self.html_content = "<h1>That's a nice HTML email right there.</h1>"
|
||||||
|
self.headers = {"Reply-To": "tarzan@example.com"}
|
||||||
|
self.tags = ["track", "this"]
|
||||||
|
|
||||||
|
def test_djrill_message_success(self):
|
||||||
|
msg = DjrillMessage(self.subject, self.text_content, self.from_email,
|
||||||
|
self.to, tags=self.tags, headers=self.headers,
|
||||||
|
from_name=self.from_name)
|
||||||
|
|
||||||
|
self.assertIsInstance(msg, DjrillMessage)
|
||||||
|
self.assertEqual(msg.body, self.text_content)
|
||||||
|
self.assertEqual(msg.recipients(), self.to)
|
||||||
|
self.assertEqual(msg.tags, self.tags)
|
||||||
|
self.assertEqual(msg.extra_headers, self.headers)
|
||||||
|
self.assertEqual(msg.from_name, self.from_name)
|
||||||
|
|
||||||
|
def test_djrill_message_html_success(self):
|
||||||
|
msg = DjrillMessage(self.subject, self.text_content, self.from_email,
|
||||||
|
self.to, tags=self.tags)
|
||||||
|
msg.attach_alternative(self.html_content, "text/html")
|
||||||
|
|
||||||
|
self.assertEqual(msg.alternatives[0][0], self.html_content)
|
||||||
|
|
||||||
|
def test_djrill_message_tag_failure(self):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
DjrillMessage(self.subject, self.text_content, self.from_email,
|
||||||
|
self.to, tags=["_fail"])
|
||||||
|
|
||||||
|
def test_djrill_message_tag_skip(self):
|
||||||
|
"""
|
||||||
|
Test that tags over 50 chars are not included in the tags list.
|
||||||
|
"""
|
||||||
|
tags = ["works", "awesomesauce",
|
||||||
|
"iwilltestmycodeiwilltestmycodeiwilltestmycodeiwilltestmycode"]
|
||||||
|
msg = DjrillMessage(self.subject, self.text_content, self.from_email,
|
||||||
|
self.to, tags=tags)
|
||||||
|
|
||||||
|
self.assertIsInstance(msg, DjrillMessage)
|
||||||
|
self.assertIn(tags[0], msg.tags)
|
||||||
|
self.assertIn(tags[1], msg.tags)
|
||||||
|
self.assertNotIn(tags[2], msg.tags)
|
||||||
|
|
||||||
|
def test_djrill_message_no_options(self):
|
||||||
|
"""DjrillMessage with only basic EmailMessage options should work"""
|
||||||
|
msg = DjrillMessage(self.subject, self.text_content,
|
||||||
|
self.from_email, self.to) # no Mandrill-specific options
|
||||||
|
|
||||||
|
self.assertIsInstance(msg, DjrillMessage)
|
||||||
|
self.assertEqual(msg.body, self.text_content)
|
||||||
|
self.assertEqual(msg.recipients(), self.to)
|
||||||
|
self.assertFalse(hasattr(msg, 'tags'))
|
||||||
|
self.assertFalse(hasattr(msg, 'from_name'))
|
||||||
|
self.assertFalse(hasattr(msg, 'preserve_recipients'))
|
||||||
@@ -1,58 +1,13 @@
|
|||||||
from mock import patch
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import admin
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.test import TestCase
|
|
||||||
from django.utils import simplejson as json
|
|
||||||
|
|
||||||
from djrill.mail import DjrillMessage
|
|
||||||
from djrill.mail.backends.djrill import DjrillBackendHTTPError
|
from djrill.mail.backends.djrill import DjrillBackendHTTPError
|
||||||
|
from djrill.tests.mock_backend import DjrillBackendMockAPITestCase
|
||||||
|
|
||||||
class DjrillBackendMockAPITestCase(TestCase):
|
|
||||||
"""TestCase that uses Djrill EmailBackend with a mocked Mandrill API"""
|
|
||||||
|
|
||||||
class MockResponse:
|
|
||||||
"""requests.post return value mock sufficient for DjrillBackend"""
|
|
||||||
def __init__(self, status_code=200, content="{}"):
|
|
||||||
self.status_code = status_code
|
|
||||||
self.content = content
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.patch = patch('requests.post')
|
|
||||||
self.mock_post = self.patch.start()
|
|
||||||
self.mock_post.return_value = self.MockResponse()
|
|
||||||
|
|
||||||
settings.MANDRILL_API_KEY = "FAKE_API_KEY_FOR_TESTING"
|
|
||||||
|
|
||||||
# Django TestCase sets up locmem EmailBackend; override it here
|
|
||||||
self.original_email_backend = settings.EMAIL_BACKEND
|
|
||||||
settings.EMAIL_BACKEND = "djrill.mail.backends.djrill.DjrillBackend"
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.patch.stop()
|
|
||||||
settings.EMAIL_BACKEND = self.original_email_backend
|
|
||||||
|
|
||||||
def get_api_call_data(self):
|
|
||||||
"""Returns the data posted to the Mandrill API.
|
|
||||||
|
|
||||||
Fails test if API wasn't called.
|
|
||||||
"""
|
|
||||||
if self.mock_post.call_args is None:
|
|
||||||
raise AssertionError("Mandrill API was not called")
|
|
||||||
(args, kwargs) = self.mock_post.call_args
|
|
||||||
if 'data' not in kwargs:
|
|
||||||
raise AssertionError("requests.post was called without data kwarg "
|
|
||||||
"-- Maybe tests need to be updated for backend changes?")
|
|
||||||
return json.loads(kwargs['data'])
|
|
||||||
|
|
||||||
|
|
||||||
class DjrillBackendTests(DjrillBackendMockAPITestCase):
|
class DjrillBackendTests(DjrillBackendMockAPITestCase):
|
||||||
"""Test Djrill's support for Django mail wrappers"""
|
"""Test Djrill backend support for Django mail wrappers"""
|
||||||
|
|
||||||
def test_send_mail(self):
|
def test_send_mail(self):
|
||||||
mail.send_mail('Subject here', 'Here is the message.',
|
mail.send_mail('Subject here', 'Here is the message.',
|
||||||
@@ -222,7 +177,7 @@ class DjrillMandrillFeatureTests(DjrillBackendMockAPITestCase):
|
|||||||
"customer@example.com": { 'GREETING': "Dear Customer",
|
"customer@example.com": { 'GREETING': "Dear Customer",
|
||||||
'ACCOUNT_TYPE': "Premium" },
|
'ACCOUNT_TYPE': "Premium" },
|
||||||
"guest@example.com": { 'GREETING': "Dear Guest" },
|
"guest@example.com": { 'GREETING': "Dear Guest" },
|
||||||
}
|
}
|
||||||
self.message.send()
|
self.message.send()
|
||||||
data = self.get_api_call_data()
|
data = self.get_api_call_data()
|
||||||
self.assertEqual(data['message']['global_merge_vars'],
|
self.assertEqual(data['message']['global_merge_vars'],
|
||||||
@@ -295,129 +250,3 @@ class DjrillMandrillFeatureTests(DjrillBackendMockAPITestCase):
|
|||||||
self.assertFalse('recipient_metadata' in data['message'])
|
self.assertFalse('recipient_metadata' in data['message'])
|
||||||
|
|
||||||
|
|
||||||
def reset_admin_site():
|
|
||||||
"""Return the Django admin globals to their original state"""
|
|
||||||
admin.site = admin.AdminSite() # restore default
|
|
||||||
if 'djrill.admin' in sys.modules:
|
|
||||||
del sys.modules['djrill.admin'] # force autodiscover to re-import
|
|
||||||
|
|
||||||
|
|
||||||
class DjrillAdminTests(DjrillBackendMockAPITestCase):
|
|
||||||
"""Test the Djrill admin site"""
|
|
||||||
|
|
||||||
# These tests currently just verify that the admin site pages load
|
|
||||||
# without error -- they don't test any Mandrill-supplied content.
|
|
||||||
# (Future improvements could mock the Mandrill responses.)
|
|
||||||
|
|
||||||
# These urls set up the DjrillAdminSite as suggested in the readme
|
|
||||||
urls = 'djrill.test_admin_urls'
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
# Other test cases may muck with the Django admin site globals,
|
|
||||||
# so return it to the default state before loading test_admin_urls
|
|
||||||
reset_admin_site()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(DjrillAdminTests, self).setUp()
|
|
||||||
# Must be authenticated staff to access admin site...
|
|
||||||
admin = User.objects.create_user('admin', 'admin@example.com', 'secret')
|
|
||||||
admin.is_staff = True
|
|
||||||
admin.save()
|
|
||||||
self.client.login(username='admin', password='secret')
|
|
||||||
|
|
||||||
def test_admin_senders(self):
|
|
||||||
response = self.client.get('/admin/djrill/senders/')
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
self.assertContains(response, "Senders")
|
|
||||||
|
|
||||||
def test_admin_status(self):
|
|
||||||
response = self.client.get('/admin/djrill/status/')
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
self.assertContains(response, "Status")
|
|
||||||
|
|
||||||
def test_admin_tags(self):
|
|
||||||
response = self.client.get('/admin/djrill/tags/')
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
self.assertContains(response, "Tags")
|
|
||||||
|
|
||||||
def test_admin_urls(self):
|
|
||||||
response = self.client.get('/admin/djrill/urls/')
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
self.assertContains(response, "URLs")
|
|
||||||
|
|
||||||
def test_admin_index(self):
|
|
||||||
"""Make sure Djrill section is included in the admin index page"""
|
|
||||||
response = self.client.get('/admin/')
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
self.assertContains(response, "Djrill")
|
|
||||||
|
|
||||||
|
|
||||||
class DjrillNoAdminTests(TestCase):
|
|
||||||
def test_admin_autodiscover_without_djrill(self):
|
|
||||||
"""Make sure autodiscover doesn't die without DjrillAdminSite"""
|
|
||||||
reset_admin_site()
|
|
||||||
admin.autodiscover() # test: this shouldn't error
|
|
||||||
|
|
||||||
|
|
||||||
class DjrillMessageTests(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.subject = "Djrill baby djrill."
|
|
||||||
self.from_name = "Tarzan"
|
|
||||||
self.from_email = "test@example"
|
|
||||||
self.to = ["King Kong <kingkong@example.com>",
|
|
||||||
"Cheetah <cheetah@example.com", "bubbles@example.com"]
|
|
||||||
self.text_content = "Wonderful fallback text content."
|
|
||||||
self.html_content = "<h1>That's a nice HTML email right there.</h1>"
|
|
||||||
self.headers = {"Reply-To": "tarzan@example.com"}
|
|
||||||
self.tags = ["track", "this"]
|
|
||||||
|
|
||||||
def test_djrill_message_success(self):
|
|
||||||
msg = DjrillMessage(self.subject, self.text_content, self.from_email,
|
|
||||||
self.to, tags=self.tags, headers=self.headers,
|
|
||||||
from_name=self.from_name)
|
|
||||||
|
|
||||||
self.assertIsInstance(msg, DjrillMessage)
|
|
||||||
self.assertEqual(msg.body, self.text_content)
|
|
||||||
self.assertEqual(msg.recipients(), self.to)
|
|
||||||
self.assertEqual(msg.tags, self.tags)
|
|
||||||
self.assertEqual(msg.extra_headers, self.headers)
|
|
||||||
self.assertEqual(msg.from_name, self.from_name)
|
|
||||||
|
|
||||||
def test_djrill_message_html_success(self):
|
|
||||||
msg = DjrillMessage(self.subject, self.text_content, self.from_email,
|
|
||||||
self.to, tags=self.tags)
|
|
||||||
msg.attach_alternative(self.html_content, "text/html")
|
|
||||||
|
|
||||||
self.assertEqual(msg.alternatives[0][0], self.html_content)
|
|
||||||
|
|
||||||
def test_djrill_message_tag_failure(self):
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
DjrillMessage(self.subject, self.text_content, self.from_email,
|
|
||||||
self.to, tags=["_fail"])
|
|
||||||
|
|
||||||
def test_djrill_message_tag_skip(self):
|
|
||||||
"""
|
|
||||||
Test that tags over 50 chars are not included in the tags list.
|
|
||||||
"""
|
|
||||||
tags = ["works", "awesomesauce",
|
|
||||||
"iwilltestmycodeiwilltestmycodeiwilltestmycodeiwilltestmycode"]
|
|
||||||
msg = DjrillMessage(self.subject, self.text_content, self.from_email,
|
|
||||||
self.to, tags=tags)
|
|
||||||
|
|
||||||
self.assertIsInstance(msg, DjrillMessage)
|
|
||||||
self.assertIn(tags[0], msg.tags)
|
|
||||||
self.assertIn(tags[1], msg.tags)
|
|
||||||
self.assertNotIn(tags[2], msg.tags)
|
|
||||||
|
|
||||||
def test_djrill_message_no_options(self):
|
|
||||||
"""DjrillMessage with only basic EmailMessage options should work"""
|
|
||||||
msg = DjrillMessage(self.subject, self.text_content,
|
|
||||||
self.from_email, self.to) # no Mandrill-specific options
|
|
||||||
|
|
||||||
self.assertIsInstance(msg, DjrillMessage)
|
|
||||||
self.assertEqual(msg.body, self.text_content)
|
|
||||||
self.assertEqual(msg.recipients(), self.to)
|
|
||||||
self.assertFalse(hasattr(msg, 'tags'))
|
|
||||||
self.assertFalse(hasattr(msg, 'from_name'))
|
|
||||||
self.assertFalse(hasattr(msg, 'preserve_recipients'))
|
|
||||||
Reference in New Issue
Block a user