Commit b381e7ce authored by Kushal Pandya's avatar Kushal Pandya

Merge branch...

Merge branch '233453-dast-scanner-profile-library-implementation-iteration-1-add-scanner-profiles-to-library-view-link-to-tab' into 'master'

Add locationHash support to DAST scanner-profile library

See merge request gitlab-org/gitlab!41532
parents b03e4224 99348ebe
<script>
import * as Sentry from '@sentry/browser';
import { GlDropdown, GlDropdownItem, GlTab, GlTabs } from '@gitlab/ui';
import { camelCase, kebabCase } from 'lodash';
import { s__ } from '~/locale';
import { getLocationHash } from '~/lib/utils/url_utility';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import ProfilesList from './dast_profiles_list.vue';
import * as cacheUtils from '../graphql/cache_utils';
......@@ -46,11 +48,23 @@ export default {
glFeatures,
);
},
tabIndex: {
get() {
const activeTabIndex = Object.keys(this.profileSettings).indexOf(
camelCase(getLocationHash()),
);
return Math.max(0, activeTabIndex);
},
},
},
created() {
this.addSmartQueriesForEnabledProfileTypes();
},
methods: {
setLocationHash(profileType) {
window.location.hash = kebabCase(profileType);
},
addSmartQueriesForEnabledProfileTypes() {
Object.values(this.profileSettings).forEach(({ profileType, graphQL: { query } }) => {
this.makeProfileTypeReactive(profileType);
......@@ -227,10 +241,14 @@ export default {
</p>
</header>
<gl-tabs>
<gl-tab v-for="(data, profileType) in profileSettings" :key="profileType">
<gl-tabs v-model="tabIndex">
<gl-tab
v-for="(settings, profileType) in profileSettings"
:key="profileType"
@click="setLocationHash(profileType)"
>
<template #title>
<span>{{ profileSettings[profileType].i18n.tabName }}</span>
<span>{{ settings.i18n.tabName }}</span>
</template>
<profiles-list
......@@ -241,7 +259,7 @@ export default {
:is-loading="isLoadingProfiles(profileType)"
:profiles-per-page="$options.profilesPerPage"
:profiles="profileTypes[profileType].profiles"
:fields="profileSettings[profileType].tableFields"
:fields="settings.tableFields"
@load-more-profiles="fetchMoreProfiles(profileType)"
@delete-profile="deleteProfile(profileType, $event)"
/>
......
import { mount, shallowMount } from '@vue/test-utils';
import { mount, shallowMount, createWrapper } from '@vue/test-utils';
import { within } from '@testing-library/dom';
import { merge } from 'lodash';
import { GlDropdown } from '@gitlab/ui';
import setWindowLocation from 'helpers/set_window_location_helper';
import DastProfiles from 'ee/dast_profiles/components/dast_profiles.vue';
const TEST_NEW_DAST_SCANNER_PROFILE_PATH = '/-/on_demand_scans/scanner_profiles/new';
......@@ -81,6 +82,11 @@ describe('EE - DastProfiles', () => {
const getDropdownComponent = () => wrapper.find(GlDropdown);
const getSiteProfilesDropdownItem = text =>
within(getDropdownComponent().element).queryByText(text);
const getTab = ({ tabName, selected }) =>
withinComponent().getByRole('tab', {
name: tabName,
selected,
});
afterEach(() => {
wrapper.destroy();
......@@ -124,31 +130,69 @@ describe('EE - DastProfiles', () => {
});
describe('tabs', () => {
beforeEach(() => {
createFullComponent();
});
const originalLocation = window.location;
describe('without location hash set', () => {
beforeEach(() => {
createFullComponent();
});
it('shows a tab-list that contains the different profile categories', () => {
const tabList = withinComponent().getByRole('tablist');
it('shows a tab-list that contains the different profile categories', () => {
const tabList = withinComponent().getByRole('tablist');
expect(tabList).not.toBe(null);
expect(tabList).not.toBe(null);
});
it.each`
tabName | shouldBeSelectedByDefault
${'Site Profiles'} | ${true}
${'Scanner Profiles'} | ${false}
`(
'shows a "$tabName" tab which has "selected" set to "$shouldBeSelectedByDefault"',
({ tabName, shouldBeSelectedByDefault }) => {
const tab = getTab({
tabName,
selected: shouldBeSelectedByDefault,
});
expect(tab).not.toBe(null);
},
);
});
it.each`
tabName | shouldBeSelectedByDefault
${'Site Profiles'} | ${true}
${'Scanner Profiles'} | ${false}
`(
'shows a "$tabName" tab which has "selected" set to "$shouldBeSelectedByDefault"',
({ tabName, shouldBeSelectedByDefault }) => {
const tab = withinComponent().getByRole('tab', {
name: tabName,
selected: shouldBeSelectedByDefault,
describe.each`
tabName | givenLocationHash
${'Site Profiles'} | ${'site-profiles'}
${'Scanner Profiles'} | ${'scanner-profiles'}
`('with location hash set to "$givenLocationHash"', ({ tabName, givenLocationHash }) => {
beforeEach(() => {
setWindowLocation(`http://foo.com/index#${givenLocationHash}`);
createFullComponent();
});
afterEach(() => {
window.location = originalLocation;
});
it(`has "${tabName}" selected`, () => {
const tab = getTab({
tabName,
selected: true,
});
expect(tab).not.toBe(null);
},
);
});
it('updates the browsers URL to contain the selected tab', () => {
window.location.hash = '';
const tab = getTab({ tabName });
createWrapper(tab).trigger('click');
expect(window.location.hash).toBe(givenLocationHash);
});
});
});
describe.each`
......
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