Skip to content

Commit 820d36e

Browse files
authored
Merge pull request #1 from datacamp-engineering/jdmunro/fix-anyof-bug
[LO-1769] Fix default option for anyOf fields
2 parents b9cb280 + eb810a8 commit 820d36e

File tree

2 files changed

+192
-2
lines changed

2 files changed

+192
-2
lines changed

packages/core/src/utils.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,26 @@ export function rangeSpec(schema) {
11581158
return spec;
11591159
}
11601160

1161+
function recursivelyRemoveRequiredFromSchema(schema) {
1162+
const copyOfSchema = { ...schema };
1163+
const copyOfProperties = { ...schema.properties };
1164+
const propertyKeys = Object.keys(copyOfProperties);
1165+
1166+
delete copyOfSchema.required;
1167+
1168+
for (const key of propertyKeys) {
1169+
copyOfProperties[key] = { ...copyOfProperties[key] };
1170+
delete copyOfProperties[key].required;
1171+
if (copyOfProperties[key].items != null) {
1172+
copyOfProperties[key].items = recursivelyRemoveRequiredFromSchema(
1173+
copyOfProperties[key].items
1174+
);
1175+
}
1176+
}
1177+
1178+
return { ...copyOfSchema, properties: copyOfProperties };
1179+
}
1180+
11611181
export function getMatchingOption(formData, options, rootSchema) {
11621182
for (let i = 0; i < options.length; i++) {
11631183
const option = options[i];
@@ -1199,9 +1219,9 @@ export function getMatchingOption(formData, options, rootSchema) {
11991219
augmentedSchema = Object.assign({}, option, requiresAnyOf);
12001220
}
12011221

1202-
// Remove the "required" field as it's likely that not all fields have
1222+
// Remove the "required" fields as it's likely that not all fields have
12031223
// been filled in yet, which will mean that the schema is not valid
1204-
delete augmentedSchema.required;
1224+
augmentedSchema = recursivelyRemoveRequiredFromSchema(augmentedSchema);
12051225

12061226
if (isValid(augmentedSchema, formData)) {
12071227
return i;

packages/core/test/utils_test.js

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
mergeSchemas,
2828
getDisplayLabel,
2929
schemaRequiresTrueValue,
30+
getMatchingOption,
3031
} from "../src/utils";
3132
import { createSandbox } from "./test_utils";
3233

@@ -3714,4 +3715,173 @@ describe("utils", () => {
37143715
expect(schemaRequiresTrueValue({ type: "string" })).eql(false);
37153716
});
37163717
});
3718+
3719+
describe("getMatchingOption", () => {
3720+
describe("basic example", () => {
3721+
const options = Object.freeze([
3722+
{
3723+
type: "object",
3724+
properties: {
3725+
type: {
3726+
type: "string",
3727+
enum: ["One"],
3728+
default: "One",
3729+
},
3730+
},
3731+
required: ["type"],
3732+
},
3733+
{
3734+
type: "object",
3735+
properties: {
3736+
type: {
3737+
type: "string",
3738+
enum: ["Two"],
3739+
default: "Two",
3740+
},
3741+
},
3742+
required: ["type"],
3743+
},
3744+
]);
3745+
3746+
it("returns undefined (default option) if nothing matches the schema", () => {
3747+
const data = { type: "Three" };
3748+
3749+
expect(getMatchingOption(data, options)).eql(undefined);
3750+
});
3751+
3752+
it("returns the expected option if it matches the schema", () => {
3753+
const data = { type: "Two" };
3754+
3755+
expect(getMatchingOption(data, options)).eql(1);
3756+
});
3757+
});
3758+
3759+
describe("partial form data", () => {
3760+
it("returns the expected option for a partial match", () => {
3761+
const options = Object.freeze([
3762+
{
3763+
type: "object",
3764+
properties: {
3765+
type: {
3766+
type: "string",
3767+
enum: ["One"],
3768+
default: "One",
3769+
},
3770+
extraType: {
3771+
type: "string",
3772+
enum: ["extra"],
3773+
default: "extra",
3774+
},
3775+
},
3776+
required: ["type", "extraType"],
3777+
},
3778+
]);
3779+
const data = { type: "One" };
3780+
3781+
expect(getMatchingOption(data, options)).eql(0);
3782+
});
3783+
3784+
it("disregards nested required properties", () => {
3785+
const options = Object.freeze([
3786+
{
3787+
type: "object",
3788+
properties: {
3789+
type: {
3790+
type: "string",
3791+
enum: ["One"],
3792+
default: "One",
3793+
},
3794+
extraObject: {
3795+
type: "object",
3796+
properties: {
3797+
extraProperty: {
3798+
type: "string",
3799+
},
3800+
},
3801+
required: ["extraProperty"],
3802+
},
3803+
},
3804+
required: ["type", "extraObject"],
3805+
},
3806+
]);
3807+
const data = { type: "One", extraObject: {} };
3808+
3809+
expect(getMatchingOption(data, options)).eql(0);
3810+
});
3811+
3812+
it("disregards nested required properties (array)", () => {
3813+
const options = Object.freeze([
3814+
{
3815+
type: "object",
3816+
properties: {
3817+
type: {
3818+
type: "string",
3819+
enum: ["One"],
3820+
default: "One",
3821+
},
3822+
extraArray: {
3823+
type: "array",
3824+
items: {
3825+
type: "object",
3826+
properties: {
3827+
extraProperty: {
3828+
type: "string",
3829+
},
3830+
},
3831+
required: ["extraProperty"],
3832+
},
3833+
required: ["items"],
3834+
},
3835+
},
3836+
required: ["type", "extraArray"],
3837+
},
3838+
]);
3839+
const data = { type: "One", extraArray: [] };
3840+
3841+
expect(getMatchingOption(data, options)).eql(0);
3842+
});
3843+
3844+
it("disregards nested required properties (recursive array)", () => {
3845+
const options = Object.freeze([
3846+
{
3847+
type: "object",
3848+
properties: {
3849+
type: {
3850+
type: "string",
3851+
enum: ["One"],
3852+
default: "One",
3853+
},
3854+
extraArray: {
3855+
type: "array",
3856+
items: {
3857+
type: "object",
3858+
properties: {
3859+
nestedArray: {
3860+
type: "array",
3861+
items: {
3862+
type: "object",
3863+
properties: {
3864+
nestedProperty: {
3865+
type: "string",
3866+
},
3867+
},
3868+
required: ["nestedProperty"],
3869+
},
3870+
required: ["items"],
3871+
},
3872+
},
3873+
required: ["nestedArray"],
3874+
},
3875+
required: ["items"],
3876+
},
3877+
},
3878+
required: ["type", "extraArray"],
3879+
},
3880+
]);
3881+
const data = { type: "One", extraArray: [{ nestedArray: [{}] }] };
3882+
3883+
expect(getMatchingOption(data, options)).eql(0);
3884+
});
3885+
});
3886+
});
37173887
});

0 commit comments

Comments
 (0)