Commit d61c5521 authored by David O'Regan's avatar David O'Regan

Merge branch '284471-simplify-vulnerability-count-list' into 'master'

Simplify vulnerability count list GraphQL query variables

See merge request gitlab-org/gitlab!58522
parents a950f7ac 1c2efd38
<script> <script>
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { vulnerabilitiesSeverityCountScopes } from '../constants';
import AutoFixUserCallout from './auto_fix_user_callout.vue'; import AutoFixUserCallout from './auto_fix_user_callout.vue';
import CsvExportButton from './csv_export_button.vue'; import CsvExportButton from './csv_export_button.vue';
import ReportsNotConfigured from './empty_states/reports_not_configured.vue'; import ReportsNotConfigured from './empty_states/reports_not_configured.vue';
...@@ -54,7 +53,6 @@ export default { ...@@ -54,7 +53,6 @@ export default {
this.shouldShowAutoFixUserCallout = false; this.shouldShowAutoFixUserCallout = false;
}, },
}, },
vulnerabilitiesSeverityCountScopes,
}; };
</script> </script>
...@@ -79,7 +77,6 @@ export default { ...@@ -79,7 +77,6 @@ export default {
<project-pipeline-status :pipeline="pipeline" /> <project-pipeline-status :pipeline="pipeline" />
<vulnerabilities-count-list <vulnerabilities-count-list
class="gl-mt-6" class="gl-mt-6"
:scope="$options.vulnerabilitiesSeverityCountScopes.project"
:full-path="projectFullPath" :full-path="projectFullPath"
:filters="filters" :filters="filters"
/> />
......
<script> <script>
import { vulnerabilitiesSeverityCountScopes } from '../constants';
import vulnerabilitySeveritiesCountQuery from '../graphql/queries/vulnerability_severities_count.query.graphql'; import vulnerabilitySeveritiesCountQuery from '../graphql/queries/vulnerability_severities_count.query.graphql';
import { DASHBOARD_TYPES } from '../store/constants';
import eventHub from '../utils/event_hub'; import eventHub from '../utils/event_hub';
import VulnerabilityCountListLayout from './vulnerability_count_list_layout.vue'; import VulnerabilityCountListLayout from './vulnerability_count_list_layout.vue';
...@@ -8,12 +8,8 @@ export default { ...@@ -8,12 +8,8 @@ export default {
components: { components: {
VulnerabilityCountListLayout, VulnerabilityCountListLayout,
}, },
inject: ['dashboardType'],
props: { props: {
scope: {
type: String,
required: true,
validator: (value) => Object.values(vulnerabilitiesSeverityCountScopes).includes(value),
},
fullPath: { fullPath: {
type: String, type: String,
required: false, required: false,
...@@ -45,13 +41,12 @@ export default { ...@@ -45,13 +41,12 @@ export default {
vulnerabilitiesCount: { vulnerabilitiesCount: {
query: vulnerabilitySeveritiesCountQuery, query: vulnerabilitySeveritiesCountQuery,
variables() { variables() {
const { scope, fullPath } = this; const { dashboardType, fullPath } = this;
const { instance, group, project } = vulnerabilitiesSeverityCountScopes;
return { return {
fullPath, fullPath,
isInstance: scope === instance, isInstance: dashboardType === DASHBOARD_TYPES.INSTANCE,
isGroup: scope === group, isGroup: dashboardType === DASHBOARD_TYPES.GROUP,
isProject: scope === project, isProject: dashboardType === DASHBOARD_TYPES.PROJECT,
...this.filters, ...this.filters,
}; };
}, },
......
...@@ -6,7 +6,6 @@ import Filters from 'ee/security_dashboard/components/first_class_vulnerability_ ...@@ -6,7 +6,6 @@ import Filters from 'ee/security_dashboard/components/first_class_vulnerability_
import SecurityDashboardLayout from 'ee/security_dashboard/components/security_dashboard_layout.vue'; import SecurityDashboardLayout from 'ee/security_dashboard/components/security_dashboard_layout.vue';
import { DASHBOARD_TYPES } from 'ee/security_dashboard/store/constants'; import { DASHBOARD_TYPES } from 'ee/security_dashboard/store/constants';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { vulnerabilitiesSeverityCountScopes } from '../constants';
import vulnerableProjectsGroupQuery from '../graphql/queries/vulnerable_projects_group.query.graphql'; import vulnerableProjectsGroupQuery from '../graphql/queries/vulnerable_projects_group.query.graphql';
import vulnerableProjectsInstanceQuery from '../graphql/queries/vulnerable_projects_instance.query.graphql'; import vulnerableProjectsInstanceQuery from '../graphql/queries/vulnerable_projects_instance.query.graphql';
import CsvExportButton from './csv_export_button.vue'; import CsvExportButton from './csv_export_button.vue';
...@@ -28,14 +27,7 @@ export default { ...@@ -28,14 +27,7 @@ export default {
GlLoadingIcon, GlLoadingIcon,
VulnerabilitiesCountList, VulnerabilitiesCountList,
}, },
inject: ['groupFullPath'], inject: ['groupFullPath', 'dashboardType'],
props: {
dashboardType: {
type: String,
required: true,
validator: (value) => Object.values(DASHBOARD_TYPES).includes(value),
},
},
queries: { queries: {
[DASHBOARD_TYPES.GROUP]: vulnerableProjectsGroupQuery, [DASHBOARD_TYPES.GROUP]: vulnerableProjectsGroupQuery,
[DASHBOARD_TYPES.INSTANCE]: vulnerableProjectsInstanceQuery, [DASHBOARD_TYPES.INSTANCE]: vulnerableProjectsInstanceQuery,
...@@ -68,11 +60,6 @@ export default { ...@@ -68,11 +60,6 @@ export default {
projectsWereFetched() { projectsWereFetched() {
return !this.$apollo.queries.projects?.loading; return !this.$apollo.queries.projects?.loading;
}, },
scope() {
return this.isGroup
? vulnerabilitiesSeverityCountScopes.group
: vulnerabilitiesSeverityCountScopes.instance;
},
isGroup() { isGroup() {
return this.dashboardType === DASHBOARD_TYPES.GROUP; return this.dashboardType === DASHBOARD_TYPES.GROUP;
}, },
...@@ -111,7 +98,7 @@ export default { ...@@ -111,7 +98,7 @@ export default {
</h2> </h2>
<csv-export-button /> <csv-export-button />
</header> </header>
<vulnerabilities-count-list :scope="scope" :full-path="groupFullPath" :filters="filters" /> <vulnerabilities-count-list :full-path="groupFullPath" :filters="filters" />
</template> </template>
<template #sticky> <template #sticky>
<filters :projects="projects" @filterChange="handleFilterChange" /> <filters :projects="projects" @filterChange="handleFilterChange" />
......
...@@ -6,10 +6,4 @@ export const SURVEY_BANNER_LOCAL_STORAGE_KEY = 'vulnerability_management_survey_ ...@@ -6,10 +6,4 @@ export const SURVEY_BANNER_LOCAL_STORAGE_KEY = 'vulnerability_management_survey_
// word 'survey' and the number, or else it will parse to a valid date. // word 'survey' and the number, or else it will parse to a valid date.
export const SURVEY_BANNER_CURRENT_ID = 'survey1'; export const SURVEY_BANNER_CURRENT_ID = 'survey1';
export const vulnerabilitiesSeverityCountScopes = {
instance: 'instance',
group: 'group',
project: 'project',
};
export const DEFAULT_SCANNER = 'GitLab'; export const DEFAULT_SCANNER = 'GitLab';
...@@ -56,6 +56,7 @@ export default (el, dashboardType) => { ...@@ -56,6 +56,7 @@ export default (el, dashboardType) => {
} }
const provide = { const provide = {
dashboardType,
dashboardDocumentation, dashboardDocumentation,
noVulnerabilitiesSvgPath, noVulnerabilitiesSvgPath,
emptyStateSvgPath, emptyStateSvgPath,
......
...@@ -92,7 +92,6 @@ describe('First class Project Security Dashboard component', () => { ...@@ -92,7 +92,6 @@ describe('First class Project Security Dashboard component', () => {
it('should pass down the properties correctly to the vulnerability count list', () => { it('should pass down the properties correctly to the vulnerability count list', () => {
expect(findVulnerabilityCountList().props()).toEqual({ expect(findVulnerabilityCountList().props()).toEqual({
scope: 'project',
fullPath: provide.projectFullPath, fullPath: provide.projectFullPath,
filters, filters,
}); });
......
...@@ -3,6 +3,7 @@ import VueApollo from 'vue-apollo'; ...@@ -3,6 +3,7 @@ import VueApollo from 'vue-apollo';
import VulnerabilityCountList from 'ee/security_dashboard/components/vulnerability_count_list.vue'; import VulnerabilityCountList from 'ee/security_dashboard/components/vulnerability_count_list.vue';
import VulnerabilityCountListLayout from 'ee/security_dashboard/components/vulnerability_count_list_layout.vue'; import VulnerabilityCountListLayout from 'ee/security_dashboard/components/vulnerability_count_list_layout.vue';
import countQuery from 'ee/security_dashboard/graphql/queries/vulnerability_severities_count.query.graphql'; import countQuery from 'ee/security_dashboard/graphql/queries/vulnerability_severities_count.query.graphql';
import { DASHBOARD_TYPES } from 'ee/security_dashboard/store/constants';
import eventHub from 'ee/security_dashboard/utils/event_hub'; import eventHub from 'ee/security_dashboard/utils/event_hub';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
...@@ -15,11 +16,12 @@ describe('Vulnerabilities count list component', () => { ...@@ -15,11 +16,12 @@ describe('Vulnerabilities count list component', () => {
const findVulnerabilityLayout = () => wrapper.find(VulnerabilityCountListLayout); const findVulnerabilityLayout = () => wrapper.find(VulnerabilityCountListLayout);
const createWrapper = ({ query = { isLoading: false }, props = { scope: 'project' } } = {}) => { const createWrapper = ({ query = { isLoading: false }, provide, data = {} } = {}) => {
refetchSpy = jest.fn(); refetchSpy = jest.fn();
return shallowMount(VulnerabilityCountList, { return shallowMount(VulnerabilityCountList, {
propsData: props, provide: { dashboardType: DASHBOARD_TYPES.PROJECT, ...provide },
data: () => data,
mocks: { mocks: {
$apollo: { queries: { vulnerabilitiesCount: { ...query, refetch: refetchSpy } } }, $apollo: { queries: { vulnerabilitiesCount: { ...query, refetch: refetchSpy } } },
}, },
...@@ -74,15 +76,15 @@ describe('Vulnerabilities count list component', () => { ...@@ -74,15 +76,15 @@ describe('Vulnerabilities count list component', () => {
}); });
describe.each` describe.each`
givenScope | expectedContainedQueryVariables dashboardType | expectedContainedQueryVariables
${'instance'} | ${{ isInstance: true, isGroup: false, isProject: false }} ${DASHBOARD_TYPES.INSTANCE} | ${{ isInstance: true, isGroup: false, isProject: false }}
${'group'} | ${{ isInstance: false, isGroup: true, isProject: false }} ${DASHBOARD_TYPES.GROUP} | ${{ isInstance: false, isGroup: true, isProject: false }}
${'project'} | ${{ isInstance: false, isGroup: false, isProject: true }} ${DASHBOARD_TYPES.PROJECT} | ${{ isInstance: false, isGroup: false, isProject: true }}
`( `(
'when the scope prop is set to "$givenScope"', 'when the dashboard type is $dashboardType',
({ givenScope, expectedContainedQueryVariables }) => { ({ dashboardType, expectedContainedQueryVariables }) => {
beforeEach(() => { beforeEach(() => {
wrapper = createWrapper({ props: { scope: givenScope } }); wrapper = createWrapper({ provide: { dashboardType } });
return wrapper.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
...@@ -96,8 +98,7 @@ describe('Vulnerabilities count list component', () => { ...@@ -96,8 +98,7 @@ describe('Vulnerabilities count list component', () => {
describe('when there is an error', () => { describe('when there is an error', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createWrapper({ query: {} }); wrapper = createWrapper({ data: { queryError: true } });
wrapper.setData({ queryError: true });
}); });
it('should tell the layout to display an error', () => { it('should tell the layout to display an error', () => {
...@@ -112,7 +113,8 @@ describe('Vulnerabilities count list component', () => { ...@@ -112,7 +113,8 @@ describe('Vulnerabilities count list component', () => {
wrapper = shallowMount(VulnerabilityCountList, { wrapper = shallowMount(VulnerabilityCountList, {
localVue, localVue,
apolloProvider: createMockApollo([[countQuery, query]]), apolloProvider: createMockApollo([[countQuery, query]]),
propsData: { scope: 'project', filters }, provide: { dashboardType: DASHBOARD_TYPES.PROJECT },
propsData: { filters },
}); });
}; };
......
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import { nextTick } from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import CsvExportButton from 'ee/security_dashboard/components/csv_export_button.vue'; import CsvExportButton from 'ee/security_dashboard/components/csv_export_button.vue';
import DashboardNotConfiguredGroup from 'ee/security_dashboard/components/empty_states/group_dashboard_not_configured.vue'; import DashboardNotConfiguredGroup from 'ee/security_dashboard/components/empty_states/group_dashboard_not_configured.vue';
...@@ -31,14 +32,7 @@ describe('Vulnerability Report', () => { ...@@ -31,14 +32,7 @@ describe('Vulnerability Report', () => {
const findVulnerabilitiesCountList = () => wrapper.findComponent(VulnerabilitiesCountList); const findVulnerabilitiesCountList = () => wrapper.findComponent(VulnerabilitiesCountList);
const findHeader = () => wrapper.find('h2'); const findHeader = () => wrapper.find('h2');
const createWrapper = ({ const createWrapper = ({ data = {}, mocks, propsData, provide, apolloProvider }) => {
data = {},
mocks,
propsData,
provide = { groupFullPath: undefined },
apolloProvider,
stubs,
}) => {
const localVue = createLocalVue(); const localVue = createLocalVue();
if (apolloProvider) { if (apolloProvider) {
...@@ -48,16 +42,11 @@ describe('Vulnerability Report', () => { ...@@ -48,16 +42,11 @@ describe('Vulnerability Report', () => {
return shallowMount(VulnerabilityReport, { return shallowMount(VulnerabilityReport, {
localVue, localVue,
apolloProvider, apolloProvider,
data() { data: () => data,
return { ...data };
},
mocks, mocks,
propsData, propsData,
provide, provide: { groupFullPath: undefined, ...provide },
stubs: { stubs: { SecurityDashboardLayout },
...stubs,
SecurityDashboardLayout,
},
}); });
}; };
...@@ -68,7 +57,7 @@ describe('Vulnerability Report', () => { ...@@ -68,7 +57,7 @@ describe('Vulnerability Report', () => {
describe('when initialized - all levels', () => { describe('when initialized - all levels', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createWrapper({ wrapper = createWrapper({
propsData: { provide: {
dashboardType: DASHBOARD_TYPES.INSTANCE, dashboardType: DASHBOARD_TYPES.INSTANCE,
}, },
apolloProvider: createApolloProvider([ apolloProvider: createApolloProvider([
...@@ -88,12 +77,12 @@ describe('Vulnerability Report', () => { ...@@ -88,12 +77,12 @@ describe('Vulnerability Report', () => {
expect(findFilters().exists()).toBe(true); expect(findFilters().exists()).toBe(true);
}); });
it('responds to the filterChange event', () => { it('responds to the filterChange event', async () => {
const filters = { severity: 'critical' }; const filters = { severity: 'critical' };
findFilters().vm.$listeners.filterChange(filters); findFilters().vm.$listeners.filterChange(filters);
return wrapper.vm.$nextTick(() => { await nextTick();
expect(findInstanceVulnerabilities().props('filters')).toEqual(filters);
}); expect(findInstanceVulnerabilities().props('filters')).toBe(filters);
}); });
it('displays the csv export button', () => { it('displays the csv export button', () => {
...@@ -106,11 +95,14 @@ describe('Vulnerability Report', () => { ...@@ -106,11 +95,14 @@ describe('Vulnerability Report', () => {
}); });
describe('when initialized - instance level', () => { describe('when initialized - instance level', () => {
const filters = {};
beforeEach(() => { beforeEach(() => {
wrapper = createWrapper({ wrapper = createWrapper({
propsData: { provide: {
dashboardType: DASHBOARD_TYPES.INSTANCE, dashboardType: DASHBOARD_TYPES.INSTANCE,
}, },
data: { filters },
apolloProvider: createApolloProvider([ apolloProvider: createApolloProvider([
[ [
vulnerableProjectsInstanceQuery, vulnerableProjectsInstanceQuery,
...@@ -124,22 +116,17 @@ describe('Vulnerability Report', () => { ...@@ -124,22 +116,17 @@ describe('Vulnerability Report', () => {
expect(findInstanceVulnerabilities().exists()).toBe(true); expect(findInstanceVulnerabilities().exists()).toBe(true);
}); });
it('displays the vulnerability count list with the correct data', () => { it('shows the vulnerability count list and passes the filters prop', () => {
expect(findVulnerabilitiesCountList().props()).toMatchObject({ expect(findVulnerabilitiesCountList().props('filters')).toBe(filters);
scope: 'instance',
filters: wrapper.vm.filters,
});
}); });
}); });
describe('when initialized - group level', () => { describe('when initialized - group level', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createWrapper({ wrapper = createWrapper({
propsData: {
dashboardType: DASHBOARD_TYPES.GROUP,
},
provide: { provide: {
groupFullPath: 'gitlab-org', groupFullPath: 'gitlab-org',
dashboardType: DASHBOARD_TYPES.GROUP,
}, },
apolloProvider: createApolloProvider([ apolloProvider: createApolloProvider([
[ [
...@@ -156,7 +143,6 @@ describe('Vulnerability Report', () => { ...@@ -156,7 +143,6 @@ describe('Vulnerability Report', () => {
it('displays the vulnerability count list with the correct data', () => { it('displays the vulnerability count list with the correct data', () => {
expect(findVulnerabilitiesCountList().props()).toEqual({ expect(findVulnerabilitiesCountList().props()).toEqual({
scope: 'group',
fullPath: 'gitlab-org', fullPath: 'gitlab-org',
filters: wrapper.vm.filters, filters: wrapper.vm.filters,
}); });
...@@ -166,8 +152,10 @@ describe('Vulnerability Report', () => { ...@@ -166,8 +152,10 @@ describe('Vulnerability Report', () => {
describe('when uninitialized', () => { describe('when uninitialized', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createWrapper({ wrapper = createWrapper({
propsData: { dashboardType: DASHBOARD_TYPES.GROUP }, provide: {
provide: { groupFullPath: 'gitlab-org' }, groupFullPath: 'gitlab-org',
dashboardType: DASHBOARD_TYPES.GROUP,
},
apolloProvider: createApolloProvider([ apolloProvider: createApolloProvider([
[ [
vulnerableProjectsGroupQuery, vulnerableProjectsGroupQuery,
...@@ -194,7 +182,7 @@ describe('Vulnerability Report', () => { ...@@ -194,7 +182,7 @@ describe('Vulnerability Report', () => {
describe('when loading projects', () => { describe('when loading projects', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createWrapper({ wrapper = createWrapper({
propsData: { dashboardType: DASHBOARD_TYPES.INSTANCE }, provide: { dashboardType: DASHBOARD_TYPES.INSTANCE },
mocks: { $apollo: { queries: { projects: { loading: true } } } }, mocks: { $apollo: { queries: { projects: { loading: true } } } },
}); });
}); });
......
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