From 5086386508d6a37beb5c83b63f4c34b82c41ce4c Mon Sep 17 00:00:00 2001 From: Jeremy Daly Date: Wed, 11 Jul 2018 16:42:31 -0400 Subject: [PATCH] close #52 by adding main handler async support --- index.js | 11 ++++--- lib/request.js | 2 +- lib/response.js | 7 ++-- test/run.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 test/run.js diff --git a/index.js b/index.js index 9cf046d..77c0c0f 100644 --- a/index.js +++ b/index.js @@ -126,7 +126,7 @@ class API { // Set the event, context and callback this._event = event - this._context = this.context = context + this._context = this.context = typeof context === 'object' ? context : {} this._cb = cb // Initalize request and response objects @@ -136,7 +136,7 @@ class API { try { // Parse the request - request.parseRequest() + await request.parseRequest() // Loop through the middleware and await response for (const mw of this._middleware) { @@ -175,9 +175,12 @@ class API { } } catch(e) { - this.catchErrors(e,response) + await this.catchErrors(e,response) } + // Return the final response + return response._response + } // end run function @@ -236,7 +239,7 @@ class API { await this._finally(response._request,response) // Execute the primary callback - this._cb(err,res) + typeof this._cb === 'function' && this._cb(err,res) } // end _callback diff --git a/lib/request.js b/lib/request.js index 6e87cae..25e5523 100644 --- a/lib/request.js +++ b/lib/request.js @@ -36,7 +36,7 @@ class REQUEST { } // end constructor // Parse the request - parseRequest() { + async parseRequest() { // Set the method this.method = this.app._event.httpMethod.toUpperCase() diff --git a/lib/response.js b/lib/response.js index ce0d521..c6de6f5 100644 --- a/lib/response.js +++ b/lib/response.js @@ -42,6 +42,9 @@ class RESPONSE { // Default Etag support this._etag = false + + // Default response object + this._response = {} } // Sets the statusCode @@ -386,7 +389,7 @@ class RESPONSE { } // Create the response - const response = { + this._response = { headers: this._headers, statusCode: this._statusCode, body: this._request.method === 'HEAD' ? '' : UTILS.encodeBody(body), @@ -394,7 +397,7 @@ class RESPONSE { } // Trigger the callback function - this.app._callback(null, response, this) + this.app._callback(null, this._response, this) } // end send diff --git a/test/run.js b/test/run.js new file mode 100644 index 0000000..10186eb --- /dev/null +++ b/test/run.js @@ -0,0 +1,86 @@ +'use strict'; + +const expect = require('chai').expect // Assertion library + +// Init API instance +const api = require('../index')({ version: 'v1.0' }) +const api_error = require('../index')({ version: 'v1.0' }) +const api_error_path = require('../index')({ version: 'v1.0' }) + +// NOTE: Set test to true +api._test = true; +api_error._test = true; +api_error_path._test = true; + +let event = { + httpMethod: 'get', + path: '/test', + body: {}, + headers: { + 'Content-Type': 'application/json' + } +} + +/******************************************************************************/ +/*** DEFINE TEST ROUTE ***/ +/******************************************************************************/ +api.get('/test', function(req,res) { + res.status(200).json({ + method: 'get', + status: 'ok' + }) +}) + +api.get('/testError', function(req,res) { + res.status(404).error('some error') +}) + +api_error.get('/testErrorThrown', function(req,res) { + throw new Error('some thrown error') +}) + + +/******************************************************************************/ +/*** BEGIN TESTS ***/ +/******************************************************************************/ + +describe('Main handler Async/Await:', function() { + + it('With context object', async function() { + let _event = Object.assign({},event,{}) + let result = await api.run(_event,{}) + expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + }) // end it + + it('Without context object', async function() { + let _event = Object.assign({},event,{}) + let result = await api.run(_event) + expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + }) // end it + + it('With callback', async function() { + let _event = Object.assign({},event,{}) + let result = await api.run(_event,{},(err,res) => {}) + expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + }) // end it + + it('Triggered Error', async function() { + let _event = Object.assign({},event,{ path: '/testError' }) + let result = await api.run(_event,{}) + expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"some error"}', isBase64Encoded: false }) + }) // end it + + it('Thrown Error', async function() { + let _event = Object.assign({},event,{ path: '/testErrorThrown' }) + let result = await api_error.run(_event,{}) + expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 500, body: '{"error":"some thrown error"}', isBase64Encoded: false }) + }) // end it + + it('Routes Error', async function() { + let _event = Object.assign({},event,{ path: '/testRoute' }) + let result = await api_error_path.run(_event,{}) + expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) + }) // end it + + +}) // end tests