8687.15.17
by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/. |
1 |
# Copyright 2009 Canonical Ltd. This software is licensed under the
|
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
5575.1.4
by Aaron Bentley
Implement objects for code review messages |
3 |
|
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
4 |
"""Unit tests for CodeReviewComment"""
|
5575.1.4
by Aaron Bentley
Implement objects for code review messages |
5 |
|
9742.8.9
by Aaron Bentley
Fix quote_text_as_email tests. |
6 |
from textwrap import dedent |
5575.1.37
by Aaron Bentley
get tests passing |
7 |
|
14604.1.1
by Curtis Hovey
Separate test-authoring classes from test-running classes. |
8 |
from lp.testing.layers import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
9 |
DatabaseFunctionalLayer, |
10 |
LaunchpadFunctionalLayer, |
|
11 |
)
|
|
8555.2.9
by Tim Penhey
Move CodeReviewVote enum. |
12 |
from lp.code.enums import CodeReviewVote |
13 |
from lp.code.event.branchmergeproposal import NewCodeReviewCommentEvent |
|
9742.8.9
by Aaron Bentley
Fix quote_text_as_email tests. |
14 |
from lp.code.model.codereviewcomment import quote_text_as_email |
14550.1.1
by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad |
15 |
from lp.services.messages.model.message import MessageSet |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
16 |
from lp.testing import ( |
17 |
TestCase, |
|
18 |
TestCaseWithFactory, |
|
19 |
)
|
|
5575.1.4
by Aaron Bentley
Implement objects for code review messages |
20 |
|
7362.12.24
by Jonathan Lange
Restore change that somehow got lost. |
21 |
|
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
22 |
class TestCodeReviewComment(TestCaseWithFactory): |
5575.1.4
by Aaron Bentley
Implement objects for code review messages |
23 |
|
7334.4.12
by Tim Penhey
Fix the TestCodeReviewComment tests. |
24 |
layer = DatabaseFunctionalLayer |
5575.1.4
by Aaron Bentley
Implement objects for code review messages |
25 |
|
26 |
def setUp(self): |
|
7334.4.12
by Tim Penhey
Fix the TestCodeReviewComment tests. |
27 |
TestCaseWithFactory.setUp(self, 'admin@canonical.com') |
7362.12.24
by Jonathan Lange
Restore change that somehow got lost. |
28 |
source = self.factory.makeProductBranch(title='source-branch') |
29 |
target = self.factory.makeProductBranch( |
|
6475.2.22
by Barry Warsaw
mergeRF |
30 |
product=source.product, title='target-branch') |
31 |
self.bmp = source.addLandingTarget(source.owner, target) |
|
6334.3.14
by Aaron Bentley
Fix failing tests |
32 |
self.submitter = self.factory.makePerson(password='password') |
33 |
self.reviewer = self.factory.makePerson(password='password') |
|
5575.1.37
by Aaron Bentley
get tests passing |
34 |
self.bmp2 = self.factory.makeBranchMergeProposal() |
5575.1.4
by Aaron Bentley
Implement objects for code review messages |
35 |
|
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
36 |
def test_createRootComment(self): |
37 |
comment = self.bmp.createComment( |
|
5575.1.29
by Aaron Bentley
Update from review comments |
38 |
self.submitter, 'Message subject', 'Message content') |
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
39 |
self.assertEqual(None, comment.vote) |
40 |
self.assertEqual(None, comment.vote_tag) |
|
41 |
self.assertEqual(self.submitter, comment.message.owner) |
|
42 |
self.assertEqual('Message subject', comment.message.subject) |
|
43 |
self.assertEqual('Message content', comment.message.chunks[0].content) |
|
5575.1.4
by Aaron Bentley
Implement objects for code review messages |
44 |
|
6475.2.22
by Barry Warsaw
mergeRF |
45 |
def test_createRootCommentNoSubject(self): |
46 |
comment = self.bmp.createComment( |
|
47 |
self.submitter, None, 'Message content') |
|
48 |
self.assertEqual(None, comment.vote) |
|
49 |
self.assertEqual(None, comment.vote_tag) |
|
50 |
self.assertEqual(self.submitter, comment.message.owner) |
|
7362.12.33
by Jonathan Lange
NEVER used hardwired strings for factory-produced objects. |
51 |
self.assertEqual( |
52 |
'Re: [Merge] %s into %s' % ( |
|
53 |
self.bmp.source_branch.bzr_identity, |
|
54 |
self.bmp.target_branch.bzr_identity), comment.message.subject) |
|
6475.2.22
by Barry Warsaw
mergeRF |
55 |
self.assertEqual('Message content', comment.message.chunks[0].content) |
56 |
||
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
57 |
def test_createReplyComment(self): |
58 |
comment = self.bmp.createComment( |
|
5575.1.29
by Aaron Bentley
Update from review comments |
59 |
self.submitter, 'Message subject', 'Message content') |
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
60 |
reply = self.bmp.createComment( |
5575.1.29
by Aaron Bentley
Update from review comments |
61 |
self.reviewer, 'Reply subject', 'Reply content', |
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
62 |
CodeReviewVote.ABSTAIN, 'My tag', comment) |
63 |
self.assertEqual(comment.message.id, reply.message.parent.id) |
|
64 |
self.assertEqual(comment.message, reply.message.parent) |
|
5575.1.5
by Aaron Bentley
Add tests and assertions |
65 |
self.assertEqual('Reply subject', reply.message.subject) |
66 |
self.assertEqual('Reply content', reply.message.chunks[0].content) |
|
5575.1.47
by Aaron Bentley
Change CodeReviewVote values to DISAPPROVE, APPROVE, ABSTAIN |
67 |
self.assertEqual(CodeReviewVote.ABSTAIN, reply.vote) |
7055.6.21
by Tim Penhey
Fix the tests that didn't take into account the lowercasing of the review type. |
68 |
self.assertEqual('my tag', reply.vote_tag) |
5575.1.5
by Aaron Bentley
Add tests and assertions |
69 |
|
6475.2.22
by Barry Warsaw
mergeRF |
70 |
def test_createReplyCommentNoSubject(self): |
71 |
comment = self.bmp.createComment( |
|
72 |
self.submitter, 'Message subject', 'Message content') |
|
73 |
reply = self.bmp.createComment( |
|
74 |
self.reviewer, subject=None, parent=comment) |
|
75 |
self.assertEqual('Re: Message subject', reply.message.subject) |
|
76 |
||
77 |
def test_createReplyCommentNoSubjectExistingRe(self): |
|
78 |
comment = self.bmp.createComment( |
|
79 |
self.submitter, 'Re: Message subject', 'Message content') |
|
80 |
reply = self.bmp.createComment( |
|
81 |
self.reviewer, subject=None, parent=comment) |
|
82 |
self.assertEqual('Re: Message subject', reply.message.subject) |
|
83 |
||
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
84 |
def test_createNoParentComment(self): |
11733.1.4
by Tim Penhey
Add an extra event for the needs review, but keep the same functionality for now. |
85 |
self.bmp.createComment( |
5575.1.29
by Aaron Bentley
Update from review comments |
86 |
self.submitter, 'Message subject', 'Message content') |
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
87 |
new_comment = self.bmp.createComment( |
5575.1.47
by Aaron Bentley
Change CodeReviewVote values to DISAPPROVE, APPROVE, ABSTAIN |
88 |
self.reviewer, 'New subject', 'New content', |
89 |
CodeReviewVote.ABSTAIN) |
|
6821.4.4
by Aaron Bentley
Use root_message_id, not root_comment, as in-reply-to id |
90 |
self.assertEqual(None, new_comment.message.parent) |
5575.1.5
by Aaron Bentley
Add tests and assertions |
91 |
|
5575.1.43
by Aaron Bentley
Style and doc updates |
92 |
def test_replyWithWrongMergeProposal(self): |
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
93 |
comment = self.bmp.createComment( |
5575.1.29
by Aaron Bentley
Update from review comments |
94 |
self.submitter, 'Message subject', 'Message content') |
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
95 |
self.assertRaises(AssertionError, self.bmp2.createComment, |
5575.1.20
by Aaron Bentley
Turn CodeReviewMessage.vote into an enum |
96 |
self.reviewer, 'Reply subject', 'Reply content', |
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
97 |
CodeReviewVote.ABSTAIN, 'My tag', comment) |
5575.1.4
by Aaron Bentley
Implement objects for code review messages |
98 |
|
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
99 |
def test_createCommentFromMessage(self): |
100 |
"""Creating a CodeReviewComment from a message works."""
|
|
6334.6.11
by Aaron Bentley
Improve testing of createMessageFromMessage |
101 |
message = self.factory.makeMessage(owner=self.submitter) |
8970.5.1
by Aaron Bentley
Ensure no codereviewcomment is created if subject missing. |
102 |
comment = self.bmp.createCommentFromMessage( |
103 |
message, None, None, original_email=None, _validate=False) |
|
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
104 |
self.assertEqual(message, comment.message) |
6334.6.11
by Aaron Bentley
Improve testing of createMessageFromMessage |
105 |
|
6334.6.36
by Aaron Bentley
Rename code review messages to code review comments |
106 |
def test_createCommentFromMessageNotifies(self): |
107 |
"""Creating a CodeReviewComment should trigger a notification."""
|
|
6334.6.11
by Aaron Bentley
Improve testing of createMessageFromMessage |
108 |
message = self.factory.makeMessage() |
6334.6.12
by Aaron Bentley
merge with notify-codereview2 |
109 |
self.assertNotifies( |
7334.4.12
by Tim Penhey
Fix the TestCodeReviewComment tests. |
110 |
NewCodeReviewCommentEvent, self.bmp.createCommentFromMessage, |
8970.5.1
by Aaron Bentley
Ensure no codereviewcomment is created if subject missing. |
111 |
message, None, None, original_email=None, _validate=False) |
5608.11.38
by Aaron Bentley
Implement graph_dict |
112 |
|
6334.6.9
by Aaron Bentley
Implement message creation from email handler |
113 |
|
7407.1.8
by Tim Penhey
Add tests for getAttachments. |
114 |
class TestCodeReviewCommentGetAttachments(TestCaseWithFactory): |
115 |
"""Test the getAttachments method of code review comments."""
|
|
116 |
||
117 |
# We need the librarian for storing the messages.
|
|
118 |
layer = LaunchpadFunctionalLayer |
|
119 |
||
120 |
def setUp(self): |
|
121 |
TestCaseWithFactory.setUp(self, 'admin@canonical.com') |
|
122 |
self.bmp = self.factory.makeBranchMergeProposal() |
|
123 |
||
124 |
def test_getAttachments_no_attachments(self): |
|
125 |
# If there are no attachments, the getAttachments should return two
|
|
126 |
# empty lists.
|
|
127 |
comment = self.bmp.createComment( |
|
128 |
self.bmp.registrant, 'Subject', content='Some content') |
|
7407.1.13
by Tim Penhey
Update following review. |
129 |
self.assertEqual(([], []), comment.getAttachments()) |
7407.1.8
by Tim Penhey
Add tests for getAttachments. |
130 |
|
131 |
def _makeCommentFromEmailWithAttachment(self, filename, content_type): |
|
132 |
# Make an email message with an attachment, and create a code
|
|
133 |
# review comment from it.
|
|
134 |
msg = self.factory.makeEmailMessage( |
|
135 |
body='This is the body of the email.', |
|
136 |
attachments=[ |
|
137 |
(filename, content_type, 'Attachment body')]) |
|
138 |
message = MessageSet().fromEmail(msg.as_string()) |
|
139 |
return self.bmp.createCommentFromMessage(message, None, None, msg) |
|
140 |
||
141 |
def test_getAttachments_text_plain_are_displayed(self): |
|
142 |
# text/plain attachments are displayed.
|
|
143 |
comment = self._makeCommentFromEmailWithAttachment( |
|
144 |
'some.txt', 'text/plain') |
|
145 |
email_body, attachment = comment.message.chunks |
|
7407.1.13
by Tim Penhey
Update following review. |
146 |
self.assertEqual(([attachment.blob], []), comment.getAttachments()) |
7407.1.8
by Tim Penhey
Add tests for getAttachments. |
147 |
|
148 |
def test_getAttachments_text_xdiff_are_displayed(self): |
|
149 |
# text/x-diff attachments are displayed.
|
|
150 |
comment = self._makeCommentFromEmailWithAttachment( |
|
151 |
'some.txt', 'text/x-diff') |
|
152 |
email_body, attachment = comment.message.chunks |
|
7407.1.13
by Tim Penhey
Update following review. |
153 |
self.assertEqual(([attachment.blob], []), comment.getAttachments()) |
7407.1.8
by Tim Penhey
Add tests for getAttachments. |
154 |
|
155 |
def test_getAttachments_text_xpatch_are_displayed(self): |
|
156 |
# text/x-patch attachments are displayed.
|
|
157 |
comment = self._makeCommentFromEmailWithAttachment( |
|
158 |
'some.txt', 'text/x-patch') |
|
159 |
email_body, attachment = comment.message.chunks |
|
7407.1.13
by Tim Penhey
Update following review. |
160 |
self.assertEqual(([attachment.blob], []), comment.getAttachments()) |
7407.1.8
by Tim Penhey
Add tests for getAttachments. |
161 |
|
162 |
def test_getAttachments_others(self): |
|
163 |
# Attachments with other content types are not considered display
|
|
164 |
# attachments.
|
|
165 |
comment = self._makeCommentFromEmailWithAttachment( |
|
166 |
'some.txt', 'application/octet-stream') |
|
167 |
email_body, attachment = comment.message.chunks |
|
7407.1.13
by Tim Penhey
Update following review. |
168 |
self.assertEqual(([], [attachment.blob]), comment.getAttachments()) |
7407.1.8
by Tim Penhey
Add tests for getAttachments. |
169 |
|
170 |
comment = self._makeCommentFromEmailWithAttachment( |
|
171 |
'pic.jpg', 'image/jpeg') |
|
172 |
email_body, attachment = comment.message.chunks |
|
7407.1.13
by Tim Penhey
Update following review. |
173 |
self.assertEqual(([], [attachment.blob]), comment.getAttachments()) |
7407.1.8
by Tim Penhey
Add tests for getAttachments. |
174 |
|
175 |
def test_getAttachments_diff_or_patch_filename_overrides(self): |
|
176 |
# If the filename ends with .diff or .patch, then we consider these
|
|
177 |
# attachments good even if attached with the wrong content type.
|
|
178 |
comment = self._makeCommentFromEmailWithAttachment( |
|
179 |
'some.diff', 'application/octet-stream') |
|
180 |
email_body, attachment = comment.message.chunks |
|
7407.1.13
by Tim Penhey
Update following review. |
181 |
self.assertEqual(([attachment.blob], []), comment.getAttachments()) |
7407.1.8
by Tim Penhey
Add tests for getAttachments. |
182 |
|
183 |
comment = self._makeCommentFromEmailWithAttachment( |
|
184 |
'some.patch', 'application/octet-stream') |
|
185 |
email_body, attachment = comment.message.chunks |
|
7407.1.13
by Tim Penhey
Update following review. |
186 |
self.assertEqual(([attachment.blob], []), comment.getAttachments()) |
7407.1.8
by Tim Penhey
Add tests for getAttachments. |
187 |
|
188 |
||
9742.8.9
by Aaron Bentley
Fix quote_text_as_email tests. |
189 |
class TestQuoteTextAsEmail(TestCase): |
190 |
"""Test the quote_text_as_email helper method."""
|
|
191 |
||
192 |
def test_empty_string(self): |
|
193 |
# Nothing just gives us an empty string.
|
|
194 |
self.assertEqual('', quote_text_as_email('')) |
|
195 |
||
196 |
def test_none_string(self): |
|
197 |
# If None is passed the quoted text is an empty string.
|
|
198 |
self.assertEqual('', quote_text_as_email(None)) |
|
199 |
||
200 |
def test_whitespace_string(self): |
|
201 |
# Just whitespace gives us an empty string.
|
|
202 |
self.assertEqual('', quote_text_as_email(' \t ')) |
|
203 |
||
204 |
def test_long_string(self): |
|
205 |
# Long lines are wrapped.
|
|
206 |
long_line = ('This is a very long line that needs to be wrapped ' |
|
207 |
'onto more than one line given a short length.') |
|
208 |
self.assertEqual( |
|
209 |
dedent("""\ |
|
210 |
> This is a very long line that needs to
|
|
211 |
> be wrapped onto more than one line
|
|
212 |
> given a short length."""), |
|
213 |
quote_text_as_email(long_line, 40)) |
|
214 |
||
215 |
def test_code_sample(self): |
|
216 |
# Initial whitespace is not trimmed.
|
|
217 |
code = """\ |
|
218 |
def test_whitespace_string(self):
|
|
219 |
# Nothing just gives us the prefix.
|
|
220 |
self.assertEqual('', wrap_text(' \t '))""" |
|
221 |
self.assertEqual( |
|
222 |
dedent("""\ |
|
223 |
> def test_whitespace_string(self):
|
|
224 |
> # Nothing just gives us the prefix.
|
|
225 |
> self.assertEqual('', wrap_text(' '))"""), |
|
226 |
quote_text_as_email(code, 60)) |
|
227 |
||
228 |
def test_empty_line_mid_string(self): |
|
229 |
# Lines in the middle of the string are quoted too.
|
|
230 |
value = dedent("""\ |
|
231 |
This is the first line.
|
|
232 |
||
233 |
This is the second line.
|
|
234 |
""") |
|
235 |
expected = dedent("""\ |
|
236 |
> This is the first line.
|
|
237 |
>
|
|
238 |
> This is the second line.""") |
|
239 |
self.assertEqual(expected, quote_text_as_email(value)) |
|
240 |
||
241 |
def test_trailing_whitespace(self): |
|
242 |
# Trailing whitespace is removed.
|
|
243 |
self.assertEqual('> foo', quote_text_as_email(' foo \n ')) |