Skip to content

Commit

Permalink
Fix deep nested dynamic types validation (#138)
Browse files Browse the repository at this point in the history
* Fix deep nested dynamic types validation

* Address PR comments
  • Loading branch information
talyssonoc authored Jun 15, 2020
1 parent 1da1204 commit 210dc05
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2.0.1 - 2020-06-15

Fix:

- Fix deep nested dynamic types validation [[#132](https://github.com/talyssonoc/structure/issues/132)]

## 2.0.0 - 2020-03-31

Refactors:
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"packages": ["packages/*"],
"version": "2.0.0",
"version": "2.0.1",
"npmClient": "yarn",
"useWorkspaces": true
}
4 changes: 2 additions & 2 deletions packages/jest-structure/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jest-structure",
"version": "2.0.0",
"version": "2.0.1",
"description": "Jest assertions to use with Structure",
"main": "index.js",
"author": "Talysson <[email protected]>",
Expand All @@ -15,7 +15,7 @@
"node": ">=10.13.0"
},
"devDependencies": {
"structure": "2.0.0"
"structure": "2.0.1"
},
"peerDependencies": {
"jest": "^25.1.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/structure/dist/structure.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/structure/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "structure",
"version": "2.0.0",
"version": "2.0.1",
"description": "A simple schema/attributes library built on top of modern JavaScript",
"main": "src/index.js",
"browser": "dist/structure.js",
Expand Down Expand Up @@ -52,7 +52,7 @@
"babel-loader": "^8.1.0",
"coveralls": "^3.1.0",
"electron": "^9.0.0",
"jest-structure": "2.0.0",
"jest-structure": "2.0.1",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.9"
}
Expand Down
20 changes: 16 additions & 4 deletions packages/structure/src/validation/validations/nested.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,32 @@ function getNestedValidations(typeSchema) {
return joiSchema;
}

exports.resolveDynamicLinks = function resolveDynamicLinks({ schema, joiValidation }) {
const resolveDynamicLinks = function resolveDynamicLinks({ schema, joiValidation }) {
return schema.attributeDefinitions.reduce((joiValidation, attributeDefinition) => {
if (!attributeDefinition.hasDynamicType) {
return joiValidation;
}

const type = attributeDefinition.resolveType();
const nestedSchema = type[SCHEMA];

if (!type[SCHEMA]) {
// warning: uses Joi internals
// https://github.com/hapijs/joi/blob/v16.1.8/lib/types/any.js#L72 ⤵
// https://github.com/hapijs/joi/blob/v16.1.8/lib/base.js#L699 ⤵
// https://github.com/hapijs/joi/blob/v16.1.8/lib/modify.js#L149
if (!nestedSchema || joiValidation._ids._get(nestedSchema.identifier)) {
return joiValidation;
}

const attributeValidation = type[SCHEMA].validation;
const attributeValidation = nestedSchema.validation;

return joiValidation.shared(attributeValidation.joiValidation);
const sharedValidation = joiValidation.shared(attributeValidation.joiValidation);

return resolveDynamicLinks({
schema: nestedSchema,
joiValidation: sharedValidation,
});
}, joiValidation);
};

exports.resolveDynamicLinks = resolveDynamicLinks;
96 changes: 96 additions & 0 deletions packages/structure/test/unit/validation/nestedStructure.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -421,5 +421,101 @@ describe('validation', () => {
});
});
});

describe('when nesting is deep', () => {
it('validates properly with manual validation', () => {
const Vehicle = attributes({
year: {
type: Number,
required: true,
},
})(class Vehicle {});

const UserPersonalInformation = attributes(
{
name: String,
vehicle: 'Vehicle',
},
{
dynamics: {
Vehicle: () => Vehicle,
},
}
)(class UserPersonalInformation {});

const AutoRiskProfile = attributes(
{
userPersonalInformation: {
type: 'UserPersonalInformation',
required: true,
},
},
{
dynamics: {
UserPersonalInformation: () => UserPersonalInformation,
},
}
)(class AutoRiskProfile {});

expect(() => {
const autoRiskProfile = new AutoRiskProfile({
userPersonalInformation: new UserPersonalInformation({
name: 'a',
vehicle: new Vehicle({
year: 2018,
}),
}),
});

autoRiskProfile.validate();
}).not.toThrow();
});

it('validates properly with strict mode', () => {
const Vehicle = attributes({
year: {
type: Number,
required: true,
},
})(class Vehicle {});

const UserPersonalInformation = attributes(
{
name: String,
vehicle: 'Vehicle',
},
{
dynamics: {
Vehicle: () => Vehicle,
},
}
)(class UserPersonalInformation {});

const AutoRiskProfile = attributes(
{
userPersonalInformation: {
type: 'UserPersonalInformation',
required: true,
},
},
{
dynamics: {
UserPersonalInformation: () => UserPersonalInformation,
},
}
)(class AutoRiskProfile {});

expect(() => {
AutoRiskProfile.buildStrict({
userPersonalInformation: new UserPersonalInformation({
name: 'a',
vehicle: new Vehicle({
year: 2018,
}),
}),
});
}).not.toThrow();
});
});
});
});

0 comments on commit 210dc05

Please sign in to comment.