import { Contains, IsDefined, MinLength, ValidateNested, ValidatePromise } from '../../src/decorator/decorators'; import { Validator } from '../../src/validation/Validator'; import { ValidationTypes } from '../../src/validation/ValidationTypes'; const validator = new Validator(); describe('promise validation', () => { it('should not validate missing nested objects', () => { expect.assertions(4); class MySubClass { @MinLength(5) name: string; } class MyClass { @Contains('hello') title: string; @ValidatePromise() @ValidateNested() @IsDefined() mySubClass: Promise; } const model: any = new MyClass(); model.title = 'helo'; return validator.validate(model).then(errors => { expect(errors[1].target).toEqual(model); expect(errors[1].value).toBeUndefined(); expect(errors[1].property).toEqual('mySubClass'); expect(errors[1].constraints).toEqual({ isDefined: 'mySubClass should not be null or undefined' }); }); }); it('should validate nested objects', () => { expect.assertions(24); class MySubClass { @MinLength(5) name: string; } class MyClass { @Contains('hello') title: string; @ValidatePromise() @ValidateNested() mySubClass: Promise; @ValidatePromise() @ValidateNested() mySubClasses: Promise; } const model = new MyClass(); model.title = 'helo world'; const mySubClass = new MySubClass(); mySubClass.name = 'my'; model.mySubClass = Promise.resolve(mySubClass); const mySubClasses = [new MySubClass(), new MySubClass()]; mySubClasses[0].name = 'my'; mySubClasses[1].name = 'not-short'; model.mySubClasses = Promise.resolve(mySubClasses); return validator.validate(model).then(errors => { return Promise.all([model.mySubClass, model.mySubClasses]).then(([modelMySubClass, modelMySubClasses]) => { expect(errors.length).toEqual(3); expect(errors[0].target).toEqual(model); expect(errors[0].property).toEqual('title'); expect(errors[0].constraints).toEqual({ contains: 'title must contain a hello string' }); expect(errors[0].value).toEqual('helo world'); expect(errors[1].target).toEqual(model); expect(errors[1].property).toEqual('mySubClass'); expect(errors[1].value).toEqual(modelMySubClass); expect(errors[1].constraints).toBeUndefined(); const subError1 = errors[1].children[0]; expect(subError1.target).toEqual(modelMySubClass); expect(subError1.property).toEqual('name'); expect(subError1.constraints).toEqual({ minLength: 'name must be longer than or equal to 5 characters' }); expect(subError1.value).toEqual('my'); expect(errors[2].target).toEqual(model); expect(errors[2].property).toEqual('mySubClasses'); expect(errors[2].value).toEqual(modelMySubClasses); expect(errors[2].constraints).toBeUndefined(); const subError2 = errors[2].children[0]; expect(subError2.target).toEqual(modelMySubClasses); expect(subError2.value).toEqual(modelMySubClasses[0]); expect(subError2.property).toEqual('0'); const subSubError = subError2.children[0]; expect(subSubError.target).toEqual(modelMySubClasses[0]); expect(subSubError.property).toEqual('name'); expect(subSubError.constraints).toEqual({ minLength: 'name must be longer than or equal to 5 characters' }); expect(subSubError.value).toEqual('my'); }); }); }); it('should validate when nested is not object', () => { expect.assertions(4); class MySubClass { @MinLength(5) name: string; } class MyClass { @ValidatePromise() @ValidateNested() mySubClass: MySubClass; } const model = new MyClass(); model.mySubClass = 'invalidnested object' as any; return validator.validate(model).then(errors => { expect(errors[0].target).toEqual(model); expect(errors[0].property).toEqual('mySubClass'); expect(errors[0].children.length).toEqual(1); const subError = errors[0].children[0]; expect(subError.constraints).toEqual({ [ValidationTypes.NESTED_VALIDATION]: 'nested property mySubClass must be either object or array', }); }); }); it('should validate array promise', () => { expect.assertions(5); class MyClass { @ValidatePromise() @MinLength(2) arrProperty: Promise; } const model = new MyClass(); model.arrProperty = Promise.resolve(['one']); return validator.validate(model).then(errors => { return Promise.all([model.arrProperty]).then(([modelArrProperty]) => { expect(errors.length).toEqual(1); expect(errors[0].target).toEqual(model); expect(errors[0].property).toEqual('arrProperty'); expect(errors[0].constraints).toEqual({ minLength: 'arrProperty must be longer than or equal to 2 characters', }); expect(errors[0].value).toEqual(modelArrProperty); }); }); }); });