Skip to content

Commit 0ef898e

Browse files
chiangfvlapo
authored andcommitted
fix: pass context for isDefined and custom validators (#296)
Close #292
1 parent c454cf9 commit 0ef898e

File tree

2 files changed

+56
-5
lines changed

2 files changed

+56
-5
lines changed

Diff for: src/validation/ValidationExecutor.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export class ValidationExecutor {
168168

169169
// handle IS_DEFINED validation type the special way - it should work no matter skipUndefinedProperties/skipMissingProperties is set or not
170170
this.defaultValidations(object, value, definedMetadatas, validationError.constraints);
171+
this.mapContexts(object, value, definedMetadatas, validationError);
171172

172173
if (value === undefined && this.validatorOptions && this.validatorOptions.skipUndefinedProperties === true) {
173174
return;
@@ -186,6 +187,7 @@ export class ValidationExecutor {
186187
this.nestedValidations(value, nestedValidationMetadatas, validationError.children);
187188

188189
this.mapContexts(object, value, metadatas, validationError);
190+
this.mapContexts(object, value, customValidationMetadatas, validationError);
189191
}
190192

191193
private generateValidationError(object: Object, value: any, propertyName: string) {
@@ -376,7 +378,13 @@ export class ValidationExecutor {
376378
return metadatas
377379
.forEach(metadata => {
378380
if (metadata.context) {
379-
const type = this.getConstraintType(metadata);
381+
let customConstraint;
382+
if (metadata.type === ValidationTypes.CUSTOM_VALIDATION) {
383+
const customConstraints = this.metadataStorage.getTargetValidatorConstraints(metadata.constraintCls);
384+
customConstraint = customConstraints[0];
385+
}
386+
387+
const type = this.getConstraintType(metadata, customConstraint);
380388

381389
if (error.constraints[type]) {
382390
if (!error.contexts) {

Diff for: test/functional/validation-options.spec.ts

+47-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import "es6-shim";
2-
import {Contains, Matches, MinLength, ValidateNested, ValidatorConstraint, Validate } from "../../src/decorator/decorators";
2+
import {Contains, IsDefined, Matches, MinLength, ValidateNested, ValidatorConstraint, Validate } from "../../src/decorator/decorators";
33
import {Validator} from "../../src/validation/Validator";
4-
import {ValidationError, ValidatorConstraintInterface} from "../../src";
4+
import {ValidationError, ValidatorConstraintInterface, ValidationOptions, registerDecorator, ValidationArguments} from "../../src";
55

66
import {should, use} from "chai";
77

@@ -937,6 +937,30 @@ describe("validation options", function() {
937937
describe("context", function() {
938938

939939
it("should map context", function() {
940+
function IsLongerThan(property: string, validationOptions?: ValidationOptions) {
941+
return function (object: Object, propertyName: string) {
942+
registerDecorator({
943+
target: object.constructor,
944+
propertyName: propertyName,
945+
options: validationOptions,
946+
constraints: [property],
947+
name: "isLongerThan",
948+
validator: {
949+
validate(value: any, args: ValidationArguments) {
950+
const [relatedPropertyName] = args.constraints;
951+
const relatedValue = (args.object as any)[relatedPropertyName];
952+
if (relatedValue === undefined || relatedValue === null)
953+
return true;
954+
955+
return typeof value === "string" &&
956+
typeof relatedValue === "string" &&
957+
value.length > relatedValue.length;
958+
}
959+
}
960+
});
961+
};
962+
}
963+
940964
class MyClass {
941965
@Contains("hello", {
942966
message: "String is not valid. You string must contain a hello word",
@@ -953,14 +977,33 @@ describe("validation options", function() {
953977
}
954978
})
955979
someOtherProperty: string;
980+
981+
@IsDefined({
982+
context: {
983+
foo: "bar"
984+
}
985+
})
986+
requiredProperty: string;
987+
988+
@IsLongerThan("lastName", {
989+
context: { baz: "qux" },
990+
message: "$property must be longer then $constraint1. Given value: $value"
991+
})
992+
firstName: string;
993+
994+
lastName: string;
956995
}
957996

958997
const model = new MyClass();
959-
// model.someProperty = "hell no world";
998+
model.firstName = "Short";
999+
model.lastName = "LongerThanFirstName";
1000+
9601001
return validator.validate(model).then(errors => {
961-
errors.length.should.be.equal(2);
1002+
errors.length.should.be.equal(4);
9621003
errors[0].contexts["contains"].should.be.eql({ hi: "there" });
9631004
errors[1].contexts["contains"].should.be.eql({ bye: "now" });
1005+
errors[2].contexts["isDefined"].should.be.eql({ foo: "bar" });
1006+
errors[3].contexts["isLongerThan"].should.be.eql({ baz: "qux" });
9641007
});
9651008
});
9661009

0 commit comments

Comments
 (0)