Skip to content
Snippets Groups Projects
Commit 5862d234 authored by Savas Vedova's avatar Savas Vedova
Browse files

Refactor form sections

Move the name and description fields into their own sections. This
helps maintaining a cleaner code by splitting the logic across multiple
child components.
parent c7a6ab39
No related branches found
No related tags found
No related merge requests found
<script>
import { GlForm, GlFormGroup, GlFormInput, GlFormTextarea } from '@gitlab/ui';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import { s__, __ } from '~/locale';
import { GlForm } from '@gitlab/ui';
import { s__ } from '~/locale';
import SectionDetails from './section_details.vue';
import SectionName from './section_name.vue';
 
export default {
name: 'NewVulnerabilityForm',
components: {
GlForm,
GlFormGroup,
GlFormInput,
GlFormTextarea,
MarkdownField,
SectionDetails,
},
props: {
markdownDocsPath: {
type: String,
required: true,
},
markdownPreviewPath: {
type: String,
required: true,
},
SectionName,
},
data() {
return {
isSubmitting: false,
form: {
vulnerabilityName: '',
vulnerabilityDesc: '',
Loading
Loading
@@ -46,20 +32,6 @@ export default {
description: s__(
'VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report.',
),
form: {
vulnerabilityName: {
label: __('Name'),
description: s__(
'VulnerabilityManagement|Vulnerability name or type. Ex: Cross-site scripting',
),
},
vulnerabilityDesc: {
label: __('Description'),
description: s__(
'VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc.',
),
},
},
},
};
</script>
Loading
Loading
@@ -75,48 +47,7 @@ export default {
</p>
</header>
<gl-form class="gl-p-4 gl-w-85p" @submit.prevent>
<gl-form-group
:label="$options.i18n.form.vulnerabilityName.label"
:description="$options.i18n.form.vulnerabilityName.description"
label-for="form-vulnerability-name"
class="gl-mb-6"
>
<gl-form-input
id="form-vulnerability-name"
v-model="form.vulnerabilityName"
class="gl-mb-2"
type="text"
/>
</gl-form-group>
<gl-form-group
:label="$options.i18n.form.vulnerabilityDesc.label"
label-for="form-vulnerability-desc"
>
<div
class="gl-border-solid gl-border-gray-100 gl-border-1 gl-pt-3 gl-pb-5 gl-px-3 gl-rounded-base"
>
<markdown-field
ref="markdownField"
:can-attach-file="false"
:add-spacing-classes="false"
:markdown-preview-path="markdownPreviewPath"
:markdown-docs-path="markdownDocsPath"
:textarea-value="form.vulnerabilityDesc"
:is-submitting="isSubmitting"
>
<template #textarea>
<gl-form-textarea
id="form-vulnerability-desc"
v-model="form.vulnerabilityDesc"
rows="8"
class="gl-shadow-none! gl-px-0! gl-py-4! gl-h-auto!"
:aria-label="$options.i18n.form.vulnerabilityDesc.description"
:placeholder="$options.i18n.form.vulnerabilityDesc.description"
/>
</template>
</markdown-field>
</div>
</gl-form-group>
<section-name @change="updateFormValues" />
<section-details @change="updateFormValues" />
</gl-form>
</div>
Loading
Loading
<script>
import { GlFormGroup, GlFormInput, GlFormTextarea } from '@gitlab/ui';
import { s__, __ } from '~/locale';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
export default {
components: {
GlFormGroup,
GlFormInput,
GlFormTextarea,
MarkdownField,
},
inject: ['markdownDocsPath', 'markdownPreviewPath'],
data() {
return {
isSubmitting: false,
vulnerabilityName: '',
vulnerabilityDesc: '',
};
},
methods: {
emitChanges() {
this.$emit('change', {
vulnerabilityName: this.vulnerabilityName,
vulnerabilityDesc: this.vulnerabilityDesc,
});
},
},
i18n: {
vulnerabilityName: {
label: __('Name'),
description: s__(
'VulnerabilityManagement|Vulnerability name or type. Ex: Cross-site scripting',
),
},
vulnerabilityDesc: {
label: __('Description'),
description: s__(
'VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc.',
),
},
},
};
</script>
<template>
<div>
<gl-form-group
:label="$options.i18n.vulnerabilityName.label"
:description="$options.i18n.vulnerabilityName.description"
label-for="form-vulnerability-name"
class="gl-mb-6"
>
<gl-form-input
id="form-vulnerability-name"
v-model="vulnerabilityName"
class="gl-mb-2"
type="text"
@change="emitChanges"
/>
</gl-form-group>
<gl-form-group
:label="$options.i18n.vulnerabilityDesc.label"
label-for="form-vulnerability-desc"
>
<div
class="gl-border-solid gl-border-gray-100 gl-border-1 gl-pt-3 gl-pb-5 gl-px-3 gl-rounded-base"
>
<markdown-field
ref="markdownField"
:can-attach-file="false"
:add-spacing-classes="false"
:markdown-preview-path="markdownPreviewPath"
:markdown-docs-path="markdownDocsPath"
:textarea-value="vulnerabilityDesc"
:is-submitting="isSubmitting"
>
<template #textarea>
<gl-form-textarea
id="form-vulnerability-desc"
v-model="vulnerabilityDesc"
rows="8"
class="gl-shadow-none! gl-px-0! gl-py-4! gl-h-auto!"
:aria-label="$options.i18n.vulnerabilityDesc.description"
:placeholder="$options.i18n.vulnerabilityDesc.description"
@change="emitChanges"
/>
</template>
</markdown-field>
</div>
</gl-form-group>
</div>
</template>
Loading
Loading
@@ -12,7 +12,7 @@ export default (el) => {
apolloProvider,
render: (h) =>
h(App, {
props: {
inject: {
markdownDocsPath: el.dataset.markdownDocsPath,
markdownPreviewPath: el.dataset.markdownPreviewPath,
},
Loading
Loading
import { GlForm } from '@gitlab/ui';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import NewVulnerability from 'ee/vulnerabilities/components/new_vulnerability/new_vulnerability.vue';
import SectionName from 'ee/vulnerabilities/components/new_vulnerability/section_name.vue';
import SectionDetails from 'ee/vulnerabilities/components/new_vulnerability/section_details.vue';
 
describe('New vulnerability component', () => {
let wrapper;
const markdownDocsPath = '/path/to/markdown/docs';
const markdownPreviewPath = '/path/to/markdown/preview';
 
const findSectionName = () => wrapper.findComponent(SectionName);
const findSectionDetails = () => wrapper.findComponent(SectionDetails);
 
const createWrapper = () => {
return mountExtended(NewVulnerability, {
propsData: {
markdownDocsPath,
markdownPreviewPath,
},
});
return shallowMountExtended(NewVulnerability);
};
 
beforeEach(() => {
Loading
Loading
@@ -41,32 +35,10 @@ describe('New vulnerability component', () => {
expect(wrapper.findComponent(GlForm).exists()).toBe(true);
});
 
it('creates markdown editor with correct props', () => {
expect(wrapper.findComponent(MarkdownField).props()).toMatchObject({
markdownDocsPath,
markdownPreviewPath,
textareaValue: '',
canAttachFile: false,
addSpacingClasses: false,
isSubmitting: false,
});
});
it.each`
labelText | description
${'Name'} | ${'Vulnerability name or type. Ex: Cross-site scripting'}
${'Description'} | ${''}
`('displays the input with the correct label: $labelText', ({ labelText, description }) => {
expect(wrapper.findByLabelText(labelText).exists()).toBe(true);
if (description) {
expect(wrapper.findByText(description).exists()).toBe(true);
}
});
it.each`
section | selector | fields
${'Details'} | ${findSectionDetails} | ${{ severity: 'low', detectionMethod: 2, status: 'confirmed' }}
section | selector | fields
${'Name and Description'} | ${findSectionName} | ${{ vulnerabilityName: 'CVE 2050', vulnerabilityDesc: 'Password leak' }}
${'Details'} | ${findSectionDetails} | ${{ severity: 'low', detectionMethod: 2, status: 'confirmed' }}
`('mounts the section $section and reacts on the change event', ({ selector, fields }) => {
const section = selector();
expect(section.exists()).toBe(true);
Loading
Loading
import { GlFormInput, GlFormTextarea } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import SectionName from 'ee/vulnerabilities/components/new_vulnerability/section_name.vue';
describe('New vulnerability - Section Details', () => {
const markdownDocsPath = '/path/to/markdown/docs';
const markdownPreviewPath = '/path/to/markdown/preview';
let wrapper;
const createWrapper = () => {
return mountExtended(SectionName, {
provide: {
markdownDocsPath,
markdownPreviewPath,
},
});
};
beforeEach(() => {
wrapper = createWrapper();
});
afterEach(() => {
wrapper.destroy();
});
it('creates markdown editor with correct props', () => {
expect(wrapper.findComponent(MarkdownField).props()).toMatchObject({
markdownDocsPath,
markdownPreviewPath,
textareaValue: '',
canAttachFile: false,
addSpacingClasses: false,
isSubmitting: false,
});
});
it.each`
labelText | description
${'Name'} | ${'Vulnerability name or type. Ex: Cross-site scripting'}
${'Description'} | ${''}
`('displays the input with the correct label: $labelText', ({ labelText, description }) => {
expect(wrapper.findByLabelText(labelText).exists()).toBe(true);
if (description) {
expect(wrapper.findByText(description).exists()).toBe(true);
}
});
it.each`
field | component | value
${'Name'} | ${GlFormInput} | ${{ vulnerabilityName: 'CVE 2021', vulnerabilityDesc: '' }}
${'Description'} | ${GlFormTextarea} | ${{ vulnerabilityName: '', vulnerabilityDesc: 'Password leak' }}
`('emits the changes: $field ', async ({ component, value }) => {
wrapper.setData(value);
wrapper.findComponent(component).vm.$emit('change', value);
expect(wrapper.emitted('change')[0][0]).toEqual(value);
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment