Skip to content

Commit

Permalink
Merge 339a335 into c9621c1
Browse files Browse the repository at this point in the history
  • Loading branch information
adammfrank committed Nov 11, 2017
2 parents c9621c1 + 339a335 commit ad27f2d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"@nestjs/microservices": "^4.0.0",
"@nestjs/testing": "^4.0.0",
"@nestjs/websockets": "^4.0.0",
"class-transformer": "^0.1.8",
"class-validator": "^0.7.3",
"cli-color": "^1.1.0",
"engine.io-client": "^3.1.1",
"express": "^4.16.2",
Expand Down
30 changes: 30 additions & 0 deletions src/core/pipes/pipes-model-parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { HttpException } from "@nestjs/core";
import {
PipeTransform,
Pipe,
ArgumentMetadata,
HttpStatus
} from "@nestjs/common";
import { validate } from "class-validator";
import { plainToClass } from "class-transformer";

@Pipe()
export class PipesModelParser implements PipeTransform<any> {
async transform(value, metadata: ArgumentMetadata) {
const { metatype } = metadata;
if (!metatype || !this.toValidate(metatype)) {
return value;
}
const entity = plainToClass(metatype, value);
const errors = await validate(entity);
if (errors.length > 0) {
throw new HttpException("Validation failed", HttpStatus.BAD_REQUEST);
}
return entity;
}

private toValidate(metatype): boolean {
const types = [String, Boolean, Number, Array, Object];
return !types.find(type => metatype === type);
}
}
51 changes: 51 additions & 0 deletions src/core/test/pipes/pipes-model-parser.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as sinon from "sinon";
import { expect } from "chai";
import { PipesModelParser } from "./../../pipes/pipes-model-parser";
import { ArgumentMetadata } from "@nestjs/common";
import { IsString } from "class-validator";

class TestModel {
constructor() {}
@IsString()
public prop1: string;

@IsString()
public prop2: string;
}

describe("PipesModelParser", () => {
let target: PipesModelParser;
let testModel;
const metadata: ArgumentMetadata = {
type: "body",
metatype: TestModel,
data: ""
};
beforeEach(() => {
target = new PipesModelParser();
});
describe("transform", () => {
describe("when metadata is empty or undefined", () => {
it("should return the value unchanged", async () => {
const testObj = { prop1: "value1", prop2: "value2" };
expect(await target.transform(testObj, {} as any)).to.equal(testObj);
expect(await target.transform(testObj, {} as any)).to.not.be.instanceOf(
TestModel
);
});
});
describe("when metadata contains a class", () => {
it("should return an instance of the class", async () => {
const testObj = { prop1: "value1", prop2: "value2" };
const result = await target.transform(testObj, metadata);
expect(result).to.be.instanceOf(TestModel);
});
});
describe("when validation vails", () => {
it("should throw an error", async () => {
const testObj = { prop1: "value1" };
return expect(target.transform(testObj, metadata)).to.be.rejected;
});
});
});
});

0 comments on commit ad27f2d

Please sign in to comment.