Merge ~cjwatson/launchpad:py3-IncomingTestCase into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: f1cee414bd9bccf1ce8d5bf7f0efd06292587af6
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:py3-IncomingTestCase
Merge into: launchpad:master
Diff against target: 102 lines (+25/-12)
1 file modified
lib/lp/services/mail/tests/test_incoming.py (+25/-12)
Reviewer Review Type Date Requested Status
Cristian Gonzalez (community) Approve
Review via email: mp+398924@code.launchpad.net

Commit message

Fix IncomingTestCase for Python 3

Description of the change

This needed several adjustments, mainly to process email messages as bytes, but also because Python 3's email library handles non-ASCII characters in message headers somewhat differently.

To post a comment you must log in.
Revision history for this message
Cristian Gonzalez (cristiangsp) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/lib/lp/services/mail/tests/test_incoming.py b/lib/lp/services/mail/tests/test_incoming.py
index a9d615a..57735c3 100644
--- a/lib/lp/services/mail/tests/test_incoming.py
+++ b/lib/lp/services/mail/tests/test_incoming.py
@@ -2,6 +2,11 @@
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4from doctest import DocTestSuite4from doctest import DocTestSuite
5from email.header import (
6 decode_header,
7 Header,
8 make_header,
9 )
5from email.mime.multipart import MIMEMultipart10from email.mime.multipart import MIMEMultipart
6import logging11import logging
7import os12import os
@@ -16,6 +21,7 @@ import transaction
16from zope.interface import implementer21from zope.interface import implementer
17from zope.security.management import setSecurityPolicy22from zope.security.management import setSecurityPolicy
1823
24from lp.services.compat import message_as_bytes
19from lp.services.config import config25from lp.services.config import config
20from lp.services.gpg.interfaces import (26from lp.services.gpg.interfaces import (
21 GPGKeyExpired,27 GPGKeyExpired,
@@ -117,7 +123,7 @@ class IncomingTestCase(TestCaseWithFactory):
117 "An error occurred while processing a mail you sent to "123 "An error occurred while processing a mail you sent to "
118 "Launchpad's email\ninterface.\n\n\n"124 "Launchpad's email\ninterface.\n\n\n"
119 "Error message:\n\nSignature couldn't be verified: "125 "Error message:\n\nSignature couldn't be verified: "
120 "(7, 58, u'No data')",126 "(7, 58, %r)" % u"No data",
121 body)127 body)
122128
123 def test_expired_key(self):129 def test_expired_key(self):
@@ -213,8 +219,9 @@ class IncomingTestCase(TestCaseWithFactory):
213219
214 def test_invalid_to_addresses(self):220 def test_invalid_to_addresses(self):
215 # Invalid To: header should not be handled as an OOPS.221 # Invalid To: header should not be handled as an OOPS.
216 raw_mail = open(os.path.join(222 with open(os.path.join(testmails_path, 'invalid-to-header.txt'),
217 testmails_path, 'invalid-to-header.txt')).read()223 'rb') as f:
224 raw_mail = f.read()
218 # Due to the way handleMail works, even if we pass a valid To header225 # Due to the way handleMail works, even if we pass a valid To header
219 # to the TestMailer, as we're doing here, it falls back to parse all226 # to the TestMailer, as we're doing here, it falls back to parse all
220 # To and CC headers from the raw_mail. Also, TestMailer is used here227 # To and CC headers from the raw_mail. Also, TestMailer is used here
@@ -224,20 +231,20 @@ class IncomingTestCase(TestCaseWithFactory):
224 self.assertEqual([], self.oopses)231 self.assertEqual([], self.oopses)
225232
226 def makeSentMessage(self, sender, to, subject='subject', body='body',233 def makeSentMessage(self, sender, to, subject='subject', body='body',
227 cc=None, handler_domain=None):234 cc=None, handler_domain=None):
228 if handler_domain is None:235 if handler_domain is None:
229 extra, handler_domain = to.split('@')236 extra, handler_domain = to.split('@')
230 test_handler = FakeHandler()237 test_handler = FakeHandler()
231 mail_handlers.add(handler_domain, test_handler)238 mail_handlers.add(handler_domain, test_handler)
232 message = MIMEMultipart()239 message = MIMEMultipart()
233 message['Message-Id'] = '<message-id>'240 message['Message-Id'] = '<message-id>'
234 message['To'] = to241 message['To'] = Header(to)
235 message['From'] = sender242 message['From'] = Header(sender)
236 message['Subject'] = subject243 message['Subject'] = Header(subject)
237 if cc is not None:244 if cc is not None:
238 message['Cc'] = cc245 message['Cc'] = cc
239 message.set_payload(body)246 message.set_payload(body)
240 TestMailer().send(sender, to, message.as_string())247 TestMailer().send(sender, to, message_as_bytes(message))
241 return message, test_handler248 return message, test_handler
242249
243 def test_invalid_from_address_no_at(self):250 def test_invalid_from_address_no_at(self):
@@ -261,20 +268,26 @@ class IncomingTestCase(TestCaseWithFactory):
261 def test_invalid_from_address_unicode(self):268 def test_invalid_from_address_unicode(self):
262 # Invalid From: header such as no "@" is handled.269 # Invalid From: header such as no "@" is handled.
263 message, test_handler = self.makeSentMessage(270 message, test_handler = self.makeSentMessage(
264 'm\xeda@eg.dom', 'test@lp.dev')271 u'm\xeda@eg.dom', 'test@lp.dev')
265 handleMail()272 handleMail()
266 self.assertEqual([], self.oopses)273 self.assertEqual([], self.oopses)
267 self.assertEqual(1, len(test_handler.handledMails))274 self.assertEqual(1, len(test_handler.handledMails))
268 self.assertEqual('m\xeda@eg.dom', test_handler.handledMails[0]['From'])275 self.assertEqual(
276 u'm\xeda@eg.dom',
277 six.text_type(make_header(decode_header(
278 test_handler.handledMails[0]['From']))))
269279
270 def test_invalid_cc_address_unicode(self):280 def test_invalid_cc_address_unicode(self):
271 # Invalid Cc: header such as no "@" is handled.281 # Invalid Cc: header such as no "@" is handled.
272 message, test_handler = self.makeSentMessage(282 message, test_handler = self.makeSentMessage(
273 'me@eg.dom', 'test@lp.dev', cc='m\xeda@eg.dom')283 'me@eg.dom', 'test@lp.dev', cc=u'm\xeda@eg.dom')
274 handleMail()284 handleMail()
275 self.assertEqual([], self.oopses)285 self.assertEqual([], self.oopses)
276 self.assertEqual(1, len(test_handler.handledMails))286 self.assertEqual(1, len(test_handler.handledMails))
277 self.assertEqual('m\xeda@eg.dom', test_handler.handledMails[0]['Cc'])287 self.assertEqual(
288 u'm\xeda@eg.dom',
289 six.text_type(make_header(decode_header(
290 test_handler.handledMails[0]['Cc']))))
278291
279292
280class AuthenticateEmailTestCase(TestCaseWithFactory):293class AuthenticateEmailTestCase(TestCaseWithFactory):

Subscribers

People subscribed via source and target branches

to status/vote changes: