Commit 679e3061 authored by Vitaly Slobodin's avatar Vitaly Slobodin

Merge branch '287761-remove-unused-vulnerabilities-history-endpoint' into 'master'

Remove unused code for vulnerability chart on pipeline security tab

See merge request gitlab-org/gitlab!48422
parents 74355ad5 375c56a6
......@@ -11,10 +11,9 @@ import {
} from '~/lib/utils/datetime_utility';
import { formattedChangeInPercent } from '~/lib/utils/number_utils';
import ChartButtons from './vulnerability_chart_buttons.vue';
import { SEVERITY_LEVELS } from '../store/constants';
import { SEVERITY_LEVELS, DAYS } from '../store/constants';
const ISO_DATE = 'isoDate';
const DAYS = { thirty: 30, sixty: 60, ninety: 90 };
export default {
components: {
......
......@@ -4,7 +4,6 @@ import IssueModal from 'ee/vue_shared/security_reports/components/modal.vue';
import Filters from './filters.vue';
import SecurityDashboardLayout from './security_dashboard_layout.vue';
import SecurityDashboardTable from './security_dashboard_table.vue';
import VulnerabilityChart from './vulnerability_chart.vue';
import FuzzingArtifactsDownload from './fuzzing_artifacts_download.vue';
import LoadingError from './loading_error.vue';
......@@ -14,7 +13,6 @@ export default {
IssueModal,
SecurityDashboardLayout,
SecurityDashboardTable,
VulnerabilityChart,
FuzzingArtifactsDownload,
LoadingError,
},
......@@ -23,11 +21,6 @@ export default {
type: String,
required: true,
},
vulnerabilitiesHistoryEndpoint: {
type: String,
required: false,
default: '',
},
pipelineId: {
type: Number,
required: false,
......@@ -67,19 +60,11 @@ export default {
vulnerability() {
return this.modal.vulnerability;
},
shouldShowAside() {
return this.shouldShowChart;
},
shouldShowChart() {
return Boolean(this.vulnerabilitiesHistoryEndpoint);
},
},
created() {
this.setPipelineId(this.pipelineId);
this.setVulnerabilitiesEndpoint(this.vulnerabilitiesEndpoint);
this.setVulnerabilitiesHistoryEndpoint(this.vulnerabilitiesHistoryEndpoint);
this.fetchVulnerabilities({ ...this.filters, page: this.pageInfo.page });
this.fetchVulnerabilitiesHistory(this.filters);
this.fetchPipelineJobs();
},
methods: {
......@@ -91,11 +76,9 @@ export default {
'createMergeRequest',
'dismissVulnerability',
'fetchVulnerabilities',
'fetchVulnerabilitiesHistory',
'openDismissalCommentBox',
'setPipelineId',
'setVulnerabilitiesEndpoint',
'setVulnerabilitiesHistoryEndpoint',
'showDismissalDeleteButtons',
'hideDismissalDeleteButtons',
'undoDismiss',
......@@ -133,10 +116,6 @@ export default {
<slot name="empty-state"></slot>
</template>
</security-dashboard-table>
<template v-if="shouldShowAside" #aside>
<vulnerability-chart v-if="shouldShowChart" class="mb-3" />
</template>
</security-dashboard-layout>
<issue-modal
......
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
import dateFormat from 'dateformat';
import { GlTooltipDirective, GlTable } from '@gitlab/ui';
import { GlSparklineChart } from '@gitlab/ui/dist/charts';
import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_badge.vue';
import { s__, sprintf } from '~/locale';
import { firstAndLastY } from '~/lib/utils/chart_utils';
import { formattedChangeInPercent } from '~/lib/utils/number_utils';
import { differenceInMilliseconds, millisecondsPerDay } from '~/lib/utils/datetime_utility';
import ChartButtons from './vulnerability_chart_buttons.vue';
import { DAYS } from '../store/modules/vulnerabilities/constants';
import { SEVERITY_LEVELS } from '../store/constants';
export default {
name: 'VulnerabilityChart',
components: {
ChartButtons,
GlSparklineChart,
GlTable,
SeverityBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
},
DAYS,
fields: [
{ key: 'severityLevel', label: s__('VulnerabilityChart|Severity'), tdClass: 'border-0' },
{ key: 'chartData', label: '', tdClass: 'border-0 w-100' },
{ key: 'changeInPercent', label: '%', thClass: 'text-right', tdClass: 'border-0 text-right' },
{
key: 'currentVulnerabilitiesCount',
label: '#',
thClass: 'text-right',
tdClass: 'border-0 text-right',
},
],
severityLevels: [
SEVERITY_LEVELS.critical,
SEVERITY_LEVELS.high,
SEVERITY_LEVELS.medium,
SEVERITY_LEVELS.low,
],
computed: {
...mapState('vulnerabilities', [
'vulnerabilitiesHistory',
'vulnerabilitiesHistoryDayRange',
'vulnerabilitiesHistoryMaxDayInterval',
]),
...mapGetters('vulnerabilities', ['getFilteredVulnerabilitiesHistory']),
charts() {
const { severityLevels } = this.$options;
return severityLevels.map(severityLevel => {
const history = this.getFilteredVulnerabilitiesHistory(severityLevel);
const chartData = history.length ? history : this.emptyDataSet;
const [pastVulnerabilitiesCount, currentVulnerabilitiesCount] = firstAndLastY(chartData);
const changeInPercent = formattedChangeInPercent(
pastVulnerabilitiesCount,
currentVulnerabilitiesCount,
);
return {
severityLevel,
chartData,
currentVulnerabilitiesCount,
changeInPercent,
};
});
},
startDate() {
return differenceInMilliseconds(millisecondsPerDay * this.vulnerabilitiesHistoryDayRange);
},
dateInfo() {
const formattedStartDate = dateFormat(this.startDate, 'mmmm dS');
return sprintf(s__('VulnerabilityChart|%{formattedStartDate} to today'), {
formattedStartDate,
});
},
days() {
const { $options } = this;
return [$options.DAYS.THIRTY, $options.DAYS.SIXTY, $options.DAYS.NINETY];
},
emptyDataSet() {
const format = 'isoDate';
const formattedStartDate = dateFormat(this.startDate, format);
const formattedEndDate = dateFormat(Date.now(), format);
return [[formattedStartDate, 0], [formattedEndDate, 0]];
},
},
methods: {
...mapActions('vulnerabilities', ['setVulnerabilitiesHistoryDayRange']),
},
};
</script>
<template>
<section class="border rounded p-0">
<div class="p-3">
<header id="vulnerability-chart-header">
<h4 class="my-0">
{{ __('Vulnerabilities over time') }}
</h4>
<p ref="timeInfo" class="text-secondary mt-0 js-vulnerabilities-chart-time-info">
{{ dateInfo }}
</p>
</header>
<chart-buttons
:days="days"
:active-day="vulnerabilitiesHistoryDayRange"
@click="setVulnerabilitiesHistoryDayRange"
/>
</div>
<gl-table
:fields="$options.fields"
:items="charts"
:borderless="true"
thead-class="thead-white"
class="js-vulnerabilities-chart-severity-level-breakdown mb-2"
>
<template #head(changeInPercent)="{ label }">
<span v-gl-tooltip :title="__('Difference between start date and now')">{{ label }}</span>
</template>
<template #head(currentVulnerabilitiesCount)="{ label }">
<span v-gl-tooltip :title="__('Current vulnerabilities count')">{{ label }}</span>
</template>
<template #cell(severityLevel)="{ value }">
<severity-badge :ref="`severityBadge${value}`" :severity="value" />
</template>
<template #cell(chartData)="{ item }">
<div class="position-relative h-32-px">
<gl-sparkline-chart
:ref="`sparklineChart${item.severityLevel}`"
:height="32"
:data="item.chartData"
:tooltip-label="__('Vulnerabilities')"
:show-last-y-value="false"
class="position-absolute w-100 position-top-0 position-left-0"
/>
</div>
</template>
<template #cell(changeInPercent)="{ value }">
<span ref="changeInPercent">{{ value }}</span>
</template>
<template #cell(currentVulnerabilitiesCount)="{ value }">
<span ref="currentVulnerabilitiesCount">{{ value }}</span>
</template>
</gl-table>
</section>
</template>
......@@ -36,3 +36,5 @@ export const UNSCANNED_PROJECTS_DATE_RANGES = [
];
export const PRIMARY_IDENTIFIER_TYPE = 'cve';
export const DAYS = { thirty: 30, sixty: 60, ninety: 90 };
......@@ -477,46 +477,6 @@ export const receiveCreateMergeRequestError = ({ commit }, { flashError }) => {
}
};
export const setVulnerabilitiesHistoryEndpoint = ({ commit }, endpoint) => {
commit(types.SET_VULNERABILITIES_HISTORY_ENDPOINT, endpoint);
};
export const fetchVulnerabilitiesHistory = ({ state, dispatch }, params = {}) => {
if (!state.vulnerabilitiesHistoryEndpoint) {
return;
}
dispatch('requestVulnerabilitiesHistory');
axios({
method: 'GET',
url: state.vulnerabilitiesHistoryEndpoint,
params,
})
.then(response => {
const { data } = response;
dispatch('receiveVulnerabilitiesHistorySuccess', { data });
})
.catch(() => {
dispatch('receiveVulnerabilitiesHistoryError');
});
};
export const setVulnerabilitiesHistoryDayRange = ({ commit }, days) => {
commit(types.SET_VULNERABILITIES_HISTORY_DAY_RANGE, days);
};
export const requestVulnerabilitiesHistory = ({ commit }) => {
commit(types.REQUEST_VULNERABILITIES_HISTORY);
};
export const receiveVulnerabilitiesHistorySuccess = ({ commit }, { data }) => {
commit(types.RECEIVE_VULNERABILITIES_HISTORY_SUCCESS, data);
};
export const receiveVulnerabilitiesHistoryError = ({ commit }) => {
commit(types.RECEIVE_VULNERABILITIES_HISTORY_ERROR);
};
export const openDismissalCommentBox = ({ commit }) => {
commit(types.OPEN_DISMISSAL_COMMENT_BOX);
};
......
......@@ -10,12 +10,6 @@ export {
SEVERITIES,
} from '~/vulnerabilities/constants';
export const DAYS = {
THIRTY: 30,
SIXTY: 60,
NINETY: 90,
};
export const LOADING_VULNERABILITIES_ERROR_CODES = {
UNAUTHORIZED: httpStatusCodes.UNAUTHORIZED,
FORBIDDEN: httpStatusCodes.FORBIDDEN,
......
......@@ -13,29 +13,6 @@ export const loadingVulnerabilitiesFailedWithRecognizedErrorCode = state =>
state.loadingVulnerabilitiesErrorCode,
);
export const getVulnerabilityHistoryByName = state => name =>
state.vulnerabilitiesHistory[name.toLowerCase()];
export const getFilteredVulnerabilitiesHistory = (state, getters) => name => {
const history = getters.getVulnerabilityHistoryByName(name);
const days = state.vulnerabilitiesHistoryDayRange;
if (!history) {
return [];
}
const data = Object.entries(history);
const currentDate = new Date();
const startDate = new Date();
startDate.setDate(currentDate.getDate() - days);
return data.filter(date => {
const parsedDate = Date.parse(date[0]);
return parsedDate > startDate;
});
};
export const selectedVulnerabilitiesCount = state =>
Object.keys(state.selectedVulnerabilities).length;
......
......@@ -6,12 +6,6 @@ export const REQUEST_VULNERABILITIES = 'REQUEST_VULNERABILITIES';
export const RECEIVE_VULNERABILITIES_SUCCESS = 'RECEIVE_VULNERABILITIES_SUCCESS';
export const RECEIVE_VULNERABILITIES_ERROR = 'RECEIVE_VULNERABILITIES_ERROR';
export const SET_VULNERABILITIES_HISTORY_ENDPOINT = 'SET_VULNERABILITIES_HISTORY_ENDPOINT';
export const SET_VULNERABILITIES_HISTORY_DAY_RANGE = 'SET_VULNERABILITIES_HISTORY_DAY_RANGE';
export const REQUEST_VULNERABILITIES_HISTORY = 'REQUEST_VULNERABILITIES_HISTORY';
export const RECEIVE_VULNERABILITIES_HISTORY_SUCCESS = 'RECEIVE_VULNERABILITIES_HISTORY_SUCCESS';
export const RECEIVE_VULNERABILITIES_HISTORY_ERROR = 'RECEIVE_VULNERABILITIES_HISTORY_ERROR';
export const SET_MODAL_DATA = 'SET_MODAL_DATA';
export const REQUEST_CREATE_ISSUE = 'REQUEST_CREATE_ISSUE';
......
......@@ -2,7 +2,6 @@ import Vue from 'vue';
import { s__, __ } from '~/locale';
import { visitUrl } from '~/lib/utils/url_utility';
import * as types from './mutation_types';
import { DAYS } from './constants';
import { isSameVulnerability } from './utils';
export default {
......@@ -34,30 +33,6 @@ export default {
[types.SET_VULNERABILITIES_PAGE](state, payload) {
state.pageInfo = { ...state.pageInfo, page: payload };
},
[types.SET_VULNERABILITIES_HISTORY_ENDPOINT](state, payload) {
state.vulnerabilitiesHistoryEndpoint = payload;
},
[types.SET_VULNERABILITIES_HISTORY_DAY_RANGE](state, days) {
state.vulnerabilitiesHistoryDayRange = days;
if (days <= DAYS.THIRTY) {
state.vulnerabilitiesHistoryMaxDayInterval = 7;
} else if (days > DAYS.SIXTY) {
state.vulnerabilitiesHistoryMaxDayInterval = 14;
}
},
[types.REQUEST_VULNERABILITIES_HISTORY](state) {
state.isLoadingVulnerabilitiesHistory = true;
state.errorLoadingVulnerabilitiesHistory = false;
},
[types.RECEIVE_VULNERABILITIES_HISTORY_SUCCESS](state, payload) {
state.isLoadingVulnerabilitiesHistory = false;
state.vulnerabilitiesHistory = payload;
},
[types.RECEIVE_VULNERABILITIES_HISTORY_ERROR](state) {
state.isLoadingVulnerabilitiesHistory = false;
state.errorLoadingVulnerabilitiesHistory = true;
},
[types.SET_MODAL_DATA](state, payload) {
const { vulnerability } = payload;
......
......@@ -5,14 +5,8 @@ export default () => ({
vulnerabilities: [],
errorLoadingVulnerabilitiesCount: false,
vulnerabilitiesCount: {},
isLoadingVulnerabilitiesHistory: true,
errorLoadingVulnerabilitiesHistory: false,
vulnerabilitiesHistory: {},
vulnerabilitiesHistoryDayRange: 90,
vulnerabilitiesHistoryMaxDayInterval: 7,
pageInfo: {},
pipelineId: null,
vulnerabilitiesHistoryEndpoint: null,
vulnerabilitiesEndpoint: null,
activeVulnerability: null,
sourceBranch: null,
......
......@@ -5,7 +5,6 @@ const refreshTypes = [`filters/${SET_FILTER}`, `filters/${SET_HIDE_DISMISSED}`];
export default store => {
const refreshVulnerabilities = payload => {
store.dispatch('vulnerabilities/fetchVulnerabilities', payload);
store.dispatch('vulnerabilities/fetchVulnerabilitiesHistory', payload);
};
store.subscribe(({ type }) => {
......
......@@ -6,7 +6,6 @@ import LoadingError from 'ee/security_dashboard/components/loading_error.vue';
import SecurityDashboardLayout from 'ee/security_dashboard/components/security_dashboard_layout.vue';
import SecurityDashboardTable from 'ee/security_dashboard/components/security_dashboard_table.vue';
import SecurityDashboard from 'ee/security_dashboard/components/security_dashboard_vuex.vue';
import VulnerabilityChart from 'ee/security_dashboard/components/vulnerability_chart.vue';
import createStore from 'ee/security_dashboard/store';
import IssueModal from 'ee/vue_shared/security_reports/components/modal.vue';
......@@ -15,7 +14,6 @@ import axios from '~/lib/utils/axios_utils';
const pipelineId = 123;
const vulnerabilitiesEndpoint = `${TEST_HOST}/vulnerabilities`;
const vulnerabilitiesHistoryEndpoint = `${TEST_HOST}/vulnerabilities_history`;
jest.mock('~/lib/utils/url_utility', () => ({
getParameterValues: jest.fn().mockReturnValue([]),
......@@ -41,7 +39,6 @@ describe('Security Dashboard component', () => {
propsData: {
dashboardDocumentation: '',
vulnerabilitiesEndpoint,
vulnerabilitiesHistoryEndpoint,
pipelineId,
...props,
},
......@@ -75,10 +72,6 @@ describe('Security Dashboard component', () => {
expect(wrapper.find(SecurityDashboardTable).exists()).toBe(true);
});
it('renders the vulnerability chart', () => {
expect(wrapper.find(VulnerabilityChart).exists()).toBe(true);
});
it('sets the pipeline id', () => {
expect(setPipelineIdSpy).toHaveBeenCalledWith(pipelineId);
});
......@@ -143,21 +136,6 @@ describe('Security Dashboard component', () => {
);
});
describe.each`
endpointProp | Component
${'vulnerabilitiesHistoryEndpoint'} | ${VulnerabilityChart}
`('with an empty $endpointProp', ({ endpointProp, Component }) => {
beforeEach(() => {
createComponent({
[endpointProp]: '',
});
});
it(`does not show the ${Component.name}`, () => {
expect(wrapper.find(Component).exists()).toBe(false);
});
});
describe('on error', () => {
beforeEach(() => {
createComponent();
......
import { shallowMount, mount, createLocalVue } from '@vue/test-utils';
import Vue from 'vue';
import component from 'ee/security_dashboard/components/vulnerability_chart_buttons.vue';
import { DAYS } from 'ee/security_dashboard/store/modules/vulnerabilities/constants';
import { DAYS } from 'ee/security_dashboard/store/constants';
const localVue = createLocalVue();
describe('Vulnerability Chart Buttons', () => {
let wrapper;
const Component = Vue.extend(component);
const days = [DAYS.THIRTY, DAYS.SIXTY, DAYS.NINETY];
const days = Object.values(DAYS);
const createWrapper = (props = {}, mountfn = shallowMount) => {
wrapper = mountfn(localVue.extend(Component), {
......@@ -23,7 +23,7 @@ describe('Vulnerability Chart Buttons', () => {
describe('when rendering the buttons', () => {
it('should render with 90 days selected', () => {
const activeDay = DAYS.NINETY;
const activeDay = DAYS.ninety;
createWrapper({ activeDay });
const activeButton = wrapper.find('[data-days="90"].active');
......@@ -32,7 +32,7 @@ describe('Vulnerability Chart Buttons', () => {
});
it('should render with 60 days selected', () => {
const activeDay = DAYS.SIXTY;
const activeDay = DAYS.sixty;
createWrapper({ activeDay });
const activeButton = wrapper.find('[data-days="60"].active');
......@@ -41,7 +41,7 @@ describe('Vulnerability Chart Buttons', () => {
});
it('should render with 30 days selected', () => {
const activeDay = DAYS.THIRTY;
const activeDay = DAYS.thirty;
createWrapper({ activeDay });
const activeButton = wrapper.find('[data-days="30"].active');
......@@ -51,7 +51,7 @@ describe('Vulnerability Chart Buttons', () => {
});
describe('when clicking the button', () => {
const activeDay = DAYS.THIRTY;
const activeDay = DAYS.thirty;
beforeEach(() => {
createWrapper({ activeDay }, mount);
......@@ -59,15 +59,15 @@ describe('Vulnerability Chart Buttons', () => {
it('should call the clickHandler', () => {
jest.spyOn(wrapper.vm, 'clickHandler');
wrapper.find('[data-days="30"].active').trigger('click', DAYS.THIRTY);
wrapper.find('[data-days="30"].active').trigger('click', DAYS.thirty);
expect(wrapper.vm.clickHandler).toHaveBeenCalledWith(DAYS.THIRTY);
expect(wrapper.vm.clickHandler).toHaveBeenCalledWith(DAYS.thirty);
});
it('should emit a click event', () => {
wrapper.find('[data-days="30"].active').trigger('click', DAYS.THIRTY);
wrapper.find('[data-days="30"].active').trigger('click', DAYS.thirty);
expect(wrapper.emitted().click[0]).toEqual([DAYS.THIRTY]);
expect(wrapper.emitted().click[0]).toEqual([DAYS.thirty]);
});
});
});
import { GlSparklineChart } from '@gitlab/ui/dist/charts';
import { mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import Chart from 'ee/security_dashboard/components/vulnerability_chart.vue';
import ChartButtons from 'ee/security_dashboard/components/vulnerability_chart_buttons.vue';
import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_badge.vue';
import stubChildren from 'helpers/stub_children';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('Vulnerability Chart component', () => {
let actions;
let getters;
let state;
let store;
let wrapper;
const findTimeInfo = () => wrapper.find({ ref: 'timeInfo' });
const findSeverityBadgeForLevel = severityLevel =>
wrapper.find(SeverityBadge, { ref: `severityBadge${severityLevel}` });
const findSparklineChartForLevel = severityLevel =>
wrapper.find(GlSparklineChart, { ref: `sparklineChart${severityLevel}` });
const findChangeInPercent = () => wrapper.find({ ref: 'changeInPercent' });
const findCurrentVulnerabilitiesCount = () =>
wrapper.find({ ref: 'currentVulnerabilitiesCount' });
const factory = ({ vulnerabilitiesCount = [], stubs = {} } = {}) => {
actions = {
setVulnerabilitiesHistoryDayRange: jest.fn(),
};
getters = {
getFilteredVulnerabilitiesHistory: () => () =>
vulnerabilitiesCount.map(c => ['some-date', c]),
getVulnerabilityHistoryByName: () => () => [],
};
state = {
vulnerabilitiesHistory: {},
vulnerabilitiesHistoryDayRange: 90,
vulnerabilitiesHistoryMaxDayInterval: 7,
};
store = new Vuex.Store({
modules: {
vulnerabilities: {
namespaced: true,
actions,
getters,
state,
},
},
});
wrapper = mount(Chart, {
localVue,
store,
stubs: {
...stubChildren(Chart),
...stubs,
},
});
};
afterEach(() => {
wrapper.destroy();
jest.restoreAllMocks();
});
describe('header', () => {
it.each`
mockDate | dayRange | expectedStartDate
${'2000-01-01T00:00:00Z'} | ${90} | ${'October 3rd'}
${'2000-01-01T00:00:00Z'} | ${60} | ${'November 2nd'}
${'2000-01-01T00:00:00Z'} | ${30} | ${'December 2nd'}
`(
'shows "$expectedStartDate" when the date range is set to "$dayRange" days',
({ mockDate, dayRange, expectedStartDate }) => {
jest.spyOn(global.Date, 'now').mockImplementation(() => new Date(mockDate));
factory();
store.state.vulnerabilities.vulnerabilitiesHistoryDayRange = dayRange;
return wrapper.vm.$nextTick().then(() => {
expect(findTimeInfo().text()).toContain(expectedStartDate);
});
},
);
});
describe('date range selectors', () => {
beforeEach(factory);
it('shows a set of buttons to select the supported day ranges', () => {
const supportedDayRanges = [30, 60, 90];
expect(wrapper.find(ChartButtons).props('days')).toEqual(supportedDayRanges);
});
it('dispatches "setVulnerabilitiesHistoryDayRange" when a day range is selected', () => {
const selectedDayRange = 30;
wrapper.find(ChartButtons).vm.$emit('click', selectedDayRange);
expect(actions.setVulnerabilitiesHistoryDayRange).toHaveBeenCalledTimes(1);
expect(actions.setVulnerabilitiesHistoryDayRange.mock.calls[0][1]).toBe(selectedDayRange);
});
});
describe('charts table', () => {
describe.each(['Critical', 'Medium', 'High', 'Low'])(
'for the given severity level "%s"',
severityLevel => {
beforeEach(() => {
factory({ stubs: { GlTable: false } });
});
it('shows a severity badge', () => {
expect(findSeverityBadgeForLevel(severityLevel).exists()).toBe(true);
});
it('shows a chart', () => {
expect(findSparklineChartForLevel(severityLevel).exists()).toBe(true);
});
},
);
it.each`
countPast | countCurrent | expectedOutput
${1} | ${2} | ${'+100%'}
${100} | ${1} | ${'-99%'}
${1} | ${1} | ${'+0%'}
${0} | ${1} | ${'-'}
`(
'shows "$expectedOutput" when the vulnerabilities changed from "$countPast" to "$countCurrent"',
({ countPast, countCurrent, expectedOutput }) => {
factory({
vulnerabilitiesCount: [countPast, countCurrent],
stubs: {
GlTable: false,
},
});
expect(findChangeInPercent().text()).toBe(expectedOutput);
},
);
it.each`
vulnerabilitiesCount | expectedOutput
${[1, 2, 3]} | ${'3'}
`('shows the current vulnerabilities count', ({ vulnerabilitiesCount, expectedOutput }) => {
factory({ vulnerabilitiesCount, stubs: { GlTable: false } });
expect(findCurrentVulnerabilitiesCount().text()).toBe(expectedOutput);
});
});
});
import MockAdapter from 'axios-mock-adapter';
import * as actions from 'ee/security_dashboard/store/modules/vulnerabilities/actions';
import { DAYS } from 'ee/security_dashboard/store/modules/vulnerabilities/constants';
import * as types from 'ee/security_dashboard/store/modules/vulnerabilities/mutation_types';
import initialState from 'ee/security_dashboard/store/modules/vulnerabilities/state';
import testAction from 'helpers/vuex_action_helper';
......@@ -10,7 +9,6 @@ import axios from '~/lib/utils/axios_utils';
import toast from '~/vue_shared/plugins/global_toast';
import mockDataVulnerabilities from './data/mock_data_vulnerabilities';
import mockDataVulnerabilitiesHistory from './data/mock_data_vulnerabilities_history.json';
const sourceBranch = 'feature-branch-1';
......@@ -34,38 +32,24 @@ describe('vulnerabilities count actions', () => {
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,
);
it('should commit the correct mutation', () => {
return testAction(actions.setPipelineId, pipelineId, state, [
{
type: types.SET_PIPELINE_ID,
payload: pipelineId,
},
]);
});
});
describe('setSourceBranch', () => {
it('should commit the correct mutation', done => {
testAction(
actions.setSourceBranch,
sourceBranch,
state,
[
{
type: types.SET_SOURCE_BRANCH,
payload: sourceBranch,
},
],
[],
done,
);
it('should commit the correct mutation', () => {
return testAction(actions.setSourceBranch, sourceBranch, state, [
{
type: types.SET_SOURCE_BRANCH,
payload: sourceBranch,
},
]);
});
});
});
......@@ -117,8 +101,8 @@ describe('vulnerabilities actions', () => {
.replyOnce(200, data, headers);
});
it('should dispatch the request and success actions', done => {
testAction(
it('should dispatch the request and success actions', () => {
return testAction(
actions.fetchVulnerabilities,
{},
state,
......@@ -130,12 +114,11 @@ describe('vulnerabilities actions', () => {
payload: { data, headers },
},
],
done,
);
});
it('should pass through the filters', done => {
testAction(
it('should pass through the filters', () => {
return testAction(
actions.fetchVulnerabilities,
params,
state,
......@@ -147,7 +130,6 @@ describe('vulnerabilities actions', () => {
payload: { data: filteredData, headers },
},
],
done,
);
});
});
......@@ -159,8 +141,8 @@ describe('vulnerabilities actions', () => {
mock.onGet(state.vulnerabilitiesEndpoint).replyOnce(errorCode, {});
});
it('should dispatch the request and error actions', done => {
testAction(
it('should dispatch the request and error actions', () => {
return testAction(
actions.fetchVulnerabilities,
{},
state,
......@@ -169,7 +151,6 @@ describe('vulnerabilities actions', () => {
{ type: 'requestVulnerabilities' },
{ type: 'receiveVulnerabilitiesError', payload: errorCode },
],
done,
);
});
});
......@@ -179,95 +160,64 @@ describe('vulnerabilities actions', () => {
state.vulnerabilitiesEndpoint = '';
});
it('should not do anything', done => {
testAction(actions.fetchVulnerabilities, {}, state, [], [], done);
it('should not do anything', () => {
return testAction(actions.fetchVulnerabilities, {}, state);
});
});
});
describe('receiveVulnerabilitiesSuccess', () => {
it('should commit the success mutation', done => {
testAction(
actions.receiveVulnerabilitiesSuccess,
{ headers, data },
state,
[
{
type: types.RECEIVE_VULNERABILITIES_SUCCESS,
payload: { pageInfo, vulnerabilities: data },
},
],
[],
done,
);
it('should commit the success mutation', () => {
return testAction(actions.receiveVulnerabilitiesSuccess, { headers, data }, state, [
{
type: types.RECEIVE_VULNERABILITIES_SUCCESS,
payload: { pageInfo, vulnerabilities: data },
},
]);
});
});
describe('receiveVulnerabilitiesError', () => {
it('should commit the error mutation', done => {
it('should commit the error mutation', () => {
const errorCode = 403;
testAction(
actions.receiveVulnerabilitiesError,
errorCode,
state,
[{ type: types.RECEIVE_VULNERABILITIES_ERROR, payload: errorCode }],
[],
done,
);
return testAction(actions.receiveVulnerabilitiesError, errorCode, state, [
{ type: types.RECEIVE_VULNERABILITIES_ERROR, payload: errorCode },
]);
});
});
describe('requestVulnerabilities', () => {
it('should commit the request mutation', done => {
testAction(
actions.requestVulnerabilities,
{},
state,
[{ type: types.REQUEST_VULNERABILITIES }],
[],
done,
);
it('should commit the request mutation', () => {
return testAction(actions.requestVulnerabilities, {}, state, [
{ type: types.REQUEST_VULNERABILITIES },
]);
});
});
describe('setVulnerabilitiesEndpoint', () => {
it('should commit the correct mutuation', done => {
it('should commit the correct mutuation', () => {
const endpoint = 'fakepath.json';
testAction(
actions.setVulnerabilitiesEndpoint,
endpoint,
state,
[
{
type: types.SET_VULNERABILITIES_ENDPOINT,
payload: endpoint,
},
],
[],
done,
);
return testAction(actions.setVulnerabilitiesEndpoint, endpoint, state, [
{
type: types.SET_VULNERABILITIES_ENDPOINT,
payload: endpoint,
},
]);
});
});
describe('setVulnerabilitiesPage', () => {
it('should commit the correct mutuation', done => {
it('should commit the correct mutuation', () => {
const page = 3;
testAction(
actions.setVulnerabilitiesPage,
page,
state,
[
{
type: types.SET_VULNERABILITIES_PAGE,
payload: page,
},
],
[],
done,
);
return testAction(actions.setVulnerabilitiesPage, page, state, [
{
type: types.SET_VULNERABILITIES_PAGE,
payload: page,
},
]);
});
});
});
......@@ -279,22 +229,15 @@ describe('openModal', () => {
state = initialState();
});
it('should commit the SET_MODAL_DATA mutation', done => {
it('should commit the SET_MODAL_DATA mutation', () => {
const vulnerability = mockDataVulnerabilities[0];
testAction(
actions.openModal,
{ vulnerability },
state,
[
{
type: types.SET_MODAL_DATA,
payload: { vulnerability },
},
],
[],
done,
);
return testAction(actions.openModal, { vulnerability }, state, [
{
type: types.SET_MODAL_DATA,
payload: { vulnerability },
},
]);
});
});
......@@ -352,8 +295,8 @@ describe('issue creation', () => {
.replyOnce(200, { data });
});
it('should dispatch the request and success actions', done => {
testAction(
it('should dispatch the request and success actions', () => {
return testAction(
actions.createIssue,
{ vulnerability },
{},
......@@ -365,7 +308,6 @@ describe('issue creation', () => {
payload: { data },
},
],
done,
);
});
});
......@@ -375,10 +317,10 @@ describe('issue creation', () => {
mock.onPost(vulnerability.create_vulnerability_feedback_issue_path).replyOnce(404, {});
});
it('should dispatch the request and error actions', done => {
it('should dispatch the request and error actions', () => {
const flashError = false;
testAction(
return testAction(
actions.createIssue,
{ vulnerability, flashError },
{},
......@@ -387,55 +329,37 @@ describe('issue creation', () => {
{ type: 'requestCreateIssue' },
{ type: 'receiveCreateIssueError', payload: { flashError } },
],
done,
);
});
});
});
describe('receiveCreateIssueSuccess', () => {
it('should commit the success mutation', done => {
it('should commit the success mutation', () => {
const data = mockDataVulnerabilities[0];
testAction(
actions.receiveCreateIssueSuccess,
{ data },
state,
[
{
type: types.RECEIVE_CREATE_ISSUE_SUCCESS,
payload: { data },
},
],
[],
done,
);
return testAction(actions.receiveCreateIssueSuccess, { data }, state, [
{
type: types.RECEIVE_CREATE_ISSUE_SUCCESS,
payload: { data },
},
]);
});
});
describe('receiveCreateIssueError', () => {
it('should commit the error mutation', done => {
testAction(
actions.receiveCreateIssueError,
{},
state,
[{ type: types.RECEIVE_CREATE_ISSUE_ERROR }],
[],
done,
);
it('should commit the error mutation', () => {
return testAction(actions.receiveCreateIssueError, {}, state, [
{ type: types.RECEIVE_CREATE_ISSUE_ERROR },
]);
});
});
describe('requestCreateIssue', () => {
it('should commit the request mutation', done => {
testAction(
actions.requestCreateIssue,
{},
state,
[{ type: types.REQUEST_CREATE_ISSUE }],
[],
done,
);
it('should commit the request mutation', () => {
return testAction(actions.requestCreateIssue, {}, state, [
{ type: types.REQUEST_CREATE_ISSUE },
]);
});
});
});
......@@ -467,8 +391,8 @@ describe('merge request creation', () => {
.replyOnce(200, { data });
});
it('should dispatch the request and success actions', done => {
testAction(
it('should dispatch the request and success actions', () => {
return testAction(
actions.createMergeRequest,
{ vulnerability },
{},
......@@ -480,7 +404,6 @@ describe('merge request creation', () => {
payload: { data },
},
],
done,
);
});
});
......@@ -490,10 +413,10 @@ describe('merge request creation', () => {
mock.onPost(vulnerability.vulnerability_feedback_merge_request_path).replyOnce(404, {});
});
it('should dispatch the request and error actions', done => {
it('should dispatch the request and error actions', () => {
const flashError = false;
testAction(
return testAction(
actions.createMergeRequest,
{ vulnerability, flashError },
{},
......@@ -502,55 +425,37 @@ describe('merge request creation', () => {
{ type: 'requestCreateMergeRequest' },
{ type: 'receiveCreateMergeRequestError', payload: { flashError } },
],
done,
);
});
});
});
describe('receiveCreateMergeRequestSuccess', () => {
it('should commit the success mutation', done => {
it('should commit the success mutation', () => {
const data = mockDataVulnerabilities[0];
testAction(
actions.receiveCreateMergeRequestSuccess,
{ data },
state,
[
{
type: types.RECEIVE_CREATE_MERGE_REQUEST_SUCCESS,
payload: { data },
},
],
[],
done,
);
return testAction(actions.receiveCreateMergeRequestSuccess, { data }, state, [
{
type: types.RECEIVE_CREATE_MERGE_REQUEST_SUCCESS,
payload: { data },
},
]);
});
});
describe('receiveCreateMergeRequestError', () => {
it('should commit the error mutation', done => {
testAction(
actions.receiveCreateMergeRequestError,
{},
state,
[{ type: types.RECEIVE_CREATE_MERGE_REQUEST_ERROR }],
[],
done,
);
it('should commit the error mutation', () => {
return testAction(actions.receiveCreateMergeRequestError, {}, state, [
{ type: types.RECEIVE_CREATE_MERGE_REQUEST_ERROR },
]);
});
});
describe('requestCreateMergeRequest', () => {
it('should commit the request mutation', done => {
testAction(
actions.requestCreateMergeRequest,
{},
state,
[{ type: types.REQUEST_CREATE_MERGE_REQUEST }],
[],
done,
);
it('should commit the request mutation', () => {
return testAction(actions.requestCreateMergeRequest, {}, state, [
{ type: types.REQUEST_CREATE_MERGE_REQUEST },
]);
});
});
});
......@@ -584,8 +489,8 @@ describe('vulnerability dismissal', () => {
.replyOnce(200, data);
});
it('should dispatch the request and success actions', done => {
testAction(
it('should dispatch the request and success actions', () => {
return testAction(
actions.dismissVulnerability,
{ vulnerability, comment },
{},
......@@ -598,17 +503,15 @@ describe('vulnerability dismissal', () => {
payload: { data, vulnerability },
},
],
done,
);
});
it('should show the dismissal toast message', done => {
it('should show the dismissal toast message', () => {
const checkToastMessage = () => {
expect(toast).toHaveBeenCalledTimes(1);
done();
};
testAction(
return testAction(
actions.dismissVulnerability,
{ vulnerability, comment },
{},
......@@ -631,10 +534,10 @@ describe('vulnerability dismissal', () => {
mock.onPost(vulnerability.create_vulnerability_feedback_dismissal_path).replyOnce(404, {});
});
it('should dispatch the request and error actions', done => {
it('should dispatch the request and error actions', () => {
const flashError = false;
testAction(
return testAction(
actions.dismissVulnerability,
{ vulnerability, flashError },
{},
......@@ -643,7 +546,6 @@ describe('vulnerability dismissal', () => {
{ type: 'requestDismissVulnerability' },
{ type: 'receiveDismissVulnerabilityError', payload: { flashError } },
],
done,
);
});
});
......@@ -661,17 +563,16 @@ describe('vulnerability dismissal', () => {
.replyOnce(200, data);
});
it('should show the dismissal toast message and refresh vulnerabilities', done => {
it('should show the dismissal toast message and refresh vulnerabilities', () => {
const checkToastMessage = () => {
const [message, options] = toast.mock.calls[0];
expect(toast).toHaveBeenCalledTimes(1);
expect(message).toContain('Turn off the hide dismissed toggle to view');
expect(Object.keys(options.action)).toHaveLength(2);
done();
};
testAction(
return testAction(
actions.dismissVulnerability,
{ vulnerability, comment },
state,
......@@ -693,7 +594,7 @@ describe('vulnerability dismissal', () => {
state.vulnerabilities = [mockDataVulnerabilities[0]];
state.pageInfo.page = 3;
testAction(
return testAction(
actions.dismissVulnerability,
{ vulnerability, comment },
state,
......@@ -713,48 +614,31 @@ describe('vulnerability dismissal', () => {
});
describe('receiveDismissVulnerabilitySuccess', () => {
it('should commit the success mutation', done => {
it('should commit the success mutation', () => {
const data = mockDataVulnerabilities[0];
testAction(
actions.receiveDismissVulnerabilitySuccess,
{ data },
state,
[
{
type: types.RECEIVE_DISMISS_VULNERABILITY_SUCCESS,
payload: { data },
},
],
[],
done,
);
return testAction(actions.receiveDismissVulnerabilitySuccess, { data }, state, [
{
type: types.RECEIVE_DISMISS_VULNERABILITY_SUCCESS,
payload: { data },
},
]);
});
});
describe('receiveDismissVulnerabilityError', () => {
it('should commit the error mutation', done => {
testAction(
actions.receiveDismissVulnerabilityError,
{},
state,
[{ type: types.RECEIVE_DISMISS_VULNERABILITY_ERROR }],
[],
done,
);
it('should commit the error mutation', () => {
return testAction(actions.receiveDismissVulnerabilityError, {}, state, [
{ type: types.RECEIVE_DISMISS_VULNERABILITY_ERROR },
]);
});
});
describe('requestDismissVulnerability', () => {
it('should commit the request mutation', done => {
testAction(
actions.requestDismissVulnerability,
{},
state,
[{ type: types.REQUEST_DISMISS_VULNERABILITY }],
[],
done,
);
it('should commit the request mutation', () => {
return testAction(actions.requestDismissVulnerability, {}, state, [
{ type: types.REQUEST_DISMISS_VULNERABILITY },
]);
});
});
});
......@@ -786,17 +670,16 @@ describe('add vulnerability dismissal comment', () => {
mock.onPatch(url).replyOnce(200, data);
});
it('should dispatch the request and success actions', done => {
it('should dispatch the request and success actions', () => {
const checkPassedData = () => {
const { project_id, id } = vulnerability.dismissal_feedback;
const expected = JSON.stringify({ project_id, id, comment });
expect(mock.history.patch[0].data).toBe(expected);
expect(toast).toHaveBeenCalledTimes(1);
done();
};
testAction(
return testAction(
actions.addDismissalComment,
{ vulnerability, comment },
{},
......@@ -810,17 +693,16 @@ describe('add vulnerability dismissal comment', () => {
);
});
it('should show the add dismissal toast message', done => {
it('should show the add dismissal toast message', () => {
const checkPassedData = () => {
const { project_id, id } = vulnerability.dismissal_feedback;
const expected = JSON.stringify({ project_id, id, comment });
expect(mock.history.patch[0].data).toBe(expected);
expect(toast).toHaveBeenCalledTimes(1);
done();
};
testAction(
return testAction(
actions.addDismissalComment,
{ vulnerability, comment },
{},
......@@ -840,54 +722,38 @@ describe('add vulnerability dismissal comment', () => {
mock.onPatch(url).replyOnce(404);
});
it('should dispatch the request and error actions', done => {
testAction(
it('should dispatch the request and error actions', () => {
return testAction(
actions.addDismissalComment,
{ vulnerability, comment },
{},
[],
[{ type: 'requestAddDismissalComment' }, { type: 'receiveAddDismissalCommentError' }],
done,
);
});
});
describe('receiveAddDismissalCommentSuccess', () => {
it('should commit the success mutation', done => {
testAction(
actions.receiveAddDismissalCommentSuccess,
{ data },
state,
[{ type: types.RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS, payload: { data } }],
[],
done,
);
it('should commit the success mutation', () => {
return testAction(actions.receiveAddDismissalCommentSuccess, { data }, state, [
{ type: types.RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS, payload: { data } },
]);
});
});
describe('receiveAddDismissalCommentError', () => {
it('should commit the error mutation', done => {
testAction(
actions.receiveAddDismissalCommentError,
{},
state,
[{ type: types.RECEIVE_ADD_DISMISSAL_COMMENT_ERROR }],
[],
done,
);
it('should commit the error mutation', () => {
return testAction(actions.receiveAddDismissalCommentError, {}, state, [
{ type: types.RECEIVE_ADD_DISMISSAL_COMMENT_ERROR },
]);
});
});
describe('requestAddDismissalComment', () => {
it('should commit the request mutation', done => {
testAction(
actions.requestAddDismissalComment,
{},
state,
[{ type: types.REQUEST_ADD_DISMISSAL_COMMENT }],
[],
done,
);
it('should commit the request mutation', () => {
return testAction(actions.requestAddDismissalComment, {}, state, [
{ type: types.REQUEST_ADD_DISMISSAL_COMMENT },
]);
});
});
});
......@@ -912,16 +778,15 @@ describe('add vulnerability dismissal comment', () => {
mock.onPatch(url).replyOnce(200, data);
});
it('should dispatch the request and success actions', done => {
it('should dispatch the request and success actions', () => {
const checkPassedData = () => {
const { project_id } = vulnerability.dismissal_feedback;
const expected = JSON.stringify({ project_id, comment });
expect(mock.history.patch[0].data).toBe(expected);
done();
};
testAction(
return testAction(
actions.deleteDismissalComment,
{ vulnerability },
{},
......@@ -938,17 +803,16 @@ describe('add vulnerability dismissal comment', () => {
);
});
it('should show the delete dismissal comment toast message', done => {
it('should show the delete dismissal comment toast message', () => {
const checkPassedData = () => {
const { project_id } = vulnerability.dismissal_feedback;
const expected = JSON.stringify({ project_id, comment });
expect(mock.history.patch[0].data).toBe(expected);
expect(toast).toHaveBeenCalledTimes(1);
done();
};
testAction(
return testAction(
actions.deleteDismissalComment,
{ vulnerability },
{},
......@@ -971,8 +835,8 @@ describe('add vulnerability dismissal comment', () => {
mock.onPatch(url).replyOnce(404);
});
it('should dispatch the request and error actions', done => {
testAction(
it('should dispatch the request and error actions', () => {
return testAction(
actions.deleteDismissalComment,
{ vulnerability },
{},
......@@ -981,47 +845,31 @@ describe('add vulnerability dismissal comment', () => {
{ type: 'requestDeleteDismissalComment' },
{ type: 'receiveDeleteDismissalCommentError' },
],
done,
);
});
});
describe('receiveDeleteDismissalCommentSuccess', () => {
it('should commit the success mutation', done => {
testAction(
actions.receiveDeleteDismissalCommentSuccess,
{ data },
state,
[{ type: types.RECEIVE_DELETE_DISMISSAL_COMMENT_SUCCESS, payload: { data } }],
[],
done,
);
it('should commit the success mutation', () => {
return testAction(actions.receiveDeleteDismissalCommentSuccess, { data }, state, [
{ type: types.RECEIVE_DELETE_DISMISSAL_COMMENT_SUCCESS, payload: { data } },
]);
});
});
describe('receiveDeleteDismissalCommentError', () => {
it('should commit the error mutation', done => {
testAction(
actions.receiveDeleteDismissalCommentError,
{},
state,
[{ type: types.RECEIVE_DELETE_DISMISSAL_COMMENT_ERROR }],
[],
done,
);
it('should commit the error mutation', () => {
return testAction(actions.receiveDeleteDismissalCommentError, {}, state, [
{ type: types.RECEIVE_DELETE_DISMISSAL_COMMENT_ERROR },
]);
});
});
describe('requestDeleteDismissalComment', () => {
it('should commit the request mutation', done => {
testAction(
actions.requestDeleteDismissalComment,
{},
state,
[{ type: types.REQUEST_DELETE_DISMISSAL_COMMENT }],
[],
done,
);
it('should commit the request mutation', () => {
return testAction(actions.requestDeleteDismissalComment, {}, state, [
{ type: types.REQUEST_DELETE_DISMISSAL_COMMENT },
]);
});
});
});
......@@ -1052,14 +900,14 @@ describe('dismiss multiple vulnerabilities', () => {
mock.restore();
});
it('should fire the dismissSelected mutations when all is well', done => {
it('should fire the dismissSelected mutations when all is well', () => {
mock
.onPost(state.vulnerabilities[0].create_vulnerability_feedback_dismissal_path)
.replyOnce(200)
.onPost(state.vulnerabilities[1].create_vulnerability_feedback_dismissal_path)
.replyOnce(200);
testAction(
return testAction(
actions.dismissSelectedVulnerabilities,
{},
state,
......@@ -1075,19 +923,18 @@ describe('dismiss multiple vulnerabilities', () => {
expect(mock.history.post[0].url).toEqual(
state.vulnerabilities[0].create_vulnerability_feedback_dismissal_path,
);
done();
},
);
});
it('should trigger the error state when something goes wrong', done => {
it('should trigger the error state when something goes wrong', () => {
mock
.onPost(state.vulnerabilities[0].create_vulnerability_feedback_dismissal_path)
.replyOnce(200)
.onPost(state.vulnerabilities[1].create_vulnerability_feedback_dismissal_path)
.replyOnce(500);
testAction(
return testAction(
actions.dismissSelectedVulnerabilities,
{},
state,
......@@ -1096,33 +943,25 @@ describe('dismiss multiple vulnerabilities', () => {
{ type: 'requestDismissSelectedVulnerabilities' },
{ type: 'receiveDismissSelectedVulnerabilitiesError', payload: { flashError: true } },
],
done,
);
});
describe('receiveDismissSelectedVulnerabilitiesSuccess', () => {
it(`should commit ${types.RECEIVE_DISMISS_SELECTED_VULNERABILITIES_SUCCESS}`, done => {
testAction(
it(`should commit ${types.RECEIVE_DISMISS_SELECTED_VULNERABILITIES_SUCCESS}`, () => {
return testAction(
actions.receiveDismissSelectedVulnerabilitiesSuccess,
{ selectedVulnerabilities },
state,
[{ type: types.RECEIVE_DISMISS_SELECTED_VULNERABILITIES_SUCCESS }],
[],
done,
);
});
});
describe('receiveDismissSelectedVulnerabilitiesError', () => {
it(`should commit ${types.RECEIVE_DISMISS_SELECTED_VULNERABILITIES_ERROR}`, done => {
testAction(
actions.receiveDismissSelectedVulnerabilitiesError,
{},
state,
[{ type: types.RECEIVE_DISMISS_SELECTED_VULNERABILITIES_ERROR }],
[],
done,
);
it(`should commit ${types.RECEIVE_DISMISS_SELECTED_VULNERABILITIES_ERROR}`, () => {
return testAction(actions.receiveDismissSelectedVulnerabilitiesError, {}, state, [
{ type: types.RECEIVE_DISMISS_SELECTED_VULNERABILITIES_ERROR },
]);
});
});
});
......@@ -1136,58 +975,38 @@ describe('selecting vulnerabilities', () => {
});
describe('selectVulnerability', () => {
it(`selectVulnerability should commit ${types.SELECT_VULNERABILITY}`, done => {
it(`selectVulnerability should commit ${types.SELECT_VULNERABILITY}`, () => {
const id = 1234;
testAction(
actions.selectVulnerability,
{ id },
state,
[{ type: types.SELECT_VULNERABILITY, payload: id }],
[],
done,
);
return testAction(actions.selectVulnerability, { id }, state, [
{ type: types.SELECT_VULNERABILITY, payload: id },
]);
});
});
describe('deselectVulnerability', () => {
it(`should commit ${types.DESELECT_VULNERABILITY}`, done => {
it(`should commit ${types.DESELECT_VULNERABILITY}`, () => {
const id = 1234;
testAction(
actions.deselectVulnerability,
{ id },
state,
[{ type: types.DESELECT_VULNERABILITY, payload: id }],
[],
done,
);
return testAction(actions.deselectVulnerability, { id }, state, [
{ type: types.DESELECT_VULNERABILITY, payload: id },
]);
});
});
describe('selectAllVulnerabilities', () => {
it(`should commit ${types.SELECT_ALL_VULNERABILITIES}`, done => {
testAction(
actions.selectAllVulnerabilities,
{},
state,
[{ type: types.SELECT_ALL_VULNERABILITIES }],
[],
done,
);
it(`should commit ${types.SELECT_ALL_VULNERABILITIES}`, () => {
return testAction(actions.selectAllVulnerabilities, {}, state, [
{ type: types.SELECT_ALL_VULNERABILITIES },
]);
});
});
describe('deselectAllVulnerabilities', () => {
it(`should commit ${types.DESELECT_ALL_VULNERABILITIES}`, done => {
testAction(
actions.deselectAllVulnerabilities,
{},
state,
[{ type: types.DESELECT_ALL_VULNERABILITIES }],
[],
done,
);
it(`should commit ${types.DESELECT_ALL_VULNERABILITIES}`, () => {
return testAction(actions.deselectAllVulnerabilities, {}, state, [
{ type: types.DESELECT_ALL_VULNERABILITIES },
]);
});
});
});
......@@ -1199,19 +1018,12 @@ describe('showDismissalDeleteButtons', () => {
state = initialState();
});
it('commits show dismissal delete buttons', done => {
testAction(
actions.showDismissalDeleteButtons,
null,
state,
[
{
type: types.SHOW_DISMISSAL_DELETE_BUTTONS,
},
],
[],
done,
);
it('commits show dismissal delete buttons', () => {
return testAction(actions.showDismissalDeleteButtons, null, state, [
{
type: types.SHOW_DISMISSAL_DELETE_BUTTONS,
},
]);
});
});
......@@ -1222,19 +1034,12 @@ describe('hideDismissalDeleteButtons', () => {
state = initialState();
});
it('commits hide dismissal delete buttons', done => {
testAction(
actions.hideDismissalDeleteButtons,
null,
state,
[
{
type: types.HIDE_DISMISSAL_DELETE_BUTTONS,
},
],
[],
done,
);
it('commits hide dismissal delete buttons', () => {
return testAction(actions.hideDismissalDeleteButtons, null, state, [
{
type: types.HIDE_DISMISSAL_DELETE_BUTTONS,
},
]);
});
});
......@@ -1257,8 +1062,8 @@ describe('revert vulnerability dismissal', () => {
mock.onDelete(url).replyOnce(200, {});
});
it('should dispatch the request and success actions', done => {
testAction(
it('should dispatch the request and success actions', () => {
return testAction(
actions.undoDismiss,
{ vulnerability },
{},
......@@ -1267,7 +1072,6 @@ describe('revert vulnerability dismissal', () => {
{ type: 'requestUndoDismiss' },
{ type: 'receiveUndoDismissSuccess', payload: { vulnerability } },
],
done,
);
});
});
......@@ -1277,10 +1081,10 @@ describe('revert vulnerability dismissal', () => {
mock.onDelete(url).replyOnce(404, {});
});
it('should dispatch the request and error actions', done => {
it('should dispatch the request and error actions', () => {
const flashError = false;
testAction(
return testAction(
actions.undoDismiss,
{ vulnerability, flashError },
{},
......@@ -1289,262 +1093,56 @@ describe('revert vulnerability dismissal', () => {
{ type: 'requestUndoDismiss' },
{ type: 'receiveUndoDismissError', payload: { flashError } },
],
done,
);
});
});
});
describe('receiveUndoDismissSuccess', () => {
it('should commit the success mutation', done => {
it('should commit the success mutation', () => {
const state = initialState;
const data = mockDataVulnerabilities[0];
testAction(
actions.receiveUndoDismissSuccess,
{ data },
state,
[
{
type: types.RECEIVE_REVERT_DISMISSAL_SUCCESS,
payload: { data },
},
],
[],
done,
);
return testAction(actions.receiveUndoDismissSuccess, { data }, state, [
{
type: types.RECEIVE_REVERT_DISMISSAL_SUCCESS,
payload: { data },
},
]);
});
});
describe('receiveUndoDismissError', () => {
it('should commit the error mutation', done => {
it('should commit the error mutation', () => {
const state = initialState;
testAction(
actions.receiveUndoDismissError,
{},
state,
[{ type: types.RECEIVE_REVERT_DISMISSAL_ERROR }],
[],
done,
);
return testAction(actions.receiveUndoDismissError, {}, state, [
{ type: types.RECEIVE_REVERT_DISMISSAL_ERROR },
]);
});
});
describe('requestUndoDismiss', () => {
it('should commit the request mutation', done => {
it('should commit the request mutation', () => {
const state = initialState;
testAction(
actions.requestUndoDismiss,
{},
state,
[{ type: types.REQUEST_REVERT_DISMISSAL }],
[],
done,
);
return testAction(actions.requestUndoDismiss, {}, state, [
{ type: types.REQUEST_REVERT_DISMISSAL },
]);
});
});
});
describe('vulnerabilities history actions', () => {
const data = mockDataVulnerabilitiesHistory;
const params = { filters: { severity: ['critical'] } };
const filteredData = mockDataVulnerabilitiesHistory.critical;
let state;
beforeEach(() => {
state = initialState();
});
describe('setVulnerabilitiesHistoryEndpoint', () => {
it('should commit the correct mutuation', done => {
const endpoint = 'fakepath.json';
testAction(
actions.setVulnerabilitiesHistoryEndpoint,
endpoint,
state,
[
{
type: types.SET_VULNERABILITIES_HISTORY_ENDPOINT,
payload: endpoint,
},
],
[],
done,
);
});
});
describe('setVulnerabilitiesHistoryDayRange', () => {
it('should commit the number of past days to show', done => {
const days = DAYS.THIRTY;
testAction(
actions.setVulnerabilitiesHistoryDayRange,
days,
state,
[
{
type: types.SET_VULNERABILITIES_HISTORY_DAY_RANGE,
payload: days,
},
],
[],
done,
);
});
describe('dismissal comment box', () => {
it('should commit the open comment mutation with a default payload', () => {
return testAction(actions.openDismissalCommentBox, undefined, undefined, [
{ type: types.OPEN_DISMISSAL_COMMENT_BOX },
]);
});
describe('fetchVulnerabilitiesHistory', () => {
let mock;
beforeEach(() => {
state.vulnerabilitiesHistoryEndpoint = `${TEST_HOST}/vulnerabilitIES_HISTORY.json`;
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
});
describe('on success', () => {
beforeEach(() => {
mock
.onGet(state.vulnerabilitiesHistoryEndpoint, { params })
.replyOnce(200, filteredData)
.onGet(state.vulnerabilitiesHistoryEndpoint)
.replyOnce(200, data);
});
it('should dispatch the request and success actions', done => {
testAction(
actions.fetchVulnerabilitiesHistory,
{},
state,
[],
[
{ type: 'requestVulnerabilitiesHistory' },
{
type: 'receiveVulnerabilitiesHistorySuccess',
payload: { data },
},
],
done,
);
});
it('return the filtered results', done => {
testAction(
actions.fetchVulnerabilitiesHistory,
params,
state,
[],
[
{ type: 'requestVulnerabilitiesHistory' },
{
type: 'receiveVulnerabilitiesHistorySuccess',
payload: { data: filteredData },
},
],
done,
);
});
});
describe('on error', () => {
beforeEach(() => {
mock.onGet(state.vulnerabilitiesHistoryEndpoint).replyOnce(404, {});
});
it('should dispatch the request and error actions', done => {
testAction(
actions.fetchVulnerabilitiesHistory,
{},
state,
[],
[
{ type: 'requestVulnerabilitiesHistory' },
{ type: 'receiveVulnerabilitiesHistoryError' },
],
done,
);
});
});
describe('with an empty endpoint', () => {
beforeEach(() => {
state.vulnerabilitiesHistoryEndpoint = '';
});
it('should not do anything', done => {
testAction(actions.fetchVulnerabilitiesHistory, {}, state, [], [], done);
});
});
});
describe('requestVulnerabilitiesHistory', () => {
it('should commit the request mutation', done => {
testAction(
actions.requestVulnerabilitiesHistory,
{},
state,
[{ type: types.REQUEST_VULNERABILITIES_HISTORY }],
[],
done,
);
});
});
describe('receiveVulnerabilitiesHistorySuccess', () => {
it('should commit the success mutation', done => {
testAction(
actions.receiveVulnerabilitiesHistorySuccess,
{ data },
state,
[{ type: types.RECEIVE_VULNERABILITIES_HISTORY_SUCCESS, payload: data }],
[],
done,
);
});
});
describe('receiveVulnerabilitiesHistoryError', () => {
it('should commit the error mutation', done => {
testAction(
actions.receiveVulnerabilitiesHistoryError,
{},
state,
[{ type: types.RECEIVE_VULNERABILITIES_HISTORY_ERROR }],
[],
done,
);
});
});
describe('openDismissalCommentBox', () => {
it('should commit the open comment mutation with a default payload', done => {
testAction(
actions.openDismissalCommentBox,
undefined,
state,
[{ type: types.OPEN_DISMISSAL_COMMENT_BOX }],
[],
done,
);
});
});
describe('closeDismissalCommentBox', () => {
it('should commit the close comment mutation', done => {
testAction(
actions.closeDismissalCommentBox,
{},
state,
[{ type: types.CLOSE_DISMISSAL_COMMENT_BOX }],
[],
done,
);
});
it('should commit the close comment mutation', () => {
return testAction(actions.closeDismissalCommentBox, {}, undefined, [
{ type: types.CLOSE_DISMISSAL_COMMENT_BOX },
]);
});
});
{
"low": {
"2018-10-1": 87,
"2018-10-2": 88,
"2018-10-3": 90,
"2018-10-4": 89,
"2018-10-5": 89,
"2018-10-6": 80,
"2018-10-7": 85,
"2018-10-8": 67,
"2018-10-9": 84,
"2018-10-10": 72,
"2018-10-11": 67,
"2018-10-12": 86,
"2018-10-13": 70,
"2018-10-14": 68,
"2018-10-15": 61,
"2018-10-16": 74,
"2018-10-17": 67,
"2018-10-18": 78,
"2018-10-19": 65,
"2018-10-20": 72,
"2018-10-21": 78,
"2018-10-22": 81,
"2018-10-23": 62,
"2018-10-24": 86,
"2018-10-25": 79,
"2018-10-26": 86,
"2018-10-27": 78,
"2018-10-28": 75,
"2018-10-29": 67,
"2018-10-30": 87,
"2018-10-31": 86,
"2018-11-1": 75,
"2018-11-2": 81,
"2018-11-3": 88,
"2018-11-4": 82,
"2018-11-5": 76,
"2018-11-6": 76,
"2018-11-7": 68,
"2018-11-8": 86,
"2018-11-9": 70,
"2018-11-10": 74,
"2018-11-11": 60,
"2018-11-12": 61,
"2018-11-13": 73,
"2018-11-14": 90,
"2018-11-15": 69,
"2018-11-16": 78,
"2018-11-17": 81,
"2018-11-18": 60,
"2018-11-19": 86,
"2018-11-20": 72,
"2018-11-21": 73,
"2018-11-22": 60,
"2018-11-23": 88,
"2018-11-24": 70,
"2018-11-25": 60,
"2018-11-26": 72,
"2018-11-27": 71,
"2018-11-28": 77,
"2018-11-29": 77,
"2018-11-30": 70,
"2018-12-1": 69,
"2018-12-2": 80,
"2018-12-3": 73,
"2018-12-4": 71,
"2018-12-5": 84,
"2018-12-6": 82,
"2018-12-7": 68,
"2018-12-8": 66,
"2018-12-9": 76,
"2018-12-10": 81,
"2018-12-11": 61,
"2018-12-12": 78,
"2018-12-13": 85,
"2018-12-14": 74,
"2018-12-15": 65,
"2018-12-16": 90,
"2018-12-17": 87,
"2018-12-18": 83,
"2018-12-19": 72,
"2018-12-20": 79,
"2018-12-21": 83,
"2018-12-22": 70,
"2018-12-23": 75,
"2018-12-24": 77,
"2018-12-25": 68,
"2018-12-26": 86,
"2018-12-27": 76,
"2018-12-28": 86,
"2018-12-29": 89,
"2018-12-30": 73,
"2018-12-31": 70
},
"medium": {
"2018-10-1": 73,
"2018-10-2": 76,
"2018-10-3": 101,
"2018-10-4": 84,
"2018-10-5": 90,
"2018-10-6": 97,
"2018-10-7": 77,
"2018-10-8": 81,
"2018-10-9": 98,
"2018-10-10": 83,
"2018-10-11": 82,
"2018-10-12": 70,
"2018-10-13": 99,
"2018-10-14": 83,
"2018-10-15": 81,
"2018-10-16": 80,
"2018-10-17": 82,
"2018-10-18": 89,
"2018-10-19": 89,
"2018-10-20": 71,
"2018-10-21": 73,
"2018-10-22": 74,
"2018-10-23": 83,
"2018-10-24": 91,
"2018-10-25": 85,
"2018-10-26": 90,
"2018-10-27": 77,
"2018-10-28": 102,
"2018-10-29": 75,
"2018-10-30": 78,
"2018-10-31": 70,
"2018-11-1": 90,
"2018-11-2": 96,
"2018-11-3": 98,
"2018-11-4": 88,
"2018-11-5": 79,
"2018-11-6": 91,
"2018-11-7": 101,
"2018-11-8": 75,
"2018-11-9": 75,
"2018-11-10": 84,
"2018-11-11": 70,
"2018-11-12": 89,
"2018-11-13": 104,
"2018-11-14": 90,
"2018-11-15": 81,
"2018-11-16": 102,
"2018-11-17": 86,
"2018-11-18": 80,
"2018-11-19": 71,
"2018-11-20": 72,
"2018-11-21": 103,
"2018-11-22": 89,
"2018-11-23": 83,
"2018-11-24": 79,
"2018-11-25": 87,
"2018-11-26": 79,
"2018-11-27": 104,
"2018-11-28": 70,
"2018-11-29": 103,
"2018-11-30": 86,
"2018-12-1": 86,
"2018-12-2": 77,
"2018-12-3": 96,
"2018-12-4": 95,
"2018-12-5": 74,
"2018-12-6": 99,
"2018-12-7": 101,
"2018-12-8": 78,
"2018-12-9": 83,
"2018-12-10": 76,
"2018-12-11": 77,
"2018-12-12": 105,
"2018-12-13": 81,
"2018-12-14": 82,
"2018-12-15": 90,
"2018-12-16": 88,
"2018-12-17": 78,
"2018-12-18": 82,
"2018-12-19": 83,
"2018-12-20": 105,
"2018-12-21": 70,
"2018-12-22": 85,
"2018-12-23": 91,
"2018-12-24": 89,
"2018-12-25": 83,
"2018-12-26": 73,
"2018-12-27": 91,
"2018-12-28": 77,
"2018-12-29": 101,
"2018-12-30": 83,
"2018-12-31": 94
},
"high": {
"2018-10-1": 43,
"2018-10-2": 42,
"2018-10-3": 42,
"2018-10-4": 49,
"2018-10-5": 44,
"2018-10-6": 59,
"2018-10-7": 49,
"2018-10-8": 53,
"2018-10-9": 44,
"2018-10-10": 51,
"2018-10-11": 43,
"2018-10-12": 53,
"2018-10-13": 52,
"2018-10-14": 43,
"2018-10-15": 60,
"2018-10-16": 53,
"2018-10-17": 57,
"2018-10-18": 42,
"2018-10-19": 46,
"2018-10-20": 43,
"2018-10-21": 43,
"2018-10-22": 41,
"2018-10-23": 47,
"2018-10-24": 44,
"2018-10-25": 43,
"2018-10-26": 60,
"2018-10-27": 43,
"2018-10-28": 59,
"2018-10-29": 55,
"2018-10-30": 45,
"2018-10-31": 51,
"2018-11-1": 55,
"2018-11-2": 50,
"2018-11-3": 43,
"2018-11-4": 41,
"2018-11-5": 51,
"2018-11-6": 49,
"2018-11-7": 49,
"2018-11-8": 60,
"2018-11-9": 60,
"2018-11-10": 43,
"2018-11-11": 57,
"2018-11-12": 42,
"2018-11-13": 59,
"2018-11-14": 41,
"2018-11-15": 53,
"2018-11-16": 53,
"2018-11-17": 43,
"2018-11-18": 53,
"2018-11-19": 48,
"2018-11-20": 56,
"2018-11-21": 51,
"2018-11-22": 42,
"2018-11-23": 60,
"2018-11-24": 50,
"2018-11-25": 49,
"2018-11-26": 47,
"2018-11-27": 46,
"2018-11-28": 40,
"2018-11-29": 41,
"2018-11-30": 57,
"2018-12-1": 57,
"2018-12-2": 45,
"2018-12-3": 52,
"2018-12-4": 46,
"2018-12-5": 56,
"2018-12-6": 48,
"2018-12-7": 58,
"2018-12-8": 59,
"2018-12-9": 47,
"2018-12-10": 58,
"2018-12-11": 50,
"2018-12-12": 45,
"2018-12-13": 59,
"2018-12-14": 40,
"2018-12-15": 40,
"2018-12-16": 48,
"2018-12-17": 44,
"2018-12-18": 54,
"2018-12-19": 44,
"2018-12-20": 57,
"2018-12-21": 54,
"2018-12-22": 44,
"2018-12-23": 59,
"2018-12-24": 41,
"2018-12-25": 52,
"2018-12-26": 52,
"2018-12-27": 50,
"2018-12-28": 49,
"2018-12-29": 45,
"2018-12-30": 44,
"2018-12-31": 60
},
"critical": {
"2018-10-1": 54,
"2018-10-2": 67,
"2018-10-3": 62,
"2018-10-4": 63,
"2018-10-5": 51,
"2018-10-6": 56,
"2018-10-7": 66,
"2018-10-8": 69,
"2018-10-9": 58,
"2018-10-10": 61,
"2018-10-11": 69,
"2018-10-12": 73,
"2018-10-13": 68,
"2018-10-14": 64,
"2018-10-15": 69,
"2018-10-16": 63,
"2018-10-17": 72,
"2018-10-18": 71,
"2018-10-19": 56,
"2018-10-20": 71,
"2018-10-21": 59,
"2018-10-22": 55,
"2018-10-23": 51,
"2018-10-24": 74,
"2018-10-25": 68,
"2018-10-26": 74,
"2018-10-27": 53,
"2018-10-28": 73,
"2018-10-29": 54,
"2018-10-30": 53,
"2018-10-31": 53,
"2018-11-1": 68,
"2018-11-2": 71,
"2018-11-3": 57,
"2018-11-4": 59,
"2018-11-5": 58,
"2018-11-6": 67,
"2018-11-7": 56,
"2018-11-8": 74,
"2018-11-9": 54,
"2018-11-10": 67,
"2018-11-11": 61,
"2018-11-12": 73,
"2018-11-13": 58,
"2018-11-14": 56,
"2018-11-15": 55,
"2018-11-16": 72,
"2018-11-17": 53,
"2018-11-18": 68,
"2018-11-19": 52,
"2018-11-20": 64,
"2018-11-21": 72,
"2018-11-22": 50,
"2018-11-23": 59,
"2018-11-24": 56,
"2018-11-25": 74,
"2018-11-26": 71,
"2018-11-27": 66,
"2018-11-28": 55,
"2018-11-29": 51,
"2018-11-30": 63,
"2018-12-1": 54,
"2018-12-2": 63,
"2018-12-3": 64,
"2018-12-4": 51,
"2018-12-5": 66,
"2018-12-6": 61,
"2018-12-7": 62,
"2018-12-8": 59,
"2018-12-9": 69,
"2018-12-10": 73,
"2018-12-11": 67,
"2018-12-12": 58,
"2018-12-13": 69,
"2018-12-14": 71,
"2018-12-15": 69,
"2018-12-16": 72,
"2018-12-17": 73,
"2018-12-18": 59,
"2018-12-19": 60,
"2018-12-20": 52,
"2018-12-21": 71,
"2018-12-22": 56,
"2018-12-23": 61,
"2018-12-24": 61,
"2018-12-25": 72,
"2018-12-26": 66,
"2018-12-27": 67,
"2018-12-28": 72,
"2018-12-29": 58,
"2018-12-30": 68,
"2018-12-31": 54,
"2019-1-1": 139,
"2019-1-2": 137,
"2019-1-3": 142,
"2019-1-4": 137,
"2019-1-5": 134,
"2019-1-6": 133,
"2019-1-7": 137,
"2019-1-8": 140,
"2019-1-9": 130,
"2019-1-10": 132,
"2019-1-11": 134,
"2019-1-12": 143,
"2019-1-13": 130,
"2019-1-14": 133,
"2019-1-15": 137,
"2019-1-16": 141,
"2019-1-17": 139,
"2019-1-18": 145,
"2019-1-19": 141,
"2019-1-20": 137,
"2019-1-21": 139,
"2019-1-22": 131,
"2019-1-23": 134,
"2019-1-24": 144,
"2019-1-25": 140,
"2019-1-26": 145,
"2019-1-27": 138,
"2019-1-28": 136,
"2019-1-29": 144,
"2019-1-30": 131,
"2019-1-31": 142
},
"unknown": {
"2018-10-1": 39,
"2018-10-2": 44,
"2018-10-3": 35,
"2018-10-4": 34,
"2018-10-5": 38,
"2018-10-6": 34,
"2018-10-7": 34,
"2018-10-8": 43,
"2018-10-9": 41,
"2018-10-10": 45,
"2018-10-11": 41,
"2018-10-12": 37,
"2018-10-13": 34,
"2018-10-14": 41,
"2018-10-15": 45,
"2018-10-16": 33,
"2018-10-17": 40,
"2018-10-18": 31,
"2018-10-19": 42,
"2018-10-20": 33,
"2018-10-21": 44,
"2018-10-22": 33,
"2018-10-23": 35,
"2018-10-24": 37,
"2018-10-25": 43,
"2018-10-26": 33,
"2018-10-27": 43,
"2018-10-28": 39,
"2018-10-29": 37,
"2018-10-30": 36,
"2018-10-31": 37,
"2018-11-1": 42,
"2018-11-2": 41,
"2018-11-3": 36,
"2018-11-4": 31,
"2018-11-5": 41,
"2018-11-6": 37,
"2018-11-7": 42,
"2018-11-8": 42,
"2018-11-9": 45,
"2018-11-10": 34,
"2018-11-11": 30,
"2018-11-12": 40,
"2018-11-13": 39,
"2018-11-14": 44,
"2018-11-15": 36,
"2018-11-16": 35,
"2018-11-17": 30,
"2018-11-18": 31,
"2018-11-19": 34,
"2018-11-20": 31,
"2018-11-21": 36,
"2018-11-22": 37,
"2018-11-23": 41,
"2018-11-24": 38,
"2018-11-25": 42,
"2018-11-26": 41,
"2018-11-27": 36,
"2018-11-28": 32,
"2018-11-29": 43,
"2018-11-30": 36,
"2018-12-1": 44,
"2018-12-2": 34,
"2018-12-3": 42,
"2018-12-4": 32,
"2018-12-5": 44,
"2018-12-6": 31,
"2018-12-7": 39,
"2018-12-8": 37,
"2018-12-9": 33,
"2018-12-10": 37,
"2018-12-11": 38,
"2018-12-12": 35,
"2018-12-13": 34,
"2018-12-14": 40,
"2018-12-15": 35,
"2018-12-16": 42,
"2018-12-17": 44,
"2018-12-18": 40,
"2018-12-19": 40,
"2018-12-20": 30,
"2018-12-21": 44,
"2018-12-22": 32,
"2018-12-23": 39,
"2018-12-24": 37,
"2018-12-25": 35,
"2018-12-26": 39,
"2018-12-27": 38,
"2018-12-28": 44,
"2018-12-29": 42,
"2018-12-30": 37,
"2018-12-31": 35
},
"all": {
"2018-10-1": 143,
"2018-10-2": 130,
"2018-10-3": 139,
"2018-10-4": 134,
"2018-10-5": 138,
"2018-10-6": 131,
"2018-10-7": 137,
"2018-10-8": 144,
"2018-10-9": 140,
"2018-10-10": 134,
"2018-10-11": 142,
"2018-10-12": 132,
"2018-10-13": 136,
"2018-10-14": 141,
"2018-10-15": 134,
"2018-10-16": 139,
"2018-10-17": 141,
"2018-10-18": 134,
"2018-10-19": 131,
"2018-10-20": 141,
"2018-10-21": 139,
"2018-10-22": 145,
"2018-10-23": 142,
"2018-10-24": 143,
"2018-10-25": 143,
"2018-10-26": 135,
"2018-10-27": 136,
"2018-10-28": 143,
"2018-10-29": 142,
"2018-10-30": 131,
"2018-10-31": 141,
"2018-11-1": 134,
"2018-11-2": 134,
"2018-11-3": 130,
"2018-11-4": 137,
"2018-11-5": 145,
"2018-11-6": 137,
"2018-11-7": 135,
"2018-11-8": 145,
"2018-11-9": 132,
"2018-11-10": 134,
"2018-11-11": 139,
"2018-11-12": 139,
"2018-11-13": 130,
"2018-11-14": 137,
"2018-11-15": 136,
"2018-11-16": 145,
"2018-11-17": 130,
"2018-11-18": 143,
"2018-11-19": 134,
"2018-11-20": 145,
"2018-11-21": 137,
"2018-11-22": 140,
"2018-11-23": 138,
"2018-11-24": 132,
"2018-11-25": 143,
"2018-11-26": 131,
"2018-11-27": 130,
"2018-11-28": 144,
"2018-11-29": 139,
"2018-11-30": 143,
"2018-12-1": 139,
"2018-12-2": 137,
"2018-12-3": 142,
"2018-12-4": 137,
"2018-12-5": 134,
"2018-12-6": 133,
"2018-12-7": 137,
"2018-12-8": 140,
"2018-12-9": 130,
"2018-12-10": 132,
"2018-12-11": 134,
"2018-12-12": 143,
"2018-12-13": 130,
"2018-12-14": 133,
"2018-12-15": 137,
"2018-12-16": 141,
"2018-12-17": 139,
"2018-12-18": 145,
"2018-12-19": 141,
"2018-12-20": 137,
"2018-12-21": 139,
"2018-12-22": 131,
"2018-12-23": 134,
"2018-12-24": 144,
"2018-12-25": 140,
"2018-12-26": 145,
"2018-12-27": 138,
"2018-12-28": 136,
"2018-12-29": 144,
"2018-12-30": 131,
"2018-12-31": 142,
"2019-1-1": 139,
"2019-1-2": 137,
"2019-1-3": 142,
"2019-1-4": 137,
"2019-1-5": 134,
"2019-1-6": 133,
"2019-1-7": 137,
"2019-1-8": 140,
"2019-1-9": 130,
"2019-1-10": 132,
"2019-1-11": 134,
"2019-1-12": 143,
"2019-1-13": 130,
"2019-1-14": 133,
"2019-1-15": 137,
"2019-1-16": 141,
"2019-1-17": 139,
"2019-1-18": 145,
"2019-1-19": 141,
"2019-1-20": 137,
"2019-1-21": 139,
"2019-1-22": 131,
"2019-1-23": 134,
"2019-1-24": 144,
"2019-1-25": 140,
"2019-1-26": 145,
"2019-1-27": 138,
"2019-1-28": 136,
"2019-1-29": 144,
"2019-1-30": 131,
"2019-1-31": 142
}
}
import { DAYS } from 'ee/security_dashboard/store/modules/vulnerabilities/constants';
import * as getters from 'ee/security_dashboard/store/modules/vulnerabilities/getters';
import createState from 'ee/security_dashboard/store/modules/vulnerabilities/state';
import mockHistoryData from './data/mock_data_vulnerabilities_history.json';
describe('vulnerabilities module getters', () => {
describe('dashboardError', () => {
......@@ -57,55 +54,6 @@ describe('vulnerabilities module getters', () => {
});
});
describe('getFilteredVulnerabilitiesHistory', () => {
let state;
const mockedGetters = () => {
const getVulnerabilityHistoryByName = name =>
getters.getVulnerabilityHistoryByName(state)(name);
return { getVulnerabilityHistoryByName };
};
beforeEach(() => {
state = createState();
state.vulnerabilitiesHistory = mockHistoryData;
const mockDate = new Date(2019, 1, 2);
const originalDate = Date;
jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
global.Date.now = originalDate.now;
global.Date.parse = originalDate.parse;
global.Date.UTC = originalDate.UTC;
});
it('should filter the data to the last 30 days and days we have data for', () => {
state.vulnerabilitiesHistoryDayRange = DAYS.THIRTY;
const filteredResults = getters.getFilteredVulnerabilitiesHistory(state, mockedGetters())(
'critical',
);
expect(filteredResults).toHaveLength(28);
});
it('should filter the data to the last 60 days and days we have data for', () => {
state.vulnerabilitiesHistoryDayRange = DAYS.SIXTY;
const filteredResults = getters.getFilteredVulnerabilitiesHistory(state, mockedGetters())(
'critical',
);
expect(filteredResults).toHaveLength(58);
});
it('should filter the data to the last 90 days and days we have data for', () => {
state.vulnerabilitiesHistoryDayRange = DAYS.NINETY;
const filteredResults = getters.getFilteredVulnerabilitiesHistory(state, mockedGetters())(
'critical',
);
expect(filteredResults).toHaveLength(88);
});
});
describe('isSelectingVulnerabilities', () => {
it('should return true if we have selected vulnerabilities', () => {
const mockedGetters = { selectedVulnerabilitiesCount: 3 };
......
import { DAYS } from 'ee/security_dashboard/store/modules/vulnerabilities/constants';
import * as types from 'ee/security_dashboard/store/modules/vulnerabilities/mutation_types';
import mutations from 'ee/security_dashboard/store/modules/vulnerabilities/mutations';
import createState from 'ee/security_dashboard/store/modules/vulnerabilities/state';
......@@ -113,76 +112,6 @@ describe('vulnerabilities module mutations', () => {
});
});
describe('SET_VULNERABILITIES_HISTORY_ENDPOINT', () => {
it('should set `vulnerabilitiesHistoryEndpoint` to `fakepath.json`', () => {
const endpoint = 'fakepath.json';
mutations[types.SET_VULNERABILITIES_HISTORY_ENDPOINT](state, endpoint);
expect(state.vulnerabilitiesHistoryEndpoint).toBe(endpoint);
});
});
describe('REQUEST_VULNERABILITIES_HISTORY', () => {
beforeEach(() => {
state.errorLoadingVulnerabilitiesHistory = true;
mutations[types.REQUEST_VULNERABILITIES_HISTORY](state);
});
it('should set `isLoadingVulnerabilitiesHistory` to `true`', () => {
expect(state.isLoadingVulnerabilitiesHistory).toBeTruthy();
});
it('should set `errorLoadingVulnerabilitiesHistory` to `false`', () => {
expect(state.errorLoadingVulnerabilitiesHistory).toBeFalsy();
});
});
describe('RECEIVE_VULNERABILITIES_HISTORY_SUCCESS', () => {
let payload;
beforeEach(() => {
payload = mockData;
mutations[types.RECEIVE_VULNERABILITIES_HISTORY_SUCCESS](state, payload);
});
it('should set `isLoadingVulnerabilitiesHistory` to `false`', () => {
expect(state.isLoadingVulnerabilitiesHistory).toBeFalsy();
});
it('should set `vulnerabilitiesHistory`', () => {
expect(state.vulnerabilitiesHistory).toBe(payload);
});
});
describe('RECEIVE_VULNERABILITIES_HISTORY_ERROR', () => {
it('should set `isLoadingVulnerabilitiesHistory` to `false`', () => {
mutations[types.RECEIVE_VULNERABILITIES_HISTORY_ERROR](state);
expect(state.isLoadingVulnerabilitiesHistory).toBeFalsy();
});
});
describe('SET_VULNERABILITIES_HISTORY_DAY_RANGE', () => {
it('should set the vulnerabilitiesHistoryDayRange to number of days', () => {
mutations[types.SET_VULNERABILITIES_HISTORY_DAY_RANGE](state, DAYS.THIRTY);
expect(state.vulnerabilitiesHistoryDayRange).toBe(DAYS.THIRTY);
});
it('should set the vulnerabilitiesHistoryMaxDayInterval to 7 if days are 60 and under', () => {
mutations[types.SET_VULNERABILITIES_HISTORY_DAY_RANGE](state, DAYS.THIRTY);
expect(state.vulnerabilitiesHistoryMaxDayInterval).toBe(7);
});
it('should set the vulnerabilitiesHistoryMaxDayInterval to 14 if over 60', () => {
mutations[types.SET_VULNERABILITIES_HISTORY_DAY_RANGE](state, DAYS.NINETY);
expect(state.vulnerabilitiesHistoryMaxDayInterval).toBe(14);
});
});
describe('SET_MODAL_DATA', () => {
describe('with all the data', () => {
const vulnerability = mockData[0];
......
......@@ -5,12 +5,8 @@ import {
} from 'ee/security_dashboard/store/modules/filters/mutation_types';
function expectRefreshDispatches(store, payload) {
expect(store.dispatch).toHaveBeenCalledTimes(2);
expect(store.dispatch).toHaveBeenCalledTimes(1);
expect(store.dispatch).toHaveBeenCalledWith('vulnerabilities/fetchVulnerabilities', payload);
expect(store.dispatch).toHaveBeenCalledWith(
'vulnerabilities/fetchVulnerabilitiesHistory',
payload,
);
}
describe('mediator', () => {
......
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