Commit ab0560cd authored by Mark Florian's avatar Mark Florian

Merge branch '238603-analyzer-configuration-part-2' into 'master'

Implement dynamic fields inside Analyzer Component Part II

Closes #238603

See merge request gitlab-org/gitlab!41772
parents 987279df 0b9ff82f
<script>
import { GlFormCheckbox } from '@gitlab/ui';
import { GlFormCheckbox, GlFormGroup } from '@gitlab/ui';
import DynamicFields from './dynamic_fields.vue';
import { isValidAnalyzerEntity } from './utils';
export default {
components: {
GlFormGroup,
GlFormCheckbox,
DynamicFields,
},
model: {
prop: 'entity',
......@@ -18,9 +21,18 @@ export default {
validator: isValidAnalyzerEntity,
},
},
computed: {
hasConfiguration() {
return this.entity.configuration?.length > 0;
},
},
methods: {
onToggle(value) {
const entity = { ...this.entity, enabled: value };
onToggle(enabled) {
const entity = { ...this.entity, enabled };
this.$emit('input', entity);
},
onConfigurationUpdate(configuration) {
const entity = { ...this.entity, configuration };
this.$emit('input', entity);
},
},
......@@ -28,8 +40,18 @@ export default {
</script>
<template>
<gl-form-group>
<gl-form-checkbox :id="entity.name" :checked="entity.enabled" @input="onToggle">
<span class="gl-font-weight-bold">{{ entity.label }}</span>
<span v-if="entity.description" class="gl-text-gray-500">({{ entity.description }})</span>
</gl-form-checkbox>
<dynamic-fields
v-if="hasConfiguration"
:disabled="!entity.enabled"
class="gl-ml-6"
:entities="entity.configuration"
@input="onConfigurationUpdate"
/>
</gl-form-group>
</template>
<script>
import { GlFormGroup } from '@gitlab/ui';
import FormInput from './form_input.vue';
import { isValidConfigurationEntity } from './utils';
export default {
components: {
GlFormGroup,
FormInput,
},
model: {
......@@ -16,6 +18,11 @@ export default {
required: true,
validator: value => value.every(isValidConfigurationEntity),
},
disabled: {
type: Boolean,
required: false,
default: false,
},
},
methods: {
componentForEntity({ type }) {
......@@ -47,7 +54,7 @@ export default {
</script>
<template>
<div>
<gl-form-group :disabled="disabled">
<component
:is="componentForEntity(entity)"
v-for="entity in entities"
......@@ -56,5 +63,5 @@ export default {
v-bind="entity"
@input="onInput(entity.field, $event)"
/>
</div>
</gl-form-group>
</template>
import { mount } from '@vue/test-utils';
import AnalyzerConfiguration from 'ee/security_configuration/sast/components/analyzer_configuration.vue';
import DynamicFields from 'ee/security_configuration/sast/components/dynamic_fields.vue';
describe('AnalyzerConfiguration component', () => {
let wrapper;
......@@ -20,6 +21,7 @@ describe('AnalyzerConfiguration component', () => {
};
const findInputElement = () => wrapper.find('input[type="checkbox"]');
const findDynamicFields = () => wrapper.find(DynamicFields);
afterEach(() => {
wrapper.destroy();
......@@ -66,4 +68,60 @@ describe('AnalyzerConfiguration component', () => {
});
});
});
describe('configuration form', () => {
describe('when there are no SastCiConfigurationEntity', () => {
beforeEach(() => {
createComponent({
props: { entity },
});
});
it('does not render the nested dynamic forms', () => {
expect(findDynamicFields().exists()).toBe(false);
});
});
describe('when there are one or more SastCiConfigurationEntity', () => {
const analyzerEntity = {
...entity,
enabled: false,
configuration: [
{
defaultValue: 'defaultVal',
description: 'desc',
field: 'field',
type: 'string',
value: 'val',
label: 'label',
},
],
};
beforeEach(() => {
createComponent({
props: { entity: analyzerEntity },
});
});
it('it renders the nested dynamic forms', () => {
expect(findDynamicFields().exists()).toBe(true);
});
it('it emits an input event when dynamic form fields emits an input event', () => {
findDynamicFields().vm.$emit('input', analyzerEntity.configuration);
const [[payload]] = wrapper.emitted('input');
expect(payload).toEqual(analyzerEntity);
});
it('passes the disabled prop to dynamic fields component', () => {
expect(findDynamicFields().props('disabled')).toBe(!analyzerEntity.enabled);
});
it('passes the entities prop to the dynamic fields component', () => {
expect(findDynamicFields().props('entities')).toBe(analyzerEntity.configuration);
});
});
});
});
import { shallowMount } from '@vue/test-utils';
import { shallowMount, mount } from '@vue/test-utils';
import DynamicFields from 'ee/security_configuration/sast/components/dynamic_fields.vue';
import { makeEntities } from './helpers';
describe('DynamicFields component', () => {
let wrapper;
const createComponent = (props = {}) => {
wrapper = shallowMount(DynamicFields, {
const createComponent = (props = {}, mountFn = shallowMount) => {
wrapper = mountFn(DynamicFields, {
propsData: {
...props,
},
......@@ -34,6 +34,21 @@ describe('DynamicFields component', () => {
});
});
describe.each([true, false])('given the disabled prop is %p', disabled => {
beforeEach(() => {
createComponent({ entities: [], disabled }, mount);
});
it('uses a fieldset as the root element', () => {
expect(wrapper.element.tagName).toBe('FIELDSET');
});
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset#attr-disabled
it(`${disabled ? 'sets' : 'does not set'} the disabled attribute on the root element`, () => {
expect('disabled' in wrapper.attributes()).toBe(disabled);
});
});
describe('given valid entities', () => {
let entities;
let fields;
......
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