Skip to content
代码片段 群组 项目
未验证 提交 2dc33014 编辑于 作者: Lorenz van Herwaarden's avatar Lorenz van Herwaarden 提交者: GitLab
浏览文件

Limit vulnerability management policy to 5 rules

Limit the amount of rules that can be added for a
vulnerability management policy to 5 and make sure the Add rule button
gets hidden conditionally.
上级 e587ad1c
No related branches found
No related tags found
无相关合并请求
<script> <script>
import { GlButton } from '@gitlab/ui'; import { GlButton, GlTooltipDirective } from '@gitlab/ui';
import { s__, sprintf, n__ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/security_orchestration/components/constants'; import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/security_orchestration/components/constants';
import { extractPolicyContent } from 'ee/security_orchestration/components/utils'; import { extractPolicyContent } from 'ee/security_orchestration/components/utils';
...@@ -15,6 +16,7 @@ import { ...@@ -15,6 +16,7 @@ import {
EDITOR_MODE_YAML, EDITOR_MODE_YAML,
PARSING_ERROR_MESSAGE, PARSING_ERROR_MESSAGE,
SECURITY_POLICY_ACTIONS, SECURITY_POLICY_ACTIONS,
MAX_ALLOWED_RULES_LENGTH,
} from '../constants'; } from '../constants';
import EditorLayout from '../editor_layout.vue'; import EditorLayout from '../editor_layout.vue';
import DimDisableContainer from '../dim_disable_container.vue'; import DimDisableContainer from '../dim_disable_container.vue';
...@@ -34,6 +36,9 @@ export default { ...@@ -34,6 +36,9 @@ export default {
RULES_LABEL, RULES_LABEL,
ADD_RULE_LABEL, ADD_RULE_LABEL,
ACTIONS_LABEL, ACTIONS_LABEL,
exceedingRulesMessage: s__(
'SecurityOrchestration|You can add a maximum of %{rulesCount} %{rules}.',
),
}, },
components: { components: {
GlButton, GlButton,
...@@ -42,6 +47,7 @@ export default { ...@@ -42,6 +47,7 @@ export default {
ActionSection, ActionSection,
DimDisableContainer, DimDisableContainer,
}, },
directives: { GlTooltip: GlTooltipDirective },
mixins: [glFeatureFlagsMixin()], mixins: [glFeatureFlagsMixin()],
inject: ['namespacePath'], inject: ['namespacePath'],
props: { props: {
...@@ -92,6 +98,18 @@ export default { ...@@ -92,6 +98,18 @@ export default {
parsingError, parsingError,
}; };
}, },
computed: {
canAddRule() {
return this.policy.rules?.length < MAX_ALLOWED_RULES_LENGTH;
},
addRuleTitle() {
const rules = n__('rule', 'rules', this.policy.rules?.length);
return sprintf(this.$options.i18n.exceedingRulesMessage, {
rulesCount: MAX_ALLOWED_RULES_LENGTH,
rules,
});
},
},
methods: { methods: {
changeEditorMode(mode) { changeEditorMode(mode) {
this.mode = mode; this.mode = mode;
...@@ -184,9 +202,22 @@ export default { ...@@ -184,9 +202,22 @@ export default {
/> />
<div class="security-policies-bg-subtle gl-mb-5 gl-rounded-base gl-p-5"> <div class="security-policies-bg-subtle gl-mb-5 gl-rounded-base gl-p-5">
<gl-button variant="link" data-testid="add-rule" @click="addRule"> <span
{{ $options.i18n.ADD_RULE_LABEL }} v-gl-tooltip="{
</gl-button> disabled: canAddRule,
title: addRuleTitle,
}"
data-testid="add-rule-wrapper"
>
<gl-button
variant="link"
data-testid="add-rule"
:disabled="!canAddRule"
@click="addRule"
>
{{ $options.i18n.ADD_RULE_LABEL }}
</gl-button>
</span>
</div> </div>
</dim-disable-container> </dim-disable-container>
</template> </template>
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
"rules": { "rules": {
"description": "Specifies conditions when this policy should be applied.", "description": "Specifies conditions when this policy should be applied.",
"type": "array", "type": "array",
"maxItems": 5,
"additionalItems": false, "additionalItems": false,
"items": { "items": {
"type": "object", "type": "object",
......
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { DEFAULT_ASSIGNED_POLICY_PROJECT } from 'ee/security_orchestration/constants'; import { DEFAULT_ASSIGNED_POLICY_PROJECT } from 'ee/security_orchestration/constants';
import EditorComponent from 'ee/security_orchestration/components/policy_editor/vulnerability_management/editor_component.vue'; import EditorComponent from 'ee/security_orchestration/components/policy_editor/vulnerability_management/editor_component.vue';
import EditorLayout from 'ee/security_orchestration/components/policy_editor/editor_layout.vue'; import EditorLayout from 'ee/security_orchestration/components/policy_editor/editor_layout.vue';
...@@ -25,6 +26,9 @@ describe('EditorComponent', () => { ...@@ -25,6 +26,9 @@ describe('EditorComponent', () => {
const factory = ({ propsData = {}, provide = {} } = {}) => { const factory = ({ propsData = {}, provide = {} } = {}) => {
wrapper = shallowMountExtended(EditorComponent, { wrapper = shallowMountExtended(EditorComponent, {
directives: {
GlTooltip: createMockDirective('gl-tooltip'),
},
propsData: { propsData: {
assignedPolicyProject: DEFAULT_ASSIGNED_POLICY_PROJECT, assignedPolicyProject: DEFAULT_ASSIGNED_POLICY_PROJECT,
isCreating: false, isCreating: false,
...@@ -39,11 +43,11 @@ describe('EditorComponent', () => { ...@@ -39,11 +43,11 @@ describe('EditorComponent', () => {
}); });
}; };
const factoryWithExistingPolicy = () => { const factoryWithExistingPolicy = ({ policy = {} } = {}) => {
return factory({ return factory({
propsData: { propsData: {
assignedPolicyProject: ASSIGNED_POLICY_PROJECT, assignedPolicyProject: ASSIGNED_POLICY_PROJECT,
existingPolicy: mockVulnerabilityManagementObject, existingPolicy: { ...mockVulnerabilityManagementObject, ...policy },
isEditing: true, isEditing: true,
}, },
}); });
...@@ -53,6 +57,8 @@ describe('EditorComponent', () => { ...@@ -53,6 +57,8 @@ describe('EditorComponent', () => {
const findRuleSection = () => wrapper.findComponent(RuleSection); const findRuleSection = () => wrapper.findComponent(RuleSection);
const findAllRuleSections = () => wrapper.findAllComponents(RuleSection); const findAllRuleSections = () => wrapper.findAllComponents(RuleSection);
const findAddRuleButton = () => wrapper.findByTestId('add-rule'); const findAddRuleButton = () => wrapper.findByTestId('add-rule');
const findTooltip = () =>
getBinding(wrapper.findByTestId('add-rule-wrapper').element, 'gl-tooltip');
const findActionSection = () => wrapper.findComponent(ActionSection); const findActionSection = () => wrapper.findComponent(ActionSection);
beforeEach(() => { beforeEach(() => {
...@@ -105,6 +111,20 @@ describe('EditorComponent', () => { ...@@ -105,6 +111,20 @@ describe('EditorComponent', () => {
it('shows correct label for add rule button', () => { it('shows correct label for add rule button', () => {
expect(findAddRuleButton().text()).toBe('Add new rule'); expect(findAddRuleButton().text()).toBe('Add new rule');
expect(findAddRuleButton().props('disabled')).toBe(false);
expect(findTooltip().value.disabled).toBe(true);
});
it('disables add button when the limit of 5 rules has been reached', () => {
const limit = 5;
const { id, ...rule } = mockVulnerabilityManagementObject.rules[0];
factoryWithExistingPolicy({ policy: { rules: [rule, rule, rule, rule, rule] } });
expect(findAllRuleSections()).toHaveLength(limit);
expect(findAddRuleButton().props('disabled')).toBe(true);
expect(findTooltip().value).toMatchObject({
disabled: false,
title: 'You can add a maximum of 5 rules.',
});
}); });
it('removes rule when "remove" event is emitted', async () => { it('removes rule when "remove" event is emitted', async () => {
......
...@@ -50537,6 +50537,9 @@ msgstr "" ...@@ -50537,6 +50537,9 @@ msgstr ""
msgid "SecurityOrchestration|You already have the maximum %{maximumAllowed} %{policyType} %{instance}." msgid "SecurityOrchestration|You already have the maximum %{maximumAllowed} %{policyType} %{instance}."
msgstr "" msgstr ""
   
msgid "SecurityOrchestration|You can add a maximum of %{rulesCount} %{rules}."
msgstr ""
msgid "SecurityOrchestration|You can select this option only once." msgid "SecurityOrchestration|You can select this option only once."
msgstr "" msgstr ""
   
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册