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

Side by Side Diff: appengine/monorail/tracker/test/tracker_views_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 """Unittest for issue tracker views."""
7
8 import unittest
9
10 import mox
11
12 from google.appengine.api import app_identity
13 from third_party import ezt
14
15 from framework import gcs_helpers
16 from framework import urls
17 from proto import project_pb2
18 from proto import tracker_pb2
19 from testing import testing_helpers
20 from tracker import tracker_views
21
22
23 def _Issue(project_name, local_id, summary, status):
24 issue = tracker_pb2.Issue()
25 issue.project_name = project_name
26 issue.local_id = local_id
27 issue.issue_id = 100000 + local_id
28 issue.summary = summary
29 issue.status = status
30 return issue
31
32
33 def _MakeConfig():
34 config = tracker_pb2.ProjectIssueConfig()
35 config.well_known_statuses.append(tracker_pb2.StatusDef(
36 status='New', means_open=True))
37 config.well_known_statuses.append(tracker_pb2.StatusDef(
38 status='Old', means_open=False))
39 return config
40
41
42 class IssueViewTest(unittest.TestCase):
43
44 def setUp(self):
45 self.issue1 = _Issue('proj', 1, 'not too long summary', 'New')
46 self.issue2 = _Issue('proj', 2, 'sum 2', '')
47 self.issue3 = _Issue('proj', 3, 'sum 3', '')
48 self.issue4 = _Issue('proj', 4, 'sum 4', '')
49
50 self.issue1.reporter_id = 1002
51 self.issue1.owner_id = 2002
52 self.issue1.labels.extend(['A', 'B'])
53 self.issue1.derived_labels.extend(['C', 'D'])
54
55 self.issue2.reporter_id = 2002
56 self.issue2.labels.extend(['foo', 'bar'])
57 self.issue2.blocked_on_iids.extend(
58 [self.issue1.issue_id, self.issue3.issue_id])
59 self.issue2.blocking_iids.extend(
60 [self.issue1.issue_id, self.issue4.issue_id])
61 dref = tracker_pb2.DanglingIssueRef()
62 dref.project = 'codesite'
63 dref.issue_id = 5001
64 self.issue2.dangling_blocking_refs.append(dref)
65
66 self.issue3.reporter_id = 3002
67 self.issue3.labels.extend(['Hot'])
68
69 self.issue4.reporter_id = 3002
70 self.issue4.labels.extend(['Foo', 'Bar'])
71
72 self.restricted = _Issue('proj', 7, 'summary 7', '')
73 self.restricted.labels.extend([
74 'Restrict-View-Commit', 'Restrict-View-MyCustomPerm'])
75 self.restricted.derived_labels.extend([
76 'Restrict-AddIssueComment-Commit', 'Restrict-EditIssue-Commit',
77 'Restrict-Action-NeededPerm'])
78
79 self.users_by_id = {
80 0: 'user 0',
81 1002: 'user 1002',
82 2002: 'user 2002',
83 3002: 'user 3002',
84 4002: 'user 4002',
85 }
86
87 def CheckSimpleIssueView(self, config):
88 view1 = tracker_views.IssueView(
89 self.issue1, self.users_by_id, config)
90 self.assertEqual('not too long summary', view1.summary)
91 self.assertEqual('New', view1.status.name)
92 self.assertEqual('user 2002', view1.owner)
93 self.assertEqual('A', view1.labels[0].name)
94 self.assertEqual('B', view1.labels[1].name)
95 self.assertEqual('C', view1.derived_labels[0].name)
96 self.assertEqual('D', view1.derived_labels[1].name)
97 self.assertEqual([], view1.blocked_on)
98 self.assertEqual([], view1.blocking)
99 detail_url = '/p/%s%s?id=%d' % (
100 self.issue1.project_name, urls.ISSUE_DETAIL,
101 self.issue1.local_id)
102 self.assertEqual(detail_url, view1.detail_relative_url)
103 return view1
104
105 def testSimpleIssueView(self):
106 config = tracker_pb2.ProjectIssueConfig()
107 view1 = self.CheckSimpleIssueView(config)
108 self.assertEqual('', view1.status.docstring)
109
110 config.well_known_statuses.append(tracker_pb2.StatusDef(
111 status='New', status_docstring='Issue has not had review yet'))
112 view1 = self.CheckSimpleIssueView(config)
113 self.assertEqual('Issue has not had review yet',
114 view1.status.docstring)
115 self.assertIsNone(view1.restrictions.has_restrictions)
116 self.assertEqual('', view1.restrictions.view)
117 self.assertEqual('', view1.restrictions.add_comment)
118 self.assertEqual('', view1.restrictions.edit)
119
120 def testIsOpen(self):
121 config = _MakeConfig()
122 view1 = tracker_views.IssueView(
123 self.issue1, self.users_by_id, config)
124 self.assertEqual(ezt.boolean(True), view1.is_open)
125
126 self.issue1.status = 'Old'
127 view1 = tracker_views.IssueView(
128 self.issue1, self.users_by_id, config)
129 self.assertEqual(ezt.boolean(False), view1.is_open)
130
131 def testIssueViewWithBlocking(self):
132 # Treat issues 3 and 4 as visible to the current user.
133 view2 = tracker_views.IssueView(
134 self.issue2, self.users_by_id, _MakeConfig(),
135 open_related={self.issue1.issue_id: self.issue1,
136 self.issue3.issue_id: self.issue3},
137 closed_related={self.issue4.issue_id: self.issue4})
138 self.assertEqual(['not too long summary', 'sum 3'],
139 [ref.summary for ref in view2.blocked_on])
140 self.assertEqual(['not too long summary', 'sum 4',
141 'Issue 5001 in codesite.'],
142 [ref.summary for ref in view2.blocking])
143
144 # Now, treat issues 3 and 4 as not visible to the current user.
145 view2 = tracker_views.IssueView(
146 self.issue2, self.users_by_id, _MakeConfig(),
147 open_related={self.issue1.issue_id: self.issue1}, closed_related={})
148 self.assertEqual(['not too long summary'],
149 [ref.summary for ref in view2.blocked_on])
150 self.assertEqual(['not too long summary', 'Issue 5001 in codesite.'],
151 [ref.summary for ref in view2.blocking])
152
153 # Treat nothing as visible to the current user. Can still see dangling ref.
154 view2 = tracker_views.IssueView(
155 self.issue2, self.users_by_id, _MakeConfig(),
156 open_related={}, closed_related={})
157 self.assertEqual([], view2.blocked_on)
158 self.assertEqual(['Issue 5001 in codesite.'],
159 [ref.summary for ref in view2.blocking])
160
161 def testIssueViewWithRestrictions(self):
162 view = tracker_views.IssueView(
163 self.restricted, self.users_by_id, _MakeConfig())
164 self.assertTrue(view.restrictions.has_restrictions)
165 self.assertEqual('Commit and MyCustomPerm', view.restrictions.view)
166 self.assertEqual('Commit', view.restrictions.add_comment)
167 self.assertEqual('Commit', view.restrictions.edit)
168 self.assertEqual(['Restrict-Action-NeededPerm'], view.restrictions.other)
169 self.assertEqual('Restrict-View-Commit', view.labels[0].name)
170 self.assertTrue(view.labels[0].is_restrict)
171
172
173 class RestrictionsViewTest(unittest.TestCase):
174 pass # TODO(jrobbins): write tests
175
176
177 class IssueRefViewTest(unittest.TestCase):
178
179 issue1 = testing_helpers.Blank(
180 local_id=1,
181 project_name='foo',
182 summary='blue screen')
183 issue2 = testing_helpers.Blank(
184 local_id=2,
185 project_name='foo',
186 summary='hissing noise')
187 issue3 = testing_helpers.Blank(
188 local_id=3,
189 project_name='foo',
190 summary='sinking feeling')
191 issue4 = testing_helpers.Blank(
192 local_id=4,
193 project_name='bar',
194 summary='aliens among us')
195
196 def testNormalCase(self):
197 open_list = {1: self.issue1,
198 2: self.issue2}
199 closed_list = {3: self.issue3}
200
201 ref_iid = 1
202 irv = tracker_views.IssueRefView('foo', ref_iid, open_list, closed_list)
203 self.assertEquals(irv.visible, ezt.boolean(True))
204 self.assertEquals(irv.is_open, ezt.boolean(True))
205 self.assertEquals(irv.url, 'detail?id=1')
206 self.assertEquals(irv.display_name, 'issue 1')
207 self.assertEquals(irv.summary, 'blue screen')
208
209 ref_iid = 3
210 irv = tracker_views.IssueRefView('foo', ref_iid, open_list, closed_list)
211 self.assertEquals(irv.visible, ezt.boolean(True))
212 self.assertEquals(irv.is_open, ezt.boolean(False))
213 self.assertEquals(irv.url, 'detail?id=3')
214 self.assertEquals(irv.display_name, 'issue 3')
215 self.assertEquals(irv.summary, 'sinking feeling')
216
217 def testMissingIssueShouldNotBeVisible(self):
218 open_list = {1: self.issue1,
219 2: self.issue2}
220 closed_list = {3: self.issue3}
221
222 ref_iid = 99
223 irv = tracker_views.IssueRefView('foo', ref_iid, open_list, closed_list)
224 self.assertEquals(irv.visible, ezt.boolean(False))
225
226 def testCrossProjectReference(self):
227 open_list = {1: self.issue1,
228 2: self.issue2}
229 closed_list = {3: self.issue3,
230 4: self.issue4}
231
232 ref_iid = 4
233 irv = tracker_views.IssueRefView('foo', ref_iid, open_list, closed_list)
234 self.assertEquals(irv.visible, ezt.boolean(True))
235 self.assertEquals(irv.is_open, ezt.boolean(False))
236 self.assertEquals(
237 irv.url, '/p/bar%s?id=4' % urls.ISSUE_DETAIL)
238 self.assertEquals(irv.display_name, 'issue bar:4')
239 self.assertEquals(irv.summary, 'aliens among us')
240
241
242 class DanglingIssueRefViewTest(unittest.TestCase):
243 pass # TODO(jrobbins): write tests
244
245
246 class AttachmentViewTest(unittest.TestCase):
247
248 def MakeViewAndVerifyFields(
249 self, size, name, mimetype, expected_size_str, expect_viewable):
250 attach_pb = tracker_pb2.Attachment()
251 attach_pb.filesize = size
252 attach_pb.attachment_id = 12345
253 attach_pb.filename = name
254 attach_pb.mimetype = mimetype
255
256 view = tracker_views.AttachmentView(attach_pb, 'proj')
257 self.assertEqual('/images/paperclip.png', view.iconurl)
258 self.assertEqual(expected_size_str, view.filesizestr)
259 dl = 'attachment?aid=12345'
260 self.assertEqual(dl, view.downloadurl)
261 if expect_viewable:
262 self.assertEqual(dl + '&inline=1', view.url)
263 self.assertEqual(dl + '&inline=1&thumb=1', view.thumbnail_url)
264 else:
265 self.assertEqual(None, view.url)
266 self.assertEqual(None, view.thumbnail_url)
267
268 def testNonImage(self):
269 self.MakeViewAndVerifyFields(
270 123, 'file.ext', 'funky/bits', '123 bytes', False)
271
272 def testViewableImage(self):
273 self.MakeViewAndVerifyFields(
274 123, 'logo.gif', 'image/gif', '123 bytes', True)
275
276 self.MakeViewAndVerifyFields(
277 123, 'screenshot.jpg', 'image/jpeg', '123 bytes', True)
278
279 def testHugeImage(self):
280 self.MakeViewAndVerifyFields(
281 18 * 1024 * 1024, 'panorama.png', 'image/jpeg', '18.0 MB', False)
282
283 def testViewableText(self):
284 name = 'hello.c'
285 attach_pb = tracker_pb2.Attachment()
286 attach_pb.filesize = 1234
287 attach_pb.attachment_id = 12345
288 attach_pb.filename = name
289 attach_pb.mimetype = 'text/plain'
290 view = tracker_views.AttachmentView(attach_pb, 'proj')
291
292 view_url = '/p/proj/issues/attachmentText?aid=12345'
293 self.assertEqual(view_url, view.url)
294
295
296 class LogoViewTest(unittest.TestCase):
297
298 def setUp(self):
299 self.mox = mox.Mox()
300
301 def tearDown(self):
302 self.mox.UnsetStubs()
303 self.mox.ResetAll()
304
305 def testProjectWithLogo(self):
306 bucket_name = 'testbucket'
307 logo_gcs_id = '123'
308 logo_file_name = 'logo.png'
309 project_pb = project_pb2.MakeProject(
310 'testProject', logo_gcs_id=logo_gcs_id, logo_file_name=logo_file_name)
311 object_path = '/' + bucket_name + logo_gcs_id
312
313 self.mox.StubOutWithMock(app_identity, 'get_default_gcs_bucket_name')
314 app_identity.get_default_gcs_bucket_name().AndReturn(bucket_name)
315
316 self.mox.StubOutWithMock(gcs_helpers, 'SignUrl')
317 gcs_helpers.SignUrl(object_path + '-thumbnail').AndReturn('signed/url')
318 gcs_helpers.SignUrl(object_path).AndReturn('signed/url')
319
320 self.mox.ReplayAll()
321
322 view = tracker_views.LogoView(project_pb)
323 self.mox.VerifyAll()
324 self.assertEquals('logo.png', view.filename)
325 self.assertEquals('image/png', view.mimetype)
326 self.assertEquals('signed/url', view.thumbnail_url)
327 self.assertEquals('signed/url&response-content-displacement=attachment%3B'
328 '+filename%3Dlogo.png', view.viewurl)
329
330 def testProjectWithNoLogo(self):
331 project_pb = project_pb2.MakeProject('testProject')
332 view = tracker_views.LogoView(project_pb)
333 self.assertEquals('', view.thumbnail_url)
334 self.assertEquals('', view.viewurl)
335
336
337 class IsViewableImageTest(unittest.TestCase):
338
339 def testIsViewableImage(self):
340 self.assertTrue(tracker_views.IsViewableImage('image/gif', 123))
341 self.assertTrue(tracker_views.IsViewableImage(
342 'image/gif; charset=binary', 123))
343 self.assertTrue(tracker_views.IsViewableImage('image/png', 123))
344 self.assertTrue(tracker_views.IsViewableImage(
345 'image/png; charset=binary', 123))
346 self.assertTrue(tracker_views.IsViewableImage('image/x-png', 123))
347 self.assertTrue(tracker_views.IsViewableImage('image/jpeg', 123))
348 self.assertTrue(tracker_views.IsViewableImage(
349 'image/jpeg; charset=binary', 123))
350 self.assertTrue(tracker_views.IsViewableImage(
351 'image/jpeg', 3 * 1024 * 1024))
352
353 self.assertFalse(tracker_views.IsViewableImage('junk/bits', 123))
354 self.assertFalse(tracker_views.IsViewableImage(
355 'junk/bits; charset=binary', 123))
356 self.assertFalse(tracker_views.IsViewableImage(
357 'image/jpeg', 13 * 1024 * 1024))
358
359
360 class IsViewableTextTest(unittest.TestCase):
361 pass # TODO(jrobbins): write tests
362
363
364 class AmendmentViewTest(unittest.TestCase):
365 pass # TODO(jrobbins): write tests
366
367
368 class ComponentDefViewTest(unittest.TestCase):
369 pass # TODO(jrobbins): write tests
370
371
372 class ComponentValueTest(unittest.TestCase):
373 pass # TODO(jrobbins): write tests
374
375
376 class FieldValueViewTest(unittest.TestCase):
377 pass # TODO(jrobbins): write tests
378
379 class FieldValueViewTest_Applicability(unittest.TestCase):
380 pass # TODO(jrobbins): write tests
381
382
383 class MakeFieldValueViewTest(unittest.TestCase):
384 pass # TODO(jrobbins): write tests
385
386
387 class FindFieldValuesTest(unittest.TestCase):
388 pass # TODO(jrobbins): write tests
389
390
391 class MakeBounceFieldValueViewsTest(unittest.TestCase):
392 pass # TODO(jrobbins): write tests
393
394
395 class ConvertLabelsToFieldValuesTest(unittest.TestCase):
396
397 def testConvertLabelsToFieldValues_NoLabels(self):
398 result = tracker_views._ConvertLabelsToFieldValues(
399 [], 'opsys', {})
400 self.assertEqual([], result)
401
402 def testConvertLabelsToFieldValues_NoMatch(self):
403 result = tracker_views._ConvertLabelsToFieldValues(
404 ['Pri-3', 'M-44', 'Security', 'Via-Wizard'], 'opsys', {})
405 self.assertEqual([], result)
406
407 def testConvertLabelsToFieldValues_HasMatch(self):
408 result = tracker_views._ConvertLabelsToFieldValues(
409 ['Pri-3', 'M-44', 'Security', 'OpSys-OSX'], 'opsys', {})
410 self.assertEqual(1, len(result))
411 self.assertEqual('OSX', result[0].val)
412 self.assertEqual('OSX', result[0].val_short)
413 self.assertEqual('', result[0].docstring)
414
415 result = tracker_views._ConvertLabelsToFieldValues(
416 ['Pri-3', 'M-44', 'Security', 'OpSys-OSX', 'OpSys-All'],
417 'opsys', {'OpSys-All': 'Happens everywhere'})
418 self.assertEqual(2, len(result))
419 self.assertEqual('OSX', result[0].val)
420 self.assertEqual('OSX', result[0].val_short)
421 self.assertEqual('', result[0].docstring)
422 self.assertEqual('All', result[1].val)
423 self.assertEqual('All', result[1].val_short)
424 self.assertEqual('Happens everywhere', result[1].docstring)
425
426
427 class FieldDefViewTest(unittest.TestCase):
428 pass # TODO(jrobbins): write tests
429
430
431 class IssueTemplateViewTest(unittest.TestCase):
432 pass # TODO(jrobbins): write tests
433
434
435 class MakeFieldUserViewsTest(unittest.TestCase):
436 pass # TODO(jrobbins): write tests
437
438
439 class ConfigViewTest(unittest.TestCase):
440 pass # TODO(jrobbins): write tests
441
442
443 if __name__ == '__main__':
444 unittest.main()
OLDNEW
« no previous file with comments | « appengine/monorail/tracker/test/tracker_helpers_test.py ('k') | appengine/monorail/tracker/tracker_bizobj.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698