Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
  def issues_insert(self, request):
    """Add a new issue."""
    mar = self.mar_factory(request)
    if not mar.perms.CanUsePerm(
        permissions.CREATE_ISSUE, mar.auth.effective_ids, mar.project, []):
      raise permissions.PermissionException(
          'The requester %s is not allowed to create issues for project %s.' %
          (mar.auth.email, mar.project_name))

    owner_id = None
    if request.owner:
      try:
        owner_id = self._services.user.LookupUserID(
            mar.cnxn, request.owner.name)
      except user_svc.NoSuchUserException:
        raise endpoints.BadRequestException(
            'The specified owner %s does not exist.' % request.owner.name)

    cc_ids = []
    if request.cc:
      cc_ids = self._services.user.LookupUserIDs(
          mar.cnxn, [ap.name for ap in request.cc],
          autocreate=True).values()
    comp_ids = api_pb2_v1_helpers.convert_component_ids(
        mar.config, request.components)
    fields_add, _, _, fields_labels, _ = (
        api_pb2_v1_helpers.convert_field_values(
            request.fieldValues, mar, self._services))
    field_helpers.ValidateCustomFields(
        mar, self._services, fields_add, mar.config, mar.errors)
    if mar.errors.AnyErrors():
      raise endpoints.BadRequestException(
          'Invalid field values: %s' % mar.errors.custom_fields)

    local_id = self._services.issue.CreateIssue(
        mar.cnxn, self._services, mar.project_id,
        request.summary, request.status, owner_id,
        cc_ids, request.labels + fields_labels, fields_add,
        comp_ids, mar.auth.user_id, request.description,
        blocked_on=api_pb2_v1_helpers.convert_issueref_pbs(
            request.blockedOn, mar, self._services),
        blocking=api_pb2_v1_helpers.convert_issueref_pbs(
            request.blocking, mar, self._services))
    new_issue = self._services.issue.GetIssueByLocalID(
        mar.cnxn, mar.project_id, local_id)

    self._services.issue_star.SetStar(
        mar.cnxn, self._services, mar.config, new_issue.issue_id,
        mar.auth.user_id, True)

    if request.sendEmail:
      notify.PrepareAndSendIssueChangeNotification(
          new_issue.issue_id, framework_helpers.GetHostPort(),
          new_issue.reporter_id, 0)

    return api_pb2_v1_helpers.convert_issue(
        api_pb2_v1.IssuesGetInsertResponse, new_issue, mar, self._services)
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
  def testConvertFieldValues_Empty(self):
    """The client's request might not have any field edits."""
    mar = mock.Mock()
    mar.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)

    field_values = []
    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)
Exemplo n.º 6
0
  def issues_comments_insert(self, request):
    """Add a comment."""
    mar = self.mar_factory(request)
    issue = self._services.issue.GetIssueByLocalID(
        mar.cnxn, mar.project_id, request.issueId)
    old_owner_id = tracker_bizobj.GetOwnerId(issue)
    if not permissions.CanCommentIssue(
        mar.auth.effective_ids, mar.perms, mar.project, issue,
        mar.granted_perms):
      raise permissions.PermissionException(
          'User is not allowed to comment this issue (%s, %d)' %
          (request.projectId, request.issueId))

    updates_dict = {}
    if request.updates:
      if request.updates.moveToProject:
        move_to = request.updates.moveToProject.lower()
        move_to_project = issuedetail.CheckMoveIssueRequest(
            self._services, mar, issue, True, move_to, mar.errors)
        if mar.errors.AnyErrors():
          raise endpoints.BadRequestException(mar.errors.move_to)
        updates_dict['move_to_project'] = move_to_project

      updates_dict['summary'] = request.updates.summary
      updates_dict['status'] = request.updates.status
      if request.updates.owner:
        if request.updates.owner == framework_constants.NO_USER_NAME:
          updates_dict['owner'] = framework_constants.NO_USER_SPECIFIED
        else:
          updates_dict['owner'] = self._services.user.LookupUserID(
              mar.cnxn, request.updates.owner)
      updates_dict['cc_add'], updates_dict['cc_remove'] = (
          api_pb2_v1_helpers.split_remove_add(request.updates.cc))
      updates_dict['cc_add'] = self._services.user.LookupUserIDs(
          mar.cnxn, updates_dict['cc_add'], autocreate=True).values()
      updates_dict['cc_remove'] = self._services.user.LookupUserIDs(
          mar.cnxn, updates_dict['cc_remove']).values()
      updates_dict['labels_add'], updates_dict['labels_remove'] = (
          api_pb2_v1_helpers.split_remove_add(request.updates.labels))
      blocked_on_add_strs, blocked_on_remove_strs = (
          api_pb2_v1_helpers.split_remove_add(request.updates.blockedOn))
      updates_dict['blocked_on_add'] = api_pb2_v1_helpers.issue_global_ids(
          blocked_on_add_strs, issue.project_id, mar,
          self._services)
      updates_dict['blocked_on_remove'] = api_pb2_v1_helpers.issue_global_ids(
          blocked_on_remove_strs, issue.project_id, mar,
          self._services)
      blocking_add_strs, blocking_remove_strs = (
          api_pb2_v1_helpers.split_remove_add(request.updates.blocking))
      updates_dict['blocking_add'] = api_pb2_v1_helpers.issue_global_ids(
          blocking_add_strs, issue.project_id, mar,
          self._services)
      updates_dict['blocking_remove'] = api_pb2_v1_helpers.issue_global_ids(
          blocking_remove_strs, issue.project_id, mar,
          self._services)
      components_add_strs, components_remove_strs = (
          api_pb2_v1_helpers.split_remove_add(request.updates.components))
      updates_dict['components_add'] = (
          api_pb2_v1_helpers.convert_component_ids(
              mar.config, components_add_strs))
      updates_dict['components_remove'] = (
          api_pb2_v1_helpers.convert_component_ids(
              mar.config, components_remove_strs))
      if request.updates.mergedInto:
        merge_project_name, merge_local_id = tracker_bizobj.ParseIssueRef(
            request.updates.mergedInto)
        merge_into_project = self._services.project.GetProjectByName(
            mar.cnxn, merge_project_name or issue.project_name)
        merge_into_issue = self._services.issue.GetIssueByLocalID(
            mar.cnxn, merge_into_project.project_id, merge_local_id)
        merge_allowed = tracker_helpers.IsMergeAllowed(
            merge_into_issue, mar, self._services)
        if not merge_allowed:
          raise permissions.PermissionException(
            'User is not allowed to merge into issue %s:%s' %
            (merge_into_issue.project_name, merge_into_issue.local_id))
        updates_dict['merged_into'] = merge_into_issue.issue_id
      (updates_dict['field_vals_add'], updates_dict['field_vals_remove'],
       updates_dict['fields_clear'], updates_dict['fields_labels_add'],
       updates_dict['fields_labels_remove']) = (
          api_pb2_v1_helpers.convert_field_values(
              request.updates.fieldValues, mar, self._services))

    field_helpers.ValidateCustomFields(
        mar, self._services,
        (updates_dict.get('field_vals_add', []) +
         updates_dict.get('field_vals_remove', [])),
        mar.config, mar.errors)
    if mar.errors.AnyErrors():
      raise endpoints.BadRequestException(
          'Invalid field values: %s' % mar.errors.custom_fields)

    _, comment = self._services.issue.DeltaUpdateIssue(
        cnxn=mar.cnxn, services=self._services,
        reporter_id=mar.auth.user_id,
        project_id=mar.project_id, config=mar.config, issue=issue,
        status=updates_dict.get('status'), owner_id=updates_dict.get('owner'),
        cc_add=updates_dict.get('cc_add', []),
        cc_remove=updates_dict.get('cc_remove', []),
        comp_ids_add=updates_dict.get('components_add', []),
        comp_ids_remove=updates_dict.get('components_remove', []),
        labels_add=(updates_dict.get('labels_add', []) +
                    updates_dict.get('fields_labels_add', [])),
        labels_remove=(updates_dict.get('labels_remove', []) +
                       updates_dict.get('fields_labels_remove', [])),
        field_vals_add=updates_dict.get('field_vals_add', []),
        field_vals_remove=updates_dict.get('field_vals_remove', []),
        fields_clear=updates_dict.get('fields_clear', []),
        blocked_on_add=updates_dict.get('blocked_on_add', []),
        blocked_on_remove=updates_dict.get('blocked_on_remove', []),
        blocking_add=updates_dict.get('blocking_add', []),
        blocking_remove=updates_dict.get('blocking_remove', []),
        merged_into=updates_dict.get('merged_into'),
        index_now=False,
        comment=request.content,
        summary=updates_dict.get('summary'),
    )

    move_comment = None
    if 'move_to_project' in updates_dict:
      move_to_project = updates_dict['move_to_project']
      old_text_ref = 'issue %s:%s' % (issue.project_name, issue.local_id)
      tracker_fulltext.UnindexIssues([issue.issue_id])
      moved_back_iids = self._services.issue.MoveIssues(
          mar.cnxn, move_to_project, [issue], self._services.user)
      new_text_ref = 'issue %s:%s' % (issue.project_name, issue.local_id)
      if issue.issue_id in moved_back_iids:
        content = 'Moved %s back to %s again.' % (old_text_ref, new_text_ref)
      else:
        content = 'Moved %s to now be %s.' % (old_text_ref, new_text_ref)
      move_comment = self._services.issue.CreateIssueComment(
        mar.cnxn, move_to_project.project_id, issue.local_id, mar.auth.user_id,
        content, amendments=[
            tracker_bizobj.MakeProjectAmendment(move_to_project.project_name)])

    if 'merged_into' in updates_dict:
      new_starrers = tracker_helpers.GetNewIssueStarrers(
          mar.cnxn, self._services, issue.issue_id, merge_into_issue.issue_id)
      tracker_helpers.AddIssueStarrers(
          mar.cnxn, self._services, mar,
          merge_into_issue.issue_id, merge_into_project, new_starrers)
      _merge_comment = tracker_helpers.MergeCCsAndAddComment(
        self._services, mar, issue, merge_into_project, merge_into_issue)
      merge_into_issue_cmnts = self._services.issue.GetCommentsForIssue(
          mar.cnxn, merge_into_issue.issue_id)
      notify.PrepareAndSendIssueChangeNotification(
          merge_into_issue.issue_id, framework_helpers.GetHostPort(),
          mar.auth.user_id, len(merge_into_issue_cmnts) - 1, send_email=True)

    tracker_fulltext.IndexIssues(
        mar.cnxn, [issue], self._services.user, self._services.issue,
        self._services.config)

    comment = comment or move_comment
    if comment is None:
      return api_pb2_v1.IssuesCommentsInsertResponse()

    cmnts = self._services.issue.GetCommentsForIssue(mar.cnxn, issue.issue_id)
    seq = len(cmnts) - 1

    if request.sendEmail:
      notify.PrepareAndSendIssueChangeNotification(
          issue.issue_id, framework_helpers.GetHostPort(),
          comment.user_id, seq, send_email=True, old_owner_id=old_owner_id)

    can_delete = permissions.CanDelete(
      mar.auth.user_id, mar.auth.effective_ids, mar.perms,
      comment.deleted_by, comment.user_id, mar.project,
      permissions.GetRestrictions(issue), granted_perms=mar.granted_perms)
    return api_pb2_v1.IssuesCommentsInsertResponse(
        id=seq,
        kind='monorail#issueComment',
        author=api_pb2_v1_helpers.convert_person(
            comment.user_id, mar.cnxn, self._services),
        content=comment.content,
        published=datetime.datetime.fromtimestamp(comment.timestamp),
        updates=api_pb2_v1_helpers.convert_amendments(
            issue, comment.amendments, mar, self._services),
        canDelete=can_delete)