Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: appengine/monorail/features/test/notify_helpers_test.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # -*- coding: utf8 -*-
2 # Copyright 2016 The Chromium Authors. All rights reserved.
3 # Use of this source code is govered by a BSD-style
4 # license that can be found in the LICENSE file or at
5 # https://developers.google.com/open-source/licenses/bsd
6
7 """Tests for notify_helpers.py."""
8
9 import unittest
10
11 from features import notify_helpers
12 from framework import emailfmt
13 from framework import framework_views
14 from services import service_manager
15 from testing import fake
16
17
18 REPLY_NOT_ALLOWED = notify_helpers.REPLY_NOT_ALLOWED
19 REPLY_MAY_COMMENT = notify_helpers.REPLY_MAY_COMMENT
20 REPLY_MAY_UPDATE = notify_helpers.REPLY_MAY_UPDATE
21
22
23 class ComputeIssueChangeAddressPermListTest(unittest.TestCase):
24
25 def setUp(self):
26 self.users_by_id = {
27 111L: framework_views.UserView(111L, 'owner@example.com', True),
28 222L: framework_views.UserView(222L, 'member@example.com', True),
29 999L: framework_views.UserView(999L, 'visitor@example.com', True),
30 }
31 self.services = service_manager.Services(
32 project=fake.ProjectService(),
33 config=fake.ConfigService(),
34 issue=fake.IssueService(),
35 user=fake.UserService(),
36 usergroup=fake.UserGroupService())
37 self.services.user.TestAddUser('owner@example.com', 111L)
38 self.services.user.TestAddUser('member@example.com', 222L)
39 self.services.user.TestAddUser('visitor@example.com', 999L)
40 self.project = self.services.project.TestAddProject(
41 'proj', owner_ids=[111L], committer_ids=[222L])
42 self.project.process_inbound_email = True
43 self.issue = fake.MakeTestIssue(
44 self.project.project_id, 1, 'summary', 'New', 111L)
45
46 def testEmptyIDs(self):
47 cnxn = 'fake cnxn'
48 addr_perm_list = notify_helpers.ComputeIssueChangeAddressPermList(
49 cnxn, [], self.project, self.issue, self.services, [], {},
50 pref_check_function=lambda *args: True)
51 self.assertEqual([], addr_perm_list)
52
53 def testRecipientIsMember(self):
54 cnxn = 'fake cnxn'
55 ids_to_consider = [111L, 222L, 999L]
56 addr_perm_list = notify_helpers.ComputeIssueChangeAddressPermList(
57 cnxn, ids_to_consider, self.project, self.issue, self.services, set(),
58 self.users_by_id, pref_check_function=lambda *args: True)
59 self.assertEqual(
60 [(True, 'owner@example.com', REPLY_MAY_UPDATE),
61 (True, 'member@example.com', REPLY_MAY_UPDATE),
62 (False, 'visitor@example.com', REPLY_MAY_COMMENT)],
63 addr_perm_list)
64
65
66 class ComputeProjectAndIssueNotificationAddrListTest(unittest.TestCase):
67
68 def setUp(self):
69 self.services = service_manager.Services(
70 project=fake.ProjectService(),
71 user=fake.UserService())
72 self.project = self.services.project.TestAddProject('project')
73 self.services.user.TestAddUser('alice@gmail.com', 111L)
74 self.services.user.TestAddUser('bob@gmail.com', 222L)
75 self.services.user.TestAddUser('fred@gmail.com', 555L)
76
77 def testNotifyAddress(self):
78 # No mailing list or filter rules are defined
79 addr_perm_list = notify_helpers.ComputeProjectNotificationAddrList(
80 self.project, True, set())
81 self.assertListEqual([], addr_perm_list)
82
83 # Only mailing list is notified.
84 self.project.issue_notify_address = 'mailing-list@domain.com'
85 addr_perm_list = notify_helpers.ComputeProjectNotificationAddrList(
86 self.project, True, set())
87 self.assertListEqual(
88 [(False, 'mailing-list@domain.com', REPLY_NOT_ALLOWED)],
89 addr_perm_list)
90
91 # No one is notified because mailing list was already notified.
92 omit_addrs = {'mailing-list@domain.com'}
93 addr_perm_list = notify_helpers.ComputeProjectNotificationAddrList(
94 self.project, False, omit_addrs)
95 self.assertListEqual([], addr_perm_list)
96
97 # No one is notified because anon users cannot view.
98 addr_perm_list = notify_helpers.ComputeProjectNotificationAddrList(
99 self.project, False, set())
100 self.assertListEqual([], addr_perm_list)
101
102 def testFilterRuleNotifyAddresses(self):
103 issue = fake.MakeTestIssue(
104 self.project.project_id, 1, 'summary', 'New', 555L)
105 issue.derived_notify_addrs.extend(['notify@domain.com'])
106
107 addr_perm_list = notify_helpers.ComputeIssueNotificationAddrList(
108 issue, set())
109 self.assertListEqual(
110 [(False, 'notify@domain.com', REPLY_NOT_ALLOWED)],
111 addr_perm_list)
112
113 # Also-notify addresses can be omitted (e.g., if it is the same as
114 # the email address of the user who made the change).
115 addr_perm_list = notify_helpers.ComputeIssueNotificationAddrList(
116 issue, {'notify@domain.com'})
117 self.assertListEqual([], addr_perm_list)
118
119
120 class MakeBulletedEmailWorkItemsTest(unittest.TestCase):
121
122 def setUp(self):
123 self.project = fake.Project(project_name='proj1')
124 self.commenter_view = framework_views.UserView(
125 111L, 'test@example.com', True)
126
127 def testEmptyAddrs(self):
128 """Test the case where we found zero users to notify."""
129 email_tasks = notify_helpers.MakeBulletedEmailWorkItems(
130 [], 'subject', 'body', 'body', self.project, 'example.com',
131 self.commenter_view)
132 self.assertEqual([], email_tasks)
133 email_tasks = notify_helpers.MakeBulletedEmailWorkItems(
134 [([], 'reason')], 'subject', 'body', 'body', self.project,
135 'example.com', self.commenter_view)
136 self.assertEqual([], email_tasks)
137
138
139 class MakeEmailWorkItemTest(unittest.TestCase):
140
141 def setUp(self):
142 self.project = fake.Project(project_name='proj1')
143 self.project.process_inbound_email = True
144 self.commenter_view = framework_views.UserView(
145 111L, 'test@example.com', True)
146 self.expected_html_footer = (
147 'You received this message because:<br/> 1. reason<br/><br/>You may '
148 'adjust your notification preferences at:<br/><a href="https://'
149 'example.com/hosting/settings">https://example.com/hosting/settings'
150 '</a>')
151
152 def testBodySelection(self):
153 """We send non-members the email body that is indented for non-members."""
154 email_task = notify_helpers._MakeEmailWorkItem(
155 (False, 'a@a.com', REPLY_NOT_ALLOWED),
156 ['reason'], 'subject', 'body non', 'body mem', self.project,
157 'example.com', self.commenter_view)
158
159 self.assertEqual('a@a.com', email_task['to'])
160 self.assertEqual('subject', email_task['subject'])
161 self.assertIn('body non', email_task['body'])
162 self.assertEqual(
163 emailfmt.FormatFromAddr(self.project, commenter_view=self.commenter_view,
164 can_reply_to=False),
165 email_task['from_addr'])
166 self.assertEqual(emailfmt.NoReplyAddress(), email_task['reply_to'])
167
168 email_task = notify_helpers._MakeEmailWorkItem(
169 (True, 'a@a.com', REPLY_NOT_ALLOWED),
170 ['reason'], 'subject', 'body mem', 'body mem', self.project,
171 'example.com', self.commenter_view)
172 self.assertIn('body mem', email_task['body'])
173
174 def testHtmlBody_NoDetailUrl(self):
175 """"An html body is not be sent if detail_url is not specified."""
176 email_task = notify_helpers._MakeEmailWorkItem(
177 (False, 'a@a.com', REPLY_NOT_ALLOWED),
178 ['reason'], 'subject', 'body non', 'body mem', self.project,
179 'example.com', self.commenter_view, detail_url=None)
180
181 self.assertIsNone(email_task['html_body'])
182
183 def testHtmlBody_WithDetailUrl(self):
184 """"An html body is sent if a detail_url is specified."""
185 detail_url = 'http://test-detail-url.com/id=1234'
186 email_task = notify_helpers._MakeEmailWorkItem(
187 (False, 'a@a.com', REPLY_NOT_ALLOWED),
188 ['reason'], 'subject', 'body non', 'body mem', self.project,
189 'example.com', self.commenter_view, detail_url=detail_url)
190
191 expected_html_body = (
192 notify_helpers.HTML_BODY_WITH_GMAIL_ACTION_TEMPLATE % (
193 detail_url,
194 'body non-- <br/>%s' % self.expected_html_footer))
195 self.assertEquals(expected_html_body, email_task['html_body'])
196
197 def testHtmlBody_WithUnicodeChars(self):
198 """"An html body is sent if a detail_url is specified."""
199 detail_url = 'http://test-detail-url.com/id=1234'
200 unicode_content = '\xe2\x9d\xa4 â â'
201 email_task = notify_helpers._MakeEmailWorkItem(
202 (False, 'a@a.com', REPLY_NOT_ALLOWED),
203 ['reason'], 'subject', unicode_content, 'unused body mem',
204 self.project, 'example.com', self.commenter_view, detail_url=detail_url)
205
206 expected_html_body = (
207 notify_helpers.HTML_BODY_WITH_GMAIL_ACTION_TEMPLATE % (
208 detail_url,
209 '%s-- <br/>%s' % (unicode_content.decode('utf-8'),
210 self.expected_html_footer)))
211 self.assertEquals(expected_html_body, email_task['html_body'])
212
213 def testHtmlBody_WithLinks(self):
214 """"An html body is sent if a detail_url is specified."""
215 detail_url = 'http://test-detail-url.com/id=1234'
216 email_task = notify_helpers._MakeEmailWorkItem(
217 (False, 'a@a.com', REPLY_NOT_ALLOWED),
218 ['reason'], 'subject', 'test google.com test', 'unused body mem',
219 self.project, 'example.com', self.commenter_view, detail_url=detail_url)
220
221 expected_html_body = (
222 notify_helpers.HTML_BODY_WITH_GMAIL_ACTION_TEMPLATE % (
223 detail_url,
224 'test <a href="http://google.com">google.com</a> test-- <br/>%s' % (
225 self.expected_html_footer)))
226 self.assertEquals(expected_html_body, email_task['html_body'])
227
228 def testHtmlBody_LinkWithinTags(self):
229 """"An html body is sent with correct <a href>s."""
230 detail_url = 'http://test-detail-url.com/id=1234'
231 email_task = notify_helpers._MakeEmailWorkItem(
232 (False, 'a@a.com', REPLY_NOT_ALLOWED),
233 ['reason'], 'subject', 'test <http://google.com> test', 'unused body',
234 self.project, 'example.com', self.commenter_view, detail_url=detail_url)
235
236 expected_html_body = (
237 notify_helpers.HTML_BODY_WITH_GMAIL_ACTION_TEMPLATE % (
238 detail_url,
239 'test <a href="http://google.com"><http://google.com></a> '
240 'test-- <br/>%s' % self.expected_html_footer))
241 self.assertEquals(expected_html_body, email_task['html_body'])
242
243 def testHtmlBody_EmailWithinTags(self):
244 """"An html body is sent with correct <a href>s."""
245 detail_url = 'http://test-detail-url.com/id=1234'
246 email_task = notify_helpers._MakeEmailWorkItem(
247 (False, 'a@a.com', REPLY_NOT_ALLOWED),
248 ['reason'], 'subject', 'test <t@chromium.org> <a@chromium.org> test',
249 'unused body mem', self.project, 'example.com', self.commenter_view,
250 detail_url=detail_url)
251
252 expected_html_body = (
253 notify_helpers.HTML_BODY_WITH_GMAIL_ACTION_TEMPLATE % (
254 detail_url,
255 'test <a href="mailto:t@chromium.org"><t@chromium.org></a> '
256 '<a href="mailto:a@chromium.org"><a@chromium.org></a> '
257 'test-- <br/>%s' % self.expected_html_footer))
258 self.assertEquals(expected_html_body, email_task['html_body'])
259
260 def testHtmlBody_WithEscapedHtml(self):
261 """"An html body is sent with html content escaped."""
262 detail_url = 'http://test-detail-url.com/id=1234'
263 body_with_html_content = (
264 '<a href="http://www.google.com">test</a> \'something\'')
265 email_task = notify_helpers._MakeEmailWorkItem(
266 (False, 'a@a.com', REPLY_NOT_ALLOWED),
267 ['reason'], 'subject', body_with_html_content, 'unused body mem',
268 self.project, 'example.com', self.commenter_view, detail_url=detail_url)
269
270 escaped_body_with_html_content = (
271 '&lt;a href=&quot;http://www.google.com&quot;&gt;test&lt;/a&gt; '
272 '&#39;something&#39;')
273 notify_helpers._MakeNotificationFooter(
274 ['reason'], REPLY_NOT_ALLOWED, 'example.com')
275 expected_html_body = (
276 notify_helpers.HTML_BODY_WITH_GMAIL_ACTION_TEMPLATE % (
277 detail_url,
278 '%s-- <br/>%s' % (escaped_body_with_html_content,
279 self.expected_html_footer)))
280 self.assertEquals(expected_html_body, email_task['html_body'])
281
282 def testReplyInvitation(self):
283 """We include a footer about replying that is appropriate for that user."""
284 email_task = notify_helpers._MakeEmailWorkItem(
285 (True, 'a@a.com', REPLY_NOT_ALLOWED),
286 ['reason'], 'subject', 'body non', 'body mem', self.project,
287 'example.com', self.commenter_view)
288 self.assertEqual(emailfmt.NoReplyAddress(), email_task['reply_to'])
289 self.assertNotIn('Reply to this email', email_task['body'])
290
291 email_task = notify_helpers._MakeEmailWorkItem(
292 (True, 'a@a.com', REPLY_MAY_COMMENT),
293 ['reason'], 'subject', 'body non', 'body mem', self.project,
294 'example.com', self.commenter_view)
295 self.assertEqual(
296 '%s@%s' % (self.project.project_name, emailfmt.MailDomain()),
297 email_task['reply_to'])
298 self.assertIn('Reply to this email to add a comment', email_task['body'])
299 self.assertNotIn('make changes', email_task['body'])
300
301 email_task = notify_helpers._MakeEmailWorkItem(
302 (True, 'a@a.com', REPLY_MAY_UPDATE),
303 ['reason'], 'subject', 'body non', 'body mem', self.project,
304 'example.com', self.commenter_view)
305 self.assertEqual(
306 '%s@%s' % (self.project.project_name, emailfmt.MailDomain()),
307 email_task['reply_to'])
308 self.assertIn('Reply to this email to add a comment', email_task['body'])
309 self.assertIn('make updates', email_task['body'])
310
311 def testInboundEmailDisabled(self):
312 """We don't invite replies if they are disabled for this project."""
313 self.project.process_inbound_email = False
314 email_task = notify_helpers._MakeEmailWorkItem(
315 (True, 'a@a.com', REPLY_MAY_UPDATE),
316 ['reason'], 'subject', 'body non', 'body mem', self.project,
317 'example.com', self.commenter_view)
318 self.assertEqual(emailfmt.NoReplyAddress(), email_task['reply_to'])
319
320 def testReasons(self):
321 """The footer lists reasons why that email was sent to that user."""
322 email_task = notify_helpers._MakeEmailWorkItem(
323 (True, 'a@a.com', REPLY_MAY_UPDATE),
324 ['Funny', 'Caring', 'Near'], 'subject', 'body', 'body', self.project,
325 'example.com', self.commenter_view)
326 self.assertIn('because:', email_task['body'])
327 self.assertIn('1. Funny', email_task['body'])
328 self.assertIn('2. Caring', email_task['body'])
329 self.assertIn('3. Near', email_task['body'])
330
331 email_task = notify_helpers._MakeEmailWorkItem(
332 (True, 'a@a.com', REPLY_MAY_UPDATE),
333 [], 'subject', 'body', 'body', self.project,
334 'example.com', self.commenter_view)
335 self.assertNotIn('because', email_task['body'])
336
337
338 class MakeNotificationFooterTest(unittest.TestCase):
339
340 def testMakeNotificationFooter_NoReason(self):
341 footer = notify_helpers._MakeNotificationFooter(
342 [], REPLY_NOT_ALLOWED, 'example.com')
343 self.assertEqual('', footer)
344
345 def testMakeNotificationFooter_WithReason(self):
346 footer = notify_helpers._MakeNotificationFooter(
347 ['REASON'], REPLY_NOT_ALLOWED, 'example.com')
348 self.assertIn('REASON', footer)
349 self.assertIn('https://example.com/hosting/settings', footer)
350
351 footer = notify_helpers._MakeNotificationFooter(
352 ['REASON'], REPLY_NOT_ALLOWED, 'example.com')
353 self.assertIn('REASON', footer)
354 self.assertIn('https://example.com/hosting/settings', footer)
355
356 def testMakeNotificationFooter_ManyReasons(self):
357 footer = notify_helpers._MakeNotificationFooter(
358 ['Funny', 'Caring', 'Warmblooded'], REPLY_NOT_ALLOWED,
359 'example.com')
360 self.assertIn('Funny', footer)
361 self.assertIn('Caring', footer)
362 self.assertIn('Warmblooded', footer)
363
364 def testMakeNotificationFooter_WithReplyInstructions(self):
365 footer = notify_helpers._MakeNotificationFooter(
366 ['REASON'], REPLY_NOT_ALLOWED, 'example.com')
367 self.assertNotIn('Reply', footer)
368 self.assertIn('https://example.com/hosting/settings', footer)
369
370 footer = notify_helpers._MakeNotificationFooter(
371 ['REASON'], REPLY_MAY_COMMENT, 'example.com')
372 self.assertIn('add a comment', footer)
373 self.assertNotIn('make updates', footer)
374 self.assertIn('https://example.com/hosting/settings', footer)
375
376 footer = notify_helpers._MakeNotificationFooter(
377 ['REASON'], REPLY_MAY_UPDATE, 'example.com')
378 self.assertIn('add a comment', footer)
379 self.assertIn('make updates', footer)
380 self.assertIn('https://example.com/hosting/settings', footer)
381
382
383 if __name__ == '__main__':
384 unittest.main()
OLDNEW
« no previous file with comments | « appengine/monorail/features/test/inboundemail_test.py ('k') | appengine/monorail/features/test/notify_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698