Commit 1ccffc75 authored by drew cimino's avatar drew cimino Committed by Adam Hegyi

Add DailybuildGroupReportResultByGroupFinder subclass

For querying Ci::DailyBuildGroupReportResult by group_id, allow a
Group to be passed into #initialize in lieu of a project. A subclass
is useful for doing group-level aggregate operations because we join
on the projects table to query 'namespace_id' and use a group-level
permission check.
parent a0b21f15
......@@ -14,17 +14,25 @@ module Ci
end
def execute
return none unless can?(current_user, :read_build_report_results, project)
return none unless query_allowed?
query
end
protected
attr_reader :current_user, :project, :ref_path, :start_date, :end_date, :limit
def query
Ci::DailyBuildGroupReportResult.recent_results(
query_params,
limit: limit
)
end
private
attr_reader :current_user, :project, :ref_path, :start_date, :end_date, :limit
def query_allowed?
can?(current_user, :read_build_report_results, project)
end
def query_params
{
......
......@@ -138,6 +138,7 @@ class GroupPolicy < BasePolicy
enable :read_group_labels
enable :read_group_milestones
enable :read_group_merge_requests
enable :read_group_build_report_results
end
rule { can?(:read_cross_project) & can?(:read_group) }.policy do
......
# frozen_string_literal: true
module Ci
class DailyBuildGroupReportResultsByGroupFinder < Ci::DailyBuildGroupReportResultsFinder
include Gitlab::Allowable
# We currently impose a maximum of 1000 returned records for performance reasons.
# This limit is subject to future removal.
# See thread: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37768#note_386839633
GROUP_QUERY_RESULT_LIMIT = 1000.freeze
def initialize(current_user:, group:, ref_path:, start_date:, end_date:, limit: nil)
super(current_user: current_user, project: nil, ref_path: ref_path, start_date: start_date, end_date: end_date, limit: limit)
@group = group
@limit = GROUP_QUERY_RESULT_LIMIT unless limit && limit < GROUP_QUERY_RESULT_LIMIT
end
private
def query_allowed?
can?(current_user, :read_group_build_report_results, @group)
end
def query_params
super.merge(project_id: @group.projects.select(:id))
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::DailyBuildGroupReportResultsByGroupFinder do
describe '#execute' do
let(:user) { create(:user) }
let(:project) { create(:project, :private) }
let!(:project_coverage) { create_daily_coverage('rspec', 95.0, '2020-03-10', project) }
let(:group) { create(:group, :private) }
let(:group_project) { create(:project, namespace: group) }
let!(:group_project_coverage) { create_daily_coverage('rspec', 79.0, '2020-03-09', group_project) }
let(:subgroup) { create(:group, :private, parent: group) }
let(:subgroup_project) { create(:project, namespace: subgroup) }
let!(:subgroup_project_coverage) { create_daily_coverage('rspec', 89.0, '2020-03-09', subgroup_project) }
let(:ref_path) { 'refs/heads/master' }
let(:limit) { nil }
subject do
described_class.new(
current_user: user,
group: group,
ref_path: ref_path,
start_date: '2020-03-09',
end_date: '2020-03-10',
limit: limit
).execute
end
context 'when current user is allowed to :read_group_build_report_results' do
before do
group.add_reporter(user)
end
it 'returns only coverages belonging to the passed group' do
expect(subject).to include(group_project_coverage)
expect(subject).not_to include(project_coverage)
expect(subject).not_to include(subgroup_project_coverage)
end
context 'with a limit below 1000' do
let(:limit) { 5 }
it 'uses the provided limit' do
expect(subject.limit_value).to eq(5)
end
end
context 'with a limit above 1000' do
let(:limit) { 1001 }
it 'uses the max constant' do
expect(subject.limit_value).to eq(Ci::DailyBuildGroupReportResultsByGroupFinder::GROUP_QUERY_RESULT_LIMIT)
end
end
context 'without a limit' do
it 'uses the max constant' do
expect(subject.limit_value).to eq(Ci::DailyBuildGroupReportResultsByGroupFinder::GROUP_QUERY_RESULT_LIMIT)
end
end
end
context 'without permmissions' do
it 'returns an empty result' do
expect(subject).to be_empty
end
end
end
private
def create_daily_coverage(group_name, coverage, date, project)
create(
:ci_daily_build_group_report_result,
project: project,
ref_path: ref_path,
group_name: group_name,
data: { 'coverage' => coverage },
date: date
)
end
end
......@@ -59,6 +59,8 @@ RSpec.describe Ci::DailyBuildGroupReportResultsFinder do
end
end
private
def create_daily_coverage(group_name, coverage, date)
create(
:ci_daily_build_group_report_result,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment