Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JSON-Logic] Part 0: Allow consts to support single values only #34

Merged
merged 7 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ export function extractParametersFromNode(schemaNode) {

return omitBy(
{
const: node.const,
label: node.title,
readOnly: node.readOnly,
...(node.deprecated && {
Expand Down
86 changes: 86 additions & 0 deletions src/tests/const.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { createHeadlessForm } from '../createHeadlessForm';
brennj marked this conversation as resolved.
Show resolved Hide resolved

describe('validations: const', () => {
it('Should work for number', () => {
const { handleValidation } = createHeadlessForm(
{
properties: {
ten_only: { type: 'number', const: 10 },
},
},
{ strictInputType: false }
);
expect(handleValidation({}).formErrors).toEqual(undefined);
expect(handleValidation({ ten_only: 1 }).formErrors).toEqual({
ten_only: 'The only accepted value is 10.',
});
expect(handleValidation({ ten_only: 10 }).formErrors).toBeUndefined();
// null is also considered valid until we fix @BUG RMT-518
// Expectation: To fail with error "The only accepted value is 10."
expect(handleValidation({ ten_only: null }).formErrors).toBeUndefined();
});

it('Should work for text', () => {
const { handleValidation } = createHeadlessForm(
{
properties: {
hello_only: { type: 'string', const: 'hello' },
},
},
{ strictInputType: false }
);
expect(handleValidation({}).formErrors).toEqual(undefined);
expect(handleValidation({ hello_only: 'what' }).formErrors).toEqual({
hello_only: 'The only accepted value is hello.',
});
expect(handleValidation({ hello_only: 'hello' }).formErrors).toEqual(undefined);
});

it('Should work for a conditionally applied const', () => {
const { handleValidation } = createHeadlessForm(
{
properties: {
answer: { type: 'string', oneOf: [{ const: 'yes' }, { const: 'no' }] },
amount: {
description: 'If you select yes, this needs to be exactly 10.',
type: 'number',
},
},
allOf: [
{
if: { properties: { answer: { const: 'yes' } }, required: ['answer'] },
then: { properties: { amount: { const: 10 } }, required: ['amount'] },
},
],
},
{ strictInputType: false }
);
expect(handleValidation({}).formErrors).toEqual(undefined);
expect(handleValidation({ answer: 'no' }).formErrors).toEqual(undefined);
expect(handleValidation({ answer: 'yes' }).formErrors).toEqual({ amount: 'Required field' });
expect(handleValidation({ answer: 'yes', amount: 1 }).formErrors).toEqual({
amount: 'The only accepted value is 10.',
});
expect(handleValidation({ answer: 'yes', amount: 10 }).formErrors).toEqual(undefined);
});

it('Should show the custom error message', () => {
const { handleValidation } = createHeadlessForm(
{
properties: {
string: {
type: 'string',
const: 'hello',
'x-jsf-errorMessage': { const: 'You must say hello!!!' },
},
},
},
{ strictInputType: false }
);
expect(handleValidation({}).formErrors).toEqual(undefined);
expect(handleValidation({ string: 'hi' }).formErrors).toEqual({
string: 'You must say hello!!!',
});
expect(handleValidation({ string: 'hello' }).formErrors).toEqual(undefined);
});
});
1 change: 0 additions & 1 deletion src/tests/helpers.custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ export const schemaInputTypeHidden = {
title: 'Select multi hidden',
default: ['Albania, Algeria'],
'x-jsf-presentation': { inputType: 'hidden' },
const: ['Albania, Algeria'],
type: 'array',
},
},
Expand Down
18 changes: 18 additions & 0 deletions src/yupSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,19 @@ export function buildYupSchema(field, config) {
);
}

function withConst(yupSchema) {
return yupSchema.test(
'isConst',
errorMessage.const ??
brennj marked this conversation as resolved.
Show resolved Hide resolved
errorMessageFromConfig.const ??
`The only accepted value is ${propertyFields.const}.`,
(value) =>
(propertyFields.required === false && value === undefined) ||
value === null ||
value === propertyFields.const
);
}

function withBaseSchema() {
const customErrorMsg = errorMessage.type || errorMessageFromConfig.type;
if (customErrorMsg) {
Expand Down Expand Up @@ -388,6 +401,11 @@ export function buildYupSchema(field, config) {
if (propertyFields.accept) {
validators.push(withFileFormat);
}

if (propertyFields.const) {
validators.push(withConst);
}

return flow(validators);
}

Expand Down