Skip to content

Commit

Permalink
add response-view decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
vincent178 committed Dec 14, 2016
1 parent b3a1a7b commit d3671b6
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 20 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ test/spec/*.js.map
/stderr
/es6/
/lib/
/dts/
/dts/

.vscode

1 change: 1 addition & 0 deletions src/constants/metadata-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export const CONTROLLER_URL = "tsed:controller:url";
export const CONTROLLER_DEPEDENCIES = "ted:controller:depedencies";
export const ENDPOINT_ARGS = "tsed:endpoint";
export const ENDPOINT_VIEW = "tsed:endpoint:view";

// INJECTION META TO CONTROLLER METHOD
export const INJECT_PARAMS = "tsed:inject:params";
Expand Down
32 changes: 19 additions & 13 deletions src/controllers/endpoint.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as Express from "express";
import {INJECT_PARAMS, EXPRESS_REQUEST, EXPRESS_RESPONSE, EXPRESS_NEXT_FN} from "../constants/metadata-keys";
import {INJECT_PARAMS, EXPRESS_REQUEST, EXPRESS_RESPONSE, EXPRESS_NEXT_FN, ENDPOINT_VIEW} from "../constants/metadata-keys";
import Metadata from "../metadata/metadata";
import {IInvokableScope} from "../interfaces/InvokableScope";
import {BadRequest} from "ts-httpexceptions";
Expand Down Expand Up @@ -161,12 +161,8 @@ export class Endpoint {
}

})
.then(
data => this.send(data, request, response, next, this.hasImpliciteNextFunction(instance)),
err => {
next(err);
}
);
.then(data => this.send(instance, data, {request, response, next}))
.catch(err => next(err));
};

/**
Expand All @@ -175,7 +171,7 @@ export class Endpoint {
* @param localScope
* @returns {(any|any)[]}
*/
private getParameters(instance, localScope): any[] {
private getParameters(instance, localScope: IInvokableScope): any[] {

const requestService = InjectorService.get(RequestService);

Expand Down Expand Up @@ -237,14 +233,24 @@ export class Endpoint {

/**
* Format data and send it to the client.
* @param instance
* @param data
* @param request
* @param response
* @param next
* @param impliciteNext
* @param localScope
* @returns {any}
*/
private send = (data, request, response, next, impliciteNext) => {
private send = (instance, data, localScope: IInvokableScope) => {

const impliciteNext = this.hasImpliciteNextFunction(instance);
const request = localScope.request;
const response = localScope.response;
const next = localScope.next;

const viewPath = Metadata.get(ENDPOINT_VIEW, instance, this.methodClassName);

if (viewPath !== undefined) {
response.render(viewPath, data);
return data;
}

// preset status code
if (request.method === "POST") {
Expand Down
3 changes: 2 additions & 1 deletion src/decorators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export * from "./next";
export * from "./header";
export * from "./use";
export * from "./controller";
export * from "./service";
export * from "./service";
export * from "./response-view";
13 changes: 13 additions & 0 deletions src/decorators/response-view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {ENDPOINT_VIEW} from "../constants/metadata-keys";
import Metadata from "../metadata/metadata";

export function ResponseView(viewPath: string): Function {

return <T> (target: Function, targetKey: string, descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> => {

Metadata.set(ENDPOINT_VIEW, viewPath, target, targetKey);

return descriptor;
};
}

53 changes: 48 additions & 5 deletions test/endpoint.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,50 +210,70 @@ describe("Endpoint :", () => {
describe('Endpoint.send()', () => {

it('should send response (boolean)', () => {
const instance = fakeController.getInstance();
const endpoint: any = new Endpoint(fakeController, 'myMethodThrowException');
const fakeRequest = new FakeRequest();
const fakeResponse = new FakeResponse();
const next = () => {};

const result = endpoint.send(true, fakeRequest, fakeResponse, next);
endpoint.send(instance, true, {
request: fakeRequest,
response: fakeResponse,
next
});

expect(fakeResponse._body).to.be.a('string');
expect(fakeResponse._body).to.equal('true');
});

it('should send response (number)', () => {
const instance = fakeController.getInstance();
const endpoint: any = new Endpoint(fakeController, 'myMethodThrowException');
const fakeRequest = new FakeRequest();
const fakeResponse = new FakeResponse();
const next = () => {};

const result = endpoint.send(1, fakeRequest, fakeResponse, next);
endpoint.send(instance, 1, {
request: fakeRequest,
response: fakeResponse,
next
});

expect(fakeResponse._body).to.be.a('string');
expect(fakeResponse._body).to.equal('1');
});

it('should send response (null)', () => {
const instance = fakeController.getInstance();
const endpoint: any = new Endpoint(fakeController, 'myMethodThrowException');
const fakeRequest = new FakeRequest();
const fakeResponse = new FakeResponse();
const next = () => {};

const result = endpoint.send(null, fakeRequest, fakeResponse, next);
endpoint.send(instance, null, {
request: fakeRequest,
response: fakeResponse,
next
});

expect(fakeResponse._body).to.be.a('string');
expect(fakeResponse._body).to.equal('null');
});

it('should send response (date)', () => {
const instance = fakeController.getInstance();
const endpoint: any = new Endpoint(fakeController, 'myMethodThrowException');
const fakeRequest = new FakeRequest();
const fakeResponse = new FakeResponse();
const next = () => {};

const date = new Date();

const result = endpoint.send(date, fakeRequest, fakeResponse, next);
endpoint.send(instance, date, {
request: fakeRequest,
response: fakeResponse,
next
});

expect(fakeResponse._body).to.be.a('string');
expect(fakeResponse._headers).to.contains('Content-Type:text/json');
Expand All @@ -262,6 +282,7 @@ describe("Endpoint :", () => {
});

it('should send response (object)', () => {
const instance = fakeController.getInstance();
const endpoint: any = new Endpoint(fakeController, 'myMethodThrowException');
const fakeRequest = new FakeRequest();
fakeRequest.method = 'POST';
Expand All @@ -271,13 +292,35 @@ describe("Endpoint :", () => {

const obj = {test:'1', test2: new Date()};

const result = endpoint.send(obj, fakeRequest, fakeResponse, next);
endpoint.send(instance, obj, {
request: fakeRequest,
response: fakeResponse,
next
});

expect(fakeResponse._body).to.be.a('string');
expect(fakeResponse._headers).to.contains('Content-Type:text/json');
expect(fakeResponse._body).to.equal(JSON.stringify(obj));

});

it('should render response (html)', () => {
const instance = fakeController.getInstance();
const endpoint: any = new Endpoint(fakeController, 'myMethodAnnotated4');
const fakeRequest = new FakeRequest();
const fakeResponse = new FakeResponse();
const next = () => {};
const obj = {test: "test"};

endpoint.send(instance, {test: "test"}, {
request: fakeRequest,
response: fakeResponse,
next
});

expect(fakeResponse._body).to.be.a('string');
expect(fakeResponse._body).to.equal("home" + obj.toString());
});
})

});
5 changes: 5 additions & 0 deletions test/helper/FakeResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export class FakeResponse {
public send(value: any) {
this._body = '' + value;
}

public render(viewPath: string, data: Object) {
this._body = viewPath + data;
}

/**
*
* @param value
Expand Down
5 changes: 5 additions & 0 deletions test/helper/TestInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Next} from '../../src/decorators/next';
import {Response} from '../../src/decorators/response';
import {BodyParams, PathParams, CookiesParams, QueryParams} from '../../src/decorators/params';
import {Required} from '../../src/decorators/required';
import {ResponseView} from "../../src/decorators/response-view";

export class TestInstance {

Expand Down Expand Up @@ -60,6 +61,10 @@ export class TestInstance {

}

@ResponseView("home")
myMethodAnnotated4() {
}

/**
*
* @param request
Expand Down

0 comments on commit d3671b6

Please sign in to comment.