def testFindMatchingComponentIDs_NoMatch(self):
   config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
   config.component_defs.append(tracker_pb2.ComponentDef(
       component_id=1, path='UI>Splash'))
   config.component_defs.append(tracker_pb2.ComponentDef(
       component_id=2, path='UI>AboutBox'))
   actual = tracker_bizobj.FindMatchingComponentIDs('DB', config)
   self.assertEqual([], actual)
   actual = tracker_bizobj.FindMatchingComponentIDs('DB', config, exact=False)
   self.assertEqual([], actual)
 def testFindMatchingComponentIDs_MatchMultiple(self):
   config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
   config.component_defs.append(tracker_pb2.ComponentDef(
       component_id=1, path='UI>Splash'))
   config.component_defs.append(tracker_pb2.ComponentDef(
       component_id=2, path='UI>AboutBox'))
   config.component_defs.append(tracker_pb2.ComponentDef(
       component_id=22, path='UI>AboutBox'))
   config.component_defs.append(tracker_pb2.ComponentDef(
       component_id=3, path='DB>Attachments'))
   actual = tracker_bizobj.FindMatchingComponentIDs('UI>AboutBox', config)
   self.assertEqual([2, 22], actual)
   actual = tracker_bizobj.FindMatchingComponentIDs('UI', config, exact=False)
   self.assertEqual([1, 2, 22], actual)
Esempio n. 3
0
def _CompareComponents(config, op, rule_values, issue_values):
  """Compare the components specified in the rule vs those in the issue."""
  trivial_result = _CheckTrivialCases(op, issue_values)
  if trivial_result is not None:
    return trivial_result

  exact = op in (ast_pb2.QueryOp.EQ, ast_pb2.QueryOp.NE)
  rule_component_ids = set()
  for path in rule_values:
    rule_component_ids.update(tracker_bizobj.FindMatchingComponentIDs(
        path, config, exact=exact))

  if op == ast_pb2.QueryOp.TEXT_HAS or op == ast_pb2.QueryOp.EQ:
    return any(rv in issue_values for rv in rule_component_ids)
  elif op == ast_pb2.QueryOp.NOT_TEXT_HAS or op == ast_pb2.QueryOp.NE:
    return all(rv not in issue_values for rv in rule_component_ids)

  return False
Esempio n. 4
0
def _PreprocessComponentCond(cnxn, cond, project_ids, services,
                             harmonized_config, _is_member):
    """Preprocess a component= or component:name cond into component_id=IDs."""
    exact = _IsEqualityOp(cond.op)
    component_ids = []
    if project_ids:
        # We are searching within specific projects, so harmonized_config
        # holds the config data for all those projects.
        for comp_path in cond.str_values:
            component_ids.extend(
                tracker_bizobj.FindMatchingComponentIDs(comp_path,
                                                        harmonized_config,
                                                        exact=exact))
    else:
        # We are searching across the whole site, so we have no harmonized_config
        # to use.
        component_ids = services.config.FindMatchingComponentIDsAnyProject(
            cnxn, cond.str_values, exact=exact)

    return ast_pb2.Condition(
        op=_TextOpToIntOp(cond.op),
        field_defs=[query2ast.BUILTIN_ISSUE_FIELDS['component_id']],
        int_values=component_ids)
 def testFindMatchingComponentIDs_Empty(self):
   config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
   actual = tracker_bizobj.FindMatchingComponentIDs('DB', config)
   self.assertEqual([], actual)
   actual = tracker_bizobj.FindMatchingComponentIDs('DB', config, exact=False)
   self.assertEqual([], actual)
Esempio n. 6
0
  def _ProcessEditComponent(self, mr, post_data, config, component_def):
    """The user wants to edit this component definition."""
    parsed = component_helpers.ParseComponentRequest(
        mr, post_data, self.services)

    if not tracker_constants.COMPONENT_NAME_RE.match(parsed.leaf_name):
      mr.errors.leaf_name = 'Invalid component name'

    original_path = component_def.path
    if mr.component_path and '>' in mr.component_path:
      parent_path = mr.component_path[:mr.component_path.rindex('>')]
      new_path = '%s>%s' % (parent_path, parsed.leaf_name)
    else:
      new_path = parsed.leaf_name

    conflict = tracker_bizobj.FindComponentDef(new_path, config)
    if conflict and conflict.component_id != component_def.component_id:
      mr.errors.leaf_name = 'That name is already in use.'

    creator, created = self._GetUserViewAndFormattedTime(
        mr, component_def.creator_id, component_def.created)
    modifier, modified = self._GetUserViewAndFormattedTime(
        mr, component_def.modifier_id, component_def.modified)

    if mr.errors.AnyErrors():
      self.PleaseCorrect(
          mr, initial_leaf_name=parsed.leaf_name,
          initial_docstring=parsed.docstring,
          initial_deprecated=ezt.boolean(parsed.deprecated),
          initial_admins=parsed.admin_usernames,
          initial_cc=parsed.cc_usernames,
          initial_labels=parsed.label_strs,
          created=created,
          creator=creator,
          modified=modified,
          modifier=modifier,
      )
      return None

    new_modified = int(time.time())
    new_modifier_id = self.services.user.LookupUserID(
        mr.cnxn, mr.auth.email, autocreate=False)
    self.services.config.UpdateComponentDef(
        mr.cnxn, mr.project_id, component_def.component_id,
        path=new_path, docstring=parsed.docstring, deprecated=parsed.deprecated,
        admin_ids=parsed.admin_ids, cc_ids=parsed.cc_ids, modified=new_modified,
        modifier_id=new_modifier_id, label_ids=parsed.label_ids)

    update_rule = False
    if new_path != original_path:
      update_rule = True
      # If the name changed then update all of its subcomponents as well.
      subcomponent_ids = tracker_bizobj.FindMatchingComponentIDs(
          original_path, config, exact=False)
      for subcomponent_id in subcomponent_ids:
        if subcomponent_id == component_def.component_id:
          continue
        subcomponent_def = tracker_bizobj.FindComponentDefByID(
            subcomponent_id, config)
        subcomponent_new_path = subcomponent_def.path.replace(
            original_path, new_path, 1)
        self.services.config.UpdateComponentDef(
            mr.cnxn, mr.project_id, subcomponent_def.component_id,
            path=subcomponent_new_path)

    if (set(parsed.cc_ids) != set(component_def.cc_ids) or
        set(parsed.label_ids) != set(component_def.label_ids)):
      update_rule = True
    if update_rule:
      filterrules_helpers.RecomputeAllDerivedFields(
          mr.cnxn, self.services, mr.project, config)

    return framework_helpers.FormatAbsoluteURL(
        mr, urls.COMPONENT_DETAIL,
        component=new_path, saved=1, ts=int(time.time()))
Esempio n. 7
0
  def components_update(self, request):
    """Update a component."""
    mar = self.mar_factory(request)
    config = self._services.config.GetProjectConfig(mar.cnxn, mar.project_id)
    component_path = request.componentPath
    component_def = tracker_bizobj.FindComponentDef(
        component_path, config)
    if not component_def:
      raise config_svc.NoSuchComponentException(
          'The component %s does not exist.' % component_path)
    if not permissions.CanViewComponentDef(
        mar.auth.effective_ids, mar.perms, mar.project, component_def):
      raise permissions.PermissionException(
          'User is not allowed to view this component %s' % component_path)
    if not permissions.CanEditComponentDef(
        mar.auth.effective_ids, mar.perms, mar.project, component_def, config):
      raise permissions.PermissionException(
          'User is not allowed to edit this component %s' % component_path)

    original_path = component_def.path
    new_path = component_def.path
    new_docstring = component_def.docstring
    new_deprecated = component_def.deprecated
    new_admin_ids = component_def.admin_ids
    new_cc_ids = component_def.cc_ids
    update_filterrule = False
    for update in request.updates:
      if update.field == api_pb2_v1.ComponentUpdateFieldID.LEAF_NAME:
        leaf_name = update.leafName
        if not tracker_constants.COMPONENT_NAME_RE.match(leaf_name):
          raise config_svc.InvalidComponentNameException(
              'The component name %s is invalid.' % leaf_name)

        if '>' in original_path:
          parent_path = original_path[:original_path.rindex('>')]
          new_path = '%s>%s' % (parent_path, leaf_name)
        else:
          new_path = leaf_name

        conflict = tracker_bizobj.FindComponentDef(new_path, config)
        if conflict and conflict.component_id != component_def.component_id:
          raise config_svc.InvalidComponentNameException(
              'The name %s is already in use.' % new_path)
        update_filterrule = True
      elif update.field == api_pb2_v1.ComponentUpdateFieldID.DESCRIPTION:
        new_docstring = update.description
      elif update.field == api_pb2_v1.ComponentUpdateFieldID.ADMIN:
        user_ids_dict = self._services.user.LookupUserIDs(
            mar.cnxn, list(update.admin), autocreate=True)
        new_admin_ids = [user_ids_dict[email] for email in update.admin]
      elif update.field == api_pb2_v1.ComponentUpdateFieldID.CC:
        user_ids_dict = self._services.user.LookupUserIDs(
            mar.cnxn, list(update.cc), autocreate=True)
        new_cc_ids = [user_ids_dict[email] for email in update.cc]
        update_filterrule = True
      elif update.field == api_pb2_v1.ComponentUpdateFieldID.DEPRECATED:
        new_deprecated = update.deprecated
      else:
        logging.error('Unknown component field %r', update.field)

    new_modified = int(time.time())
    new_modifier_id = self._services.user.LookupUserID(
        mar.cnxn, mar.auth.email, autocreate=False)
    logging.info(
        'Updating component id %d: path-%s, docstring-%s, deprecated-%s,'
        ' admin_ids-%s, cc_ids-%s modified by %s', component_def.component_id,
        new_path, new_docstring, new_deprecated, new_admin_ids, new_cc_ids,
        new_modifier_id)
    self._services.config.UpdateComponentDef(
        mar.cnxn, mar.project_id, component_def.component_id,
        path=new_path, docstring=new_docstring, deprecated=new_deprecated,
        admin_ids=new_admin_ids, cc_ids=new_cc_ids, modified=new_modified,
        modifier_id=new_modifier_id)

    # TODO(sheyang): reuse the code in componentdetails
    if original_path != new_path:
      # If the name changed then update all of its subcomponents as well.
      subcomponent_ids = tracker_bizobj.FindMatchingComponentIDs(
          original_path, config, exact=False)
      for subcomponent_id in subcomponent_ids:
        if subcomponent_id == component_def.component_id:
          continue
        subcomponent_def = tracker_bizobj.FindComponentDefByID(
            subcomponent_id, config)
        subcomponent_new_path = subcomponent_def.path.replace(
            original_path, new_path, 1)
        self._services.config.UpdateComponentDef(
            mar.cnxn, mar.project_id, subcomponent_def.component_id,
            path=subcomponent_new_path)

    if update_filterrule:
      filterrules_helpers.RecomputeAllDerivedFields(
          mar.cnxn, self._services, mar.project, config)

    return message_types.VoidMessage()