2021-01-29 00:20:46 +05:30
|
|
|
import { shallowMount } from '@vue/test-utils';
|
2021-06-08 01:23:25 +05:30
|
|
|
import validation, { initForm } from '~/vue_shared/directives/validation';
|
2021-01-29 00:20:46 +05:30
|
|
|
|
|
|
|
describe('validation directive', () => {
|
|
|
|
let wrapper;
|
|
|
|
|
2021-06-08 01:23:25 +05:30
|
|
|
const createComponentFactory = ({ inputAttributes, template, data }) => {
|
2021-01-29 00:20:46 +05:30
|
|
|
const defaultInputAttributes = {
|
|
|
|
type: 'text',
|
|
|
|
required: true,
|
|
|
|
};
|
|
|
|
|
2021-06-08 01:23:25 +05:30
|
|
|
const defaultTemplate = `
|
|
|
|
<form>
|
|
|
|
<input v-validation:[showValidation] name="exampleField" v-bind="attributes" />
|
|
|
|
</form>
|
|
|
|
`;
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
const component = {
|
|
|
|
directives: {
|
|
|
|
validation: validation(),
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
attributes: inputAttributes || defaultInputAttributes,
|
2021-06-08 01:23:25 +05:30
|
|
|
...data,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
template: template || defaultTemplate,
|
|
|
|
};
|
|
|
|
|
|
|
|
wrapper = shallowMount(component, { attachTo: document.body });
|
|
|
|
};
|
|
|
|
|
|
|
|
const createComponent = ({ inputAttributes, showValidation, template } = {}) =>
|
|
|
|
createComponentFactory({
|
|
|
|
inputAttributes,
|
|
|
|
data: {
|
|
|
|
showValidation,
|
|
|
|
form: {
|
|
|
|
state: null,
|
|
|
|
fields: {
|
|
|
|
exampleField: {
|
|
|
|
state: null,
|
|
|
|
feedback: '',
|
2021-01-29 00:20:46 +05:30
|
|
|
},
|
|
|
|
},
|
2021-06-08 01:23:25 +05:30
|
|
|
},
|
|
|
|
},
|
|
|
|
template,
|
|
|
|
});
|
|
|
|
|
|
|
|
const createComponentWithInitForm = ({ inputAttributes } = {}) =>
|
|
|
|
createComponentFactory({
|
|
|
|
inputAttributes,
|
|
|
|
data: {
|
|
|
|
form: initForm({
|
|
|
|
fields: {
|
|
|
|
exampleField: {
|
|
|
|
state: null,
|
|
|
|
value: 'lorem',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}),
|
2021-01-29 00:20:46 +05:30
|
|
|
},
|
|
|
|
template: `
|
|
|
|
<form>
|
2021-06-08 01:23:25 +05:30
|
|
|
<input v-validation:[form.showValidation] name="exampleField" v-bind="attributes" />
|
2021-01-29 00:20:46 +05:30
|
|
|
</form>
|
|
|
|
`,
|
2021-06-08 01:23:25 +05:30
|
|
|
});
|
2021-01-29 00:20:46 +05:30
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
wrapper.destroy();
|
|
|
|
wrapper = null;
|
|
|
|
});
|
|
|
|
|
|
|
|
const getFormData = () => wrapper.vm.form;
|
|
|
|
const findForm = () => wrapper.find('form');
|
|
|
|
const findInput = () => wrapper.find('input');
|
|
|
|
|
2021-06-08 01:23:25 +05:30
|
|
|
const setValueAndTriggerValidation = (value) => {
|
|
|
|
const input = findInput();
|
|
|
|
input.setValue(value);
|
|
|
|
input.trigger('blur');
|
|
|
|
};
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
describe.each([true, false])(
|
|
|
|
'with fields untouched and "showValidation" set to "%s"',
|
2021-03-08 18:12:59 +05:30
|
|
|
(showValidation) => {
|
2021-01-29 00:20:46 +05:30
|
|
|
beforeEach(() => {
|
|
|
|
createComponent({ showValidation });
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets the fields validity correctly', () => {
|
|
|
|
expect(getFormData().fields.exampleField).toEqual({
|
|
|
|
state: showValidation ? false : null,
|
|
|
|
feedback: showValidation ? expect.any(String) : '',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets the form validity correctly', () => {
|
|
|
|
expect(getFormData().state).toBe(false);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
describe.each`
|
|
|
|
inputAttributes | validValue | invalidValue
|
|
|
|
${{ required: true }} | ${'foo'} | ${''}
|
|
|
|
${{ type: 'url' }} | ${'http://foo.com'} | ${'foo'}
|
|
|
|
${{ type: 'number', min: 1, max: 5 }} | ${3} | ${0}
|
|
|
|
${{ type: 'number', min: 1, max: 5 }} | ${3} | ${6}
|
|
|
|
${{ pattern: 'foo|bar' }} | ${'bar'} | ${'quz'}
|
|
|
|
`(
|
|
|
|
'with input-attributes set to $inputAttributes',
|
|
|
|
({ inputAttributes, validValue, invalidValue }) => {
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent({ inputAttributes });
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('with valid value', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
setValueAndTriggerValidation(validValue);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets the field to be valid', () => {
|
|
|
|
expect(getFormData().fields.exampleField).toEqual({
|
|
|
|
state: true,
|
|
|
|
feedback: '',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets the form to be valid', () => {
|
|
|
|
expect(getFormData().state).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('with invalid value', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
setValueAndTriggerValidation(invalidValue);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets the field to be invalid', () => {
|
|
|
|
expect(getFormData().fields.exampleField).toEqual({
|
|
|
|
state: false,
|
|
|
|
feedback: expect.any(String),
|
|
|
|
});
|
|
|
|
expect(getFormData().fields.exampleField.feedback.length).toBeGreaterThan(0);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets the form to be invalid', () => {
|
|
|
|
expect(getFormData().state).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets focus on the first invalid input when the form is submitted', () => {
|
|
|
|
findForm().trigger('submit');
|
|
|
|
expect(findInput().element).toBe(document.activeElement);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
);
|
2021-06-08 01:23:25 +05:30
|
|
|
|
|
|
|
describe('with group elements', () => {
|
|
|
|
const template = `
|
|
|
|
<form>
|
|
|
|
<div v-validation:[showValidation]>
|
|
|
|
<input name="exampleField" v-bind="attributes" />
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
`;
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent({
|
|
|
|
template,
|
|
|
|
inputAttributes: {
|
|
|
|
required: true,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('with invalid value', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
setValueAndTriggerValidation('');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should set correct field state', () => {
|
|
|
|
expect(getFormData().fields.exampleField).toEqual({
|
|
|
|
state: false,
|
|
|
|
feedback: expect.any(String),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should set correct feedback', () => {
|
|
|
|
expect(getFormData().fields.exampleField.feedback).toBe('Please fill out this field.');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('with valid value', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
setValueAndTriggerValidation('hello');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('set the correct state', () => {
|
|
|
|
expect(getFormData().fields.exampleField).toEqual({
|
|
|
|
state: true,
|
|
|
|
feedback: '',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('component using initForm', () => {
|
|
|
|
it('sets the form fields correctly', () => {
|
|
|
|
createComponentWithInitForm();
|
|
|
|
|
|
|
|
expect(getFormData().state).toBe(false);
|
|
|
|
expect(getFormData().showValidation).toBe(false);
|
|
|
|
|
|
|
|
expect(getFormData().fields.exampleField).toMatchObject({
|
|
|
|
value: 'lorem',
|
|
|
|
state: null,
|
|
|
|
required: true,
|
|
|
|
feedback: expect.any(String),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('initForm', () => {
|
|
|
|
const MOCK_FORM = {
|
|
|
|
fields: {
|
|
|
|
name: {
|
|
|
|
value: 'lorem',
|
|
|
|
},
|
|
|
|
description: {
|
|
|
|
value: 'ipsum',
|
|
|
|
required: false,
|
|
|
|
skipValidation: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const EXPECTED_FIELDS = {
|
|
|
|
name: { value: 'lorem', required: true, state: null, feedback: null },
|
|
|
|
description: { value: 'ipsum', required: false, state: true, feedback: null },
|
|
|
|
};
|
|
|
|
|
|
|
|
it('returns form object', () => {
|
|
|
|
expect(initForm(MOCK_FORM)).toMatchObject({
|
|
|
|
state: false,
|
|
|
|
showValidation: false,
|
|
|
|
fields: EXPECTED_FIELDS,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns form object with additional parameters', () => {
|
|
|
|
const customFormObject = {
|
|
|
|
foo: {
|
|
|
|
bar: 'lorem',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const form = {
|
|
|
|
...MOCK_FORM,
|
|
|
|
...customFormObject,
|
|
|
|
};
|
|
|
|
|
|
|
|
expect(initForm(form)).toMatchObject({
|
|
|
|
state: false,
|
|
|
|
showValidation: false,
|
|
|
|
fields: EXPECTED_FIELDS,
|
|
|
|
...customFormObject,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('can override existing state and showValidation values', () => {
|
|
|
|
const form = {
|
|
|
|
...MOCK_FORM,
|
|
|
|
state: true,
|
|
|
|
showValidation: true,
|
|
|
|
};
|
|
|
|
|
|
|
|
expect(initForm(form)).toMatchObject({
|
|
|
|
state: true,
|
|
|
|
showValidation: true,
|
|
|
|
fields: EXPECTED_FIELDS,
|
|
|
|
});
|
|
|
|
});
|
2021-01-29 00:20:46 +05:30
|
|
|
});
|