Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/tracker/test/field_helpers_test.py b/tracker/test/field_helpers_test.py
new file mode 100644
index 0000000..f49a147
--- /dev/null
+++ b/tracker/test/field_helpers_test.py
@@ -0,0 +1,1276 @@
+# 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 the field_helpers module."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import time
+import unittest
+import re
+
+from framework import exceptions
+from framework import permissions
+from framework import template_helpers
+from proto import project_pb2
+from proto import tracker_pb2
+from services import service_manager
+from services import config_svc
+from testing import fake
+from testing import testing_helpers
+from tracker import field_helpers
+from tracker import tracker_bizobj
+
+
+class FieldHelpersTest(unittest.TestCase):
+
+ def setUp(self):
+ self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
+ self.config.well_known_labels.append(tracker_pb2.LabelDef(
+ label='OldLabel', label_docstring='Do not use any longer',
+ deprecated=True))
+
+ self.services = service_manager.Services(
+ issue=fake.IssueService(),
+ usergroup=fake.UserGroupService(),
+ config=fake.ConfigService(),
+ user=fake.UserService())
+ self.project = fake.Project()
+ self.mr = testing_helpers.MakeMonorailRequest(
+ project=self.project, services=self.services)
+ self.mr.cnxn = fake.MonorailConnection()
+ self.errors = template_helpers.EZTError()
+
+ def testListApplicableFieldDefs(self):
+ issue_1 = fake.MakeTestIssue(
+ 789,
+ 1,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78901,
+ labels=['type-defect', 'other-label'])
+ issue_2 = fake.MakeTestIssue(
+ 789,
+ 2,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78902,
+ labels=['type-feedback', 'other-label1'])
+ issue_3 = fake.MakeTestIssue(
+ 789,
+ 3,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78903,
+ labels=['type-defect'],
+ approval_values=[
+ tracker_pb2.ApprovalValue(approval_id=3),
+ tracker_pb2.ApprovalValue(approval_id=5)
+ ])
+ issue_4 = fake.MakeTestIssue(
+ 789, 4, 'sum', 'New', 111, issue_id=78904) # test no labels at all
+ issue_5 = fake.MakeTestIssue(
+ 789,
+ 5,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78905,
+ labels=['type'], # test labels ignored
+ approval_values=[tracker_pb2.ApprovalValue(approval_id=5)])
+ self.services.issue.TestAddIssue(issue_1)
+ self.services.issue.TestAddIssue(issue_2)
+ self.services.issue.TestAddIssue(issue_3)
+ self.services.issue.TestAddIssue(issue_4)
+ self.services.issue.TestAddIssue(issue_5)
+ fd_1 = tracker_pb2.FieldDef(
+ field_name='FirstField',
+ field_id=1,
+ field_type=tracker_pb2.FieldTypes.STR_TYPE,
+ applicable_type='feedback') # applicable
+ fd_2 = tracker_pb2.FieldDef(
+ field_name='SecField',
+ field_id=2,
+ field_type=tracker_pb2.FieldTypes.INT_TYPE,
+ applicable_type='no') # not applicable
+ fd_3 = tracker_pb2.FieldDef(
+ field_name='LegalApproval',
+ field_id=3,
+ field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE,
+ applicable_type='') # applicable
+ fd_4 = tracker_pb2.FieldDef(
+ field_name='UserField',
+ field_id=4,
+ field_type=tracker_pb2.FieldTypes.USER_TYPE,
+ applicable_type='') # applicable
+ fd_5 = tracker_pb2.FieldDef(
+ field_name='DogApproval',
+ field_id=5,
+ field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE,
+ applicable_type='') # applicable
+ fd_6 = tracker_pb2.FieldDef(
+ field_name='SixthField',
+ field_id=6,
+ field_type=tracker_pb2.FieldTypes.INT_TYPE,
+ applicable_type='Defect') # applicable
+ fd_7 = tracker_pb2.FieldDef(
+ field_name='CatApproval',
+ field_id=7,
+ field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE,
+ applicable_type='') # not applicable
+ config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
+ config.field_defs = [fd_1, fd_2, fd_3, fd_4, fd_5, fd_6, fd_7]
+ issues = [issue_1, issue_2, issue_3, issue_4, issue_5]
+
+ actual_fds = field_helpers.ListApplicableFieldDefs(issues, config)
+ self.assertEqual(actual_fds, [fd_1, fd_3, fd_4, fd_5, fd_6])
+
+ def testParseFieldDefRequest_Empty(self):
+ post_data = fake.PostData()
+ parsed = field_helpers.ParseFieldDefRequest(post_data, self.config)
+ self.assertEqual('', parsed.field_name)
+ self.assertEqual(None, parsed.field_type_str)
+ self.assertEqual(None, parsed.min_value)
+ self.assertEqual(None, parsed.max_value)
+ self.assertEqual(None, parsed.regex)
+ self.assertFalse(parsed.needs_member)
+ self.assertEqual('', parsed.needs_perm)
+ self.assertEqual('', parsed.grants_perm)
+ self.assertEqual(0, parsed.notify_on)
+ self.assertFalse(parsed.is_required)
+ self.assertFalse(parsed.is_niche)
+ self.assertFalse(parsed.is_multivalued)
+ self.assertEqual('', parsed.field_docstring)
+ self.assertEqual('', parsed.choices_text)
+ self.assertEqual('', parsed.applicable_type)
+ self.assertEqual('', parsed.applicable_predicate)
+ unchanged_labels = [
+ (label_def.label, label_def.label_docstring, label_def.deprecated)
+ for label_def in self.config.well_known_labels]
+ self.assertEqual(unchanged_labels, parsed.revised_labels)
+ self.assertEqual('', parsed.approvers_str)
+ self.assertEqual('', parsed.survey)
+ self.assertEqual('', parsed.parent_approval_name)
+ self.assertFalse(parsed.is_phase_field)
+
+ def testParseFieldDefRequest_Normal(self):
+ post_data = fake.PostData(
+ name=['somefield'],
+ field_type=['INT_TYPE'],
+ min_value=['11'],
+ max_value=['99'],
+ regex=['.*'],
+ needs_member=['Yes'],
+ needs_perm=['Commit'],
+ grants_perm=['View'],
+ notify_on=['any_comment'],
+ importance=['required'],
+ is_multivalued=['Yes'],
+ docstring=['It is just some field'],
+ choices=['Hot = Lots of activity\nCold = Not much activity'],
+ applicable_type=['Defect'],
+ approver_names=['approver@chromium.org'],
+ survey=['Are there UX changes?'],
+ parent_approval_name=['UIReview'],
+ is_phase_field=['on'],
+ )
+ parsed = field_helpers.ParseFieldDefRequest(post_data, self.config)
+ self.assertEqual('somefield', parsed.field_name)
+ self.assertEqual('INT_TYPE', parsed.field_type_str)
+ self.assertEqual(11, parsed.min_value)
+ self.assertEqual(99, parsed.max_value)
+ self.assertEqual('.*', parsed.regex)
+ self.assertTrue(parsed.needs_member)
+ self.assertEqual('Commit', parsed.needs_perm)
+ self.assertEqual('View', parsed.grants_perm)
+ self.assertEqual(1, parsed.notify_on)
+ self.assertTrue(parsed.is_required)
+ self.assertFalse(parsed.is_niche)
+ self.assertTrue(parsed.is_multivalued)
+ self.assertEqual('It is just some field', parsed.field_docstring)
+ self.assertEqual('Hot = Lots of activity\nCold = Not much activity',
+ parsed.choices_text)
+ self.assertEqual('Defect', parsed.applicable_type)
+ self.assertEqual('', parsed.applicable_predicate)
+ unchanged_labels = [
+ (label_def.label, label_def.label_docstring, label_def.deprecated)
+ for label_def in self.config.well_known_labels]
+ new_labels = [
+ ('somefield-Hot', 'Lots of activity', False),
+ ('somefield-Cold', 'Not much activity', False)]
+ self.assertEqual(unchanged_labels + new_labels, parsed.revised_labels)
+ self.assertEqual('approver@chromium.org', parsed.approvers_str)
+ self.assertEqual('Are there UX changes?', parsed.survey)
+ self.assertEqual('UIReview', parsed.parent_approval_name)
+ self.assertTrue(parsed.is_phase_field)
+
+ def testParseFieldDefRequest_PreventPhaseApprovals(self):
+ post_data = fake.PostData(
+ field_type=['approval_type'],
+ is_phase_field=['on'],
+ )
+ parsed = field_helpers.ParseFieldDefRequest(post_data, self.config)
+ self.assertEqual('approval_type', parsed.field_type_str)
+ self.assertFalse(parsed.is_phase_field)
+
+ def testParseChoicesIntoWellKnownLabels_NewFieldDef(self):
+ choices_text = 'Hot = Lots of activity\nCold = Not much activity'
+ field_name = 'somefield'
+ revised_labels = field_helpers._ParseChoicesIntoWellKnownLabels(
+ choices_text, field_name, self.config, 'enum_type')
+ unchanged_labels = [
+ (label_def.label, label_def.label_docstring, label_def.deprecated)
+ for label_def in self.config.well_known_labels]
+ new_labels = [
+ ('somefield-Hot', 'Lots of activity', False),
+ ('somefield-Cold', 'Not much activity', False)]
+ self.assertEqual(unchanged_labels + new_labels, revised_labels)
+
+ def testParseChoicesIntoWellKnownLabels_ConvertExistingLabel(self):
+ choices_text = 'High = Must be fixed\nMedium = Might slip'
+ field_name = 'Priority'
+ revised_labels = field_helpers._ParseChoicesIntoWellKnownLabels(
+ choices_text, field_name, self.config, 'enum_type')
+ kept_labels = [
+ (label_def.label, label_def.label_docstring, label_def.deprecated)
+ for label_def in self.config.well_known_labels
+ if not label_def.label.startswith('Priority-')]
+ new_labels = [
+ ('Priority-High', 'Must be fixed', False),
+ ('Priority-Medium', 'Might slip', False)]
+ self.maxDiff = None
+ self.assertEqual(kept_labels + new_labels, revised_labels)
+
+ # TODO(jojwang): test this separately
+ # test None field_type_str, updating existing fielddef
+ self.config.field_defs.append(tracker_pb2.FieldDef(
+ field_id=13, field_name='Priority',
+ field_type=tracker_pb2.FieldTypes.ENUM_TYPE))
+ revised_labels = field_helpers._ParseChoicesIntoWellKnownLabels(
+ choices_text, field_name, self.config, None)
+ self.assertEqual(kept_labels + new_labels, revised_labels)
+
+ def testParseChoicesIntoWellKnownLabels_NotEnumField(self):
+ choices_text = ''
+ field_name = 'NotEnum'
+ self.config.well_known_labels = [
+ tracker_pb2.LabelDef(label='NotEnum-Should'),
+ tracker_pb2.LabelDef(label='NotEnum-Not-Be-Masked')]
+ revised_labels = field_helpers._ParseChoicesIntoWellKnownLabels(
+ choices_text, field_name, self.config, 'str_type')
+ new_labels = [
+ ('NotEnum-Should', None, False),
+ ('NotEnum-Not-Be-Masked', None, False)]
+ self.assertEqual(new_labels, revised_labels)
+
+ # TODO(jojwang): test this separately
+ # test None field_type_str, updating existing fielddef
+ self.config.field_defs.append(tracker_pb2.FieldDef(
+ field_id=13, field_name='NotEnum',
+ field_type=tracker_pb2.FieldTypes.STR_TYPE))
+ revised_labels = field_helpers._ParseChoicesIntoWellKnownLabels(
+ choices_text, field_name, self.config, None)
+ self.assertEqual(revised_labels, new_labels)
+
+ def testShiftEnumFieldsIntoLabels_Empty(self):
+ labels = []
+ labels_remove = []
+ field_val_strs = {}
+ field_val_strs_remove = {}
+ field_helpers.ShiftEnumFieldsIntoLabels(
+ labels, labels_remove, field_val_strs, field_val_strs_remove,
+ self.config)
+ self.assertEqual([], labels)
+ self.assertEqual([], labels_remove)
+ self.assertEqual({}, field_val_strs)
+ self.assertEqual({}, field_val_strs_remove)
+
+ def testShiftEnumFieldsIntoLabels_NoOp(self):
+ labels = ['Security', 'Performance', 'Pri-1', 'M-2']
+ labels_remove = ['ReleaseBlock']
+ field_val_strs = {123: ['CPU']}
+ field_val_strs_remove = {234: ['Small']}
+ field_helpers.ShiftEnumFieldsIntoLabels(
+ labels, labels_remove, field_val_strs, field_val_strs_remove,
+ self.config)
+ self.assertEqual(['Security', 'Performance', 'Pri-1', 'M-2'], labels)
+ self.assertEqual(['ReleaseBlock'], labels_remove)
+ self.assertEqual({123: ['CPU']}, field_val_strs)
+ self.assertEqual({234: ['Small']}, field_val_strs_remove)
+
+ def testShiftEnumFieldsIntoLabels_FoundSomeEnumFields(self):
+ self.config.field_defs.append(
+ tracker_bizobj.MakeFieldDef(
+ 123, 789, 'Component', tracker_pb2.FieldTypes.ENUM_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action', 'What HW part is affected?',
+ False))
+ self.config.field_defs.append(
+ tracker_bizobj.MakeFieldDef(
+ 234, 789, 'Size', tracker_pb2.FieldTypes.ENUM_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action', 'How big is this work item?',
+ False))
+ labels = ['Security', 'Performance', 'Pri-1', 'M-2']
+ labels_remove = ['ReleaseBlock']
+ field_val_strs = {123: ['CPU']}
+ field_val_strs_remove = {234: ['Small']}
+ field_helpers.ShiftEnumFieldsIntoLabels(
+ labels, labels_remove, field_val_strs, field_val_strs_remove,
+ self.config)
+ self.assertEqual(
+ ['Security', 'Performance', 'Pri-1', 'M-2', 'Component-CPU'],
+ labels)
+ self.assertEqual(['ReleaseBlock', 'Size-Small'], labels_remove)
+ self.assertEqual({}, field_val_strs)
+ self.assertEqual({}, field_val_strs_remove)
+
+ def testReviseApprovals_New(self):
+ self.config.field_defs.append(
+ tracker_bizobj.MakeFieldDef(
+ 123, 789, 'UX Review', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action',
+ 'Approval for UX review', False))
+ existing_approvaldef = tracker_pb2.ApprovalDef(
+ approval_id=123, approver_ids=[101, 102], survey='')
+ self.config.approval_defs = [existing_approvaldef]
+ revised_approvals = field_helpers.ReviseApprovals(
+ 124, [103], '', self.config)
+ self.assertEqual(len(revised_approvals), 2)
+ self.assertEqual(revised_approvals,
+ [(123, [101, 102], ''), (124, [103], '')])
+
+ def testReviseApprovals_Existing(self):
+ existing_approvaldef = tracker_pb2.ApprovalDef(
+ approval_id=123, approver_ids=[101, 102], survey='')
+ self.config.approval_defs = [existing_approvaldef]
+ revised_approvals = field_helpers.ReviseApprovals(
+ 123, [103], '', self.config)
+ self.assertEqual(revised_approvals, [(123, [103], '')])
+
+ def testParseOneFieldValue_IntType(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'Foo', tracker_pb2.FieldTypes.INT_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fv = field_helpers.ParseOneFieldValue(
+ self.mr.cnxn, self.services.user, fd, '8675309')
+ self.assertEqual(fv.field_id, 123)
+ self.assertEqual(fv.int_value, 8675309)
+
+ def testParseOneFieldValue_StrType(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'Foo', tracker_pb2.FieldTypes.STR_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fv = field_helpers.ParseOneFieldValue(
+ self.mr.cnxn, self.services.user, fd, '8675309')
+ self.assertEqual(fv.field_id, 123)
+ self.assertEqual(fv.str_value, '8675309')
+
+ def testParseOneFieldValue_UserType(self):
+ self.services.user.TestAddUser('user@example.com', 111)
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'Foo', tracker_pb2.FieldTypes.USER_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fv = field_helpers.ParseOneFieldValue(
+ self.mr.cnxn, self.services.user, fd, 'user@example.com')
+ self.assertEqual(fv.field_id, 123)
+ self.assertEqual(fv.user_id, 111)
+
+ def testParseOneFieldValue_DateType(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'Deadline', tracker_pb2.FieldTypes.DATE_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fv = field_helpers.ParseOneFieldValue(
+ self.mr.cnxn, self.services.user, fd, '2009-02-13')
+ self.assertEqual(fv.field_id, 123)
+ self.assertEqual(fv.date_value, 1234483200)
+
+ def testParseOneFieldValue_UrlType(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'Design Doc', tracker_pb2.FieldTypes.URL_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fv = field_helpers.ParseOneFieldValue(
+ self.mr.cnxn, self.services.user, fd, 'www.google.com')
+ self.assertEqual(fv.field_id, 123)
+ self.assertEqual(fv.url_value, 'http://www.google.com')
+
+ def testParseOneFieldValue(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'Target', tracker_pb2.FieldTypes.INT_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'milestone target',
+ False, is_phase_field=True)
+ phase_fvs = field_helpers.ParseOnePhaseFieldValue(
+ self.mr.cnxn, self.services.user, fd, '70', [30, 40])
+ self.assertEqual(len(phase_fvs), 2)
+ self.assertEqual(phase_fvs[0].phase_id, 30)
+ self.assertEqual(phase_fvs[1].phase_id, 40)
+
+ def testParseFieldValues_Empty(self):
+ field_val_strs = {}
+ phase_field_val_strs = {}
+ field_values = field_helpers.ParseFieldValues(
+ self.mr.cnxn, self.services.user, field_val_strs,
+ phase_field_val_strs, self.config)
+ self.assertEqual([], field_values)
+
+ def testParseFieldValues_EmptyPhases(self):
+ field_val_strs = {126: ['70']}
+ phase_field_val_strs = {}
+ fd_phase = tracker_bizobj.MakeFieldDef(
+ 126, 789, 'Target', tracker_pb2.FieldTypes.INT_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'milestone target',
+ False, is_phase_field=True)
+ self.config.field_defs.extend([fd_phase])
+ field_values = field_helpers.ParseFieldValues(
+ self.mr.cnxn, self.services.user, field_val_strs,
+ phase_field_val_strs, self.config)
+ self.assertEqual([], field_values)
+
+ def testParseFieldValues_Normal(self):
+ fd_int = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fd_date = tracker_bizobj.MakeFieldDef(
+ 124, 789, 'Deadline', tracker_pb2.FieldTypes.DATE_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fd_url = tracker_bizobj.MakeFieldDef(
+ 125, 789, 'Design Doc', tracker_pb2.FieldTypes.URL_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fd_phase = tracker_bizobj.MakeFieldDef(
+ 126, 789, 'Target', tracker_pb2.FieldTypes.INT_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'milestone target',
+ False, is_phase_field=True)
+ self.config.field_defs.extend([fd_int, fd_date, fd_url, fd_phase])
+ field_val_strs = {
+ 123: ['80386', '68040'],
+ 124: ['2009-02-13'],
+ 125: ['www.google.com'],
+ }
+ phase_field_val_strs = {
+ 126: {'beta': ['89'],
+ 'stable': ['70'],
+ 'missing': ['234'],
+ }}
+ field_values = field_helpers.ParseFieldValues(
+ self.mr.cnxn, self.services.user, field_val_strs,
+ phase_field_val_strs, self.config,
+ phase_ids_by_name={'stable': [30, 40], 'beta': [88]})
+ fv1 = tracker_bizobj.MakeFieldValue(
+ 123, 80386, None, None, None, None, False)
+ fv2 = tracker_bizobj.MakeFieldValue(
+ 123, 68040, None, None, None, None, False)
+ fv3 = tracker_bizobj.MakeFieldValue(
+ 124, None, None, None, 1234483200, None, False)
+ fv4 = tracker_bizobj.MakeFieldValue(
+ 125, None, None, None, None, 'http://www.google.com', False)
+ fv5 = tracker_bizobj.MakeFieldValue(
+ 126, 89, None, None, None, None, False, phase_id=88)
+ fv6 = tracker_bizobj.MakeFieldValue(
+ 126, 70, None, None, None, None, False, phase_id=30)
+ fv7 = tracker_bizobj.MakeFieldValue(
+ 126, 70, None, None, None, None, False, phase_id=40)
+ self.assertEqual([fv1, fv2, fv3, fv4, fv5, fv6, fv7], field_values)
+
+ def test_IntType(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fv = tracker_bizobj.MakeFieldValue(123, 8086, None, None, None, None, False)
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertIsNone(msg)
+
+ fd.min_value = 1
+ fd.max_value = 999
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertEqual('Value must be <= 999.', msg)
+
+ fv.int_value = 0
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertEqual('Value must be >= 1.', msg)
+
+ def test_StrType(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.STR_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fv = tracker_bizobj.MakeFieldValue(
+ 123, None, 'i386', None, None, None, False)
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertIsNone(msg)
+
+ fd.regex = r'^\d*$'
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertEqual(r'Value must match regular expression: ^\d*$.', msg)
+
+ fv.str_value = '386'
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertIsNone(msg)
+
+ def test_UserType(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'Fake Field', tracker_pb2.FieldTypes.USER_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+
+ self.services.user.TestAddUser('owner@example.com', 111)
+ self.mr.project.owner_ids.extend([111])
+ owner = tracker_bizobj.MakeFieldValue(
+ fd.field_id, None, None, 111, None, None, False)
+
+ self.services.user.TestAddUser('committer@example.com', 222)
+ self.mr.project.committer_ids.extend([222])
+ self.mr.project.extra_perms = [
+ project_pb2.Project.ExtraPerms(
+ member_id=222,
+ perms=['FooPerm'])]
+ committer = tracker_bizobj.MakeFieldValue(
+ fd.field_id, None, None, 222, None, None, False)
+
+ self.services.user.TestAddUser('user@example.com', 333)
+ user = tracker_bizobj.MakeFieldValue(
+ fd.field_id, None, None, 333, None, None, False)
+
+ # Normal
+ for fv in (owner, committer, user):
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertIsNone(msg)
+
+ # Needs to be member (user isn't a member).
+ fd.needs_member = True
+ for fv in (owner, committer):
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertIsNone(msg)
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, user)
+ self.assertEqual('User must be a member of the project.', msg)
+
+ # Needs DeleteAny permission (only owner has it).
+ fd.needs_perm = 'DeleteAny'
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, owner)
+ self.assertIsNone(msg)
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, committer)
+ self.assertEqual('User must have permission "DeleteAny".', msg)
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, user)
+ self.assertEqual('User must be a member of the project.', msg)
+
+ # Needs custom permission (only committer has it).
+ fd.needs_perm = 'FooPerm'
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, owner)
+ self.assertEqual('User must have permission "FooPerm".', msg)
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, committer)
+ self.assertIsNone(msg)
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, user)
+ self.assertEqual('User must be a member of the project.', msg)
+
+ def test_DateType(self):
+ pass # TODO(jrobbins): write this test. @@@
+
+ def test_UrlType(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.URL_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+
+ fv = tracker_bizobj.MakeFieldValue(
+ 123, None, None, None, None, 'www.google.com', False)
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertIsNone(msg)
+
+ fv.url_value = 'go/puppies'
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertIsNone(msg)
+
+ fv.url_value = 'go/213'
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertIsNone(msg)
+
+ fv.url_value = 'puppies'
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertEqual('Value must be a valid url.', msg)
+
+ def test_OtherType(self):
+ # There are currently no validation options for date-type custom fields.
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'Deadline', tracker_pb2.FieldTypes.DATE_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ fv = tracker_bizobj.MakeFieldValue(
+ 123, None, None, None, 1234567890, None, False)
+ msg = field_helpers.ValidateCustomFieldValue(
+ self.mr.cnxn, self.mr.project, self.services, fd, fv)
+ self.assertIsNone(msg)
+
+ def testValidateCustomFields_NoCustomFieldValues(self):
+ err_msgs = field_helpers.ValidateCustomFields(
+ self.mr, self.services, [], self.config, self.mr.project,
+ ezt_errors=self.errors)
+ self.assertFalse(self.errors.AnyErrors())
+ self.assertEqual(err_msgs, [])
+
+ def testValidateCustomFields_NoErrors(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ self.config.field_defs.append(fd)
+ fv1 = tracker_bizobj.MakeFieldValue(
+ 123, 8086, None, None, None, None, False)
+ fv2 = tracker_bizobj.MakeFieldValue(123, 486, None, None, None, None, False)
+
+ err_msgs = field_helpers.ValidateCustomFields(
+ self.mr, self.services, [fv1, fv2], self.config, self.mr.project,
+ ezt_errors=self.errors)
+ self.assertFalse(self.errors.AnyErrors())
+ self.assertEqual(err_msgs, [])
+
+ def testValidateCustomFields_SomeValueErrors(self):
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None,
+ '', False, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ self.config.field_defs.append(fd)
+ fv1 = tracker_bizobj.MakeFieldValue(
+ 123, 8086, None, None, None, None, False)
+ fv2 = tracker_bizobj.MakeFieldValue(123, 486, None, None, None, None, False)
+
+ fd.min_value = 1
+ fd.max_value = 999
+ err_msgs = field_helpers.ValidateCustomFields(
+ self.mr, self.services, [fv1, fv2], self.config, self.mr.project,
+ ezt_errors=self.errors)
+ self.assertTrue(self.errors.AnyErrors())
+ self.assertEqual(1, len(self.errors.custom_fields))
+ custom_field_error = self.errors.custom_fields[0]
+ self.assertEqual(123, custom_field_error.field_id)
+ self.assertEqual('Value must be <= 999.', custom_field_error.message)
+ self.assertEqual(len(err_msgs), 1)
+ self.assertTrue(re.search(r'Value must be <= 999.', err_msgs[0]))
+
+ def testValidateCustomFields_DeletedRequiredFields_Ignored(self):
+ issue = fake.MakeTestIssue(
+ 789,
+ 1,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78901,
+ labels=['type-defect', 'other-label'])
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None, '', False,
+ False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', True)
+ self.config.field_defs.append(fd)
+
+ err_msgs = field_helpers.ValidateCustomFields(
+ self.mr,
+ self.services, [],
+ self.config,
+ self.mr.project,
+ ezt_errors=self.errors,
+ issue=issue)
+ self.assertFalse(self.errors.AnyErrors())
+ self.assertEqual(err_msgs, [])
+
+ def testValidateCustomFields_RequiredFields_Normal(self):
+ issue = fake.MakeTestIssue(
+ 789,
+ 1,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78901,
+ labels=['type-defect', 'other-label'])
+
+ required = True
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None, '', required,
+ False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ self.config.field_defs.append(fd)
+ fv1 = tracker_bizobj.MakeFieldValue(
+ 123, 8086, None, None, None, None, False)
+ fv2 = tracker_bizobj.MakeFieldValue(123, 486, None, None, None, None, False)
+
+ err_msgs = field_helpers.ValidateCustomFields(
+ self.mr,
+ self.services, [fv1, fv2],
+ self.config,
+ self.mr.project,
+ issue=issue)
+ self.assertEqual(len(err_msgs), 0)
+
+ def testValidateCustomFields_RequiredFields_ErrorsWhenMissing(self):
+ issue = fake.MakeTestIssue(
+ 789,
+ 1,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78901,
+ labels=['type-defect', 'other-label'])
+
+ required = True
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None, '', required,
+ False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ self.config.field_defs.append(fd)
+
+ err_msgs = field_helpers.ValidateCustomFields(
+ self.mr, self.services, [], self.config, self.mr.project, issue=issue)
+ self.assertEqual(len(err_msgs), 1)
+ self.assertTrue(re.search(r'CPU field is required.', err_msgs[0]))
+
+ def testValidateCustomFields_RequiredFields_EnumFieldNormal(self):
+ # Enums are a special case because their values are stored in labels.
+ issue = fake.MakeTestIssue(
+ 789,
+ 1,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78901,
+ labels=['type-defect', 'other-label', 'CPU-enum-value'])
+ required = True
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.ENUM_TYPE, None, '', required,
+ False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ self.config.field_defs.append(fd)
+
+ err_msgs = field_helpers.ValidateCustomFields(
+ self.mr, self.services, [], self.config, self.mr.project, issue=issue)
+ self.assertEqual(len(err_msgs), 0)
+
+ def testValidateCustomFields_RequiredFields_EnumFieldMultiWord(self):
+ # Enum fields with dashes in them require special label prefix parsing.
+ issue = fake.MakeTestIssue(
+ 789,
+ 1,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78901,
+ labels=['type-defect', 'other-label', 'an-enum-value'])
+ required = True
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'an-enum', tracker_pb2.FieldTypes.ENUM_TYPE, None, '',
+ required, False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ self.config.field_defs.append(fd)
+
+ err_msgs = field_helpers.ValidateCustomFields(
+ self.mr, self.services, [], self.config, self.mr.project, issue=issue)
+ self.assertEqual(len(err_msgs), 0)
+
+ def testValidateCustomFields_RequiredFields_EnumFieldError(self):
+ # Enums are a special case because their values are stored in labels.
+ issue = fake.MakeTestIssue(
+ 789,
+ 1,
+ 'sum',
+ 'New',
+ 111,
+ issue_id=78901,
+ labels=['type-defect', 'other-label'])
+ required = True
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'CPU', tracker_pb2.FieldTypes.ENUM_TYPE, None, '', required,
+ False, False, None, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
+ self.config.field_defs.append(fd)
+
+ err_msgs = field_helpers.ValidateCustomFields(
+ self.mr, self.services, [], self.config, self.mr.project, issue=issue)
+ self.assertEqual(len(err_msgs), 1)
+ self.assertTrue(re.search(r'CPU field is required.', err_msgs[0]))
+
+ def testAssertCustomFieldsEditPerms_Empty(self):
+ self.assertIsNone(
+ field_helpers.AssertCustomFieldsEditPerms(
+ self.mr, self.config, [], [], [], [], []))
+
+ def testAssertCustomFieldsEditPerms_Normal(self):
+ self.services.user.TestAddUser('user@example.com', 222)
+ self.mr.auth.effective_ids = {222}
+ fd_int = tracker_bizobj.MakeFieldDef(
+ 11111,
+ 1,
+ 'fdInt',
+ tracker_pb2.FieldTypes.INT_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=True)
+ fd_str = tracker_bizobj.MakeFieldDef(
+ 22222,
+ 1,
+ 'fdStr',
+ tracker_pb2.FieldTypes.STR_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=True)
+ fd_date = tracker_bizobj.MakeFieldDef(
+ 33333,
+ 1,
+ 'fdDate',
+ tracker_pb2.FieldTypes.DATE_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=True)
+ fd_enum1 = tracker_bizobj.MakeFieldDef(
+ 44444,
+ 1,
+ 'fdEnum1',
+ tracker_pb2.FieldTypes.ENUM_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=True)
+ fd_enum2 = tracker_bizobj.MakeFieldDef(
+ 55555,
+ 1,
+ 'fdEnum2',
+ tracker_pb2.FieldTypes.ENUM_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=True)
+ self.config.field_defs = [fd_int, fd_str, fd_date, fd_enum1, fd_enum2]
+ fv1 = tracker_bizobj.MakeFieldValue(
+ 11111, 37, None, None, None, None, False)
+ fv2 = tracker_bizobj.MakeFieldValue(
+ 22222, None, 'Chicken', None, None, None, False)
+ self.assertIsNone(
+ field_helpers.AssertCustomFieldsEditPerms(
+ self.mr, self.config, [fv1], [fv2], [33333], ['Dog', 'fdEnum1-a'],
+ ['Cat', 'fdEnum2-b']))
+
+ def testAssertCustomFieldsEditPerms_Reject(self):
+ self.mr.perms = permissions.PermissionSet([])
+ fd_int = tracker_bizobj.MakeFieldDef(
+ 11111,
+ 1,
+ 'fdInt',
+ tracker_pb2.FieldTypes.INT_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=True)
+ fd_enum = tracker_bizobj.MakeFieldDef(
+ 44444,
+ 1,
+ 'fdEnum',
+ tracker_pb2.FieldTypes.ENUM_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=True)
+ self.config.field_defs = [fd_int, fd_enum]
+ fv = tracker_bizobj.MakeFieldValue(11111, 37, None, None, None, None, False)
+
+ self.assertRaises(
+ AssertionError, field_helpers.AssertCustomFieldsEditPerms, self.mr,
+ self.config, [fv], [], [], [], [])
+
+ self.assertRaises(
+ AssertionError, field_helpers.AssertCustomFieldsEditPerms, self.mr,
+ self.config, [], [fv], [], [], [])
+
+ self.assertRaises(
+ AssertionError, field_helpers.AssertCustomFieldsEditPerms, self.mr,
+ self.config, [], [], [11111], [], [])
+
+ self.assertRaises(
+ AssertionError, field_helpers.AssertCustomFieldsEditPerms, self.mr,
+ self.config, [], [], [], ['Dog', 'fdEnum-a'], [])
+
+ self.assertRaises(
+ AssertionError, field_helpers.AssertCustomFieldsEditPerms, self.mr,
+ self.config, [], [], [], [], ['Cat', 'fdEnum-b'])
+
+ def testApplyRestrictedDefaultValues(self):
+ self.mr.perms = permissions.PermissionSet([])
+ self.services.user.TestAddUser('user@example.com', 222)
+ self.mr.auth.effective_ids = {222}
+ fd_int = tracker_bizobj.MakeFieldDef(
+ 11111,
+ 1,
+ 'fdInt',
+ tracker_pb2.FieldTypes.INT_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=False)
+ fd_str = tracker_bizobj.MakeFieldDef(
+ 22222,
+ 1,
+ 'fdStr',
+ tracker_pb2.FieldTypes.STR_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=True)
+ fd_str_2 = tracker_bizobj.MakeFieldDef(
+ 33333,
+ 1,
+ 'fdStr_2',
+ tracker_pb2.FieldTypes.STR_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=False)
+ fd_enum = tracker_bizobj.MakeFieldDef(
+ 44444,
+ 1,
+ 'fdEnum',
+ tracker_pb2.FieldTypes.ENUM_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=False)
+ fd_restricted_enum = tracker_bizobj.MakeFieldDef(
+ 55555,
+ 1,
+ 'fdRestrictedEnum',
+ tracker_pb2.FieldTypes.ENUM_TYPE,
+ None,
+ '',
+ False,
+ False,
+ False,
+ None,
+ None,
+ '',
+ False,
+ '',
+ '',
+ tracker_pb2.NotifyTriggers.NEVER,
+ 'no_action',
+ 'doc',
+ False,
+ is_restricted_field=True)
+ self.config.field_defs = [
+ fd_int, fd_str, fd_str_2, fd_enum, fd_restricted_enum
+ ]
+ fv = tracker_bizobj.MakeFieldValue(
+ 33333, None, 'Happy', None, None, None, False)
+ temp_fv = tracker_bizobj.MakeFieldValue(
+ 11111, 37, None, None, None, None, False)
+ temp_restricted_fv = tracker_bizobj.MakeFieldValue(
+ 22222, None, 'Chicken', None, None, None, False)
+ field_vals = [fv]
+ labels = ['Car', 'Bus']
+ temp_field_vals = [temp_fv, temp_restricted_fv]
+ temp_labels = ['Bike', 'fdEnum-a', 'fdRestrictedEnum-b']
+ field_helpers.ApplyRestrictedDefaultValues(
+ self.mr, self.config, field_vals, labels, temp_field_vals, temp_labels)
+ self.assertEqual(labels, ['Car', 'Bus', 'fdRestrictedEnum-b'])
+ self.assertEqual(field_vals, [fv, temp_restricted_fv])
+
+ def testFormatUrlFieldValue(self):
+ self.assertEqual('http://www.google.com',
+ field_helpers.FormatUrlFieldValue('www.google.com'))
+ self.assertEqual('https://www.bing.com',
+ field_helpers.FormatUrlFieldValue('https://www.bing.com'))
+
+ def testReviseFieldDefFromParsed_INT(self):
+ parsed_field_def = field_helpers.ParsedFieldDef(
+ 'EstDays',
+ 'int_type',
+ min_value=5,
+ max_value=7,
+ regex='',
+ needs_member=True,
+ needs_perm='Commit',
+ grants_perm='View',
+ notify_on=tracker_pb2.NotifyTriggers.ANY_COMMENT,
+ is_required=True,
+ is_niche=True,
+ importance='required',
+ is_multivalued=True,
+ field_docstring='updated doc',
+ choices_text='',
+ applicable_type='Launch',
+ applicable_predicate='',
+ revised_labels=[],
+ date_action_str='ping_participants',
+ approvers_str='',
+ survey='',
+ parent_approval_name='',
+ is_phase_field=False,
+ is_restricted_field=False)
+
+ fd = tracker_bizobj.MakeFieldDef(
+ 123, 789, 'EstDays', tracker_pb2.FieldTypes.INT_TYPE, None,
+ '', False, False, False, 4, None, '', False, '', '',
+ tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False,
+ approval_id=3)
+
+ new_fd = field_helpers.ReviseFieldDefFromParsed(parsed_field_def, fd)
+ # assert INT fields
+ self.assertEqual(new_fd.min_value, 5)
+ self.assertEqual(new_fd.max_value, 7)
+
+ # assert USER fields
+ self.assertEqual(new_fd.notify_on, tracker_pb2.NotifyTriggers.ANY_COMMENT)
+ self.assertTrue(new_fd.needs_member)
+ self.assertEqual(new_fd.needs_perm, 'Commit')
+ self.assertEqual(new_fd.grants_perm, 'View')
+
+ # assert DATE fields
+ self.assertEqual(new_fd.date_action,
+ tracker_pb2.DateAction.PING_PARTICIPANTS)
+
+ # assert general fields
+ self.assertTrue(new_fd.is_required)
+ self.assertTrue(new_fd.is_niche)
+ self.assertEqual(new_fd.applicable_type, 'Launch')
+ self.assertEqual(new_fd.docstring, 'updated doc')
+ self.assertTrue(new_fd.is_multivalued)
+ self.assertEqual(new_fd.approval_id, 3)
+ self.assertFalse(new_fd.is_phase_field)
+ self.assertFalse(new_fd.is_restricted_field)
+
+ def testParsedFieldDefAssertions_Accepted(self):
+ parsed_fd = field_helpers.ParsedFieldDef(
+ 'EstDays',
+ 'int_type',
+ min_value=5,
+ max_value=7,
+ regex='',
+ needs_member=True,
+ needs_perm='Commit',
+ grants_perm='View',
+ notify_on=tracker_pb2.NotifyTriggers.ANY_COMMENT,
+ is_required=True,
+ is_niche=False,
+ importance='required',
+ is_multivalued=True,
+ field_docstring='updated doc',
+ choices_text='',
+ applicable_type='Launch',
+ applicable_predicate='',
+ revised_labels=[],
+ date_action_str='ping_participants',
+ approvers_str='',
+ survey='',
+ parent_approval_name='',
+ is_phase_field=False,
+ is_restricted_field=False)
+
+ field_helpers.ParsedFieldDefAssertions(self.mr, parsed_fd)
+ self.assertFalse(self.mr.errors.AnyErrors())
+
+ def testParsedFieldDefAssertions_Rejected(self):
+ parsed_fd = field_helpers.ParsedFieldDef(
+ 'restrictApprovalField',
+ 'approval_type',
+ min_value=10,
+ max_value=7,
+ regex='/foo(?)/',
+ needs_member=True,
+ needs_perm='Commit',
+ grants_perm='View',
+ notify_on=tracker_pb2.NotifyTriggers.ANY_COMMENT,
+ is_required=True,
+ is_niche=True,
+ importance='required',
+ is_multivalued=True,
+ field_docstring='updated doc',
+ choices_text='',
+ applicable_type='Launch',
+ applicable_predicate='',
+ revised_labels=[],
+ date_action_str='custom_date_action_str',
+ approvers_str='',
+ survey='',
+ parent_approval_name='',
+ is_phase_field=False,
+ is_restricted_field=True)
+
+ field_helpers.ParsedFieldDefAssertions(self.mr, parsed_fd)
+ self.assertTrue(self.mr.errors.AnyErrors())
+
+ self.assertEqual(
+ self.mr.errors.is_niche, 'A field cannot be both required and niche.')
+ self.assertEqual(
+ self.mr.errors.date_action,
+ 'The date action should be either: ' + ', '.join(
+ config_svc.DATE_ACTION_ENUM) + '.')
+ self.assertEqual(
+ self.mr.errors.min_value, 'Minimum value must be less than maximum.')
+ self.assertEqual(self.mr.errors.regex, 'Invalid regular expression.')