From 212b61594d156129a38483989cc4469ec4e8aae8 Mon Sep 17 00:00:00 2001 From: Jakob Guddas Date: Sun, 4 Jun 2023 12:30:08 +0200 Subject: [PATCH 1/8] feat: support integer field type --- src/tests/createHeadlessForm.test.js | 34 ++++++++++++++++++++++++++++ src/tests/helpers.js | 18 +++++++++++++++ src/yupSchema.js | 16 +++++++++++++ 3 files changed, 68 insertions(+) diff --git a/src/tests/createHeadlessForm.test.js b/src/tests/createHeadlessForm.test.js index 1be17398e..41ef9a651 100644 --- a/src/tests/createHeadlessForm.test.js +++ b/src/tests/createHeadlessForm.test.js @@ -22,6 +22,7 @@ import { schemaInputTypeSelectMultiple, schemaInputTypeSelectMultipleOptional, schemaInputTypeFieldset, + schemaInputTypeInteger, schemaInputTypeNumber, schemaInputTypeNumberZeroMaximum, schemaInputTypeDate, @@ -994,6 +995,39 @@ describe('createHeadlessForm', () => { expect(fieldOptions).toEqual([]); }); + it('support "integer" field type', () => { + const result = createHeadlessForm(schemaInputTypeInteger); + expect(result).toMatchObject({ + fields: [ + { + description: 'How many open tabs do you have?', + label: 'Tabs', + name: 'tabs', + required: true, + schema: expect.any(Object), + type: 'integer', + minimum: 1, + maximum: 10, + }, + ], + }); + + const fieldValidator = result.fields[0].schema; + expect(fieldValidator.isValidSync('0')).toBe(false); + expect(fieldValidator.isValidSync('10')).toBe(true); + expect(fieldValidator.isValidSync('11')).toBe(false); + expect(fieldValidator.isValidSync('5.5')).toBe(false); + expect(fieldValidator.isValidSync('1.0')).toBe(true); + expect(fieldValidator.isValidSync('this is text with a number 1')).toBe(false); + expect(() => fieldValidator.validateSync('5.5')).toThrowError( + 'Must not contain decimal points. E.g. 5 instead of 5.5' + ); + expect(() => fieldValidator.validateSync('some text')).toThrowError( + 'The value must be a number' + ); + expect(() => fieldValidator.validateSync('')).toThrowError('The value must be a number'); + }); + it('support "number" field type', () => { const result = createHeadlessForm(schemaInputTypeNumber); expect(result).toMatchObject({ diff --git a/src/tests/helpers.js b/src/tests/helpers.js index ff65ba78f..c1d79885e 100644 --- a/src/tests/helpers.js +++ b/src/tests/helpers.js @@ -35,6 +35,17 @@ export const mockTextareaInput = { type: 'string', }; +export const mockIntegerInput = { + title: 'Tabs', + description: 'How many open tabs do you have?', + 'x-jsf-presentation': { + inputType: 'integer', + }, + minimum: 1, + maximum: 10, + type: 'integer', +}; + export const mockNumberInput = { title: 'Tabs', description: 'How many open tabs do you have?', @@ -1046,6 +1057,13 @@ export const schemaInputTypeSelectMultipleOptional = JSONSchemaBuilder() }) .build(); +export const schemaInputTypeInteger = JSONSchemaBuilder() + .addInput({ + tabs: mockIntegerInput, + }) + .setRequiredFields(['tabs']) + .build(); + export const schemaInputTypeNumber = JSONSchemaBuilder() .addInput({ tabs: mockNumberInput, diff --git a/src/yupSchema.js b/src/yupSchema.js index 8f4f2e70e..acf8ed310 100644 --- a/src/yupSchema.js +++ b/src/yupSchema.js @@ -320,6 +320,18 @@ export function buildYupSchema(field, config, logic) { } return yupSchema.required(requiredMessage); } + + function withInteger(yupSchema) { + return yupSchema.integer( + (message) => + errorMessage.integer ?? + errorMessageFromConfig.integer ?? + `Must not contain decimal points. E.g. ${Math.floor(message.value)} instead of ${ + message.value + }` + ); + } + function withMin(yupSchema) { return yupSchema.min( propertyFields.minimum, @@ -488,6 +500,10 @@ export function buildYupSchema(field, config, logic) { validators.push(withFile); } + if (propertyFields.type === 'integer') { + validators.push(withInteger); + } + // support minimum with 0 value if (typeof propertyFields.minimum !== 'undefined') { validators.push(withMin); From 724409f56da923963352851f3cabc798a805c841 Mon Sep 17 00:00:00 2001 From: Jakob Guddas Date: Fri, 14 Jul 2023 21:35:23 +0200 Subject: [PATCH 2/8] refactor: changed integer field type test to new format --- src/tests/createHeadlessForm.test.js | 29 ++++++++++++++++++++++++ src/tests/helpers.js | 33 +++++++++++++--------------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/tests/createHeadlessForm.test.js b/src/tests/createHeadlessForm.test.js index 41ef9a651..c0facf845 100644 --- a/src/tests/createHeadlessForm.test.js +++ b/src/tests/createHeadlessForm.test.js @@ -48,6 +48,7 @@ import { mockTextInputDeprecated, mockNumberInput, mockNumberInputWithPercentageAndCustomRange, + schemaInputTypeIntegerNumber, mockTextPatternInput, mockTextMaxLengthInput, mockFieldset, @@ -2576,6 +2577,34 @@ describe('createHeadlessForm', () => { }); }); }); + describe('and type is integer', () => { + it('should validate field', () => { + const { handleValidation } = createHeadlessForm(schemaInputTypeIntegerNumber); + const validateForm = (vals) => friendlyError(handleValidation(vals)); + + expect(validateForm({ tabs: '10' })).toBeUndefined(); + expect(validateForm({ tabs: '1.0' })).toBeUndefined(); + + expect(validateForm({ tabs: '0' })).toEqual({ + tabs: 'Must be greater or equal to 1', + }); + expect(validateForm({ tabs: '11' })).toEqual({ + tabs: 'Must be smaller or equal to 10', + }); + expect(validateForm({ tabs: '5.5' })).toEqual({ + tabs: 'Must not contain decimal points. E.g. 5 instead of 5.5', + }); + expect(validateForm({ tabs: 'this is text with a number 1' })).toEqual({ + tabs: 'The value must be a number', + }); + expect(validateForm({ tabs: 'some text' })).toEqual({ + tabs: 'The value must be a number', + }); + expect(validateForm({ tabs: '' })).toEqual({ + tabs: 'The value must be a number', + }); + }); + }); }); describe('when a field has a maxLength of 10', () => { diff --git a/src/tests/helpers.js b/src/tests/helpers.js index c1d79885e..6e4176277 100644 --- a/src/tests/helpers.js +++ b/src/tests/helpers.js @@ -35,17 +35,6 @@ export const mockTextareaInput = { type: 'string', }; -export const mockIntegerInput = { - title: 'Tabs', - description: 'How many open tabs do you have?', - 'x-jsf-presentation': { - inputType: 'integer', - }, - minimum: 1, - maximum: 10, - type: 'integer', -}; - export const mockNumberInput = { title: 'Tabs', description: 'How many open tabs do you have?', @@ -72,6 +61,21 @@ export const schemaInputTypeNumberZeroMaximum = { }, }; +export const schemaInputTypeIntegerNumber = { + properties: { + tabs: { + title: 'Tabs', + description: 'How many open tabs do you have?', + 'x-jsf-presentation': { + inputType: 'integer', + }, + minimum: 1, + maximum: 10, + type: 'integer', + }, + }, +}; + export const mockNumberInputWithPercentage = { title: 'Shares', description: 'What % of shares do you own?', @@ -1057,13 +1061,6 @@ export const schemaInputTypeSelectMultipleOptional = JSONSchemaBuilder() }) .build(); -export const schemaInputTypeInteger = JSONSchemaBuilder() - .addInput({ - tabs: mockIntegerInput, - }) - .setRequiredFields(['tabs']) - .build(); - export const schemaInputTypeNumber = JSONSchemaBuilder() .addInput({ tabs: mockNumberInput, From c9363ad0434a282118a5173c5afd42252a4001d7 Mon Sep 17 00:00:00 2001 From: Sandrina Pereira Date: Tue, 19 Nov 2024 18:56:46 +0000 Subject: [PATCH 3/8] remove duplicated test --- src/tests/createHeadlessForm.test.js | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/tests/createHeadlessForm.test.js b/src/tests/createHeadlessForm.test.js index c0facf845..0475461c8 100644 --- a/src/tests/createHeadlessForm.test.js +++ b/src/tests/createHeadlessForm.test.js @@ -2577,34 +2577,6 @@ describe('createHeadlessForm', () => { }); }); }); - describe('and type is integer', () => { - it('should validate field', () => { - const { handleValidation } = createHeadlessForm(schemaInputTypeIntegerNumber); - const validateForm = (vals) => friendlyError(handleValidation(vals)); - - expect(validateForm({ tabs: '10' })).toBeUndefined(); - expect(validateForm({ tabs: '1.0' })).toBeUndefined(); - - expect(validateForm({ tabs: '0' })).toEqual({ - tabs: 'Must be greater or equal to 1', - }); - expect(validateForm({ tabs: '11' })).toEqual({ - tabs: 'Must be smaller or equal to 10', - }); - expect(validateForm({ tabs: '5.5' })).toEqual({ - tabs: 'Must not contain decimal points. E.g. 5 instead of 5.5', - }); - expect(validateForm({ tabs: 'this is text with a number 1' })).toEqual({ - tabs: 'The value must be a number', - }); - expect(validateForm({ tabs: 'some text' })).toEqual({ - tabs: 'The value must be a number', - }); - expect(validateForm({ tabs: '' })).toEqual({ - tabs: 'The value must be a number', - }); - }); - }); }); describe('when a field has a maxLength of 10', () => { From 2902ff6918c3556b657eaef1cd25398c7d34431f Mon Sep 17 00:00:00 2001 From: Sandrina Pereira Date: Tue, 19 Nov 2024 19:00:45 +0000 Subject: [PATCH 4/8] support jsonType integer with inputType number --- src/tests/createHeadlessForm.test.js | 11 ++++++----- src/tests/helpers.js | 2 +- src/yupSchema.js | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/tests/createHeadlessForm.test.js b/src/tests/createHeadlessForm.test.js index 0475461c8..edb54e101 100644 --- a/src/tests/createHeadlessForm.test.js +++ b/src/tests/createHeadlessForm.test.js @@ -22,7 +22,7 @@ import { schemaInputTypeSelectMultiple, schemaInputTypeSelectMultipleOptional, schemaInputTypeFieldset, - schemaInputTypeInteger, + schemaInputTypeIntegerNumber, schemaInputTypeNumber, schemaInputTypeNumberZeroMaximum, schemaInputTypeDate, @@ -48,7 +48,6 @@ import { mockTextInputDeprecated, mockNumberInput, mockNumberInputWithPercentageAndCustomRange, - schemaInputTypeIntegerNumber, mockTextPatternInput, mockTextMaxLengthInput, mockFieldset, @@ -997,16 +996,18 @@ describe('createHeadlessForm', () => { }); it('support "integer" field type', () => { - const result = createHeadlessForm(schemaInputTypeInteger); + const result = createHeadlessForm(schemaInputTypeIntegerNumber); expect(result).toMatchObject({ fields: [ { description: 'How many open tabs do you have?', label: 'Tabs', name: 'tabs', - required: true, + required: false, schema: expect.any(Object), - type: 'integer', + type: 'number', + jsonType: 'integer', + inputType: 'number', minimum: 1, maximum: 10, }, diff --git a/src/tests/helpers.js b/src/tests/helpers.js index 6e4176277..5cc8f320d 100644 --- a/src/tests/helpers.js +++ b/src/tests/helpers.js @@ -67,7 +67,7 @@ export const schemaInputTypeIntegerNumber = { title: 'Tabs', description: 'How many open tabs do you have?', 'x-jsf-presentation': { - inputType: 'integer', + inputType: 'number', }, minimum: 1, maximum: 10, diff --git a/src/yupSchema.js b/src/yupSchema.js index acf8ed310..c1f6143b8 100644 --- a/src/yupSchema.js +++ b/src/yupSchema.js @@ -293,6 +293,7 @@ export function buildYupSchema(field, config, logic) { const isCheckboxBoolean = typeof propertyFields.checkboxValue === 'boolean'; let baseSchema; const errorMessageFromConfig = config?.inputTypes?.[inputType]?.errorMessage || {}; + const jsonType = getJsonTypeInArray(field.jsonType); if (propertyFields.multiple) { // keep inputType while non-core are being removed #RMT-439 @@ -500,7 +501,7 @@ export function buildYupSchema(field, config, logic) { validators.push(withFile); } - if (propertyFields.type === 'integer') { + if (jsonType === 'integer') { validators.push(withInteger); } From ad7f6475778187fb3b1c308a2fd323e10d4b0abc Mon Sep 17 00:00:00 2001 From: Sandrina Pereira Date: Wed, 20 Nov 2024 08:11:07 +0000 Subject: [PATCH 5/8] Release 0.11.7-dev.20241120081050 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 67f6d77a5..50130d23a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@remoteoss/json-schema-form", - "version": "0.11.6-beta.0", + "version": "0.11.7-dev.20241120081050", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@remoteoss/json-schema-form", - "version": "0.11.6-beta.0", + "version": "0.11.7-dev.20241120081050", "license": "MIT", "dependencies": { "json-logic-js": "^2.0.2", diff --git a/package.json b/package.json index c0e7b3e67..50584f3cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@remoteoss/json-schema-form", - "version": "0.11.6-beta.0", + "version": "0.11.7-dev.20241120081050", "description": "Headless UI form powered by JSON Schemas", "author": "Remote.com (https://remote.com/)", "license": "MIT", From 4f2a6bccdc5f464d54146cf2d7ff728c74842327 Mon Sep 17 00:00:00 2001 From: Sandrina Pereira Date: Wed, 20 Nov 2024 09:15:17 +0000 Subject: [PATCH 6/8] fix a_hidden_field_money to have integer --- src/tests/helpers.custom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/helpers.custom.js b/src/tests/helpers.custom.js index 024a255dc..e95de3c92 100644 --- a/src/tests/helpers.custom.js +++ b/src/tests/helpers.custom.js @@ -194,7 +194,7 @@ export const schemaInputTypeHidden = { title: 'Money hidden', 'x-jsf-presentation': { inputType: 'hidden', currency: 'EUR' }, minimum: 0, - default: 12.3, + default: 1099, }, a_hidden_select: { ...mockSelectInputSolo, From 47bc8e2bdfb50b1ddef73aa51c5819b76aca7792 Mon Sep 17 00:00:00 2001 From: Sandrina Pereira Date: Wed, 20 Nov 2024 09:15:48 +0000 Subject: [PATCH 7/8] Release 0.11.7-dev.20241120091537 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 50130d23a..1b75e8ed5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@remoteoss/json-schema-form", - "version": "0.11.7-dev.20241120081050", + "version": "0.11.7-dev.20241120091537", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@remoteoss/json-schema-form", - "version": "0.11.7-dev.20241120081050", + "version": "0.11.7-dev.20241120091537", "license": "MIT", "dependencies": { "json-logic-js": "^2.0.2", diff --git a/package.json b/package.json index 50584f3cf..2d1ad7921 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@remoteoss/json-schema-form", - "version": "0.11.7-dev.20241120081050", + "version": "0.11.7-dev.20241120091537", "description": "Headless UI form powered by JSON Schemas", "author": "Remote.com (https://remote.com/)", "license": "MIT", From 6dcfb0410041924d8fb022ad4771771ac79ebb8b Mon Sep 17 00:00:00 2001 From: Sandrina Pereira Date: Wed, 20 Nov 2024 13:06:12 +0000 Subject: [PATCH 8/8] Revert back to 0.11.6-beta.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1b75e8ed5..67f6d77a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@remoteoss/json-schema-form", - "version": "0.11.7-dev.20241120091537", + "version": "0.11.6-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@remoteoss/json-schema-form", - "version": "0.11.7-dev.20241120091537", + "version": "0.11.6-beta.0", "license": "MIT", "dependencies": { "json-logic-js": "^2.0.2", diff --git a/package.json b/package.json index 2d1ad7921..c0e7b3e67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@remoteoss/json-schema-form", - "version": "0.11.7-dev.20241120091537", + "version": "0.11.6-beta.0", "description": "Headless UI form powered by JSON Schemas", "author": "Remote.com (https://remote.com/)", "license": "MIT",