Commit 9f155ff4 authored by Phil Hughes's avatar Phil Hughes

Merge branch '346162-policy-editor-v2' into 'master'

Add policy editor version 2

See merge request gitlab-org/gitlab!83395
parents 86146204 2a082e24
......@@ -4,7 +4,7 @@ import { s__ } from '~/locale';
import { getParameterByName, removeParams, visitUrl } from '~/lib/utils/url_utility';
import { POLICY_TYPE_COMPONENT_OPTIONS } from '../constants';
import PolicySelection from './policy_selection.vue';
import PolicyEditor from './policy_editor.vue';
import PolicyEditor from './policy_editor_v2.vue';
export default {
components: {
......
<script>
import { GlAlert, GlFormGroup, GlFormSelect } from '@gitlab/ui';
import { POLICY_TYPE_COMPONENT_OPTIONS } from '../constants';
import EnvironmentPicker from '../environment_picker.vue';
import NetworkPolicyEditor from './network_policy/network_policy_editor.vue';
import ScanExecutionPolicyEditor from './scan_execution_policy/scan_execution_policy_editor.vue';
import ScanResultPolicyEditor from './scan_result_policy/scan_result_policy_editor.vue';
export default {
components: {
GlAlert,
GlFormGroup,
GlFormSelect,
EnvironmentPicker,
NetworkPolicyEditor,
ScanExecutionPolicyEditor,
ScanResultPolicyEditor,
},
props: {
assignedPolicyProject: {
type: Object,
required: true,
},
existingPolicy: {
type: Object,
required: false,
default: null,
},
// This is the `value` field of the POLICY_TYPE_COMPONENT_OPTIONS
selectedPolicyType: {
type: String,
required: true,
},
},
data() {
return {
error: '',
errorMessages: [],
};
},
computed: {
isEditing() {
if (!this.existingPolicy) {
return false;
}
return Boolean(
this.existingPolicy.creation_timestamp ||
[
POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.urlParameter,
POLICY_TYPE_COMPONENT_OPTIONS.scanResult?.urlParameter,
].includes(this.existingPolicy.type),
);
},
policyTypes() {
return Object.values(POLICY_TYPE_COMPONENT_OPTIONS);
},
policyOptions() {
return (
this.policyTypes.find(({ value }) => value === this.selectedPolicyType) ||
POLICY_TYPE_COMPONENT_OPTIONS.container
);
},
shouldAllowPolicyTypeSelection() {
return !this.existingPolicy;
},
},
methods: {
setError(errors) {
[this.error, ...this.errorMessages] = errors.split('\n');
},
},
};
</script>
<template>
<section class="policy-editor">
<gl-alert v-if="error" :title="error" dismissible variant="danger" @dismiss="setError('')">
<ul v-if="errorMessages.length" class="gl-mb-0! gl-ml-5">
<li v-for="errorMessage in errorMessages" :key="errorMessage">
{{ errorMessage }}
</li>
</ul>
</gl-alert>
<div class="gl-display-flex">
<environment-picker v-if="policyOptions.shouldShowEnvironmentPicker" />
</div>
<component
:is="policyOptions.component"
:existing-policy="existingPolicy"
:assigned-policy-project="assignedPolicyProject"
:is-editing="isEditing"
@error="setError($event)"
/>
</section>
</template>
......@@ -4,7 +4,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/threat_monitoring/components/constants';
import NewPolicy from 'ee/threat_monitoring/components/policy_editor/new_policy.vue';
import PolicySelection from 'ee/threat_monitoring/components/policy_editor/policy_selection.vue';
import PolicyEditor from 'ee/threat_monitoring/components/policy_editor/policy_editor.vue';
import PolicyEditor from 'ee/threat_monitoring/components/policy_editor/policy_editor_v2.vue';
describe('NewPolicy component', () => {
let wrapper;
......
import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/threat_monitoring/components/constants';
import EnvironmentPicker from 'ee/threat_monitoring/components/environment_picker.vue';
import NetworkPolicyEditor from 'ee/threat_monitoring/components/policy_editor/network_policy/network_policy_editor.vue';
import PolicyEditor from 'ee/threat_monitoring/components/policy_editor/policy_editor_v2.vue';
import ScanExecutionPolicyEditor from 'ee/threat_monitoring/components/policy_editor/scan_execution_policy/scan_execution_policy_editor.vue';
import ScanResultPolicyEditor from 'ee/threat_monitoring/components/policy_editor/scan_result_policy/scan_result_policy_editor.vue';
import { DEFAULT_ASSIGNED_POLICY_PROJECT } from 'ee/threat_monitoring/constants';
describe('PolicyEditor V2 component', () => {
let wrapper;
const findAlert = () => wrapper.findComponent(GlAlert);
const findEnvironmentPicker = () => wrapper.findComponent(EnvironmentPicker);
const findNetworkPolicyEditor = () => wrapper.findComponent(NetworkPolicyEditor);
const findScanExecutionPolicyEditor = () => wrapper.findComponent(ScanExecutionPolicyEditor);
const findScanResultPolicyEditor = () => wrapper.findComponent(ScanResultPolicyEditor);
const factory = ({ propsData = {}, provide = {} } = {}) => {
wrapper = shallowMount(PolicyEditor, {
propsData: {
assignedPolicyProject: DEFAULT_ASSIGNED_POLICY_PROJECT,
selectedPolicyType: 'container',
...propsData,
},
provide: {
policyType: undefined,
...provide,
},
});
};
afterEach(() => {
wrapper.destroy();
});
describe('default', () => {
beforeEach(factory);
it.each`
component | status | findComponent | state
${'environment picker'} | ${'does display'} | ${findEnvironmentPicker} | ${true}
${'alert'} | ${'does not display'} | ${findAlert} | ${false}
`('$status the $component', ({ findComponent, state }) => {
expect(findComponent().exists()).toBe(state);
});
it('renders the network policy editor component', () => {
expect(findNetworkPolicyEditor().props('existingPolicy')).toBe(null);
});
it('shows an alert when "error" is emitted from the component', async () => {
const errorMessage = 'test';
findNetworkPolicyEditor().vm.$emit('error', errorMessage);
await nextTick();
const alert = findAlert();
expect(alert.exists()).toBe(true);
expect(alert.props('title')).toBe(errorMessage);
});
it('shows an alert with details when multiline "error" is emitted from the component', async () => {
const errorMessages = 'title\ndetail1';
findNetworkPolicyEditor().vm.$emit('error', errorMessages);
await nextTick();
const alert = findAlert();
expect(alert.exists()).toBe(true);
expect(alert.props('title')).toBe('title');
expect(alert.text()).toBe('detail1');
});
it.each`
policyTypeId | findComponent
${POLICY_TYPE_COMPONENT_OPTIONS.container.value} | ${findNetworkPolicyEditor}
${POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value} | ${findScanExecutionPolicyEditor}
${POLICY_TYPE_COMPONENT_OPTIONS.scanResult.value} | ${findScanResultPolicyEditor}
`(
'renders the policy editor of type $policyType when selected',
async ({ findComponent, policyTypeId }) => {
wrapper.setProps({ selectedPolicyType: policyTypeId });
await nextTick();
const component = findComponent();
expect(component.exists()).toBe(true);
expect(component.props('isEditing')).toBe(false);
},
);
});
});
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