Commit a7305e64 authored by Savas Vedova's avatar Savas Vedova Committed by Olena Horal-Koretska

Track security report findings

parent 721c7bbb
...@@ -18,6 +18,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => { ...@@ -18,6 +18,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => {
return fetchDiffData(rootState, state.paths.diffEndpoint, REPORT_TYPE_SAST) return fetchDiffData(rootState, state.paths.diffEndpoint, REPORT_TYPE_SAST)
.then((data) => { .then((data) => {
dispatch('receiveDiffSuccess', data); dispatch('receiveDiffSuccess', data);
return data;
}) })
.catch(() => { .catch(() => {
dispatch('receiveDiffError'); dispatch('receiveDiffError');
......
...@@ -18,6 +18,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => { ...@@ -18,6 +18,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => {
return fetchDiffData(rootState, state.paths.diffEndpoint, REPORT_TYPE_SECRET_DETECTION) return fetchDiffData(rootState, state.paths.diffEndpoint, REPORT_TYPE_SECRET_DETECTION)
.then((data) => { .then((data) => {
dispatch('receiveDiffSuccess', data); dispatch('receiveDiffSuccess', data);
return data;
}) })
.catch(() => { .catch(() => {
dispatch('receiveDiffError'); dispatch('receiveDiffError');
......
...@@ -394,38 +394,38 @@ export default { ...@@ -394,38 +394,38 @@ export default {
if (this.sastComparisonPath && this.hasSastReports) { if (this.sastComparisonPath && this.hasSastReports) {
this.setSastDiffEndpoint(this.sastComparisonPath); this.setSastDiffEndpoint(this.sastComparisonPath);
this.fetchSastDiff(); this.fetchSecurityReport(this.fetchSastDiff, 'sast');
} }
if (this.containerScanningComparisonPath && this.hasContainerScanningReports) { if (this.containerScanningComparisonPath && this.hasContainerScanningReports) {
this.setContainerScanningDiffEndpoint(this.containerScanningComparisonPath); this.setContainerScanningDiffEndpoint(this.containerScanningComparisonPath);
this.fetchContainerScanningDiff(); this.fetchSecurityReport(this.fetchContainerScanningDiff, 'container_scanning');
} }
if (this.dastComparisonPath && this.hasDastReports) { if (this.dastComparisonPath && this.hasDastReports) {
this.setDastDiffEndpoint(this.dastComparisonPath); this.setDastDiffEndpoint(this.dastComparisonPath);
this.fetchDastDiff(); this.fetchSecurityReport(this.fetchDastDiff, 'dast');
} }
if (this.dependencyScanningComparisonPath && this.hasDependencyScanningReports) { if (this.dependencyScanningComparisonPath && this.hasDependencyScanningReports) {
this.setDependencyScanningDiffEndpoint(this.dependencyScanningComparisonPath); this.setDependencyScanningDiffEndpoint(this.dependencyScanningComparisonPath);
this.fetchDependencyScanningDiff(); this.fetchSecurityReport(this.fetchDependencyScanningDiff, 'dependency_scanning');
} }
if (this.secretDetectionComparisonPath && this.hasSecretDetectionReports) { if (this.secretDetectionComparisonPath && this.hasSecretDetectionReports) {
this.setSecretDetectionDiffEndpoint(this.secretDetectionComparisonPath); this.setSecretDetectionDiffEndpoint(this.secretDetectionComparisonPath);
this.fetchSecretDetectionDiff(); this.fetchSecurityReport(this.fetchSecretDetectionDiff, 'secret_detection');
} }
if (this.coverageFuzzingComparisonPath && this.hasCoverageFuzzingReports) { if (this.coverageFuzzingComparisonPath && this.hasCoverageFuzzingReports) {
this.setCoverageFuzzingDiffEndpoint(this.coverageFuzzingComparisonPath); this.setCoverageFuzzingDiffEndpoint(this.coverageFuzzingComparisonPath);
this.fetchCoverageFuzzingDiff(); this.fetchSecurityReport(this.fetchCoverageFuzzingDiff, 'coverage_fuzzing');
this.fetchPipelineJobs(); this.fetchPipelineJobs();
} }
if (this.apiFuzzingComparisonPath && this.hasApiFuzzingReports) { if (this.apiFuzzingComparisonPath && this.hasApiFuzzingReports) {
this.setApiFuzzingDiffEndpoint(this.apiFuzzingComparisonPath); this.setApiFuzzingDiffEndpoint(this.apiFuzzingComparisonPath);
this.fetchApiFuzzingDiff(); this.fetchSecurityReport(this.fetchApiFuzzingDiff, 'api_fuzzing');
} }
}, },
methods: { methods: {
...@@ -475,6 +475,24 @@ export default { ...@@ -475,6 +475,24 @@ export default {
hasIssuesForReportType(reportType) { hasIssuesForReportType(reportType) {
return Boolean(this[reportType]?.newIssues.length || this[reportType]?.resolvedIssues.length); return Boolean(this[reportType]?.newIssues.length || this[reportType]?.resolvedIssues.length);
}, },
async fetchSecurityReport(fetchFn, toolName) {
try {
const reports = await fetchFn();
const category = 'Vulnerability_Management';
const eventNameFixed = `mr_widget_findings_counts_${toolName}_fixed`;
const eventNameAdded = `mr_widget_findings_counts_${toolName}_added`;
Tracking.event(category, eventNameFixed, {
value: reports?.diff?.fixed?.length || 0,
});
Tracking.event(category, eventNameAdded, {
value: reports?.diff?.added?.length || 0,
});
} catch {
// Do nothing, we dispatch an error message in the action
}
},
}, },
summarySlots: ['success', 'error', 'loading'], summarySlots: ['success', 'error', 'loading'],
reportTypes: { reportTypes: {
......
...@@ -67,6 +67,7 @@ export const fetchContainerScanningDiff = ({ state, dispatch }) => { ...@@ -67,6 +67,7 @@ export const fetchContainerScanningDiff = ({ state, dispatch }) => {
return fetchDiffData(state, state.containerScanning.paths.diffEndpoint, 'container_scanning') return fetchDiffData(state, state.containerScanning.paths.diffEndpoint, 'container_scanning')
.then((data) => { .then((data) => {
dispatch('receiveContainerScanningDiffSuccess', data); dispatch('receiveContainerScanningDiffSuccess', data);
return data;
}) })
.catch(() => { .catch(() => {
dispatch('receiveContainerScanningDiffError'); dispatch('receiveContainerScanningDiffError');
...@@ -96,6 +97,7 @@ export const fetchDastDiff = ({ state, dispatch }) => { ...@@ -96,6 +97,7 @@ export const fetchDastDiff = ({ state, dispatch }) => {
return fetchDiffData(state, state.dast.paths.diffEndpoint, 'dast') return fetchDiffData(state, state.dast.paths.diffEndpoint, 'dast')
.then((data) => { .then((data) => {
dispatch('receiveDastDiffSuccess', data); dispatch('receiveDastDiffSuccess', data);
return data;
}) })
.catch(() => { .catch(() => {
dispatch('receiveDastDiffError'); dispatch('receiveDastDiffError');
...@@ -124,6 +126,7 @@ export const fetchDependencyScanningDiff = ({ state, dispatch }) => { ...@@ -124,6 +126,7 @@ export const fetchDependencyScanningDiff = ({ state, dispatch }) => {
return fetchDiffData(state, state.dependencyScanning.paths.diffEndpoint, 'dependency_scanning') return fetchDiffData(state, state.dependencyScanning.paths.diffEndpoint, 'dependency_scanning')
.then((data) => { .then((data) => {
dispatch('receiveDependencyScanningDiffSuccess', data); dispatch('receiveDependencyScanningDiffSuccess', data);
return data;
}) })
.catch(() => { .catch(() => {
dispatch('receiveDependencyScanningDiffError'); dispatch('receiveDependencyScanningDiffError');
...@@ -160,10 +163,13 @@ export const fetchCoverageFuzzingDiff = ({ state, dispatch }) => { ...@@ -160,10 +163,13 @@ export const fetchCoverageFuzzingDiff = ({ state, dispatch }) => {
}), }),
]) ])
.then((values) => { .then((values) => {
dispatch('receiveCoverageFuzzingDiffSuccess', { const data = {
diff: values[0].data, diff: values[0].data,
enrichData: values[1].data, enrichData: values[1].data,
}); };
dispatch('receiveCoverageFuzzingDiffSuccess', data);
return data;
}) })
.catch(() => { .catch(() => {
dispatch('receiveCoverageFuzzingDiffError'); dispatch('receiveCoverageFuzzingDiffError');
......
...@@ -17,6 +17,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => { ...@@ -17,6 +17,7 @@ export const fetchDiff = ({ state, rootState, dispatch }) => {
return fetchDiffData(rootState, state.paths.diffEndpoint, 'api_fuzzing') return fetchDiffData(rootState, state.paths.diffEndpoint, 'api_fuzzing')
.then((data) => { .then((data) => {
dispatch('receiveDiffSuccess', data); dispatch('receiveDiffSuccess', data);
return data;
}) })
.catch(() => { .catch(() => {
dispatch('receiveDiffError'); dispatch('receiveDiffError');
......
...@@ -274,6 +274,9 @@ describe('Grouped security reports app', () => { ...@@ -274,6 +274,9 @@ describe('Grouped security reports app', () => {
}); });
describe('with successful responses', () => { describe('with successful responses', () => {
let trackingSpy;
const { category } = trackMrSecurityReportDetails;
beforeEach(() => { beforeEach(() => {
mock.onGet(CONTAINER_SCANNING_DIFF_ENDPOINT).reply(200, containerScanningDiffSuccessMock); mock.onGet(CONTAINER_SCANNING_DIFF_ENDPOINT).reply(200, containerScanningDiffSuccessMock);
mock.onGet(DEPENDENCY_SCANNING_DIFF_ENDPOINT).reply(200, dependencyScanningDiffSuccessMock); mock.onGet(DEPENDENCY_SCANNING_DIFF_ENDPOINT).reply(200, dependencyScanningDiffSuccessMock);
...@@ -284,6 +287,7 @@ describe('Grouped security reports app', () => { ...@@ -284,6 +287,7 @@ describe('Grouped security reports app', () => {
mock.onGet(API_FUZZING_DIFF_ENDPOINT).reply(200, apiFuzzingDiffSuccessMock); mock.onGet(API_FUZZING_DIFF_ENDPOINT).reply(200, apiFuzzingDiffSuccessMock);
createWrapper(allReportProps); createWrapper(allReportProps);
trackingSpy = mockTracking(category, wrapper.element, jest.spyOn);
return Promise.all([ return Promise.all([
waitForMutation(wrapper.vm.$store, `sast/${sastTypes.RECEIVE_DIFF_SUCCESS}`), waitForMutation(wrapper.vm.$store, `sast/${sastTypes.RECEIVE_DIFF_SUCCESS}`),
...@@ -299,6 +303,31 @@ describe('Grouped security reports app', () => { ...@@ -299,6 +303,31 @@ describe('Grouped security reports app', () => {
]); ]);
}); });
afterEach(() => {
unmockTracking();
});
const eventName = (toolName, eventType) =>
`mr_widget_findings_counts_${toolName}_${eventType}`;
it.each`
toolName | report
${'coverage_fuzzing'} | ${coverageFuzzingDiffSuccessMock}
${'sast'} | ${sastDiffSuccessMock}
${'container_scanning'} | ${containerScanningDiffSuccessMock}
${'dast'} | ${dastDiffSuccessMock}
${'dependency_scanning'} | ${dependencyScanningDiffSuccessMock}
${'secret_detection'} | ${secretDetectionDiffSuccessMock}
${'api_fuzzing'} | ${apiFuzzingDiffSuccessMock}
`('track reports for "$toolName', ({ toolName, report }) => {
expect(trackingSpy).toHaveBeenCalledWith(category, eventName(toolName, 'fixed'), {
value: report.fixed.length,
});
expect(trackingSpy).toHaveBeenCalledWith(category, eventName(toolName, 'added'), {
value: report.added.length,
});
});
it('renders reports', () => { it('renders reports', () => {
// It's not loading // It's not loading
expect(findSpinner().exists()).toBe(false); expect(findSpinner().exists()).toBe(false);
......
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