def testConvertFieldValues_ClearAndRemove(self): """The client wants to clear and remove some custom fields.""" mar = mock.Mock() mar.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) mar.config.field_defs = [ tracker_bizobj.MakeFieldDef(1, 789, 'Priority', tracker_pb2.FieldTypes.ENUM_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef(11, 789, 'OS', tracker_pb2.FieldTypes.ENUM_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef(2, 789, 'EstDays', tracker_pb2.FieldTypes.INT_TYPE, None, None, False, False, False, 0, 99, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef(3, 789, 'Nickname', tracker_pb2.FieldTypes.STR_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), ] field_values = [ api_pb2_v1.FieldValue( fieldName='Priority', fieldValue='High', operator=api_pb2_v1.FieldValueOperator.remove), api_pb2_v1.FieldValue( fieldName='OS', operator=api_pb2_v1.FieldValueOperator.clear), api_pb2_v1.FieldValue( fieldName='EstDays', operator=api_pb2_v1.FieldValueOperator.clear), api_pb2_v1.FieldValue( fieldName='Nickname', fieldValue='Scout', operator=api_pb2_v1.FieldValueOperator.remove), ] actual = api_pb2_v1_helpers.convert_field_values( field_values, mar, self.services) (fv_list_add, fv_list_remove, fv_list_clear, label_list_add, label_list_remove) = actual self.assertEquals([], fv_list_add) self.assertEquals([ tracker_bizobj.MakeFieldValue(3, None, 'Scout', None, None, None, False) ], fv_list_remove) self.assertEquals([11, 2], fv_list_clear) self.assertEquals([], label_list_add) self.assertEquals(['Priority-High'], label_list_remove)
def convert_approval_amendments(amendments, mar, services): """Convert a list of Monorail Amendment PBs API ApprovalUpdate.""" amendments_user_ids = tracker_bizobj.UsersInvolvedInAmendments(amendments) users_by_id = framework_views.MakeAllUserViews(mar.cnxn, services.user, amendments_user_ids) framework_views.RevealAllEmailsToMembers(mar.auth, mar.project, users_by_id) result = api_pb2_v1.ApprovalUpdate(kind='monorail#approvalCommentUpdate') for amendment in amendments: if amendment.field == tracker_pb2.FieldID.CUSTOM: if amendment.custom_field_name == 'Status': status_number = tracker_pb2.ApprovalStatus( amendment.newvalue.upper()).number result.status = api_pb2_v1.ApprovalStatus(status_number).name elif amendment.custom_field_name == 'Approvers': for user_id in amendment.added_user_ids: user_email = _get_user_email(services.user, mar.cnxn, user_id) result.approvers.append(user_email) for user_id in amendment.removed_user_ids: user_email = _get_user_email(services.user, mar.cnxn, user_id) result.approvers.append('-%s' % user_email) else: fv = api_pb2_v1.FieldValue() fv.fieldName = amendment.custom_field_name fv.fieldValue = tracker_bizobj.AmendmentString( amendment, users_by_id) # TODO(jojwang): monorail:4229, add approvalName field to FieldValue result.fieldValues.append(fv) return result
def testConvertFieldValues_Errors(self): """We don't crash on bad requests.""" mar = mock.Mock() mar.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) mar.config.field_defs = [ tracker_bizobj.MakeFieldDef(2, 789, 'EstDays', tracker_pb2.FieldTypes.INT_TYPE, None, None, False, False, False, 0, 99, None, False, None, None, None, None, 'doc', False), ] field_values = [ api_pb2_v1.FieldValue( fieldName='Unknown', operator=api_pb2_v1.FieldValueOperator.clear), ] actual = api_pb2_v1_helpers.convert_field_values( field_values, mar, self.services) (fv_list_add, fv_list_remove, fv_list_clear, label_list_add, label_list_remove) = actual self.assertEquals([], fv_list_add) self.assertEquals([], fv_list_remove) self.assertEquals([], fv_list_clear) self.assertEquals([], label_list_add) self.assertEquals([], label_list_remove)
def testConvertFieldValues_Normal(self): """The client wants to edit a custom field.""" mar = mock.Mock() mar.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) mar.config.field_defs = [ tracker_bizobj.MakeFieldDef( 1, 789, 'Priority', tracker_pb2.FieldTypes.ENUM_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef( 2, 789, 'EstDays', tracker_pb2.FieldTypes.INT_TYPE, None, None, False, False, False, 0, 99, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef( 3, 789, 'Nickname', tracker_pb2.FieldTypes.STR_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef( 4, 789, 'Verifier', tracker_pb2.FieldTypes.USER_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef( 5, 789, 'Deadline', tracker_pb2.FieldTypes.DATE_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef( 6, 789, 'Homepage', tracker_pb2.FieldTypes.URL_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), ] field_values = [ api_pb2_v1.FieldValue(fieldName='Priority', fieldValue='High'), api_pb2_v1.FieldValue(fieldName='EstDays', fieldValue='4'), api_pb2_v1.FieldValue(fieldName='Nickname', fieldValue='Scout'), api_pb2_v1.FieldValue( fieldName='Verifier', fieldValue='*****@*****.**'), api_pb2_v1.FieldValue(fieldName='Deadline', fieldValue='2017-12-06'), api_pb2_v1.FieldValue( fieldName='Homepage', fieldValue='http://example.com'), ] actual = api_pb2_v1_helpers.convert_field_values( field_values, mar, self.services) (fv_list_add, fv_list_remove, fv_list_clear, label_list_add, label_list_remove) = actual self.assertEquals( [tracker_bizobj.MakeFieldValue(2, 4, None, None, None, None, False), tracker_bizobj.MakeFieldValue(3, None, 'Scout', None, None, None, False), tracker_bizobj.MakeFieldValue(4, None, None, 111, None, None, False), tracker_bizobj.MakeFieldValue( 5, None, None, None, 1512518400, None, False), tracker_bizobj.MakeFieldValue( 6, None, None, None, None, 'http://example.com', False), ], fv_list_add) self.assertEquals([], fv_list_remove) self.assertEquals([], fv_list_clear) self.assertEquals(['Priority-High'], label_list_add) self.assertEquals([], label_list_remove)
def convert_amendments(issue, amendments, mar, services): """Convert a list of Monorail Amendment PBs to API Update.""" amendments_user_ids = tracker_bizobj.UsersInvolvedInAmendments(amendments) users_by_id = framework_views.MakeAllUserViews(mar.cnxn, services.user, amendments_user_ids) framework_views.RevealAllEmailsToMembers(mar.auth, mar.project, users_by_id) result = api_pb2_v1.Update(kind='monorail#issueCommentUpdate') for amendment in amendments: if amendment.field == tracker_pb2.FieldID.SUMMARY: result.summary = amendment.newvalue elif amendment.field == tracker_pb2.FieldID.STATUS: result.status = amendment.newvalue elif amendment.field == tracker_pb2.FieldID.OWNER: if len(amendment.added_user_ids) == 0: result.owner = framework_constants.NO_USER_NAME else: result.owner = _get_user_email(services.user, mar.cnxn, amendment.added_user_ids[0]) elif amendment.field == tracker_pb2.FieldID.LABELS: result.labels = amendment.newvalue.split() elif amendment.field == tracker_pb2.FieldID.CC: for user_id in amendment.added_user_ids: user_email = _get_user_email(services.user, mar.cnxn, user_id) result.cc.append(user_email) for user_id in amendment.removed_user_ids: user_email = _get_user_email(services.user, mar.cnxn, user_id) result.cc.append('-%s' % user_email) elif amendment.field == tracker_pb2.FieldID.BLOCKEDON: result.blockedOn = _append_project(amendment.newvalue, issue.project_name) elif amendment.field == tracker_pb2.FieldID.BLOCKING: result.blocking = _append_project(amendment.newvalue, issue.project_name) elif amendment.field == tracker_pb2.FieldID.MERGEDINTO: result.mergedInto = amendment.newvalue elif amendment.field == tracker_pb2.FieldID.COMPONENTS: result.components = amendment.newvalue.split() elif amendment.field == tracker_pb2.FieldID.CUSTOM: fv = api_pb2_v1.FieldValue() fv.fieldName = amendment.custom_field_name fv.fieldValue = tracker_bizobj.AmendmentString( amendment, users_by_id) result.fieldValues.append(fv) return result
def testConvertIssue(self): """Convert an internal Issue PB to an IssueWrapper API PB.""" self.services.project.TestAddProject( 'test-project', owner_ids=[2], project_id=12345) self.services.user.TestAddUser('*****@*****.**', 111) mar = mock.Mock() mar.cnxn = None mar.project_name = 'test-project' mar.project_id = 12345 mar.auth.effective_ids = {111} mar.perms = permissions.READ_ONLY_PERMISSIONSET mar.profiler = profiler.Profiler() mar.config = tracker_bizobj.MakeDefaultProjectIssueConfig(12345) mar.config.field_defs = [ tracker_bizobj.MakeFieldDef( 1, 12345, 'EstDays', tracker_pb2.FieldTypes.INT_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False, approval_id=2), tracker_bizobj.MakeFieldDef( 2, 12345, 'DesignReview', tracker_pb2.FieldTypes.APPROVAL_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef( 3, 12345, 'StringField', tracker_pb2.FieldTypes.STR_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), tracker_bizobj.MakeFieldDef( 4, 12345, 'DressReview', tracker_pb2.FieldTypes.APPROVAL_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'doc', False), ] self.services.config.StoreConfig(mar.cnxn, mar.config) now = 1472067725 now_dt = datetime.datetime.fromtimestamp(now) fvs = [ tracker_bizobj.MakeFieldValue( 1, 4, None, None, None, None, False, phase_id=4), tracker_bizobj.MakeFieldValue( 3, None, 'string', None, None, None, False, phase_id=4), # missing phase tracker_bizobj.MakeFieldValue( 3, None, u'\xe2\x9d\xa4\xef\xb8\x8f', None, None, None, False, phase_id=2), ] phases = [ tracker_pb2.Phase(phase_id=3, name="JustAPhase", rank=4), tracker_pb2.Phase(phase_id=4, name="NotAPhase", rank=9) ] approval_values = [ tracker_pb2.ApprovalValue( approval_id=2, phase_id=3, approver_ids=[111]), tracker_pb2.ApprovalValue(approval_id=4, approver_ids=[111]) ] issue = fake.MakeTestIssue( 12345, 1, 'one', 'New', 111, field_values=fvs, approval_values=approval_values, phases=phases) issue.opened_timestamp = now issue.owner_modified_timestamp = now issue.status_modified_timestamp = now issue.component_modified_timestamp = now # TODO(jrobbins): set up a lot more fields. for cls in [api_pb2_v1.IssueWrapper, api_pb2_v1.IssuesGetInsertResponse]: result = api_pb2_v1_helpers.convert_issue(cls, issue, mar, self.services) self.assertEquals(1, result.id) self.assertEquals('one', result.title) self.assertEquals('one', result.summary) self.assertEquals(now_dt, result.published) self.assertEquals(now_dt, result.owner_modified) self.assertEquals(now_dt, result.status_modified) self.assertEquals(now_dt, result.component_modified) self.assertEquals( result.fieldValues, [api_pb2_v1.FieldValue( fieldName='EstDays', fieldValue='4', approvalName='DesignReview', derived=False), api_pb2_v1.FieldValue(fieldName='StringField', fieldValue='string', phaseName="NotAPhase", derived=False), api_pb2_v1.FieldValue(fieldName='StringField', fieldValue=u'\xe2\x9d\xa4\xef\xb8\x8f', derived=False), ] ) self.assertEqual( result.approvalValues, [api_pb2_v1.Approval( approvalName="DesignReview", approvers=[self.person_1], status=api_pb2_v1.ApprovalStatus.notSet, phaseName="JustAPhase", ), api_pb2_v1.Approval( approvalName="DressReview", approvers=[self.person_1], status=api_pb2_v1.ApprovalStatus.notSet, )] ) self.assertEqual( result.phases, [api_pb2_v1.Phase(phaseName="JustAPhase", rank=4), api_pb2_v1.Phase(phaseName="NotAPhase", rank=9) ])
def convert_issue(cls, issue, mar, services): """Convert Monorail Issue PB to API IssuesGetInsertResponse.""" config = services.config.GetProjectConfig(mar.cnxn, issue.project_id) granted_perms = tracker_bizobj.GetGrantedPerms(issue, mar.auth.effective_ids, config) issue_project = services.project.GetProject(mar.cnxn, issue.project_id) component_list = [] for cd in config.component_defs: cid = cd.component_id if cid in issue.component_ids: component_list.append(cd.path) cc_list = [convert_person(p, mar.cnxn, services) for p in issue.cc_ids] cc_list = [p for p in cc_list if p is not None] field_values_list = [] fds_by_id = {fd.field_id: fd for fd in config.field_defs} phases_by_id = {phase.phase_id: phase for phase in issue.phases} for fv in issue.field_values: fd = fds_by_id.get(fv.field_id) if not fd: logging.warning('Custom field %d of project %s does not exist', fv.field_id, issue_project.project_name) continue val = None if fv.user_id: val = _get_user_email(services.user, mar.cnxn, fv.user_id) else: val = tracker_bizobj.GetFieldValue(fv, {}) if not isinstance(val, string_types): val = str(val) new_fv = api_pb2_v1.FieldValue(fieldName=fd.field_name, fieldValue=val, derived=fv.derived) if fd.approval_id: # Attach parent approval name approval_fd = fds_by_id.get(fd.approval_id) if not approval_fd: logging.warning( 'Parent approval field %d of field %s does not exist', fd.approval_id, fd.field_name) else: new_fv.approvalName = approval_fd.field_name elif fv.phase_id: # Attach phase name phase = phases_by_id.get(fv.phase_id) if not phase: logging.warning('Phase %d for field %s does not exist', fv.phase_id, fd.field_name) else: new_fv.phaseName = phase.name field_values_list.append(new_fv) approval_values_list = convert_approvals(mar.cnxn, issue.approval_values, services, config, issue.phases) phases_list = convert_phases(issue.phases) with work_env.WorkEnv(mar, services) as we: starred = we.IsIssueStarred(issue) resp = cls( kind='monorail#issue', id=issue.local_id, title=issue.summary, summary=issue.summary, projectId=issue_project.project_name, stars=issue.star_count, starred=starred, status=issue.status, state=(api_pb2_v1.IssueState.open if tracker_helpers.MeansOpenInProject( tracker_bizobj.GetStatus(issue), config) else api_pb2_v1.IssueState.closed), labels=issue.labels, components=component_list, author=convert_person(issue.reporter_id, mar.cnxn, services), owner=convert_person(issue.owner_id, mar.cnxn, services), cc=cc_list, updated=datetime.datetime.fromtimestamp(issue.modified_timestamp), published=datetime.datetime.fromtimestamp(issue.opened_timestamp), blockedOn=convert_issue_ids(issue.blocked_on_iids, mar, services), blocking=convert_issue_ids(issue.blocking_iids, mar, services), canComment=permissions.CanCommentIssue(mar.auth.effective_ids, mar.perms, issue_project, issue, granted_perms=granted_perms), canEdit=permissions.CanEditIssue(mar.auth.effective_ids, mar.perms, issue_project, issue, granted_perms=granted_perms), fieldValues=field_values_list, approvalValues=approval_values_list, phases=phases_list) if issue.closed_timestamp > 0: resp.closed = datetime.datetime.fromtimestamp(issue.closed_timestamp) if issue.merged_into: resp.mergedInto = convert_issue_ids([issue.merged_into], mar, services)[0] if issue.owner_modified_timestamp: resp.owner_modified = datetime.datetime.fromtimestamp( issue.owner_modified_timestamp) if issue.status_modified_timestamp: resp.status_modified = datetime.datetime.fromtimestamp( issue.status_modified_timestamp) if issue.component_modified_timestamp: resp.component_modified = datetime.datetime.fromtimestamp( issue.component_modified_timestamp) return resp
def convert_issue(cls, issue, mar, services): """Convert Monorail Issue PB to API IssuesGetInsertResponse.""" config = services.config.GetProjectConfig(mar.cnxn, issue.project_id) granted_perms = tracker_bizobj.GetGrantedPerms( issue, mar.auth.effective_ids, config) issue_project = services.project.GetProject(mar.cnxn, issue.project_id) component_list = [] for cd in config.component_defs: cid = cd.component_id if cid in issue.component_ids: component_list.append(cd.path) cc_list = [convert_person(p, mar.cnxn, services) for p in issue.cc_ids] cc_list = [p for p in cc_list if p is not None] field_values_list = [] field_id_dict = { fd.field_id: fd.field_name for fd in config.field_defs} for fv in issue.field_values: field_name = field_id_dict.get(fv.field_id) if not field_name: logging.warning('Custom field %d of project %s does not exist', fv.field_id, issue_project.project_name) continue val = None if fv.user_id: val = _get_user_email( services.user, mar.cnxn, fv.user_id) elif fv.str_value: val = fv.str_value elif fv.int_value: val = str(fv.int_value) new_fv = api_pb2_v1.FieldValue( fieldName=field_name, fieldValue=val, derived=fv.derived) field_values_list.append(new_fv) resp = cls( kind='monorail#issue', id=issue.local_id, title=issue.summary, summary=issue.summary, projectId=issue_project.project_name, stars=issue.star_count, starred=services.issue_star.IsItemStarredBy( mar.cnxn, issue.issue_id, mar.auth.user_id), status=issue.status, state=(api_pb2_v1.IssueState.open if tracker_helpers.MeansOpenInProject( tracker_bizobj.GetStatus(issue), config) else api_pb2_v1.IssueState.closed), labels=issue.labels, components=component_list, author=convert_person(issue.reporter_id, mar.cnxn, services), owner=convert_person(issue.owner_id, mar.cnxn, services), cc=cc_list, updated=datetime.datetime.fromtimestamp(issue.modified_timestamp), published=datetime.datetime.fromtimestamp(issue.opened_timestamp), blockedOn=convert_issue_ids(issue.blocked_on_iids, mar, services), blocking=convert_issue_ids(issue.blocking_iids, mar, services), canComment=permissions.CanCommentIssue( mar.auth.effective_ids, mar.perms, issue_project, issue, granted_perms=granted_perms), canEdit=permissions.CanEditIssue( mar.auth.effective_ids, mar.perms, issue_project, issue, granted_perms=granted_perms), fieldValues=field_values_list) if issue.closed_timestamp > 0: resp.closed = datetime.datetime.fromtimestamp(issue.closed_timestamp) if issue.merged_into: resp.mergedInto=convert_issue_ids([issue.merged_into], mar, services)[0] if issue.owner_modified_timestamp: resp.owner_modified = datetime.datetime.fromtimestamp( issue.owner_modified_timestamp) if issue.status_modified_timestamp: resp.status_modified = datetime.datetime.fromtimestamp( issue.status_modified_timestamp) if issue.component_modified_timestamp: resp.component_modified = datetime.datetime.fromtimestamp( issue.component_modified_timestamp) return resp