Skip to content

Commit

Permalink
[cb-#99] simplifying request-resource-response lifecycle
Browse files Browse the repository at this point in the history
  • Loading branch information
crookse committed Dec 17, 2019
1 parent 3480885 commit 6c9a1ad
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 274 deletions.
3 changes: 3 additions & 0 deletions mod.ts
Expand Up @@ -19,6 +19,7 @@ import mime_db from "https://raw.githubusercontent.com/jshttp/mime-db/v1.39.0/db
// Exceptions
import http_exception from "./src/exceptions/http_exception.ts";
import http_middleware_exception from "./src/exceptions/http_middleware_exception.ts";
import http_response_exception from "./src/exceptions/http_response_exception.ts";

// Http
import middleware from "./src/http/middleware.ts";
Expand Down Expand Up @@ -69,6 +70,8 @@ namespace Drash {
export const HttpException = http_exception;
export type HttpMiddlewareException = http_middleware_exception;
export const HttpMiddlewareException = http_middleware_exception;
export type HttpResponseException = http_response_exception;
export const HttpResponseException = http_response_exception;
}

export namespace Loggers {
Expand Down
38 changes: 38 additions & 0 deletions src/exceptions/http_response_exception.ts
@@ -0,0 +1,38 @@
/**
* @memberof Drash.Exceptions
* @class HttpResponseException
*
* @description
* This class gives you a way to throw HTTP errors semantically in the
* response class. The difference between this class and `HttpException`
* comes when you want to check which exception was thrown via
* `exception.constructor.name`.
*
* This class extends `Error`.
*/
export default class HttpResponseException extends Error {
/**
* @description
* A property to hold the HTTP response code associated with this
* exception.
*
* @property number code
*/
public code: number;

// FILE MARKER: CONSTRUCTOR //////////////////////////////////////////////////

/**
* @description
* Construct an object of this class.
*
* @param number code
* The HTTP response code associated with this exception.
* @param string message
* (optional) The exception message.
*/
constructor(code: number, message?: string) {
super(message);
this.code = code;
}
}
50 changes: 25 additions & 25 deletions src/http/server.ts
Expand Up @@ -111,10 +111,6 @@ export default class Server {
configs.address = "127.0.0.1:8000";
}

if (!configs.response_output) {
configs.response_output = "application/json";
}

this.configs = configs;

if (configs.hasOwnProperty("middleware")) {
Expand All @@ -137,6 +133,31 @@ export default class Server {

// FILE MARKER: METHODS - PUBLIC /////////////////////////////////////////////

/**
* @description
* Get the request object with more properties and methods.
*
* @param ServerRequest request
* The request object.
*
* @return any
* Returns the `ServerRequest` object with more properties and methods.
*/
public getRequest(request: any): any {
request = Drash.Services.HttpService.hydrateHttpRequest(request, {
base_url: this.configs.address,
});

// Were we able to determine the content type the request wants to receive?
if (!request.response_content_type) {
request.response_content_type = this.configs.response_output
? this.configs.response_output
: "application/json";
}

return request;
}

/**
* @description
* Handle an HTTP request from the Deno server.
Expand Down Expand Up @@ -541,27 +562,6 @@ export default class Server {
return new Drash.Exceptions.HttpException(code);
}

/**
* @description
* Get the request object with more properties and methods.
*
* @param ServerRequest request
* The request object.
*
* @return any
* Returns the `ServerRequest` object with more properties and methods.
*/
protected getRequest(request: any): any {
request = Drash.Services.HttpService.hydrateHttpRequest(request, {
base_url: this.configs.address,
headers: {
"Response-Content-Type-Default": this.configs.response_output
},
});

return request;
}

/**
* @description
* Get the resource class.
Expand Down
2 changes: 1 addition & 1 deletion src/services/http_service.ts
Expand Up @@ -277,7 +277,7 @@ export default class HttpService {
* @return string
*/
public getResponseContentType(request): string {
let contentType = request.headers.get("Response-Content-Type-Default");
let contentType = null;

// Check the request's headers to see if `response-content-type:
// {content-type}` has been specified
Expand Down
5 changes: 1 addition & 4 deletions tests/members.ts
Expand Up @@ -43,10 +43,7 @@ class MockServer extends Drash.Http.Server {
}

function responseJsonEquals(actual: any, expected: any) {
return assertEquals(
JSON.parse(decoder.decode(actual)),
expected
);
return assertEquals(JSON.parse(decoder.decode(actual)), expected);
}

function runTest(name, testFn) {
Expand Down
167 changes: 11 additions & 156 deletions tests/unit/http/middleware_test.ts
Expand Up @@ -27,20 +27,7 @@ members.test("Middleware server/resource: missing CSRF token", async () => {
)
);

members.assert.responseJsonEquals(
response.body,
{
status_code: 400,
status_message: "Bad Request",
body: "No CSRF token, dude.",
request: {
method: "GET",
uri: "/users/1",
url_query_params: {},
url: "127.0.0.1:8000/users/1"
}
}
);
members.assert.responseJsonEquals(response.body, "No CSRF token, dude.");
});

/**
Expand Down Expand Up @@ -73,20 +60,7 @@ members.test("Middleware server/resource: wrong CSRF token", async () => {
)
);

members.assert.responseJsonEquals(
response.body,
{
status_code: 400,
status_message: "Bad Request",
body: "Wrong CSRF token, dude.",
request: {
method: "GET",
uri: "/users/1",
url_query_params: {},
url: "127.0.0.1:8000/users/1"
}
}
);
members.assert.responseJsonEquals(response.body, "Wrong CSRF token, dude.");
});

/**
Expand Down Expand Up @@ -120,20 +94,7 @@ members.test("Middleware server/resource: user is not an admin", async () => {
)
);

members.assert.responseJsonEquals(
response.body,
{
status_code: 400,
status_message: "Bad Request",
body: "'user_id' unknown.",
request: {
method: "GET",
uri: "/users/1",
url_query_params: {},
url: "127.0.0.1:8000/users/1"
}
}
);
members.assert.responseJsonEquals(response.body, "'user_id' unknown.");
});

/**
Expand Down Expand Up @@ -167,22 +128,7 @@ members.test("Middleware server/resource: pass", async () => {
)
);

members.assert.responseJsonEquals(
response.body,
{
status_code: 200,
status_message: "OK",
body: {
name: "Thor"
},
request: {
method: "GET",
uri: "/users/1",
url_query_params: {},
url: "127.0.0.1:8000/users/1"
}
}
);
members.assert.responseJsonEquals(response.body, {name: "Thor"});
});

/**
Expand All @@ -202,20 +148,7 @@ members.test("Middleware server/resource: middleware not found", async () => {

let response = await server.handleHttpRequest(members.mockRequest("/users/1", "get"));

members.assert.responseJsonEquals(
response.body,
{
status_code: 418,
status_message: "I'm a teapot",
body: "I'm a teapot",
request: {
method: "GET",
uri: "/users/1",
url_query_params: {},
url: "127.0.0.1:8000/users/1"
}
}
);
members.assert.responseJsonEquals(response.body, "I'm a teapot");
});

/**
Expand All @@ -237,20 +170,7 @@ members.test("Middleware server before_response: missing header", async () => {

let response = await server.handleHttpRequest(members.mockRequest("/", "get"));

members.assert.responseJsonEquals(
response.body,
{
status_code: 400,
status_message: "Bad Request",
body: "Missing header, guy.",
request: {
method: "GET",
uri: "/",
url_query_params: {},
url: "127.0.0.1:8000/"
}
}
);
members.assert.responseJsonEquals(response.body, "Missing header, guy.");
});

/**
Expand All @@ -272,20 +192,7 @@ members.test("Middleware server before_response: wrong header", async () => {

let response = await server.handleHttpRequest(members.mockRequest("/", "get", {send_response: "yes please"}));

members.assert.responseJsonEquals(
response.body,
{
status_code: 400,
status_message: "Bad Request",
body: "Ha... try again. Close though.",
request: {
method: "GET",
uri: "/",
url_query_params: {},
url: "127.0.0.1:8000/"
}
}
);
members.assert.responseJsonEquals(response.body, "Ha... try again. Close though.");
});

/**
Expand All @@ -307,20 +214,7 @@ members.test("Middleware server before_response: pass", async () => {

let response = await server.handleHttpRequest(members.mockRequest("/", "get", {send_response: "yes do it"}));

members.assert.responseJsonEquals(
response.body,
{
status_code: 200,
status_message: "OK",
body: "got",
request: {
method: "GET",
uri: "/",
url_query_params: {},
url: "127.0.0.1:8000/"
}
}
);
members.assert.responseJsonEquals(response.body, "got");
});

/**
Expand All @@ -344,20 +238,7 @@ members.test("Middleware server before_request: missing header", async () => {

members.assert.equal(request.hello, undefined);

members.assert.responseJsonEquals(
response.body,
{
status_code: 400,
status_message: "Bad Request",
body: "Missing header, guy.",
request: {
method: "GET",
uri: "/",
url_query_params: {},
url: "127.0.0.1:8000/"
}
}
);
members.assert.responseJsonEquals(response.body, "Missing header, guy.");
});

/**
Expand All @@ -381,20 +262,7 @@ members.test("Middleware server before_request: wrong header", async () => {

members.assert.equal(request.hello, undefined);

members.assert.responseJsonEquals(
response.body,
{
status_code: 400,
status_message: "Bad Request",
body: "Ha... try again. Close though.",
request: {
method: "GET",
uri: "/",
url_query_params: {},
url: "127.0.0.1:8000/"
}
}
);
members.assert.responseJsonEquals(response.body, "Ha... try again. Close though.");
});

/**
Expand All @@ -418,20 +286,7 @@ members.test("Middleware server before_request: pass", async () => {

members.assert.equal(request.hello, "changed_before_request");

members.assert.responseJsonEquals(
response.body,
{
status_code: 200,
status_message: "OK",
body: "got",
request: {
method: "GET",
uri: "/",
url_query_params: {},
url: "127.0.0.1:8000/"
}
}
);
members.assert.responseJsonEquals(response.body, "got");
});

////////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 6c9a1ad

Please sign in to comment.