Commit 5382795f authored by Savas Vedova's avatar Savas Vedova

Merge branch 'jnnkl-disabled-analyzer-warning' into 'master'

SAST Config introduce disabled analyzer warning

See merge request gitlab-org/gitlab!55172
parents 4986a856 91066fde
<script>
import { GlAlert, GlButton, GlIcon, GlLink } from '@gitlab/ui';
import { GlAlert, GlButton, GlIcon, GlLink, GlSprintf } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { cloneDeep } from 'lodash';
import DynamicFields from 'ee/security_configuration/components/dynamic_fields.vue';
......@@ -22,6 +22,7 @@ export default {
GlButton,
GlIcon,
GlLink,
GlSprintf,
},
inject: {
createSastMergeRequestPath: {
......@@ -55,6 +56,7 @@ export default {
analyzersConfiguration: cloneDeep(this.sastCiConfiguration.analyzers.nodes),
hasSubmissionError: false,
isSubmitting: false,
showAnalyzersTip: false,
};
},
computed: {
......@@ -62,6 +64,9 @@ export default {
return this.analyzersConfiguration.length > 0;
},
},
beforeMount() {
this.shouldRenderAnalyzersTip();
},
methods: {
onSubmit() {
this.isSubmitting = true;
......@@ -100,7 +105,20 @@ export default {
analyzers: this.analyzersConfiguration.map(toSastCiConfigurationAnalyzerEntityInput),
};
},
shouldRenderAnalyzersTip() {
this.analyzersConfiguration.some((analyzer) => {
if (analyzer.enabled === false && this.showAnalyzersTip === false) {
this.showAnalyzersTip = true;
return true;
}
return false;
});
},
onAnalyzerChange(name, updatedAnalyzer) {
// show AnalyzersTip when Analyzer was unchecked
if (updatedAnalyzer.enabled === false && this.showAnalyzersTip === false) {
this.showAnalyzersTip = true;
}
const index = this.analyzersConfiguration.findIndex((analyzer) => analyzer.name === name);
if (index === -1) {
return;
......@@ -108,6 +126,9 @@ export default {
this.analyzersConfiguration.splice(index, 1, updatedAnalyzer);
},
dismissAnalyzersTip() {
this.showAnalyzersTip = false;
},
},
i18n: {
submissionError: s__(
......@@ -122,6 +143,10 @@ export default {
cover all languages across your project, and only run if the language is
detected in the Merge Request.`,
),
analyzersTipHeading: s__('We recommend leaving all SAST analyzers enabled'),
analyzersTipBody: s__(
'Keeping all SAST analyzers enabled future-proofs the project in case new languages are added later on. Determining which analyzers apply is a process that consumes minimal resources and adds minimal time to the pipeline. Leaving all SAST analyzers enabled ensures maximum coverage.',
),
},
};
</script>
......@@ -157,13 +182,27 @@ export default {
:entity="analyzer"
@input="onAnalyzerChange(analyzer.name, $event)"
/>
<gl-alert
v-if="showAnalyzersTip"
data-testid="analyzers-section-tip"
:title="$options.i18n.analyzersTipHeading"
variant="tip"
@dismiss="dismissAnalyzersTip"
>
<gl-sprintf :message="$options.i18n.analyzersTipBody" />
</gl-alert>
</expandable-section>
<hr v-else />
<gl-alert v-if="hasSubmissionError" class="gl-mb-5" variant="danger" :dismissible="false">{{
$options.i18n.submissionError
}}</gl-alert>
<gl-alert
v-if="hasSubmissionError"
data-testid="analyzers-error-alert"
class="gl-mb-5"
variant="danger"
:dismissible="false"
>{{ $options.i18n.submissionError }}</gl-alert
>
<div class="gl-display-flex">
<gl-button
......
---
title: Introduce disabled analyzer warning to SAST Config Page
merge_request: 55172
author:
type: changed
......@@ -28,12 +28,12 @@ export const makeEntities = (count, changes) =>
* generated entities.
* @returns {Object[]}
*/
export const makeAnalyzerEntities = (count, changes) =>
export const makeAnalyzerEntities = (count, changes, isEnabled = true) =>
[...Array(count).keys()].map((i) => ({
name: `nameValue${i}`,
label: `label${i}`,
description: `description${i}`,
enabled: true,
enabled: isEnabled,
...changes,
}));
......@@ -43,7 +43,7 @@ export const makeAnalyzerEntities = (count, changes) =>
* @param {number} totalEntities - The total number of entities to create.
* @returns {SastCiConfiguration}
*/
export const makeSastCiConfiguration = () => {
export const makeSastCiConfiguration = (analyzerEnabled = true) => {
// Call makeEntities just once to ensure unique fields
const entities = makeEntities(3);
......@@ -55,11 +55,15 @@ export const makeSastCiConfiguration = () => {
nodes: [entities.shift()],
},
analyzers: {
nodes: makeAnalyzerEntities(1, {
variables: {
nodes: [entities.shift()],
nodes: makeAnalyzerEntities(
1,
{
variables: {
nodes: [entities.shift()],
},
},
}),
analyzerEnabled,
),
},
};
};
import { GlAlert, GlLink } from '@gitlab/ui';
import { GlLink } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { shallowMount } from '@vue/test-utils';
import { merge } from 'lodash';
......@@ -29,7 +29,10 @@ describe('ConfigurationForm component', () => {
};
const createComponent = ({ mutationResult, ...options } = {}) => {
sastCiConfiguration = makeSastCiConfiguration();
sastCiConfiguration =
options?.analyzerEnabled === false
? makeSastCiConfiguration(options?.analyzerEnabled)
: makeSastCiConfiguration();
wrapper = shallowMount(
ConfigurationForm,
......@@ -65,11 +68,12 @@ describe('ConfigurationForm component', () => {
const findForm = () => wrapper.find('form');
const findSubmitButton = () => wrapper.find({ ref: 'submitButton' });
const findErrorAlert = () => wrapper.find(GlAlert);
const findErrorAlert = () => wrapper.find('[data-testid="analyzers-error-alert"]');
const findCancelButton = () => wrapper.find({ ref: 'cancelButton' });
const findDynamicFieldsComponents = () => wrapper.findAll(DynamicFields);
const findAnalyzerConfigurations = () => wrapper.findAll(AnalyzerConfiguration);
const findAnalyzersSection = () => wrapper.find('[data-testid="analyzers-section"]');
const findAnalyzersSectionTip = () => wrapper.find('[data-testid="analyzers-section-tip"]');
const expectPayloadForEntities = () => {
const expectedPayload = {
......@@ -188,6 +192,11 @@ describe('ConfigurationForm component', () => {
});
});
it('does not render alert-tip', () => {
const analyzersSectionTip = findAnalyzersSectionTip();
expect(analyzersSectionTip.exists()).toBe(false);
});
describe('when an AnalyzerConfiguration emits an input event', () => {
let analyzer;
let updatedEntity;
......@@ -205,6 +214,52 @@ describe('ConfigurationForm component', () => {
expect(analyzer.props('entity')).toBe(updatedEntity);
});
});
describe('when at least 1 analyzer gets disabled', () => {
let analyzer;
let updatedEntity;
beforeEach(() => {
analyzer = findAnalyzerConfigurations().at(0);
// eslint-disable-next-line prefer-destructuring
updatedEntity = sastCiConfiguration.analyzers.nodes[0];
updatedEntity.enabled = false;
analyzer.vm.$emit('input', updatedEntity);
});
it('renders alert-tip', () => {
const analyzersSectionTip = findAnalyzersSectionTip();
expect(analyzersSectionTip.exists()).toBe(true);
expect(analyzersSectionTip.html()).toContain(ConfigurationForm.i18n.analyzersTipHeading);
expect(analyzersSectionTip.html()).toContain(ConfigurationForm.i18n.analyzersTipBody);
});
describe('when alert-tip is dismissed', () => {
beforeEach(() => {
findAnalyzersSectionTip().vm.$emit('dismiss');
return wrapper.vm.$nextTick();
});
it('should not be displayed', () => {
expect(findAnalyzersSectionTip().exists()).toBe(false);
});
});
});
});
describe('on Load with disabled analyzers', () => {
beforeEach(() => {
createComponent({
analyzerEnabled: false,
});
});
it('renders alert-tip', () => {
const analyzersSectionTip = findAnalyzersSectionTip();
expect(analyzersSectionTip.exists()).toBe(true);
expect(analyzersSectionTip.html()).toContain(ConfigurationForm.i18n.analyzersTipHeading);
expect(analyzersSectionTip.html()).toContain(ConfigurationForm.i18n.analyzersTipBody);
});
});
describe('when submitting the form', () => {
......
......@@ -17368,6 +17368,9 @@ msgstr ""
msgid "Keep editing"
msgstr ""
msgid "Keeping all SAST analyzers enabled future-proofs the project in case new languages are added later on. Determining which analyzers apply is a process that consumes minimal resources and adds minimal time to the pipeline. Leaving all SAST analyzers enabled ensures maximum coverage."
msgstr ""
msgid "Kerberos access denied"
msgstr ""
......@@ -33422,6 +33425,9 @@ msgstr ""
msgid "We recommend cloud-based mobile authenticator apps such as Authy, Duo Mobile, and LastPass. They can restore access if you lose your hardware device."
msgstr ""
msgid "We recommend leaving all SAST analyzers enabled"
msgstr ""
msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
msgstr ""
......
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