def testExtractUniqueValues_CombinedColumns(self):
    cols = ['priority/pri', 'owner', 'status', 'stars', 'mstone/milestone']
    users_by_id = {
        111: framework_views.StuffUserView(111, '*****@*****.**', True),
        }
    issue = fake.MakeTestIssue(
        789, 5, 'sum 5', 'New', 111, merged_into=200001,
        labels='Priority-High Pri-0 Milestone-1.0 mstone-1',
        star_count=15)

    column_values = table_view_helpers.ExtractUniqueValues(
        cols, SEARCH_RESULTS_WITH_LABELS + [issue], users_by_id,
        self.config, {})
    self.assertEquals(5, len(column_values))

    self.assertEquals('priority/pri', column_values[0].column_name)
    self.assertEquals(['0', 'High', 'Low'], column_values[0].filter_values)

    self.assertEquals('owner', column_values[1].column_name)
    self.assertEquals(['*****@*****.**'], column_values[1].filter_values)

    self.assertEquals('status', column_values[2].column_name)
    self.assertEquals(['New'], column_values[2].filter_values)

    self.assertEquals('stars', column_values[3].column_name)
    self.assertEquals([1, 15], column_values[3].filter_values)

    self.assertEquals('mstone/milestone', column_values[4].column_name)
    self.assertEquals(['1', '1.0', '1.1'], column_values[4].filter_values)
  def testExtractUniqueValues_ExplicitResults(self):
    cols = ['priority', 'owner', 'status', 'stars', 'mstone', 'foo']
    users_by_id = {
        111: framework_views.StuffUserView(111, '*****@*****.**', True),
        }
    column_values = table_view_helpers.ExtractUniqueValues(
        cols, SEARCH_RESULTS_WITH_LABELS, users_by_id, self.config, {})
    self.assertEquals(len(cols), len(column_values))

    self.assertEquals('priority', column_values[0].column_name)
    self.assertEquals(['High', 'Low'], column_values[0].filter_values)

    self.assertEquals('owner', column_values[1].column_name)
    self.assertEquals(['*****@*****.**'], column_values[1].filter_values)

    self.assertEquals('status', column_values[2].column_name)
    self.assertEquals(['New'], column_values[2].filter_values)

    self.assertEquals('stars', column_values[3].column_name)
    self.assertEquals([1], column_values[3].filter_values)

    self.assertEquals('mstone', column_values[4].column_name)
    self.assertEquals(['1', '1.1'], column_values[4].filter_values)

    self.assertEquals('foo', column_values[5].column_name)
    self.assertEquals([], column_values[5].filter_values)
示例#3
0
 def testExtractUniqueValues_NoResults(self):
   cols = ['type', 'priority', 'owner', 'status', 'stars', 'attachments']
   column_values = table_view_helpers.ExtractUniqueValues(
       cols, EMPTY_SEARCH_RESULTS, {}, self.config, {})
   self.assertEquals(6, len(column_values))
   for index, col in enumerate(cols):
     self.assertEquals(index, column_values[index].col_index)
     self.assertEquals(col, column_values[index].column_name)
     self.assertEquals([], column_values[index].filter_values)
示例#4
0
  def GetTableViewData(
      self, mr, results, config, users_by_id, starred_iid_set, related_issues,
      viewable_iids_set):
    """EZT template values to render a Table View of issues.

    Args:
      mr: commonly used info parsed from the request.
      results: list of Issue PBs for the search results to be displayed.
      config: The ProjectIssueConfig PB for the current project.
      users_by_id: A dictionary {user_id: UserView} for all the users
      involved in results.
      starred_iid_set: Set of issues that the user has starred.
      related_issues: dict {issue_id: issue} of pre-fetched related issues.
      viewable_iids_set: set of issue ids that are viewable by the user.

    Returns:
      Dictionary of page data for rendering of the Table View.
    """
    # We need ordered_columns because EZT loops have no loop-counter available.
    # And, we use column number in the Javascript to hide/show columns.
    columns = mr.col_spec.split()
    ordered_columns = [template_helpers.EZTItem(col_index=i, name=col)
                       for i, col in enumerate(columns)]
    unshown_columns = table_view_helpers.ComputeUnshownColumns(
        results, columns, config, tracker_constants.OTHER_BUILT_IN_COLS)

    lower_columns = mr.col_spec.lower().split()
    lower_group_by = mr.group_by_spec.lower().split()
    table_data = _MakeTableData(
        results, starred_iid_set, lower_columns, lower_group_by,
        users_by_id, self.GetCellFactories(), related_issues,
        viewable_iids_set, config)

    # Used to offer easy filtering of each unique value in each column.
    column_values = table_view_helpers.ExtractUniqueValues(
        lower_columns, results, users_by_id, config, related_issues)

    table_view_data = {
        'table_data': table_data,
        'column_values': column_values,
        # Put ordered_columns inside a list of exactly 1 panel so that
        # it can work the same as the dashboard initial panel list headers.
        'panels': [template_helpers.EZTItem(ordered_columns=ordered_columns)],
        'unshown_columns': unshown_columns,
        'cursor': mr.cursor or mr.preview,
        'preview': mr.preview,
        'default_colspec': tracker_constants.DEFAULT_COL_SPEC,
        'default_results_per_page': tracker_constants.DEFAULT_RESULTS_PER_PAGE,
        'csv_link': framework_helpers.FormatURL(
            [(name, mr.GetParam(name)) for name in
             framework_helpers.RECOGNIZED_PARAMS],
            'csv', num=settings.max_artifact_search_results_per_page),
        'preview_on_hover': ezt.boolean(
            _ShouldPreviewOnHover(mr.auth.user_pb)),
        }
    return table_view_data
示例#5
0
  def testExtractUniqueValues_ColumnsRobustness(self):
    cols = ['reporter', 'cc', 'owner', 'status', 'attachments']
    search_results = [
        tracker_pb2.Issue(),
        ]
    column_values = table_view_helpers.ExtractUniqueValues(
        cols, search_results, {}, self.config, {})

    self.assertEquals(5, len(column_values))
    for col_val in column_values:
      if col_val.column_name == 'attachments':
        self.assertEquals([0], col_val.filter_values)
      else:
        self.assertEquals([], col_val.filter_values)
示例#6
0
    def testExtractUniqueValues_DerivedValues(self):
        cols = ['priority', 'milestone', 'owner', 'status']
        users_by_id = {
            111: framework_views.StuffUserView(111, '*****@*****.**', True),
            222: framework_views.StuffUserView(222, '*****@*****.**', True),
            333: framework_views.StuffUserView(333, '*****@*****.**', True),
        }
        search_results = [
            fake.MakeTestIssue(789,
                               1,
                               'sum 1',
                               '',
                               111,
                               labels='Priority-High Milestone-1.0',
                               derived_labels='Milestone-2.0 Foo',
                               derived_status='Started'),
            fake.MakeTestIssue(
                789,
                2,
                'sum 2',
                'New',
                111,
                labels='Priority-High Milestone-1.0',
                derived_owner_id=333),  # Not seen because of owner_id
            fake.MakeTestIssue(789,
                               3,
                               'sum 3',
                               'New',
                               0,
                               labels='Priority-Low Milestone-1.1',
                               derived_owner_id=222),
        ]

        column_values = table_view_helpers.ExtractUniqueValues(
            cols, search_results, users_by_id, self.config, {})
        self.assertEquals(4, len(column_values))

        self.assertEquals('priority', column_values[0].column_name)
        self.assertEquals(['High', 'Low'], column_values[0].filter_values)

        self.assertEquals('milestone', column_values[1].column_name)
        self.assertEquals(['1.0', '1.1', '2.0'],
                          column_values[1].filter_values)

        self.assertEquals('owner', column_values[2].column_name)
        self.assertEquals(['*****@*****.**', '*****@*****.**'],
                          column_values[2].filter_values)

        self.assertEquals('status', column_values[3].column_name)
        self.assertEquals(['New', 'Started'], column_values[3].filter_values)
示例#7
0
def GetGridViewData(mr,
                    results,
                    config,
                    users_by_id,
                    starred_iid_set,
                    grid_limited,
                    related_issues,
                    hotlist_context_dict=None):
    """EZT template values to render a Grid View of issues.
  Args:
    mr: commonly used info parsed from the request.
    results: The Issue PBs that are the search results to be displayed.
    config: The ProjectConfig PB for the project this view is in.
    users_by_id: A dictionary {user_id: user_view,...} for all the users
        involved in results.
    starred_iid_set: Set of issues that the user has starred.
    grid_limited: True if the results were limited to fit within the grid.
    related_issues: dict {issue_id: issue} of pre-fetched related issues.
    hotlist_context_dict: dict for building a hotlist grid table

  Returns:
    Dictionary for EZT template rendering of the Grid View.
  """
    # We need ordered_columns because EZT loops have no loop-counter available.
    # And, we use column number in the Javascript to hide/show columns.
    columns = mr.col_spec.split()
    ordered_columns = [
        template_helpers.EZTItem(col_index=i, name=col)
        for i, col in enumerate(columns)
    ]
    other_built_in_cols = (features_constants.OTHER_BUILT_IN_COLS
                           if hotlist_context_dict else
                           tracker_constants.OTHER_BUILT_IN_COLS)
    unshown_columns = table_view_helpers.ComputeUnshownColumns(
        results, columns, config, other_built_in_cols)

    grid_x_attr = (mr.x or config.default_x_attr or '--').lower()
    grid_y_attr = (mr.y or config.default_y_attr or '--').lower()
    all_label_values = {}
    for art in results:
        all_label_values[art.local_id] = (MakeLabelValuesDict(art))

    if grid_x_attr == '--':
        grid_x_headings = ['All']
    else:
        grid_x_items = table_view_helpers.ExtractUniqueValues(
            [grid_x_attr],
            results,
            users_by_id,
            config,
            related_issues,
            hotlist_context_dict=hotlist_context_dict)
        grid_x_headings = grid_x_items[0].filter_values
        if AnyArtifactHasNoAttr(results,
                                grid_x_attr,
                                users_by_id,
                                all_label_values,
                                config,
                                related_issues,
                                hotlist_context_dict=hotlist_context_dict):
            grid_x_headings.append(framework_constants.NO_VALUES)
        grid_x_headings = SortGridHeadings(grid_x_attr, grid_x_headings,
                                           users_by_id, config,
                                           tracker_helpers.SORTABLE_FIELDS)

    if grid_y_attr == '--':
        grid_y_headings = ['All']
    else:
        grid_y_items = table_view_helpers.ExtractUniqueValues(
            [grid_y_attr],
            results,
            users_by_id,
            config,
            related_issues,
            hotlist_context_dict=hotlist_context_dict)
        grid_y_headings = grid_y_items[0].filter_values
        if AnyArtifactHasNoAttr(results,
                                grid_y_attr,
                                users_by_id,
                                all_label_values,
                                config,
                                related_issues,
                                hotlist_context_dict=hotlist_context_dict):
            grid_y_headings.append(framework_constants.NO_VALUES)
        grid_y_headings = SortGridHeadings(grid_y_attr, grid_y_headings,
                                           users_by_id, config,
                                           tracker_helpers.SORTABLE_FIELDS)

    logging.info('grid_x_headings = %s', grid_x_headings)
    logging.info('grid_y_headings = %s', grid_y_headings)
    grid_data = PrepareForMakeGridData(
        results,
        starred_iid_set,
        grid_x_attr,
        grid_x_headings,
        grid_y_attr,
        grid_y_headings,
        users_by_id,
        all_label_values,
        config,
        related_issues,
        hotlist_context_dict=hotlist_context_dict)

    grid_axis_choice_dict = {}
    for oc in ordered_columns:
        grid_axis_choice_dict[oc.name] = True
    for uc in unshown_columns:
        grid_axis_choice_dict[uc] = True
    for bad_axis in tracker_constants.NOT_USED_IN_GRID_AXES:
        if bad_axis in grid_axis_choice_dict:
            del grid_axis_choice_dict[bad_axis]
    grid_axis_choices = grid_axis_choice_dict.keys()
    grid_axis_choices.sort()

    grid_cell_mode = mr.cells
    if len(results) > settings.max_tiles_in_grid and mr.cells == 'tiles':
        grid_cell_mode = 'ids'

    grid_view_data = {
        'grid_limited': ezt.boolean(grid_limited),
        'grid_shown': len(results),
        'grid_x_headings': grid_x_headings,
        'grid_y_headings': grid_y_headings,
        'grid_data': grid_data,
        'grid_axis_choices': grid_axis_choices,
        'grid_cell_mode': grid_cell_mode,
        'results': results,  # Really only useful in if-any.
    }
    return grid_view_data
示例#8
0
def CreateHotlistTableData(mr, hotlist_issues, profiler, services):
    """Creates the table data for the hotlistissues table."""
    with profiler.Phase('getting stars'):
        starred_iid_set = set(
            services.issue_star.LookupStarredItemIDs(mr.cnxn, mr.auth.user_id))

    with profiler.Phase('Computing col_spec'):
        mr.ComputeColSpec(mr.hotlist)

    issues_list = services.issue.GetIssues(
        mr.cnxn, [hotlist_issue.issue_id for hotlist_issue in hotlist_issues])
    with profiler.Phase('Getting config'):
        hotlist_issues_project_ids = GetAllProjectsOfIssues(
            [issue for issue in issues_list])
        is_cross_project = len(hotlist_issues_project_ids) > 1
        config_list = GetAllConfigsOfProjects(mr.cnxn,
                                              hotlist_issues_project_ids,
                                              services)
        harmonized_config = tracker_bizobj.HarmonizeConfigs(config_list)

    (sorted_issues, hotlist_issues_context,
     issues_users_by_id) = GetSortedHotlistIssues(mr, hotlist_issues,
                                                  issues_list,
                                                  harmonized_config, profiler,
                                                  services)

    with profiler.Phase("getting related issues"):
        related_iids = set()
        results_needing_related = sorted_issues
        lower_cols = mr.col_spec.lower().split()
        for issue in results_needing_related:
            if 'blockedon' in lower_cols:
                related_iids.update(issue.blocked_on_iids)
            if 'blocking' in lower_cols:
                related_iids.update(issue.blocking_iids)
            if 'mergedinto' in lower_cols:
                related_iids.add(issue.merged_into)
        related_issues_list = services.issue.GetIssues(mr.cnxn,
                                                       list(related_iids))
        related_issues = {
            issue.issue_id: issue
            for issue in related_issues_list
        }

    with profiler.Phase('building table'):
        context_for_all_issues = {
            issue.issue_id: hotlist_issues_context[issue.issue_id]
            for issue in sorted_issues
        }

        column_values = table_view_helpers.ExtractUniqueValues(
            mr.col_spec.lower().split(),
            sorted_issues,
            issues_users_by_id,
            harmonized_config,
            related_issues,
            hotlist_context_dict=context_for_all_issues)
        unshown_columns = table_view_helpers.ComputeUnshownColumns(
            sorted_issues, mr.col_spec.split(), harmonized_config,
            features_constants.OTHER_BUILT_IN_COLS)
        pagination = paginate.ArtifactPagination(
            mr, sorted_issues, mr.num,
            GetURLOfHotlist(mr.cnxn, mr.hotlist, services.user),
            len(sorted_issues))

        sort_spec = '%s %s %s' % (mr.group_by_spec, mr.sort_spec,
                                  harmonized_config.default_sort_spec)

        table_data = _MakeTableData(pagination.visible_results,
                                    starred_iid_set,
                                    mr.col_spec.lower().split(),
                                    mr.group_by_spec.lower().split(),
                                    issues_users_by_id,
                                    tablecell.CELL_FACTORIES, related_issues,
                                    harmonized_config, context_for_all_issues,
                                    mr.hotlist_id, sort_spec)

    table_related_dict = {
        'column_values': column_values,
        'unshown_columns': unshown_columns,
        'pagination': pagination,
        'is_cross_project': is_cross_project
    }
    return table_data, table_related_dict
示例#9
0
 def testExtractUniqueValues_NoColumns(self):
   column_values = table_view_helpers.ExtractUniqueValues(
       [], SEARCH_RESULTS_WITH_LABELS, {}, self.config, {})
   self.assertEquals([], column_values)
示例#10
0
  def testExtractUniqueValues_NoResults(self):
    cols = ['type', 'priority', 'owner', 'status', 'stars', 'attachments']
    column_values = table_view_helpers.ExtractUniqueValues(
        cols, EMPTY_SEARCH_RESULTS, {}, self.config, {})
    self.assertEquals(6, len(column_values))
    for index, col in enumerate(cols):
      self.assertEquals(index, column_values[index].col_index)
      self.assertEquals(col, column_values[index].column_name)
      self.assertEquals([], column_values[index].filter_values)

  def testExtractUniqueValues_ExplicitResults(self):
    cols = ['priority', 'owner', 'status', 'stars', 'mstone', 'foo']
    users_by_id = {
        111L: framework_views.StuffUserView(111, '*****@*****.**', True),
        }
    column_values = table_view_helpers.ExtractUniqueValues(
        cols, SEARCH_RESULTS_WITH_LABELS, users_by_id, self.config, {})
    self.assertEquals(len(cols), len(column_values))

    self.assertEquals('priority', column_values[0].column_name)
    self.assertEquals(['High', 'Low'], column_values[0].filter_values)

    self.assertEquals('owner', column_values[1].column_name)
    self.assertEquals(['*****@*****.**'], column_values[1].filter_values)

    self.assertEquals('status', column_values[2].column_name)
    self.assertEquals(['New'], column_values[2].filter_values)

    self.assertEquals('stars', column_values[3].column_name)
    self.assertEquals([1], column_values[3].filter_values)

    self.assertEquals('mstone', column_values[4].column_name)
示例#11
0
def CreateHotlistTableData(mr, hotlist_issues, services):
    """Creates the table data for the hotlistissues table."""
    with mr.profiler.Phase('getting stars'):
        starred_iid_set = set(
            services.issue_star.LookupStarredItemIDs(mr.cnxn, mr.auth.user_id))

    with mr.profiler.Phase('Computing col_spec'):
        mr.ComputeColSpec(mr.hotlist)

    issues_list = services.issue.GetIssues(
        mr.cnxn, [hotlist_issue.issue_id for hotlist_issue in hotlist_issues])
    with mr.profiler.Phase('Getting config'):
        hotlist_issues_project_ids = GetAllProjectsOfIssues(
            [issue for issue in issues_list])
        is_cross_project = len(hotlist_issues_project_ids) > 1
        config_list = GetAllConfigsOfProjects(mr.cnxn,
                                              hotlist_issues_project_ids,
                                              services)
        harmonized_config = tracker_bizobj.HarmonizeConfigs(config_list)

    (sorted_issues, hotlist_issues_context,
     issues_users_by_id) = GetSortedHotlistIssues(mr, hotlist_issues,
                                                  issues_list,
                                                  harmonized_config, services)

    with mr.profiler.Phase("getting related issues"):
        related_iids = set()
        results_needing_related = sorted_issues
        lower_cols = mr.col_spec.lower().split()
        for issue in results_needing_related:
            if 'blockedon' in lower_cols:
                related_iids.update(issue.blocked_on_iids)
            if 'blocking' in lower_cols:
                related_iids.update(issue.blocking_iids)
            if 'mergedinto' in lower_cols:
                related_iids.add(issue.merged_into)
        related_issues_list = services.issue.GetIssues(mr.cnxn,
                                                       list(related_iids))
        related_issues = {
            issue.issue_id: issue
            for issue in related_issues_list
        }

    with mr.profiler.Phase('filtering unviewable issues'):
        viewable_iids_set = {
            issue.issue_id
            for issue in tracker_helpers.GetAllowedIssues(
                mr, [related_issues.values()], services)[0]
        }

    with mr.profiler.Phase('building table'):
        context_for_all_issues = {
            issue.issue_id: hotlist_issues_context[issue.issue_id]
            for issue in sorted_issues
        }

        column_values = table_view_helpers.ExtractUniqueValues(
            mr.col_spec.lower().split(),
            sorted_issues,
            issues_users_by_id,
            harmonized_config,
            related_issues,
            hotlist_context_dict=context_for_all_issues)
        unshown_columns = table_view_helpers.ComputeUnshownColumns(
            sorted_issues, mr.col_spec.split(), harmonized_config,
            features_constants.OTHER_BUILT_IN_COLS)
        url_params = [(name, mr.GetParam(name))
                      for name in framework_helpers.RECOGNIZED_PARAMS]
        # We are passing in None for the project_name because we are not operating
        # under any project.
        pagination = paginate.ArtifactPagination(
            sorted_issues,
            mr.num,
            mr.GetPositiveIntParam('start'),
            None,
            GetURLOfHotlist(mr.cnxn, mr.hotlist, services.user),
            total_count=len(sorted_issues),
            url_params=url_params)

        sort_spec = '%s %s %s' % (mr.group_by_spec, mr.sort_spec,
                                  harmonized_config.default_sort_spec)

        table_data = _MakeTableData(
            pagination.visible_results, starred_iid_set,
            mr.col_spec.lower().split(),
            mr.group_by_spec.lower().split(), issues_users_by_id,
            tablecell.CELL_FACTORIES, related_issues, viewable_iids_set,
            harmonized_config, context_for_all_issues, mr.hotlist_id,
            sort_spec)

    table_related_dict = {
        'column_values': column_values,
        'unshown_columns': unshown_columns,
        'pagination': pagination,
        'is_cross_project': is_cross_project
    }
    return table_data, table_related_dict