UNPKG

@plone/volto

Version:
1,224 lines (1,121 loc) 31.6 kB
import FormValidation from './FormValidation'; import { messages } from '../MessageLabels/MessageLabels'; import config from '@plone/volto/registry'; import { urlValidator } from './validators'; const schema = { properties: { username: { title: 'Username', type: 'string', description: '' }, email: { title: 'Email', type: 'string', widget: 'email', description: '' }, url: { title: 'url', type: 'string', widget: 'url', description: '' }, file: { title: 'file', type: 'object', description: '', size: 5, }, notafile: { title: 'notafile', type: 'object', description: '', whatever: 1, }, }, fieldsets: [ { id: 'default', title: 'FIXME: User Data', fields: ['username'] }, { id: 'second', title: 'Second: User Data', fields: ['email'] }, ], required: ['username'], }; const errors = { email: ['The specified email is not valid.'] }; const formData = { username: 'test username', email: 'test' }; const formatMessage = (messageObj) => { return messageObj?.defaultMessage; }; const errorJSON = "[{'message': 'The specified email is not valid.', 'field': 'email', 'error': 'ValidationError'}]"; describe('FormValidation', () => { describe('showFirstTabWithErrors', () => { it('does not break without arguments', () => { expect(FormValidation.showFirstTabWithErrors()).toEqual(0); }); it('shows the correct tab index', () => { expect( FormValidation.showFirstTabWithErrors({ errors, schema, }), ).toEqual(1); }); }); describe('giveServerErrorsToCorrespondingFields', () => { it('does not break without arguments', () => { expect(FormValidation.giveServerErrorsToCorrespondingFields()).toEqual( {}, ); }); it('fix JSON and show correct error', () => { expect( FormValidation.giveServerErrorsToCorrespondingFields(errorJSON), ).toEqual({ email: ['The specified email is not valid.'] }); }); }); describe('validateFieldsPerFieldset', () => { it('does not break without arguments', () => { expect(FormValidation.validateFieldsPerFieldset()).toEqual({}); }); it('required - validates missing', () => { const validationErrorMessages = [messages.required.defaultMessage]; validationErrorMessages.title = 'Username'; expect( FormValidation.validateFieldsPerFieldset({ schema, formData: {}, formatMessage, }), ).toEqual({ username: validationErrorMessages, }); }); it('required - do not treat 0 as missing required value', () => { let newSchema = { ...schema, properties: { ...schema.properties, age: { title: 'age', type: 'integer', widget: 'number', description: '', }, }, required: ['age'], }; const validationErrorMessages = [messages.required.defaultMessage]; validationErrorMessages.title = 'age'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', age: null }, formatMessage, }), ).toEqual({ age: validationErrorMessages, }); expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', age: 0 }, formatMessage, }), ).toEqual({}); }); it('email - validates incorrect', () => { const validationErrorMessages = [messages.isValidEmail.defaultMessage]; validationErrorMessages.title = 'Email'; expect( FormValidation.validateFieldsPerFieldset({ schema, formData, formatMessage, }), ).toEqual({ email: validationErrorMessages, }); }); it('email - validates', () => { formData.email = 'test@domain.name'; expect( FormValidation.validateFieldsPerFieldset({ schema, formData, formatMessage, }), ).toEqual({}); }); it('url - validates incorrect url', () => { const validationErrorMessages = [messages.isValidURL.defaultMessage]; validationErrorMessages.title = 'url'; expect( FormValidation.validateFieldsPerFieldset({ schema, formData: { url: 'foo', username: 'test username' }, formatMessage, }), ).toEqual({ url: validationErrorMessages, }); }); it('url - validates', () => { formData.url = 'https://plone.org/'; expect( FormValidation.validateFieldsPerFieldset({ schema, formData, formatMessage, }), ).toEqual({}); }); it('url - validates url with ip', () => { formData.url = 'http://127.0.0.1:8080/Plone'; expect( FormValidation.validateFieldsPerFieldset({ schema, formData, formatMessage, }), ).toEqual({}); }); it('url - validates url with localhost', () => { formData.url = 'http://localhost:8080/Plone'; expect( FormValidation.validateFieldsPerFieldset({ schema, formData, formatMessage, }), ).toEqual({}); }); it('file - validates invalid size', () => { const validationErrorMessages = [messages.maxSize.defaultMessage]; validationErrorMessages.title = 'file'; expect( FormValidation.validateFieldsPerFieldset({ schema, formData: { ...formData, file: { size: 10 } }, formatMessage, }), ).toEqual({ file: validationErrorMessages, }); }); it('file - validates size', () => { expect( FormValidation.validateFieldsPerFieldset({ schema, formData: { ...formData, file: { size: 1 } }, formatMessage, }), ).toEqual({}); }); it('notafile - the size validator does nothing', () => { expect( FormValidation.validateFieldsPerFieldset({ schema, formData: { ...formData, notafile: { whatever: 1 } }, formatMessage, }), ).toEqual({}); }); it('widget - validator from block - Fails', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Default field', description: '', widget: 'url', }, }, required: [], }; const validationErrorMessages = [messages.isValidURL.defaultMessage]; validationErrorMessages.title = 'Default field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'asd', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('type + widget - validator from block - Fails', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Default field', description: '', type: 'customfieldtype', widget: 'url', }, }, required: [], }; config.registerUtility({ type: 'validator', name: 'alwaysFail', dependencies: { fieldType: 'customfieldtype' }, method: () => 'Fails', }); const validationErrorMessages = [ 'Fails', messages.isValidURL.defaultMessage, ]; validationErrorMessages.title = 'Default field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'asd', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('widget - validator from content type set - Fails', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Default field', description: '', widgetOptions: { frontendOptions: { widget: 'url', }, }, }, }, required: [], }; const validationErrorMessages = [messages.isValidURL.defaultMessage]; validationErrorMessages.title = 'Default field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'asd', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('string - min length', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'password', description: '', minLength: '8', }, }, required: [], }; const validationErrorMessages = [messages.minLength.defaultMessage]; validationErrorMessages.title = 'password'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'asd', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('string - max length', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'password', description: '', maxLength: '8', }, }, required: [], }; const validationErrorMessages = [messages.maxLength.defaultMessage]; validationErrorMessages.title = 'password'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'asdasdasdasdasd', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('string - pattern - Fail', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'password', description: '', pattern: '^[a-zA-Z0-9]*$', }, }, required: [], }; const validationErrorMessages = [messages.pattern.defaultMessage]; validationErrorMessages.title = 'password'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'as#', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('string - pattern - Succeeds', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'password', description: '', pattern: '^[a-zA-Z0-9]*$', }, }, required: [], }; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'asasd', }, formatMessage, }), ).toEqual({}); }); it('number - isNumber - fails (not string|number as number)', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Number field', type: 'number', description: '', }, }, required: [], }; const validationErrorMessages = [messages.isNumber.defaultMessage]; validationErrorMessages.title = 'Number field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', //since 'number' can accept digits in string & number format hence testing it with an alphabet customField: 'n', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('number - isNumber - as string', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Number field', type: 'number', description: '', }, }, required: [], }; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', //since 'number' can accept digits in string & number format hence testing it with an alphabet customField: '1', }, formatMessage, }), ).toEqual({}); }); it('number - isNumber - as number', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Number field', type: 'number', description: '', }, }, required: [], }; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', //since 'number' can accept digits in string & number format hence testing it with an alphabet customField: 1, }, formatMessage, }), ).toEqual({}); }); it('number - minimum', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Number field', type: 'number', description: '', minimum: 8, }, }, required: [], }; const validationErrorMessages = [messages.minimum.defaultMessage]; validationErrorMessages.title = 'Number field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 1, }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('number - maximum', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Number field', type: 'number', description: '', maximum: 8, }, }, required: [], }; const validationErrorMessages = [messages.maximum.defaultMessage]; validationErrorMessages.title = 'Number field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 10, }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('integer - isInteger', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Integer field', type: 'integer', description: '', }, }, required: [], }; const validationErrorMessages = [messages.isInteger.defaultMessage]; validationErrorMessages.title = 'Integer field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 1.5, }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('integer - minimum', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Integer field', type: 'integer', description: '', minimum: 8, }, }, required: [], }; const validationErrorMessages = [messages.minimum.defaultMessage]; validationErrorMessages.title = 'Integer field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 1, }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('integer - maximum', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Integer field', type: 'integer', description: '', maximum: 8, }, }, required: [], }; const validationErrorMessages = [messages.maximum.defaultMessage]; validationErrorMessages.title = 'Integer field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 10, }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('password - min length', () => { let newSchema = { ...schema, properties: { ...schema.properties, password: { title: 'password', type: 'password', description: '', minLength: '8', }, }, required: [], }; const validationErrorMessages = [messages.minLength.defaultMessage]; validationErrorMessages.title = 'password'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', password: 'asd' }, formatMessage, }), ).toEqual({ password: validationErrorMessages, }); }); it('description - min length from server side', () => { let newSchema = { ...schema, properties: { ...schema.properties, description: { title: 'description', type: 'string', description: '', widgetOptions: { frontendOptions: { widgetProps: { minLength: 8, }, }, }, }, }, required: [], }; const validationErrorMessages = [messages.minLength.defaultMessage]; validationErrorMessages.title = 'description'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', description: 'asd', }, formatMessage, }), ).toEqual({ description: validationErrorMessages, }); }); it('password - max length', () => { let newSchema = { ...schema, properties: { ...schema.properties, password: { title: 'password', type: 'password', description: '', maxLength: '8', }, }, required: [], }; const validationErrorMessages = [messages.maxLength.defaultMessage]; validationErrorMessages.title = 'password'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', password: 'asdasdasdasdasd' }, formatMessage, }), ).toEqual({ password: validationErrorMessages, }); }); it('description - max length from server side', () => { let newSchema = { ...schema, properties: { ...schema.properties, description: { title: 'description', type: 'string', description: '', widgetOptions: { frontendOptions: { widgetProps: { maxLength: 8, }, }, }, }, }, required: [], }; const validationErrorMessages = [messages.maxLength.defaultMessage]; validationErrorMessages.title = 'description'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', description: 'asdasdasdasdasd', }, formatMessage, }), ).toEqual({ description: validationErrorMessages, }); }); it('array - maxItems', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Array field', type: 'array', description: '', maxItems: 1, }, }, required: [], }; const validationErrorMessages = [messages.maxItems.defaultMessage]; validationErrorMessages.title = 'Array field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: [1, 2], }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('array - minItems', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Array field', type: 'array', description: '', minItems: 3, }, }, required: [], }; const validationErrorMessages = [messages.minItems.defaultMessage]; validationErrorMessages.title = 'Array field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: [1], }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('array - uniqueItems', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Array field', type: 'array', description: '', uniqueItems: true, }, }, required: [], }; const validationErrorMessages = [messages.uniqueItems.defaultMessage]; validationErrorMessages.title = 'Array field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: [1, 1], }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('array - uniqueItems - false', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Array field', type: 'array', description: '', uniqueItems: false, }, }, required: [], }; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: [1, 1], }, formatMessage, }), ).toEqual({}); expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: [1], }, formatMessage, }), ).toEqual({}); }); it('format - specific validator set - Errors', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Default field', description: '', format: 'url', }, }, required: [], }; config.registerUtility({ type: 'validator', name: 'url', dependencies: { format: 'url' }, method: urlValidator, }); const validationErrorMessages = [messages.isValidURL.defaultMessage]; validationErrorMessages.title = 'Default field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'foo', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('format - specific validator set - Succeeds', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Default field', description: '', format: 'url', }, }, required: [], }; config.registerUtility({ type: 'validator', name: 'url', dependencies: { format: 'url' }, method: urlValidator, }); expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'https://plone.org/', }, formatMessage, }), ).toEqual({}); }); it('format - specific validator from content type set - Fails', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Default field', description: '', widgetOptions: { frontendOptions: { format: 'url', }, }, }, }, required: [], }; config.registerUtility({ type: 'validator', name: 'url', dependencies: { format: 'url' }, method: urlValidator, }); const validationErrorMessages = [messages.isValidURL.defaultMessage]; validationErrorMessages.title = 'Default field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'asdasd', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('format - specific validator from content type set - Succeeds', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Default field', description: '', widgetOptions: { frontendOptions: { format: 'url', }, }, }, }, required: [], }; config.registerUtility({ type: 'validator', name: 'url', dependencies: { format: 'url' }, method: urlValidator, }); expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'https://plone.org/', }, formatMessage, }), ).toEqual({}); }); it('behavior + fieldName - Fails', () => { let newSchema = { properties: { ...schema.properties, customField: { behavior: 'plone.eventbasic', title: 'Default field', description: '', }, }, required: [], }; config.registerUtility({ type: 'validator', name: 'url', dependencies: { behaviorName: 'plone.eventbasic', fieldName: 'customField', format: 'url', }, method: urlValidator, }); const validationErrorMessages = [messages.isValidURL.defaultMessage]; validationErrorMessages.title = 'Default field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { username: 'test username', customField: 'asd', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); it('behavior + fieldName - start date in Event - Fails', () => { let contentTypeSchema = { properties: { ...schema.properties, start: { behavior: 'plone.eventbasic', type: 'string', title: 'Start date', description: '', }, }, required: [], }; const validationErrorMessages = [messages.startEventRange.defaultMessage]; validationErrorMessages.title = 'Start date'; expect( FormValidation.validateFieldsPerFieldset({ schema: contentTypeSchema, formData: { start: '2024-08-01T11:00:00+00:00', end: '2024-04-01T11:00:00+00:00', }, formatMessage, }), ).toEqual({ start: validationErrorMessages, }); }); it('behavior + fieldName - end date in Event - Fails', () => { let contentTypeSchema = { properties: { ...schema.properties, end: { behavior: 'plone.eventbasic', type: 'string', title: 'End date', description: '', }, }, required: [], }; const validationErrorMessages = [messages.endEventRange.defaultMessage]; validationErrorMessages.title = 'End date'; expect( FormValidation.validateFieldsPerFieldset({ schema: contentTypeSchema, formData: { start: '2024-08-01T11:00:00+00:00', end: '2024-04-01T11:00:00+00:00', }, formatMessage, }), ).toEqual({ end: validationErrorMessages, }); }); it('block - per block type and fieldID specific - Fails', () => { let newSchema = { properties: { ...schema.properties, customField: { title: 'Default field', description: '', }, }, required: [], }; config.registerUtility({ type: 'validator', dependencies: { blockType: 'slider', fieldName: 'customField' }, method: urlValidator, }); const validationErrorMessages = [messages.isValidURL.defaultMessage]; validationErrorMessages.title = 'Default field'; expect( FormValidation.validateFieldsPerFieldset({ schema: newSchema, formData: { '@type': 'slider', username: 'test username', customField: 'asd', }, formatMessage, }), ).toEqual({ customField: validationErrorMessages, }); }); }); });