Skip to content

Commit be9045a

Browse files
committed
Multiple API changes
Add template_name parameter to BaseEmailMessage constructor Add context tests Add mock for python 2.7 to tox dependencies Update set_context_data into get_context_data Update render to be invoked on send Update tests for API changes
1 parent 95313c1 commit be9045a

File tree

3 files changed

+121
-29
lines changed

3 files changed

+121
-29
lines changed

templated_mail/mail.py

+36-13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from copy import deepcopy
2+
13
from django.contrib.sites.shortcuts import get_current_site
24
from django.core import mail
35
from django.template.context import make_context
@@ -14,36 +16,57 @@ class BaseEmailMessage(mail.EmailMultiAlternatives):
1416
}
1517
template_name = None
1618

17-
def __init__(self, request, context=None, *args, **kwargs):
19+
def __init__(self, request=None, context=None, template_name=None,
20+
*args, **kwargs):
1821
super(BaseEmailMessage, self).__init__(*args, **kwargs)
1922

2023
self.request = request
2124
self.context = {} if context is None else context
2225
self.html = None
2326

24-
if request is not None:
25-
self.set_context_data()
26-
self.render()
27+
if template_name is not None:
28+
self.template_name = template_name
2729

28-
def set_context_data(self):
29-
site = get_current_site(self.request)
30-
self.context.update({
31-
'domain': getattr(settings, 'DOMAIN', '') or site.domain,
32-
'protocol': self.context.get('protocol') or (
33-
'https' if self.request.is_secure() else 'http'),
34-
'site_name': getattr(settings, 'SITE_NAME', '') or site.name,
35-
'user': self.context.get('user') or self.request.user,
30+
def get_context_data(self):
31+
context = deepcopy(self.context)
32+
if self.request:
33+
site = get_current_site(self.request)
34+
domain = context.get('domain') or (
35+
getattr(settings, 'DOMAIN', '') or site.domain
36+
)
37+
protocol = context.get('protocol') or (
38+
'https' if self.request.is_secure() else 'http'
39+
)
40+
site_name = context.get('site_name') or (
41+
getattr(settings, 'SITE_NAME', '') or site.name
42+
)
43+
user = context.get('user') or self.request.user
44+
else:
45+
domain = context.get('domain') or getattr(settings, 'DOMAIN', '')
46+
protocol = context.get('protocol') or 'http'
47+
site_name = context.get('site_name') or getattr(
48+
settings, 'SITE_NAME', ''
49+
)
50+
user = context.get('user')
51+
52+
context.update({
53+
'domain': domain,
54+
'protocol': protocol,
55+
'site_name': site_name,
56+
'user': user
3657
})
58+
return context
3759

3860
def render(self):
39-
context = make_context(self.context, request=self.request)
61+
context = make_context(self.get_context_data(), request=self.request)
4062
template = get_template(self.template_name)
4163
with context.bind_template(template.template):
4264
for node in template.template.nodelist:
4365
self._process_node(node, context)
4466
self._attach_body()
4567

4668
def send(self, to, cc=None, bcc=None, *args, **kwargs):
69+
self.render()
4770
self.to = to
4871
if cc:
4972
self.cc = cc

tests/test_mail.py

+84-16
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,83 @@
1+
from unittest import mock
2+
13
from django.contrib.auth.models import AnonymousUser
4+
from django.contrib.sites.shortcuts import get_current_site
25
from django.core import mail
36
from django.test import RequestFactory, TestCase
47

58
from templated_mail.mail import BaseEmailMessage
69

710

8-
class EmailMessage(BaseEmailMessage):
9-
pass
10-
11-
1211
class TestBaseEmailMessage(TestCase):
1312
def setUp(self):
1413
self.factory = RequestFactory()
1514
self.recipients = ['foo@bar.tld']
1615

16+
@mock.patch('django.core.handlers.wsgi.WSGIRequest.is_secure')
17+
def test_get_context_data_with_insecure_request(self, is_secure_mock):
18+
is_secure_mock.return_value = False
19+
20+
request = self.factory.get('/')
21+
request.user = AnonymousUser()
22+
23+
email_message = BaseEmailMessage(
24+
request=request, template_name='text_mail.html'
25+
)
26+
context = email_message.get_context_data()
27+
site = get_current_site(request)
28+
29+
self.assertEquals(context['domain'], site.domain)
30+
self.assertEquals(context['protocol'], 'http')
31+
self.assertEquals(context['site_name'], site.name)
32+
self.assertEquals(context['user'], request.user)
33+
34+
@mock.patch('django.core.handlers.wsgi.WSGIRequest.is_secure')
35+
def test_get_context_data_with_secure_request(self, is_secure_mock):
36+
is_secure_mock.return_value = True
37+
38+
request = self.factory.get('/')
39+
request.user = AnonymousUser()
40+
41+
email_message = BaseEmailMessage(
42+
request=request, template_name='text_mail.html'
43+
)
44+
context = email_message.get_context_data()
45+
site = get_current_site(request)
46+
47+
self.assertEquals(context['domain'], site.domain)
48+
self.assertEquals(context['protocol'], 'https')
49+
self.assertEquals(context['site_name'], site.name)
50+
self.assertEquals(context['user'], request.user)
51+
52+
def test_get_context_data_without_request_no_context(self):
53+
email_message = BaseEmailMessage(template_name='text_mail.html')
54+
context = email_message.get_context_data()
55+
56+
self.assertEquals(context['domain'], '')
57+
self.assertEquals(context['protocol'], 'http')
58+
self.assertEquals(context['site_name'], '')
59+
self.assertEquals(context['user'], None)
60+
61+
def test_get_context_data_without_request_user_context(self):
62+
user = AnonymousUser()
63+
email_message = BaseEmailMessage(
64+
context={'user': user}, template_name='text_mail.html'
65+
)
66+
context = email_message.get_context_data()
67+
68+
self.assertEquals(context['domain'], '')
69+
self.assertEquals(context['protocol'], 'http')
70+
self.assertEquals(context['site_name'], '')
71+
self.assertEquals(context['user'], user)
72+
1773
def test_text_mail_contains_valid_data(self):
1874
request = self.factory.get('/')
1975
request.user = AnonymousUser()
2076

21-
EmailMessage.template_name = 'text_mail.html'
22-
EmailMessage(request=request).send(to=self.recipients)
77+
BaseEmailMessage(
78+
request=request, template_name='text_mail.html'
79+
).send(to=self.recipients)
80+
2381
self.assertEqual(len(mail.outbox), 1)
2482
self.assertEqual(mail.outbox[0].recipients(), self.recipients)
2583
self.assertEqual(mail.outbox[0].subject, 'Text mail subject')
@@ -31,8 +89,10 @@ def test_html_mail_contains_valid_data(self):
3189
request = self.factory.get('/')
3290
request.user = AnonymousUser()
3391

34-
EmailMessage.template_name = 'html_mail.html'
35-
EmailMessage(request=request).send(to=self.recipients)
92+
BaseEmailMessage(
93+
request=request, template_name='html_mail.html'
94+
).send(to=self.recipients)
95+
3696
self.assertEqual(len(mail.outbox), 1)
3797
self.assertEqual(mail.outbox[0].recipients(), self.recipients)
3898
self.assertEqual(mail.outbox[0].subject, 'HTML mail subject')
@@ -44,8 +104,10 @@ def test_text_and_html_mail_contains_valid_data(self):
44104
request = self.factory.get('/')
45105
request.user = AnonymousUser()
46106

47-
EmailMessage.template_name = 'text_and_html_mail.html'
48-
EmailMessage(request=request).send(to=self.recipients)
107+
BaseEmailMessage(
108+
request=request, template_name='text_and_html_mail.html'
109+
).send(to=self.recipients)
110+
49111
self.assertEqual(len(mail.outbox), 1)
50112
self.assertEqual(mail.outbox[0].recipients(), self.recipients)
51113
self.assertEqual(mail.outbox[0].subject, 'Text and HTML mail subject')
@@ -57,8 +119,10 @@ def test_text_and_html_mail_contains_valid_data(self):
57119
self.assertEqual(mail.outbox[0].content_subtype, 'plain')
58120

59121
def test_can_send_mail_with_none_request(self):
60-
EmailMessage.template_name = 'text_mail.html'
61-
EmailMessage(request=None).send(to=self.recipients)
122+
BaseEmailMessage(
123+
request=None, template_name='text_mail.html'
124+
).send(to=self.recipients)
125+
62126
self.assertEqual(len(mail.outbox), 1)
63127
self.assertEqual(mail.outbox[0].recipients(), self.recipients)
64128
self.assertEqual(mail.outbox[0].subject, 'Text mail subject')
@@ -72,8 +136,10 @@ def test_mail_cc_is_sent_to_valid_cc(self):
72136

73137
cc = ['email@example.tld']
74138

75-
EmailMessage.template_name = 'text_mail.html'
76-
EmailMessage(request=request).send(to=self.recipients, cc=cc)
139+
BaseEmailMessage(
140+
request=request, template_name='text_mail.html'
141+
).send(to=self.recipients, cc=cc)
142+
77143
self.assertEqual(len(mail.outbox), 1)
78144
self.assertEqual(mail.outbox[0].to, self.recipients)
79145
self.assertEqual(mail.outbox[0].cc, cc)
@@ -88,8 +154,10 @@ def test_mail_bcc_is_sent_to_valid_bcc(self):
88154

89155
bcc = ['email@example.tld']
90156

91-
EmailMessage.template_name = 'text_mail.html'
92-
EmailMessage(request=request).send(to=self.recipients, bcc=bcc)
157+
BaseEmailMessage(
158+
request=request, template_name='text_mail.html'
159+
).send(to=self.recipients, bcc=bcc)
160+
93161
self.assertEqual(len(mail.outbox), 1)
94162
self.assertEqual(mail.outbox[0].to, self.recipients)
95163
self.assertEqual(mail.outbox[0].bcc, bcc)

tox.ini

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ deps =
3232
django110: django>=1.10,<1.11
3333
django111: django>=1.11,<2.0
3434
djangomaster: git+git://github.com/django/django.git
35+
py27: mock
3536
-rrequirements/test
3637
commands =
3738
py.test --ds=tests.settings --capture=no --cov-report term-missing --cov-report html --cov=templated_mail tests

0 commit comments

Comments
 (0)