Skip to content

Commit

Permalink
fix: pass context for isDefined and custom validators (#296)
Browse files Browse the repository at this point in the history
Close #292
  • Loading branch information
chiangf authored and vlapo committed Oct 28, 2019
1 parent c454cf9 commit 0ef898e
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 5 deletions.
10 changes: 9 additions & 1 deletion src/validation/ValidationExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export class ValidationExecutor {

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

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

this.mapContexts(object, value, metadatas, validationError);
this.mapContexts(object, value, customValidationMetadatas, validationError);
}

private generateValidationError(object: Object, value: any, propertyName: string) {
Expand Down Expand Up @@ -376,7 +378,13 @@ export class ValidationExecutor {
return metadatas
.forEach(metadata => {
if (metadata.context) {
const type = this.getConstraintType(metadata);
let customConstraint;
if (metadata.type === ValidationTypes.CUSTOM_VALIDATION) {
const customConstraints = this.metadataStorage.getTargetValidatorConstraints(metadata.constraintCls);
customConstraint = customConstraints[0];
}

const type = this.getConstraintType(metadata, customConstraint);

if (error.constraints[type]) {
if (!error.contexts) {
Expand Down
51 changes: 47 additions & 4 deletions test/functional/validation-options.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "es6-shim";
import {Contains, Matches, MinLength, ValidateNested, ValidatorConstraint, Validate } from "../../src/decorator/decorators";
import {Contains, IsDefined, Matches, MinLength, ValidateNested, ValidatorConstraint, Validate } from "../../src/decorator/decorators";
import {Validator} from "../../src/validation/Validator";
import {ValidationError, ValidatorConstraintInterface} from "../../src";
import {ValidationError, ValidatorConstraintInterface, ValidationOptions, registerDecorator, ValidationArguments} from "../../src";

import {should, use} from "chai";

Expand Down Expand Up @@ -937,6 +937,30 @@ describe("validation options", function() {
describe("context", function() {

it("should map context", function() {
function IsLongerThan(property: string, validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
constraints: [property],
name: "isLongerThan",
validator: {
validate(value: any, args: ValidationArguments) {
const [relatedPropertyName] = args.constraints;
const relatedValue = (args.object as any)[relatedPropertyName];
if (relatedValue === undefined || relatedValue === null)
return true;

return typeof value === "string" &&
typeof relatedValue === "string" &&
value.length > relatedValue.length;
}
}
});
};
}

class MyClass {
@Contains("hello", {
message: "String is not valid. You string must contain a hello word",
Expand All @@ -953,14 +977,33 @@ describe("validation options", function() {
}
})
someOtherProperty: string;

@IsDefined({
context: {
foo: "bar"
}
})
requiredProperty: string;

@IsLongerThan("lastName", {
context: { baz: "qux" },
message: "$property must be longer then $constraint1. Given value: $value"
})
firstName: string;

lastName: string;
}

const model = new MyClass();
// model.someProperty = "hell no world";
model.firstName = "Short";
model.lastName = "LongerThanFirstName";

return validator.validate(model).then(errors => {
errors.length.should.be.equal(2);
errors.length.should.be.equal(4);
errors[0].contexts["contains"].should.be.eql({ hi: "there" });
errors[1].contexts["contains"].should.be.eql({ bye: "now" });
errors[2].contexts["isDefined"].should.be.eql({ foo: "bar" });
errors[3].contexts["isLongerThan"].should.be.eql({ baz: "qux" });
});
});

Expand Down

0 comments on commit 0ef898e

Please sign in to comment.