Commit 6f3b675c authored by Peter Hegman's avatar Peter Hegman

Merge branch '347159-fix-tab-querystring-getting-zapped' into 'master'

Fix vulnerability report tab querystring removed when filters changed

See merge request gitlab-org/gitlab!76208
parents 805dc68d aaf6dc48
......@@ -6,6 +6,8 @@ import VulnerabilityReportHeader from './vulnerability_report_header.vue';
import VulnerabilityReport from './vulnerability_report.vue';
import { REPORT_TAB } from './constants';
const OPERATIONAL_TAB_INDEX = 1;
export default {
components: {
GlTabs,
......@@ -26,8 +28,24 @@ export default {
default: false,
},
},
data() {
return {
tabIndex: this.$route.query.tab === REPORT_TAB.OPERATIONAL ? OPERATIONAL_TAB_INDEX : 0,
};
},
watch: {
tabIndex(index) {
// Set tab querystring value to 'OPERATIONAL' if it's the operational tab, otherwise remove it
// for the development tab.
const query = {
...this.$route.query,
tab: index === OPERATIONAL_TAB_INDEX ? REPORT_TAB.OPERATIONAL : undefined,
};
this.$router.push({ query });
},
},
i18n: {
operationalTabParameter: REPORT_TAB.OPERATIONAL.toLowerCase(),
developmentTab: s__('SecurityReports|Development vulnerabilities'),
operationalTab: s__('SecurityReports|Operational vulnerabilities'),
operationalTabMessage: s__(
......@@ -44,7 +62,7 @@ export default {
<vulnerability-report-header />
<gl-tabs class="gl-mt-5" content-class="gl-pt-0" sync-active-tab-with-query-params>
<gl-tabs v-model="tabIndex" class="gl-mt-5" content-class="gl-pt-0">
<gl-tab :title="$options.i18n.developmentTab" lazy>
<slot name="header-development"></slot>
......@@ -55,11 +73,7 @@ export default {
/>
</gl-tab>
<gl-tab
:title="$options.i18n.operationalTab"
:query-param-value="$options.i18n.operationalTabParameter"
lazy
>
<gl-tab :title="$options.i18n.operationalTab" lazy>
<gl-card body-class="gl-p-6">{{ $options.i18n.operationalTabMessage }}</gl-card>
<slot name="header-operational"></slot>
......
......@@ -2,6 +2,7 @@ import { nextTick } from 'vue';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import Cookies from 'js-cookie';
import VueRouter from 'vue-router';
import ProjectVulnerabilityReport from 'ee/security_dashboard/components/project/project_vulnerability_report.vue';
import ReportNotConfiguredProject from 'ee/security_dashboard/components/shared/empty_states/report_not_configured_project.vue';
import VulnerabilityReportTabs from 'ee/security_dashboard/components/shared/vulnerability_report/vulnerability_report_tabs.vue';
......@@ -15,6 +16,8 @@ import createMockApollo from 'helpers/mock_apollo_helper';
const localVue = createLocalVue();
localVue.use(VueApollo);
localVue.use(VueRouter);
const router = new VueRouter();
describe('Project vulnerability report app component', () => {
useLocalStorageSpy();
......@@ -38,6 +41,7 @@ describe('Project vulnerability report app component', () => {
} = {}) => {
wrapper = shallowMount(ProjectVulnerabilityReport, {
localVue,
router,
apolloProvider: createMockApollo([
[securityScannersQuery, securityScannersHandler(securityScanners)],
]),
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { nextTick } from 'vue';
import { GlTabs, GlTab } from '@gitlab/ui';
import VueRouter from 'vue-router';
import VulnerabilityReportTabs from 'ee/security_dashboard/components/shared/vulnerability_report/vulnerability_report_tabs.vue';
import VulnerabilityReport from 'ee/security_dashboard/components/shared/vulnerability_report/vulnerability_report.vue';
import SurveyRequestBanner from 'ee/security_dashboard/components/shared/survey_request_banner.vue';
import projectVulnerabilitiesQuery from 'ee/security_dashboard/graphql/queries/project_vulnerabilities.query.graphql';
import { REPORT_TAB } from 'ee/security_dashboard/components/shared/vulnerability_report/constants';
const localVue = createLocalVue();
localVue.use(VueRouter);
const router = new VueRouter();
describe('Vulnerability report tabs component', () => {
let wrapper;
const createWrapper = ({ showProjectFilter = false } = {}) => {
wrapper = shallowMount(VulnerabilityReportTabs, {
localVue,
router,
propsData: {
query: projectVulnerabilitiesQuery,
showProjectFilter,
......@@ -17,6 +26,7 @@ describe('Vulnerability report tabs component', () => {
});
};
const findTabs = () => wrapper.findComponent(GlTabs);
const findVulnerabilityReports = () => wrapper.findAllComponents(VulnerabilityReport);
afterEach(() => {
......@@ -35,13 +45,43 @@ describe('Vulnerability report tabs component', () => {
it('renders 2 tabs', () => {
createWrapper();
expect(wrapper.findComponent(GlTabs).exists()).toBe(true);
expect(findTabs().exists()).toBe(true);
const tabs = wrapper.findAllComponents(GlTab);
expect(tabs).toHaveLength(2);
expect(tabs.at(0).attributes('title')).toBe('Development vulnerabilities');
expect(tabs.at(1).attributes('title')).toBe('Operational vulnerabilities');
});
it.each`
queryParam | tabIndex
${undefined} | ${0}
${REPORT_TAB.OPERATIONAL} | ${1}
`(
'shows tab with tabIndex $tabIndex when querystring is "$queryParam"',
({ queryParam, tabIndex }) => {
router.replace({ query: { tab: queryParam } });
createWrapper();
expect(findTabs().props('value')).toBe(tabIndex);
},
);
it.each`
tabIndex | queryParam
${0} | ${undefined}
${1} | ${REPORT_TAB.OPERATIONAL}
`(
'changes the tab when tabIndex $tabIndex is clicked and sets querystring to "$queryParam"',
async ({ tabIndex, queryParam }) => {
createWrapper();
findTabs().vm.$emit('input', tabIndex);
await nextTick();
expect(findTabs().props('value')).toBe(tabIndex);
expect(router.currentRoute.query.tab).toBe(queryParam);
},
);
});
describe('vulnerability report components', () => {
......
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