Commit 9ba40bc4 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch '224170_compare_report_types_with_base_branch' into 'master'

Expose missing security scan types information

See merge request gitlab-org/gitlab!40171
parents 95172605 f793677f
......@@ -10,6 +10,7 @@ module EE
before_action only: [:show] do
push_frontend_feature_flag(:anonymous_visual_review_feedback)
push_frontend_feature_flag(:missing_mr_security_scan_types, @project)
end
before_action :whitelist_query_limiting_ee_merge, only: [:merge]
......
......@@ -257,6 +257,12 @@ module EE
end
end
def missing_security_scan_types
return [] unless actual_head_pipeline && base_pipeline
(base_pipeline.security_scans.pluck(:scan_type) - actual_head_pipeline.security_scans.pluck(:scan_type)).uniq
end
private
def has_approved_license_check?
......
......@@ -48,11 +48,20 @@ module EE
expose_mr_approval_path? ? APPROVALS_WIDGET_FULL_TYPE : super
end
def missing_security_scan_types
merge_request.missing_security_scan_types if expose_missing_security_scan_types?
end
private
def expose_mr_approval_path?
approval_feature_available? && merge_request.iid
end
def expose_missing_security_scan_types?
::Feature.enabled?(:missing_mr_security_scan_types, project) &&
can?(current_user, :read_pipeline, merge_request.actual_head_pipeline)
end
end
end
......
......@@ -12,6 +12,10 @@ module EE
expose :policy_violation do |merge_request|
presenter(merge_request).has_denied_policies?
end
expose :missing_security_scan_types do |merge_request|
presenter(merge_request).missing_security_scan_types
end
end
end
end
---
name: missing_mr_security_scan_types
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40171
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/241154
group: group::threat insights
type: development
default_enabled: false
\ No newline at end of file
......@@ -880,4 +880,114 @@ RSpec.describe MergeRequest do
expect(described_class.sort_by_attribute('review_time_desc')).to match([mr3, mr4, mr2, mr1, mr5])
end
end
describe '#missing_security_scan_types' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:merge_request) { create(:ee_merge_request, source_project: project) }
subject { merge_request.missing_security_scan_types }
context 'when there is no head pipeline' do
context 'when there is no base pipeline' do
it { is_expected.to be_empty }
end
context 'when there is a base pipeline' do
let_it_be(:base_pipeline) do
create(:ee_ci_pipeline,
project: project,
ref: merge_request.target_branch,
sha: merge_request.diff_base_sha)
end
context 'when there is no security scan for the base pipeline' do
it { is_expected.to be_empty }
end
context 'when there are security scans for the base_pipeline' do
before do
build = create(:ci_build, :success, pipeline: base_pipeline, project: project)
create(:security_scan, build: build)
end
it { is_expected.to be_empty }
end
end
end
context 'when there is a head pipeline' do
let_it_be(:head_pipeline) { create(:ee_ci_pipeline, project: project, sha: merge_request.diff_head_sha) }
before do
merge_request.update_head_pipeline
end
context 'when there is no base pipeline' do
it { is_expected.to be_empty }
end
context 'when there is a base pipeline' do
let_it_be(:base_pipeline) do
create(:ee_ci_pipeline,
project: project,
ref: merge_request.target_branch,
sha: merge_request.diff_base_sha)
end
let_it_be(:base_pipeline_build) { create(:ci_build, :success, pipeline: base_pipeline, project: project) }
let_it_be(:head_pipeline_build) { create(:ci_build, :success, pipeline: head_pipeline, project: project) }
context 'when the head pipeline does not have security scans' do
context 'when the base pipeline does not have security scans' do
it { is_expected.to be_empty }
end
context 'when the base pipeline has security scans' do
before do
create(:security_scan, build: base_pipeline_build, scan_type: 'sast')
end
it { is_expected.to eq(['sast']) }
end
end
context 'when the head pipeline has security scans' do
before do
create(:security_scan, build: head_pipeline_build, scan_type: 'dast')
end
context 'when the base pipeline does not have security scans' do
it { is_expected.to be_empty }
end
context 'when the base pipeline has security scans' do
before do
create(:security_scan, build: base_pipeline_build, scan_type: 'dast')
end
context 'when there are no missing security scans for the head pipeline' do
it { is_expected.to be_empty }
end
context 'when there are missing security scans for the head pipeline' do
before do
create(:security_scan, build: base_pipeline_build, scan_type: 'sast')
end
it { is_expected.to eq(['sast']) }
context 'when there are multiple scans for the same type for base pipeline' do
before do
build = create(:ci_build, :success, pipeline: base_pipeline, project: project)
create(:security_scan, build: build, scan_type: 'sast')
end
it { is_expected.to eq(['sast']) }
end
end
end
end
end
end
end
end
......@@ -106,4 +106,29 @@ RSpec.describe MergeRequestPresenter do
end
end
end
describe '#missing_security_scan_types' do
let(:presenter) { described_class.new(merge_request, current_user: user) }
let(:pipeline) { instance_double(Ci::Pipeline) }
subject(:missing_security_scan_types) { presenter.missing_security_scan_types }
where(:feature_flag_enabled?, :can_read_pipeline?, :attribute_value) do
false | false | nil
false | true | nil
true | false | nil
true | true | %w(sast)
end
with_them do
before do
stub_feature_flags(missing_mr_security_scan_types: feature_flag_enabled?)
allow(merge_request).to receive(:actual_head_pipeline).and_return(pipeline)
allow(presenter).to receive(:can?).with(user, :read_pipeline, pipeline).and_return(can_read_pipeline?)
allow(merge_request).to receive(:missing_security_scan_types).and_return(%w(sast))
end
it { is_expected.to eq(attribute_value) }
end
end
end
......@@ -18,4 +18,8 @@ RSpec.describe MergeRequestPollCachedWidgetEntity do
it 'includes policy violation status' do
is_expected.to include(:policy_violation)
end
it 'includes missing security scan types' do
is_expected.to include(:missing_security_scan_types)
end
end
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