Merge lp:~abentley/launchpad/fix-encoded-attachments into lp:launchpad

Proposed by Aaron Bentley
Status: Merged
Merged at revision: 10838
Proposed branch: lp:~abentley/launchpad/fix-encoded-attachments
Merge into: lp:launchpad
Diff against target: 98 lines (+31/-8)
3 files modified
lib/lp/code/mail/codereviewcomment.py (+2/-1)
lib/lp/code/mail/tests/test_codereviewcomment.py (+26/-6)
lib/lp/testing/factory.py (+3/-1)
To merge this branch: bzr merge lp:~abentley/launchpad/fix-encoded-attachments
Reviewer Review Type Date Requested Status
Paul Hummer (community) code Approve
Review via email: mp+24917@code.launchpad.net

Commit message

Fix code review comments with encoded attachments

Description of the change

= Summary =
Fix bug #575185: Some merge proposal attachments are encoded as base64 but reported as qoted-printable

== Proposed fix ==
Decode message attachments before re-attaching them.

== Pre-implementation notes ==
None

== Implementation details ==
None

== Tests ==
bin/test -t test_encoded_attachments

== Demo and Q/A ==
Send an email with a base64-encoded attachment to a merge proposal on Staging.

The copy sent by launchpad should not display the attachment as base64-encoded.

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/code/mail/codereviewcomment.py
  lib/lp/code/mail/tests/test_codereviewcomment.py
  lib/lp/testing/factory.py

To post a comment you must log in.
Revision history for this message
Paul Hummer (rockstar) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/mail/codereviewcomment.py'
2--- lib/lp/code/mail/codereviewcomment.py 2010-03-28 23:36:16 +0000
3+++ lib/lp/code/mail/codereviewcomment.py 2010-05-07 17:45:47 +0000
4@@ -61,8 +61,9 @@
5 else:
6 content_type = part['content-type']
7 if (filename, content_type) in include_attachments:
8+ payload = part.get_payload(decode=True)
9 self.attachments.append(
10- (part.get_payload(), filename, content_type))
11+ (payload, filename, content_type))
12 self._generateBodyBits()
13
14 @classmethod
15
16=== modified file 'lib/lp/code/mail/tests/test_codereviewcomment.py'
17--- lib/lp/code/mail/tests/test_codereviewcomment.py 2010-04-13 19:15:48 +0000
18+++ lib/lp/code/mail/tests/test_codereviewcomment.py 2010-05-07 17:45:47 +0000
19@@ -205,6 +205,15 @@
20 self.assertEqual(ctrl.body.splitlines()[1:-3],
21 mailer.message.text_contents.splitlines())
22
23+ def makeComment(self, email_message):
24+ message = getUtility(IMessageSet).fromEmail(email_message.as_string())
25+ bmp = self.factory.makeBranchMergeProposal()
26+ comment = bmp.createCommentFromMessage(
27+ message, None, None, email_message)
28+ # We need to make sure the Librarian is up-to-date, so we commit.
29+ transaction.commit()
30+ return comment
31+
32 def test_mailer_attachments(self):
33 # Ensure that the attachments are attached.
34 # Only attachments that we would show in the web ui are attached,
35@@ -214,18 +223,14 @@
36 attachments=[
37 ('inc.diff', 'text/x-diff', 'This is a diff.'),
38 ('pic.jpg', 'image/jpeg', 'Binary data')])
39- message = getUtility(IMessageSet).fromEmail(msg.as_string())
40- bmp = self.factory.makeBranchMergeProposal()
41- comment = bmp.createCommentFromMessage(message, None, None, msg)
42- # We need to make sure the Librarian is up-to-date, so we commit.
43- transaction.commit()
44+ comment = self.makeComment(msg)
45 mailer = CodeReviewCommentMailer.forCreation(comment)
46 # The attachments of the mailer should have only the diff.
47 [outgoing_attachment] = mailer.attachments
48 self.assertEqual('inc.diff', outgoing_attachment[1])
49 self.assertEqual('text/x-diff', outgoing_attachment[2])
50 # The attachments are attached to the outgoing message.
51- person = bmp.target_branch.owner
52+ person = comment.branch_merge_proposal.target_branch.owner
53 message = mailer.generateEmail(
54 person.preferredemail.email, person).makeMessage()
55 self.assertTrue(message.is_multipart())
56@@ -233,6 +238,21 @@
57 self.assertEqual('inc.diff', attachment.get_filename())
58 self.assertEqual('text/x-diff', attachment['content-type'])
59
60+ def test_encoded_attachments(self):
61+ msg = self.factory.makeEmailMessage(
62+ body='This is the body of the email.',
63+ attachments=[('inc.diff', 'text/x-diff', 'This is a diff.')],
64+ encode_attachments=True)
65+ comment = self.makeComment(msg)
66+ mailer = CodeReviewCommentMailer.forCreation(comment)
67+ person = comment.branch_merge_proposal.target_branch.owner
68+ message = mailer.generateEmail(
69+ person.preferredemail.email, person).makeMessage()
70+ attachment = message.get_payload()[1]
71+ self.assertEqual(
72+ 'This is a diff.', attachment.get_payload(decode=True))
73+
74+
75 def makeCommentAndParticipants(self):
76 """Create a merge proposal and comment.
77
78
79=== modified file 'lib/lp/testing/factory.py'
80--- lib/lp/testing/factory.py 2010-05-07 14:39:20 +0000
81+++ lib/lp/testing/factory.py 2010-05-07 17:45:47 +0000
82@@ -2305,7 +2305,7 @@
83 return DistributionSourcePackage(distribution, sourcepackagename)
84
85 def makeEmailMessage(self, body=None, sender=None, to=None,
86- attachments=None):
87+ attachments=None, encode_attachments=False):
88 """Make an email message with possible attachments.
89
90 :param attachments: Should be an interable of tuples containing
91@@ -2335,6 +2335,8 @@
92 attachment['Content-Type'] = content_type
93 attachment['Content-Disposition'] = (
94 'attachment; filename="%s"' % filename)
95+ if encode_attachments:
96+ encode_base64(attachment)
97 msg.attach(attachment)
98 return msg
99