diff --git a/ee/app/presenters/vulnerability_presenter.rb b/ee/app/presenters/vulnerability_presenter.rb index 55e68566bff0c30cc94544ec5566fb5753dd640b..f04b3f6f87fe61d9d810c152db7423dec373a971 100644 --- a/ee/app/presenters/vulnerability_presenter.rb +++ b/ee/app/presenters/vulnerability_presenter.rb @@ -7,6 +7,10 @@ class VulnerabilityPresenter < Gitlab::View::Presenter::Delegated vulnerability.links.map(&:with_indifferent_access) end + def remediations + vulnerability.remediations.to_a.compact.map(&:with_indifferent_access) + end + def location_text return file unless line diff --git a/ee/spec/factories/vulnerabilities.rb b/ee/spec/factories/vulnerabilities.rb index 98bc729a32956f13980c8005656b23e88f8d3f17..8a9cf96e38a5901dbe1ec8ec654e2d052f31c07e 100644 --- a/ee/spec/factories/vulnerabilities.rb +++ b/ee/spec/factories/vulnerabilities.rb @@ -86,6 +86,21 @@ FactoryBot.define do end end + trait :with_remediation do + after(:build) do |vulnerability| + finding = build( + :vulnerabilities_finding, + :identifier, + :with_remediation, + vulnerability: vulnerability, + report_type: vulnerability.report_type, + project: vulnerability.project + ) + + vulnerability.findings = [finding] + end + end + trait :with_findings do after(:build) do |vulnerability| findings_with_solution = build_list( diff --git a/ee/spec/factories/vulnerabilities/findings.rb b/ee/spec/factories/vulnerabilities/findings.rb index b743b4fde964be990a3c4d9572cae75a146bf077..3c81ed09863441e0f0a8bdddb196d93c713d9c47 100644 --- a/ee/spec/factories/vulnerabilities/findings.rb +++ b/ee/spec/factories/vulnerabilities/findings.rb @@ -16,7 +16,8 @@ FactoryBot.define do raw_metadata.delete('solution') raw_metadata['remediations'] = [ { - summary: evaluator.summary + summary: evaluator.summary, + diff: Base64.encode64("This ain't a diff") } ] finding.raw_metadata = raw_metadata.to_json @@ -114,7 +115,8 @@ FactoryBot.define do raw_metadata.delete(:solution) raw_metadata[:remediations] = [ { - summary: 'Use GCM mode which includes HMAC in the resulting encrypted data, providing integrity of the result.' + summary: 'Use GCM mode which includes HMAC in the resulting encrypted data, providing integrity of the result.', + diff: Base64.encode64("This is a diff") } ] finding.raw_metadata = raw_metadata.to_json diff --git a/ee/spec/services/ee/issues/create_from_vulnerability_service_spec.rb b/ee/spec/services/ee/issues/create_from_vulnerability_service_spec.rb index 646c6f359b59fc09443d00c825f52220f459ca51..d2982234a0d7bdd54023be11ca9d6b0a08052d09 100644 --- a/ee/spec/services/ee/issues/create_from_vulnerability_service_spec.rb +++ b/ee/spec/services/ee/issues/create_from_vulnerability_service_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Issues::CreateFromVulnerabilityService, '#execute' do let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, :public, :repository, namespace: group) } let_it_be(:user) { create(:user) } - let_it_be(:vulnerability) { create(:vulnerability, :with_finding, project: project) } + let(:vulnerability) { create(:vulnerability, :with_finding, project: project) } let(:params) { { vulnerability: vulnerability, link_type: Vulnerabilities::IssueLink.link_types[:created] } } before do @@ -32,18 +32,42 @@ RSpec.describe Issues::CreateFromVulnerabilityService, '#execute' do context 'when a vulnerability exists' do let(:result) { described_class.new(container: project, current_user: user, params: params).execute } - context 'when raw_metadata has no remediations' do - before do - finding = vulnerability.finding - metadata = Gitlab::Json.parse(finding.raw_metadata) - metadata["remediations"] = [nil] - finding.raw_metadata = metadata.to_json - finding.save! + context 'is a vulnerability with remediations' do + let(:vulnerability) { create(:vulnerability, :with_remediation, project: project) } + + context 'when raw_metadata has no remediations' do + let(:vulnerability) { create(:vulnerability, :with_finding, project: project) } + + it 'does not display Remediations section' do + expect(vulnerability.remediations).to eq(nil) + expect(result[:issue].description).not_to match(/Remediations/) + end + end + + context 'when raw_metadata has empty remediations key' do + before do + finding = vulnerability.finding + metadata = Gitlab::Json.parse(finding.raw_metadata) + metadata["remediations"] = [nil] + finding.raw_metadata = metadata.to_json + finding.save! + end + + it 'does not display Remediations section' do + expect(vulnerability.remediations).to eq([nil]) + expect(result[:issue].description).not_to match(/Remediations/) + end end - it 'does not display Remediations section' do - expect(vulnerability.remediations).to eq([nil]) - expect(result[:issue].description).not_to match(/Remediations/) + context 'when raw_metadata has a remediation' do + it 'displays Remediations section' do + expect(vulnerability.remediations.length).to eq(1) + expect(result[:issue].description).to match(/Remediations/) + end + + it 'attaches the diff' do + expect(result[:issue].description).to match(/This is a diff/) + end end end