diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/vulnerability_management/editor_component.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/vulnerability_management/editor_component.vue index f28d8cdee24722482a8fa705a9ea5baddce1d304..273bf041eb9686c4f2ce287e309adb35b3ab32fb 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/vulnerability_management/editor_component.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/vulnerability_management/editor_component.vue @@ -7,6 +7,7 @@ import { EDITOR_MODE_RULE, EDITOR_MODE_YAML, PARSING_ERROR_MESSAGE, + SECURITY_POLICY_ACTIONS, } from '../constants'; import EditorLayout from '../editor_layout.vue'; import DimDisableContainer from '../dim_disable_container.vue'; @@ -16,6 +17,7 @@ import RuleSection from './rule/rule_section.vue'; import ActionSection from './action/action_section.vue'; export default { + SECURITY_POLICY_ACTIONS, EDITOR_MODE_RULE, EDITOR_MODE_YAML, i18n: { @@ -41,6 +43,14 @@ export default { required: false, default: null, }, + isCreating: { + type: Boolean, + required: true, + }, + isDeleting: { + type: Boolean, + required: true, + }, isEditing: { type: Boolean, required: true, @@ -62,16 +72,28 @@ export default { mode: EDITOR_MODE_RULE, policy, yamlEditorValue, - isUpdatingPolicy: false, - isRemovingPolicy: false, hasParsingError, parsingError, }; }, + computed: { + policyActionName() { + return this.isEditing + ? this.$options.SECURITY_POLICY_ACTIONS.REPLACE + : this.$options.SECURITY_POLICY_ACTIONS.APPEND; + }, + }, methods: { changeEditorMode(mode) { this.mode = mode; }, + async handleModifyPolicy(act) { + // Assumes feature flag securityPoliciesProjectBackgroundWorker is enabled + this.$emit('save', { + action: act || this.policyActionName, + policy: this.yamlEditorValue, + }); + }, handleUpdateProperty(property, value) { this.policy[property] = value; this.updateYamlEditorValue(this.policy); @@ -107,10 +129,12 @@ export default { :policy="policy" :yaml-editor-value="yamlEditorValue" :is-editing="isEditing" - :is-removing-policy="isRemovingPolicy" - :is-updating-policy="isUpdatingPolicy" + :is-removing-policy="isDeleting" + :is-updating-policy="isCreating" :has-parsing-error="hasParsingError" :parsing-error="parsingError" + @remove-policy="handleModifyPolicy($options.SECURITY_POLICY_ACTIONS.REMOVE)" + @save-policy="handleModifyPolicy()" @update-editor-mode="changeEditorMode" @update-property="handleUpdateProperty" @update-yaml="handleUpdateYaml" diff --git a/ee/spec/frontend/security_orchestration/components/policy_editor/vulnerability_management/editor_component_spec.js b/ee/spec/frontend/security_orchestration/components/policy_editor/vulnerability_management/editor_component_spec.js index e2e0e6acc612e51625793076eeb6d4ffb002afb7..76789df3c78fd3409ea06ce5ef4e0c7108f274d4 100644 --- a/ee/spec/frontend/security_orchestration/components/policy_editor/vulnerability_management/editor_component_spec.js +++ b/ee/spec/frontend/security_orchestration/components/policy_editor/vulnerability_management/editor_component_spec.js @@ -1,4 +1,5 @@ import { nextTick } from 'vue'; +import waitForPromises from 'helpers/wait_for_promises'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { DEFAULT_ASSIGNED_POLICY_PROJECT } from 'ee/security_orchestration/constants'; import EditorComponent from 'ee/security_orchestration/components/policy_editor/vulnerability_management/editor_component.vue'; @@ -6,6 +7,9 @@ import EditorLayout from 'ee/security_orchestration/components/policy_editor/edi import RuleSection from 'ee/security_orchestration/components/policy_editor/vulnerability_management/rule/rule_section.vue'; import ActionSection from 'ee/security_orchestration/components/policy_editor/vulnerability_management/action/action_section.vue'; import { DEFAULT_VULNERABILITY_MANAGEMENT_POLICY } from 'ee/security_orchestration/components/policy_editor/vulnerability_management/constants'; + +import { SECURITY_POLICY_ACTIONS } from 'ee/security_orchestration/components/policy_editor/constants'; +import { ASSIGNED_POLICY_PROJECT } from 'ee_jest/security_orchestration/mocks/mock_data'; import { mockVulnerabilityManagementManifest, mockVulnerabilityManagementObject, @@ -19,6 +23,8 @@ describe('EditorComponent', () => { wrapper = shallowMountExtended(EditorComponent, { propsData: { assignedPolicyProject: DEFAULT_ASSIGNED_POLICY_PROJECT, + isCreating: false, + isDeleting: false, isEditing: false, ...propsData, }, @@ -29,6 +35,16 @@ describe('EditorComponent', () => { }); }; + const factoryWithExistingPolicy = () => { + return factory({ + propsData: { + assignedPolicyProject: ASSIGNED_POLICY_PROJECT, + existingPolicy: mockVulnerabilityManagementObject, + isEditing: true, + }, + }); + }; + const findPolicyEditorLayout = () => wrapper.findComponent(EditorLayout); const findRuleSection = () => wrapper.findComponent(RuleSection); const findAllRuleSections = () => wrapper.findAllComponents(RuleSection); @@ -124,4 +140,18 @@ describe('EditorComponent', () => { ); }); }); + + describe('modifying a policy', () => { + it.each` + status | action | event | factoryFn | yamlEditorValue + ${'creating a new policy'} | ${SECURITY_POLICY_ACTIONS.APPEND} | ${'save-policy'} | ${factory} | ${DEFAULT_VULNERABILITY_MANAGEMENT_POLICY} + ${'updating an existing policy'} | ${SECURITY_POLICY_ACTIONS.REPLACE} | ${'save-policy'} | ${factoryWithExistingPolicy} | ${mockVulnerabilityManagementManifest} + ${'deleting an existing policy'} | ${SECURITY_POLICY_ACTIONS.REMOVE} | ${'remove-policy'} | ${factoryWithExistingPolicy} | ${mockVulnerabilityManagementManifest} + `('emits "save" when $status', async ({ action, event, factoryFn, yamlEditorValue }) => { + factoryFn(); + findPolicyEditorLayout().vm.$emit(event); + await waitForPromises(); + expect(wrapper.emitted('save')).toEqual([[{ action, policy: yamlEditorValue }]]); + }); + }); }); diff --git a/ee/spec/frontend/security_orchestration/mocks/mock_vulnerability_management_policy_data.js b/ee/spec/frontend/security_orchestration/mocks/mock_vulnerability_management_policy_data.js index 8ca7115b33671a7ffe5d0effcd669a98c3bb8a9f..a7387e811656a5d64666a4cb153a9fe482f245c0 100644 --- a/ee/spec/frontend/security_orchestration/mocks/mock_vulnerability_management_policy_data.js +++ b/ee/spec/frontend/security_orchestration/mocks/mock_vulnerability_management_policy_data.js @@ -24,11 +24,16 @@ actions: - type: auto_resolve rules: - type: no_longer_detected - scanners: ["sast", "dependency_scanning"] - severity_levels: ["high", "medium"] + scanners: + - sast + - dependency_scanning + severity_levels: + - high + - medium - type: no_longer_detected scanners: [] - severity_levels: ["low"] + severity_levels: + - low `; export const mockVulnerabilityManagementObject = fromYaml({