Commit fa47fcd2 authored by Dheeraj Joshi's avatar Dheeraj Joshi Committed by Kushal Pandya

Improve DAST Profile selectors UX

  * Add a search option
  * Add fixed rows to dropdown
  * and some UI updates
parent ed29856f
...@@ -106,6 +106,9 @@ export default { ...@@ -106,6 +106,9 @@ export default {
dastSiteValidationDocsPath: { dastSiteValidationDocsPath: {
default: '', default: '',
}, },
profilesLibraryPath: {
default: '',
},
}, },
props: { props: {
helpPagePath: { helpPagePath: {
...@@ -165,6 +168,11 @@ export default { ...@@ -165,6 +168,11 @@ export default {
? s__('OnDemandScans|Edit on-demand DAST scan') ? s__('OnDemandScans|Edit on-demand DAST scan')
: s__('OnDemandScans|New on-demand DAST scan'); : s__('OnDemandScans|New on-demand DAST scan');
}, },
manageProfilesLabel() {
return this.glFeatures.dastSavedScans
? s__('OnDemandScans|Manage DAST scans')
: s__('OnDemandScans|Manage profiles');
},
selectedScannerProfile() { selectedScannerProfile() {
return this.selectedScannerProfileId return this.selectedScannerProfileId
? this.scannerProfiles.find(({ id }) => id === this.selectedScannerProfileId) ? this.scannerProfiles.find(({ id }) => id === this.selectedScannerProfileId)
...@@ -304,7 +312,12 @@ export default { ...@@ -304,7 +312,12 @@ export default {
<template> <template>
<gl-form novalidate @submit.prevent="onSubmit()"> <gl-form novalidate @submit.prevent="onSubmit()">
<header class="gl-mb-6"> <header class="gl-mb-6">
<h2>{{ title }}</h2> <div class="gl-mt-6 gl-display-flex">
<h2 class="gl-flex-grow-1 gl-my-0">{{ title }}</h2>
<gl-button :href="profilesLibraryPath" data-testid="manage-profiles-link">
{{ manageProfilesLabel }}
</gl-button>
</div>
<p> <p>
<gl-sprintf <gl-sprintf
:message=" :message="
......
<script> <script>
import { GlButton, GlCard, GlFormGroup, GlDropdown, GlDropdownItem } from '@gitlab/ui'; import {
GlButton,
GlCard,
GlFormGroup,
GlDropdown,
GlDropdownItem,
GlSearchBoxByType,
GlTooltipDirective,
} from '@gitlab/ui';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
export default { export default {
name: 'OnDemandScansProfileSelector', name: 'OnDemandScansProfileSelector',
...@@ -9,6 +18,10 @@ export default { ...@@ -9,6 +18,10 @@ export default {
GlFormGroup, GlFormGroup,
GlDropdown, GlDropdown,
GlDropdownItem, GlDropdownItem,
GlSearchBoxByType,
},
directives: {
GlTooltip: GlTooltipDirective,
}, },
props: { props: {
libraryPath: { libraryPath: {
...@@ -30,10 +43,24 @@ export default { ...@@ -30,10 +43,24 @@ export default {
default: null, default: null,
}, },
}, },
data() {
return { searchTerm: '' };
},
computed: { computed: {
selectedProfile() { selectedProfile() {
return this.value ? this.profiles.find(({ id }) => this.value === id) : null; return this.value ? this.profiles.find(({ id }) => this.value === id) : null;
}, },
filteredProfiles() {
if (this.searchTerm) {
return fuzzaldrinPlus.filter(this.profiles, this.searchTerm, {
key: ['profileName'],
});
}
return this.profiles;
},
filteredProfilesEmpty() {
return this.filteredProfiles.length === 0;
},
}, },
}; };
</script> </script>
...@@ -47,24 +74,13 @@ export default { ...@@ -47,24 +74,13 @@ export default {
<slot name="title"></slot> <slot name="title"></slot>
</h3> </h3>
</div> </div>
<div class="col-5 gl-text-right">
<gl-button
:href="profiles.length ? libraryPath : null"
:disabled="!profiles.length"
variant="success"
category="secondary"
size="small"
data-testid="manage-profiles-link"
>
{{ s__('OnDemandScans|Manage profiles') }}
</gl-button>
</div>
</div> </div>
</template> </template>
<gl-form-group v-if="profiles.length"> <gl-form-group v-if="profiles.length">
<template #label> <template #label>
<slot name="label"></slot> <slot name="label"></slot>
</template> </template>
<gl-dropdown <gl-dropdown
:text=" :text="
selectedProfile selectedProfile
...@@ -74,8 +90,11 @@ export default { ...@@ -74,8 +90,11 @@ export default {
class="mw-460" class="mw-460"
data-testid="profiles-dropdown" data-testid="profiles-dropdown"
> >
<template #header>
<gl-search-box-by-type v-model.trim="searchTerm" />
</template>
<gl-dropdown-item <gl-dropdown-item
v-for="profile in profiles" v-for="profile in filteredProfiles"
:key="profile.id" :key="profile.id"
:is-checked="value === profile.id" :is-checked="value === profile.id"
is-check-item is-check-item
...@@ -83,12 +102,33 @@ export default { ...@@ -83,12 +102,33 @@ export default {
> >
{{ profile.profileName }} {{ profile.profileName }}
</gl-dropdown-item> </gl-dropdown-item>
<div v-show="filteredProfilesEmpty" class="gl-p-3 gl-text-center">
{{ __('No matching results...') }}
</div>
<template #footer>
<gl-dropdown-item :href="newProfilePath" data-testid="create-profile-option">
<slot name="new-profile"></slot>
</gl-dropdown-item>
<gl-dropdown-item :href="libraryPath" data-testid="manage-profiles-option">
<slot name="manage-profile"></slot>
</gl-dropdown-item>
</template>
</gl-dropdown> </gl-dropdown>
<div <div
v-if="value && $scopedSlots.summary" v-if="value && $scopedSlots.summary"
data-testid="selected-profile-summary" data-testid="selected-profile-summary"
class="gl-mt-6 gl-pt-6 gl-border-t-solid gl-border-gray-100 gl-border-t-1" class="gl-mt-6 gl-pt-6 gl-border-t-solid gl-border-gray-100 gl-border-t-1"
> >
<gl-button
v-if="selectedProfile"
v-gl-tooltip
category="primary"
icon="pencil"
:title="s__('DastProfiles|Edit profile')"
:href="selectedProfile.editPath"
class="gl-absolute gl-right-7"
/>
<slot name="summary"></slot> <slot name="summary"></slot>
</div> </div>
</gl-form-group> </gl-form-group>
......
...@@ -56,7 +56,8 @@ export default { ...@@ -56,7 +56,8 @@ export default {
'OnDemandScans|No profile yet. In order to create a new scan, you need to have at least one completed scanner profile.', 'OnDemandScans|No profile yet. In order to create a new scan, you need to have at least one completed scanner profile.',
) )
}}</template> }}</template>
<template #new-profile>{{ s__('OnDemandScans|Create a new scanner profile') }}</template> <template #new-profile>{{ s__('OnDemandScans|Create new scanner profile') }}</template>
<template #manage-profile>{{ s__('OnDemandScans|Manage scanner profiles') }}</template>
<template #summary> <template #summary>
<slot name="summary"></slot> <slot name="summary"></slot>
</template> </template>
......
...@@ -59,7 +59,8 @@ export default { ...@@ -59,7 +59,8 @@ export default {
'OnDemandScans|No profile yet. In order to create a new scan, you need to have at least one completed site profile.', 'OnDemandScans|No profile yet. In order to create a new scan, you need to have at least one completed site profile.',
) )
}}</template> }}</template>
<template #new-profile>{{ s__('OnDemandScans|Create a new site profile') }}</template> <template #new-profile>{{ s__('OnDemandScans|Create new site profile') }}</template>
<template #manage-profile>{{ s__('OnDemandScans|Manage site profiles') }}</template>
<template #summary> <template #summary>
<slot name="summary"></slot> <slot name="summary"></slot>
</template> </template>
......
...@@ -13,6 +13,7 @@ export default () => { ...@@ -13,6 +13,7 @@ export default () => {
dastSiteValidationDocsPath, dastSiteValidationDocsPath,
projectPath, projectPath,
defaultBranch, defaultBranch,
profilesLibraryPath,
scannerProfilesLibraryPath, scannerProfilesLibraryPath,
siteProfilesLibraryPath, siteProfilesLibraryPath,
newSiteProfilePath, newSiteProfilePath,
...@@ -25,6 +26,7 @@ export default () => { ...@@ -25,6 +26,7 @@ export default () => {
el, el,
apolloProvider, apolloProvider,
provide: { provide: {
profilesLibraryPath,
scannerProfilesLibraryPath, scannerProfilesLibraryPath,
siteProfilesLibraryPath, siteProfilesLibraryPath,
newScannerProfilePath, newScannerProfilePath,
......
...@@ -8,6 +8,7 @@ module Projects::OnDemandScansHelper ...@@ -8,6 +8,7 @@ module Projects::OnDemandScansHelper
'empty-state-svg-path' => image_path('illustrations/empty-state/ondemand-scan-empty.svg'), 'empty-state-svg-path' => image_path('illustrations/empty-state/ondemand-scan-empty.svg'),
'default-branch' => project.default_branch, 'default-branch' => project.default_branch,
'project-path' => project.path_with_namespace, 'project-path' => project.path_with_namespace,
'profiles-library-path' => project_security_configuration_dast_profiles_path(project),
'scanner-profiles-library-path' => project_security_configuration_dast_profiles_path(project, anchor: 'scanner-profiles'), 'scanner-profiles-library-path' => project_security_configuration_dast_profiles_path(project, anchor: 'scanner-profiles'),
'site-profiles-library-path' => project_security_configuration_dast_profiles_path(project, anchor: 'site-profiles'), 'site-profiles-library-path' => project_security_configuration_dast_profiles_path(project, anchor: 'site-profiles'),
'new-scanner-profile-path' => new_project_security_configuration_dast_profiles_dast_scanner_profile_path(project), 'new-scanner-profile-path' => new_project_security_configuration_dast_profiles_dast_scanner_profile_path(project),
......
---
title: Improve UX for DAST Profiles selector
merge_request: 51957
author:
type: changed
...@@ -21,28 +21,6 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`] ...@@ -21,28 +21,6 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`]
Scanner profile Scanner profile
</h3> </h3>
</div> </div>
<div
class="col-5 gl-text-right"
>
<a
class="btn btn-success btn-sm gl-button btn-success-secondary"
data-testid="manage-profiles-link"
href="/test/scanner/profiles/library/path"
>
<!---->
<!---->
<span
class="gl-button-text"
>
Manage profiles
</span>
</a>
</div>
</div> </div>
</div> </div>
...@@ -104,11 +82,45 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`] ...@@ -104,11 +82,45 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`]
<div <div
class="gl-new-dropdown-inner" class="gl-new-dropdown-inner"
> >
<!----> <div
class="gl-new-dropdown-header gl-border-b-0!"
>
<!---->
<div
class="gl-search-box-by-type"
>
<svg
aria-hidden="true"
class="gl-search-box-by-type-search-icon gl-icon s16"
data-testid="search-icon"
>
<use
href="#search"
/>
</svg>
<input
aria-label="Search"
class="gl-form-input gl-search-box-by-type-input form-control"
placeholder="Search"
type="text"
/>
<div
class="gl-search-box-by-type-right-icons"
>
<!---->
<!---->
</div>
</div>
</div>
<div <div
class="gl-new-dropdown-contents" class="gl-new-dropdown-contents"
> >
<li <li
class="gl-new-dropdown-item" class="gl-new-dropdown-item"
role="presentation" role="presentation"
...@@ -189,9 +201,86 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`] ...@@ -189,9 +201,86 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`]
<!----> <!---->
</button> </button>
</li> </li>
<div
class="gl-p-3 gl-text-center"
style="display: none;"
>
No matching results...
</div>
</div> </div>
<!----> <div
class="gl-new-dropdown-footer"
>
<li
class="gl-new-dropdown-item"
role="presentation"
>
<a
class="dropdown-item"
data-testid="create-profile-option"
href="/test/new/scanner/profile/path"
role="menuitem"
target="_self"
>
<!---->
<!---->
<!---->
<div
class="gl-new-dropdown-item-text-wrapper"
>
<p
class="gl-new-dropdown-item-text-primary"
>
Create new scanner profile
</p>
<!---->
</div>
<!---->
</a>
</li>
<li
class="gl-new-dropdown-item"
role="presentation"
>
<a
class="dropdown-item"
data-testid="manage-profiles-option"
href="/test/scanner/profiles/library/path"
role="menuitem"
target="_self"
>
<!---->
<!---->
<!---->
<div
class="gl-new-dropdown-item-text-wrapper"
>
<p
class="gl-new-dropdown-item-text-primary"
>
Manage scanner profiles
</p>
<!---->
</div>
<!---->
</a>
</li>
</div>
</div> </div>
</ul> </ul>
...@@ -201,6 +290,26 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`] ...@@ -201,6 +290,26 @@ exports[`OnDemandScansScannerProfileSelector renders properly with profiles 1`]
class="gl-mt-6 gl-pt-6 gl-border-t-solid gl-border-gray-100 gl-border-t-1" class="gl-mt-6 gl-pt-6 gl-border-t-solid gl-border-gray-100 gl-border-t-1"
data-testid="selected-profile-summary" data-testid="selected-profile-summary"
> >
<a
class="btn gl-absolute gl-right-7 btn-default btn-md gl-button btn-icon"
href="/scanner_profile/edit/1"
title="Edit profile"
>
<!---->
<svg
aria-hidden="true"
class="gl-button-icon gl-icon s16"
data-testid="pencil-icon"
>
<use
href="#pencil"
/>
</svg>
<!---->
</a>
<div> <div>
Scanner profile #1's summary Scanner profile #1's summary
</div> </div>
...@@ -236,29 +345,6 @@ exports[`OnDemandScansScannerProfileSelector renders properly without profiles 1 ...@@ -236,29 +345,6 @@ exports[`OnDemandScansScannerProfileSelector renders properly without profiles 1
Scanner profile Scanner profile
</h3> </h3>
</div> </div>
<div
class="col-5 gl-text-right"
>
<button
class="btn btn-success btn-sm disabled gl-button btn-success-secondary"
data-testid="manage-profiles-link"
disabled="disabled"
type="button"
>
<!---->
<!---->
<span
class="gl-button-text"
>
Manage profiles
</span>
</button>
</div>
</div> </div>
</div> </div>
...@@ -284,7 +370,7 @@ exports[`OnDemandScansScannerProfileSelector renders properly without profiles 1 ...@@ -284,7 +370,7 @@ exports[`OnDemandScansScannerProfileSelector renders properly without profiles 1
<span <span
class="gl-button-text" class="gl-button-text"
> >
Create a new scanner profile Create new scanner profile
</span> </span>
</a> </a>
</div> </div>
......
...@@ -21,28 +21,6 @@ exports[`OnDemandScansSiteProfileSelector renders properly with profiles 1`] = ` ...@@ -21,28 +21,6 @@ exports[`OnDemandScansSiteProfileSelector renders properly with profiles 1`] = `
Site profile Site profile
</h3> </h3>
</div> </div>
<div
class="col-5 gl-text-right"
>
<a
class="btn btn-success btn-sm gl-button btn-success-secondary"
data-testid="manage-profiles-link"
href="/test/site/profiles/library/path"
>
<!---->
<!---->
<span
class="gl-button-text"
>
Manage profiles
</span>
</a>
</div>
</div> </div>
</div> </div>
...@@ -104,11 +82,45 @@ exports[`OnDemandScansSiteProfileSelector renders properly with profiles 1`] = ` ...@@ -104,11 +82,45 @@ exports[`OnDemandScansSiteProfileSelector renders properly with profiles 1`] = `
<div <div
class="gl-new-dropdown-inner" class="gl-new-dropdown-inner"
> >
<!----> <div
class="gl-new-dropdown-header gl-border-b-0!"
>
<!---->
<div
class="gl-search-box-by-type"
>
<svg
aria-hidden="true"
class="gl-search-box-by-type-search-icon gl-icon s16"
data-testid="search-icon"
>
<use
href="#search"
/>
</svg>
<input
aria-label="Search"
class="gl-form-input gl-search-box-by-type-input form-control"
placeholder="Search"
type="text"
/>
<div
class="gl-search-box-by-type-right-icons"
>
<!---->
<!---->
</div>
</div>
</div>
<div <div
class="gl-new-dropdown-contents" class="gl-new-dropdown-contents"
> >
<li <li
class="gl-new-dropdown-item" class="gl-new-dropdown-item"
role="presentation" role="presentation"
...@@ -189,9 +201,86 @@ exports[`OnDemandScansSiteProfileSelector renders properly with profiles 1`] = ` ...@@ -189,9 +201,86 @@ exports[`OnDemandScansSiteProfileSelector renders properly with profiles 1`] = `
<!----> <!---->
</button> </button>
</li> </li>
<div
class="gl-p-3 gl-text-center"
style="display: none;"
>
No matching results...
</div>
</div> </div>
<!----> <div
class="gl-new-dropdown-footer"
>
<li
class="gl-new-dropdown-item"
role="presentation"
>
<a
class="dropdown-item"
data-testid="create-profile-option"
href="/test/new/site/profile/path"
role="menuitem"
target="_self"
>
<!---->
<!---->
<!---->
<div
class="gl-new-dropdown-item-text-wrapper"
>
<p
class="gl-new-dropdown-item-text-primary"
>
Create new site profile
</p>
<!---->
</div>
<!---->
</a>
</li>
<li
class="gl-new-dropdown-item"
role="presentation"
>
<a
class="dropdown-item"
data-testid="manage-profiles-option"
href="/test/site/profiles/library/path"
role="menuitem"
target="_self"
>
<!---->
<!---->
<!---->
<div
class="gl-new-dropdown-item-text-wrapper"
>
<p
class="gl-new-dropdown-item-text-primary"
>
Manage site profiles
</p>
<!---->
</div>
<!---->
</a>
</li>
</div>
</div> </div>
</ul> </ul>
...@@ -201,6 +290,26 @@ exports[`OnDemandScansSiteProfileSelector renders properly with profiles 1`] = ` ...@@ -201,6 +290,26 @@ exports[`OnDemandScansSiteProfileSelector renders properly with profiles 1`] = `
class="gl-mt-6 gl-pt-6 gl-border-t-solid gl-border-gray-100 gl-border-t-1" class="gl-mt-6 gl-pt-6 gl-border-t-solid gl-border-gray-100 gl-border-t-1"
data-testid="selected-profile-summary" data-testid="selected-profile-summary"
> >
<a
class="btn gl-absolute gl-right-7 btn-default btn-md gl-button btn-icon"
href="/site_profiles/edit/1"
title="Edit profile"
>
<!---->
<svg
aria-hidden="true"
class="gl-button-icon gl-icon s16"
data-testid="pencil-icon"
>
<use
href="#pencil"
/>
</svg>
<!---->
</a>
<div> <div>
Site profile #1's summary Site profile #1's summary
</div> </div>
...@@ -236,29 +345,6 @@ exports[`OnDemandScansSiteProfileSelector renders properly without profiles 1`] ...@@ -236,29 +345,6 @@ exports[`OnDemandScansSiteProfileSelector renders properly without profiles 1`]
Site profile Site profile
</h3> </h3>
</div> </div>
<div
class="col-5 gl-text-right"
>
<button
class="btn btn-success btn-sm disabled gl-button btn-success-secondary"
data-testid="manage-profiles-link"
disabled="disabled"
type="button"
>
<!---->
<!---->
<span
class="gl-button-text"
>
Manage profiles
</span>
</button>
</div>
</div> </div>
</div> </div>
...@@ -284,7 +370,7 @@ exports[`OnDemandScansSiteProfileSelector renders properly without profiles 1`] ...@@ -284,7 +370,7 @@ exports[`OnDemandScansSiteProfileSelector renders properly without profiles 1`]
<span <span
class="gl-button-text" class="gl-button-text"
> >
Create a new site profile Create new site profile
</span> </span>
</a> </a>
</div> </div>
......
...@@ -13,8 +13,20 @@ describe('OnDemandScansProfileSelector', () => { ...@@ -13,8 +13,20 @@ describe('OnDemandScansProfileSelector', () => {
profiles: [], profiles: [],
}; };
const defaultDropdownItems = [
{
text: 'Create new profile',
isChecked: false,
},
{
text: 'Manage scanner profiles',
isChecked: false,
},
];
const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`); const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`);
const findProfilesLibraryPathLink = () => findByTestId('manage-profiles-link'); const findCreateProfileOption = () => findByTestId('create-profile-option');
const findManageProfilesOption = () => findByTestId('manage-profiles-option');
const findProfilesDropdown = () => findByTestId('profiles-dropdown'); const findProfilesDropdown = () => findByTestId('profiles-dropdown');
const findCreateNewProfileLink = () => findByTestId('create-profile-link'); const findCreateNewProfileLink = () => findByTestId('create-profile-link');
const findSelectedProfileSummary = () => findByTestId('selected-profile-summary'); const findSelectedProfileSummary = () => findByTestId('selected-profile-summary');
...@@ -25,7 +37,6 @@ describe('OnDemandScansProfileSelector', () => { ...@@ -25,7 +37,6 @@ describe('OnDemandScansProfileSelector', () => {
text: x.text(), text: x.text(),
isChecked: x.props('isChecked'), isChecked: x.props('isChecked'),
})); }));
const selectFirstProfile = () => { const selectFirstProfile = () => {
return findProfilesDropdown().find(GlDropdownItem).vm.$emit('click'); return findProfilesDropdown().find(GlDropdownItem).vm.$emit('click');
}; };
...@@ -41,7 +52,8 @@ describe('OnDemandScansProfileSelector', () => { ...@@ -41,7 +52,8 @@ describe('OnDemandScansProfileSelector', () => {
label: 'Use existing scanner profile', label: 'Use existing scanner profile',
summary: `<div>Profile's summary</div>`, summary: `<div>Profile's summary</div>`,
'no-profiles': 'No profile yet', 'no-profiles': 'No profile yet',
'new-profile': 'Create a new profile', 'new-profile': 'Create new profile',
'manage-profile': 'Manage scanner profiles',
}, },
}, },
options, options,
...@@ -64,8 +76,8 @@ describe('OnDemandScansProfileSelector', () => { ...@@ -64,8 +76,8 @@ describe('OnDemandScansProfileSelector', () => {
createFullComponent(); createFullComponent();
}); });
it('disables the link to profiles library', () => { it('do not show profile selector', () => {
expect(findProfilesLibraryPathLink().props('disabled')).toBe(true); expect(findProfilesDropdown().exists()).toBe(false);
}); });
it('shows a help text and a link to create a new profile', () => { it('shows a help text and a link to create a new profile', () => {
...@@ -74,7 +86,7 @@ describe('OnDemandScansProfileSelector', () => { ...@@ -74,7 +86,7 @@ describe('OnDemandScansProfileSelector', () => {
expect(wrapper.text()).toContain('No profile yet'); expect(wrapper.text()).toContain('No profile yet');
expect(link.exists()).toBe(true); expect(link.exists()).toBe(true);
expect(link.attributes('href')).toBe('/path/to/new/profile/form'); expect(link.attributes('href')).toBe('/path/to/new/profile/form');
expect(link.text()).toBe('Create a new profile'); expect(link.text()).toBe('Create new profile');
}); });
}); });
...@@ -85,11 +97,6 @@ describe('OnDemandScansProfileSelector', () => { ...@@ -85,11 +97,6 @@ describe('OnDemandScansProfileSelector', () => {
}); });
}); });
it('enables link to profiles management', () => {
expect(findProfilesLibraryPathLink().props('disabled')).toBe(false);
expect(findProfilesLibraryPathLink().attributes('href')).toBe('/path/to/profiles/library');
});
it('shows a dropdown containing the profiles', () => { it('shows a dropdown containing the profiles', () => {
const dropdown = findProfilesDropdown(); const dropdown = findProfilesDropdown();
...@@ -105,12 +112,21 @@ describe('OnDemandScansProfileSelector', () => { ...@@ -105,12 +112,21 @@ describe('OnDemandScansProfileSelector', () => {
}); });
it('shows dropdown items for each profile', () => { it('shows dropdown items for each profile', () => {
expect(parseDropdownItems()).toEqual( expect(parseDropdownItems()).toEqual([
scannerProfiles.map((x) => ({ ...scannerProfiles.map((x) => ({
text: x.profileName, text: x.profileName,
isChecked: false, isChecked: false,
})), })),
); ...defaultDropdownItems,
]);
});
it('show options for profiles management', () => {
expect(findCreateProfileOption().exists()).toBe(true);
expect(findCreateProfileOption().attributes('href')).toBe('/path/to/new/profile/form');
expect(findManageProfilesOption().exists()).toBe(true);
expect(findManageProfilesOption().attributes('href')).toBe('/path/to/profiles/library');
}); });
it('does not show summary', () => { it('does not show summary', () => {
...@@ -139,12 +155,13 @@ describe('OnDemandScansProfileSelector', () => { ...@@ -139,12 +155,13 @@ describe('OnDemandScansProfileSelector', () => {
}); });
it('displays item as checked', () => { it('displays item as checked', () => {
expect(parseDropdownItems()).toEqual( expect(parseDropdownItems()).toEqual([
scannerProfiles.map((x, i) => ({ ...scannerProfiles.map((x, i) => ({
text: x.profileName, text: x.profileName,
isChecked: i === 0, isChecked: i === 0,
})), })),
); ...defaultDropdownItems,
]);
}); });
}); });
}); });
...@@ -13,6 +13,7 @@ RSpec.describe Projects::OnDemandScansHelper do ...@@ -13,6 +13,7 @@ RSpec.describe Projects::OnDemandScansHelper do
'empty-state-svg-path' => match_asset_path('/assets/illustrations/empty-state/ondemand-scan-empty.svg'), 'empty-state-svg-path' => match_asset_path('/assets/illustrations/empty-state/ondemand-scan-empty.svg'),
'default-branch' => project.default_branch, 'default-branch' => project.default_branch,
'project-path' => project.path_with_namespace, 'project-path' => project.path_with_namespace,
'profiles-library-path' => project_security_configuration_dast_profiles_path(project),
'scanner-profiles-library-path' => project_security_configuration_dast_profiles_path(project, anchor: 'scanner-profiles'), 'scanner-profiles-library-path' => project_security_configuration_dast_profiles_path(project, anchor: 'scanner-profiles'),
'site-profiles-library-path' => project_security_configuration_dast_profiles_path(project, anchor: 'site-profiles'), 'site-profiles-library-path' => project_security_configuration_dast_profiles_path(project, anchor: 'site-profiles'),
'new-scanner-profile-path' => new_project_security_configuration_dast_profiles_dast_scanner_profile_path(project), 'new-scanner-profile-path' => new_project_security_configuration_dast_profiles_dast_scanner_profile_path(project),
......
...@@ -19441,6 +19441,9 @@ msgstr "" ...@@ -19441,6 +19441,9 @@ msgstr ""
msgid "No matching results for \"%{query}\"" msgid "No matching results for \"%{query}\""
msgstr "" msgstr ""
msgid "No matching results..."
msgstr ""
msgid "No members found" msgid "No members found"
msgstr "" msgstr ""
...@@ -19990,10 +19993,10 @@ msgstr "" ...@@ -19990,10 +19993,10 @@ msgstr ""
msgid "OnDemandScans|Could not run the scan. Please try again." msgid "OnDemandScans|Could not run the scan. Please try again."
msgstr "" msgstr ""
msgid "OnDemandScans|Create a new scanner profile" msgid "OnDemandScans|Create new scanner profile"
msgstr "" msgstr ""
msgid "OnDemandScans|Create a new site profile" msgid "OnDemandScans|Create new site profile"
msgstr "" msgstr ""
msgid "OnDemandScans|Description (optional)" msgid "OnDemandScans|Description (optional)"
...@@ -20005,9 +20008,18 @@ msgstr "" ...@@ -20005,9 +20008,18 @@ msgstr ""
msgid "OnDemandScans|For example: Tests the login page for SQL injections" msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr "" msgstr ""
msgid "OnDemandScans|Manage DAST scans"
msgstr ""
msgid "OnDemandScans|Manage profiles" msgid "OnDemandScans|Manage profiles"
msgstr "" msgstr ""
msgid "OnDemandScans|Manage scanner profiles"
msgstr ""
msgid "OnDemandScans|Manage site profiles"
msgstr ""
msgid "OnDemandScans|My daily scan" msgid "OnDemandScans|My daily scan"
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