Commit 01aa62ad authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch...

Merge branch '334128-pipeline-security-report-generic-security-report-items-of-type-commit-construct-incorrect' into 'master'

Generic Security Reports: Link to correct commits when GitLab instance is running under a relative URL

See merge request gitlab-org/gitlab!64565
parents 5da48471 c7691f4b
......@@ -167,6 +167,14 @@ module CommitsHelper
]
end
DEFAULT_SHA = '0000000'
# Returns the template path for commit resources
# to be utilized by the client applications.
def commit_path_template(project)
project_commit_path(project, DEFAULT_SHA).sub("/#{DEFAULT_SHA}", '/$COMMIT_SHA')
end
protected
# Private: Returns a link to a person. If the person has a matching user and
......
......@@ -23,6 +23,7 @@ export default () => {
vulnerabilitiesEndpoint,
emptyStateUnauthorizedSvgPath,
emptyStateForbiddenSvgPath,
commitPathTemplate,
projectFullPath,
pipelineJobsPath,
canAdminVulnerability,
......@@ -43,6 +44,7 @@ export default () => {
provide: {
dashboardType: DASHBOARD_TYPES.PIPELINE,
projectId: parseInt(projectId, 10),
commitPathTemplate,
projectFullPath,
dashboardDocumentation,
emptyStateSvgPath,
......
<script>
import { GlLink } from '@gitlab/ui';
import { isRootRelative } from '~/lib/utils/url_utility';
export default {
components: {
GlLink,
},
inject: ['projectFullPath'],
inject: ['commitPathTemplate'],
props: {
value: {
type: String,
......@@ -15,14 +14,10 @@ export default {
},
computed: {
commitPath() {
const { projectFullPath, value } = this;
// `projectFullPath` comes in two flavors: relative (e.g.: `group/project`) and absolute (e.g.: `/group/project`)
// adding a leading slash to the relative path makes sure we always link to an absolute path
const absoluteProjectPath = isRootRelative(projectFullPath)
? projectFullPath
: `/${projectFullPath}`;
return `${absoluteProjectPath}/-/commit/${value}`;
// Search for all occurences of "$COMMIT_SHA" within the given template, eg.: "/base/project/path/-/commit/$COMMIT_SHA"
// NOTE: This should be swapped to using `String.prototype.replaceAll` and a raw string, once browser supported is wider (https://caniuse.com/?search=replaceAll)
const allCommitShaPlaceHolders = /\$COMMIT_SHA/g;
return this.commitPathTemplate.replace(allCommitShaPlaceHolders, this.value);
},
},
};
......
......@@ -18,6 +18,7 @@ export default (el) => {
provide: {
reportType: vulnerability.reportType,
newIssueUrl: vulnerability.newIssueUrl,
commitPathTemplate: el.dataset.commitPathTemplate,
projectFingerprint: vulnerability.projectFingerprint,
projectFullPath: vulnerability.project?.fullPath,
vulnerabilityId: vulnerability.id,
......
......@@ -21,6 +21,7 @@
empty_state_unauthorized_svg_path: image_path('illustrations/user-not-logged-in.svg'),
empty_state_forbidden_svg_path: image_path('illustrations/lock_promotion.svg'),
project_full_path: project.path_with_namespace,
commit_path_template: commit_path_template(project),
can_admin_vulnerability: can?(current_user, :admin_vulnerability, project).to_s,
security_report_help_page_link: help_page_path('user/application_security/index', anchor: 'security-report-validation') } }
......
......@@ -3,7 +3,7 @@
- breadcrumb_title @vulnerability.id
- page_title @vulnerability.title
- page_description @vulnerability.description
- vulnerability_init_details = { vulnerability: vulnerability_details_json(@vulnerability, @pipeline)}
- add_page_specific_style 'page_bundles/security_dashboard'
#js-vulnerability-main{ data: vulnerability_init_details }
#js-vulnerability-main{ data: { vulnerability: vulnerability_details_json(@vulnerability, @pipeline),
commit_path_template: commit_path_template(@project) } }
......@@ -5,40 +5,39 @@ import Commit from 'ee/vulnerabilities/components/generic_report/types/commit.vu
const TEST_DATA = {
value: '24922148',
};
const TEST_COMMIT_PATH_BASE = `/foo/bar`;
const TEST_COMMIT_PATH_PARAMETERS = '?baz=quz';
const TEST_COMMIT_PATH_TEMPLATE = `${TEST_COMMIT_PATH_BASE}/$COMMIT_SHA/${TEST_COMMIT_PATH_PARAMETERS}`;
describe('ee/vulnerabilities/components/generic_report/types/commit.vue', () => {
let wrapper;
const createWrapper = ({ provide } = {}) => {
const createWrapper = () => {
return shallowMount(Commit, {
propsData: TEST_DATA,
provide: {
projectFullPath: '',
...provide,
commitPathTemplate: TEST_COMMIT_PATH_TEMPLATE,
},
});
};
const findLink = () => wrapper.findComponent(GlLink);
beforeEach(() => {
wrapper = createWrapper();
});
afterEach(() => {
wrapper.destroy();
});
it.each(['/foo/bar', 'foo/bar'])(
'given `projectFullPath` is "%s" it links to the absolute path of the commit',
(projectFullPath) => {
const absoluteCommitPath = `/foo/bar/-/commit/${TEST_DATA.value}`;
wrapper = createWrapper({ provide: { projectFullPath } });
expect(findLink().attributes('href')).toBe(absoluteCommitPath);
},
it('links to the given commit hash', () => {
expect(findLink().attributes('href')).toBe(
`${TEST_COMMIT_PATH_BASE}/${TEST_DATA.value}/${TEST_COMMIT_PATH_PARAMETERS}`,
);
});
it('shows the value as the link-text', () => {
wrapper = createWrapper();
expect(findLink().text()).toBe(TEST_DATA.value);
});
});
......@@ -321,4 +321,13 @@ RSpec.describe CommitsHelper do
it { is_expected.to include(pipeline.cache_key) }
end
end
describe "#commit_path_template" do
let(:project) { build(:project) }
let(:expected_path) { "/#{project.full_path}/-/commit/$COMMIT_SHA" }
subject { helper.commit_path_template(project) }
it { is_expected.to eq(expected_path) }
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