Move translations mapping to a helper

This extracts the code that maps scanner names to their translations
into a dedicated helper.
parent 75fd592a
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { SCANNER_NAMES_MAP } from '~/security_configuration/components/constants';
export const augmentFeatures = (securityFeatures, complianceFeatures, features = []) => { export const augmentFeatures = (securityFeatures, complianceFeatures, features = []) => {
const featuresByType = features.reduce((acc, feature) => { const featuresByType = features.reduce((acc, feature) => {
...@@ -24,3 +25,13 @@ export const augmentFeatures = (securityFeatures, complianceFeatures, features = ...@@ -24,3 +25,13 @@ export const augmentFeatures = (securityFeatures, complianceFeatures, features =
augmentedComplianceFeatures: complianceFeatures.map((feature) => augmentFeature(feature)), augmentedComplianceFeatures: complianceFeatures.map((feature) => augmentFeature(feature)),
}; };
}; };
/**
* Converts a list of security scanner IDs (such as SAST_IAC) into a list of their translated
* names defined in the SCANNER_NAMES_MAP constant (eg. IaC Scanning).
*
* @param {String[]} scannerNames
* @returns {String[]}
*/
export const translateScannerNames = (scannerNames = []) =>
scannerNames.map((scannerName) => SCANNER_NAMES_MAP[scannerName] || scannerName);
...@@ -9,7 +9,7 @@ import { preparePageInfo } from 'ee/security_dashboard/helpers'; ...@@ -9,7 +9,7 @@ import { preparePageInfo } from 'ee/security_dashboard/helpers';
import { VULNERABILITIES_PER_PAGE } from 'ee/security_dashboard/store/constants'; import { VULNERABILITIES_PER_PAGE } from 'ee/security_dashboard/store/constants';
import { parseBoolean } from '~/lib/utils/common_utils'; import { parseBoolean } from '~/lib/utils/common_utils';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import { SCANNER_NAMES_MAP } from '~/security_configuration/components/constants'; import { translateScannerNames } from '~/security_configuration/utils';
import VulnerabilityList from '../shared/vulnerability_list.vue'; import VulnerabilityList from '../shared/vulnerability_list.vue';
import SecurityScannerAlert from './security_scanner_alert.vue'; import SecurityScannerAlert from './security_scanner_alert.vue';
...@@ -92,12 +92,11 @@ export default { ...@@ -92,12 +92,11 @@ export default {
}, },
update({ project = {} }) { update({ project = {} }) {
const { available = [], enabled = [], pipelineRun = [] } = project?.securityScanners || {}; const { available = [], enabled = [], pipelineRun = [] } = project?.securityScanners || {};
const translateScannerName = (scannerName) => SCANNER_NAMES_MAP[scannerName] || scannerName;
return { return {
available: available.map(translateScannerName), available: translateScannerNames(available),
enabled: enabled.map(translateScannerName), enabled: translateScannerNames(enabled),
pipelineRun: pipelineRun.map(translateScannerName), pipelineRun: translateScannerNames(pipelineRun),
}; };
}, },
}, },
......
...@@ -4,7 +4,7 @@ import { difference } from 'lodash'; ...@@ -4,7 +4,7 @@ import { difference } from 'lodash';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import { parseBoolean } from '~/lib/utils/common_utils'; import { parseBoolean } from '~/lib/utils/common_utils';
import { SCANNER_NAMES_MAP } from '~/security_configuration/components/constants'; import { translateScannerNames } from '~/security_configuration/utils';
import ReportNotConfiguredProject from '../shared/empty_states/report_not_configured_project.vue'; import ReportNotConfiguredProject from '../shared/empty_states/report_not_configured_project.vue';
import VulnerabilityReportTabs from '../shared/vulnerability_report/vulnerability_report_tabs.vue'; import VulnerabilityReportTabs from '../shared/vulnerability_report/vulnerability_report_tabs.vue';
import projectVulnerabilitiesQuery from '../../graphql/queries/project_vulnerabilities.query.graphql'; import projectVulnerabilitiesQuery from '../../graphql/queries/project_vulnerabilities.query.graphql';
...@@ -40,12 +40,11 @@ export default { ...@@ -40,12 +40,11 @@ export default {
}, },
update({ project = {} }) { update({ project = {} }) {
const { available = [], enabled = [], pipelineRun = [] } = project?.securityScanners || {}; const { available = [], enabled = [], pipelineRun = [] } = project?.securityScanners || {};
const translateScannerName = (scannerName) => SCANNER_NAMES_MAP[scannerName] || scannerName;
return { return {
available: available.map(translateScannerName), available: translateScannerNames(available),
enabled: enabled.map(translateScannerName), enabled: translateScannerNames(enabled),
pipelineRun: pipelineRun.map(translateScannerName), pipelineRun: translateScannerNames(pipelineRun),
}; };
}, },
}, },
......
import { augmentFeatures } from '~/security_configuration/utils'; import { augmentFeatures, translateScannerNames } from '~/security_configuration/utils';
import { SCANNER_NAMES_MAP } from '~/security_configuration/components/constants';
const mockSecurityFeatures = [ describe('augmentFeatures', () => {
const mockSecurityFeatures = [
{ {
name: 'SAST', name: 'SAST',
type: 'SAST', type: 'SAST',
}, },
]; ];
const mockComplianceFeatures = [ const mockComplianceFeatures = [
{ {
name: 'LICENSE_COMPLIANCE', name: 'LICENSE_COMPLIANCE',
type: 'LICENSE_COMPLIANCE', type: 'LICENSE_COMPLIANCE',
}, },
]; ];
const mockFeaturesWithSecondary = [ const mockFeaturesWithSecondary = [
{ {
name: 'DAST', name: 'DAST',
type: 'DAST', type: 'DAST',
...@@ -23,46 +25,46 @@ const mockFeaturesWithSecondary = [ ...@@ -23,46 +25,46 @@ const mockFeaturesWithSecondary = [
name: 'DAST PROFILES', name: 'DAST PROFILES',
}, },
}, },
]; ];
const mockInvalidCustomFeature = [ const mockInvalidCustomFeature = [
{ {
foo: 'bar', foo: 'bar',
}, },
]; ];
const mockValidCustomFeature = [ const mockValidCustomFeature = [
{ {
name: 'SAST', name: 'SAST',
type: 'SAST', type: 'SAST',
customField: 'customvalue', customField: 'customvalue',
}, },
]; ];
const mockValidCustomFeatureSnakeCase = [ const mockValidCustomFeatureSnakeCase = [
{ {
name: 'SAST', name: 'SAST',
type: 'SAST', type: 'SAST',
custom_field: 'customvalue', custom_field: 'customvalue',
}, },
]; ];
const expectedOutputDefault = { const expectedOutputDefault = {
augmentedSecurityFeatures: mockSecurityFeatures, augmentedSecurityFeatures: mockSecurityFeatures,
augmentedComplianceFeatures: mockComplianceFeatures, augmentedComplianceFeatures: mockComplianceFeatures,
}; };
const expectedOutputSecondary = { const expectedOutputSecondary = {
augmentedSecurityFeatures: mockSecurityFeatures, augmentedSecurityFeatures: mockSecurityFeatures,
augmentedComplianceFeatures: mockFeaturesWithSecondary, augmentedComplianceFeatures: mockFeaturesWithSecondary,
}; };
const expectedOutputCustomFeature = { const expectedOutputCustomFeature = {
augmentedSecurityFeatures: mockValidCustomFeature, augmentedSecurityFeatures: mockValidCustomFeature,
augmentedComplianceFeatures: mockComplianceFeatures, augmentedComplianceFeatures: mockComplianceFeatures,
}; };
describe('returns an object with augmentedSecurityFeatures and augmentedComplianceFeatures when', () => { describe('returns an object with augmentedSecurityFeatures and augmentedComplianceFeatures when', () => {
it('given an empty array', () => { it('given an empty array', () => {
expect(augmentFeatures(mockSecurityFeatures, mockComplianceFeatures, [])).toEqual( expect(augmentFeatures(mockSecurityFeatures, mockComplianceFeatures, [])).toEqual(
expectedOutputDefault, expectedOutputDefault,
...@@ -86,9 +88,9 @@ describe('returns an object with augmentedSecurityFeatures and augmentedComplian ...@@ -86,9 +88,9 @@ describe('returns an object with augmentedSecurityFeatures and augmentedComplian
augmentFeatures(mockSecurityFeatures, mockComplianceFeatures, mockValidCustomFeature), augmentFeatures(mockSecurityFeatures, mockComplianceFeatures, mockValidCustomFeature),
).toEqual(expectedOutputCustomFeature); ).toEqual(expectedOutputCustomFeature);
}); });
}); });
describe('returns an object with camelcased keys', () => { describe('returns an object with camelcased keys', () => {
it('given a customfeature in snakecase', () => { it('given a customfeature in snakecase', () => {
expect( expect(
augmentFeatures( augmentFeatures(
...@@ -98,4 +100,21 @@ describe('returns an object with camelcased keys', () => { ...@@ -98,4 +100,21 @@ describe('returns an object with camelcased keys', () => {
), ),
).toEqual(expectedOutputCustomFeature); ).toEqual(expectedOutputCustomFeature);
}); });
});
});
describe('translateScannerNames', () => {
it.each(['', undefined, null, 1, 'UNKNOWN_SCANNER_KEY'])('returns %p as is', (key) => {
expect(translateScannerNames([key])).toEqual([key]);
});
it('returns an empty array if no input is provided', () => {
expect(translateScannerNames([])).toEqual([]);
});
it('returns translated scanner names', () => {
expect(translateScannerNames(Object.keys(SCANNER_NAMES_MAP))).toEqual(
Object.values(SCANNER_NAMES_MAP),
);
});
}); });
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