adds ability to match suffix, prefix and contains for the serverValidationManager + tests

This commit is contained in:
Shannon
2020-07-15 15:08:17 +10:00
parent 74ab1c0262
commit f4d8d0e28e
2 changed files with 119 additions and 21 deletions

View File

@@ -17,7 +17,7 @@ function serverValidationManager($timeout) {
// - segment
// - callback (function)
// - id (unique identifier, auto-generated, used internally for unsubscribing the callback)
// - 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)
// - options (used for complex properties, can contain options.matchType which can be either "suffix" or "prefix" or "contains")
var callbacks = [];
// The array of error message objects, each object 'key' is:
@@ -30,8 +30,7 @@ function serverValidationManager($timeout) {
var items = [];
var defaultMatchOptions = {
matchPrefix: false,
matchSuffix: false
matchType: null
}
/** calls the callback specified with the errors specified, used internally */
@@ -99,19 +98,25 @@ function serverValidationManager($timeout) {
//find all errors for this property
return _.filter(items, function (item) {
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;
if (!item.propertyAlias) {
return false;
}
var ignoreField = options.matchPrefix || options.matchSuffix;
var matchProp = item.propertyAlias === propertyAlias
? true
: options.matchType === "prefix"
? item.propertyAlias.startsWith(propertyAlias + '/')
: options.matchType === "suffix"
? item.propertyAlias.endsWith('/' + propertyAlias)
: options.matchType === "contains"
? item.propertyAlias.includes('/' + propertyAlias + '/')
: false;
return matchProp
&& item.culture === culture
&& item.segment === segment
// ignore field matching if match options are used
&& (ignoreField || (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
&& (options.matchType || (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
});
}
@@ -234,20 +239,22 @@ function serverValidationManager($timeout) {
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;
var matchProp = cb.propertyAlias === propertyAlias
? true
: cb.options.matchType === "prefix"
? propertyAlias.startsWith(cb.propertyAlias + '/')
: cb.options.matchType === "suffix"
? propertyAlias.endsWith('/' + cb.propertyAlias)
: cb.options.matchType === "contains"
? propertyAlias.includes('/' + cb.propertyAlias + '/')
: false;
//returns any callback that have been registered directly against the field and for only the property
return matchProp
&& cb.culture === culture
&& cb.segment === segment
// if the callback is configured to patch prefix then we ignore the field value
&& (ignoreField || (cb.fieldName === fieldName || (cb.fieldName === undefined || cb.fieldName === "")));
// ignore field matching if match options are used
&& (cb.options.matchType || (cb.fieldName === fieldName || (cb.fieldName === undefined || cb.fieldName === "")));
});
return found;
}

View File

@@ -639,13 +639,13 @@
if (propertyErrors.length > 0) {
callbackA.push(propertyErrors);
}
}, null, { matchPrefix: true });
}, null, { matchType: "prefix" });
serverValidationManager.subscribe("myProperty/34E3A26C-103D-4A05-AB9D-7E14032309C3/addresses", null, null, function (isValid, propertyErrors, allErrors) {
if (propertyErrors.length > 0) {
callbackB.push(propertyErrors);
}
}, null, { matchPrefix: true });
}, null, { matchType: "prefix" });
//act
// will match A:
@@ -682,6 +682,97 @@
});
it('can subscribe to a property validation path suffix', function () {
var callbackA = [];
var callbackB = [];
//arrange
serverValidationManager.subscribe("myProperty", null, null, function (isValid, propertyErrors, allErrors) {
if (propertyErrors.length > 0) {
callbackA.push(propertyErrors);
}
}, null, { matchType: "suffix" });
serverValidationManager.subscribe("city", null, null, function (isValid, propertyErrors, allErrors) {
if (propertyErrors.length > 0) {
callbackB.push(propertyErrors);
}
}, null, { matchType: "suffix" });
//act
// will match A:
serverValidationManager.addPropertyError("myProperty", null, null, "property error", null);
serverValidationManager.addPropertyError("myProperty", null, "value1", "value error", null);
// will match B
serverValidationManager.addPropertyError("myProperty/34E3A26C-103D-4A05-AB9D-7E14032309C3/addresses/FBEAEE8F-4BC9-43EE-8B81-FCA8978850F1/city", null, null, "property error", null);
serverValidationManager.addPropertyError("myProperty/34E3A26C-103D-4A05-AB9D-7E14032309C3/addresses/FBEAEE8F-4BC9-43EE-8B81-FCA8978850F1/city", null, "value1", "value error", null);
// won't match:
serverValidationManager.addPropertyError("myProperty", "en-US", null, "property error", null);
serverValidationManager.addPropertyError("myProperty/34E3A26C-103D-4A05-AB9D-7E14032309C3/addresses/FBEAEE8F-4BC9-43EE-8B81-FCA8978850F1/city", "en-US", null, "property error", null);
serverValidationManager.addPropertyError("otherProperty", null, null, "property error", null);
serverValidationManager.addPropertyError("otherProperty", null, "value1", "value error", null);
//assert
// both will be called each time addPropertyError is called
expect(callbackA.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(2); // 2 errors for A
expect(callbackB[callbackB.length - 1].length).toEqual(2); // 2 errors for B
// clear the data and notify
callbackA = [];
callbackB = [];
serverValidationManager.notify();
$timeout.flush();
expect(callbackA.length).toEqual(1);
expect(callbackB.length).toEqual(1);
expect(callbackA[0].length).toEqual(2); // 2 errors for A
expect(callbackB[0].length).toEqual(2); // 2 errors for B
});
it('can subscribe to a property validation path contains', function () {
var callbackA = [];
//arrange
serverValidationManager.subscribe("addresses", null, null, function (isValid, propertyErrors, allErrors) {
if (propertyErrors.length > 0) {
callbackA.push(propertyErrors);
}
}, null, { matchType: "contains" });
//act
// will match A:
serverValidationManager.addPropertyError("addresses", null, null, "property error", null);
serverValidationManager.addPropertyError("addresses", null, "value1", "value error", null);
serverValidationManager.addPropertyError("myProperty/34E3A26C-103D-4A05-AB9D-7E14032309C3/addresses/FBEAEE8F-4BC9-43EE-8B81-FCA8978850F1/city", null, null, "property error", null);
serverValidationManager.addPropertyError("myProperty/34E3A26C-103D-4A05-AB9D-7E14032309C3/addresses/FBEAEE8F-4BC9-43EE-8B81-FCA8978850F1/city", null, "value1", "value error", null);
// won't match:
serverValidationManager.addPropertyError("addresses", "en-US", null, "property error", null);
serverValidationManager.addPropertyError("addresses/34E3A26C-103D-4A05-AB9D-7E14032309C3/addresses/FBEAEE8F-4BC9-43EE-8B81-FCA8978850F1/city", "en-US", null, "property error", null);
serverValidationManager.addPropertyError("otherProperty", null, null, "property error", null);
serverValidationManager.addPropertyError("otherProperty", null, "value1", "value error", null);
//assert
// both will be called each time addPropertyError is called
expect(callbackA.length).toEqual(8);
expect(callbackA[callbackA.length - 1].length).toEqual(4); // 4 errors for A
// clear the data and notify
callbackA = [];
serverValidationManager.notify();
$timeout.flush();
expect(callbackA.length).toEqual(1);
expect(callbackA[0].length).toEqual(4); // 4 errors for A
});
// TODO: Finish testing the rest!
});