Skip to content

Commit 14de687

Browse files
committed
Add regression tests (and accompanying test mode) for utils.mail.
Fixes ietf-tools#538 - Legacy-Id: 2639
1 parent 16959bd commit 14de687

4 files changed

Lines changed: 121 additions & 6 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
template {{ value }} rendered with a good {{ thing }}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
you can have
2+
{{ unsafe|safe }}
3+
in your context

fenner/ietf/utils/mail.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@
1414
import sys
1515
import time
1616

17+
# Testing mode:
18+
# import ietf.utils.mail
19+
# ietf.utils.mail.test_mode = True
20+
# ... send some mail ...
21+
# ... inspect ietf.utils.mail.outbox ...
22+
# ... call ietf.utils.mail.empty_outbox() ...
23+
test_mode=False
24+
outbox=[]
25+
26+
def empty_outbox():
27+
global outbox
28+
outbox = []
29+
1730
def add_headers(msg):
1831
if not(msg.has_key('Message-ID')):
1932
msg['Message-ID'] = make_msgid('idtracker')
@@ -29,13 +42,19 @@ def send_smtp(msg, bcc=None):
2942
The destination list will be taken from the To:/Cc: headers in the
3043
Message. The From address will be used if present or will default
3144
to the django setting DEFAULT_FROM_EMAIL
45+
46+
If someone has set test_mode=True, then just append the msg to
47+
the outbox.
3248
'''
3349
add_headers(msg)
3450
(fname, frm) = parseaddr(msg.get('From'))
3551
addrlist = msg.get_all('To') + msg.get_all('Cc', [])
3652
if bcc:
3753
addrlist += [bcc]
3854
to = [addr for name, addr in getaddresses(addrlist)]
55+
if test_mode:
56+
outbox.append((msg, to, msg.as_string()))
57+
return
3958
server = None
4059
try:
4160
server = smtplib.SMTP()
@@ -73,9 +92,6 @@ def copy_email(msg, to, toUser=False):
7392
Send a copy of the given email message to the given recipient.
7493
'''
7594
add_headers(msg)
76-
# Overwrite the From: header, so that the copy from a development or
77-
# test server doesn't look like spam.
78-
msg['From'] = settings.DEFAULT_FROM_EMAIL
7995
new = MIMEMultipart()
8096
# get info for first part.
8197
# Mode: if it's production, then "copy of a message", otherwise
@@ -91,7 +107,9 @@ def copy_email(msg, to, toUser=False):
91107
explanation = "The attached message would have been sent, but the tracker is in %s mode.\nIt was not sent to anybody." % settings.SERVER_MODE
92108
new.attach(MIMEText(explanation + "\n\n"))
93109
new.attach(MIMEMessage(msg))
94-
new['From'] = msg['From']
110+
# Overwrite the From: header, so that the copy from a development or
111+
# test server doesn't look like spam.
112+
new['From'] = settings.DEFAULT_FROM_EMAIL
95113
new['Subject'] = '[Django %s] %s' % (settings.SERVER_MODE, msg.get('Subject', '[no subject]'))
96114
new['To'] = to
97115
send_smtp(new)
@@ -128,7 +146,7 @@ def send_mail_text(request, to, frm, subject, txt, cc=None, extra=None, toUser=N
128146
else:
129147
msg = MIMEText(txt)
130148

131-
send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=None, bcc=None)
149+
send_mail_mime(request, to, frm, subject, msg, cc, extra, toUser, bcc)
132150

133151
def send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=None, bcc=None):
134152
"""Send MIME message with content already filled in."""
@@ -148,7 +166,7 @@ def send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=N
148166
if extra:
149167
for k, v in extra.iteritems():
150168
msg[k] = v
151-
if settings.SERVER_MODE == 'production':
169+
if test_mode or settings.SERVER_MODE == 'production':
152170
send_smtp(msg, bcc)
153171
elif settings.SERVER_MODE == 'test':
154172
if toUser:

fenner/ietf/utils/tests.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env python
2+
# Copyright The IETF Trust 2010, All Rights Reserved
3+
4+
import unittest
5+
import mail
6+
from django.conf import settings
7+
8+
mail.test_mode = True
9+
10+
class MailDestinationTest(unittest.TestCase):
11+
def testSendMailText(self):
12+
mail.empty_outbox()
13+
mail.send_mail_text(None, [ 'a', 'b' ], None, 'Subject', 'body', cc=[ 'c', 'd' ],
14+
extra={ 'Extra1': 'Value1', 'Extra2': 'Value2' }, toUser=False,
15+
bcc='e')
16+
(result, to, txt) = mail.outbox[ 0 ]
17+
# add_headers must have added what we needed:
18+
self.assertNotEquals( result[ 'Message-ID' ], None )
19+
self.assertNotEquals( result[ 'Date' ], None )
20+
self.assertEquals( result[ 'From' ], settings.DEFAULT_FROM_EMAIL )
21+
# The arguments should have come through
22+
self.assertEquals( result[ 'To' ], 'a, b' )
23+
self.assertEquals( result[ 'Subject' ], 'Subject' )
24+
self.assertEquals( result[ 'Cc' ], 'c, d' )
25+
self.assertEquals( result[ 'Extra1' ], 'Value1' )
26+
self.assertEquals( result[ 'Extra2' ], 'Value2' )
27+
self.assertTrue( txt.endswith( 'body' ) )
28+
# make sure that Bcc worked
29+
self.assertTrue( 'e' in to )
30+
31+
# Also test that archiving is done.
32+
self.assertTrue( len( mail.outbox ) == 2 )
33+
(archive, to, txt) = mail.outbox[ 1 ]
34+
self.assertEquals( archive[ 'Subject' ], '[Django development] Subject' )
35+
36+
mail.empty_outbox()
37+
# Another test, just testing that a well-formed "From:" makes it through.
38+
test_from = "The person the email is from <person@email.exmaple.com>"
39+
mail.send_mail_text(None, [ 'a' ], test_from, 'Subject', 'body')
40+
(result, to, txt) = mail.outbox[ 0 ]
41+
self.assertEqual( result[ 'From' ], test_from )
42+
43+
mail.empty_outbox()
44+
# This should be the same result due to formataddr
45+
# Also check the use of formataddr in the To header.
46+
mail.send_mail_text(None, [ ('a', 'a@a.example.com'), 'b <b@b.example.com>' ], ( 'The person the email is from', 'person@email.exmaple.com' ), 'Subject', 'body', cc=[ 'd@d.example.com', ('e', 'e@e.example.com' ) ])
47+
(result, to, txt) = mail.outbox[ 0 ]
48+
self.assertEqual( result[ 'From' ], test_from )
49+
self.assertEqual( result[ 'To' ], 'a <a@a.example.com>, b <b@b.example.com>' )
50+
self.assertEqual( result[ 'Cc' ], 'd@d.example.com, e <e@e.example.com>' )
51+
self.assertEqual( to, [ 'a@a.example.com', 'b@b.example.com', 'd@d.example.com', 'e@e.example.com' ] )
52+
53+
def testSendMailSubj( self ):
54+
mail.empty_outbox()
55+
mail.send_mail_subj( None, 'a@a.example.com', None,
56+
'test/mail_subject.txt', 'test/mail_body.txt',
57+
{ 'value': 'one', 'thing': 'two',
58+
'unsafe': '<>&'} )
59+
(result, to, txt) = mail.outbox[ 0 ]
60+
self.assertEqual( result[ 'Subject' ], 'you can have <>& in your context' )
61+
# In the test environment, we get base64-encoded ASCII. In the real environment,
62+
# we don't seem to. We'd like to test this.
63+
#self.assertTrue( 'template one rendered with a good two' in txt )
64+
65+
def testSendMail( self ):
66+
mail.empty_outbox()
67+
mail.send_mail( None, 'a@a.example.com', None, 'Subject', 'test/mail_body.txt',
68+
{ 'value': 'one', 'thing': 'two' } )
69+
(result, to, txt) = mail.outbox[ 0 ]
70+
self.assertEqual( result[ 'Subject' ], 'Subject' )
71+
# In the test environment, we get base64-encoded ASCII. In the real environment,
72+
# we don't seem to. We'd like to test this.
73+
#self.assertTrue( 'template one rendered with a good two' in txt )
74+
75+
def testSendMailPreformatted( self ):
76+
mail.empty_outbox()
77+
mail.send_mail_preformatted( None, '''From: me@here.example.com
78+
To: Joe Blow <joe@a.example.com>, fred@b.example.com
79+
Subject: Hello, what do you know?
80+
Cc: d@d.example.com
81+
Bcc: x@x.example.com
82+
83+
body body body''' )
84+
(result, to, txt) = mail.outbox[ 0 ]
85+
self.assertEqual( result[ 'From' ], 'me@here.example.com' )
86+
self.assertEqual( result[ 'To' ], 'Joe Blow <joe@a.example.com>, fred@b.example.com' )
87+
self.assertEqual( result[ 'Subject' ], 'Hello, what do you know?' )
88+
self.assertEqual( result[ 'Cc' ], 'd@d.example.com' )
89+
self.assertTrue( txt.endswith( 'body body body' ) )
90+
self.assertEqual( set( to ), set( [ 'joe@a.example.com', 'fred@b.example.com', 'd@d.example.com', 'x@x.example.com' ] ) )
91+
92+
if __name__ == '__main__':
93+
unittest.main()

0 commit comments

Comments
 (0)