Updates serverValidationManager to have different matching options, fixes unit tests, now need to write tests for the Suffix match

This commit is contained in:
Shannon
2020-07-14 18:09:46 +10:00
parent 0b78b277e3
commit 74ab1c0262
4 changed files with 73 additions and 34 deletions
@@ -288,7 +288,7 @@ function valPropertyMsg(serverValidationManager, localizationService, angularHel
"",
serverValidationManagerCallback,
currentSegment,
true // match property validation path prefix
{ matchPrefix: true } // match property validation path prefix
));
}
@@ -111,8 +111,6 @@ function valServer(serverValidationManager) {
}
}
unsubscribe.push(serverValidationManager.subscribe(
propertyValidationPath,
currentCulture,
@@ -17,7 +17,7 @@ function serverValidationManager($timeout) {
// - segment
// - callback (function)
// - id (unique identifier, auto-generated, used internally for unsubscribing the callback)
// - matchPrefix (used for complex properties, default is false, if set to true the callback will fire for any item with this propertyAlias prefix)
// - options (used for complex properties, can contain options.matchPrefix options.matchSuffix if either are set to true the callback will fire for any item with this propertyAlias prefix or suffix)
var callbacks = [];
// The array of error message objects, each object 'key' is:
@@ -28,7 +28,12 @@ function serverValidationManager($timeout) {
// The object also contains:
// - errorMsg
var items = [];
var defaultMatchOptions = {
matchPrefix: false,
matchSuffix: false
}
/** calls the callback specified with the errors specified, used internally */
function executeCallback(errorsForCallback, callback, culture, segment, isValid) {
@@ -72,7 +77,7 @@ function serverValidationManager($timeout) {
});
}
function getPropertyErrors(propertyAlias, culture, segment, fieldName, matchPrefixValidationPath) {
function getPropertyErrors(propertyAlias, culture, segment, fieldName, options) {
if (!Utilities.isString(propertyAlias)) {
throw "propertyAlias must be a string";
}
@@ -87,14 +92,26 @@ function serverValidationManager($timeout) {
segment = null;
}
if (!options) {
options = defaultMatchOptions;
}
//find all errors for this property
return _.filter(items, function (item) {
return ((matchPrefixValidationPath ? (item.propertyAlias === propertyAlias || (item.propertyAlias && item.propertyAlias.startsWith(propertyAlias + '/'))) : item.propertyAlias === propertyAlias)
//return ((matchPrefixValidationPath ? (item.propertyAlias === propertyAlias || propertyAlias.startsWith(item.propertyAlias + '/')) : item.propertyAlias === propertyAlias)
var matchProp = options.matchPrefix
? (item.propertyAlias === propertyAlias || (item.propertyAlias && item.propertyAlias.startsWith(propertyAlias + '/')))
: options.matchSuffix
? (item.propertyAlias === propertyAlias || (item.propertyAlias && item.propertyAlias.endsWith('/' + propertyAlias)))
: item.propertyAlias === propertyAlias;
var ignoreField = options.matchPrefix || options.matchSuffix;
return matchProp
&& item.culture === culture
&& item.segment === segment
// ignore field matching if
&& (matchPrefixValidationPath || (item.fieldName === fieldName || (fieldName === undefined || fieldName === ""))));
// ignore field matching if match options are used
&& (ignoreField || (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
});
}
@@ -122,7 +139,7 @@ function serverValidationManager($timeout) {
}
else if (cb.propertyAlias != null) {
//its a property error
const propErrors = getPropertyErrors(cb.propertyAlias, cb.culture, cb.segment, cb.fieldName, cb.matchPrefix);
const propErrors = getPropertyErrors(cb.propertyAlias, cb.culture, cb.segment, cb.fieldName, cb.options);
const valid = propErrors.length === 0;
executeCallback(propErrors, cb.callback, cb.culture, cb.segment, valid);
}
@@ -213,12 +230,24 @@ function serverValidationManager($timeout) {
var found = _.filter(callbacks, function (cb) {
if (!cb.options) {
cb.options = defaultMatchOptions;
}
var matchProp = cb.options.matchPrefix
? (cb.propertyAlias === propertyAlias || propertyAlias.startsWith(cb.propertyAlias + '/'))
: cb.options.matchSuffix
? (cb.propertyAlias === propertyAlias || propertyAlias.endsWith(cb.propertyAlias + '/'))
: cb.propertyAlias === propertyAlias;
var ignoreField = cb.options.matchPrefix || cb.options.matchSuffix;
//returns any callback that have been registered directly against the field and for only the property
return ((cb.matchPrefix ? (cb.propertyAlias === propertyAlias || propertyAlias.startsWith(cb.propertyAlias + '/')) : cb.propertyAlias === propertyAlias)
return matchProp
&& cb.culture === culture
&& cb.segment === segment
// if the callback is configured to patch prefix then we ignore the field value
&& (cb.matchPrefix || (cb.fieldName === fieldName || (cb.fieldName === undefined || cb.fieldName === ""))));
&& (ignoreField || (cb.fieldName === fieldName || (cb.fieldName === undefined || cb.fieldName === "")));
});
return found;
}
@@ -567,7 +596,7 @@ function serverValidationManager($timeout) {
* field alias to listen for.
* If propertyAlias is null, then this subscription is for a field property (not a user defined property).
*/
subscribe: function (propertyAlias, culture, fieldName, callback, segment, matchValidationPathPrefix) {
subscribe: function (propertyAlias, culture, fieldName, callback, segment, options) {
if (!callback) {
return;
}
@@ -604,7 +633,7 @@ function serverValidationManager($timeout) {
fieldName: fieldName,
callback: callback,
id: id,
matchPrefix: matchValidationPathPrefix
options: options
};
}
@@ -740,8 +769,8 @@ function serverValidationManager($timeout) {
return undefined;
},
getPropertyErrorsByValidationPath: function (propertyAlias, culture, segment) {
return getPropertyErrors(propertyAlias, culture, segment, "", true);
getPropertyErrorsByValidationPath: function (propertyAlias, culture, segment, options) {
return getPropertyErrors(propertyAlias, culture, segment, "", options);
},
/**
@@ -533,6 +533,7 @@
var args1;
var args2;
var numCalled = 0;
var numCalledWithErrors = 0;
//arrange
serverValidationManager.subscribe("myProperty", null, "value1", function (isValid, propertyErrors, allErrors) {
@@ -546,6 +547,9 @@
serverValidationManager.subscribe("myProperty", null, "", function (isValid, propertyErrors, allErrors) {
numCalled++;
if (propertyErrors.length > 0) {
numCalledWithErrors++;
}
args2 = {
isValid: isValid,
propertyErrors: propertyErrors,
@@ -553,9 +557,6 @@
};
}, null);
console.log("NOW ADDING ERRORS " + numCalled);
//act
serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1", null);
serverValidationManager.addPropertyError("myProperty", null, "value2", "Some value 2", null);
@@ -578,19 +579,23 @@
expect(args2.propertyErrors[0].errorMsg).toEqual("Some value 1");
expect(args2.propertyErrors[1].errorMsg).toEqual("Some value 2");
expect(args2.allErrors.length).toEqual(2);
//Even though only 2 errors are added, the callback is called 3 times because any call to addPropertyError will invoke the callback
// if the property has errors existing.
expect(numCalled).toEqual(3);
//3 errors are added but a call to subscribe also calls the callback
expect(numCalled).toEqual(4);
expect(numCalledWithErrors).toEqual(3);
});
it('can subscribe to a culture error for both a property and its sub field', function () {
var args1;
var args2;
var numCalled = 0;
var numCalledWithErrors = 0;
//arrange
serverValidationManager.subscribe(null, "en-US", null, function (isValid, propertyErrors, allErrors) {
numCalled++;
if (propertyErrors.length > 0) {
numCalledWithErrors++;
}
args1 = {
isValid: isValid,
propertyErrors: propertyErrors,
@@ -601,25 +606,28 @@
serverValidationManager.subscribe(null, "es-ES", null, function (isValid, propertyErrors, allErrors) {
numCalled++;
if (propertyErrors.length > 0) {
numCalledWithErrors++;
}
args2 = {
isValid: isValid,
propertyErrors: propertyErrors,
allErrors: allErrors
};
}, null);
//act
serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1", null);
serverValidationManager.addPropertyError("myProperty", "en-US", "value1", "Some value 1", null);
serverValidationManager.addPropertyError("myProperty", "en-US", "value2", "Some value 2", null);
serverValidationManager.addPropertyError("myProperty", "fr-FR", "", "Some value 3", null);
serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1", null); // doesn't match
serverValidationManager.addPropertyError("myProperty", "en-US", "value1", "Some value 1", null); // matches callback 1
serverValidationManager.addPropertyError("myProperty", "en-US", "value2", "Some value 2", null); // matches callback 1
serverValidationManager.addPropertyError("myProperty", "fr-FR", "", "Some value 3", null); // doesn't match - but all callbacks still execute
//assert
expect(args1.isValid).toBe(false);
expect(args2.isValid).toBe(true); // no errors registered for this callback
expect(numCalled).toEqual(8); // both subscriptions will be called once per addPropertyError
expect(numCalled).toEqual(10); // both subscriptions will be called once per addPropertyError and also called on subscribe
expect(numCalledWithErrors).toEqual(3); // the first subscription is called 3 times with errors because the 4th time we call addPropertyError all callbacks still execute
});
it('can subscribe to a property validation path prefix', function () {
@@ -628,12 +636,16 @@
//arrange
serverValidationManager.subscribe("myProperty", null, null, function (isValid, propertyErrors, allErrors) {
callbackA.push(propertyErrors);
}, null, true);
if (propertyErrors.length > 0) {
callbackA.push(propertyErrors);
}
}, null, { matchPrefix: true });
serverValidationManager.subscribe("myProperty/34E3A26C-103D-4A05-AB9D-7E14032309C3/addresses", null, null, function (isValid, propertyErrors, allErrors) {
callbackB.push(propertyErrors);
}, null, true);
if (propertyErrors.length > 0) {
callbackB.push(propertyErrors);
}
}, null, { matchPrefix: true });
//act
// will match A:
@@ -652,7 +664,7 @@
// both will be called each time addPropertyError is called
expect(callbackA.length).toEqual(8);
expect(callbackB.length).toEqual(8);
expect(callbackB.length).toEqual(6); // B - will only be called 6 times with errors because the first 2 calls to addPropertyError haven't added errors for B yet
expect(callbackA[callbackA.length - 1].length).toEqual(4); // 4 errors for A
expect(callbackB[callbackB.length - 1].length).toEqual(2); // 2 errors for B