diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/action/approver_action.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/action/approver_action.vue index cfe8ad970a6ba7862b2fa8b47db8c45dc573b8dd..96921d35bef5e9a48fc222a2ebcb1636a7ee3b5d 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/action/approver_action.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/action/approver_action.vue @@ -1,4 +1,5 @@ <script> +import { isNumber } from 'lodash'; import { GlSprintf, GlIcon, GlFormInput, GlPopover, GlButton } from '@gitlab/ui'; import SectionLayout from 'ee/security_orchestration/components/policy_editor/section_layout.vue'; import { @@ -77,8 +78,17 @@ export default { selectedRoles() { return this.initAction.role_approvers || []; }, + approvalsRequiredValid() { + const { approvals_required: approvalsRequired } = this.initAction; + const isValidNumber = isNumber(approvalsRequired) && !Number.isNaN(approvalsRequired); + + return isValidNumber && approvalsRequired >= 1; + }, approvalsRequired() { - return this.initAction.approvals_required; + return this.approvalsRequiredValid ? this.initAction.approvals_required : 1; + }, + approvalsRequiredFieldValid() { + return this.approvalsRequiredValid && this.isApproverFieldValid; }, humanizedTemplate() { return this.isWarnType ? WARN_TEMPLATE : getDefaultHumanizedTemplate(this.approvalsRequired); @@ -196,7 +206,7 @@ export default { <template #approvalsRequired> <gl-form-input - :state="isApproverFieldValid" + :state="approvalsRequiredFieldValid" :value="approvalsRequired" data-testid="approvals-required-input" type="number" diff --git a/ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/action/approver_action_spec.js b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/action/approver_action_spec.js index a478908e8122427a3ae333638c067ef7e7ce71bd..d331cd03274f3982a480ed6fd597f9957720463e 100644 --- a/ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/action/approver_action_spec.js +++ b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/action/approver_action_spec.js @@ -419,4 +419,18 @@ describe('ApproverAction', () => { ]); }); }); + + describe('sanitize required approval actions', () => { + it.each(['invalid', NaN, undefined, null, -1, -10, 0.5])( + 'validates required approval action number for invalid type', + (approvalsRequired) => { + createWrapper({ + initAction: { ...DEFAULT_ACTION, approvals_required: approvalsRequired }, + }); + + expect(findApprovalsRequiredInput().props('value')).toBe(1); + expect(findApprovalsRequiredInput().props('state')).toBe(false); + }, + ); + }); });