Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/project/test/project_helpers_test.py b/project/test/project_helpers_test.py
new file mode 100644
index 0000000..4732895
--- /dev/null
+++ b/project/test/project_helpers_test.py
@@ -0,0 +1,179 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Unit tests for helpers module."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import unittest
+
+from mock import patch
+
+from framework import framework_views
+from framework import permissions
+from project import project_constants
+from project import project_helpers
+from proto import project_pb2
+from services import service_manager
+from testing import fake
+
+
+class HelpersUnitTest(unittest.TestCase):
+
+ def setUp(self):
+ self.cnxn = 'fake sql connection'
+ self.services = service_manager.Services(
+ project=fake.ProjectService(),
+ user=fake.UserService())
+ self.services.user.TestAddUser('a@example.com', 111)
+ self.services.user.TestAddUser('b@example.com', 222)
+ self.services.user.TestAddUser('c@example.com', 333)
+ self.users_by_id = framework_views.MakeAllUserViews(
+ 'cnxn', self.services.user, [111, 222, 333])
+ self.effective_ids_by_user = {user: set() for user in {111, 222, 333}}
+
+ def testBuildProjectMembers(self):
+ project = project_pb2.MakeProject(
+ 'proj', owner_ids=[111], committer_ids=[222],
+ contributor_ids=[333])
+ page_data = project_helpers.BuildProjectMembers(
+ self.cnxn, project, self.services.user)
+ self.assertEqual(111, page_data['owners'][0].user_id)
+ self.assertEqual(222, page_data['committers'][0].user_id)
+ self.assertEqual(333, page_data['contributors'][0].user_id)
+ self.assertEqual(3, len(page_data['all_members']))
+
+ def testParseUsernames(self):
+ # Form field was not present in post data.
+ id_set = project_helpers.ParseUsernames(
+ self.cnxn, self.services.user, None)
+ self.assertEqual(set(), id_set)
+
+ # Form field was present, but empty.
+ id_set = project_helpers.ParseUsernames(
+ self.cnxn, self.services.user, '')
+ self.assertEqual(set(), id_set)
+
+ # Parsing valid user names.
+ id_set = project_helpers.ParseUsernames(
+ self.cnxn, self.services.user, 'a@example.com, c@example.com')
+ self.assertEqual({111, 333}, id_set)
+
+ def testParseProjectAccess_NotOffered(self):
+ project = project_pb2.MakeProject('proj')
+ access = project_helpers.ParseProjectAccess(project, None)
+ self.assertEqual(None, access)
+
+ def testParseProjectAccess_AllowedChoice(self):
+ project = project_pb2.MakeProject('proj')
+ access = project_helpers.ParseProjectAccess(project, '1')
+ self.assertEqual(project_pb2.ProjectAccess.ANYONE, access)
+
+ access = project_helpers.ParseProjectAccess(project, '3')
+ self.assertEqual(project_pb2.ProjectAccess.MEMBERS_ONLY, access)
+
+ def testParseProjectAccess_BogusChoice(self):
+ project = project_pb2.MakeProject('proj')
+ access = project_helpers.ParseProjectAccess(project, '9')
+ self.assertEqual(None, access)
+
+ def testUsersWithPermsInProject_StandardPermission(self):
+ project = project_pb2.MakeProject('proj', committer_ids=[111])
+ perms_needed = {permissions.VIEW, permissions.EDIT_ISSUE}
+ actual = project_helpers.UsersWithPermsInProject(
+ project, perms_needed, self.users_by_id, self.effective_ids_by_user)
+ self.assertEqual(
+ {permissions.VIEW: {111, 222, 333},
+ permissions.EDIT_ISSUE: {111}},
+ actual)
+
+ def testUsersWithPermsInProject_IndirectPermission(self):
+ perms_needed = {permissions.EDIT_ISSUE}
+ # User 111 has the EDIT_ISSUE permission.
+ project = project_pb2.MakeProject('proj', committer_ids=[111])
+ # User 222 has the EDIT_ISSUE permission, because 111 is included in its
+ # effective IDs.
+ self.effective_ids_by_user[222] = {111}
+ # User 333 doesn't have the EDIT_ISSUE permission, since only direct
+ # effective IDs are taken into account.
+ self.effective_ids_by_user[333] = {222}
+ actual = project_helpers.UsersWithPermsInProject(
+ project, perms_needed, self.users_by_id, self.effective_ids_by_user)
+ self.assertEqual(
+ {permissions.EDIT_ISSUE: {111, 222}},
+ actual)
+
+ def testUsersWithPermsInProject_CustomPermission(self):
+ project = project_pb2.MakeProject('proj')
+ project.extra_perms = [
+ project_pb2.Project.ExtraPerms(
+ member_id=111,
+ perms=['FooPerm', 'BarPerm']),
+ project_pb2.Project.ExtraPerms(
+ member_id=222,
+ perms=['BarPerm'])]
+ perms_needed = {'FooPerm', 'BarPerm'}
+ actual = project_helpers.UsersWithPermsInProject(
+ project, perms_needed, self.users_by_id, self.effective_ids_by_user)
+ self.assertEqual(
+ {'FooPerm': {111},
+ 'BarPerm': {111, 222}},
+ actual)
+
+ @patch('google.appengine.api.app_identity.get_default_gcs_bucket_name')
+ @patch('framework.gcs_helpers.SignUrl')
+ def testGetThumbnailUrl(self, mock_SignUrl, mock_get_default_gcs_bucket_name):
+ bucket_name = 'testbucket'
+ expected_url = 'signed/url'
+
+ mock_get_default_gcs_bucket_name.return_value = bucket_name
+ mock_SignUrl.return_value = expected_url
+
+ self.assertEqual(expected_url, project_helpers.GetThumbnailUrl('xyz'))
+ mock_get_default_gcs_bucket_name.assert_called_once()
+ mock_SignUrl.assert_called_once_with(bucket_name, 'xyz' + '-thumbnail')
+
+ def testIsValidProjectName_BadChars(self):
+ self.assertFalse(project_helpers.IsValidProjectName('spa ce'))
+ self.assertFalse(project_helpers.IsValidProjectName('under_score'))
+ self.assertFalse(project_helpers.IsValidProjectName('name.dot'))
+ self.assertFalse(project_helpers.IsValidProjectName('pie#sign$'))
+ self.assertFalse(project_helpers.IsValidProjectName('(who?)'))
+
+ def testIsValidProjectName_BadHyphen(self):
+ self.assertFalse(project_helpers.IsValidProjectName('name-'))
+ self.assertFalse(project_helpers.IsValidProjectName('-name'))
+ self.assertTrue(project_helpers.IsValidProjectName('project-name'))
+
+ def testIsValidProjectName_MinimumLength(self):
+ self.assertFalse(project_helpers.IsValidProjectName('x'))
+ self.assertTrue(project_helpers.IsValidProjectName('xy'))
+
+ def testIsValidProjectName_MaximumLength(self):
+ self.assertFalse(
+ project_helpers.IsValidProjectName(
+ 'x' * (project_constants.MAX_PROJECT_NAME_LENGTH + 1)))
+ self.assertTrue(
+ project_helpers.IsValidProjectName(
+ 'x' * (project_constants.MAX_PROJECT_NAME_LENGTH)))
+
+ def testIsValidProjectName_InvalidName(self):
+ self.assertFalse(project_helpers.IsValidProjectName(''))
+ self.assertFalse(project_helpers.IsValidProjectName('000'))
+
+ def testIsValidProjectName_ValidName(self):
+ self.assertTrue(project_helpers.IsValidProjectName('098asd'))
+ self.assertTrue(project_helpers.IsValidProjectName('one-two-three'))
+
+ def testAllProjectMembers(self):
+ p = project_pb2.Project()
+ self.assertEqual(project_helpers.AllProjectMembers(p), [])
+
+ p.owner_ids.extend([1, 2, 3])
+ p.committer_ids.extend([4, 5, 6])
+ p.contributor_ids.extend([7, 8, 9])
+ self.assertEqual(
+ project_helpers.AllProjectMembers(p), [1, 2, 3, 4, 5, 6, 7, 8, 9])