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

Side by Side Diff: appengine/monorail/tracker/test/issuebulkedit_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.issuebulkedit."""
7
8 import os
9 import unittest
10 import webapp2
11
12 from google.appengine.api import memcache
13 from google.appengine.api import taskqueue
14 from google.appengine.ext import testbed
15
16 from framework import monorailrequest
17 from framework import permissions
18 from proto import tracker_pb2
19 from services import service_manager
20 from services import tracker_fulltext
21 from testing import fake
22 from testing import testing_helpers
23 from tracker import issuebulkedit
24 from tracker import tracker_bizobj
25
26
27 class Response(object):
28
29 def __init__(self):
30 self.status = None
31
32
33 class IssueBulkEditTest(unittest.TestCase):
34
35 def setUp(self):
36 self.services = service_manager.Services(
37 features=fake.FeaturesService(),
38 project=fake.ProjectService(),
39 config=fake.ConfigService(),
40 issue=fake.IssueService(),
41 issue_star=fake.IssueStarService(),
42 user=fake.UserService(),
43 usergroup=fake.UserGroupService())
44 self.servlet = issuebulkedit.IssueBulkEdit(
45 'req', 'res', services=self.services)
46 self.mr = testing_helpers.MakeMonorailRequest(
47 perms=permissions.OWNER_ACTIVE_PERMISSIONSET)
48 self.project = self.services.project.TestAddProject(
49 name='proj', project_id=789, owner_ids=[111])
50 self.cnxn = 'fake connection'
51 self.config = self.services.config.GetProjectConfig(
52 self.cnxn, self.project.project_id)
53 self.services.config.StoreConfig(self.cnxn, self.config)
54 self.owner = self.services.user.TestAddUser('owner@example.com', 111)
55
56 self.testbed = testbed.Testbed()
57 self.testbed.activate()
58 self.testbed.init_taskqueue_stub()
59 self.testbed.init_memcache_stub()
60 self.testbed.init_datastore_v3_stub()
61 self.taskqueue_stub = self.testbed.get_stub(testbed.TASKQUEUE_SERVICE_NAME)
62 self.taskqueue_stub._root_path = os.path.dirname(
63 os.path.dirname(os.path.dirname( __file__ )))
64
65 self.mocked_methods = {}
66
67 def tearDown(self):
68 """Restore mocked objects of other modules."""
69 for obj, items in self.mocked_methods.iteritems():
70 for member, previous_value in items.iteritems():
71 setattr(obj, member, previous_value)
72
73 def testAssertBasePermission(self):
74 """Permit users with EDIT_ISSUE and ADD_ISSUE_COMMENT permissions."""
75 mr = testing_helpers.MakeMonorailRequest(
76 perms=permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET)
77 self.assertRaises(permissions.PermissionException,
78 self.servlet.AssertBasePermission, mr)
79
80 self.servlet.AssertBasePermission(self.mr)
81
82 def testGatherPageData(self):
83 """Test GPD works in a normal no-corner-cases case."""
84 local_id_1 = self.services.issue.CreateIssue(
85 self.cnxn, self.services, 789, 'issue summary', 'New', None,
86 [], [], [], [], 111L, 'test issue')
87 mr = testing_helpers.MakeMonorailRequest(
88 project=self.project)
89 mr.local_id_list = [local_id_1]
90
91 page_data = self.servlet.GatherPageData(mr)
92 self.assertEqual(1, page_data['num_issues'])
93
94 def testGatherPageData_NoIssues(self):
95 """Test GPD when no issues are specified in the mr."""
96 mr = testing_helpers.MakeMonorailRequest(
97 project=self.project)
98 self.assertRaises(monorailrequest.InputException,
99 self.servlet.GatherPageData, mr)
100
101 def testGatherPageData_FilteredIssues(self):
102 """Test GPD when all specified issues get filtered out."""
103 local_id_1 = self.services.issue.CreateIssue(
104 self.cnxn, self.services, 789, 'issue summary', 'New', None, [],
105 ['restrict-view-Googler'], [], [],
106 111L, 'test issue')
107 mr = testing_helpers.MakeMonorailRequest(
108 project=self.project)
109 mr.local_id_list = [local_id_1]
110
111 self.assertRaises(webapp2.HTTPException,
112 self.servlet.GatherPageData, mr)
113
114 def testGatherPageData_TypeLabels(self):
115 """Test that GPD displays a custom field for appropriate issues."""
116 local_id_1 = self.services.issue.CreateIssue(
117 self.cnxn, self.services, 789, 'issue summary', 'New', None, [],
118 ['type-customlabels'], [], [],
119 111L, 'test issue')
120 mr = testing_helpers.MakeMonorailRequest(
121 project=self.project)
122 mr.local_id_list = [local_id_1]
123
124 fd = tracker_bizobj.MakeFieldDef(
125 123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None,
126 '', False, False, None, None, '', False, '', '',
127 tracker_pb2.NotifyTriggers.NEVER, 'doc', False)
128 self.config.field_defs.append(fd)
129
130 page_data = self.servlet.GatherPageData(mr)
131 self.assertEqual(1, len(page_data['fields']))
132
133 def testProcessFormData(self):
134 """Test that PFD works in a normal no-corner-cases case."""
135 local_id_1 = self.services.issue.CreateIssue(
136 self.cnxn, self.services, 789, 'issue summary', 'New', 111L,
137 [], [], [], [], 111L, 'test issue')
138 mr = testing_helpers.MakeMonorailRequest(
139 project=self.project,
140 perms=permissions.OWNER_ACTIVE_PERMISSIONSET,
141 user_info={'user_id': 111})
142 mr.local_id_list = [local_id_1]
143
144 post_data = fake.PostData(
145 owner=['owner@example.com'], can=[1],
146 q=[''], colspec=[''], sort=[''], groupby=[''], start=[0], num=[100])
147 self._MockMethods()
148 url = self.servlet.ProcessFormData(mr, post_data)
149 self.assertTrue('list?can=1&saved=1' in url)
150
151 def testProcessFormData_NoIssues(self):
152 """Test PFD when no issues are specified."""
153 mr = testing_helpers.MakeMonorailRequest(
154 project=self.project,
155 perms=permissions.OWNER_ACTIVE_PERMISSIONSET,
156 user_info={'user_id': 111})
157 post_data = fake.PostData()
158 self.servlet.response = Response()
159 self.servlet.ProcessFormData(mr, post_data)
160 # 400 == bad request
161 self.assertEqual(400, self.servlet.response.status)
162
163 def testProcessFormData_NoUser(self):
164 """Test PDF when the user is not logged in."""
165 mr = testing_helpers.MakeMonorailRequest(
166 project=self.project)
167 mr.local_id_list = [99999]
168 post_data = fake.PostData()
169 self.servlet.response = Response()
170 self.servlet.ProcessFormData(mr, post_data)
171 # 400 == bad request
172 self.assertEqual(400, self.servlet.response.status)
173
174 def testProcessFormData_CantComment(self):
175 """Test PFD when the user can't comment on any of the issues."""
176 mr = testing_helpers.MakeMonorailRequest(
177 project=self.project,
178 perms=permissions.EMPTY_PERMISSIONSET,
179 user_info={'user_id': 111})
180 mr.local_id_list = [99999]
181 post_data = fake.PostData()
182 self.servlet.response = Response()
183 self.servlet.ProcessFormData(mr, post_data)
184 # 400 == bad request
185 self.assertEqual(400, self.servlet.response.status)
186
187 def testProcessFormData_CantEdit(self):
188 """Test PFD when the user can't edit any issue metadata."""
189 mr = testing_helpers.MakeMonorailRequest(
190 project=self.project,
191 perms=permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET,
192 user_info={'user_id': 111})
193 mr.local_id_list = [99999]
194 post_data = fake.PostData()
195 self.servlet.response = Response()
196 self.servlet.ProcessFormData(mr, post_data)
197 # 400 == bad request
198 self.assertEqual(400, self.servlet.response.status)
199
200 def testProcessFormData_CantMove(self):
201 """Test PFD when the user can't move issues."""
202 mr = testing_helpers.MakeMonorailRequest(
203 project=self.project,
204 perms=permissions.COMMITTER_ACTIVE_PERMISSIONSET,
205 user_info={'user_id': 111})
206 mr.local_id_list = [99999]
207 post_data = fake.PostData(move_to=['proj'])
208 self.servlet.response = Response()
209 self.servlet.ProcessFormData(mr, post_data)
210 # 400 == bad request
211 self.assertEqual(400, self.servlet.response.status)
212
213 local_id_1 = self.services.issue.CreateIssue(
214 self.cnxn, self.services, 789, 'issue summary', 'New', 111L,
215 [], [], [], [], 111L, 'test issue')
216 mr.perms = permissions.OWNER_ACTIVE_PERMISSIONSET
217 mr.local_id_list = [local_id_1]
218 mr.project_name = 'proj'
219 self._MockMethods()
220 self.servlet.ProcessFormData(mr, post_data)
221 self.assertEqual(
222 'The issues are already in project proj', mr.errors.move_to)
223
224 post_data = fake.PostData(move_to=['notexist'])
225 self.servlet.ProcessFormData(mr, post_data)
226 self.assertEqual('No such project: notexist', mr.errors.move_to)
227
228 def _MockMethods(self):
229 # Mock methods of other modules to avoid unnecessary testing
230 self.mocked_methods[tracker_fulltext] = {
231 'IndexIssues': tracker_fulltext.IndexIssues,
232 'UnindexIssues': tracker_fulltext.UnindexIssues}
233 def DoNothing(*_args, **_kwargs):
234 pass
235 self.servlet.PleaseCorrect = DoNothing
236 tracker_fulltext.IndexIssues = DoNothing
237 tracker_fulltext.UnindexIssues = DoNothing
238
239 def VerifyIssueUpdated(self, project_id, local_id):
240 issue = self.services.issue.GetIssueByLocalID(
241 self.cnxn, project_id, local_id)
242 issue_id = issue.issue_id
243 comments = self.services.issue.GetCommentsForIssue(self.cnxn, issue_id)
244 last_comment = comments[-1]
245 if last_comment.amendments[0].newvalue == 'Updated':
246 return True
247 else:
248 return False
249
250 def testProcessFormData_CustomFields(self):
251 """Test PFD processes edits to custom fields."""
252 local_id_1 = self.services.issue.CreateIssue(
253 self.cnxn, self.services, 789, 'issue summary', 'New', 111L,
254 [], [], [], [], 111L, 'test issue')
255 mr = testing_helpers.MakeMonorailRequest(
256 project=self.project,
257 perms=permissions.OWNER_ACTIVE_PERMISSIONSET,
258 user_info={'user_id': 111})
259 mr.local_id_list = [local_id_1]
260
261 fd = tracker_bizobj.MakeFieldDef(
262 12345, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None,
263 '', False, False, None, None, '', False, '', '',
264 tracker_pb2.NotifyTriggers.NEVER, 'doc', False)
265 self.config.field_defs.append(fd)
266
267 post_data = fake.PostData(
268 custom_12345=['111'], owner=['owner@example.com'], can=[1],
269 q=[''], colspec=[''], sort=[''], groupby=[''], start=[0], num=[100])
270 self._MockMethods()
271 self.servlet.ProcessFormData(mr, post_data)
272 self.assertTrue(self.VerifyIssueUpdated(789, local_id_1))
273
274 def testProcessFormData_DuplicateStatus_MergeSameIssue(self):
275 """Test PFD processes null/cleared status values."""
276 local_id_1 = self.services.issue.CreateIssue(
277 self.cnxn, self.services, self.project.project_id, 'issue summary',
278 'New', 111L, [], [], [], [], 111L, 'test issue')
279 merge_into_local_id_2 = self.services.issue.CreateIssue(
280 self.cnxn, self.services, self.project.project_id, 'issue summary2',
281 'New', 112L, [], [], [], [], 112L, 'test issue2')
282
283 mr = testing_helpers.MakeMonorailRequest(
284 project=self.project,
285 perms=permissions.OWNER_ACTIVE_PERMISSIONSET,
286 user_info={'user_id': 111})
287 mr.local_id_list = [local_id_1, merge_into_local_id_2]
288 mr.project_name = 'proj'
289
290 # Add required project_name to merge_into_issue.
291 merge_into_issue = self.services.issue.GetIssueByLocalID(
292 mr.cnxn, self.project.project_id, merge_into_local_id_2)
293 merge_into_issue.project_name = 'proj'
294
295 post_data = fake.PostData(status=['Duplicate'],
296 merge_into=[str(merge_into_local_id_2)], owner=['owner@example.com'],
297 can=[1], q=[''], colspec=[''], sort=[''], groupby=[''], start=[0],
298 num=[100])
299 self._MockMethods()
300 self.servlet.ProcessFormData(mr, post_data)
301 self.assertEquals('Cannot merge issue into itself', mr.errors.merge_into_id)
302
303 def testProcessFormData_DuplicateStatus_MergeMissingIssue(self):
304 """Test PFD processes null/cleared status values."""
305 local_id_1 = self.services.issue.CreateIssue(
306 self.cnxn, self.services, self.project.project_id, 'issue summary',
307 'New', 111L, [], [], [], [], 111L, 'test issue')
308 local_id_2 = self.services.issue.CreateIssue(
309 self.cnxn, self.services, self.project.project_id, 'issue summary2',
310 'New', 112L, [], [], [], [], 112L, 'test issue2')
311 mr = testing_helpers.MakeMonorailRequest(
312 project=self.project,
313 perms=permissions.OWNER_ACTIVE_PERMISSIONSET,
314 user_info={'user_id': 111})
315 mr.local_id_list = [local_id_1, local_id_2]
316 mr.project_name = 'proj'
317
318 post_data = fake.PostData(status=['Duplicate'],
319 merge_into=['non existant id'], owner=['owner@example.com'],
320 can=[1], q=[''], colspec=[''], sort=[''], groupby=[''], start=[0],
321 num=[100])
322 self._MockMethods()
323 self.servlet.ProcessFormData(mr, post_data)
324 self.assertEquals('Please enter an issue ID',
325 mr.errors.merge_into_id)
326
327 def testProcessFormData_DuplicateStatus_Success(self):
328 """Test PFD processes null/cleared status values."""
329 local_id_1 = self.services.issue.CreateIssue(
330 self.cnxn, self.services, self.project.project_id, 'issue summary',
331 'New', 111L, [], [], [], [], 111L, 'test issue')
332 local_id_2 = self.services.issue.CreateIssue(
333 self.cnxn, self.services, self.project.project_id, 'issue summary2',
334 'New', 111L, [], [], [], [], 111L, 'test issue2')
335 merge_into_local_id_3 = self.services.issue.CreateIssue(
336 self.cnxn, self.services, self.project.project_id, 'issue summary3',
337 'New', 112L, [], [], [], [], 112L, 'test issue3')
338 mr = testing_helpers.MakeMonorailRequest(
339 project=self.project,
340 perms=permissions.OWNER_ACTIVE_PERMISSIONSET,
341 user_info={'user_id': 111})
342 mr.local_id_list = [local_id_1, local_id_2]
343 mr.project_name = 'proj'
344
345 post_data = fake.PostData(status=['Duplicate'],
346 merge_into=[str(merge_into_local_id_3)], owner=['owner@example.com'],
347 can=[1], q=[''], colspec=[''], sort=[''], groupby=[''], start=[0],
348 num=[100])
349 self._MockMethods()
350
351 # Add project_name, CCs and starrers to the merge_into_issue.
352 merge_into_issue = self.services.issue.GetIssueByLocalID(
353 mr.cnxn, self.project.project_id, merge_into_local_id_3)
354 merge_into_issue.project_name = 'proj'
355 merge_into_issue.cc_ids = [113L, 120L]
356 self.services.issue_star.SetStar(
357 mr.cnxn, None, None, merge_into_issue.issue_id, 120L, True)
358
359 # Add project_name, CCs and starrers to the source issues.
360 # Issue 1
361 issue_1 = self.services.issue.GetIssueByLocalID(
362 mr.cnxn, self.project.project_id, local_id_1)
363 issue_1.project_name = 'proj'
364 issue_1.cc_ids = [113L, 114L]
365 self.services.issue_star.SetStar(
366 mr.cnxn, None, None, issue_1.issue_id, 113L, True)
367 # Issue 2
368 issue_2 = self.services.issue.GetIssueByLocalID(
369 mr.cnxn, self.project.project_id, local_id_2)
370 issue_2.project_name = 'proj'
371 issue_2.cc_ids = [113L, 115L, 118L]
372 self.services.issue_star.SetStar(
373 mr.cnxn, None, None, issue_2.issue_id, 114L, True)
374 self.services.issue_star.SetStar(
375 mr.cnxn, None, None, issue_2.issue_id, 115L, True)
376
377 self.servlet.ProcessFormData(mr, post_data)
378
379 # Verify both source issues were updated.
380 self.assertTrue(
381 self.VerifyIssueUpdated(self.project.project_id, local_id_1))
382 self.assertTrue(
383 self.VerifyIssueUpdated(self.project.project_id, local_id_2))
384
385 # Verify that the merge into issue was updated with a comment.
386 comments = self.services.issue.GetCommentsForIssue(
387 self.cnxn, merge_into_issue.issue_id)
388 self.assertEquals(
389 'Issue 1 has been merged into this issue.\n'
390 'Issue 2 has been merged into this issue.', comments[-1].content)
391
392 # Verify CC lists and owner were merged to the merge_into issue.
393 self.assertEquals(
394 [113L, 120L, 114L, 115L, 118L, 111L], merge_into_issue.cc_ids)
395 # Verify new starrers were added to the merge_into issue.
396 self.assertEquals(4,
397 self.services.issue_star.CountItemStars(
398 self.cnxn, merge_into_issue.issue_id))
399 self.assertEquals([120L, 113L, 114L, 115L],
400 self.services.issue_star.LookupItemStarrers(
401 self.cnxn, merge_into_issue.issue_id))
402
403 def testProcessFormData_ClearStatus(self):
404 """Test PFD processes null/cleared status values."""
405 local_id_1 = self.services.issue.CreateIssue(
406 self.cnxn, self.services, 789, 'issue summary', 'New', 111L,
407 [], [], [], [], 111L, 'test issue')
408 mr = testing_helpers.MakeMonorailRequest(
409 project=self.project,
410 perms=permissions.OWNER_ACTIVE_PERMISSIONSET,
411 user_info={'user_id': 111})
412 mr.local_id_list = [local_id_1]
413
414 post_data = fake.PostData(
415 op_statusenter=['clear'], owner=['owner@example.com'], can=[1],
416 q=[''], colspec=[''], sort=[''], groupby=[''], start=[0], num=[100])
417 self._MockMethods()
418 self.servlet.ProcessFormData(mr, post_data)
419 self.assertTrue(self.VerifyIssueUpdated(789, local_id_1))
420
421 def testProcessFormData_InvalidOwner(self):
422 """Test PFD rejects invalid owner emails."""
423 local_id_1 = self.services.issue.CreateIssue(
424 self.cnxn, self.services, 789, 'issue summary', 'New', None,
425 [], [], [], [], 111L, 'test issue')
426 mr = testing_helpers.MakeMonorailRequest(
427 project=self.project,
428 perms=permissions.OWNER_ACTIVE_PERMISSIONSET,
429 user_info={'user_id': 111})
430 mr.local_id_list = [local_id_1]
431 post_data = fake.PostData(
432 owner=['invalid'])
433 self.servlet.response = Response()
434 self._MockMethods()
435 self.servlet.ProcessFormData(mr, post_data)
436 self.assertTrue(mr.errors.AnyErrors())
437
438 def testProcessFormData_MoveTo(self):
439 """Test PFD processes move_to values."""
440 local_id_1 = self.services.issue.CreateIssue(
441 self.cnxn, self.services, 789, 'issue to move', 'New', 111L,
442 [], [], [], [], 111L, 'test issue')
443 move_to_project = self.services.project.TestAddProject(
444 name='proj2', project_id=790, owner_ids=[111])
445
446 mr = testing_helpers.MakeMonorailRequest(
447 project=self.project,
448 perms=permissions.OWNER_ACTIVE_PERMISSIONSET,
449 user_info={'user_id': 111})
450 mr.project_name = 'proj'
451 mr.local_id_list = [local_id_1]
452
453 self._MockMethods()
454 post_data = fake.PostData(
455 move_to=['proj2'], can=[1], q=[''],
456 colspec=[''], sort=[''], groupby=[''], start=[0], num=[100])
457 self.servlet.response = Response()
458 self.servlet.ProcessFormData(mr, post_data)
459
460 issue = self.services.issue.GetIssueByLocalID(
461 self.cnxn, move_to_project.project_id, local_id_1)
462 self.assertIsNotNone(issue)
OLDNEW
« no previous file with comments | « appengine/monorail/tracker/test/issueattachmenttext_test.py ('k') | appengine/monorail/tracker/test/issuedetail_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698