Commit 20828283 authored by Brandon Labuschagne's avatar Brandon Labuschagne

Merge branch '323789-dast-profiles-branch-info' into 'master'

Show branch info in DAST profiles library

See merge request gitlab-org/gitlab!56019
parents 5a446be2 aa74e10b
...@@ -3,16 +3,20 @@ import { GlButton } from '@gitlab/ui'; ...@@ -3,16 +3,20 @@ import { GlButton } from '@gitlab/ui';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { ERROR_RUN_SCAN, ERROR_MESSAGES } from 'ee/on_demand_scans/settings'; import { ERROR_RUN_SCAN, ERROR_MESSAGES } from 'ee/on_demand_scans/settings';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import dastProfileRunMutation from '../graphql/dast_profile_run.mutation.graphql'; import dastProfileRunMutation from '../graphql/dast_profile_run.mutation.graphql';
import ProfilesList from './dast_profiles_list.vue'; import ProfilesList from './dast_profiles_list.vue';
import DastScanBranch from './dast_scan_branch.vue';
import ScanTypeBadge from './dast_scan_type_badge.vue'; import ScanTypeBadge from './dast_scan_type_badge.vue';
export default { export default {
components: { components: {
GlButton, GlButton,
ProfilesList, ProfilesList,
DastScanBranch,
ScanTypeBadge, ScanTypeBadge,
}, },
mixins: [glFeatureFlagsMixin()],
props: { props: {
fullPath: { fullPath: {
type: String, type: String,
...@@ -101,6 +105,15 @@ export default { ...@@ -101,6 +105,15 @@ export default {
v-bind="$attrs" v-bind="$attrs"
v-on="$listeners" v-on="$listeners"
> >
<template #cell(name)="{ item: { name, branch, editPath } }">
{{ name }}
<dast-scan-branch
v-if="glFeatures.dastBranchSelection"
:branch="branch"
:edit-path="editPath"
/>
</template>
<!-- eslint-disable-next-line vue/valid-v-slot --> <!-- eslint-disable-next-line vue/valid-v-slot -->
<template #cell(dastScannerProfile.scanType)="{ value }"> <template #cell(dastScannerProfile.scanType)="{ value }">
<scan-type-badge :scan-type="value" /> <scan-type-badge :scan-type="value" />
......
<script>
import { GlLink, GlIcon } from '@gitlab/ui';
import { isString, isBoolean } from 'lodash';
export default {
name: 'DastScanBranch',
components: {
GlLink,
GlIcon,
},
props: {
branch: {
type: Object,
required: true,
validator: ({ name, exists }) => isString(name) && isBoolean(exists),
},
editPath: {
type: String,
required: true,
},
},
};
</script>
<template>
<div>
<template v-if="branch.exists">
<gl-icon name="branch" />
{{ branch.name }}
</template>
<template v-else>
<span class="gl-text-red-500">
<gl-icon name="warning" />
{{ s__('DastProfiles|Branch missing') }}
</span>
<gl-link :href="editPath">{{ s__('DastProfiles|Select branch') }}</gl-link>
</template>
</div>
</template>
...@@ -18,6 +18,10 @@ query DastProfiles($fullPath: ID!, $after: String, $before: String, $first: Int, ...@@ -18,6 +18,10 @@ query DastProfiles($fullPath: ID!, $after: String, $before: String, $first: Int,
id id
scanType scanType
} }
branch {
name
exists
}
editPath editPath
} }
} }
......
...@@ -9,6 +9,7 @@ module Projects ...@@ -9,6 +9,7 @@ module Projects
authorize_read_on_demand_scans! authorize_read_on_demand_scans!
push_frontend_feature_flag(:dast_saved_scans, @project, default_enabled: :yaml) push_frontend_feature_flag(:dast_saved_scans, @project, default_enabled: :yaml)
push_frontend_feature_flag(:dast_failed_site_validations, @project, default_enabled: :yaml) push_frontend_feature_flag(:dast_failed_site_validations, @project, default_enabled: :yaml)
push_frontend_feature_flag(:dast_branch_selection, @project, default_enabled: :yaml)
end end
feature_category :dynamic_application_security_testing feature_category :dynamic_application_security_testing
......
...@@ -3,6 +3,7 @@ import { merge } from 'lodash'; ...@@ -3,6 +3,7 @@ import { merge } from 'lodash';
import { ERROR_RUN_SCAN, ERROR_MESSAGES } from 'ee/on_demand_scans/settings'; import { ERROR_RUN_SCAN, ERROR_MESSAGES } from 'ee/on_demand_scans/settings';
import ProfilesList from 'ee/security_configuration/dast_profiles/components/dast_profiles_list.vue'; import ProfilesList from 'ee/security_configuration/dast_profiles/components/dast_profiles_list.vue';
import Component from 'ee/security_configuration/dast_profiles/components/dast_saved_scans_list.vue'; import Component from 'ee/security_configuration/dast_profiles/components/dast_saved_scans_list.vue';
import DastScanBranch from 'ee/security_configuration/dast_profiles/components/dast_scan_branch.vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash'; import createFlash from '~/flash';
...@@ -38,6 +39,11 @@ describe('EE - DastSavedScansList', () => { ...@@ -38,6 +39,11 @@ describe('EE - DastSavedScansList', () => {
Component, Component,
merge( merge(
{ {
provide: {
glFeatures: {
dastBranchSelection: true,
},
},
propsData: defaultProps, propsData: defaultProps,
}, },
options, options,
...@@ -61,6 +67,14 @@ describe('EE - DastSavedScansList', () => { ...@@ -61,6 +67,14 @@ describe('EE - DastSavedScansList', () => {
expect(findProfileList()).toExist(); expect(findProfileList()).toExist();
}); });
it('renders branch information for each profile', () => {
createFullComponent({
propsData: { profiles: savedScans },
});
expect(wrapper.findAll(DastScanBranch)).toHaveLength(savedScans.length);
});
it('passes down the props properly', () => { it('passes down the props properly', () => {
createFullComponent(); createFullComponent();
...@@ -181,4 +195,19 @@ describe('EE - DastSavedScansList', () => { ...@@ -181,4 +195,19 @@ describe('EE - DastSavedScansList', () => {
expect(redirectTo).not.toHaveBeenCalled(); expect(redirectTo).not.toHaveBeenCalled();
}); });
}); });
describe('dastBranchSelection feature flag disabled', () => {
it('does not render branch information', () => {
createFullComponent({
provide: {
glFeatures: {
dastBranchSelection: false,
},
},
propsData: { profiles: savedScans },
});
expect(wrapper.findAll(DastScanBranch)).toHaveLength(0);
});
});
}); });
import { GlIcon, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import DastScanBranch from 'ee/security_configuration/dast_profiles/components/dast_scan_branch.vue';
import { savedScans } from '../mocks/mock_data';
const [scanWithExistingBranch, scanWithInexistingBranch] = savedScans;
describe('EE - DastSavedScansList', () => {
let wrapper;
const createWrapper = (propsData = {}) => {
wrapper = shallowMount(DastScanBranch, {
propsData,
});
};
afterEach(() => {
wrapper.destroy();
});
it('renders branch information if it exists', () => {
const { branch, editPath } = scanWithExistingBranch;
createWrapper({ branch, editPath });
expect(wrapper.text()).toContain(branch.name);
expect(wrapper.find(GlIcon).props('name')).toBe('branch');
});
describe('branch does not exist', () => {
beforeEach(() => {
const { branch, editPath } = scanWithInexistingBranch;
createWrapper({ branch, editPath });
});
it('renders a warning message', () => {
expect(wrapper.text()).toContain('Branch missing');
expect(wrapper.find(GlIcon).props('name')).toBe('warning');
});
it('renders the edit link', () => {
const link = wrapper.find(GlLink);
expect(link.text()).toBe('Select branch');
expect(link.attributes('href')).toBe(scanWithInexistingBranch.editPath);
});
});
});
...@@ -69,6 +69,10 @@ export const savedScans = [ ...@@ -69,6 +69,10 @@ export const savedScans = [
dastSiteProfile: siteProfiles[0], dastSiteProfile: siteProfiles[0],
dastScannerProfile: scannerProfiles[0], dastScannerProfile: scannerProfiles[0],
editPath: '/1/edit', editPath: '/1/edit',
branch: {
name: 'main',
exists: true,
},
}, },
{ {
id: 'gid://gitlab/DastProfile/2', id: 'gid://gitlab/DastProfile/2',
...@@ -76,5 +80,9 @@ export const savedScans = [ ...@@ -76,5 +80,9 @@ export const savedScans = [
dastSiteProfile: siteProfiles[1], dastSiteProfile: siteProfiles[1],
dastScannerProfile: scannerProfiles[1], dastScannerProfile: scannerProfiles[1],
editPath: '/2/edit', editPath: '/2/edit',
branch: {
name: 'feature-branch',
exists: false,
},
}, },
]; ];
...@@ -9422,6 +9422,9 @@ msgstr "" ...@@ -9422,6 +9422,9 @@ msgstr ""
msgid "DastProfiles|Authentication URL" msgid "DastProfiles|Authentication URL"
msgstr "" msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
msgid "DastProfiles|Could not create the scanner profile. Please try again." msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr "" msgstr ""
...@@ -9593,6 +9596,9 @@ msgstr "" ...@@ -9593,6 +9596,9 @@ msgstr ""
msgid "DastProfiles|Scanner name" msgid "DastProfiles|Scanner name"
msgstr "" msgstr ""
msgid "DastProfiles|Select branch"
msgstr ""
msgid "DastProfiles|Show debug messages" msgid "DastProfiles|Show debug messages"
msgstr "" msgstr ""
......
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