New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

lambda-api

Package Overview
Dependencies
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lambda-api - npm Package Compare versions

Comparing version 0.4.0 to 0.5.0

lib/mimemap.js

239

index.js

@@ -6,9 +6,8 @@ 'use strict';

* @author Jeremy Daly <jeremy@jeremydaly.com>
* @version 0.3.0
* @version 0.5.0
* @license MIT
*/
const REQUEST = require('./request.js') // Response object
const RESPONSE = require('./response.js') // Response object
const Promise = require('bluebird') // Promise library
const REQUEST = require('./lib/request.js') // Response object
const RESPONSE = require('./lib/response.js') // Response object

@@ -55,10 +54,6 @@ // Create the API class

// Promise placeholder for final route promise resolution
this._promise = function() { console.log('no promise to resolve') }
this._reject = function() { console.log('no promise to reject') }
// Global error status
this._errorStatus = 500
// Testing flag
// Testing flag (disables logging)
this._test = false

@@ -68,32 +63,13 @@

// GET: convenience method
get(path, handler) {
this.METHOD('GET', path, handler)
}
// POST: convenience method
post(path, handler) {
this.METHOD('POST', path, handler)
}
// PUT: convenience method
put(path, handler) {
this.METHOD('PUT', path, handler)
}
// Convenience methods (path, handler)
get(p,h) { this.METHOD('GET',p,h) }
post(p,h) { this.METHOD('POST',p,h) }
put(p,h) { this.METHOD('PUT',p,h) }
patch(p,h) { this.METHOD('PATCH',p,h) }
delete(p,h) { this.METHOD('DELETE',p,h) }
options(p,h) { this.METHOD('OPTIONS',p,h) }
// PATCH: convenience method
patch(path, handler) {
this.METHOD('PATCH', path, handler)
}
// DELETE: convenience method
delete(path, handler) {
this.METHOD('DELETE', path, handler)
}
// OPTIONS: convenience method
options(path, handler) {
this.METHOD('OPTIONS', path, handler)
}
// METHOD: Adds method and handler to routes

@@ -130,3 +106,3 @@ METHOD(method, path, handler) {

route.slice(0,i+1)
);
)

@@ -138,9 +114,6 @@ } // end for loop

// RUN: This runs the routes
run(event,context,cb) { // TODO: Make this dynamic
async run(event,context,cb) {
this.startTimer('total')
this._done = false
// Set the event, context and callback

@@ -151,83 +124,61 @@ this._event = event

// Initalize response object
let response = new RESPONSE(this)
let request = {}
try {
// Initalize response and request objects
this.response = new RESPONSE(this)
this.request = new REQUEST(this)
Promise.try(() => { // Start a promise
// Loop through the middleware and await response
for (const mw of this._middleware) {
await new Promise(r => { mw(this.request,this.response,() => { r() }) })
} // end for
// Initalize the request object
request = new REQUEST(this)
// Execute the primary handler
await this.handler(this.request,this.response)
// Execute the request
return this.execute(request,response)
} catch(e) {
this.catchErrors(e)
}
}).catch((e) => {
} // end run function
// Error messages should never be base64 encoded
response._isBase64 = false
// Strip the headers (TODO: find a better way to handle this)
response._headers = {}
let message;
// Catch all async/sync errors
async catchErrors(e) {
if (e instanceof Error) {
response.status(this._errorStatus)
message = e.message
!this._test && console.log(e)
} else {
message = e
!this._test && console.log('API Error:',e)
}
// Error messages should never be base64 encoded
this.response._isBase64 = false
// Execute error middleware
if (this._errors.length > 0) {
// Strip the headers (TODO: find a better way to handle this)
this.response._headers = {}
// Init stack queue
let queue = []
let message;
// Loop through the middleware and queue promises
for (let i in this._errors) {
queue.push(() => {
return new Promise((resolve, reject) => {
this._promise = () => { resolve() } // keep track of the last resolve()
this._reject = (e) => { reject(e) } // keep track of the last reject()
this._errors[i](e,request,response,() => { resolve() }) // execute the errors with the resolve callback
}) // end promise
}) // end queue
} // end for
if (e instanceof Error) {
this.response.status(this._errorStatus)
message = e.message
!this._test && console.log(e)
} else {
message = e
!this._test && console.log('API Error:',e)
}
// Return Promise.each serialially
return Promise.each(queue, function(queue_item) {
return queue_item()
}).then(() => {
response.json({'error':message})
})
// Execute error middleware
for (const err of this._errors) {
// Promisify error middleware
await new Promise(r => { err(e,this.request,this.response,() => { r() }) })
} // end for
} else {
response.json({'error':message})
}
this.response.json({'error':message})
}).finally(() => {
this._finally(request,response)
})
} // end run function
} // end catch
// Custom callback
_callback(err, res) {
async _callback(err, res) {
// Resolve any outstanding promise
this._promise()
// Execute finally
await this._finally(this.request,this.response)
this._done = true
this.endTimer('total')
if (res) {
if (this._debug) {
console.log(this._procTimes)
}
}
// Execute the primary callback

@@ -239,2 +190,3 @@ this._cb(err,res)

// Middleware handler

@@ -251,3 +203,4 @@ use(fn) {

// Finally function
// Finally handler
finally(fn) {

@@ -257,73 +210,5 @@ this._finally = fn

// Process
execute(req,res) {
// Init stack queue
let queue = []
// If execute is called after the app is done, just return out
if (this._done) { return; }
// If there is middleware
if (this._middleware.length > 0) {
// Loop through the middleware and queue promises
for (let i in this._middleware) {
queue.push(() => {
return new Promise((resolve, reject) => {
this._promise = () => { resolve() } // keep track of the last resolve()
this._reject = (e) => { reject(e) } // keep track of the last reject()
this._middleware[i](req,res,() => { resolve() }) // execute the middleware with the resolve callback
}) // end promise
}) // end queue
} // end for
} // end if
// Push the main execution path to the queue stack
queue.push(() => {
return new Promise((resolve, reject) => {
this._promise = () => { resolve() } // keep track of the last resolve()
this._reject = (e) => { reject(e) } // keep track of the last reject()
this.handler(req,res) // execute the handler with no callback
})
})
// Return Promise.each serialially
return Promise.each(queue, function(queue_item) {
return queue_item()
})
} // end execute
//-------------------------------------------------------------------------//
// TIMER FUNCTIONS
//-------------------------------------------------------------------------//
// Returns the calculated processing times from all stopped timers
getTimers(timer) {
if (timer) {
return this._procTimes[timer]
} else {
return this._procTimes
}
} // end getTimers
// Starts a timer for debugging purposes
startTimer(name) {
this._timers[name] = Date.now()
} // end startTimer
// Ends a timer and calculates the total processing time
endTimer(name) {
try {
this._procTimes[name] = (Date.now()-this._timers[name]) + ' ms'
delete this._timers[name]
} catch(e) {
console.error('Could not end timer: ' + name)
}
} // end endTimer
//-------------------------------------------------------------------------//
// UTILITY FUNCTIONS

@@ -336,3 +221,3 @@ //-------------------------------------------------------------------------//

// Recursive function to create routes object
setRoute(obj, value, path) {

@@ -345,3 +230,3 @@ if (typeof path === "string") {

let p = path.shift()
if (obj[p] === null) { // || typeof obj[p] !== 'object') {
if (obj[p] === null) {
obj[p] = {}

@@ -351,3 +236,3 @@ }

} else {
if (obj[path[0]] === null) { // || typeof obj[path[0]] !== 'object') {
if (obj[path[0]] === null) {
obj[path[0]] = value

@@ -401,5 +286,7 @@ } else {

} // end API class
// Export the API class
// Export the API class as a new instance
module.exports = opts => new API(opts)
{
"name": "lambda-api",
"version": "0.4.0",
"version": "0.5.0",
"description": "Lightweight web framework for your serverless applications",

@@ -31,7 +31,6 @@ "main": "index.js",

"homepage": "https://github.com/jeremydaly/lambda-api#readme",
"dependencies": {
"bluebird": "^3.5.1"
},
"dependencies": {},
"devDependencies": {
"aws-sdk": "^2.218.1",
"aws-sdk": "^2.228.1",
"bluebird": "^3.5.1",
"chai": "^4.1.2",

@@ -42,4 +41,4 @@ "mocha": "^4.0.1",

"engines": {
"node": ">= 6.10.0"
"node": ">= 8.10.0"
}
}

@@ -9,6 +9,4 @@ [![Lambda API](https://www.jeremydaly.com/wp-content/uploads/2018/03/lambda-api-logo.svg)](https://serverless-api.com/)

Lambda API is a lightweight web framework for use with AWS API Gateway and AWS Lambda using Lambda Proxy integration. This closely mirrors (and is based on) other routers like Express.js, but is significantly stripped down to maximize performance with Lambda's stateless, single run executions.
Lambda API is a lightweight web framework for use with AWS API Gateway and AWS Lambda using Lambda Proxy Integration. This closely mirrors (and is based on) other web frameworks like Express.js and Fastify, but is significantly stripped down to maximize performance with Lambda's stateless, single run executions.
**IMPORTANT:** There is a [breaking change](#breaking-change-in-v03) in v0.3 that affects instantiation.
## Simple Example

@@ -21,4 +19,4 @@

// Define a route
api.get('/test', function(req,res) {
res.status(200).json({ status: 'ok' })
api.get('/status', (req,res) => {
res.json({ status: 'ok' })
})

@@ -33,2 +31,4 @@

For a full tutorial see [How To: Build a Serverless API with Serverless, AWS Lambda and Lambda API](https://www.jeremydaly.com/build-serverless-api-serverless-aws-lambda-lambda-api/).
## Why Another Web Framework?

@@ -39,96 +39,17 @@ Express.js, Fastify, Koa, Restify, and Hapi are just a few of the many amazing web frameworks out there for Node.js. So why build yet another one when there are so many great options already? One word: **DEPENDENCIES**.

Lambda API has **ONE** dependency. We use [Bluebird](http://bluebirdjs.com/docs/getting-started.html) promises to serialize asynchronous execution. We use promises because AWS Lambda currently only supports Node v6.10, which doesn't support `async / await`. Bluebird is faster than native promise and it has **no dependencies** either, making it the perfect choice for Lambda API.
Lambda API has **ZERO** dependencies.
Lambda API was written to be extremely lightweight and built specifically for serverless applications using AWS Lambda. It provides support for API routing, serving up HTML pages, issuing redirects, serving binary files and much more. It has a powerful middleware and error handling system, allowing you to implement everything from custom authentication to complex logging systems. Best of all, it was designed to work with Lambda's Proxy Integration, automatically handling all the interaction with API Gateway for you. It parses **REQUESTS** and formats **RESPONSES** for you, allowing you to focus on your application's core functionality, instead of fiddling with inputs and outputs.
## New in v0.4 - Binary Support!
Binary support has been added! This allows you to both send and receive binary files from API Gateway. For more information, see [Enabling Binary Support](#enabling-binary-support).
## Breaking Change in v0.3
Please note that the invocation method has been changed. You no longer need to use the `new` keyword to instantiate Lambda API. It can now be instantiated in one line:
```javascript
const api = require('lambda-api')()
```
`lambda-api` returns a `function` now instead of a `class`, so options can be passed in as its only argument:
```javascript
const api = require('lambda-api')({ version: 'v1.0', base: 'v1' });
## Installation
```
**IMPORTANT:** Upgrading to v0.3.0 requires either removing the `new` keyword or switching to the one-line format. This provides more flexibility for instantiating Lambda API in future releases.
## Lambda Proxy integration
Lambda Proxy Integration is an option in API Gateway that allows the details of an API request to be passed as the `event` parameter of a Lambda function. A typical API Gateway request event with Lambda Proxy Integration enabled looks like this:
```javascript
{
"resource": "/v1/posts",
"path": "/v1/posts",
"httpMethod": "GET",
"headers": {
"Authorization": "Bearer ...",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-us",
"cache-control": "max-age=0",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Cookie": "...",
"Host": "...",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) ...",
"Via": "2.0 ... (CloudFront)",
"X-Amz-Cf-Id": "...",
"X-Amzn-Trace-Id": "...",
"X-Forwarded-For": "xxx.xxx.xxx.xxx",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"queryStringParameters": {
"qs1": "q1"
},
"stageVariables": null,
"requestContext": {
"accountId": "...",
"resourceId": "...",
"stage": "prod",
"requestId": "...",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"apiKey": null,
"sourceIp": "xxx.xxx.xxx.xxx",
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "...",
"user": null
},
"resourcePath": "/v1/posts",
"httpMethod": "GET",
"apiId": "..."
},
"body": null,
"isBase64Encoded": false
}
npm i lambda-api --save
```
The API automatically parses this information to create a normalized `REQUEST` object. The request can then be routed using the APIs methods.
## Requirements
- AWS Lambda running **Node 8.10+**
- AWS Gateway using [Proxy Integration](#lambda-proxy-integration)
## Install
```
npm i lambda-api --save
```
## Configuration
Require the `lambda-api` module into your Lambda handler script and instantiate it. You can initialize the API with the following options:

@@ -148,2 +69,26 @@

## Recent Updates
For detailed release notes see [Releases](https://github.com/jeremydaly/lambda-api/releases).
### v0.5: Remove Bluebird Promises Dependency
Now that AWS Lambda supports Node v8.10, asynchronous operations can be handled more efficiently with `async/await` rather than with promises. The core Lambda API execution engine has been rewritten to take advantage of `async/await`, which means we no longer need to depend on Bluebird. We now have **ZERO** dependencies.
### v0.4: Binary Support
Binary support has been added! This allows you to both send and receive binary files from API Gateway. For more information, see [Enabling Binary Support](#enabling-binary-support).
### v0.3: New Instantiation Method
Please note that the invocation method has been changed. You no longer need to use the `new` keyword to instantiate Lambda API. It can now be instantiated in one line:
```javascript
const api = require('lambda-api')()
```
`lambda-api` returns a `function` now instead of a `class`, so options can be passed in as its only argument:
```javascript
const api = require('lambda-api')({ version: 'v1.0', base: 'v1' });
```
**IMPORTANT:** Upgrading from <v0.3.0 requires either removing the `new` keyword or switching to the one-line format. This provides more flexibility for instantiating Lambda API in future releases.
## Routes and HTTP Methods

@@ -154,11 +99,11 @@

```javascript
api.get('/users', function(req,res) {
api.get('/users', (req,res) => {
// do something
})
api.post('/users', function(req,res) {
api.post('/users', (req,res) => {
// do something
})
api.delete('/users', function(req,res) {
api.delete('/users', (req,res) => {
// do something

@@ -170,3 +115,3 @@ })

```javascript
api.METHOD('patch','/users', function(req,res) {
api.METHOD('trace','/users', (req,res) => {
// do something

@@ -176,2 +121,4 @@ })

All `GET` methods have a `HEAD` alias that executes the `GET` request but returns a blank `body`. `GET` requests should be idempotent with no side effects.
## Route Prefixing

@@ -235,6 +182,7 @@

- `rawHeaders`: An object containing the original request headers (property case preserved)
- `body`: The body of the request.
- `body`: The body of the request. If the `isBase64Encoded` flag is `true`, it will be decoded automatically.
- If the `Content-Type` header is `application/json`, it will attempt to parse the request using `JSON.parse()`
- If the `Content-Type` header is `application/x-www-form-urlencoded`, it will attempt to parse a URL encoded string using `querystring`
- Otherwise it will be plain text.
- `rawBody`: If the `isBase64Encoded` flag is `true`, this is a copy of the original, base64 encoded body
- `route`: The matched route of the request

@@ -255,3 +203,3 @@ - `requestContext`: The `requestContext` passed from the API Gateway

```javascript
api.get('/users', function(req,res) {
api.get('/users', (req,res) => {
res.status(401).error('Not Authorized')

@@ -261,7 +209,7 @@ })

### header(field, value)
### header(key, value)
The `header` method allows for you to set additional headers to return to the client. By default, just the `Content-Type` header is sent with `application/json` as the value. Headers can be added or overwritten by calling the `header()` method with two string arguments. The first is the name of the header and then second is the value.
```javascript
api.get('/users', function(req,res) {
api.get('/users', (req,res) => {
res.header('Content-Type','text/html').send('<div>This is HTML</div>')

@@ -271,2 +219,13 @@ })

**NOTE:** Header keys are converted and stored as lowercase in compliance with [rfc7540 8.1.2. HTTP Header Fields](https://tools.ietf.org/html/rfc7540) for HTTP/2. Header convenience methods (`getHeader`, `hasHeader`, and `removeHeader`) automatically ignore case.
### getHeader([key])
Retrieve the current header object or pass the optional `key` parameter and retrieve a specific header value. `key` is case insensitive.
### hasHeader(key)
Returns a boolean indicating the existence of `key` in the response headers. `key` is case insensitive.
### removeHeader(key)
Removes header matching `key` from the response headers. `key` is case insensitive. This method is chainable.
### send(body)

@@ -279,3 +238,3 @@ The `send` methods triggers the API to return data to the API Gateway. The `send` method accepts one parameter and sends the contents through as is, e.g. as an object, string, integer, etc. AWS Gateway expects a string, so the data should be converted accordingly.

```javascript
api.get('/users', function(req,res) {
api.get('/users', (req,res) => {
res.json({ message: 'This will be converted automatically' })

@@ -318,3 +277,3 @@ })

```javascript
api.get('/users', function(req,res) {
api.get('/users', (req,res) => {
res.html('<div>This is HTML</div>')

@@ -337,3 +296,3 @@ })

For a complete list of auto supported types, see [mimemap.js](mindmap.js). Custom MIME types can be added by using the `mimeTypes` option when instantiating Lambda API
For a complete list of auto supported types, see [mimemap.js](lib/mindmap.js). Custom MIME types can be added by using the `mimeTypes` option when instantiating Lambda API

@@ -344,7 +303,7 @@ ### location(path)

```javascript
api.get('/redirectToHome', function(req,res) {
api.get('/redirectToHome', (req,res) => {
res.location('/home').status(302).html('<div>Redirect to Home</div>')
})
api.get('/redirectToGithub', function(req,res) {
api.get('/redirectToGithub', (req,res) => {
res.location('https://github.com').status(302).html('<div>Redirect to GitHub</div>')

@@ -358,7 +317,7 @@ })

```javascript
api.get('/redirectToHome', function(req,res) {
api.get('/redirectToHome', (req,res) => {
res.redirect('/home')
})
api.get('/redirectToGithub', function(req,res) {
api.get('/redirectToGithub', (req,res) => {
res.redirect(301,'https://github.com')

@@ -368,2 +327,40 @@ })

### cors([options])
Convenience method for adding [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) headers to responses. An optional `options` object can be passed in to customize the defaults.
The six defined **CORS** headers are as follows:
- Access-Control-Allow-Origin (defaults to `*`)
- Access-Control-Allow-Methods (defaults to `GET, PUT, POST, DELETE, OPTIONS`)
- Access-Control-Allow-Headers (defaults to `Content-Type, Authorization, Content-Length, X-Requested-With`)
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Access-Control-Allow-Credentials
The `options` object can contain the following properties that correspond to the above headers:
- origin *(string)*
- methods *(string)*
- headers *(string)*
- exposeHeaders *(string)*
- maxAge *(number in milliseconds)*
- credentials *(boolean)*
Defaults can be set by calling `res.cors()` with no properties, or with any combination of the above options.
```javascript
res.cors({
origin: 'example.com',
methods: 'GET, POST, OPTIONS',
headers: 'Content-Type, Authorization',
maxAge: 84000000
})
```
You can override existing values by calling `res.cors()` with just the updated values:
```javascript
res.cors({
origin: 'api.example.com'
})
```
### error(message)

@@ -373,3 +370,3 @@ An error can be triggered by calling the `error` method. This will cause the API to stop execution and return the message to the client. Custom error handling can be accomplished using the [Error Handling](#error-handling) feature.

```javascript
api.get('/users', function(req,res) {
api.get('/users', (req,res) => {
res.error('This is an error')

@@ -468,3 +465,3 @@ })

The `callback` function supports promises, allowing you to perform additional tasks *after* the file is successfully loaded from the source. This can be used to perform additional synchronous tasks before returning control to the API execution.
The `callback` function supports returning a promise, allowing you to perform additional tasks *after* the file is successfully loaded from the source. This can be used to perform additional synchronous tasks before returning control to the API execution.

@@ -485,3 +482,3 @@ **NOTE:** In order to access S3 files, your Lambda function must have `GetObject` access to the files you're attempting to access.

```javascript
api.get('/users/:userId', function(req,res) {
api.get('/users/:userId', (req,res) => {
res.send('User ID: ' + req.params.userId)

@@ -496,8 +493,12 @@ })

## Wildcard Routes
Wildcard routes are supported for methods that match an existing route. E.g. `options` on an existing `get` route. As of now, the best use case is for the OPTIONS method to provide CORS headers. Wildcards only work in the base path. `/users/*`, for example, is not supported. For additional wildcard support, use [Path Parameters](#path-parameters) instead.
Wildcard routes are supported for methods that **match an existing route**. E.g. `options` on an existing `get` route. Wildcards only work at the *end of a route definition* such as `/*` or `/users/*`. Wildcards within a path, e.g. `/users/*/posts` are not supported. Wildcard routes do support parameters, so `/users/:id/*` would capture the `:id` parameter in your wildcard handler.
Wildcard routes will match deep paths if the route exists. For example, an `OPTIONS` method for path `/users/*` would match `/users/:id/posts/latest` if that path was defined by another method.
The best use case is for the `OPTIONS` method to provide CORS headers. For more control over variable paths, use [Path Parameters](#path-parameters) instead.
```javascript
api.options('/*', function(req,res) {
api.options('/users/*', (req,res) => {
// Do something
res.status(200).send({});
res.status(200).send({})
})

@@ -510,3 +511,3 @@ ```

```javascript
api.use(function(req,res,next) {
api.use((req,res,next) => {
// do something

@@ -521,3 +522,3 @@ next()

// Auth User
api.use(function(req,res,next) {
api.use((req,res,next) => {
if (req.headers.Authorization === 'some value') {

@@ -538,3 +539,3 @@ req.authorized = true

```javascript
api.finally(function(req,res) {
api.finally((req,res) => {
// close unneeded database connections and perform clean up

@@ -544,3 +545,3 @@ })

The `RESPONSE` **CANNOT** be manipulated since it has already been generated. Only one `finally()` method can be defined. This uses the Bluebird `finally()` method internally and will execute after properly handled errors as well.
The `RESPONSE` **CANNOT** be manipulated since it has already been generated. Only one `finally()` method can be defined and will execute after properly handled errors as well.

@@ -551,3 +552,3 @@ ## Error Handling

```javascript
api.use(function(err,req,res,next) {
api.use((err,req,res,next) => {
// do something with the error

@@ -576,6 +577,6 @@ next()

```javascript
module.exports = function(req, res) {
module.exports = (req, res) => {
let userInfo = req.namespace.data.getUser(req.params.userId)
res.json({ 'userInfo': userInfo })
});
}
```

@@ -596,7 +597,2 @@

## Promises
The API uses Bluebird promises to manage asynchronous script execution. The API will wait for a request ending call before returning data back to the client. Middleware will wait for the `next()` callback before proceeding to the next step.
**NOTE:** AWS Lambda currently only supports Node v6.10, which doesn't support `async / await`. If you'd like to use `async / await`, you'll need to polyfill.
## CORS Support

@@ -606,3 +602,3 @@ CORS can be implemented using the [wildcard routes](#wildcard-routes) feature. A typical implementation would be as follows:

```javascript
api.options('/*', function(req,res) {
api.options('/*', (req,res) => {
// Add CORS headers

@@ -616,4 +612,70 @@ res.header('Access-Control-Allow-Origin', '*');

You can also use the `cors()` ([see here](#corsoptions)) convenience method to add CORS headers.
Conditional route support could be added via middleware or with conditional logic within the `OPTIONS` route.
## Lambda Proxy Integration
Lambda Proxy Integration is an option in API Gateway that allows the details of an API request to be passed as the `event` parameter of a Lambda function. A typical API Gateway request event with Lambda Proxy Integration enabled looks like this:
```javascript
{
"resource": "/v1/posts",
"path": "/v1/posts",
"httpMethod": "GET",
"headers": {
"Authorization": "Bearer ...",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-us",
"cache-control": "max-age=0",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Cookie": "...",
"Host": "...",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) ...",
"Via": "2.0 ... (CloudFront)",
"X-Amz-Cf-Id": "...",
"X-Amzn-Trace-Id": "...",
"X-Forwarded-For": "xxx.xxx.xxx.xxx",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"queryStringParameters": {
"qs1": "q1"
},
"stageVariables": null,
"requestContext": {
"accountId": "...",
"resourceId": "...",
"stage": "prod",
"requestId": "...",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"apiKey": null,
"sourceIp": "xxx.xxx.xxx.xxx",
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "...",
"user": null
},
"resourcePath": "/v1/posts",
"httpMethod": "GET",
"apiId": "..."
},
"body": null,
"isBase64Encoded": false
}
```
The API automatically parses this information to create a normalized `REQUEST` object. The request can then be routed using the APIs methods.
## Configuring Routes in API Gateway

@@ -620,0 +682,0 @@ Routes must be configured in API Gateway in order to support routing to the Lambda function. The easiest way to support all of your routes without recreating them is to use [API Gateway's Proxy Integration](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-proxy-resource?icmpid=docs_apigateway_console).

'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library

@@ -60,72 +59,44 @@

it('Simple attachment', function() {
it('Simple attachment', async function() {
let _event = Object.assign({},event,{ path: '/attachment' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Disposition': 'attachment', 'Content-Type': 'application/json' }, statusCode: 200, body: '{"status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-disposition': 'attachment', 'content-type': 'application/json' }, statusCode: 200, body: '{"status":"ok"}', isBase64Encoded: false })
}) // end it
it('PDF attachment w/ path', function() {
it('PDF attachment w/ path', async function() {
let _event = Object.assign({},event,{ path: '/attachment/pdf' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Disposition': 'attachment; filename=\"foo.pdf\"', 'Content-Type': 'application/pdf' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-disposition': 'attachment; filename=\"foo.pdf\"', 'content-type': 'application/pdf' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
}) // end it
it('PNG attachment w/ path', function() {
it('PNG attachment w/ path', async function() {
let _event = Object.assign({},event,{ path: '/attachment/png' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Disposition': 'attachment; filename=\"foo.png\"', 'Content-Type': 'image/png' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-disposition': 'attachment; filename=\"foo.png\"', 'content-type': 'image/png' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
}) // end it
it('CSV attachment w/ path', function() {
it('CSV attachment w/ path', async function() {
let _event = Object.assign({},event,{ path: '/attachment/csv' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Disposition': 'attachment; filename=\"foo.csv\"', 'Content-Type': 'text/csv' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-disposition': 'attachment; filename=\"foo.csv\"', 'content-type': 'text/csv' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
}) // end it
it('Custom MIME type attachment w/ path', function() {
it('Custom MIME type attachment w/ path', async function() {
let _event = Object.assign({},event,{ path: '/attachment/custom' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Disposition': 'attachment; filename=\"foo.test\"', 'Content-Type': 'text/test' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-disposition': 'attachment; filename=\"foo.test\"', 'content-type': 'text/test' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
}) // end it
it('Empty string', function() {
it('Empty string', async function() {
let _event = Object.assign({},event,{ path: '/attachment/empty-string' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Disposition': 'attachment', 'Content-Type': 'application/json' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-disposition': 'attachment', 'content-type': 'application/json' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
}) // end it
it('Null string', function() {
it('Null string', async function() {
let _event = Object.assign({},event,{ path: '/attachment/empty-string' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Disposition': 'attachment', 'Content-Type': 'application/json' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-disposition': 'attachment', 'content-type': 'application/json' }, statusCode: 200, body: 'filedata', isBase64Encoded: false })
}) // end it
}) // end HEADER tests
'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library

@@ -44,33 +43,20 @@

it('Simple path with base: /v1/test', function() {
it('Simple path with base: /v1/test', async function() {
let _event = Object.assign({},event,{ path: '/v1/test' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
}) // end it
it('Path with base and parameter: /v1/test/123', function() {
it('Path with base and parameter: /v1/test/123', async function() {
let _event = Object.assign({},event,{ path: '/v1/test/123' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123"}', isBase64Encoded: false })
}) // end it
it('Nested path with base: /v1/test/test2/test3', function() {
it('Nested path with base: /v1/test/test2/test3', async function() {
let _event = Object.assign({},event,{ path: '/v1/test/test2/test3' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(JSON.stringify(JSON.parse(result.body),null,2));
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/v1/test/test2/test3","method":"get","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/v1/test/test2/test3","method":"get","status":"ok"}', isBase64Encoded: false })
}) // end it
}) // end BASEPATH tests
'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library

@@ -17,3 +16,3 @@

headers: {
'Content-Type': 'application/json'
'content-type': 'application/json'
}

@@ -125,29 +124,21 @@ }

describe("Set", function() {
it('Basic Session Cookie', function() {
it('Basic Session Cookie', async function() {
let _event = Object.assign({},event,{ path: '/cookie' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Basic Session Cookie (encoded value)', function() {
it('Basic Session Cookie (encoded value)', async function() {
let _event = Object.assign({},event,{ path: '/cookieEncoded' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=http%3A%2F%2F%20%5B%5D%20foo%3Bbar; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=http%3A%2F%2F%20%5B%5D%20foo%3Bbar; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})

@@ -157,14 +148,10 @@ }) // end it

it('Basic Session Cookie (object value)', function() {
it('Basic Session Cookie (object value)', async function() {
let _event = Object.assign({},event,{ path: '/cookieObject' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=%7B%22foo%22%3A%22bar%22%7D; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=%7B%22foo%22%3A%22bar%22%7D; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})

@@ -174,14 +161,10 @@ }) // end it

it('Basic Session Cookie (non-string name)', function() {
it('Basic Session Cookie (non-string name)', async function() {
let _event = Object.assign({},event,{ path: '/cookieNonString' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': '123=value; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': '123=value; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})

@@ -191,134 +174,98 @@ }) // end it

it('Permanent Cookie (set expires)', function() {
it('Permanent Cookie (set expires)', async function() {
let _event = Object.assign({},event,{ path: '/cookieExpire' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Permanent Cookie (set maxAge)', function() {
it('Permanent Cookie (set maxAge)', async function() {
let _event = Object.assign({},event,{ path: '/cookieMaxAge' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; MaxAge=3600; Expires='+ new Date(Date.now()+3600000).toUTCString() + '; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; MaxAge=3600; Expires='+ new Date(Date.now()+3600000).toUTCString() + '; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Permanent Cookie (set domain)', function() {
it('Permanent Cookie (set domain)', async function() {
let _event = Object.assign({},event,{ path: '/cookieDomain' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Permanent Cookie (set httpOnly)', function() {
it('Permanent Cookie (set httpOnly)', async function() {
let _event = Object.assign({},event,{ path: '/cookieHttpOnly' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; HttpOnly; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; HttpOnly; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Permanent Cookie (set secure)', function() {
it('Permanent Cookie (set secure)', async function() {
let _event = Object.assign({},event,{ path: '/cookieSecure' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/; Secure'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/; Secure'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Permanent Cookie (set path)', function() {
it('Permanent Cookie (set path)', async function() {
let _event = Object.assign({},event,{ path: '/cookiePath' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/test; Secure'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/test; Secure'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Permanent Cookie (set sameSite - true)', function() {
it('Permanent Cookie (set sameSite - true)', async function() {
let _event = Object.assign({},event,{ path: '/cookieSameSiteTrue' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/; SameSite=Strict'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/; SameSite=Strict'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Permanent Cookie (set sameSite - false)', function() {
it('Permanent Cookie (set sameSite - false)', async function() {
let _event = Object.assign({},event,{ path: '/cookieSameSiteFalse' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/; SameSite=Lax'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/; SameSite=Lax'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Permanent Cookie (set sameSite - string)', function() {
it('Permanent Cookie (set sameSite - string)', async function() {
let _event = Object.assign({},event,{ path: '/cookieSameSiteString' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/; SameSite=Test'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=value; Domain=test.com; Expires=Tue, 01 Jan 2019 00:00:00 GMT; Path=/; SameSite=Test'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})

@@ -332,3 +279,3 @@ }) // end it

it('Parse single cookie', function() {
it('Parse single cookie', async function() {
let _event = Object.assign({},event,{

@@ -340,15 +287,11 @@ path: '/cookieParse',

})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
}, statusCode: 200, body: '{"cookies":{"test":"some value"}}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
}, statusCode: 200, body: '{"cookies":{"test":"some value"}}', isBase64Encoded: false
})
}) // end it
it('Parse & decode two cookies', function() {
it('Parse & decode two cookies', async function() {
let _event = Object.assign({},event,{

@@ -360,11 +303,7 @@ path: '/cookieParse',

})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
}, statusCode: 200, body: '{\"cookies\":{\"test\":\"some value\",\"test2\":{\"foo\":\"bar\"}}}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
}, statusCode: 200, body: '{\"cookies\":{\"test\":\"some value\",\"test2\":{\"foo\":\"bar\"}}}', isBase64Encoded: false
})

@@ -374,3 +313,3 @@ }) // end it

it('Parse & decode multiple cookies', function() {
it('Parse & decode multiple cookies', async function() {
let _event = Object.assign({},event,{

@@ -382,11 +321,7 @@ path: '/cookieParse',

})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
}, statusCode: 200, body: '{\"cookies\":{\"test\":\"some value\",\"test2\":{\"foo\":\"bar\"},\"test3\":\"domain\"}}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
}, statusCode: 200, body: '{\"cookies\":{\"test\":\"some value\",\"test2\":{\"foo\":\"bar\"},\"test3\":\"domain\"}}', isBase64Encoded: false
})

@@ -397,35 +332,27 @@ }) // end it

describe("Clear", function() {
describe("Clear", async function() {
it('Clear cookie (no options)', function() {
it('Clear cookie (no options)', async function() {
let _event = Object.assign({},event,{
path: '/cookieClear'
})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; MaxAge=-1; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; MaxAge=-1; Path=/'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
}) // end it
it('Clear cookie (w/ options)', function() {
it('Clear cookie (w/ options)', async function() {
let _event = Object.assign({},event,{
path: '/cookieClearOptions'
})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Set-Cookie': 'test=; Domain=test.com; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; MaxAge=-1; Path=/; Secure'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'set-cookie': 'test=; Domain=test.com; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; MaxAge=-1; Path=/; Secure'
}, statusCode: 200, body: '{}', isBase64Encoded: false
})

@@ -432,0 +359,0 @@ }) // end it

@@ -12,3 +12,3 @@ 'use strict';

const AWS = require('aws-sdk') // AWS SDK (automatically available in Lambda)
const S3 = require('../s3-service') // Init S3 Service
const S3 = require('../lib/s3-service') // Init S3 Service

@@ -26,3 +26,3 @@ // Init API instance

headers: {
'Content-Type': 'application/json'
'content-type': 'application/json'
}

@@ -95,10 +95,12 @@ }

stub.withArgs({Bucket: 'my-test-bucket', Key: 'test.txt'}).resolves({
AcceptRanges: 'bytes',
LastModified: new Date('2018-04-01T13:32:58.000Z'),
ContentLength: 23,
ETag: '"ae771fbbba6a74eeeb77754355831713"',
ContentType: 'text/plain',
Metadata: {},
Body: Buffer.from('Test file for sendFile\n')
stub.withArgs({Bucket: 'my-test-bucket', Key: 'test.txt'}).returns({
promise: () => { return {
AcceptRanges: 'bytes',
LastModified: new Date('2018-04-01T13:32:58.000Z'),
ContentLength: 23,
ETag: '"ae771fbbba6a74eeeb77754355831713"',
ContentType: 'text/plain',
Metadata: {},
Body: Buffer.from('Test file for sendFile\n')
}}
})

@@ -111,10 +113,12 @@

stub.withArgs({Bucket: 'my-test-bucket', Key: 'test/test.txt'}).resolves({
AcceptRanges: 'bytes',
LastModified: new Date('2018-04-01T13:32:58.000Z'),
ContentLength: 23,
ETag: '"ae771fbbba6a74eeeb77754355831713"',
ContentType: 'text/plain',
Metadata: {},
Body: Buffer.from('Test file for sendFile\n')
stub.withArgs({Bucket: 'my-test-bucket', Key: 'test/test.txt'}).returns({
promise: () => { return {
AcceptRanges: 'bytes',
LastModified: new Date('2018-04-01T13:32:58.000Z'),
ContentLength: 23,
ETag: '"ae771fbbba6a74eeeb77754355831713"',
ContentType: 'text/plain',
Metadata: {},
Body: Buffer.from('Test file for sendFile\n')
}}
})

@@ -150,102 +154,69 @@

// Stub getObjectAsync
stub = sinon.stub(S3,'getObjectAsync')
stub = sinon.stub(S3,'getObject')
})
it('Bad path', function() {
it('Bad path', async function() {
let _event = Object.assign({},event,{ path: '/download/badpath' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json', 'x-error': 'true' }, statusCode: 500, body: '{"error":"Invalid file"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json', 'x-error': 'true' }, statusCode: 500, body: '{"error":"Invalid file"}', isBase64Encoded: false })
}) // end it
it('Missing file', function() {
it('Missing file', async function() {
let _event = Object.assign({},event,{ path: '/download' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json', 'x-error': 'true' }, statusCode: 500, body: '{"error":"ENOENT: no such file or directory, open \'./test-missing.txt\'"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json', 'x-error': 'true' }, statusCode: 500, body: '{"error":"ENOENT: no such file or directory, open \'./test-missing.txt\'"}', isBase64Encoded: false })
}) // end it
it('Missing file with custom catch', function() {
it('Missing file with custom catch', async function() {
let _event = Object.assign({},event,{ path: '/download/err' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json', 'x-error': 'true' }, statusCode: 404, body: '{"error":"There was an error accessing the requested file"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json', 'x-error': 'true' }, statusCode: 404, body: '{"error":"There was an error accessing the requested file"}', isBase64Encoded: false })
}) // end it
it('Text file w/ callback override (promise)', function() {
it('Text file w/ callback override (promise)', async function() {
let _event = Object.assign({},event,{ path: '/download/test' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=0',
'Expires': result.headers.Expires,
'Last-Modified': result.headers['Last-Modified'],
'Content-Disposition': 'attachment; filename="test.txt"'
},
statusCode: 201, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'max-age=0',
'expires': result.headers.expires,
'last-modified': result.headers['last-modified'],
'content-disposition': 'attachment; filename="test.txt"'
},
statusCode: 201, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('Text file error w/ callback override (promise)', function() {
it('Text file error w/ callback override (promise)', async function() {
let _event = Object.assign({},event,{ path: '/download/test', queryStringParameters: { test: 'x' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json', 'x-error': 'true' }, statusCode: 501, body: '{"error":"Custom File Error"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json', 'x-error': 'true' }, statusCode: 501, body: '{"error":"Custom File Error"}', isBase64Encoded: false })
}) // end it
it('Buffer Input (no filename)', function() {
it('Buffer Input (no filename)', async function() {
let _event = Object.assign({},event,{ path: '/download/buffer' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'max-age=0',
'Expires': result.headers.Expires,
'Last-Modified': result.headers['Last-Modified'],
'Content-Disposition': 'attachment'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'cache-control': 'max-age=0',
'expires': result.headers.expires,
'last-modified': result.headers['last-modified'],
'content-disposition': 'attachment'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('Buffer Input (w/ filename)', function() {
it('Buffer Input (w/ filename)', async function() {
let _event = Object.assign({},event,{ path: '/download/buffer', queryStringParameters: { filename: 'test.txt' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=0',
'Expires': result.headers.Expires,
'Last-Modified': result.headers['Last-Modified'],
'Content-Disposition': 'attachment; filename="test.txt"'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'max-age=0',
'expires': result.headers.expires,
'last-modified': result.headers['last-modified'],
'content-disposition': 'attachment; filename="test.txt"'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})

@@ -255,18 +226,15 @@ }) // end it

it('Text file w/ headers', function() {
it('Text file w/ headers', async function() {
let _event = Object.assign({},event,{ path: '/download/headers' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'x-test': 'test',
'x-timestamp': 1,
'Cache-Control': 'max-age=0',
'Expires': result.headers.Expires,
'Last-Modified': result.headers['Last-Modified'],
'Content-Disposition': 'attachment; filename="test.txt"'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'x-test': 'test',
'x-timestamp': 1,
'cache-control': 'max-age=0',
'expires': result.headers.expires,
'last-modified': result.headers['last-modified'],
'content-disposition': 'attachment; filename="test.txt"'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})

@@ -276,17 +244,14 @@ }) // end it

it('Text file w/ filename, options, and callback', function() {
it('Text file w/ filename, options, and callback', async function() {
let _event = Object.assign({},event,{ path: '/download/all' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'x-callback': 'true',
'Cache-Control': 'private, max-age=3600',
'Expires': result.headers.Expires,
'Last-Modified': result.headers['Last-Modified'],
'Content-Disposition': 'attachment; filename="test-file.txt"'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'x-callback': 'true',
'cache-control': 'private, max-age=3600',
'expires': result.headers.expires,
'last-modified': result.headers['last-modified'],
'content-disposition': 'attachment; filename="test-file.txt"'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})

@@ -296,49 +261,40 @@ }) // end it

it('S3 file', function() {
it('S3 file', async function() {
let _event = Object.assign({},event,{ path: '/download/s3' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=0',
'Content-Disposition': 'attachment; filename="test.txt"',
'Expires': result.headers['Expires'],
'ETag': '"ae771fbbba6a74eeeb77754355831713"',
'Last-Modified': result.headers['Last-Modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'max-age=0',
'content-disposition': 'attachment; filename="test.txt"',
'expires': result.headers['expires'],
'etag': '"ae771fbbba6a74eeeb77754355831713"',
'last-modified': result.headers['last-modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('S3 file w/ nested path', function() {
it('S3 file w/ nested path', async function() {
let _event = Object.assign({},event,{ path: '/download/s3path' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=0',
'Content-Disposition': 'attachment; filename="test.txt"',
'Expires': result.headers['Expires'],
'ETag': '"ae771fbbba6a74eeeb77754355831713"',
'Last-Modified': result.headers['Last-Modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'max-age=0',
'content-disposition': 'attachment; filename="test.txt"',
'expires': result.headers['expires'],
'etag': '"ae771fbbba6a74eeeb77754355831713"',
'last-modified': result.headers['last-modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('S3 file error', function() {
it('S3 file error', async function() {
let _event = Object.assign({},event,{ path: '/download/s3missing' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'x-error': 'true'
}, statusCode: 500, body: '{"error":"NoSuchKey: The specified key does not exist."}', isBase64Encoded: false })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'x-error': 'true'
}, statusCode: 500, body: '{"error":"NoSuchKey: The specified key does not exist."}', isBase64Encoded: false
})

@@ -345,0 +301,0 @@ }) // end it

@@ -97,52 +97,32 @@ 'use strict';

it('Called Error', function() {
it('Called Error', async function() {
let _event = Object.assign({},event,{ path: '/testError'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 500, body: '{"error":"This is a test error message"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 500, body: '{"error":"This is a test error message"}', isBase64Encoded: false })
}) // end it
it('Thrown Error', function() {
it('Thrown Error', async function() {
let _event = Object.assign({},event,{ path: '/testErrorThrow'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 500, body: '{"error":"This is a test thrown error"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 500, body: '{"error":"This is a test thrown error"}', isBase64Encoded: false })
}) // end it
it('Simulated Error', function() {
it('Simulated Error', async function() {
let _event = Object.assign({},event,{ path: '/testErrorSimulated'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 405, body: '{"error":"This is a simulated error"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 405, body: '{"error":"This is a simulated error"}', isBase64Encoded: false })
}) // end it
it('Error Middleware', function() {
it('Error Middleware', async function() {
let _event = Object.assign({},event,{ path: '/testErrorMiddleware'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'text/plain' }, statusCode: 500, body: 'This is a test error message: 123/456', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'text/plain' }, statusCode: 500, body: 'This is a test error message: 123/456', isBase64Encoded: false })
}) // end it
it('Error Middleware w/ Promise', function() {
it('Error Middleware w/ Promise', async function() {
let _event = Object.assign({},event,{ path: '/testErrorPromise'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'text/plain' }, statusCode: 500, body: 'This is a test error message: 123/456', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'text/plain' }, statusCode: 500, body: 'This is a test error message: 123/456', isBase64Encoded: false })
}) // end it
}) // end ERROR HANDLING tests
'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library

@@ -31,3 +30,3 @@

status: 'ok',
connected: fakeDatabase.connected
connected: fakeDatabase.connected.toString()
})

@@ -49,23 +48,14 @@ })

it('Connected on first execution and after callback', function() {
it('Connected on first execution and after callback', async function() {
let _event = Object.assign({},event,{})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","connected":true}', isBase64Encoded: false })
expect(fakeDatabase).to.deep.equal({ connected: true })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","connected":"true"}', isBase64Encoded: false })
}) // end it
it('Disconnected on second execution', function() {
it('Disconnected on second execution', async function() {
let _event = Object.assign({},event,{})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","connected":false}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","connected":"false"}', isBase64Encoded: false })
}) // end it
}) // end FINALLY tests
'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library

@@ -42,3 +41,54 @@

api.get('/getHeader', function(req,res) {
res.status(200).header('TestHeader','test')
res.json({
headers: res.getHeader(),
getHeader: res.getHeader('testheader'),
getHeaderCase: res.getHeader('coNtEnt-TyPe'),
getHeaderMissing: res.getHeader('test') ? false : true,
getHeaderEmpty: res.getHeader() ? false : true
})
})
api.get('/hasHeader', function(req,res) {
res.status(200).header('TestHeader','test')
res.json({
hasHeader: res.hasHeader('testheader'),
hasHeaderCase: res.hasHeader('coNtEnt-TyPe'),
hasHeaderMissing: res.hasHeader('test'),
hasHeaderEmpty: res.hasHeader() ? false : true
})
})
api.get('/removeHeader', function(req,res) {
res.status(200).header('TestHeader','test').header('NewHeader','test').removeHeader('testHeader')
res.json({
removeHeader: res.hasHeader('testheader') ? false : true,
hasHeader: res.hasHeader('NewHeader')
})
})
api.get('/cors', function(req,res) {
res.cors().json({})
})
api.get('/corsCustom', function(req,res) {
res.cors({
origin: 'example.com',
methods: 'GET, OPTIONS',
headers: 'Content-Type, Authorization',
maxAge: 84000000,
credentials: true,
exposeHeaders: 'Content-Type'
}).json({})
})
api.get('/corsOverride', function(req,res) {
res.cors().cors({
origin: 'example.com',
credentials: true
}).json({})
})
/******************************************************************************/

@@ -50,32 +100,115 @@ /*** BEGIN TESTS ***/

it('New Header: /test -- test: testVal', function() {
let _event = Object.assign({},event,{})
describe('Standard Tests:', function() {
it('New Header: /test -- test: testVal', async function() {
let _event = Object.assign({},event,{})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json', 'test': 'testVal' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
}) // end it
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json', 'test': 'testVal' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
})
}) // end it
it('Override Header: /testOveride -- Content-Type: text/html', async function() {
let _event = Object.assign({},event,{ path: '/testOverride'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'text/html' }, statusCode: 200, body: '<div>testHTML</div>', isBase64Encoded: false })
}) // end it
it('Override Header: /testOveride -- Content-Type: text/html', function() {
let _event = Object.assign({},event,{ path: '/testOverride'})
it('HTML Convenience Method: /testHTML', async function() {
let _event = Object.assign({},event,{ path: '/testHTML'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'text/html' }, statusCode: 200, body: '<div>testHTML</div>', isBase64Encoded: false })
}) // end it
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'text/html' }, statusCode: 200, body: '<div>testHTML</div>', isBase64Encoded: false })
})
}) // end it
it('HTML Convenience Method: /testHTML', function() {
let _event = Object.assign({},event,{ path: '/testHTML'})
it('Get Header', async function() {
let _event = Object.assign({},event,{ path: '/getHeader'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'testheader': 'test'
}, statusCode: 200,
body: '{"headers":{"content-type":"application/json","testheader":"test"},"getHeader":"test","getHeaderCase":"application/json","getHeaderMissing":true,"getHeaderEmpty":false}',
isBase64Encoded: false
})
}) // end it
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'text/html' }, statusCode: 200, body: '<div>testHTML</div>', isBase64Encoded: false })
})
}) // end it
it('Has Header', async function() {
let _event = Object.assign({},event,{ path: '/hasHeader'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'testheader': 'test'
}, statusCode: 200,
body: '{"hasHeader":true,"hasHeaderCase":true,"hasHeaderMissing":false,"hasHeaderEmpty":false}',
isBase64Encoded: false
})
}) // end it
it('Remove Header', async function() {
let _event = Object.assign({},event,{ path: '/removeHeader'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'newheader': 'test'
}, statusCode: 200,
body: '{"removeHeader":true,"hasHeader":true}',
isBase64Encoded: false
})
}) // end it
}) // end Standard tests
describe('CORS Tests:', function() {
it('Add Default CORS Headers', async function() {
let _event = Object.assign({},event,{ path: '/cors'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'access-control-allow-headers': 'Content-Type, Authorization, Content-Length, X-Requested-With',
'access-control-allow-methods': 'GET, PUT, POST, DELETE, OPTIONS',
'access-control-allow-origin': '*'
}, statusCode: 200,
body: '{}',
isBase64Encoded: false
})
}) // end it
it('Add Custom CORS Headers', async function() {
let _event = Object.assign({},event,{ path: '/corsCustom'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'access-control-allow-headers': 'Content-Type, Authorization',
'access-control-allow-methods': 'GET, OPTIONS',
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'Content-Type',
'access-control-max-age': '84000'
}, statusCode: 200,
body: '{}',
isBase64Encoded: false
})
}) // end it
it('Override CORS Headers', async function() {
let _event = Object.assign({},event,{ path: '/corsOverride'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'access-control-allow-headers': 'Content-Type, Authorization, Content-Length, X-Requested-With',
'access-control-allow-methods': 'GET, PUT, POST, DELETE, OPTIONS',
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true'
}, statusCode: 200,
body: '{}',
isBase64Encoded: false
})
}) // end it
}) // end CORS tests
}) // end HEADER tests

@@ -44,6 +44,6 @@ 'use strict';

Promise.try(() => {
for(let i = 0; i<40000000; i++) {}
for(let i = 0; i<100000000; i++) {}
return true
}).then((x) => {
//console.log('Time:',Date.now()-start);
// console.log('Time:',Date.now()-start);
req.testMiddlewarePromise = 'test'

@@ -82,33 +82,21 @@ next()

it('Set Values in res object', function() {
it('Set Values in res object', async function() {
let _event = Object.assign({},event,{})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","testMiddleware":"123","testMiddleware2":"456"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","testMiddleware":"123","testMiddleware2":"456"}', isBase64Encoded: false })
}) // end it
it('Access params, querystring, and body values', function() {
it('Access params, querystring, and body values', async function() {
let _event = Object.assign({},event,{ httpMethod: 'post', path: '/test/123', queryStringParameters: { test: "456" }, body: { test: "789" } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","testMiddleware3":"123","testMiddleware4":"456","testMiddleware5":"789"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","testMiddleware3":"123","testMiddleware4":"456","testMiddleware5":"789"}', isBase64Encoded: false })
}) // end it
it('Middleware with Promise/Delay', function() {
it('Middleware with Promise/Delay', async function() {
let _event = Object.assign({},event,{ path: '/testPromise'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","testMiddlewarePromise":"test"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","testMiddlewarePromise":"test"}', isBase64Encoded: false })
}) // end it
}) // end MIDDLEWARE tests

@@ -52,42 +52,26 @@ 'use strict';

it('Standard module response', function() {
it('Standard module response', async function() {
let _event = Object.assign({},event,{ path:'/testApp' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","app":"app1"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","app":"app1"}', isBase64Encoded: false })
}) // end it
it('Module with promise', function() {
it('Module with promise', async function() {
let _event = Object.assign({},event,{ path:'/testAppPromise' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","app":"app2"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","app":"app2"}', isBase64Encoded: false })
}) // end it
it('Module with called error', function() {
it('Module with called error', async function() {
let _event = Object.assign({},event,{ path:'/testAppError' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 500, body: '{"error":"This is a called module error"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 500, body: '{"error":"This is a called module error"}', isBase64Encoded: false })
}) // end it
it('Module with thrown error', function() {
it('Module with thrown error', async function() {
let _event = Object.assign({},event,{ path:'/testAppThrownError' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 500, body: '{"error":"This is a thrown module error"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 500, body: '{"error":"This is a thrown module error"}', isBase64Encoded: false })
}) // end it
}) // end MODULE tests
'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library

@@ -60,24 +59,14 @@

it('Invoke namespace', function() {
it('Invoke namespace', async function() {
let _event = Object.assign({},event,{ path:'/testData' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log("RESULTS:",result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","data":{"foo":"sample data","bar":"additional sample data"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","data":{"foo":"sample data","bar":"additional sample data"}}', isBase64Encoded: false })
}) // end it
it('Invoke namespace via required module', function() {
it('Invoke namespace via required module', async function() {
let _event = Object.assign({},event,{ path:'/testAppData' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log("RESULTS:",result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","data":{"foo":"sample data","bar":"additional sample data"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","data":{"foo":"sample data","bar":"additional sample data"}}', isBase64Encoded: false })
}) // end it
}) // end MODULE tests
'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library

@@ -36,165 +35,99 @@

it('No prefix', function() {
it('No prefix', async function() {
let _event = Object.assign({},event,{ path: '/test-register' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
}) // end it
it('No prefix (nested)', function() {
it('No prefix (nested)', async function() {
let _event = Object.assign({},event,{ path: '/test-register/sub1' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
}) // end it
it('No prefix (nested w/ param)', function() {
it('No prefix (nested w/ param)', async function() {
let _event = Object.assign({},event,{ path: '/test-register/TEST/test' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
}) // end it
it('With prefix', function() {
it('With prefix', async function() {
let _event = Object.assign({},event,{ path: '/v1/test-register' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/v1/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/v1/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
}) // end it
it('With prefix (nested)', function() {
it('With prefix (nested)', async function() {
let _event = Object.assign({},event,{ path: '/v1/test-register/sub1' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/v1/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/v1/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
}) // end it
it('With prefix (nested w/ param)', function() {
it('With prefix (nested w/ param)', async function() {
let _event = Object.assign({},event,{ path: '/v1/test-register/TEST/test' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/v1/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/v1/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
}) // end it
it('With double prefix', function() {
it('With double prefix', async function() {
let _event = Object.assign({},event,{ path: '/vX/vY/test-register' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
}) // end it
it('With double prefix (nested)', function() {
it('With double prefix (nested)', async function() {
let _event = Object.assign({},event,{ path: '/vX/vY/test-register/sub1' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
}) // end it
it('With double prefix (nested w/ param)', function() {
it('With double prefix (nested w/ param)', async function() {
let _event = Object.assign({},event,{ path: '/vX/vY/test-register/TEST/test' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
}) // end it
it('With recursive prefix', function() {
it('With recursive prefix', async function() {
let _event = Object.assign({},event,{ path: '/vX/vY/vZ/test-register' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/vZ/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/vZ/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
}) // end it
it('With recursive prefix (nested)', function() {
it('With recursive prefix (nested)', async function() {
let _event = Object.assign({},event,{ path: '/vX/vY/vZ/test-register/sub1' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/vZ/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/vZ/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
}) // end it
it('With recursive prefix (nested w/ param)', function() {
it('With recursive prefix (nested w/ param)', async function() {
let _event = Object.assign({},event,{ path: '/vX/vY/vZ/test-register/TEST/test' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/vZ/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/vZ/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
}) // end it
it('After recursive interation', function() {
it('After recursive interation', async function() {
let _event = Object.assign({},event,{ path: '/vX/vY/test-register/sub2' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/test-register/sub2","route":"/test-register/sub2","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/vX/vY/test-register/sub2","route":"/test-register/sub2","method":"GET"}', isBase64Encoded: false })
}) // end it
it('New prefix', function() {
it('New prefix', async function() {
let _event = Object.assign({},event,{ path: '/v2/test-register' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/v2/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/v2/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false })
}) // end it
it('New prefix (nested)', function() {
it('New prefix (nested)', async function() {
let _event = Object.assign({},event,{ path: '/v2/test-register/sub1' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/v2/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/v2/test-register/sub1","route":"/test-register/sub1","method":"GET"}', isBase64Encoded: false })
}) // end it
it('New prefix (nested w/ param)', function() {
it('New prefix (nested w/ param)', async function() {
let _event = Object.assign({},event,{ path: '/v2/test-register/TEST/test' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"path":"/v2/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"path":"/v2/test-register/TEST/test","route":"/test-register/:param1/test","method":"GET","params":{"param1":"TEST"}}', isBase64Encoded: false })
}) // end it
}) // end ROUTE tests
'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library

@@ -73,2 +72,6 @@

api.get('/redirect310', function(req,res) {
res.redirect(310,'http://www.github.com')
})
api.get('/redirectHTML', function(req,res) {

@@ -84,143 +87,92 @@ res.redirect('http://www.github.com?foo=bar&bat=baz<script>alert(\'not good\')</script>')

it('Object response: convert to string', function() {
it('Object response: convert to string', async function() {
let _event = Object.assign({},event,{ path: '/testObjectResponse'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"object":true}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"object":true}', isBase64Encoded: false })
}) // end it
it('Numeric response: convert to string', function() {
it('Numeric response: convert to string', async function() {
let _event = Object.assign({},event,{ path: '/testNumberResponse'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '123', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '123', isBase64Encoded: false })
}) // end it
it('Array response: convert to string', function() {
it('Array response: convert to string', async function() {
let _event = Object.assign({},event,{ path: '/testArrayResponse'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '[1,2,3]', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '[1,2,3]', isBase64Encoded: false })
}) // end it
it('String response: no conversion', function() {
it('String response: no conversion', async function() {
let _event = Object.assign({},event,{ path: '/testStringResponse'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: 'this is a string', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: 'this is a string', isBase64Encoded: false })
}) // end it
it('Empty response', function() {
it('Empty response', async function() {
let _event = Object.assign({},event,{ path: '/testEmptyResponse'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '', isBase64Encoded: false })
}) // end it
it('JSONP response (default callback)', function() {
it('JSONP response (default callback)', async function() {
let _event = Object.assign({},event,{ path: '/testJSONPResponse' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: 'callback({"foo":"bar"})', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: 'callback({"foo":"bar"})', isBase64Encoded: false })
}) // end it
it('JSONP response (using callback URL param)', function() {
it('JSONP response (using callback URL param)', async function() {
let _event = Object.assign({},event,{ path: '/testJSONPResponse', queryStringParameters: { callback: 'foo' }})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: 'foo({"foo":"bar"})', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: 'foo({"foo":"bar"})', isBase64Encoded: false })
}) // end it
it('JSONP response (using cb URL param)', function() {
it('JSONP response (using cb URL param)', async function() {
let _event = Object.assign({},event,{ path: '/testJSONPResponse', queryStringParameters: { cb: 'bar' }})
return new Promise((resolve,reject) => {
api2.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: 'bar({"foo":"bar"})', isBase64Encoded: false })
})
let result = await new Promise(r => api2.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: 'bar({"foo":"bar"})', isBase64Encoded: false })
}) // end it
it('JSONP response (using URL param with spaces)', function() {
it('JSONP response (using URL param with spaces)', async function() {
let _event = Object.assign({},event,{ path: '/testJSONPResponse', queryStringParameters: { callback: 'foo bar'}})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: 'foo_bar({"foo":"bar"})', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: 'foo_bar({"foo":"bar"})', isBase64Encoded: false })
}) // end it
it('Location method', function() {
it('Location method', async function() {
let _event = Object.assign({},event,{ path: '/location'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'text/html', 'Location': 'http://www.github.com' }, statusCode: 200, body: 'Location header set', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'text/html', 'location': 'http://www.github.com' }, statusCode: 200, body: 'Location header set', isBase64Encoded: false })
}) // end it
it('Location method (encode URL)', function() {
it('Location method (encode URL)', async function() {
let _event = Object.assign({},event,{ path: '/locationEncode'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'text/html', 'Location': 'http://www.github.com?foo=bar%20with%20space' }, statusCode: 200, body: 'Location header set', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'text/html', 'location': 'http://www.github.com?foo=bar%20with%20space' }, statusCode: 200, body: 'Location header set', isBase64Encoded: false })
}) // end it
it('Redirect (default 302)', function() {
it('Redirect (default 302)', async function() {
let _event = Object.assign({},event,{ path: '/redirect'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'text/html', 'Location': 'http://www.github.com' }, statusCode: 302, body: '<p>302 Redirecting to <a href="http://www.github.com">http://www.github.com</a></p>', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'text/html', 'location': 'http://www.github.com' }, statusCode: 302, body: '<p>302 Redirecting to <a href="http://www.github.com">http://www.github.com</a></p>', isBase64Encoded: false })
}) // end it
it('Redirect (301)', function() {
it('Redirect (301)', async function() {
let _event = Object.assign({},event,{ path: '/redirect301'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'text/html', 'location': 'http://www.github.com' }, statusCode: 301, body: '<p>301 Redirecting to <a href="http://www.github.com">http://www.github.com</a></p>', isBase64Encoded: false })
}) // end it
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'text/html', 'Location': 'http://www.github.com' }, statusCode: 301, body: '<p>301 Redirecting to <a href="http://www.github.com">http://www.github.com</a></p>', isBase64Encoded: false })
})
it('Redirect (310 - Invalid Code)', async function() {
let _event = Object.assign({},event,{ path: '/redirect310'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 500, body: '{"error":"310 is an invalid redirect status code"}', isBase64Encoded: false })
}) // end it
it('Redirect (escape html)', function() {
it('Redirect (escape html)', async function() {
let _event = Object.assign({},event,{ path: '/redirectHTML'})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'text/html', 'Location': 'http://www.github.com?foo=bar&bat=baz%3Cscript%3Ealert(\'not%20good\')%3C/script%3E' }, statusCode: 302, body: '<p>302 Redirecting to <a href=\"http://www.github.com?foo=bar&amp;bat=baz&lt;script&gt;alert(&#39;not good&#39;)&lt;/script&gt;\">http://www.github.com?foo=bar&amp;bat=baz&lt;script&gt;alert(&#39;not good&#39;)&lt;/script&gt;</a></p>', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'text/html', 'location': 'http://www.github.com?foo=bar&bat=baz%3Cscript%3Ealert(\'not%20good\')%3C/script%3E' }, statusCode: 302, body: '<p>302 Redirecting to <a href=\"http://www.github.com?foo=bar&amp;bat=baz&lt;script&gt;alert(&#39;not good&#39;)&lt;/script&gt;\">http://www.github.com?foo=bar&amp;bat=baz&lt;script&gt;alert(&#39;not good&#39;)&lt;/script&gt;</a></p>', isBase64Encoded: false })
}) // end it
}) // end ERROR HANDLING tests
'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library

@@ -8,5 +7,7 @@

const api = require('../index')({ version: 'v1.0' })
const api2 = require('../index')({ version: 'v1.0' })
// NOTE: Set test to true
api._test = true;
api2._test = true;

@@ -30,2 +31,6 @@ let event = {

api2.get('/', function(req,res) {
res.status(200).json({ method: 'get', status: 'ok' })
})
api.get('/test', function(req,res) {

@@ -136,2 +141,10 @@ res.status(200).json({ method: 'get', status: 'ok' })

api.METHOD('TEST','/test/:param1/queryx', function(req,res) {
res.status(200).json({ method: 'test', status: 'ok', body: req.body })
})
api.METHOD('TEST','/test_options2/:param1/test', function(req,res) {
res.status(200).json({ method: 'test', status: 'ok', body: req.body })
})
api.options('/*', function(req,res) {

@@ -141,6 +154,10 @@ res.status(200).json({ method: 'options', status: 'ok', path: '/*'})

// api.options('/test_options2/*', function(req,res) {
// res.status(200).json({ method: 'options', status: 'ok', path: '/test_options2/*'})
// })
api.options('/test_options2/*', function(req,res) {
res.status(200).json({ method: 'options', status: 'ok', path: '/test_options2/*'})
})
api.options('/test_options2/:param1/*', function(req,res) {
res.status(200).json({ method: 'options', status: 'ok', path: '/test_options2/:param1/*', params:req.params})
})
/******************************************************************************/

@@ -158,97 +175,67 @@ /*** BEGIN TESTS ***/

it('Base path: /', function() {
it('Base path: /', async function() {
let _event = Object.assign({},event,{ path: '/' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: { 'content-type': 'application/json' },
statusCode: 200,
body: '{"method":"get","status":"ok"}',
isBase64Encoded: false
})
}) // end it
it('Simple path: /test', function() {
it('Simple path: /test', async function() {
let _event = Object.assign({},event,{})
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
}) // end it
it('Simple path w/ trailing slash: /test/', function() {
it('Simple path w/ trailing slash: /test/', async function() {
let _event = Object.assign({},event,{ path: '/test/' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
}) // end it
it('Path with parameter: /test/123', function() {
it('Path with parameter: /test/123', async function() {
let _event = Object.assign({},event,{ path: '/test/123' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123"}', isBase64Encoded: false })
}) // end it
it('Path with parameter and querystring: /test/123/query/?test=321', function() {
it('Path with parameter and querystring: /test/123/query/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
//console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
}) // end it
it('Path with multiple parameters and querystring: /test/123/query/456/?test=321', function() {
it('Path with multiple parameters and querystring: /test/123/query/456/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query/456', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false })
}) // end it
it('Event path + querystring w/ trailing slash (this shouldn\'t happen with API Gateway)', function() {
it('Event path + querystring w/ trailing slash (this shouldn\'t happen with API Gateway)', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query/?test=321', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
//console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
}) // end it
it('Event path + querystring w/o trailing slash (this shouldn\'t happen with API Gateway)', function() {
it('Event path + querystring w/o trailing slash (this shouldn\'t happen with API Gateway)', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query?test=321', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
//console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
}) // end it
it('Missing path: /not_found', function() {
it('Missing path: /not_found', async function() {
let _event = Object.assign({},event,{ path: '/not_found' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
}) // end it
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
})
it('Missing path: /not_found (new api instance)', async function() {
let _event = Object.assign({},event,{ path: '/not_found' })
let result = await new Promise(r => api2.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
}) // end it

@@ -260,2 +247,70 @@

/******************/
/*** HEAD Tests ***/
/******************/
describe('HEAD', function() {
it('Base path: /', async function() {
let _event = Object.assign({},event,{ path: '/', httpMethod: 'head' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: { 'content-type': 'application/json' },
statusCode: 200,
body: '',
isBase64Encoded: false
})
}) // end it
it('Simple path: /test', async function() {
let _event = Object.assign({},event,{ httpMethod: 'head'})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '', isBase64Encoded: false })
}) // end it
it('Simple path w/ trailing slash: /test/', async function() {
let _event = Object.assign({},event,{ path: '/test/', httpMethod: 'head' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '', isBase64Encoded: false })
}) // end it
it('Path with parameter: /test/123', async function() {
let _event = Object.assign({},event,{ path: '/test/123', httpMethod: 'head' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '', isBase64Encoded: false })
}) // end it
it('Path with parameter and querystring: /test/123/query/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'head', queryStringParameters: { test: '321' } })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '', isBase64Encoded: false })
}) // end it
it('Path with multiple parameters and querystring: /test/123/query/456/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query/456', httpMethod: 'head', queryStringParameters: { test: '321' } })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '', isBase64Encoded: false })
}) // end it
it('Event path + querystring w/ trailing slash (this shouldn\'t happen with API Gateway)', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query/?test=321', httpMethod: 'head', queryStringParameters: { test: '321' } })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '', isBase64Encoded: false })
}) // end it
it('Event path + querystring w/o trailing slash (this shouldn\'t happen with API Gateway)', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query?test=321', httpMethod: 'head', queryStringParameters: { test: '321' } })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '', isBase64Encoded: false })
}) // end it
it('Missing path: /not_found', async function() {
let _event = Object.assign({},event,{ path: '/not_found', httpMethod: 'head' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '', isBase64Encoded: false })
}) // end it
}) // end HEAD tests
/******************/
/*** POST Tests ***/

@@ -266,129 +321,72 @@ /******************/

it('Simple path: /test', function() {
it('Simple path: /test', async function() {
let _event = Object.assign({},event,{ httpMethod: 'post' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok"}', isBase64Encoded: false })
}) // end it
it('Simple path w/ trailing slash: /test/', function() {
it('Simple path w/ trailing slash: /test/', async function() {
let _event = Object.assign({},event,{ path: '/test/', httpMethod: 'post' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok"}', isBase64Encoded: false })
}) // end it
it('Path with parameter: /test/123', function() {
it('Path with parameter: /test/123', async function() {
let _event = Object.assign({},event,{ path: '/test/123', httpMethod: 'post' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","param":"123"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","param":"123"}', isBase64Encoded: false })
}) // end it
it('Path with parameter and querystring: /test/123/query/?test=321', function() {
it('Path with parameter and querystring: /test/123/query/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'post', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
//console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
}) // end it
it('Path with multiple parameters and querystring: /test/123/query/456/?test=321', function() {
it('Path with multiple parameters and querystring: /test/123/query/456/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query/456', httpMethod: 'post', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false })
}) // end it
it('With JSON body: /test/json', function() {
it('With JSON body: /test/json', async function() {
let _event = Object.assign({},event,{ path: '/test/json', httpMethod: 'post', body: { test: '123' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123"}}', isBase64Encoded: false })
}) // end it
it('With stringified JSON body: /test/json', function() {
it('With stringified JSON body: /test/json', async function() {
let _event = Object.assign({},event,{ path: '/test/json', httpMethod: 'post', body: JSON.stringify({ test: '123' }) })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123"}}', isBase64Encoded: false })
}) // end it
it('With x-www-form-urlencoded body: /test/form', function() {
it('With x-www-form-urlencoded body: /test/form', async function() {
let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'post', body: 'test=123&test2=456', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
}) // end it
it('With "x-www-form-urlencoded; charset=UTF-8" body: /test/form', function() {
it('With "x-www-form-urlencoded; charset=UTF-8" body: /test/form', async function() {
let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'post', body: 'test=123&test2=456', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
}) // end it
it('With x-www-form-urlencoded body and lowercase "Content-Type" header: /test/form', function() {
it('With x-www-form-urlencoded body and lowercase "Content-Type" header: /test/form', async function() {
let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'post', body: 'test=123&test2=456', headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
}) // end it
it('With x-www-form-urlencoded body and mixed case "Content-Type" header: /test/form', function() {
it('With x-www-form-urlencoded body and mixed case "Content-Type" header: /test/form', async function() {
let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'post', body: 'test=123&test2=456', headers: { 'CoNtEnt-TYPe': 'application/x-www-form-urlencoded' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
}) // end it
it('Missing path: /not_found', function() {
it('Missing path: /not_found', async function() {
let _event = Object.assign({},event,{ path: '/not_found', httpMethod: 'post' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
}) // end it

@@ -405,131 +403,73 @@

it('Simple path: /test', function() {
it('Simple path: /test', async function() {
let _event = Object.assign({},event,{ httpMethod: 'put' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok"}', isBase64Encoded: false })
}) // end it
it('Simple path w/ trailing slash: /test/', function() {
it('Simple path w/ trailing slash: /test/', async function() {
let _event = Object.assign({},event,{ path: '/test/', httpMethod: 'put' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok"}', isBase64Encoded: false })
}) // end it
it('Path with parameter: /test/123', function() {
it('Path with parameter: /test/123', async function() {
let _event = Object.assign({},event,{ path: '/test/123', httpMethod: 'put' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","param":"123"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","param":"123"}', isBase64Encoded: false })
}) // end it
it('Path with parameter and querystring: /test/123/query/?test=321', function() {
it('Path with parameter and querystring: /test/123/query/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'put', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
//console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
}) // end it
it('Path with multiple parameters and querystring: /test/123/query/456/?test=321', function() {
it('Path with multiple parameters and querystring: /test/123/query/456/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query/456', httpMethod: 'put', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false })
}) // end it
it('With JSON body: /test/json', function() {
it('With JSON body: /test/json', async function() {
let _event = Object.assign({},event,{ path: '/test/json', httpMethod: 'put', body: { test: '123' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123"}}', isBase64Encoded: false })
}) // end it
it('With stringified JSON body: /test/json', function() {
it('With stringified JSON body: /test/json', async function() {
let _event = Object.assign({},event,{ path: '/test/json', httpMethod: 'put', body: JSON.stringify({ test: '123' }) })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123"}}', isBase64Encoded: false })
}) // end it
it('With x-www-form-urlencoded body: /test/form', function() {
it('With x-www-form-urlencoded body: /test/form', async function() {
let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'put', body: 'test=123&test2=456', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
}) // end it
it('With "x-www-form-urlencoded; charset=UTF-8" body: /test/form', function() {
it('With "x-www-form-urlencoded; charset=UTF-8" body: /test/form', async function() {
let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'put', body: 'test=123&test2=456', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
}) // end it
it('With x-www-form-urlencoded body and lowercase "Content-Type" header: /test/form', function() {
it('With x-www-form-urlencoded body and lowercase "Content-Type" header: /test/form', async function() {
let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'put', body: 'test=123&test2=456', headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
}) // end it
it('With x-www-form-urlencoded body and mixed case "Content-Type" header: /test/form', function() {
it('With x-www-form-urlencoded body and mixed case "Content-Type" header: /test/form', async function() {
let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'put', body: 'test=123&test2=456', headers: { 'CoNtEnt-TYPe': 'application/x-www-form-urlencoded' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"put","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false })
}) // end it
it('Missing path: /not_found', function() {
it('Missing path: /not_found', async function() {
let _event = Object.assign({},event,{ path: '/not_found', httpMethod: 'put' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
}) // end it

@@ -545,33 +485,19 @@

it('Path with parameter: /test/123', function() {
it('Path with parameter: /test/123', async function() {
let _event = Object.assign({},event,{ path: '/test/123', httpMethod: 'delete' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"delete","status":"ok","param":"123"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"delete","status":"ok","param":"123"}', isBase64Encoded: false })
}) // end it
it('Path with multiple parameters: /test/123/456', function() {
it('Path with multiple parameters: /test/123/456', async function() {
let _event = Object.assign({},event,{ path: '/test/123/456', httpMethod: 'delete' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"delete","status":"ok","params":{"test":"123","test2":"456"}}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"delete","status":"ok","params":{"test":"123","test2":"456"}}', isBase64Encoded: false })
}) // end it
it('Missing path: /not_found', function() {
it('Missing path: /not_found', async function() {
let _event = Object.assign({},event,{ path: '/not_found', httpMethod: 'delete' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
}) // end it

@@ -588,100 +514,87 @@

it('Simple path: /test', function() {
it('Simple path: /test', async function() {
let _event = Object.assign({},event,{ httpMethod: 'options' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok"}', isBase64Encoded: false })
}) // end it
it('Simple path w/ trailing slash: /test/', function() {
it('Simple path w/ trailing slash: /test/', async function() {
let _event = Object.assign({},event,{ path: '/test/', httpMethod: 'options' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok"}', isBase64Encoded: false })
}) // end it
it('Path with parameter: /test/123', function() {
it('Path with parameter: /test/123', async function() {
let _event = Object.assign({},event,{ path: '/test/123', httpMethod: 'options' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","param":"123"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","param":"123"}', isBase64Encoded: false })
}) // end it
it('Path with parameter and querystring: /test/123/query/?test=321', function() {
it('Path with parameter and querystring: /test/123/query/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'options', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
//console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","param":"123","query":"321"}', isBase64Encoded: false })
}) // end it
it('Path with multiple parameters and querystring: /test/123/query/456/?test=321', function() {
it('Path with multiple parameters and querystring: /test/123/query/456/?test=321', async function() {
let _event = Object.assign({},event,{ path: '/test/123/query/456', httpMethod: 'options', queryStringParameters: { test: '321' } })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false })
}) // end it
it('Wildcard: /test_options', function() {
it('Wildcard: /test_options', async function() {
let _event = Object.assign({},event,{ path: '/test_options', httpMethod: 'options' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/*"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/*"}', isBase64Encoded: false })
}) // end it
it('Wildcard with parameter: /test_options2/123', function() {
it('Wildcard with path: /test_options2/123', async function() {
let _event = Object.assign({},event,{ path: '/test_options2/123', httpMethod: 'options' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/test_options2/*"}', isBase64Encoded: false })
}) // end it
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/*"}', isBase64Encoded: false })
})
it('Wildcard with deep path: /test/param1/queryx', async function() {
let _event = Object.assign({},event,{ path: '/test/param1/queryx', httpMethod: 'options' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/*"}', isBase64Encoded: false })
}) // end it
// it('Nested Wildcard: /test_options2', function() {
// let _event = Object.assign({},event,{ path: '/test_options2/test', httpMethod: 'options' })
//
// return new Promise((resolve,reject) => {
// api.run(_event,{},function(err,res) { resolve(res) })
// }).then((result) => {
// // console.log(result);
// expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/test_options2/*"}' })
// })
// }) // end it
it('Nested Wildcard: /test_options2', async function() {
let _event = Object.assign({},event,{ path: '/test_options2/test', httpMethod: 'options' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/test_options2/*"}', isBase64Encoded: false })
}) // end it
it('Missing path: /not_found', function() {
it('Nested Wildcard with parameters: /test_options2/param1/test', async function() {
let _event = Object.assign({},event,{ path: '/test_options2/param1/test', httpMethod: 'options' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/test_options2/:param1/*","params":{"param1":"param1"}}', isBase64Encoded: false })
}) // end it
it('Missing path: /not_found', async function() {
let _event = Object.assign({},event,{ path: '/not_found', httpMethod: 'options' })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
}) // end it
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
// console.log(result);
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false })
}) // end OPTIONS tests
describe('METHOD', function() {
it('Invalid method (new api instance)', async function() {
let _event = Object.assign({},event,{ path: '/', httpMethod: 'test' })
let result = await new Promise(r => api2.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: { 'content-type': 'application/json' },
statusCode: 405,
body: '{"error":"Method not allowed"}',
isBase64Encoded: false
})
}) // end it
}) // end DELETE tests
}) // end method tests
}) // end ROUTE tests

@@ -12,4 +12,7 @@ 'use strict';

const AWS = require('aws-sdk') // AWS SDK (automatically available in Lambda)
const S3 = require('../s3-service') // Init S3 Service
// AWS.config.credentials = new AWS.SharedIniFileCredentials({profile: 'madlucas'})
const S3 = require('../lib/s3-service') // Init S3 Service
// Init API instance

@@ -26,3 +29,3 @@ const api = require('../index')({ version: 'v1.0', mimeTypes: { test: 'text/test' } })

headers: {
'Content-Type': 'application/json'
'content-type': 'application/json'
}

@@ -53,3 +56,2 @@ }

res.sendFile('test/test.txt' + (req.query.test ? req.query.test : ''), err => {
// Return a promise

@@ -72,2 +74,19 @@ return Promise.try(() => {

api.get('/sendfile/error', function(req,res) {
res.sendFile('test/test.txtx', err => {
// Return a promise
return Promise.try(() => {
for(let i = 0; i<40000000; i++) {}
return true
}).then((x) => {
if (err) {
// log error
return true
}
})
})
})
api.get('/sendfile/buffer', function(req,res) {

@@ -117,10 +136,12 @@ res.sendFile(fs.readFileSync('test/test.txt'))

stub.withArgs({Bucket: 'my-test-bucket', Key: 'test.txt'}).resolves({
AcceptRanges: 'bytes',
LastModified: new Date('2018-04-01T13:32:58.000Z'),
ContentLength: 23,
ETag: '"ae771fbbba6a74eeeb77754355831713"',
ContentType: 'text/plain',
Metadata: {},
Body: Buffer.from('Test file for sendFile\n')
stub.withArgs({Bucket: 'my-test-bucket', Key: 'test.txt'}).returns({
promise: () => { return {
AcceptRanges: 'bytes',
LastModified: new Date('2018-04-01T13:32:58.000Z'),
ContentLength: 23,
ETag: '"ae771fbbba6a74eeeb77754355831713"',
ContentType: 'text/plain',
Metadata: {},
Body: Buffer.from('Test file for sendFile\n')
}}
})

@@ -133,10 +154,12 @@

stub.withArgs({Bucket: 'my-test-bucket', Key: 'test/test.txt'}).resolves({
AcceptRanges: 'bytes',
LastModified: new Date('2018-04-01T13:32:58.000Z'),
ContentLength: 23,
ETag: '"ae771fbbba6a74eeeb77754355831713"',
ContentType: 'text/plain',
Metadata: {},
Body: Buffer.from('Test file for sendFile\n')
stub.withArgs({Bucket: 'my-test-bucket', Key: 'test/test.txt'}).returns({
promise: () => { return {
AcceptRanges: 'bytes',
LastModified: new Date('2018-04-01T13:32:58.000Z'),
ContentLength: 23,
ETag: '"ae771fbbba6a74eeeb77754355831713"',
ContentType: 'text/plain',
Metadata: {},
Body: Buffer.from('Test file for sendFile\n')
}}
})

@@ -172,134 +195,106 @@

// Stub getObjectAsync
stub = sinon.stub(S3,'getObjectAsync')
stub = sinon.stub(S3,'getObject')
//stub.prototype.promise = function() { console.log('test') }
//console.log('proto:',);
//S3.getObject.promise = () => { }
//stub.promise = () => {}
})
it('Bad path', function() {
it('Bad path', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/badpath' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json','x-error': 'true' }, statusCode: 500, body: '{"error":"Invalid file"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json','x-error': 'true' }, statusCode: 500, body: '{"error":"Invalid file"}', isBase64Encoded: false })
}) // end it
it('Missing file', function() {
it('Missing file', async function() {
let _event = Object.assign({},event,{ path: '/sendfile' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json','x-error': 'true' }, statusCode: 500, body: '{"error":"ENOENT: no such file or directory, open \'./test-missing.txt\'"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json','x-error': 'true' }, statusCode: 500, body: '{"error":"ENOENT: no such file or directory, open \'./test-missing.txt\'"}', isBase64Encoded: false })
}) // end it
it('Missing file with custom catch', function() {
it('Missing file with custom catch', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/err' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json','x-error': 'true' }, statusCode: 404, body: '{"error":"There was an error accessing the requested file"}', isBase64Encoded: false })
})
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json','x-error': 'true' }, statusCode: 404, body: '{"error":"There was an error accessing the requested file"}', isBase64Encoded: false })
}) // end it
it('Text file w/ callback override (promise)', function() {
it('Text file w/ callback override (promise)', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/test' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=0',
'Expires': result.headers.Expires,
'Last-Modified': result.headers['Last-Modified']
},
statusCode: 201, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'max-age=0',
'expires': result.headers.expires,
'last-modified': result.headers['last-modified']
},
statusCode: 201, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('Text file error w/ callback override (promise)', function() {
it('Text file error w/ callback override (promise)', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/test', queryStringParameters: { test: 'x' } })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json','x-error': 'true' }, statusCode: 501, body: '{"error":"Custom File Error"}', isBase64Encoded: false })
}) // end it
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({ headers: { 'Content-Type': 'application/json','x-error': 'true' }, statusCode: 501, body: '{"error":"Custom File Error"}', isBase64Encoded: false })
})
it('Text file error w/ callback override (promise - no end)', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/error', queryStringParameters: { test: 'x' } })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({ headers: { 'content-type': 'application/json','x-error': 'true' }, statusCode: 500, body: result.body, isBase64Encoded: false })
}) // end it
it('Buffer Input', function() {
it('Buffer Input', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/buffer' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'max-age=0',
'Expires': result.headers.Expires,
'Last-Modified': result.headers['Last-Modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'cache-control': 'max-age=0',
'expires': result.headers.expires,
'last-modified': result.headers['last-modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('Text file w/ headers', function() {
it('Text file w/ headers', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/headers' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'x-test': 'test',
'x-timestamp': 1,
'Cache-Control': 'max-age=0',
'Expires': result.headers.Expires,
'Last-Modified': result.headers['Last-Modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'x-test': 'test',
'x-timestamp': 1,
'cache-control': 'max-age=0',
'expires': result.headers.expires,
'last-modified': result.headers['last-modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('Text file w/ headers (private cache)', function() {
it('Text file w/ headers (private cache)', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/headers-private' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'x-test': 'test',
'x-timestamp': 1,
'Cache-Control': 'private, max-age=0',
'Expires': result.headers.Expires,
'Last-Modified': result.headers['Last-Modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'x-test': 'test',
'x-timestamp': 1,
'cache-control': 'private, max-age=0',
'expires': result.headers.expires,
'last-modified': result.headers['last-modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('Text file custom Last-Modified', function() {
it('Text file custom Last-Modified', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/last-modified' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=0',
'Expires': result.headers.Expires,
'Last-Modified': 'Mon, 01 Jan 2018 00:00:00 GMT'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'max-age=0',
'expires': result.headers.expires,
'last-modified': 'Mon, 01 Jan 2018 00:00:00 GMT'
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})

@@ -309,14 +304,11 @@ }) // end it

it('Text file no Last-Modified', function() {
it('Text file no Last-Modified', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/no-last-modified' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=0',
'Expires': result.headers.Expires
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'max-age=0',
'expires': result.headers.expires
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})

@@ -326,13 +318,10 @@ }) // end it

it('Text file no Cache-Control', function() {
it('Text file no Cache-Control', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/no-cache-control' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Last-Modified': result.headers['Last-Modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'last-modified': result.headers['last-modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})

@@ -342,14 +331,11 @@ }) // end it

it('Text file custom Cache-Control', function() {
it('Text file custom Cache-Control', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/custom-cache-control' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'no-cache, no-store',
'Last-Modified': result.headers['Last-Modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'no-cache, no-store',
'last-modified': result.headers['last-modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})

@@ -359,47 +345,38 @@ }) // end it

it('S3 file', function() {
it('S3 file', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/s3' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=0',
'Expires': result.headers['Expires'],
'ETag': '"ae771fbbba6a74eeeb77754355831713"',
'Last-Modified': result.headers['Last-Modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'max-age=0',
'expires': result.headers['expires'],
'etag': '"ae771fbbba6a74eeeb77754355831713"',
'last-modified': result.headers['last-modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('S3 file w/ nested path', function() {
it('S3 file w/ nested path', async function() {
let _event = Object.assign({},event,{ path: '/sendfile/s3path' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=0',
'Expires': result.headers['Expires'],
'ETag': '"ae771fbbba6a74eeeb77754355831713"',
'Last-Modified': result.headers['Last-Modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'text/plain',
'cache-control': 'max-age=0',
'expires': result.headers['expires'],
'etag': '"ae771fbbba6a74eeeb77754355831713"',
'last-modified': result.headers['last-modified']
}, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true
})
}) // end it
it('S3 file error', function() {
it('S3 file error',async function() {
let _event = Object.assign({},event,{ path: '/sendfile/s3missing' })
return new Promise((resolve,reject) => {
api.run(_event,{},function(err,res) { resolve(res) })
}).then((result) => {
expect(result).to.deep.equal({
headers: {
'Content-Type': 'application/json',
'x-error': 'true'
}, statusCode: 500, body: '{"error":"NoSuchKey: The specified key does not exist."}', isBase64Encoded: false })
let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) }))
expect(result).to.deep.equal({
headers: {
'content-type': 'application/json',
'x-error': 'true'
}, statusCode: 500, body: '{"error":"NoSuchKey: The specified key does not exist."}', isBase64Encoded: false
})

@@ -406,0 +383,0 @@ }) // end it

'use strict';
const Promise = require('bluebird') // Promise library
const expect = require('chai').expect // Assertion library
const utils = require('../utils')
const utils = require('../lib/utils')

@@ -8,0 +7,0 @@ /******************************************************************************/

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc