Commit c6fda1cc authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '13496-use-security-dashboard-in-pipelines-view-ee' into 'master'

Use Security Dashboard in pipelines view

See merge request gitlab-org/gitlab-ee!15682
parents 563d3d00 e0ad65ab
import Vue from 'vue'; import Vue from 'vue';
import Translate from '~/vue_shared/translate'; import Translate from '~/vue_shared/translate';
import createDashboardStore from 'ee/security_dashboard/store';
import SecurityDashboardApp from 'ee/security_dashboard/components/app.vue';
import SecurityReportApp from 'ee/vue_shared/security_reports/split_security_reports_app.vue'; import SecurityReportApp from 'ee/vue_shared/security_reports/split_security_reports_app.vue';
import createStore from 'ee/vue_shared/security_reports/store'; import createStore from 'ee/vue_shared/security_reports/store';
import { updateBadgeCount } from './utils'; import { updateBadgeCount } from './utils';
Vue.use(Translate); Vue.use(Translate);
export default () => { const initSecurityDashboardApp = el => {
const securityTab = document.getElementById('js-security-report-app'); const {
dashboardDocumentation,
emptyStateSvgPath,
pipelineId,
projectId,
vulnerabilitiesEndpoint,
vulnerabilityFeedbackHelpPath,
} = el.dataset;
// They are being rendered under the same condition return new Vue({
if (securityTab) { el,
const datasetOptions = securityTab.dataset; store: createDashboardStore(),
const { render(createElement) {
headBlobPath, return createElement(SecurityDashboardApp, {
sourceBranch, props: {
sastHeadPath, dashboardDocumentation,
sastHelpPath, emptyStateSvgPath,
dependencyScanningHeadPath, lockToProject: {
dependencyScanningHelpPath, id: parseInt(projectId, 10),
vulnerabilityFeedbackPath, },
vulnerabilityFeedbackHelpPath, pipelineId: parseInt(pipelineId, 10),
createVulnerabilityFeedbackIssuePath, vulnerabilitiesEndpoint,
createVulnerabilityFeedbackMergeRequestPath, vulnerabilityFeedbackHelpPath,
createVulnerabilityFeedbackDismissalPath, },
dastHeadPath, on: {
sastContainerHeadPath, vulnerabilitiesCountChanged(count) {
dastHelpPath, updateBadgeCount('.js-security-counter', count);
sastContainerHelpPath, },
} = datasetOptions; },
const pipelineId = parseInt(datasetOptions.pipelineId, 10); });
},
});
};
const store = createStore(); const initSplitSecurityReportsApp = el => {
const datasetOptions = el.dataset;
const {
headBlobPath,
sourceBranch,
sastHeadPath,
sastHelpPath,
dependencyScanningHeadPath,
dependencyScanningHelpPath,
vulnerabilityFeedbackPath,
vulnerabilityFeedbackHelpPath,
createVulnerabilityFeedbackIssuePath,
createVulnerabilityFeedbackMergeRequestPath,
createVulnerabilityFeedbackDismissalPath,
dastHeadPath,
sastContainerHeadPath,
dastHelpPath,
sastContainerHelpPath,
} = datasetOptions;
const pipelineId = parseInt(datasetOptions.pipelineId, 10);
// Tab content const store = createStore();
// eslint-disable-next-line no-new
new Vue({ return new Vue({
el: securityTab, el,
store, store,
components: { components: {
SecurityReportApp, SecurityReportApp,
}, },
render(createElement) { render(createElement) {
return createElement('security-report-app', { return createElement('security-report-app', {
props: { props: {
headBlobPath, headBlobPath,
sourceBranch, sourceBranch,
sastHeadPath, sastHeadPath,
sastHelpPath, sastHelpPath,
dependencyScanningHeadPath, dependencyScanningHeadPath,
dependencyScanningHelpPath, dependencyScanningHelpPath,
vulnerabilityFeedbackPath, vulnerabilityFeedbackPath,
vulnerabilityFeedbackHelpPath, vulnerabilityFeedbackHelpPath,
createVulnerabilityFeedbackIssuePath, createVulnerabilityFeedbackIssuePath,
createVulnerabilityFeedbackMergeRequestPath, createVulnerabilityFeedbackMergeRequestPath,
createVulnerabilityFeedbackDismissalPath, createVulnerabilityFeedbackDismissalPath,
pipelineId, pipelineId,
dastHeadPath, dastHeadPath,
sastContainerHeadPath, sastContainerHeadPath,
dastHelpPath, dastHelpPath,
sastContainerHelpPath, sastContainerHelpPath,
canCreateIssue: Boolean(createVulnerabilityFeedbackIssuePath), canCreateIssue: Boolean(createVulnerabilityFeedbackIssuePath),
canCreateMergeRequest: Boolean(createVulnerabilityFeedbackMergeRequestPath), canCreateMergeRequest: Boolean(createVulnerabilityFeedbackMergeRequestPath),
canDismissVulnerability: Boolean(createVulnerabilityFeedbackDismissalPath), canDismissVulnerability: Boolean(createVulnerabilityFeedbackDismissalPath),
}, },
on: { on: {
updateBadgeCount: count => { updateBadgeCount: count => {
updateBadgeCount('.js-sast-counter', count); updateBadgeCount('.js-security-counter', count);
},
}, },
}); },
}, });
}); },
});
};
export default () => {
const securityTab = document.getElementById('js-security-report-app');
if (securityTab) {
if (gon.features && gon.features.pipelineReportApi) {
initSecurityDashboardApp(securityTab);
} else {
initSplitSecurityReportsApp(securityTab);
}
} }
}; };
...@@ -23,7 +23,6 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -23,7 +23,6 @@ document.addEventListener('DOMContentLoaded', () => {
dashboardDocumentation, dashboardDocumentation,
emptyStateSvgPath, emptyStateSvgPath,
vulnerabilitiesEndpoint, vulnerabilitiesEndpoint,
vulnerabilitiesHistoryEndpoint,
vulnerabilitiesSummaryEndpoint, vulnerabilitiesSummaryEndpoint,
vulnerabilityFeedbackHelpPath, vulnerabilityFeedbackHelpPath,
securityDashboardHelpPath, securityDashboardHelpPath,
...@@ -40,7 +39,6 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -40,7 +39,6 @@ document.addEventListener('DOMContentLoaded', () => {
dashboardDocumentation, dashboardDocumentation,
emptyStateSvgPath, emptyStateSvgPath,
vulnerabilitiesEndpoint, vulnerabilitiesEndpoint,
vulnerabilitiesHistoryEndpoint,
vulnerabilitiesSummaryEndpoint, vulnerabilitiesSummaryEndpoint,
vulnerabilityFeedbackHelpPath, vulnerabilityFeedbackHelpPath,
securityDashboardHelpPath, securityDashboardHelpPath,
...@@ -80,7 +78,6 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -80,7 +78,6 @@ document.addEventListener('DOMContentLoaded', () => {
components: { components: {
SecurityReportApp, SecurityReportApp,
}, },
methods: {},
render(createElement) { render(createElement) {
return createElement('security-report-app', { return createElement('security-report-app', {
props, props,
......
...@@ -36,11 +36,13 @@ export default { ...@@ -36,11 +36,13 @@ export default {
}, },
vulnerabilitiesCountEndpoint: { vulnerabilitiesCountEndpoint: {
type: String, type: String,
required: true, required: false,
default: '',
}, },
vulnerabilitiesHistoryEndpoint: { vulnerabilitiesHistoryEndpoint: {
type: String, type: String,
required: true, required: false,
default: '',
}, },
vulnerabilityFeedbackHelpPath: { vulnerabilityFeedbackHelpPath: {
type: String, type: String,
...@@ -50,7 +52,12 @@ export default { ...@@ -50,7 +52,12 @@ export default {
type: Object, type: Object,
required: false, required: false,
default: null, default: null,
validator: project => !isUndefined(project.id) && !isUndefined(project.name), validator: project => !isUndefined(project.id),
},
pipelineId: {
type: Number,
required: false,
default: null,
}, },
}, },
computed: { computed: {
...@@ -75,6 +82,15 @@ export default { ...@@ -75,6 +82,15 @@ export default {
isLockedToProject() { isLockedToProject() {
return this.lockToProject !== null; return this.lockToProject !== null;
}, },
shouldShowChart() {
return Boolean(this.vulnerabilitiesHistoryEndpoint);
},
shouldShowCountList() {
return this.isLockedToProject && Boolean(this.vulnerabilitiesCountEndpoint);
},
},
watch: {
'pageInfo.total': 'emitVulnerabilitiesCountChanged',
}, },
created() { created() {
if (this.isLockedToProject) { if (this.isLockedToProject) {
...@@ -83,6 +99,7 @@ export default { ...@@ -83,6 +99,7 @@ export default {
optionId: this.lockToProject.id, optionId: this.lockToProject.id,
}); });
} }
this.setPipelineId(this.pipelineId);
this.setProjectsEndpoint(this.projectsEndpoint); this.setProjectsEndpoint(this.projectsEndpoint);
this.setVulnerabilitiesEndpoint(this.vulnerabilitiesEndpoint); this.setVulnerabilitiesEndpoint(this.vulnerabilitiesEndpoint);
this.setVulnerabilitiesCountEndpoint(this.vulnerabilitiesCountEndpoint); this.setVulnerabilitiesCountEndpoint(this.vulnerabilitiesCountEndpoint);
...@@ -90,9 +107,7 @@ export default { ...@@ -90,9 +107,7 @@ export default {
this.fetchVulnerabilities({ ...this.activeFilters, page: this.pageInfo.page }); this.fetchVulnerabilities({ ...this.activeFilters, page: this.pageInfo.page });
this.fetchVulnerabilitiesCount(this.activeFilters); this.fetchVulnerabilitiesCount(this.activeFilters);
this.fetchVulnerabilitiesHistory(this.activeFilters); this.fetchVulnerabilitiesHistory(this.activeFilters);
if (!this.isLockedToProject) { this.fetchProjects();
this.fetchProjects();
}
}, },
methods: { methods: {
...mapActions('vulnerabilities', [ ...mapActions('vulnerabilities', [
...@@ -106,6 +121,7 @@ export default { ...@@ -106,6 +121,7 @@ export default {
'fetchVulnerabilitiesCount', 'fetchVulnerabilitiesCount',
'fetchVulnerabilitiesHistory', 'fetchVulnerabilitiesHistory',
'openDismissalCommentBox', 'openDismissalCommentBox',
'setPipelineId',
'setVulnerabilitiesCountEndpoint', 'setVulnerabilitiesCountEndpoint',
'setVulnerabilitiesEndpoint', 'setVulnerabilitiesEndpoint',
'setVulnerabilitiesHistoryEndpoint', 'setVulnerabilitiesHistoryEndpoint',
...@@ -116,6 +132,9 @@ export default { ...@@ -116,6 +132,9 @@ export default {
]), ]),
...mapActions('projects', ['setProjectsEndpoint', 'fetchProjects']), ...mapActions('projects', ['setProjectsEndpoint', 'fetchProjects']),
...mapActions('filters', ['lockFilter']), ...mapActions('filters', ['lockFilter']),
emitVulnerabilitiesCountChanged(count) {
this.$emit('vulnerabilitiesCountChanged', count);
},
}, },
}; };
</script> </script>
...@@ -126,7 +145,7 @@ export default { ...@@ -126,7 +145,7 @@ export default {
<filters /> <filters />
</header> </header>
<vulnerability-count-list v-if="isLockedToProject" class="mb-0" /> <vulnerability-count-list v-if="shouldShowCountList" class="mb-0" />
<div class="row mt-4"> <div class="row mt-4">
<main role="main" class="col" :class="{ 'col-xl-7': !isLockedToProject }"> <main role="main" class="col" :class="{ 'col-xl-7': !isLockedToProject }">
...@@ -136,7 +155,7 @@ export default { ...@@ -136,7 +155,7 @@ export default {
/> />
</main> </main>
<aside v-if="!isLockedToProject" class="col-xl-5"> <aside v-if="shouldShowChart" class="col-xl-5">
<vulnerability-chart /> <vulnerability-chart />
</aside> </aside>
</div> </div>
......
...@@ -27,6 +27,10 @@ export const setProjectsEndpoint = ({ commit }, endpoint) => { ...@@ -27,6 +27,10 @@ export const setProjectsEndpoint = ({ commit }, endpoint) => {
}; };
export const fetchProjects = ({ state, dispatch }) => { export const fetchProjects = ({ state, dispatch }) => {
if (!state.projectsEndpoint) {
return;
}
dispatch('requestProjects'); dispatch('requestProjects');
getAllProjects(state.projectsEndpoint) getAllProjects(state.projectsEndpoint)
......
...@@ -17,6 +17,8 @@ import createFlash from '~/flash'; ...@@ -17,6 +17,8 @@ import createFlash from '~/flash';
const hideModal = () => $('#modal-mrwidget-security-issue').modal('hide'); const hideModal = () => $('#modal-mrwidget-security-issue').modal('hide');
export const setPipelineId = ({ commit }, id) => commit(types.SET_PIPELINE_ID, id);
export const setVulnerabilitiesEndpoint = ({ commit }, endpoint) => { export const setVulnerabilitiesEndpoint = ({ commit }, endpoint) => {
commit(types.SET_VULNERABILITIES_ENDPOINT, endpoint); commit(types.SET_VULNERABILITIES_ENDPOINT, endpoint);
}; };
...@@ -145,7 +147,10 @@ export const receiveCreateIssueError = ({ commit }, { flashError }) => { ...@@ -145,7 +147,10 @@ export const receiveCreateIssueError = ({ commit }, { flashError }) => {
} }
}; };
export const dismissVulnerability = ({ dispatch }, { vulnerability, flashError, comment }) => { export const dismissVulnerability = (
{ dispatch, state },
{ vulnerability, flashError, comment },
) => {
dispatch('requestDismissVulnerability'); dispatch('requestDismissVulnerability');
axios axios
...@@ -154,6 +159,7 @@ export const dismissVulnerability = ({ dispatch }, { vulnerability, flashError, ...@@ -154,6 +159,7 @@ export const dismissVulnerability = ({ dispatch }, { vulnerability, flashError,
category: vulnerability.report_type, category: vulnerability.report_type,
comment, comment,
feedback_type: 'dismissal', feedback_type: 'dismissal',
pipeline_id: state.pipelineId,
project_fingerprint: vulnerability.project_fingerprint, project_fingerprint: vulnerability.project_fingerprint,
vulnerability_data: { vulnerability_data: {
...vulnerability, ...vulnerability,
...@@ -162,9 +168,8 @@ export const dismissVulnerability = ({ dispatch }, { vulnerability, flashError, ...@@ -162,9 +168,8 @@ export const dismissVulnerability = ({ dispatch }, { vulnerability, flashError,
}, },
}) })
.then(({ data }) => { .then(({ data }) => {
const { id } = vulnerability;
dispatch('closeDismissalCommentBox'); dispatch('closeDismissalCommentBox');
dispatch('receiveDismissVulnerabilitySuccess', { id, data }); dispatch('receiveDismissVulnerabilitySuccess', { vulnerability, data });
}) })
.catch(() => { .catch(() => {
dispatch('receiveDismissVulnerabilityError', { flashError }); dispatch('receiveDismissVulnerabilityError', { flashError });
...@@ -204,9 +209,8 @@ export const addDismissalComment = ({ dispatch }, { vulnerability, comment }) => ...@@ -204,9 +209,8 @@ export const addDismissalComment = ({ dispatch }, { vulnerability, comment }) =>
comment, comment,
}) })
.then(({ data }) => { .then(({ data }) => {
const { id } = vulnerability;
dispatch('closeDismissalCommentBox'); dispatch('closeDismissalCommentBox');
dispatch('receiveAddDismissalCommentSuccess', { id, data }); dispatch('receiveAddDismissalCommentSuccess', { vulnerability, data });
}) })
.catch(() => { .catch(() => {
dispatch('receiveAddDismissalCommentError'); dispatch('receiveAddDismissalCommentError');
...@@ -276,8 +280,7 @@ export const undoDismiss = ({ dispatch }, { vulnerability, flashError }) => { ...@@ -276,8 +280,7 @@ export const undoDismiss = ({ dispatch }, { vulnerability, flashError }) => {
axios axios
.delete(destroy_vulnerability_feedback_dismissal_path) .delete(destroy_vulnerability_feedback_dismissal_path)
.then(() => { .then(() => {
const { id } = vulnerability; dispatch('receiveUndoDismissSuccess', { vulnerability });
dispatch('receiveUndoDismissSuccess', { id });
}) })
.catch(() => { .catch(() => {
dispatch('receiveUndoDismissError', { flashError }); dispatch('receiveUndoDismissError', { flashError });
......
export const SET_PIPELINE_ID = 'SET_PIPELINE_ID';
export const SET_VULNERABILITIES_ENDPOINT = 'SET_VULNERABILITIES_ENDPOINT'; export const SET_VULNERABILITIES_ENDPOINT = 'SET_VULNERABILITIES_ENDPOINT';
export const SET_VULNERABILITIES_PAGE = 'SET_VULNERABILITIES_PAGE'; export const SET_VULNERABILITIES_PAGE = 'SET_VULNERABILITIES_PAGE';
export const REQUEST_VULNERABILITIES = 'REQUEST_VULNERABILITIES'; export const REQUEST_VULNERABILITIES = 'REQUEST_VULNERABILITIES';
......
...@@ -3,8 +3,12 @@ import { s__, __ } from '~/locale'; ...@@ -3,8 +3,12 @@ import { s__, __ } from '~/locale';
import { visitUrl } from '~/lib/utils/url_utility'; import { visitUrl } from '~/lib/utils/url_utility';
import * as types from './mutation_types'; import * as types from './mutation_types';
import { DAYS } from './constants'; import { DAYS } from './constants';
import { isSameVulnerability } from './utils';
export default { export default {
[types.SET_PIPELINE_ID](state, payload) {
state.pipelineId = payload;
},
[types.SET_VULNERABILITIES_ENDPOINT](state, payload) { [types.SET_VULNERABILITIES_ENDPOINT](state, payload) {
state.vulnerabilitiesEndpoint = payload; state.vulnerabilitiesEndpoint = payload;
}, },
...@@ -106,7 +110,7 @@ export default { ...@@ -106,7 +110,7 @@ export default {
} }
Vue.set(state.modal.data.className, 'value', className); Vue.set(state.modal.data.className, 'value', className);
Vue.set(state.modal.data.file, 'value', `${file}${lineSuffix}`); Vue.set(state.modal.data.file, 'value', file ? `${file}${lineSuffix}` : null);
Vue.set(state.modal.data.image, 'value', image); Vue.set(state.modal.data.image, 'value', image);
Vue.set(state.modal.data.namespace, 'value', namespace); Vue.set(state.modal.data.namespace, 'value', namespace);
} }
...@@ -164,7 +168,9 @@ export default { ...@@ -164,7 +168,9 @@ export default {
Vue.set(state.modal, 'error', null); Vue.set(state.modal, 'error', null);
}, },
[types.RECEIVE_DISMISS_VULNERABILITY_SUCCESS](state, payload) { [types.RECEIVE_DISMISS_VULNERABILITY_SUCCESS](state, payload) {
const vulnerability = state.vulnerabilities.find(vuln => vuln.id === payload.id); const vulnerability = state.vulnerabilities.find(vuln =>
isSameVulnerability(vuln, payload.vulnerability),
);
vulnerability.dismissal_feedback = payload.data; vulnerability.dismissal_feedback = payload.data;
state.isDismissingVulnerability = false; state.isDismissingVulnerability = false;
Vue.set(state.modal, 'isDismissingVulnerability', false); Vue.set(state.modal, 'isDismissingVulnerability', false);
...@@ -185,7 +191,9 @@ export default { ...@@ -185,7 +191,9 @@ export default {
Vue.set(state.modal, 'error', null); Vue.set(state.modal, 'error', null);
}, },
[types.RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS](state, payload) { [types.RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS](state, payload) {
const vulnerability = state.vulnerabilities.find(vuln => vuln.id === payload.id); const vulnerability = state.vulnerabilities.find(vuln =>
isSameVulnerability(vuln, payload.vulnerability),
);
if (vulnerability) { if (vulnerability) {
vulnerability.dismissal_feedback = payload.data; vulnerability.dismissal_feedback = payload.data;
state.isDismissingVulnerability = false; state.isDismissingVulnerability = false;
...@@ -223,7 +231,9 @@ export default { ...@@ -223,7 +231,9 @@ export default {
Vue.set(state.modal, 'error', null); Vue.set(state.modal, 'error', null);
}, },
[types.RECEIVE_REVERT_DISMISSAL_SUCCESS](state, payload) { [types.RECEIVE_REVERT_DISMISSAL_SUCCESS](state, payload) {
const vulnerability = state.vulnerabilities.find(vuln => vuln.id === payload.id); const vulnerability = state.vulnerabilities.find(vuln =>
isSameVulnerability(vuln, payload.vulnerability),
);
vulnerability.dismissal_feedback = null; vulnerability.dismissal_feedback = null;
state.isDismissingVulnerability = false; state.isDismissingVulnerability = false;
Vue.set(state.modal, 'isDismissingVulnerability', false); Vue.set(state.modal, 'isDismissingVulnerability', false);
......
...@@ -13,6 +13,7 @@ export default () => ({ ...@@ -13,6 +13,7 @@ export default () => ({
vulnerabilitiesHistoryDayRange: 90, vulnerabilitiesHistoryDayRange: 90,
vulnerabilitiesHistoryMaxDayInterval: 7, vulnerabilitiesHistoryMaxDayInterval: 7,
pageInfo: {}, pageInfo: {},
pipelineId: null,
vulnerabilitiesCountEndpoint: null, vulnerabilitiesCountEndpoint: null,
vulnerabilitiesHistoryEndpoint: null, vulnerabilitiesHistoryEndpoint: null,
vulnerabilitiesEndpoint: null, vulnerabilitiesEndpoint: null,
......
/* eslint-disable import/prefer-default-export */
import { isEqual } from 'underscore';
const isVulnerabilityLike = object =>
Boolean(object && object.location && object.identifiers && object.identifiers[0]);
/**
* Determines whether the provided objects represent the same vulnerability.
* @param {Object} vulnerability A vulnerability occurrence
* @param {Object} other Another vulnerability occurrence
* @returns {boolean}
*/
export const isSameVulnerability = (vulnerability, other) => {
if (!isVulnerabilityLike(vulnerability) || !isVulnerabilityLike(other)) {
return false;
}
// The `[location_fingerprint, identifiers[0]]` tuple is currently the most
// correct/robust set of data to compare to see if two objects represent the
// same vulnerability[1]. Unfortunately, `location_fingerprint` isn't exposed
// by the API yet, so we fall back to a slower deep equality comparison on
// `location` (which is a superset of `location_fingerprint`) if the former
// isn't present.
//
// [1]: https://gitlab.com/gitlab-org/gitlab-ee/issues/7586
let isLocationEqual = false;
if (vulnerability.location_fingerprint && other.location_fingerprint) {
isLocationEqual = vulnerability.location_fingerprint === other.location_fingerprint;
} else {
isLocationEqual = isEqual(vulnerability.location, other.location);
}
return isLocationEqual && isEqual(vulnerability.identifiers[0], other.identifiers[0]);
};
...@@ -81,11 +81,6 @@ export default { ...@@ -81,11 +81,6 @@ export default {
required: false, required: false,
default: null, default: null,
}, },
vulnerabilitiesHistoryEndpoint: {
type: String,
required: false,
default: null,
},
}, },
computed: { computed: {
headline() { headline() {
...@@ -141,7 +136,6 @@ export default { ...@@ -141,7 +136,6 @@ export default {
:empty-state-svg-path="emptyStateSvgPath" :empty-state-svg-path="emptyStateSvgPath"
:vulnerabilities-endpoint="vulnerabilitiesEndpoint" :vulnerabilities-endpoint="vulnerabilitiesEndpoint"
:vulnerabilities-count-endpoint="vulnerabilitiesSummaryEndpoint" :vulnerabilities-count-endpoint="vulnerabilitiesSummaryEndpoint"
:vulnerabilities-history-endpoint="vulnerabilitiesHistoryEndpoint"
:vulnerability-feedback-help-path="vulnerabilityFeedbackHelpPath" :vulnerability-feedback-help-path="vulnerabilityFeedbackHelpPath"
/> />
</template> </template>
......
...@@ -11,22 +11,30 @@ ...@@ -11,22 +11,30 @@
- if pipeline.expose_security_dashboard? - if pipeline.expose_security_dashboard?
#js-tab-security.build-security.tab-pane #js-tab-security.build-security.tab-pane
#js-security-report-app{ data: { head_blob_path: blob_path, - if Feature.enabled?(:pipeline_report_api)
sast_head_path: sast_endpoint, #js-security-report-app{ data: { dashboard_documentation: help_page_path('user/application_security/security_dashboard/index'),
dependency_scanning_head_path: dependency_scanning_endpoint, empty_state_svg_path: image_path('illustrations/security-dashboard-empty-state.svg'),
dast_head_path: dast_endpoint, pipeline_id: pipeline.id,
sast_container_head_path: sast_container_endpoint, project_id: project.id,
pipeline_id: pipeline.id, vulnerabilities_endpoint: expose_path(api_v4_projects_vulnerabilities_path(id: project.id, params: { pipeline_id: pipeline.id, scope: 'all' })),
source_branch: pipeline.ref, vulnerability_feedback_help_path: help_page_path('user/application_security/index') } }
vulnerability_feedback_path: project_vulnerability_feedback_index_path(project), - else
vulnerability_feedback_help_path: help_page_path('user/application_security/index'), #js-security-report-app{ data: { head_blob_path: blob_path,
sast_help_path: help_page_path('user/application_security/sast/index'), sast_head_path: sast_endpoint,
dependency_scanning_help_path: help_page_path('user/application_security/dependency_scanning/index'), dependency_scanning_head_path: dependency_scanning_endpoint,
dast_help_path: help_page_path('user/application_security/dast/index'), dast_head_path: dast_endpoint,
sast_container_help_path: help_page_path('user/application_security/container_scanning/index'), sast_container_head_path: sast_container_endpoint,
create_vulnerability_feedback_issue_path: create_vulnerability_feedback_issue_path(project), pipeline_id: pipeline.id,
create_vulnerability_feedback_merge_request_path: create_vulnerability_feedback_merge_request_path(project), source_branch: pipeline.ref,
create_vulnerability_feedback_dismissal_path: create_vulnerability_feedback_dismissal_path(project) } } vulnerability_feedback_path: project_vulnerability_feedback_index_path(project),
vulnerability_feedback_help_path: help_page_path('user/application_security/index'),
sast_help_path: help_page_path('user/application_security/sast/index'),
dependency_scanning_help_path: help_page_path('user/application_security/dependency_scanning/index'),
dast_help_path: help_page_path('user/application_security/dast/index'),
sast_container_help_path: help_page_path('user/application_security/container_scanning/index'),
create_vulnerability_feedback_issue_path: create_vulnerability_feedback_issue_path(project),
create_vulnerability_feedback_merge_request_path: create_vulnerability_feedback_merge_request_path(project),
create_vulnerability_feedback_dismissal_path: create_vulnerability_feedback_dismissal_path(project) } }
- if pipeline.expose_license_management_data? - if pipeline.expose_license_management_data?
#js-tab-licenses.tab-pane #js-tab-licenses.tab-pane
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
%li.js-security-tab-link %li.js-security-tab-link
= link_to security_project_pipeline_path(project, pipeline), data: { target: '#js-tab-security', action: 'security', toggle: 'tab' }, class: 'security-tab qa-security-tab' do = link_to security_project_pipeline_path(project, pipeline), data: { target: '#js-tab-security', action: 'security', toggle: 'tab' }, class: 'security-tab qa-security-tab' do
= _("Security") = _("Security")
%span.badge.badge-pill.js-sast-counter.hidden %span.badge.badge-pill.js-security-counter.hidden
- if pipeline.expose_license_management_data? - if pipeline.expose_license_management_data?
%li.js-licenses-tab-link %li.js-licenses-tab-link
......
...@@ -99,17 +99,37 @@ describe 'Pipeline', :js do ...@@ -99,17 +99,37 @@ describe 'Pipeline', :js do
context 'with a sast artifact' do context 'with a sast artifact' do
before do before do
create(:ee_ci_build, :sast, pipeline: pipeline) create(:ee_ci_build, :sast, pipeline: pipeline)
visit security_project_pipeline_path(project, pipeline)
end end
it 'shows jobs tab pane as active' do context 'when feature flag is enabled' do
expect(page).to have_content('Security') before do
expect(page).to have_css('#js-tab-security') visit security_project_pipeline_path(project, pipeline)
end
it 'shows jobs tab pane as active' do
expect(page).to have_content('Security')
expect(page).to have_css('#js-tab-security')
end
it 'shows security dashboard' do
expect(page).to have_css('.js-security-dashboard-table')
end
end end
it 'shows security report section' do context 'when feature flag is disabled' do
expect(page).to have_content('SAST is loading') before do
stub_feature_flags(pipeline_report_api: false)
visit security_project_pipeline_path(project, pipeline)
end
it 'shows jobs tab pane as active' do
expect(page).to have_content('Security')
expect(page).to have_css('#js-tab-security')
end
it 'shows security report section' do
expect(page).to have_content('SAST is loading')
end
end end
end end
......
...@@ -13,31 +13,37 @@ import createStore from 'ee/security_dashboard/store'; ...@@ -13,31 +13,37 @@ import createStore from 'ee/security_dashboard/store';
const localVue = createLocalVue(); const localVue = createLocalVue();
const pipelineId = 123;
const projectsEndpoint = `${TEST_HOST}/projects`; const projectsEndpoint = `${TEST_HOST}/projects`;
const vulnerabilitiesEndpoint = `${TEST_HOST}/vulnerabilities`; const vulnerabilitiesEndpoint = `${TEST_HOST}/vulnerabilities`;
const vulnerabilitiesCountEndpoint = `${TEST_HOST}/vulnerabilities_summary`; const vulnerabilitiesCountEndpoint = `${TEST_HOST}/vulnerabilities_summary`;
const vulnerabilitiesHistoryEndpoint = `${TEST_HOST}/vulnerabilities_history`; const vulnerabilitiesHistoryEndpoint = `${TEST_HOST}/vulnerabilities_history`;
describe('Card security reports app', () => { describe('Security Dashboard app', () => {
let wrapper; let wrapper;
let mock; let mock;
let fetchProjectsSpy; let fetchProjectsSpy;
let lockFilterSpy; let lockFilterSpy;
let setPipelineIdSpy;
let store;
const setup = () => { const setup = () => {
mock = new MockAdapter(axios); mock = new MockAdapter(axios);
fetchProjectsSpy = jest.fn(); fetchProjectsSpy = jest.fn();
lockFilterSpy = jest.fn(); lockFilterSpy = jest.fn();
setPipelineIdSpy = jest.fn();
}; };
const createComponent = props => { const createComponent = props => {
store = createStore();
wrapper = shallowMount(SecurityDashboardApp, { wrapper = shallowMount(SecurityDashboardApp, {
localVue, localVue,
store: createStore(), store,
sync: false, sync: false,
methods: { methods: {
lockFilter: lockFilterSpy, lockFilter: lockFilterSpy,
fetchProjects: fetchProjectsSpy, fetchProjects: fetchProjectsSpy,
setPipelineId: setPipelineIdSpy,
}, },
propsData: { propsData: {
dashboardDocumentation: '', dashboardDocumentation: '',
...@@ -46,6 +52,7 @@ describe('Card security reports app', () => { ...@@ -46,6 +52,7 @@ describe('Card security reports app', () => {
vulnerabilitiesEndpoint, vulnerabilitiesEndpoint,
vulnerabilitiesCountEndpoint, vulnerabilitiesCountEndpoint,
vulnerabilitiesHistoryEndpoint, vulnerabilitiesHistoryEndpoint,
pipelineId,
vulnerabilityFeedbackHelpPath: `${TEST_HOST}/vulnerabilities_feedback_help`, vulnerabilityFeedbackHelpPath: `${TEST_HOST}/vulnerabilities_feedback_help`,
...props, ...props,
}, },
...@@ -90,12 +97,27 @@ describe('Card security reports app', () => { ...@@ -90,12 +97,27 @@ describe('Card security reports app', () => {
it('does not lock project filters', () => { it('does not lock project filters', () => {
expect(lockFilterSpy).not.toHaveBeenCalled(); expect(lockFilterSpy).not.toHaveBeenCalled();
}); });
it('sets the pipeline id', () => {
expect(setPipelineIdSpy).toHaveBeenCalledWith(pipelineId);
});
describe('when the total number of vulnerabilities change', () => {
const newCount = 3;
beforeEach(() => {
localVue.set(store.state.vulnerabilities.pageInfo, 'total', newCount);
});
it('emits a vulnerabilitiesCountChanged event', () => {
expect(wrapper.emitted('vulnerabilitiesCountChanged')).toEqual([[newCount]]);
});
});
}); });
describe('with project lock', () => { describe('with project lock', () => {
const project = { const project = {
id: 123, id: 123,
name: 'my-project',
}; };
beforeEach(() => { beforeEach(() => {
setup(); setup();
...@@ -112,8 +134,8 @@ describe('Card security reports app', () => { ...@@ -112,8 +134,8 @@ describe('Card security reports app', () => {
expect(wrapper.vm.isLockedToProject).toBe(true); expect(wrapper.vm.isLockedToProject).toBe(true);
}); });
it('does not fetch projects', () => { it('fetches projects', () => {
expect(fetchProjectsSpy).not.toHaveBeenCalled(); expect(fetchProjectsSpy).toHaveBeenCalled();
}); });
it('locks the filters to a given project', () => { it('locks the filters to a given project', () => {
...@@ -123,4 +145,21 @@ describe('Card security reports app', () => { ...@@ -123,4 +145,21 @@ describe('Card security reports app', () => {
}); });
}); });
}); });
describe.each`
endpointProp | Component
${'vulnerabilitiesCountEndpoint'} | ${VulnerabilityCountList}
${'vulnerabilitiesHistoryEndpoint'} | ${VulnerabilityChart}
`('with an empty $endpointProp', ({ endpointProp, Component }) => {
beforeEach(() => {
setup();
createComponent({
[endpointProp]: '',
});
});
it(`does not show the ${Component.name}`, () => {
expect(wrapper.find(Component).exists()).toBe(false);
});
});
}); });
import { isSameVulnerability } from 'ee/security_dashboard/store/modules/vulnerabilities/utils';
import mockData from '../../../../javascripts/security_dashboard/store/vulnerabilities/data/mock_data_vulnerabilities.json';
describe('Vulnerabilities utils', () => {
const clone = serializable => JSON.parse(JSON.stringify(serializable));
const vuln = clone(mockData[0]);
const vulnWithNewLocation = { ...clone(vuln), location: { foo: 1 } };
const vulnWithNewIdentifier = { ...clone(vuln), identifiers: [{ foo: 1 }] };
describe('isSameVulnerability', () => {
describe.each`
description | vulnerability | other | result
${'identical vulnerabilities'} | ${vuln} | ${vuln} | ${true}
${'cloned vulnerabilities'} | ${vuln} | ${clone(vuln)} | ${true}
${'different locations'} | ${vuln} | ${vulnWithNewLocation} | ${false}
${'different primary identifiers'} | ${vuln} | ${vulnWithNewIdentifier} | ${false}
${'cloned non-vulnerabilities'} | ${{ foo: 1 }} | ${{ foo: 1 }} | ${false}
${'null values'} | ${null} | ${null} | ${false}
${'undefined values'} | ${undefined} | ${undefined} | ${false}
`('given $description', ({ vulnerability, other, result }) => {
it(`returns ${result}`, () => {
expect(isSameVulnerability(vulnerability, other)).toBe(result);
});
});
});
});
...@@ -12,7 +12,6 @@ const localVue = createLocalVue(); ...@@ -12,7 +12,6 @@ const localVue = createLocalVue();
const vulnerabilitiesEndpoint = `${TEST_HOST}/vulnerabilities`; const vulnerabilitiesEndpoint = `${TEST_HOST}/vulnerabilities`;
const vulnerabilitiesSummaryEndpoint = `${TEST_HOST}/vulnerabilities_summary`; const vulnerabilitiesSummaryEndpoint = `${TEST_HOST}/vulnerabilities_summary`;
const vulnerabilitiesHistoryEndpoint = `${TEST_HOST}/vulnerabilities_history`;
describe('Card security reports app', () => { describe('Card security reports app', () => {
let wrapper; let wrapper;
...@@ -58,7 +57,6 @@ describe('Card security reports app', () => { ...@@ -58,7 +57,6 @@ describe('Card security reports app', () => {
vulnerabilityFeedbackHelpPath: `${TEST_HOST}/vulnerability_feedback_help`, vulnerabilityFeedbackHelpPath: `${TEST_HOST}/vulnerability_feedback_help`,
vulnerabilitiesEndpoint, vulnerabilitiesEndpoint,
vulnerabilitiesSummaryEndpoint, vulnerabilitiesSummaryEndpoint,
vulnerabilitiesHistoryEndpoint,
...props, ...props,
}, },
}); });
......
...@@ -92,6 +92,16 @@ describe('projects actions', () => { ...@@ -92,6 +92,16 @@ describe('projects actions', () => {
); );
}); });
}); });
describe('with an empty endpoint', () => {
beforeEach(() => {
state.projectsEndpoint = '';
});
it('should not do anything', done => {
testAction(actions.fetchProjects, {}, state, [], [], done);
});
});
}); });
describe('receiveProjectsSuccess', () => { describe('receiveProjectsSuccess', () => {
......
...@@ -16,10 +16,34 @@ describe('vulnerabilities count actions', () => { ...@@ -16,10 +16,34 @@ describe('vulnerabilities count actions', () => {
const data = mockDataVulnerabilitiesCount; const data = mockDataVulnerabilitiesCount;
const params = { filters: { type: ['sast'] } }; const params = { filters: { type: ['sast'] } };
const filteredData = mockDataVulnerabilitiesCount.sast; const filteredData = mockDataVulnerabilitiesCount.sast;
let state;
beforeEach(() => {
state = initialState();
});
describe('setPipelineId', () => {
const pipelineId = 123;
it('should commit the correct mutation', done => {
testAction(
actions.setPipelineId,
pipelineId,
state,
[
{
type: types.SET_PIPELINE_ID,
payload: pipelineId,
},
],
[],
done,
);
});
});
describe('setVulnerabilitiesCountEndpoint', () => { describe('setVulnerabilitiesCountEndpoint', () => {
it('should commit the correct mutuation', done => { it('should commit the correct mutuation', done => {
const state = initialState;
const endpoint = 'fakepath.json'; const endpoint = 'fakepath.json';
testAction( testAction(
...@@ -40,7 +64,6 @@ describe('vulnerabilities count actions', () => { ...@@ -40,7 +64,6 @@ describe('vulnerabilities count actions', () => {
describe('fetchVulnerabilitiesCount', () => { describe('fetchVulnerabilitiesCount', () => {
let mock; let mock;
const state = initialState;
beforeEach(() => { beforeEach(() => {
state.vulnerabilitiesCountEndpoint = `${TEST_HOST}/vulnerabilities_count.json`; state.vulnerabilitiesCountEndpoint = `${TEST_HOST}/vulnerabilities_count.json`;
...@@ -111,12 +134,20 @@ describe('vulnerabilities count actions', () => { ...@@ -111,12 +134,20 @@ describe('vulnerabilities count actions', () => {
); );
}); });
}); });
describe('with an empty endpoint', () => {
beforeEach(() => {
state.vulnerabilitiesCountEndpoint = '';
});
it('should not do anything', done => {
testAction(actions.fetchVulnerabilitiesCount, {}, state, [], [], done);
});
});
}); });
describe('requestVulnerabilitiesCount', () => { describe('requestVulnerabilitiesCount', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState;
testAction( testAction(
actions.requestVulnerabilitiesCount, actions.requestVulnerabilitiesCount,
{}, {},
...@@ -130,8 +161,6 @@ describe('vulnerabilities count actions', () => { ...@@ -130,8 +161,6 @@ describe('vulnerabilities count actions', () => {
describe('receiveVulnerabilitiesCountSuccess', () => { describe('receiveVulnerabilitiesCountSuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveVulnerabilitiesCountSuccess, actions.receiveVulnerabilitiesCountSuccess,
{ data }, { data },
...@@ -145,8 +174,6 @@ describe('vulnerabilities count actions', () => { ...@@ -145,8 +174,6 @@ describe('vulnerabilities count actions', () => {
describe('receiveVulnerabilitiesCountError', () => { describe('receiveVulnerabilitiesCountError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveVulnerabilitiesCountError, actions.receiveVulnerabilitiesCountError,
{}, {},
...@@ -179,10 +206,14 @@ describe('vulnerabilities actions', () => { ...@@ -179,10 +206,14 @@ describe('vulnerabilities actions', () => {
'X-Total': pageInfo.total, 'X-Total': pageInfo.total,
'X-Total-Pages': pageInfo.totalPages, 'X-Total-Pages': pageInfo.totalPages,
}; };
let state;
beforeEach(() => {
state = initialState();
});
describe('fetchVulnerabilities', () => { describe('fetchVulnerabilities', () => {
let mock; let mock;
const state = initialState;
beforeEach(() => { beforeEach(() => {
state.vulnerabilitiesEndpoint = `${TEST_HOST}/vulnerabilities.json`; state.vulnerabilitiesEndpoint = `${TEST_HOST}/vulnerabilities.json`;
...@@ -253,12 +284,20 @@ describe('vulnerabilities actions', () => { ...@@ -253,12 +284,20 @@ describe('vulnerabilities actions', () => {
); );
}); });
}); });
describe('with an empty endpoint', () => {
beforeEach(() => {
state.vulnerabilitiesEndpoint = '';
});
it('should not do anything', done => {
testAction(actions.fetchVulnerabilities, {}, state, [], [], done);
});
});
}); });
describe('receiveVulnerabilitiesSuccess', () => { describe('receiveVulnerabilitiesSuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveVulnerabilitiesSuccess, actions.receiveVulnerabilitiesSuccess,
{ headers, data }, { headers, data },
...@@ -277,8 +316,6 @@ describe('vulnerabilities actions', () => { ...@@ -277,8 +316,6 @@ describe('vulnerabilities actions', () => {
describe('receiveVulnerabilitiesError', () => { describe('receiveVulnerabilitiesError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveVulnerabilitiesError, actions.receiveVulnerabilitiesError,
{}, {},
...@@ -292,8 +329,6 @@ describe('vulnerabilities actions', () => { ...@@ -292,8 +329,6 @@ describe('vulnerabilities actions', () => {
describe('requestVulnerabilities', () => { describe('requestVulnerabilities', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState;
testAction( testAction(
actions.requestVulnerabilities, actions.requestVulnerabilities,
{}, {},
...@@ -307,7 +342,6 @@ describe('vulnerabilities actions', () => { ...@@ -307,7 +342,6 @@ describe('vulnerabilities actions', () => {
describe('setVulnerabilitiesEndpoint', () => { describe('setVulnerabilitiesEndpoint', () => {
it('should commit the correct mutuation', done => { it('should commit the correct mutuation', done => {
const state = initialState;
const endpoint = 'fakepath.json'; const endpoint = 'fakepath.json';
testAction( testAction(
...@@ -328,7 +362,6 @@ describe('vulnerabilities actions', () => { ...@@ -328,7 +362,6 @@ describe('vulnerabilities actions', () => {
describe('setVulnerabilitiesPage', () => { describe('setVulnerabilitiesPage', () => {
it('should commit the correct mutuation', done => { it('should commit the correct mutuation', done => {
const state = initialState;
const page = 3; const page = 3;
testAction( testAction(
...@@ -349,8 +382,13 @@ describe('vulnerabilities actions', () => { ...@@ -349,8 +382,13 @@ describe('vulnerabilities actions', () => {
}); });
describe('openModal', () => { describe('openModal', () => {
let state;
beforeEach(() => {
state = initialState();
});
it('should commit the SET_MODAL_DATA mutation', done => { it('should commit the SET_MODAL_DATA mutation', done => {
const state = initialState;
const vulnerability = mockDataVulnerabilities[0]; const vulnerability = mockDataVulnerabilities[0];
testAction( testAction(
...@@ -396,6 +434,12 @@ describe('downloadPatch', () => { ...@@ -396,6 +434,12 @@ describe('downloadPatch', () => {
}); });
describe('issue creation', () => { describe('issue creation', () => {
let state;
beforeEach(() => {
state = initialState();
});
describe('createIssue', () => { describe('createIssue', () => {
const vulnerability = mockDataVulnerabilities[0]; const vulnerability = mockDataVulnerabilities[0];
const data = { issue_url: 'fakepath.html' }; const data = { issue_url: 'fakepath.html' };
...@@ -459,7 +503,6 @@ describe('issue creation', () => { ...@@ -459,7 +503,6 @@ describe('issue creation', () => {
describe('receiveCreateIssueSuccess', () => { describe('receiveCreateIssueSuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState;
const data = mockDataVulnerabilities[0]; const data = mockDataVulnerabilities[0];
testAction( testAction(
...@@ -480,8 +523,6 @@ describe('issue creation', () => { ...@@ -480,8 +523,6 @@ describe('issue creation', () => {
describe('receiveCreateIssueError', () => { describe('receiveCreateIssueError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveCreateIssueError, actions.receiveCreateIssueError,
{}, {},
...@@ -495,8 +536,6 @@ describe('issue creation', () => { ...@@ -495,8 +536,6 @@ describe('issue creation', () => {
describe('requestCreateIssue', () => { describe('requestCreateIssue', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState;
testAction( testAction(
actions.requestCreateIssue, actions.requestCreateIssue,
{}, {},
...@@ -510,6 +549,12 @@ describe('issue creation', () => { ...@@ -510,6 +549,12 @@ describe('issue creation', () => {
}); });
describe('merge request creation', () => { describe('merge request creation', () => {
let state;
beforeEach(() => {
state = initialState();
});
describe('createMergeRequest', () => { describe('createMergeRequest', () => {
const vulnerability = mockDataVulnerabilities[0]; const vulnerability = mockDataVulnerabilities[0];
const data = { merge_request_path: 'fakepath.html' }; const data = { merge_request_path: 'fakepath.html' };
...@@ -573,7 +618,6 @@ describe('merge request creation', () => { ...@@ -573,7 +618,6 @@ describe('merge request creation', () => {
describe('receiveCreateMergeRequestSuccess', () => { describe('receiveCreateMergeRequestSuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState;
const data = mockDataVulnerabilities[0]; const data = mockDataVulnerabilities[0];
testAction( testAction(
...@@ -594,8 +638,6 @@ describe('merge request creation', () => { ...@@ -594,8 +638,6 @@ describe('merge request creation', () => {
describe('receiveCreateMergeRequestError', () => { describe('receiveCreateMergeRequestError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveCreateMergeRequestError, actions.receiveCreateMergeRequestError,
{}, {},
...@@ -609,8 +651,6 @@ describe('merge request creation', () => { ...@@ -609,8 +651,6 @@ describe('merge request creation', () => {
describe('requestCreateMergeRequest', () => { describe('requestCreateMergeRequest', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState;
testAction( testAction(
actions.requestCreateMergeRequest, actions.requestCreateMergeRequest,
{}, {},
...@@ -624,6 +664,12 @@ describe('merge request creation', () => { ...@@ -624,6 +664,12 @@ describe('merge request creation', () => {
}); });
describe('vulnerability dismissal', () => { describe('vulnerability dismissal', () => {
let state;
beforeEach(() => {
state = initialState();
});
describe('dismissVulnerability', () => { describe('dismissVulnerability', () => {
const vulnerability = mockDataVulnerabilities[0]; const vulnerability = mockDataVulnerabilities[0];
const data = { vulnerability }; const data = { vulnerability };
...@@ -657,7 +703,7 @@ describe('vulnerability dismissal', () => { ...@@ -657,7 +703,7 @@ describe('vulnerability dismissal', () => {
{ type: 'closeDismissalCommentBox' }, { type: 'closeDismissalCommentBox' },
{ {
type: 'receiveDismissVulnerabilitySuccess', type: 'receiveDismissVulnerabilitySuccess',
payload: { data, id: vulnerability.id }, payload: { data, vulnerability },
}, },
], ],
done, done,
...@@ -690,7 +736,6 @@ describe('vulnerability dismissal', () => { ...@@ -690,7 +736,6 @@ describe('vulnerability dismissal', () => {
describe('receiveDismissVulnerabilitySuccess', () => { describe('receiveDismissVulnerabilitySuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState;
const data = mockDataVulnerabilities[0]; const data = mockDataVulnerabilities[0];
testAction( testAction(
...@@ -711,8 +756,6 @@ describe('vulnerability dismissal', () => { ...@@ -711,8 +756,6 @@ describe('vulnerability dismissal', () => {
describe('receiveDismissVulnerabilityError', () => { describe('receiveDismissVulnerabilityError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveDismissVulnerabilityError, actions.receiveDismissVulnerabilityError,
{}, {},
...@@ -726,8 +769,6 @@ describe('vulnerability dismissal', () => { ...@@ -726,8 +769,6 @@ describe('vulnerability dismissal', () => {
describe('requestDismissVulnerability', () => { describe('requestDismissVulnerability', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState;
testAction( testAction(
actions.requestDismissVulnerability, actions.requestDismissVulnerability,
{}, {},
...@@ -741,6 +782,12 @@ describe('vulnerability dismissal', () => { ...@@ -741,6 +782,12 @@ describe('vulnerability dismissal', () => {
}); });
describe('add vulnerability dismissal comment', () => { describe('add vulnerability dismissal comment', () => {
let state;
beforeEach(() => {
state = initialState();
});
describe('addDismissalComment', () => { describe('addDismissalComment', () => {
const vulnerability = mockDataVulnerabilities[2]; const vulnerability = mockDataVulnerabilities[2];
const data = { vulnerability }; const data = { vulnerability };
...@@ -778,7 +825,7 @@ describe('add vulnerability dismissal comment', () => { ...@@ -778,7 +825,7 @@ describe('add vulnerability dismissal comment', () => {
[ [
{ type: 'requestAddDismissalComment' }, { type: 'requestAddDismissalComment' },
{ type: 'closeDismissalCommentBox' }, { type: 'closeDismissalCommentBox' },
{ type: 'receiveAddDismissalCommentSuccess', payload: { data, id: vulnerability.id } }, { type: 'receiveAddDismissalCommentSuccess', payload: { data, vulnerability } },
], ],
checkPassedData, checkPassedData,
); );
...@@ -804,8 +851,6 @@ describe('add vulnerability dismissal comment', () => { ...@@ -804,8 +851,6 @@ describe('add vulnerability dismissal comment', () => {
describe('receiveAddDismissalCommentSuccess', () => { describe('receiveAddDismissalCommentSuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveAddDismissalCommentSuccess, actions.receiveAddDismissalCommentSuccess,
{ data }, { data },
...@@ -819,8 +864,6 @@ describe('add vulnerability dismissal comment', () => { ...@@ -819,8 +864,6 @@ describe('add vulnerability dismissal comment', () => {
describe('receiveAddDismissalCommentError', () => { describe('receiveAddDismissalCommentError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveAddDismissalCommentError, actions.receiveAddDismissalCommentError,
{}, {},
...@@ -834,8 +877,6 @@ describe('add vulnerability dismissal comment', () => { ...@@ -834,8 +877,6 @@ describe('add vulnerability dismissal comment', () => {
describe('requestAddDismissalComment', () => { describe('requestAddDismissalComment', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState;
testAction( testAction(
actions.requestAddDismissalComment, actions.requestAddDismissalComment,
{}, {},
...@@ -917,8 +958,6 @@ describe('add vulnerability dismissal comment', () => { ...@@ -917,8 +958,6 @@ describe('add vulnerability dismissal comment', () => {
describe('receiveDeleteDismissalCommentSuccess', () => { describe('receiveDeleteDismissalCommentSuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveDeleteDismissalCommentSuccess, actions.receiveDeleteDismissalCommentSuccess,
{ data }, { data },
...@@ -932,8 +971,6 @@ describe('add vulnerability dismissal comment', () => { ...@@ -932,8 +971,6 @@ describe('add vulnerability dismissal comment', () => {
describe('receiveDeleteDismissalCommentError', () => { describe('receiveDeleteDismissalCommentError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveDeleteDismissalCommentError, actions.receiveDeleteDismissalCommentError,
{}, {},
...@@ -947,8 +984,6 @@ describe('add vulnerability dismissal comment', () => { ...@@ -947,8 +984,6 @@ describe('add vulnerability dismissal comment', () => {
describe('requestDeleteDismissalComment', () => { describe('requestDeleteDismissalComment', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState;
testAction( testAction(
actions.requestDeleteDismissalComment, actions.requestDeleteDismissalComment,
{}, {},
...@@ -963,9 +998,13 @@ describe('add vulnerability dismissal comment', () => { ...@@ -963,9 +998,13 @@ describe('add vulnerability dismissal comment', () => {
}); });
describe('showDismissalDeleteButtons', () => { describe('showDismissalDeleteButtons', () => {
it('commits show dismissal delete buttons', done => { let state;
const state = initialState;
beforeEach(() => {
state = initialState();
});
it('commits show dismissal delete buttons', done => {
testAction( testAction(
actions.showDismissalDeleteButtons, actions.showDismissalDeleteButtons,
null, null,
...@@ -982,9 +1021,13 @@ describe('showDismissalDeleteButtons', () => { ...@@ -982,9 +1021,13 @@ describe('showDismissalDeleteButtons', () => {
}); });
describe('hideDismissalDeleteButtons', () => { describe('hideDismissalDeleteButtons', () => {
it('commits hide dismissal delete buttons', done => { let state;
const state = initialState;
beforeEach(() => {
state = initialState();
});
it('commits hide dismissal delete buttons', done => {
testAction( testAction(
actions.hideDismissalDeleteButtons, actions.hideDismissalDeleteButtons,
null, null,
...@@ -1027,7 +1070,7 @@ describe('revert vulnerability dismissal', () => { ...@@ -1027,7 +1070,7 @@ describe('revert vulnerability dismissal', () => {
[], [],
[ [
{ type: 'requestUndoDismiss' }, { type: 'requestUndoDismiss' },
{ type: 'receiveUndoDismissSuccess', payload: { id: vulnerability.id } }, { type: 'receiveUndoDismissSuccess', payload: { vulnerability } },
], ],
done, done,
); );
...@@ -1113,10 +1156,14 @@ describe('vulnerabilities history actions', () => { ...@@ -1113,10 +1156,14 @@ describe('vulnerabilities history actions', () => {
const data = mockDataVulnerabilitiesHistory; const data = mockDataVulnerabilitiesHistory;
const params = { filters: { severity: ['critical'] } }; const params = { filters: { severity: ['critical'] } };
const filteredData = mockDataVulnerabilitiesHistory.critical; const filteredData = mockDataVulnerabilitiesHistory.critical;
let state;
beforeEach(() => {
state = initialState();
});
describe('setVulnerabilitiesHistoryEndpoint', () => { describe('setVulnerabilitiesHistoryEndpoint', () => {
it('should commit the correct mutuation', done => { it('should commit the correct mutuation', done => {
const state = initialState;
const endpoint = 'fakepath.json'; const endpoint = 'fakepath.json';
testAction( testAction(
...@@ -1137,7 +1184,6 @@ describe('vulnerabilities history actions', () => { ...@@ -1137,7 +1184,6 @@ describe('vulnerabilities history actions', () => {
describe('setVulnerabilitiesHistoryDayRange', () => { describe('setVulnerabilitiesHistoryDayRange', () => {
it('should commit the number of past days to show', done => { it('should commit the number of past days to show', done => {
const state = initialState;
const days = DAYS.THIRTY; const days = DAYS.THIRTY;
testAction( testAction(
actions.setVulnerabilitiesHistoryDayRange, actions.setVulnerabilitiesHistoryDayRange,
...@@ -1155,9 +1201,8 @@ describe('vulnerabilities history actions', () => { ...@@ -1155,9 +1201,8 @@ describe('vulnerabilities history actions', () => {
}); });
}); });
describe('fetchVulnerabilitiesTimeline', () => { describe('fetchVulnerabilitiesHistory', () => {
let mock; let mock;
const state = initialState;
beforeEach(() => { beforeEach(() => {
state.vulnerabilitiesHistoryEndpoint = `${TEST_HOST}/vulnerabilitIES_HISTORY.json`; state.vulnerabilitiesHistoryEndpoint = `${TEST_HOST}/vulnerabilitIES_HISTORY.json`;
...@@ -1231,12 +1276,20 @@ describe('vulnerabilities history actions', () => { ...@@ -1231,12 +1276,20 @@ describe('vulnerabilities history actions', () => {
); );
}); });
}); });
describe('with an empty endpoint', () => {
beforeEach(() => {
state.vulnerabilitiesHistoryEndpoint = '';
});
it('should not do anything', done => {
testAction(actions.fetchVulnerabilitiesHistory, {}, state, [], [], done);
});
});
}); });
describe('requestVulnerabilitiesTimeline', () => { describe('requestVulnerabilitiesHistory', () => {
it('should commit the request mutation', done => { it('should commit the request mutation', done => {
const state = initialState;
testAction( testAction(
actions.requestVulnerabilitiesHistory, actions.requestVulnerabilitiesHistory,
{}, {},
...@@ -1248,10 +1301,8 @@ describe('vulnerabilities history actions', () => { ...@@ -1248,10 +1301,8 @@ describe('vulnerabilities history actions', () => {
}); });
}); });
describe('receiveVulnerabilitiesTimelineSuccess', () => { describe('receiveVulnerabilitiesHistorySuccess', () => {
it('should commit the success mutation', done => { it('should commit the success mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveVulnerabilitiesHistorySuccess, actions.receiveVulnerabilitiesHistorySuccess,
{ data }, { data },
...@@ -1263,10 +1314,8 @@ describe('vulnerabilities history actions', () => { ...@@ -1263,10 +1314,8 @@ describe('vulnerabilities history actions', () => {
}); });
}); });
describe('receiveVulnerabilitiesTimelineError', () => { describe('receiveVulnerabilitiesHistoryError', () => {
it('should commit the error mutation', done => { it('should commit the error mutation', done => {
const state = initialState;
testAction( testAction(
actions.receiveVulnerabilitiesHistoryError, actions.receiveVulnerabilitiesHistoryError,
{}, {},
...@@ -1280,8 +1329,6 @@ describe('vulnerabilities history actions', () => { ...@@ -1280,8 +1329,6 @@ describe('vulnerabilities history actions', () => {
describe('openDismissalCommentBox', () => { describe('openDismissalCommentBox', () => {
it('should commit the open comment mutation with a default payload', done => { it('should commit the open comment mutation with a default payload', done => {
const state = initialState();
testAction( testAction(
actions.openDismissalCommentBox, actions.openDismissalCommentBox,
undefined, undefined,
...@@ -1295,8 +1342,6 @@ describe('vulnerabilities history actions', () => { ...@@ -1295,8 +1342,6 @@ describe('vulnerabilities history actions', () => {
describe('closeDismissalCommentBox', () => { describe('closeDismissalCommentBox', () => {
it('should commit the close comment mutation', done => { it('should commit the close comment mutation', done => {
const state = initialState();
testAction( testAction(
actions.closeDismissalCommentBox, actions.closeDismissalCommentBox,
{}, {},
......
...@@ -5,9 +5,24 @@ import { DAYS } from 'ee/security_dashboard/store/modules/vulnerabilities/consta ...@@ -5,9 +5,24 @@ import { DAYS } from 'ee/security_dashboard/store/modules/vulnerabilities/consta
import mockData from './data/mock_data_vulnerabilities.json'; import mockData from './data/mock_data_vulnerabilities.json';
describe('vulnerabilities module mutations', () => { describe('vulnerabilities module mutations', () => {
let state;
beforeEach(() => {
state = createState();
});
describe('SET_PIPELINE_ID', () => {
const pipelineId = 123;
it(`should set the pipelineId to ${pipelineId}`, () => {
mutations[types.SET_PIPELINE_ID](state, pipelineId);
expect(state.pipelineId).toBe(pipelineId);
});
});
describe('SET_VULNERABILITIES_ENDPOINT', () => { describe('SET_VULNERABILITIES_ENDPOINT', () => {
it('should set `vulnerabilitiesEndpoint` to `fakepath.json`', () => { it('should set `vulnerabilitiesEndpoint` to `fakepath.json`', () => {
const state = createState();
const endpoint = 'fakepath.json'; const endpoint = 'fakepath.json';
mutations[types.SET_VULNERABILITIES_ENDPOINT](state, endpoint); mutations[types.SET_VULNERABILITIES_ENDPOINT](state, endpoint);
...@@ -19,8 +34,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -19,8 +34,6 @@ describe('vulnerabilities module mutations', () => {
describe('SET_VULNERABILITIES_PAGE', () => { describe('SET_VULNERABILITIES_PAGE', () => {
const page = 3; const page = 3;
it(`should set pageInfo.page to ${page}`, () => { it(`should set pageInfo.page to ${page}`, () => {
const state = createState();
mutations[types.SET_VULNERABILITIES_PAGE](state, page); mutations[types.SET_VULNERABILITIES_PAGE](state, page);
expect(state.pageInfo.page).toEqual(page); expect(state.pageInfo.page).toEqual(page);
...@@ -28,13 +41,8 @@ describe('vulnerabilities module mutations', () => { ...@@ -28,13 +41,8 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('REQUEST_VULNERABILITIES', () => { describe('REQUEST_VULNERABILITIES', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = { state.errorLoadingVulnerabilities = true;
...createState(),
errorLoadingVulnerabilities: true,
};
mutations[types.REQUEST_VULNERABILITIES](state); mutations[types.REQUEST_VULNERABILITIES](state);
}); });
...@@ -49,14 +57,12 @@ describe('vulnerabilities module mutations', () => { ...@@ -49,14 +57,12 @@ describe('vulnerabilities module mutations', () => {
describe('RECEIVE_VULNERABILITIES_SUCCESS', () => { describe('RECEIVE_VULNERABILITIES_SUCCESS', () => {
let payload; let payload;
let state;
beforeEach(() => { beforeEach(() => {
payload = { payload = {
vulnerabilities: mockData, vulnerabilities: mockData,
pageInfo: { a: 1, b: 2, c: 3 }, pageInfo: { a: 1, b: 2, c: 3 },
}; };
state = createState();
mutations[types.RECEIVE_VULNERABILITIES_SUCCESS](state, payload); mutations[types.RECEIVE_VULNERABILITIES_SUCCESS](state, payload);
}); });
...@@ -75,8 +81,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -75,8 +81,6 @@ describe('vulnerabilities module mutations', () => {
describe('RECEIVE_VULNERABILITIES_ERROR', () => { describe('RECEIVE_VULNERABILITIES_ERROR', () => {
it('should set `isLoadingVulnerabilities` to `false`', () => { it('should set `isLoadingVulnerabilities` to `false`', () => {
const state = createState();
mutations[types.RECEIVE_VULNERABILITIES_ERROR](state); mutations[types.RECEIVE_VULNERABILITIES_ERROR](state);
expect(state.isLoadingVulnerabilities).toBeFalsy(); expect(state.isLoadingVulnerabilities).toBeFalsy();
...@@ -85,7 +89,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -85,7 +89,6 @@ describe('vulnerabilities module mutations', () => {
describe('SET_VULNERABILITIES_COUNT_ENDPOINT', () => { describe('SET_VULNERABILITIES_COUNT_ENDPOINT', () => {
it('should set `vulnerabilitiesCountEndpoint` to `fakepath.json`', () => { it('should set `vulnerabilitiesCountEndpoint` to `fakepath.json`', () => {
const state = createState();
const endpoint = 'fakepath.json'; const endpoint = 'fakepath.json';
mutations[types.SET_VULNERABILITIES_COUNT_ENDPOINT](state, endpoint); mutations[types.SET_VULNERABILITIES_COUNT_ENDPOINT](state, endpoint);
...@@ -95,13 +98,8 @@ describe('vulnerabilities module mutations', () => { ...@@ -95,13 +98,8 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('REQUEST_VULNERABILITIES_COUNT', () => { describe('REQUEST_VULNERABILITIES_COUNT', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = { state.errorLoadingVulnerabilitiesCount = true;
...createState(),
errorLoadingVulnerabilitiesCount: true,
};
mutations[types.REQUEST_VULNERABILITIES_COUNT](state); mutations[types.REQUEST_VULNERABILITIES_COUNT](state);
}); });
...@@ -116,11 +114,9 @@ describe('vulnerabilities module mutations', () => { ...@@ -116,11 +114,9 @@ describe('vulnerabilities module mutations', () => {
describe('RECEIVE_VULNERABILITIES_COUNT_SUCCESS', () => { describe('RECEIVE_VULNERABILITIES_COUNT_SUCCESS', () => {
let payload; let payload;
let state;
beforeEach(() => { beforeEach(() => {
payload = mockData; payload = mockData;
state = createState();
mutations[types.RECEIVE_VULNERABILITIES_COUNT_SUCCESS](state, payload); mutations[types.RECEIVE_VULNERABILITIES_COUNT_SUCCESS](state, payload);
}); });
...@@ -135,8 +131,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -135,8 +131,6 @@ describe('vulnerabilities module mutations', () => {
describe('RECEIVE_VULNERABILITIES_COUNT_ERROR', () => { describe('RECEIVE_VULNERABILITIES_COUNT_ERROR', () => {
it('should set `isLoadingVulnerabilitiesCount` to `false`', () => { it('should set `isLoadingVulnerabilitiesCount` to `false`', () => {
const state = createState();
mutations[types.RECEIVE_VULNERABILITIES_COUNT_ERROR](state); mutations[types.RECEIVE_VULNERABILITIES_COUNT_ERROR](state);
expect(state.isLoadingVulnerabilitiesCount).toBeFalsy(); expect(state.isLoadingVulnerabilitiesCount).toBeFalsy();
...@@ -145,7 +139,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -145,7 +139,6 @@ describe('vulnerabilities module mutations', () => {
describe('SET_VULNERABILITIES_HISTORY_ENDPOINT', () => { describe('SET_VULNERABILITIES_HISTORY_ENDPOINT', () => {
it('should set `vulnerabilitiesHistoryEndpoint` to `fakepath.json`', () => { it('should set `vulnerabilitiesHistoryEndpoint` to `fakepath.json`', () => {
const state = createState();
const endpoint = 'fakepath.json'; const endpoint = 'fakepath.json';
mutations[types.SET_VULNERABILITIES_HISTORY_ENDPOINT](state, endpoint); mutations[types.SET_VULNERABILITIES_HISTORY_ENDPOINT](state, endpoint);
...@@ -155,13 +148,8 @@ describe('vulnerabilities module mutations', () => { ...@@ -155,13 +148,8 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('REQUEST_VULNERABILITIES_HISTORY', () => { describe('REQUEST_VULNERABILITIES_HISTORY', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = { state.errorLoadingVulnerabilitiesHistory = true;
...createState(),
errorLoadingVulnerabilitiesHistory: true,
};
mutations[types.REQUEST_VULNERABILITIES_HISTORY](state); mutations[types.REQUEST_VULNERABILITIES_HISTORY](state);
}); });
...@@ -176,11 +164,9 @@ describe('vulnerabilities module mutations', () => { ...@@ -176,11 +164,9 @@ describe('vulnerabilities module mutations', () => {
describe('RECEIVE_VULNERABILITIES_HISTORY_SUCCESS', () => { describe('RECEIVE_VULNERABILITIES_HISTORY_SUCCESS', () => {
let payload; let payload;
let state;
beforeEach(() => { beforeEach(() => {
payload = mockData; payload = mockData;
state = createState();
mutations[types.RECEIVE_VULNERABILITIES_HISTORY_SUCCESS](state, payload); mutations[types.RECEIVE_VULNERABILITIES_HISTORY_SUCCESS](state, payload);
}); });
...@@ -195,8 +181,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -195,8 +181,6 @@ describe('vulnerabilities module mutations', () => {
describe('RECEIVE_VULNERABILITIES_HISTORY_ERROR', () => { describe('RECEIVE_VULNERABILITIES_HISTORY_ERROR', () => {
it('should set `isLoadingVulnerabilitiesHistory` to `false`', () => { it('should set `isLoadingVulnerabilitiesHistory` to `false`', () => {
const state = createState();
mutations[types.RECEIVE_VULNERABILITIES_HISTORY_ERROR](state); mutations[types.RECEIVE_VULNERABILITIES_HISTORY_ERROR](state);
expect(state.isLoadingVulnerabilitiesHistory).toBeFalsy(); expect(state.isLoadingVulnerabilitiesHistory).toBeFalsy();
...@@ -204,12 +188,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -204,12 +188,6 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('SET_VULNERABILITIES_HISTORY_DAY_RANGE', () => { describe('SET_VULNERABILITIES_HISTORY_DAY_RANGE', () => {
let state;
beforeEach(() => {
state = createState();
});
it('should set the vulnerabilitiesHistoryDayRange to number of days', () => { it('should set the vulnerabilitiesHistoryDayRange to number of days', () => {
mutations[types.SET_VULNERABILITIES_HISTORY_DAY_RANGE](state, DAYS.THIRTY); mutations[types.SET_VULNERABILITIES_HISTORY_DAY_RANGE](state, DAYS.THIRTY);
...@@ -233,10 +211,8 @@ describe('vulnerabilities module mutations', () => { ...@@ -233,10 +211,8 @@ describe('vulnerabilities module mutations', () => {
describe('with all the data', () => { describe('with all the data', () => {
const vulnerability = mockData[0]; const vulnerability = mockData[0];
let payload; let payload;
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
payload = { vulnerability }; payload = { vulnerability };
mutations[types.SET_MODAL_DATA](state, payload); mutations[types.SET_MODAL_DATA](state, payload);
}); });
...@@ -303,12 +279,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -303,12 +279,6 @@ describe('vulnerabilities module mutations', () => {
describe('with irregular data', () => { describe('with irregular data', () => {
const vulnerability = mockData[0]; const vulnerability = mockData[0];
let state;
beforeEach(() => {
state = createState();
});
it('should set isDismissed when the vulnerabilitiy is dismissed', () => { it('should set isDismissed when the vulnerabilitiy is dismissed', () => {
const payload = { const payload = {
vulnerability: { ...vulnerability, dismissal_feedback: 'I am dismissed' }, vulnerability: { ...vulnerability, dismissal_feedback: 'I am dismissed' },
...@@ -359,14 +329,18 @@ describe('vulnerabilities module mutations', () => { ...@@ -359,14 +329,18 @@ describe('vulnerabilities module mutations', () => {
expect(state.modal.data.instances.value).toEqual(null); expect(state.modal.data.instances.value).toEqual(null);
}); });
it('should nullify the file value', () => {
const payload = { vulnerability: { ...vulnerability, location: {} } };
mutations[types.SET_MODAL_DATA](state, payload);
expect(state.modal.data.file.value).toEqual(null);
});
}); });
}); });
describe('REQUEST_CREATE_ISSUE', () => { describe('REQUEST_CREATE_ISSUE', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.REQUEST_CREATE_ISSUE](state); mutations[types.REQUEST_CREATE_ISSUE](state);
}); });
...@@ -385,7 +359,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -385,7 +359,6 @@ describe('vulnerabilities module mutations', () => {
describe('RECEIVE_CREATE_ISSUE_SUCCESS', () => { describe('RECEIVE_CREATE_ISSUE_SUCCESS', () => {
it('should fire the visitUrl function on the issue URL', () => { it('should fire the visitUrl function on the issue URL', () => {
const state = createState();
const payload = { issue_url: 'fakepath.html' }; const payload = { issue_url: 'fakepath.html' };
const visitUrl = spyOnDependency(mutations, 'visitUrl'); const visitUrl = spyOnDependency(mutations, 'visitUrl');
mutations[types.RECEIVE_CREATE_ISSUE_SUCCESS](state, payload); mutations[types.RECEIVE_CREATE_ISSUE_SUCCESS](state, payload);
...@@ -395,10 +368,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -395,10 +368,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_CREATE_ISSUE_ERROR', () => { describe('RECEIVE_CREATE_ISSUE_ERROR', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.RECEIVE_CREATE_ISSUE_ERROR](state); mutations[types.RECEIVE_CREATE_ISSUE_ERROR](state);
}); });
...@@ -416,10 +386,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -416,10 +386,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('REQUEST_CREATE_MERGE_REQUEST', () => { describe('REQUEST_CREATE_MERGE_REQUEST', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.REQUEST_CREATE_MERGE_REQUEST](state); mutations[types.REQUEST_CREATE_MERGE_REQUEST](state);
}); });
...@@ -438,7 +405,6 @@ describe('vulnerabilities module mutations', () => { ...@@ -438,7 +405,6 @@ describe('vulnerabilities module mutations', () => {
describe('RECEIVE_CREATE_MERGE_REQUEST_SUCCESS', () => { describe('RECEIVE_CREATE_MERGE_REQUEST_SUCCESS', () => {
it('should fire the visitUrl function on the merge request URL', () => { it('should fire the visitUrl function on the merge request URL', () => {
const state = createState();
const payload = { merge_request_path: 'fakepath.html' }; const payload = { merge_request_path: 'fakepath.html' };
const visitUrl = spyOnDependency(mutations, 'visitUrl'); const visitUrl = spyOnDependency(mutations, 'visitUrl');
mutations[types.RECEIVE_CREATE_MERGE_REQUEST_SUCCESS](state, payload); mutations[types.RECEIVE_CREATE_MERGE_REQUEST_SUCCESS](state, payload);
...@@ -448,10 +414,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -448,10 +414,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_CREATE_MERGE_REQUEST_ERROR', () => { describe('RECEIVE_CREATE_MERGE_REQUEST_ERROR', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.RECEIVE_CREATE_MERGE_REQUEST_ERROR](state); mutations[types.RECEIVE_CREATE_MERGE_REQUEST_ERROR](state);
}); });
...@@ -469,10 +432,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -469,10 +432,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('REQUEST_DISMISS_VULNERABILITY', () => { describe('REQUEST_DISMISS_VULNERABILITY', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.REQUEST_DISMISS_VULNERABILITY](state); mutations[types.REQUEST_DISMISS_VULNERABILITY](state);
}); });
...@@ -490,17 +450,15 @@ describe('vulnerabilities module mutations', () => { ...@@ -490,17 +450,15 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_DISMISS_VULNERABILITY_SUCCESS', () => { describe('RECEIVE_DISMISS_VULNERABILITY_SUCCESS', () => {
let state;
let payload; let payload;
let vulnerability; let vulnerability;
let data; let data;
beforeEach(() => { beforeEach(() => {
state = createState();
state.vulnerabilities = mockData; state.vulnerabilities = mockData;
[vulnerability] = mockData; [vulnerability] = mockData;
data = { name: 'dismissal feedback' }; data = { name: 'dismissal feedback' };
payload = { id: vulnerability.id, data }; payload = { vulnerability, data };
mutations[types.RECEIVE_DISMISS_VULNERABILITY_SUCCESS](state, payload); mutations[types.RECEIVE_DISMISS_VULNERABILITY_SUCCESS](state, payload);
}); });
...@@ -522,10 +480,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -522,10 +480,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_DISMISS_VULNERABILITY_ERROR', () => { describe('RECEIVE_DISMISS_VULNERABILITY_ERROR', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.RECEIVE_DISMISS_VULNERABILITY_ERROR](state); mutations[types.RECEIVE_DISMISS_VULNERABILITY_ERROR](state);
}); });
...@@ -543,10 +498,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -543,10 +498,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('REQUEST_DELETE_DISMISSAL_COMMENT', () => { describe('REQUEST_DELETE_DISMISSAL_COMMENT', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.REQUEST_DELETE_DISMISSAL_COMMENT](state); mutations[types.REQUEST_DELETE_DISMISSAL_COMMENT](state);
}); });
...@@ -564,13 +516,11 @@ describe('vulnerabilities module mutations', () => { ...@@ -564,13 +516,11 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_DELETE_DISMISSAL_COMMENT_SUCCESS', () => { describe('RECEIVE_DELETE_DISMISSAL_COMMENT_SUCCESS', () => {
let state;
let payload; let payload;
let vulnerability; let vulnerability;
let data; let data;
beforeEach(() => { beforeEach(() => {
state = createState();
state.vulnerabilities = mockData; state.vulnerabilities = mockData;
[vulnerability] = mockData; [vulnerability] = mockData;
data = { name: '' }; data = { name: '' };
...@@ -596,10 +546,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -596,10 +546,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_DELETE_DISMISSAL_COMMENT_ERROR', () => { describe('RECEIVE_DELETE_DISMISSAL_COMMENT_ERROR', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.RECEIVE_DELETE_DISMISSAL_COMMENT_ERROR](state); mutations[types.RECEIVE_DELETE_DISMISSAL_COMMENT_ERROR](state);
}); });
...@@ -617,10 +564,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -617,10 +564,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe(types.SHOW_DISMISSAL_DELETE_BUTTONS, () => { describe(types.SHOW_DISMISSAL_DELETE_BUTTONS, () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.SHOW_DISMISSAL_DELETE_BUTTONS](state); mutations[types.SHOW_DISMISSAL_DELETE_BUTTONS](state);
}); });
...@@ -630,10 +574,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -630,10 +574,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe(types.HIDE_DISMISSAL_DELETE_BUTTONS, () => { describe(types.HIDE_DISMISSAL_DELETE_BUTTONS, () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.HIDE_DISMISSAL_DELETE_BUTTONS](state); mutations[types.HIDE_DISMISSAL_DELETE_BUTTONS](state);
}); });
...@@ -643,10 +584,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -643,10 +584,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('REQUEST_ADD_DISMISSAL_COMMENT', () => { describe('REQUEST_ADD_DISMISSAL_COMMENT', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.REQUEST_ADD_DISMISSAL_COMMENT](state); mutations[types.REQUEST_ADD_DISMISSAL_COMMENT](state);
}); });
...@@ -664,17 +602,15 @@ describe('vulnerabilities module mutations', () => { ...@@ -664,17 +602,15 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS', () => { describe('RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS', () => {
let state;
let payload; let payload;
let vulnerability; let vulnerability;
let data; let data;
beforeEach(() => { beforeEach(() => {
state = createState();
state.vulnerabilities = mockData; state.vulnerabilities = mockData;
[vulnerability] = mockData; [vulnerability] = mockData;
data = { name: 'dismissal feedback' }; data = { name: 'dismissal feedback' };
payload = { id: vulnerability.id, data }; payload = { vulnerability, data };
mutations[types.RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS](state, payload); mutations[types.RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS](state, payload);
}); });
...@@ -696,10 +632,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -696,10 +632,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_ADD_DISMISSAL_COMMENT_ERROR', () => { describe('RECEIVE_ADD_DISMISSAL_COMMENT_ERROR', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.RECEIVE_ADD_DISMISSAL_COMMENT_ERROR](state); mutations[types.RECEIVE_ADD_DISMISSAL_COMMENT_ERROR](state);
}); });
...@@ -717,10 +650,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -717,10 +650,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('REQUEST_REVERT_DISMISSAL', () => { describe('REQUEST_REVERT_DISMISSAL', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.REQUEST_REVERT_DISMISSAL](state); mutations[types.REQUEST_REVERT_DISMISSAL](state);
}); });
...@@ -738,15 +668,13 @@ describe('vulnerabilities module mutations', () => { ...@@ -738,15 +668,13 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_REVERT_DISMISSAL_SUCCESS', () => { describe('RECEIVE_REVERT_DISMISSAL_SUCCESS', () => {
let state;
let payload; let payload;
let vulnerability; let vulnerability;
beforeEach(() => { beforeEach(() => {
state = createState();
state.vulnerabilities = mockData; state.vulnerabilities = mockData;
[vulnerability] = mockData; [vulnerability] = mockData;
payload = { id: vulnerability.id }; payload = { vulnerability };
mutations[types.RECEIVE_REVERT_DISMISSAL_SUCCESS](state, payload); mutations[types.RECEIVE_REVERT_DISMISSAL_SUCCESS](state, payload);
}); });
...@@ -768,10 +696,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -768,10 +696,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('RECEIVE_REVERT_DISMISSAL_ERROR', () => { describe('RECEIVE_REVERT_DISMISSAL_ERROR', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.RECEIVE_REVERT_DISMISSAL_ERROR](state); mutations[types.RECEIVE_REVERT_DISMISSAL_ERROR](state);
}); });
...@@ -789,10 +714,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -789,10 +714,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('OPEN_DISMISSAL_COMMENT_BOX', () => { describe('OPEN_DISMISSAL_COMMENT_BOX', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.OPEN_DISMISSAL_COMMENT_BOX](state); mutations[types.OPEN_DISMISSAL_COMMENT_BOX](state);
}); });
...@@ -802,10 +724,7 @@ describe('vulnerabilities module mutations', () => { ...@@ -802,10 +724,7 @@ describe('vulnerabilities module mutations', () => {
}); });
describe('CLOSE_DISMISSAL_COMMENT_BOX', () => { describe('CLOSE_DISMISSAL_COMMENT_BOX', () => {
let state;
beforeEach(() => { beforeEach(() => {
state = createState();
mutations[types.CLOSE_DISMISSAL_COMMENT_BOX](state); mutations[types.CLOSE_DISMISSAL_COMMENT_BOX](state);
}); });
......
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