Skip to content

Commit

Permalink
Fix/warn unknown formats (#1277)
Browse files Browse the repository at this point in the history
* fix: console warn on unknown format errors instead of showing an error

* fix: default to default widget if string format is not found

* test: update tests
  • Loading branch information
epicfaace authored May 7, 2019
1 parent c4322bf commit fba5bee
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 28 deletions.
6 changes: 5 additions & 1 deletion src/components/fields/StringField.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
isSelect,
optionsList,
getDefaultRegistry,
hasWidget,
} from "../../utils";

function StringField(props) {
Expand All @@ -29,7 +30,10 @@ function StringField(props) {
const { title, format } = schema;
const { widgets, formContext } = registry;
const enumOptions = isSelect(schema) && optionsList(schema);
const defaultWidget = format || (enumOptions ? "select" : "text");
let defaultWidget = enumOptions ? "select" : "text";
if (format && hasWidget(schema, format, widgets)) {
defaultWidget = format;
}
const { widget = defaultWidget, placeholder = "", ...options } = getUiOptions(
uiSchema
);
Expand Down
16 changes: 16 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,22 @@ export function getWidget(schema, widget, registeredWidgets = {}) {
throw new Error(`No widget "${widget}" for type "${type}"`);
}

export function hasWidget(schema, widget, registeredWidgets = {}) {
try {
getWidget(schema, widget, registeredWidgets);
return true;
} catch (e) {
if (
e.message &&
(e.message.startsWith("No widget") ||
e.message.startsWith("Unsupported widget"))
) {
return false;
}
throw e;
}
}

function computeDefaults(schema, parentDefaults, definitions = {}) {
// Compute the defaults recursively: give highest priority to deepest nodes.
let defaults = parentDefaults;
Expand Down
11 changes: 3 additions & 8 deletions src/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function createAjvInstance() {
allErrors: true,
multipleOfPrecision: 8,
schemaId: "auto",
unknownFormats: "ignore",
});

// add custom formats
Expand Down Expand Up @@ -215,13 +216,7 @@ export default function validateFormData(
typeof validationError.message === "string" &&
validationError.message.includes("no schema with key or ref ");

const unknownFormat =
validationError &&
validationError.message &&
typeof validationError.message === "string" &&
validationError.message.includes("unknown format");

if (noProperMetaSchema || unknownFormat) {
if (noProperMetaSchema) {
errors = [
...errors,
{
Expand All @@ -235,7 +230,7 @@ export default function validateFormData(

let errorSchema = toErrorSchema(errors);

if (noProperMetaSchema || unknownFormat) {
if (noProperMetaSchema) {
errorSchema = {
...errorSchema,
...{
Expand Down
20 changes: 9 additions & 11 deletions test/Form_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1984,13 +1984,13 @@ describe("Form", () => {
const formProps = {
liveValidate: true,
formData: {
areaCode: 123,
areaCode: "123455",
},
schema: {
type: "object",
properties: {
areaCode: {
type: "number",
type: "string",
format: "area-code",
},
},
Expand All @@ -2007,22 +2007,20 @@ describe("Form", () => {

const { comp } = createFormComponent(formProps);

expect(comp.state.errorSchema).eql({
$schema: {
__errors: [
'unknown format "area-code" is used in schema at path "#/properties/areaCode"',
],
},
});
expect(comp.state.errorSchema).eql({});

setProps(comp, {
...formProps,
customFormats: {
"area-code": /\d{3}/,
"area-code": /^\d{3}$/,
},
});

expect(comp.state.errorSchema).eql({});
expect(comp.state.errorSchema).eql({
areaCode: {
__errors: ['should match format "area-code"'],
},
});
});
});

Expand Down
10 changes: 2 additions & 8 deletions test/validate_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,9 @@ describe("Validation", () => {
},
};

it("should return a validation error if unknown string format is used", () => {
it("should not return a validation error if unknown string format is used", () => {
const result = validateFormData({ phone: "800.555.2368" }, schema);
const errMessage =
'unknown format "phone-us" is used in schema at path "#/properties/phone"';

expect(result.errors[0].stack).include(errMessage);
expect(result.errorSchema).to.eql({
$schema: { __errors: [errMessage] },
});
expect(result.errors.length).eql(0);
});

it("should return a validation error about formData", () => {
Expand Down

0 comments on commit fba5bee

Please sign in to comment.