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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: appengine/monorail/tracker/test/tracker_views_test.py
diff --git a/appengine/monorail/tracker/test/tracker_views_test.py b/appengine/monorail/tracker/test/tracker_views_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..124aa7f8ca14f03b3e49fad4662d093f5a689c9a
--- /dev/null
+++ b/appengine/monorail/tracker/test/tracker_views_test.py
@@ -0,0 +1,444 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is govered by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Unittest for issue tracker views."""
+
+import unittest
+
+import mox
+
+from google.appengine.api import app_identity
+from third_party import ezt
+
+from framework import gcs_helpers
+from framework import urls
+from proto import project_pb2
+from proto import tracker_pb2
+from testing import testing_helpers
+from tracker import tracker_views
+
+
+def _Issue(project_name, local_id, summary, status):
+ issue = tracker_pb2.Issue()
+ issue.project_name = project_name
+ issue.local_id = local_id
+ issue.issue_id = 100000 + local_id
+ issue.summary = summary
+ issue.status = status
+ return issue
+
+
+def _MakeConfig():
+ config = tracker_pb2.ProjectIssueConfig()
+ config.well_known_statuses.append(tracker_pb2.StatusDef(
+ status='New', means_open=True))
+ config.well_known_statuses.append(tracker_pb2.StatusDef(
+ status='Old', means_open=False))
+ return config
+
+
+class IssueViewTest(unittest.TestCase):
+
+ def setUp(self):
+ self.issue1 = _Issue('proj', 1, 'not too long summary', 'New')
+ self.issue2 = _Issue('proj', 2, 'sum 2', '')
+ self.issue3 = _Issue('proj', 3, 'sum 3', '')
+ self.issue4 = _Issue('proj', 4, 'sum 4', '')
+
+ self.issue1.reporter_id = 1002
+ self.issue1.owner_id = 2002
+ self.issue1.labels.extend(['A', 'B'])
+ self.issue1.derived_labels.extend(['C', 'D'])
+
+ self.issue2.reporter_id = 2002
+ self.issue2.labels.extend(['foo', 'bar'])
+ self.issue2.blocked_on_iids.extend(
+ [self.issue1.issue_id, self.issue3.issue_id])
+ self.issue2.blocking_iids.extend(
+ [self.issue1.issue_id, self.issue4.issue_id])
+ dref = tracker_pb2.DanglingIssueRef()
+ dref.project = 'codesite'
+ dref.issue_id = 5001
+ self.issue2.dangling_blocking_refs.append(dref)
+
+ self.issue3.reporter_id = 3002
+ self.issue3.labels.extend(['Hot'])
+
+ self.issue4.reporter_id = 3002
+ self.issue4.labels.extend(['Foo', 'Bar'])
+
+ self.restricted = _Issue('proj', 7, 'summary 7', '')
+ self.restricted.labels.extend([
+ 'Restrict-View-Commit', 'Restrict-View-MyCustomPerm'])
+ self.restricted.derived_labels.extend([
+ 'Restrict-AddIssueComment-Commit', 'Restrict-EditIssue-Commit',
+ 'Restrict-Action-NeededPerm'])
+
+ self.users_by_id = {
+ 0: 'user 0',
+ 1002: 'user 1002',
+ 2002: 'user 2002',
+ 3002: 'user 3002',
+ 4002: 'user 4002',
+ }
+
+ def CheckSimpleIssueView(self, config):
+ view1 = tracker_views.IssueView(
+ self.issue1, self.users_by_id, config)
+ self.assertEqual('not too long summary', view1.summary)
+ self.assertEqual('New', view1.status.name)
+ self.assertEqual('user 2002', view1.owner)
+ self.assertEqual('A', view1.labels[0].name)
+ self.assertEqual('B', view1.labels[1].name)
+ self.assertEqual('C', view1.derived_labels[0].name)
+ self.assertEqual('D', view1.derived_labels[1].name)
+ self.assertEqual([], view1.blocked_on)
+ self.assertEqual([], view1.blocking)
+ detail_url = '/p/%s%s?id=%d' % (
+ self.issue1.project_name, urls.ISSUE_DETAIL,
+ self.issue1.local_id)
+ self.assertEqual(detail_url, view1.detail_relative_url)
+ return view1
+
+ def testSimpleIssueView(self):
+ config = tracker_pb2.ProjectIssueConfig()
+ view1 = self.CheckSimpleIssueView(config)
+ self.assertEqual('', view1.status.docstring)
+
+ config.well_known_statuses.append(tracker_pb2.StatusDef(
+ status='New', status_docstring='Issue has not had review yet'))
+ view1 = self.CheckSimpleIssueView(config)
+ self.assertEqual('Issue has not had review yet',
+ view1.status.docstring)
+ self.assertIsNone(view1.restrictions.has_restrictions)
+ self.assertEqual('', view1.restrictions.view)
+ self.assertEqual('', view1.restrictions.add_comment)
+ self.assertEqual('', view1.restrictions.edit)
+
+ def testIsOpen(self):
+ config = _MakeConfig()
+ view1 = tracker_views.IssueView(
+ self.issue1, self.users_by_id, config)
+ self.assertEqual(ezt.boolean(True), view1.is_open)
+
+ self.issue1.status = 'Old'
+ view1 = tracker_views.IssueView(
+ self.issue1, self.users_by_id, config)
+ self.assertEqual(ezt.boolean(False), view1.is_open)
+
+ def testIssueViewWithBlocking(self):
+ # Treat issues 3 and 4 as visible to the current user.
+ view2 = tracker_views.IssueView(
+ self.issue2, self.users_by_id, _MakeConfig(),
+ open_related={self.issue1.issue_id: self.issue1,
+ self.issue3.issue_id: self.issue3},
+ closed_related={self.issue4.issue_id: self.issue4})
+ self.assertEqual(['not too long summary', 'sum 3'],
+ [ref.summary for ref in view2.blocked_on])
+ self.assertEqual(['not too long summary', 'sum 4',
+ 'Issue 5001 in codesite.'],
+ [ref.summary for ref in view2.blocking])
+
+ # Now, treat issues 3 and 4 as not visible to the current user.
+ view2 = tracker_views.IssueView(
+ self.issue2, self.users_by_id, _MakeConfig(),
+ open_related={self.issue1.issue_id: self.issue1}, closed_related={})
+ self.assertEqual(['not too long summary'],
+ [ref.summary for ref in view2.blocked_on])
+ self.assertEqual(['not too long summary', 'Issue 5001 in codesite.'],
+ [ref.summary for ref in view2.blocking])
+
+ # Treat nothing as visible to the current user. Can still see dangling ref.
+ view2 = tracker_views.IssueView(
+ self.issue2, self.users_by_id, _MakeConfig(),
+ open_related={}, closed_related={})
+ self.assertEqual([], view2.blocked_on)
+ self.assertEqual(['Issue 5001 in codesite.'],
+ [ref.summary for ref in view2.blocking])
+
+ def testIssueViewWithRestrictions(self):
+ view = tracker_views.IssueView(
+ self.restricted, self.users_by_id, _MakeConfig())
+ self.assertTrue(view.restrictions.has_restrictions)
+ self.assertEqual('Commit and MyCustomPerm', view.restrictions.view)
+ self.assertEqual('Commit', view.restrictions.add_comment)
+ self.assertEqual('Commit', view.restrictions.edit)
+ self.assertEqual(['Restrict-Action-NeededPerm'], view.restrictions.other)
+ self.assertEqual('Restrict-View-Commit', view.labels[0].name)
+ self.assertTrue(view.labels[0].is_restrict)
+
+
+class RestrictionsViewTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class IssueRefViewTest(unittest.TestCase):
+
+ issue1 = testing_helpers.Blank(
+ local_id=1,
+ project_name='foo',
+ summary='blue screen')
+ issue2 = testing_helpers.Blank(
+ local_id=2,
+ project_name='foo',
+ summary='hissing noise')
+ issue3 = testing_helpers.Blank(
+ local_id=3,
+ project_name='foo',
+ summary='sinking feeling')
+ issue4 = testing_helpers.Blank(
+ local_id=4,
+ project_name='bar',
+ summary='aliens among us')
+
+ def testNormalCase(self):
+ open_list = {1: self.issue1,
+ 2: self.issue2}
+ closed_list = {3: self.issue3}
+
+ ref_iid = 1
+ irv = tracker_views.IssueRefView('foo', ref_iid, open_list, closed_list)
+ self.assertEquals(irv.visible, ezt.boolean(True))
+ self.assertEquals(irv.is_open, ezt.boolean(True))
+ self.assertEquals(irv.url, 'detail?id=1')
+ self.assertEquals(irv.display_name, 'issue 1')
+ self.assertEquals(irv.summary, 'blue screen')
+
+ ref_iid = 3
+ irv = tracker_views.IssueRefView('foo', ref_iid, open_list, closed_list)
+ self.assertEquals(irv.visible, ezt.boolean(True))
+ self.assertEquals(irv.is_open, ezt.boolean(False))
+ self.assertEquals(irv.url, 'detail?id=3')
+ self.assertEquals(irv.display_name, 'issue 3')
+ self.assertEquals(irv.summary, 'sinking feeling')
+
+ def testMissingIssueShouldNotBeVisible(self):
+ open_list = {1: self.issue1,
+ 2: self.issue2}
+ closed_list = {3: self.issue3}
+
+ ref_iid = 99
+ irv = tracker_views.IssueRefView('foo', ref_iid, open_list, closed_list)
+ self.assertEquals(irv.visible, ezt.boolean(False))
+
+ def testCrossProjectReference(self):
+ open_list = {1: self.issue1,
+ 2: self.issue2}
+ closed_list = {3: self.issue3,
+ 4: self.issue4}
+
+ ref_iid = 4
+ irv = tracker_views.IssueRefView('foo', ref_iid, open_list, closed_list)
+ self.assertEquals(irv.visible, ezt.boolean(True))
+ self.assertEquals(irv.is_open, ezt.boolean(False))
+ self.assertEquals(
+ irv.url, '/p/bar%s?id=4' % urls.ISSUE_DETAIL)
+ self.assertEquals(irv.display_name, 'issue bar:4')
+ self.assertEquals(irv.summary, 'aliens among us')
+
+
+class DanglingIssueRefViewTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class AttachmentViewTest(unittest.TestCase):
+
+ def MakeViewAndVerifyFields(
+ self, size, name, mimetype, expected_size_str, expect_viewable):
+ attach_pb = tracker_pb2.Attachment()
+ attach_pb.filesize = size
+ attach_pb.attachment_id = 12345
+ attach_pb.filename = name
+ attach_pb.mimetype = mimetype
+
+ view = tracker_views.AttachmentView(attach_pb, 'proj')
+ self.assertEqual('/images/paperclip.png', view.iconurl)
+ self.assertEqual(expected_size_str, view.filesizestr)
+ dl = 'attachment?aid=12345'
+ self.assertEqual(dl, view.downloadurl)
+ if expect_viewable:
+ self.assertEqual(dl + '&inline=1', view.url)
+ self.assertEqual(dl + '&inline=1&thumb=1', view.thumbnail_url)
+ else:
+ self.assertEqual(None, view.url)
+ self.assertEqual(None, view.thumbnail_url)
+
+ def testNonImage(self):
+ self.MakeViewAndVerifyFields(
+ 123, 'file.ext', 'funky/bits', '123 bytes', False)
+
+ def testViewableImage(self):
+ self.MakeViewAndVerifyFields(
+ 123, 'logo.gif', 'image/gif', '123 bytes', True)
+
+ self.MakeViewAndVerifyFields(
+ 123, 'screenshot.jpg', 'image/jpeg', '123 bytes', True)
+
+ def testHugeImage(self):
+ self.MakeViewAndVerifyFields(
+ 18 * 1024 * 1024, 'panorama.png', 'image/jpeg', '18.0 MB', False)
+
+ def testViewableText(self):
+ name = 'hello.c'
+ attach_pb = tracker_pb2.Attachment()
+ attach_pb.filesize = 1234
+ attach_pb.attachment_id = 12345
+ attach_pb.filename = name
+ attach_pb.mimetype = 'text/plain'
+ view = tracker_views.AttachmentView(attach_pb, 'proj')
+
+ view_url = '/p/proj/issues/attachmentText?aid=12345'
+ self.assertEqual(view_url, view.url)
+
+
+class LogoViewTest(unittest.TestCase):
+
+ def setUp(self):
+ self.mox = mox.Mox()
+
+ def tearDown(self):
+ self.mox.UnsetStubs()
+ self.mox.ResetAll()
+
+ def testProjectWithLogo(self):
+ bucket_name = 'testbucket'
+ logo_gcs_id = '123'
+ logo_file_name = 'logo.png'
+ project_pb = project_pb2.MakeProject(
+ 'testProject', logo_gcs_id=logo_gcs_id, logo_file_name=logo_file_name)
+ object_path = '/' + bucket_name + logo_gcs_id
+
+ self.mox.StubOutWithMock(app_identity, 'get_default_gcs_bucket_name')
+ app_identity.get_default_gcs_bucket_name().AndReturn(bucket_name)
+
+ self.mox.StubOutWithMock(gcs_helpers, 'SignUrl')
+ gcs_helpers.SignUrl(object_path + '-thumbnail').AndReturn('signed/url')
+ gcs_helpers.SignUrl(object_path).AndReturn('signed/url')
+
+ self.mox.ReplayAll()
+
+ view = tracker_views.LogoView(project_pb)
+ self.mox.VerifyAll()
+ self.assertEquals('logo.png', view.filename)
+ self.assertEquals('image/png', view.mimetype)
+ self.assertEquals('signed/url', view.thumbnail_url)
+ self.assertEquals('signed/url&response-content-displacement=attachment%3B'
+ '+filename%3Dlogo.png', view.viewurl)
+
+ def testProjectWithNoLogo(self):
+ project_pb = project_pb2.MakeProject('testProject')
+ view = tracker_views.LogoView(project_pb)
+ self.assertEquals('', view.thumbnail_url)
+ self.assertEquals('', view.viewurl)
+
+
+class IsViewableImageTest(unittest.TestCase):
+
+ def testIsViewableImage(self):
+ self.assertTrue(tracker_views.IsViewableImage('image/gif', 123))
+ self.assertTrue(tracker_views.IsViewableImage(
+ 'image/gif; charset=binary', 123))
+ self.assertTrue(tracker_views.IsViewableImage('image/png', 123))
+ self.assertTrue(tracker_views.IsViewableImage(
+ 'image/png; charset=binary', 123))
+ self.assertTrue(tracker_views.IsViewableImage('image/x-png', 123))
+ self.assertTrue(tracker_views.IsViewableImage('image/jpeg', 123))
+ self.assertTrue(tracker_views.IsViewableImage(
+ 'image/jpeg; charset=binary', 123))
+ self.assertTrue(tracker_views.IsViewableImage(
+ 'image/jpeg', 3 * 1024 * 1024))
+
+ self.assertFalse(tracker_views.IsViewableImage('junk/bits', 123))
+ self.assertFalse(tracker_views.IsViewableImage(
+ 'junk/bits; charset=binary', 123))
+ self.assertFalse(tracker_views.IsViewableImage(
+ 'image/jpeg', 13 * 1024 * 1024))
+
+
+class IsViewableTextTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class AmendmentViewTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class ComponentDefViewTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class ComponentValueTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class FieldValueViewTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+class FieldValueViewTest_Applicability(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class MakeFieldValueViewTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class FindFieldValuesTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class MakeBounceFieldValueViewsTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class ConvertLabelsToFieldValuesTest(unittest.TestCase):
+
+ def testConvertLabelsToFieldValues_NoLabels(self):
+ result = tracker_views._ConvertLabelsToFieldValues(
+ [], 'opsys', {})
+ self.assertEqual([], result)
+
+ def testConvertLabelsToFieldValues_NoMatch(self):
+ result = tracker_views._ConvertLabelsToFieldValues(
+ ['Pri-3', 'M-44', 'Security', 'Via-Wizard'], 'opsys', {})
+ self.assertEqual([], result)
+
+ def testConvertLabelsToFieldValues_HasMatch(self):
+ result = tracker_views._ConvertLabelsToFieldValues(
+ ['Pri-3', 'M-44', 'Security', 'OpSys-OSX'], 'opsys', {})
+ self.assertEqual(1, len(result))
+ self.assertEqual('OSX', result[0].val)
+ self.assertEqual('OSX', result[0].val_short)
+ self.assertEqual('', result[0].docstring)
+
+ result = tracker_views._ConvertLabelsToFieldValues(
+ ['Pri-3', 'M-44', 'Security', 'OpSys-OSX', 'OpSys-All'],
+ 'opsys', {'OpSys-All': 'Happens everywhere'})
+ self.assertEqual(2, len(result))
+ self.assertEqual('OSX', result[0].val)
+ self.assertEqual('OSX', result[0].val_short)
+ self.assertEqual('', result[0].docstring)
+ self.assertEqual('All', result[1].val)
+ self.assertEqual('All', result[1].val_short)
+ self.assertEqual('Happens everywhere', result[1].docstring)
+
+
+class FieldDefViewTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class IssueTemplateViewTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class MakeFieldUserViewsTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+class ConfigViewTest(unittest.TestCase):
+ pass # TODO(jrobbins): write tests
+
+
+if __name__ == '__main__':
+ unittest.main()
« 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