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

Side by Side Diff: appengine/monorail/tracker/test/issuedetail_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 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered by a BSD-style
3 # license that can be found in the LICENSE file or at
4 # https://developers.google.com/open-source/licenses/bsd
5
6 """Unittests for monorail.tracker.issuedetail."""
7
8 import logging
9 import mox
10 import time
11 import unittest
12
13 import settings
14 from features import notify
15 from framework import permissions
16 from framework import template_helpers
17 from proto import project_pb2
18 from proto import tracker_pb2
19 from proto import user_pb2
20 from services import service_manager
21 from services import issue_svc
22 from testing import fake
23 from testing import testing_helpers
24 from tracker import issuedetail
25 from tracker import tracker_constants
26 from tracker import tracker_helpers
27
28
29 class IssueDetailTest(unittest.TestCase):
30
31 def setUp(self):
32 self.cnxn = 'fake cnxn'
33 self.services = service_manager.Services(
34 config=fake.ConfigService(),
35 issue=fake.IssueService(),
36 user=fake.UserService(),
37 project=fake.ProjectService(),
38 issue_star=fake.IssueStarService(),
39 spam=fake.SpamService())
40 self.project = self.services.project.TestAddProject('proj', project_id=987)
41 self.config = tracker_pb2.ProjectIssueConfig()
42 self.config.statuses_offer_merge.append('Duplicate')
43 self.services.config.StoreConfig(self.cnxn, self.config)
44
45 def testChooseNextPage(self):
46 mr = testing_helpers.MakeMonorailRequest(
47 path='/p/proj/issues/detail?id=123&q=term')
48 mr.col_spec = ''
49 config = tracker_pb2.ProjectIssueConfig()
50 issue = fake.MakeTestIssue(987, 123, 'summary', 'New', 111L)
51
52 url = issuedetail._ChooseNextPage(
53 mr, issue.local_id, config, None, None,
54 user_pb2.IssueUpdateNav.UP_TO_LIST, '124')
55 self.assertTrue(url.startswith(
56 'http://127.0.0.1/p/proj/issues/list?cursor=proj%3A123&q=term'))
57 self.assertTrue(url.endswith('&updated=123'))
58
59 url = issuedetail._ChooseNextPage(
60 mr, issue.local_id, config, None, None,
61 user_pb2.IssueUpdateNav.STAY_SAME_ISSUE, '124')
62 self.assertEqual('http://127.0.0.1/p/proj/issues/detail?id=123&q=term',
63 url)
64
65 url = issuedetail._ChooseNextPage(
66 mr, issue.local_id, config, None, None,
67 user_pb2.IssueUpdateNav.NEXT_IN_LIST, '124')
68 self.assertEqual('http://127.0.0.1/p/proj/issues/detail?id=124&q=term',
69 url)
70
71 # If this is the last in the list, the next_id from the form will be ''.
72 url = issuedetail._ChooseNextPage(
73 mr, issue.local_id, config, None, None,
74 user_pb2.IssueUpdateNav.NEXT_IN_LIST, '')
75 self.assertTrue(url.startswith(
76 'http://127.0.0.1/p/proj/issues/list?cursor=proj%3A123&q=term'))
77 self.assertTrue(url.endswith('&updated=123'))
78
79 def testChooseNextPage_ForMoveRequest(self):
80 mr = testing_helpers.MakeMonorailRequest(
81 path='/p/proj/issues/detail?id=123&q=term')
82 mr.col_spec = ''
83 config = tracker_pb2.ProjectIssueConfig()
84 issue = fake.MakeTestIssue(987, 123, 'summary', 'New', 111L)
85 moved_to_project_name = 'projB'
86 moved_to_project_local_id = 543
87 moved_to_project_name_and_local_id = (moved_to_project_name,
88 moved_to_project_local_id)
89
90 url = issuedetail._ChooseNextPage(
91 mr, issue.local_id, config, moved_to_project_name_and_local_id, None,
92 user_pb2.IssueUpdateNav.UP_TO_LIST, '124')
93 self.assertTrue(url.startswith(
94 'http://127.0.0.1/p/proj/issues/list?cursor=proj%3A123&moved_to_id=' +
95 str(moved_to_project_local_id) + '&moved_to_project=' +
96 moved_to_project_name + '&q=term'))
97
98 url = issuedetail._ChooseNextPage(
99 mr, issue.local_id, config, moved_to_project_name_and_local_id, None,
100 user_pb2.IssueUpdateNav.STAY_SAME_ISSUE, '124')
101 self.assertEqual(
102 'http://127.0.0.1/p/%s/issues/detail?id=123&q=term' % (
103 moved_to_project_name),
104 url)
105 mr.project_name = 'proj' # reset project name back.
106
107 url = issuedetail._ChooseNextPage(
108 mr, issue.local_id, config, moved_to_project_name_and_local_id, None,
109 user_pb2.IssueUpdateNav.NEXT_IN_LIST, '124')
110 self.assertEqual('http://127.0.0.1/p/proj/issues/detail?id=124&q=term',
111 url)
112
113 # If this is the last in the list, the next_id from the form will be ''.
114 url = issuedetail._ChooseNextPage(
115 mr, issue.local_id, config, moved_to_project_name_and_local_id, None,
116 user_pb2.IssueUpdateNav.NEXT_IN_LIST, '')
117 self.assertTrue(url.startswith(
118 'http://127.0.0.1/p/proj/issues/list?cursor=proj%3A123&moved_to_id=' +
119 str(moved_to_project_local_id) + '&moved_to_project=' +
120 moved_to_project_name + '&q=term'))
121
122 def testChooseNextPage_ForCopyRequest(self):
123 mr = testing_helpers.MakeMonorailRequest(
124 path='/p/proj/issues/detail?id=123&q=term')
125 mr.col_spec = ''
126 config = tracker_pb2.ProjectIssueConfig()
127 issue = fake.MakeTestIssue(987, 123, 'summary', 'New', 111L)
128 copied_to_project_name = 'projB'
129 copied_to_project_local_id = 543
130 copied_to_project_name_and_local_id = (copied_to_project_name,
131 copied_to_project_local_id)
132
133 url = issuedetail._ChooseNextPage(
134 mr, issue.local_id, config, None, copied_to_project_name_and_local_id,
135 user_pb2.IssueUpdateNav.UP_TO_LIST, '124')
136 self.assertTrue(url.startswith(
137 'http://127.0.0.1/p/proj/issues/list?copied_from_id=123'
138 '&copied_to_id=' + str(copied_to_project_local_id) +
139 '&copied_to_project=' + copied_to_project_name +
140 '&cursor=proj%3A123&q=term'))
141
142 url = issuedetail._ChooseNextPage(
143 mr, issue.local_id, config, None, copied_to_project_name_and_local_id,
144 user_pb2.IssueUpdateNav.STAY_SAME_ISSUE, '124')
145 self.assertEqual('http://127.0.0.1/p/proj/issues/detail?id=123&q=term', url)
146 mr.project_name = 'proj' # reset project name back.
147
148 url = issuedetail._ChooseNextPage(
149 mr, issue.local_id, config, None, copied_to_project_name_and_local_id,
150 user_pb2.IssueUpdateNav.NEXT_IN_LIST, '124')
151 self.assertEqual('http://127.0.0.1/p/proj/issues/detail?id=124&q=term',
152 url)
153
154 # If this is the last in the list, the next_id from the form will be ''.
155 url = issuedetail._ChooseNextPage(
156 mr, issue.local_id, config, None, copied_to_project_name_and_local_id,
157 user_pb2.IssueUpdateNav.NEXT_IN_LIST, '')
158 self.assertTrue(url.startswith(
159 'http://127.0.0.1/p/proj/issues/list?copied_from_id=123'
160 '&copied_to_id=' + str(copied_to_project_local_id) +
161 '&copied_to_project=' + copied_to_project_name +
162 '&cursor=proj%3A123&q=term'))
163
164 def testGatherHelpData(self):
165 servlet = issuedetail.IssueDetail('req', 'res', services=self.services)
166 mr = testing_helpers.MakeMonorailRequest()
167
168 # User did not jump to an issue, no query at all.
169 help_data = servlet.GatherHelpData(mr, {})
170 self.assertEqual(None, help_data['cue'])
171
172 # User did not jump to an issue, query was not a local ID number.
173 mr.query = 'memory leak'
174 help_data = servlet.GatherHelpData(mr, {})
175 self.assertEqual(None, help_data['cue'])
176
177 # User jumped directly to an issue, maybe they meant to search instead.
178 mr.query = '123'
179 help_data = servlet.GatherHelpData(mr, {})
180 self.assertEqual('search_for_numbers', help_data['cue'])
181 self.assertEqual(123, help_data['jump_local_id'])
182
183
184 class IssueDetailFunctionsTest(unittest.TestCase):
185
186 def setUp(self):
187 self.project_name = 'proj'
188 self.project_id = 987
189 self.cnxn = 'fake cnxn'
190 self.services = service_manager.Services(
191 config=fake.ConfigService(),
192 issue=fake.IssueService(),
193 issue_star=fake.IssueStarService(),
194 project=fake.ProjectService(),
195 user=fake.UserService())
196 self.project = self.services.project.TestAddProject(
197 'proj', project_id=987, committer_ids=[111L])
198 self.servlet = issuedetail.IssueDetail(
199 'req', 'res', services=self.services)
200 self.mox = mox.Mox()
201
202 def tearDown(self):
203 self.mox.UnsetStubs()
204 self.mox.ResetAll()
205
206 def VerifyShouldShowFlipper(
207 self, expected, query, sort_spec, can, create_issues=0):
208 """Instantiate a _Flipper and check if makes a pipeline or not."""
209 services = service_manager.Services(
210 config=fake.ConfigService(),
211 issue=fake.IssueService(),
212 project=fake.ProjectService(),
213 user=fake.UserService())
214 mr = testing_helpers.MakeMonorailRequest(project=self.project)
215 mr.query = query
216 mr.sort_spec = sort_spec
217 mr.can = can
218 mr.project_name = self.project.project_name
219 mr.project = self.project
220
221 for idx in range(create_issues):
222 _local_id = services.issue.CreateIssue(
223 self.cnxn, services, self.project.project_id,
224 'summary_%d' % idx, 'status', 111L, [], [], [], [], 111L,
225 'description_%d' % idx)
226
227 self.assertEqual(
228 expected,
229 issuedetail._ShouldShowFlipper(mr, services))
230
231 def testShouldShowFlipper_RegularSizedProject(self):
232 # If the user is looking for a specific issue, no flipper.
233 self.VerifyShouldShowFlipper(
234 False, '123', '', tracker_constants.OPEN_ISSUES_CAN)
235 self.VerifyShouldShowFlipper(False, '123', '', 5)
236 self.VerifyShouldShowFlipper(
237 False, '123', 'priority', tracker_constants.OPEN_ISSUES_CAN)
238
239 # If the user did a search or sort or all in a small can, show flipper.
240 self.VerifyShouldShowFlipper(
241 True, 'memory leak', '', tracker_constants.OPEN_ISSUES_CAN)
242 self.VerifyShouldShowFlipper(
243 True, 'id=1,2,3', '', tracker_constants.OPEN_ISSUES_CAN)
244 # Any can other than 1 or 2 is doing a query and so it should have a
245 # failry narrow result set size. 5 is issues starred by me.
246 self.VerifyShouldShowFlipper(True, '', '', 5)
247 self.VerifyShouldShowFlipper(
248 True, '', 'status', tracker_constants.OPEN_ISSUES_CAN)
249
250 # In a project without a huge number of issues, still show the flipper even
251 # if there was no specific query.
252 self.VerifyShouldShowFlipper(
253 True, '', '', tracker_constants.OPEN_ISSUES_CAN)
254
255 def testShouldShowFlipper_LargeSizedProject(self):
256 settings.threshold_to_suppress_prev_next = 1
257
258 # In a project that has tons of issues, save time by not showing the
259 # flipper unless there was a specific query, sort, or can.
260 self.VerifyShouldShowFlipper(
261 False, '', '', tracker_constants.ALL_ISSUES_CAN, create_issues=3)
262 self.VerifyShouldShowFlipper(
263 False, '', '', tracker_constants.OPEN_ISSUES_CAN, create_issues=3)
264
265 def testFieldEditPermitted_NoEdit(self):
266 page_perms = testing_helpers.Blank(
267 EditIssueSummary=False, EditIssueStatus=False, EditIssueOwner=False,
268 EditIssueCc=False) # no perms are needed.
269 self.assertTrue(issuedetail._FieldEditPermitted(
270 [], '', '', '', '', 0, [], page_perms))
271
272 def testFieldEditPermitted_AllNeededPerms(self):
273 page_perms = testing_helpers.Blank(
274 EditIssueSummary=True, EditIssueStatus=True, EditIssueOwner=True,
275 EditIssueCc=True)
276 self.assertTrue(issuedetail._FieldEditPermitted(
277 [], '', '', 'new sum', 'new status', 111L, [222L], page_perms))
278
279 def testFieldEditPermitted_MissingPerms(self):
280 page_perms = testing_helpers.Blank(
281 EditIssueSummary=False, EditIssueStatus=False, EditIssueOwner=False,
282 EditIssueCc=False) # no perms.
283 self.assertFalse(issuedetail._FieldEditPermitted(
284 [], '', '', 'new sum', '', 0, [], page_perms))
285 self.assertFalse(issuedetail._FieldEditPermitted(
286 [], '', '', '', 'new status', 0, [], page_perms))
287 self.assertFalse(issuedetail._FieldEditPermitted(
288 [], '', '', '', '', 111L, [], page_perms))
289 self.assertFalse(issuedetail._FieldEditPermitted(
290 [], '', '', '', '', 0, [222L], page_perms))
291
292 def testFieldEditPermitted_NeededPermsNotOffered(self):
293 """Even if user has all the field-level perms, they still can't do this."""
294 page_perms = testing_helpers.Blank(
295 EditIssueSummary=True, EditIssueStatus=True, EditIssueOwner=True,
296 EditIssueCc=True)
297 self.assertFalse(issuedetail._FieldEditPermitted(
298 ['NewLabel'], '', '', '', '', 0, [], page_perms))
299 self.assertFalse(issuedetail._FieldEditPermitted(
300 [], 'new blocked on', '', '', '', 0, [], page_perms))
301 self.assertFalse(issuedetail._FieldEditPermitted(
302 [], '', 'new blocking', '', '', 0, [], page_perms))
303
304 def testValidateOwner_ChangedToValidOwner(self):
305 post_data_owner = 'superman@krypton.com'
306 parsed_owner_id = 111
307 original_issue_owner_id = 111
308 mr = testing_helpers.MakeMonorailRequest(project=self.project)
309
310 self.mox.StubOutWithMock(tracker_helpers, 'IsValidIssueOwner')
311 tracker_helpers.IsValidIssueOwner(
312 mr.cnxn, mr.project, parsed_owner_id, self.services).AndReturn(
313 (True, ''))
314 self.mox.ReplayAll()
315
316 ret = self.servlet._ValidateOwner(
317 mr, post_data_owner, parsed_owner_id, original_issue_owner_id)
318 self.mox.VerifyAll()
319 self.assertIsNone(ret)
320
321 def testValidateOwner_UnchangedInvalidOwner(self):
322 post_data_owner = 'superman@krypton.com'
323 parsed_owner_id = 111
324 original_issue_owner_id = 111
325 mr = testing_helpers.MakeMonorailRequest(project=self.project)
326 self.services.user.TestAddUser(post_data_owner, original_issue_owner_id)
327
328 self.mox.StubOutWithMock(tracker_helpers, 'IsValidIssueOwner')
329 tracker_helpers.IsValidIssueOwner(
330 mr.cnxn, mr.project, parsed_owner_id, self.services).AndReturn(
331 (False, 'invalid owner'))
332 self.mox.ReplayAll()
333
334 ret = self.servlet._ValidateOwner(
335 mr, post_data_owner, parsed_owner_id, original_issue_owner_id)
336 self.mox.VerifyAll()
337 self.assertIsNone(ret)
338
339 def testValidateOwner_ChangedFromValidToInvalidOwner(self):
340 post_data_owner = 'lexluthor'
341 parsed_owner_id = 111
342 original_issue_owner_id = 111
343 original_issue_owner = 'superman@krypton.com'
344 mr = testing_helpers.MakeMonorailRequest(project=self.project)
345 self.services.user.TestAddUser(original_issue_owner,
346 original_issue_owner_id)
347
348 self.mox.StubOutWithMock(tracker_helpers, 'IsValidIssueOwner')
349 tracker_helpers.IsValidIssueOwner(
350 mr.cnxn, mr.project, parsed_owner_id, self.services).AndReturn(
351 (False, 'invalid owner'))
352 self.mox.ReplayAll()
353
354 ret = self.servlet._ValidateOwner(
355 mr, post_data_owner, parsed_owner_id, original_issue_owner_id)
356 self.mox.VerifyAll()
357 self.assertEquals('invalid owner', ret)
358
359 def testProcessFormData_NoPermission(self):
360 """Anonymous users and users without ADD_ISSUE_COMMENT cannot comment."""
361 local_id_1 = self.services.issue.CreateIssue(
362 self.cnxn, self.services, self.project.project_id,
363 'summary_1', 'status', 111L, [], [], [], [], 111L, 'description_1')
364 _, mr = testing_helpers.GetRequestObjects(
365 project=self.project,
366 perms=permissions.CONTRIBUTOR_INACTIVE_PERMISSIONSET)
367 mr.auth.user_id = 0
368 mr.local_id = local_id_1
369 self.assertRaises(permissions.PermissionException,
370 self.servlet.ProcessFormData, mr, {})
371 mr.auth.user_id = 111L
372 self.assertRaises(permissions.PermissionException,
373 self.servlet.ProcessFormData, mr, {})
374
375 def testProcessFormData_NonMembersCantEdit(self):
376 """Non-members can comment, but never affect issue fields."""
377 orig_prepsend = notify.PrepareAndSendIssueChangeNotification
378 notify.PrepareAndSendIssueChangeNotification = lambda *args, **kwargs: None
379
380 local_id_1 = self.services.issue.CreateIssue(
381 self.cnxn, self.services, self.project.project_id,
382 'summary_1', 'status', 111L, [], [], [], [], 111L, 'description_1')
383 local_id_2 = self.services.issue.CreateIssue(
384 self.cnxn, self.services, self.project.project_id,
385 'summary_2', 'status', 111L, [], [], [], [], 111L, 'description_2')
386
387 _amendments, _cmnt_pb = self.services.issue.ApplyIssueComment(
388 self.cnxn, self.services, 111L,
389 self.project.project_id, local_id_2, 'summary', 'Duplicate', 111L,
390 [], [], [], [], [], [], [], [], local_id_1,
391 comment='closing as a dup of 1')
392
393 non_member_user_id = 999L
394 post_data = fake.PostData({
395 'merge_into': [''], # non-member tries to remove merged_into
396 'comment': ['thanks!'],
397 'can': ['1'],
398 'q': ['foo'],
399 'colspec': ['bar'],
400 'sort': 'baz',
401 'groupby': 'qux',
402 'start': ['0'],
403 'num': ['100'],
404 'pagegen': [str(int(time.time()) + 1)],
405 })
406
407 _, mr = testing_helpers.GetRequestObjects(
408 user_info={'user_id': non_member_user_id},
409 path='/p/proj/issues/detail.do?id=%d' % local_id_2,
410 project=self.project, method='POST',
411 perms=permissions.USER_PERMISSIONSET)
412 mr.project_name = self.project.project_name
413 mr.project = self.project
414
415 # The form should be processed and redirect back to viewing the issue.
416 redirect_url = self.servlet.ProcessFormData(mr, post_data)
417 self.assertTrue(redirect_url.startswith(
418 'http://127.0.0.1/p/proj/issues/detail?id=%d' % local_id_2))
419
420 # BUT, issue should not have been edited because user lacked permission.
421 updated_issue_2 = self.services.issue.GetIssueByLocalID(
422 self.cnxn, self.project.project_id, local_id_2)
423 self.assertEqual(local_id_1, updated_issue_2.merged_into)
424
425 notify.PrepareAndSendIssueChangeNotification = orig_prepsend
426
427 def testProcessFormData_DuplicateAddsACommentToTarget(self):
428 """Marking issue 2 as dup of 1 adds a comment to 1."""
429 orig_prepsend = notify.PrepareAndSendIssueChangeNotification
430 notify.PrepareAndSendIssueChangeNotification = lambda *args, **kwargs: None
431 orig_get_starrers = tracker_helpers.GetNewIssueStarrers
432 tracker_helpers.GetNewIssueStarrers = lambda *args, **kwargs: []
433
434 local_id_1 = self.services.issue.CreateIssue(
435 self.cnxn, self.services, self.project.project_id,
436 'summary_1', 'New', 111L, [], [], [], [], 111L, 'description_1')
437 issue_1 = self.services.issue.GetIssueByLocalID(
438 self.cnxn, self.project.project_id, local_id_1)
439 issue_1.project_name = 'proj'
440 local_id_2 = self.services.issue.CreateIssue(
441 self.cnxn, self.services, self.project.project_id,
442 'summary_2', 'New', 111L, [], [], [], [], 111L, 'description_2')
443 issue_2 = self.services.issue.GetIssueByLocalID(
444 self.cnxn, self.project.project_id, local_id_2)
445 issue_2.project_name = 'proj'
446
447 post_data = fake.PostData({
448 'status': ['Duplicate'],
449 'merge_into': [str(local_id_1)],
450 'comment': ['marking as dup'],
451 'can': ['1'],
452 'q': ['foo'],
453 'colspec': ['bar'],
454 'sort': 'baz',
455 'groupby': 'qux',
456 'start': ['0'],
457 'num': ['100'],
458 'pagegen': [str(int(time.time()) + 1)],
459 })
460
461 member_user_id = 111L
462 _, mr = testing_helpers.GetRequestObjects(
463 user_info={'user_id': member_user_id},
464 path='/p/proj/issues/detail.do?id=%d' % local_id_2,
465 project=self.project, method='POST',
466 perms=permissions.COMMITTER_ACTIVE_PERMISSIONSET)
467 mr.project_name = self.project.project_name
468 mr.project = self.project
469
470 # The form should be processed and redirect back to viewing the issue.
471 self.servlet.ProcessFormData(mr, post_data)
472
473 self.assertEqual('Duplicate', issue_2.status)
474 self.assertEqual(issue_1.issue_id, issue_2.merged_into)
475 comments_1 = self.services.issue.GetCommentsForIssue(
476 self.cnxn, issue_1.issue_id)
477 self.assertEqual(2, len(comments_1))
478 self.assertEqual(
479 'Issue 2 has been merged into this issue.',
480 comments_1[1].content)
481
482 # Making another comment on issue 2 does not affect issue 1.
483 self.servlet.ProcessFormData(mr, post_data)
484 comments_1 = self.services.issue.GetCommentsForIssue(
485 self.cnxn, issue_1.issue_id)
486 self.assertEqual(2, len(comments_1))
487
488 notify.PrepareAndSendIssueChangeNotification = orig_prepsend
489 tracker_helpers.GetNewIssueStarrers = orig_get_starrers
490
491 # TODO(jrobbins): add more unit tests for other aspects of ProcessForm.
492
493
494 class SetStarFormTest(unittest.TestCase):
495
496 def setUp(self):
497 self.cnxn = 'fake cnxn'
498 self.services = service_manager.Services(
499 config=fake.ConfigService(),
500 issue=fake.IssueService(),
501 user=fake.UserService(),
502 project=fake.ProjectService(),
503 issue_star=fake.IssueStarService())
504 self.project = self.services.project.TestAddProject('proj', project_id=987)
505 self.servlet = issuedetail.SetStarForm(
506 'req', 'res', services=self.services)
507
508 def testAssertBasePermission(self):
509 """Only users with SET_STAR could set star."""
510 local_id_1 = self.services.issue.CreateIssue(
511 self.cnxn, self.services, self.project.project_id,
512 'summary_1', 'status', 111L, [], [], [], [], 111L, 'description_1')
513 _, mr = testing_helpers.GetRequestObjects(
514 project=self.project,
515 perms=permissions.READ_ONLY_PERMISSIONSET)
516 mr.local_id = local_id_1
517 self.assertRaises(permissions.PermissionException,
518 self.servlet.AssertBasePermission, mr)
519 _, mr = testing_helpers.GetRequestObjects(
520 project=self.project,
521 perms=permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET)
522 mr.local_id = local_id_1
523 self.servlet.AssertBasePermission(mr)
524
525
526 class IssueCommentDeletionTest(unittest.TestCase):
527
528 def setUp(self):
529 self.cnxn = 'fake cnxn'
530 self.services = service_manager.Services(
531 config=fake.ConfigService(),
532 issue=fake.IssueService(),
533 user=fake.UserService(),
534 project=fake.ProjectService(),
535 issue_star=fake.IssueStarService())
536 self.project = self.services.project.TestAddProject('proj', project_id=987)
537 self.servlet = issuedetail.IssueCommentDeletion(
538 'req', 'res', services=self.services)
539
540 def testProcessFormData_Permission(self):
541 """Permit users who can delete."""
542 local_id_1 = self.services.issue.CreateIssue(
543 self.cnxn, self.services, self.project.project_id,
544 'summary_1', 'status', 111L, [], [], [], [], 111L, 'description_1')
545 _, mr = testing_helpers.GetRequestObjects(
546 project=self.project,
547 perms=permissions.READ_ONLY_PERMISSIONSET)
548 mr.local_id = local_id_1
549 mr.auth.user_id = 222L
550 post_data = {
551 'id': local_id_1,
552 'sequence_num': 0,
553 'mode': 0}
554 self.assertRaises(permissions.PermissionException,
555 self.servlet.ProcessFormData, mr, post_data)
556 _, mr = testing_helpers.GetRequestObjects(
557 project=self.project,
558 perms=permissions.OWNER_ACTIVE_PERMISSIONSET)
559 mr.local_id = local_id_1
560 mr.auth.user_id = 222L
561 self.servlet.ProcessFormData(mr, post_data)
562
563
564 if __name__ == '__main__':
565 unittest.main()
OLDNEW
« no previous file with comments | « appengine/monorail/tracker/test/issuebulkedit_test.py ('k') | appengine/monorail/tracker/test/issueentry_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698