Skip to content

Commit

Permalink
Merge pull request #234 from Kashoo/issue-98-custom-validation
Browse files Browse the repository at this point in the history
Issue #98: Pass correct values to final param of custom validation constraints
  • Loading branch information
dkichler authored Feb 19, 2018
2 parents 0d869cc + 8b1a7ac commit 45945d3
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 16 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
This project adheres to [Semantic Versioning](http://semver.org/). All notable changes will be documented in this file.

## [Unreleased]
Nothing yet.
### Fixed
- [#98](https://github.com/Kashoo/synctos/issues/98): Final argument of custom validation constraint receives incorrect value

## [2.0.0] - 2018-02-16
### Added
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ In either case, specification files must be denoted by the `.spec.js` filename s

To execute the full test suite and lint the project's JS files with JSHint, run `npm test` from the project's root directory. A detailed, human-readable code coverage report is generated at `build/coverage/lcov-report/index.html`.

### Document definitions validator
### Document definitions schema validator

Whenever configuration elements are added or updated, the document definitions schema (see the `src/validation/document-definition-schema` and `src/validation/property-validator-schema` modules) must also be updated for use by the document-definitions-validator module. The schema is defined according to the [Joi](https://github.com/hapijs/joi) library's API. See the project's official API [documentation](https://github.com/hapijs/joi/blob/v13.1.1/API.md) for more info.
Whenever configuration elements are added or updated, the document definitions schema (see the `src/validation/document-definition-schema` and `src/validation/property-validator-schema` modules) must also be updated for use by the document-definitions-validator module. The schema is defined according to the [Joi](https://github.com/hapijs/joi) library's API. See the project's official API [documentation](https://github.com/hapijs/joi/blob/v13.1.2/API.md) for more info.

### Documentation

Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -515,15 +515,15 @@ propertyValidators: {
type: 'integer',
minimumValue: 1,
maximumValue: 100,
customValidation: function(doc, oldDoc, currentItemElement, validationItemStack) {
customValidation: function(doc, oldDoc, currentItemEntry, validationItemStack) {
var parentObjectElement = validationItemStack[validationItemStack.length - 1];
var parentObjectName = parentObjectElement.itemName;
var parentObjectValue = parentObjectElement.itemValue;
var parentObjectOldValue = parentObjectElement.oldItemValue;
var currentPropName = currentItemElement.itemName;
var currentPropValue = currentItemElement.itemValue;
var currentPropOldValue = currentItemElement.oldItemValue;
var currentPropName = currentItemEntry.itemName;
var currentPropValue = currentItemEntry.itemValue;
var currentPropOldValue = currentItemEntry.oldItemValue;
var currentPropPath = parentObjectName + '.' + currentPropName;
var myStringPropPath = parentObjectName + '.myStringProp';
Expand Down
6 changes: 3 additions & 3 deletions samples/sample-sync-doc-definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ function() {
}

// Checks that a business ID is valid (an integer greater than 0) and is not changed from the old version of the document
function validateBusinessIdProperty(doc, oldDoc, currentItemElement, validationItemStack) {
function validateBusinessIdProperty(doc, oldDoc, currentItemEntry, validationItemStack) {
var parentObjectElement = validationItemStack[validationItemStack.length - 1];

var businessId = currentItemElement.itemValue;
var oldBusinessId = currentItemElement.oldItemValue;
var businessId = currentItemEntry.itemValue;
var oldBusinessId = currentItemEntry.oldItemValue;

var validationErrors = [ ];

Expand Down
2 changes: 1 addition & 1 deletion src/validation/property-validator-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ function universalConstraintSchemas(typeEqualitySchema) {
immutableWhenSetStrict: dynamicConstraintSchema(joi.boolean()),
mustEqual: dynamicConstraintSchema(mustEqualConstraintSchema(typeEqualitySchema)),
mustEqualStrict: dynamicConstraintSchema(mustEqualConstraintSchema(typeEqualitySchema)),
customValidation: joi.func().maxArity(4) // Function parameters: doc, oldDoc, currentItemElement, validationItemStack
customValidation: joi.func().maxArity(4) // Function parameters: doc, oldDoc, currentItemEntry, validationItemStack
};
}

Expand Down
2 changes: 1 addition & 1 deletion templates/sync-function-validation-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ function validationModule() {
var currentItemEntry = itemStack[itemStack.length - 1];

// Copy all but the last/top element so that the item's parent is at the top of the stack for the custom validation function
var customValidationItemStack = itemStack.slice(-1);
var customValidationItemStack = itemStack.slice(0, -1);

var customValidationErrors = validator.customValidation(doc, oldDoc, currentItemEntry, customValidationItemStack);

Expand Down
66 changes: 66 additions & 0 deletions test/custom-validation.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const testHelper = require('../src/testing/test-helper.js');

describe('Custom validation constraint:', () => {
beforeEach(() => {
testHelper.initSyncFunction('build/sync-functions/test-custom-validation-sync-function.js');
});

it('allows a document if custom validation succeeds', () => {
const doc = {
_id: 'my-doc',
type: 'customValidationDoc',
baseProp: {
failValidation: false,
customValidationProp: 'foo'
}
};

testHelper.verifyDocumentCreated(doc);
});

it('blocks a document if custom validation fails', () => {
const oldDoc = {
_id: 'my-doc',
type: 'customValidationDoc',
baseProp: { }
};

const doc = {
_id: 'my-doc',
type: 'customValidationDoc',
baseProp: {
failValidation: true,
customValidationProp: 'foo'
}
};

const expectedCurrentItemEntry = {
itemValue: doc.baseProp.customValidationProp,
oldItemValue: null,
itemName: 'customValidationProp'
};
const expectedValidationItemStack = [
{ // The document (root)
itemValue: doc,
oldItemValue: oldDoc,
itemName: null
},
{ // The parent of the property with the customValidation constraint
itemValue: doc.baseProp,
oldItemValue: oldDoc.baseProp,
itemName: 'baseProp'
}
];

testHelper.verifyDocumentNotReplaced(
doc,
oldDoc,
'customValidationDoc',
[
'doc: ' + JSON.stringify(doc),
'oldDoc: ' + JSON.stringify(oldDoc),
'currentItemEntry: ' + JSON.stringify(expectedCurrentItemEntry),
'validationItemStack: ' + JSON.stringify(expectedValidationItemStack)
]);
});
});
34 changes: 34 additions & 0 deletions test/resources/custom-validation-doc-definitions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
function() {
return {
customValidationDoc: {
typeFilter: simpleTypeFilter,
channels: { write: 'write' },
propertyValidators: {
baseProp: {
type: 'object',
propertyValidators: {
failValidation: {
type: 'boolean'
},
customValidationProp: {
type: 'string',
customValidation: function(doc, oldDoc, currentItemEntry, validationItemStack) {
var parentItemValue = validationItemStack[validationItemStack.length - 1].itemValue;
if (parentItemValue && parentItemValue.failValidation) {
return [
'doc: ' + jsonStringify(doc),
'oldDoc: ' + jsonStringify(oldDoc),
'currentItemEntry: ' + jsonStringify(currentItemEntry),
'validationItemStack: ' + jsonStringify(validationItemStack)
];
} else {
return [ ];
}
}
}
}
}
}
}
};
}
7 changes: 3 additions & 4 deletions test/resources/underscore-js-doc-definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
myProp: {
type: 'string',
required: true,
customValidation: function(doc, oldDoc, currentItemElement, validationItemStack) {
var escapedItemValue = _.chain(currentItemElement.itemValue).escape().value();

if (escapedItemValue === currentItemElement.itemValue) {
customValidation: function(doc, oldDoc, currentItemEntry, validationItemStack) {
var escapedItemValue = _.chain(currentItemEntry.itemValue).escape().value();
if (escapedItemValue === currentItemEntry.itemValue) {
return null;
} else {
return [ 'escaped value of "myProp" does not match raw value' ];
Expand Down

0 comments on commit 45945d3

Please sign in to comment.