diff --git a/README.md b/README.md index e1b6c94..9c06395 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,11 @@ Whatever you decide is best for your use case, **Lambda API** is there to suppor - [download()](#downloadfile--filename--options--callback) - [error()](#errorcode-message-detail) - [etag()](#etagboolean) - - [getHeader()](#getheaderkey) + - [getHeader()](#getheaderkey-value--asarray) + - [getHeaders()](#getheaders) - [getLink()](#getlinks3path-expires-callback) - [hasHeader()](#hasheaderkey) - - [header()](#headerkey-value) + - [header()](#headerkey-value--append) - [html()](#htmlbody) - [json()](#jsonbody) - [jsonp()](#jsonpbody) @@ -429,19 +430,36 @@ api.get('/users', (req,res) => { }) ``` -### 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. +### header(key, value [,append]) +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. You can utilize multi-value headers by specifying an array with multiple values as the `value`, or you can use an optional third boolean parameter and append multiple headers. ```javascript api.get('/users', (req,res) => { res.header('content-type','text/html').send('
This is HTML
') }) + +// Set multiple header values +api.get('/users', (req,res) => { + res.header('someHeader',['foo','bar').send({}) +}) + +// Set multiple header by adding to existing header +api.get('/users', (req,res) => { + res.header('someHeader','foo') + .header('someHeader','bar',true) // append another value + .send({}) +}) ``` **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. +### getHeader(key [,asArray]) +Retrieve a specific header value. `key` is case insensitive. By default (and for backwards compatibility), header values are returned as a `string`. Multi-value headers will be concatenated using a comma (see [rfc2616 4.2. Message Headers](https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2)). An optional second boolean parameter can be passed to return header values as an `array`. + +**NOTE:** The ability to retrieve the current header object by calling `getHeader()` is still possible, but the preferred method is to use the `getHeaders()` method. By default, `getHeader()` will return the object with `string` values. + +### getHeaders() +Retrieve the current header object. Values are returned as `array`s. ### hasHeader(key) Returns a boolean indicating the existence of `key` in the response headers. `key` is case insensitive. diff --git a/lib/response.js b/lib/response.js index 24d94c9..8e33631 100644 --- a/lib/response.js +++ b/lib/response.js @@ -41,7 +41,7 @@ class RESPONSE { // Default the header this._headers = { // Set the Content-Type by default - 'content-type': 'application/json' //charset=UTF-8 + 'content-type': ['application/json'] //charset=UTF-8 } // base64 encoding flag @@ -64,17 +64,28 @@ class RESPONSE { } // Adds a header field - header(key,value) { + header(key,value,append) { let _key = key.toLowerCase() // store as lowercase - value = value !== undefined ? value : '' // default value - this._headers[_key] = value // set + let _values = value ? (Array.isArray(value) ? value : [value]) : [''] + this._headers[_key] = append ? + this.hasHeader(_key) ? this._headers[_key].concat(_values) : _values + : _values return this } // Gets a header field - getHeader(key) { - if (!key) return this._headers // return all headers - return this._headers[key.toLowerCase()] + getHeader(key,asArr) { + if (!key) return asArr ? this._headers : + Object.keys(this._headers).reduce((headers,key) => + Object.assign(headers, { [key]: this._headers[key].toString() }) + ,{}) // return all headers + return asArr ? this._headers[key.toLowerCase()] + : this._headers[key.toLowerCase()] ? + this._headers[key.toLowerCase()].toString() : undefined + } + + getHeaders() { + return this._headers } // Removes a header field @@ -202,7 +213,7 @@ class RESPONSE { (opts.sameSite === false ? 'Lax' : opts.sameSite )) : '' - this.header('Set-Cookie',cookieString) + this.header('Set-Cookie',cookieString,true) return this } @@ -440,12 +451,15 @@ class RESPONSE { } // Create the response - this._response = { - headers: this._headers, - statusCode: this._statusCode, - body: this._request.method === 'HEAD' ? '' : UTILS.encodeBody(body,this._serializer), - isBase64Encoded: this._isBase64 - } + this._response = Object.assign({}, + this._request._multiValueSupport ? { multiValueHeaders: this._headers } + : { headers: UTILS.stringifyHeaders(this._headers) }, + { + statusCode: this._statusCode, + body: this._request.method === 'HEAD' ? '' : UTILS.encodeBody(body,this._serializer), + isBase64Encoded: this._isBase64 + } + ) // Trigger the callback function this.app._callback(null, this._response, this) diff --git a/lib/utils.js b/lib/utils.js index 8071760..b9cb79d 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -138,3 +138,13 @@ exports.deepMerge = (a,b) => { // Concats values from an array to ',' separated string exports.fromArray = val => val && val instanceof Array ? val.toString() : undefined + +// Stringify multi-value headers +exports.stringifyHeaders = headers => + Object.keys(headers) + .reduce((acc,key) => + Object.assign(acc,{ + // set-cookie cannot be concatenated with a comma + [key]: key === 'set-cookie' ? headers[key].slice(-1)[0] : headers[key].toString() + }) + ,{}) diff --git a/test/attachments.js b/test/attachments.js index b407fd0..8508693 100644 --- a/test/attachments.js +++ b/test/attachments.js @@ -12,8 +12,8 @@ let event = { httpMethod: 'get', path: '/', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'Content-Type': ['application/json'] } } @@ -59,43 +59,43 @@ describe('Attachment Tests:', function() { it('Simple attachment', async function() { let _event = Object.assign({},event,{ path: '/attachment' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-disposition': ['attachment'], 'content-type': ['application/json'] }, statusCode: 200, body: '{"status":"ok"}', isBase64Encoded: false }) }) // end it it('PDF attachment w/ path', async function() { let _event = Object.assign({},event,{ path: '/attachment/pdf' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-disposition': ['attachment; filename=\"foo.pdf\"'], 'content-type': ['application/pdf'] }, statusCode: 200, body: 'filedata', isBase64Encoded: false }) }) // end it it('PNG attachment w/ path', async function() { let _event = Object.assign({},event,{ path: '/attachment/png' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-disposition': ['attachment; filename=\"foo.png\"'], 'content-type': ['image/png'] }, statusCode: 200, body: 'filedata', isBase64Encoded: false }) }) // end it it('CSV attachment w/ path', async function() { let _event = Object.assign({},event,{ path: '/attachment/csv' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/attachment/custom' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-disposition': ['attachment; filename=\"foo.test\"'], 'content-type': ['text/test'] }, statusCode: 200, body: 'filedata', isBase64Encoded: false }) }) // end it it('Empty string', async function() { let _event = Object.assign({},event,{ path: '/attachment/empty-string' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-disposition': ['attachment'], 'content-type': ['application/json'] }, statusCode: 200, body: 'filedata', isBase64Encoded: false }) }) // end it it('Null string', async function() { let _event = Object.assign({},event,{ path: '/attachment/empty-string' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-disposition': ['attachment'], 'content-type': ['application/json'] }, statusCode: 200, body: 'filedata', isBase64Encoded: false }) }) // end it }) // end HEADER tests diff --git a/test/basePath.js b/test/basePath.js index 5eddef1..c03c52f 100644 --- a/test/basePath.js +++ b/test/basePath.js @@ -12,8 +12,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'Content-Type': ['application/json'] } } @@ -43,19 +43,19 @@ describe('Base Path Tests:', function() { it('Simple path with base: /v1/test', async function() { let _event = Object.assign({},event,{ path: '/v1/test' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it it('Path with base and parameter: /v1/test/123', async function() { let _event = Object.assign({},event,{ path: '/v1/test/123' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/v1/test/test2/test3' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"path":"/v1/test/test2/test3","method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it }) // end BASEPATH tests diff --git a/test/cacheControl.js b/test/cacheControl.js index 6327186..b5f9cd6 100644 --- a/test/cacheControl.js +++ b/test/cacheControl.js @@ -14,8 +14,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'Content-Type': ['application/json'] } } @@ -75,10 +75,10 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cache' }) 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 + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires }, statusCode: 200, body: 'cache', @@ -90,10 +90,10 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cacheTrue' }) 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 + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires }, statusCode: 200, body: 'cache', @@ -105,9 +105,9 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cacheFalse' }) 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': 'no-cache, no-store, must-revalidate' + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['no-cache, no-store, must-revalidate'] }, statusCode: 200, body: 'cache', @@ -119,10 +119,10 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cacheMaxAge' }) 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=1', - 'expires': result.headers.expires + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['max-age=1'], + 'expires': result.multiValueHeaders.expires }, statusCode: 200, body: 'cache', @@ -134,10 +134,10 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cachePrivate' }) 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': 'private, max-age=1', - 'expires': result.headers.expires + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['private, max-age=1'], + 'expires': result.multiValueHeaders.expires }, statusCode: 200, body: 'cache', @@ -149,10 +149,10 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cachePrivateFalse' }) 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=1', - 'expires': result.headers.expires + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['max-age=1'], + 'expires': result.multiValueHeaders.expires }, statusCode: 200, body: 'cache', @@ -164,10 +164,10 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cachePrivateInvalid' }) 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=1', - 'expires': result.headers.expires + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['max-age=1'], + 'expires': result.multiValueHeaders.expires }, statusCode: 200, body: 'cache', @@ -179,10 +179,10 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cacheCustomUndefined' }) 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 + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires }, statusCode: 200, body: 'cache', @@ -194,10 +194,10 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cacheCustomNull' }) 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 + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires }, statusCode: 200, body: 'cache', @@ -209,9 +209,9 @@ describe('cacheControl Tests:', function() { let _event = Object.assign({},event,{ path: '/cacheCustom' }) 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': 'custom value' + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['custom value'] }, statusCode: 200, body: 'cache', diff --git a/test/context.js b/test/context.js index 047c9b6..7964af3 100644 --- a/test/context.js +++ b/test/context.js @@ -12,8 +12,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'Content-Type': ['application/json'] } } @@ -45,7 +45,7 @@ describe('Context Tests:', function() { identity: { cognitoIdentityId: 321 } },(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"id":"1234","context":{"functionName":"testFunction","awsRequestId":"1234","log_group_name":"testLogGroup","log_stream_name":"testLogStream","clientContext":{},"identity":{"cognitoIdentityId":321}}}', isBase64Encoded: false }) diff --git a/test/cookies.js b/test/cookies.js index 71af5bd..d0c92cb 100644 --- a/test/cookies.js +++ b/test/cookies.js @@ -12,8 +12,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'content-type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -25,6 +25,10 @@ api.get('/cookie', function(req,res) { res.cookie('test','value').send({}) }) +api.get('/cookieMultiple', function(req,res) { + res.cookie('test','value').cookie('test2','value2').send({}) +}) + api.get('/cookieEncoded', function(req,res) { res.cookie('test','http:// [] foo;bar').send({}) }) @@ -124,9 +128,20 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookie' }) 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=/' + multiValueHeaders: { + 'content-type': ['application/json'], + 'set-cookie': ['test=value; Path=/'] + }, statusCode: 200, body: '{}', isBase64Encoded: false + }) + }) // end it + + it('Basic Session Cookie (multi-header)', async function() { + let _event = Object.assign({},event,{ path: '/cookieMultiple' }) + let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) + expect(result).to.deep.equal({ + multiValueHeaders: { + 'content-type': ['application/json'], + 'set-cookie': ['test=value; Path=/','test2=value2; Path=/'] }, statusCode: 200, body: '{}', isBase64Encoded: false }) }) // end it @@ -135,9 +150,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieEncoded' }) 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=/' + multiValueHeaders: { + 'content-type': ['application/json'], + 'set-cookie': ['test=http%3A%2F%2F%20%5B%5D%20foo%3Bbar; Path=/'] }, statusCode: 200, body: '{}', isBase64Encoded: false }) }) // end it @@ -147,9 +162,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieObject' }) 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=/' + multiValueHeaders: { + 'content-type': ['application/json'], + 'set-cookie': ['test=%7B%22foo%22%3A%22bar%22%7D; Path=/'] }, statusCode: 200, body: '{}', isBase64Encoded: false }) }) // end it @@ -159,9 +174,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieNonString' }) 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=/' + multiValueHeaders: { + 'content-type': ['application/json'], + 'set-cookie': ['123=value; Path=/'] }, statusCode: 200, body: '{}', isBase64Encoded: false }) }) // end it @@ -171,9 +186,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieExpire' }) 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=/' + multiValueHeaders: { + '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 @@ -182,9 +197,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieMaxAge' }) 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=/' + multiValueHeaders: { + '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 @@ -193,9 +208,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieDomain' }) 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=/' + multiValueHeaders: { + '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 @@ -204,9 +219,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieHttpOnly' }) 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=/' + multiValueHeaders: { + '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 @@ -215,9 +230,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieSecure' }) 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' + multiValueHeaders: { + '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 @@ -226,9 +241,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookiePath' }) 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' + multiValueHeaders: { + '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 @@ -237,9 +252,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieSameSiteTrue' }) 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' + multiValueHeaders: { + '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 @@ -248,9 +263,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieSameSiteFalse' }) 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' + multiValueHeaders: { + '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 @@ -259,9 +274,9 @@ describe('Cookie Tests:', function() { let _event = Object.assign({},event,{ path: '/cookieSameSiteString' }) 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' + multiValueHeaders: { + '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 }) }) // end it @@ -274,14 +289,14 @@ describe('Cookie Tests:', function() { it('Parse single cookie', async function() { let _event = Object.assign({},event,{ path: '/cookieParse', - headers: { - Cookie: "test=some%20value" + multiValueHeaders: { + cookie: ["test=some%20value"] } }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'application/json', + multiValueHeaders: { + 'content-type': ['application/json'], }, statusCode: 200, body: '{"cookies":{"test":"some value"}}', isBase64Encoded: false }) }) // end it @@ -289,14 +304,14 @@ describe('Cookie Tests:', function() { it('Parse & decode two cookies', async function() { let _event = Object.assign({},event,{ path: '/cookieParse', - headers: { - Cookie: "test=some%20value; test2=%7B%22foo%22%3A%22bar%22%7D" + multiValueHeaders: { + cookie: ["test=some%20value; test2=%7B%22foo%22%3A%22bar%22%7D"] } }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'application/json', + multiValueHeaders: { + 'content-type': ['application/json'], }, statusCode: 200, body: '{\"cookies\":{\"test\":\"some value\",\"test2\":{\"foo\":\"bar\"}}}', isBase64Encoded: false }) }) // end it @@ -305,14 +320,14 @@ describe('Cookie Tests:', function() { it('Parse & decode multiple cookies', async function() { let _event = Object.assign({},event,{ path: '/cookieParse', - headers: { - Cookie: "test=some%20value; test2=%7B%22foo%22%3A%22bar%22%7D; test3=domain" + multiValueHeaders: { + cookie: ["test=some%20value; test2=%7B%22foo%22%3A%22bar%22%7D; test3=domain"] } }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'application/json', + multiValueHeaders: { + 'content-type': ['application/json'], }, statusCode: 200, body: '{\"cookies\":{\"test\":\"some value\",\"test2\":{\"foo\":\"bar\"},\"test3\":\"domain\"}}', isBase64Encoded: false }) }) // end it @@ -327,9 +342,9 @@ describe('Cookie Tests:', function() { }) 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=/' + multiValueHeaders: { + '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 @@ -340,9 +355,9 @@ describe('Cookie Tests:', function() { }) 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' + multiValueHeaders: { + '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 }) }) // end it diff --git a/test/download.js b/test/download.js index 5018e24..d9423cf 100644 --- a/test/download.js +++ b/test/download.js @@ -14,15 +14,12 @@ const S3 = require('../lib/s3-service') // Init S3 Service // Init API instance const api = require('../index')({ version: 'v1.0', mimeTypes: { test: 'text/test' } }) -// NOTE: Set test to true -api._test = true; - let event = { httpMethod: 'get', path: '/', body: {}, - headers: { - 'content-type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -154,31 +151,31 @@ describe('Download Tests:', function() { it('Bad path', async function() { let _event = Object.assign({},event,{ path: '/download/badpath' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'], 'x-error': ['true'] }, statusCode: 500, body: '{"error":"Invalid file"}', isBase64Encoded: false }) }) // end it it('Missing file', async function() { let _event = Object.assign({},event,{ path: '/download' }) 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":"No such file"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'], 'x-error': ['true'] }, statusCode: 500, body: '{"error":"No such file"}', isBase64Encoded: false }) }) // end it it('Missing file with custom catch', async function() { let _event = Object.assign({},event,{ path: '/download/err' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/download/test' }) 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"' + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'], + 'content-disposition': ['attachment; filename="test.txt"'] }, statusCode: 201, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) @@ -187,19 +184,19 @@ describe('Download Tests:', function() { it('Text file error w/ callback override (promise)', async function() { let _event = Object.assign({},event,{ path: '/download/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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'], 'x-error': ['true'] }, statusCode: 501, body: '{"error":"Custom File Error"}', isBase64Encoded: false }) }) // end it it('Buffer Input (no filename)', async function() { let _event = Object.assign({},event,{ path: '/download/buffer' }) 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' + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'], + 'content-disposition': ['attachment'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -208,12 +205,12 @@ describe('Download Tests:', function() { let _event = Object.assign({},event,{ path: '/download/buffer', queryStringParameters: { filename: 'test.txt' } }) 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"' + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'], + 'content-disposition': ['attachment; filename="test.txt"'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -223,14 +220,14 @@ describe('Download Tests:', function() { let _event = Object.assign({},event,{ path: '/download/headers' }) 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"' + multiValueHeaders: { + 'content-type': ['text/plain'], + 'x-test': ['test'], + 'x-timestamp': [1], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'], + 'content-disposition': ['attachment; filename="test.txt"'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -240,13 +237,13 @@ describe('Download Tests:', function() { let _event = Object.assign({},event,{ path: '/download/all' }) 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"' + multiValueHeaders: { + 'content-type': ['text/plain'], + 'x-callback': ['true'], + 'cache-control': ['private, max-age=3600'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'], + 'content-disposition': ['attachment; filename="test-file.txt"'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -256,13 +253,13 @@ describe('Download Tests:', function() { let _event = Object.assign({},event,{ path: '/download/no-options' }) 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': 'max-age=0', - 'expires': result.headers.expires, - 'last-modified': result.headers['last-modified'], - 'content-disposition': 'attachment; filename="test-file.txt"' + multiValueHeaders: { + 'content-type': ['text/plain'], + 'x-callback': ['true'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'], + 'content-disposition': ['attachment; filename="test-file.txt"'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -272,13 +269,13 @@ describe('Download Tests:', function() { let _event = Object.assign({},event,{ path: '/download/s3' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'content-disposition': ['attachment; filename="test.txt"'], + 'expires': result.multiValueHeaders['expires'], + 'etag': ['"ae771fbbba6a74eeeb77754355831713"'], + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -287,13 +284,13 @@ describe('Download Tests:', function() { let _event = Object.assign({},event,{ path: '/download/s3path' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'content-disposition': ['attachment; filename="test.txt"'], + 'expires': result.multiValueHeaders['expires'], + 'etag': ['"ae771fbbba6a74eeeb77754355831713"'], + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -302,9 +299,9 @@ describe('Download Tests:', function() { let _event = Object.assign({},event,{ path: '/download/s3missing' }) 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' + multiValueHeaders: { + 'content-type': ['application/json'], + 'x-error': ['true'] }, statusCode: 500, body: '{"error":"NoSuchKey: The specified key does not exist."}', isBase64Encoded: false }) }) // end it diff --git a/test/errorHandling.js b/test/errorHandling.js index c4565ed..fb66282 100644 --- a/test/errorHandling.js +++ b/test/errorHandling.js @@ -15,8 +15,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -162,19 +162,19 @@ describe('Error Handling Tests:', function() { it('Called Error', async function() { let _event = Object.assign({},event,{ path: '/testError'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"This is a test error message"}', isBase64Encoded: false }) }) // end it it('Thrown Error', async function() { let _event = Object.assign({},event,{ path: '/testErrorThrow'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"This is a test thrown error"}', isBase64Encoded: false }) }) // end it it('Simulated Error', async function() { let _event = Object.assign({},event,{ path: '/testErrorSimulated'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 405, body: '{"error":"This is a simulated error"}', isBase64Encoded: false }) }) // end it }) @@ -184,31 +184,31 @@ describe('Error Handling Tests:', function() { it('Error Middleware', async function() { let _event = Object.assign({},event,{ path: '/testErrorMiddleware'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['text/plain'] }, statusCode: 500, body: 'This is a test error message: 123/456', isBase64Encoded: false }) }) // end it it('Error Middleware w/ Promise', async function() { let _event = Object.assign({},event,{ path: '/testErrorPromise'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['text/plain'] }, statusCode: 500, body: 'This is a test error message: 123/456', isBase64Encoded: false }) }) // end it it('Multiple error middlewares', async function() { let _event = Object.assign({},event,{ path: '/testError'}) let result = await new Promise(r => api2.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: true/true', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['text/plain'] }, statusCode: 500, body: 'This is a test error message: true/true', isBase64Encoded: false }) }) // end it it('Returned error from middleware (async)', async function() { let _event = Object.assign({},event,{ path: '/testError'}) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { }, statusCode: 500, body: 'this is an error: false', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { }, statusCode: 500, body: 'this is an error: false', isBase64Encoded: false }) }) // end it it('Returned error from middleware (callback)', async function() { let _event = Object.assign({},event,{ path: '/testError'}) let result = await new Promise(r => api4.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { }, statusCode: 500, body: 'this is an error: false', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { }, statusCode: 500, body: 'this is an error: false', isBase64Encoded: false }) }) // end it }) @@ -216,31 +216,31 @@ describe('Error Handling Tests:', function() { it('RouteError', async function() { let _event = Object.assign({},event,{ path: '/testx'}) let result = await new Promise(r => api_errors.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { }, statusCode: 404, body: '{"errorType":"RouteError"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { }, statusCode: 404, body: '{"errorType":"RouteError"}', isBase64Encoded: false }) }) // end it it('MethodError', async function() { let _event = Object.assign({},event,{ path: '/fileError', httpMethod: 'put' }) let result = await new Promise(r => api_errors.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { }, statusCode: 405, body: '{"errorType":"MethodError"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { }, statusCode: 405, body: '{"errorType":"MethodError"}', isBase64Encoded: false }) }) // end it it('FileError (s3)', async function() { let _event = Object.assign({},event,{ path: '/fileError' }) let result = await new Promise(r => api_errors.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { }, statusCode: 500, body: '{"errorType":"FileError"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { }, statusCode: 500, body: '{"errorType":"FileError"}', isBase64Encoded: false }) }) // end it it('FileError (local)', async function() { let _event = Object.assign({},event,{ path: '/fileErrorLocal' }) let result = await new Promise(r => api_errors.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { }, statusCode: 500, body: '{"errorType":"FileError"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { }, statusCode: 500, body: '{"errorType":"FileError"}', isBase64Encoded: false }) }) // end it it('ResponseError', async function() { let _event = Object.assign({},event,{ path: '/responseError' }) let result = await new Promise(r => api_errors.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { }, statusCode: 500, body: '{"errorType":"ResponseError"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { }, statusCode: 500, body: '{"errorType":"ResponseError"}', isBase64Encoded: false }) }) // end it }) @@ -255,7 +255,7 @@ describe('Error Handling Tests:', function() { let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) })) api._test = true console.log = logger - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 500, body: '{"error":"This is a test thrown error"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"This is a test thrown error"}', isBase64Encoded: false }) expect(_log.level).to.equal('fatal') expect(_log.msg).to.equal('This is a test thrown error') }) // end it @@ -270,7 +270,7 @@ describe('Error Handling Tests:', function() { let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) })) api._test = true console.log = logger - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 500, body: '{"error":"This is a test error message"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"This is a test error message"}', isBase64Encoded: false }) expect(_log.level).to.equal('error') expect(_log.msg).to.equal('This is a test error message') }) // end it diff --git a/test/etag.js b/test/etag.js index 95abe1d..6fb8ede 100644 --- a/test/etag.js +++ b/test/etag.js @@ -12,7 +12,7 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { + multiValueHeaders: { 'Content-Type': 'application/json' } } @@ -42,53 +42,53 @@ describe('Etag Tests:', function() { it('Initial request', async function() { let _event = Object.assign({},event,{ path: '/testEtag'}) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { - 'content-type': 'application/json', - 'etag': '"6fd977db9b2afe87a9ceee4843288129"' + expect(result).to.deep.equal({ multiValueHeaders: { + 'content-type': ['application/json'], + 'etag': ['"6fd977db9b2afe87a9ceee4843288129"'] }, statusCode: 200, body: '{"test":true}', isBase64Encoded: false }) }) // end it it('Initial request 2', async function() { let _event = Object.assign({},event,{ path: '/testEtag2'}) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { - 'content-type': 'application/json', - 'etag': '"ad2ba8d138b3cda185243603ec9fcaa7"' + expect(result).to.deep.equal({ multiValueHeaders: { + 'content-type': ['application/json'], + 'etag': ['"ad2ba8d138b3cda185243603ec9fcaa7"'] }, statusCode: 200, body: '{"test":false}', isBase64Encoded: false }) }) // end it it('Second request', async function() { - let _event = Object.assign({},event,{ path: '/testEtag', headers: { 'If-None-Match': '"6fd977db9b2afe87a9ceee4843288129"' }}) + let _event = Object.assign({},event,{ path: '/testEtag', multiValueHeaders: { 'If-None-Match': ['"6fd977db9b2afe87a9ceee4843288129"'] }}) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { - 'content-type': 'application/json', - 'etag': '"6fd977db9b2afe87a9ceee4843288129"' + expect(result).to.deep.equal({ multiValueHeaders: { + 'content-type': ['application/json'], + 'etag': ['"6fd977db9b2afe87a9ceee4843288129"'] }, statusCode: 304, body: '', isBase64Encoded: false }) }) // end it it('Second request 2', async function() { - let _event = Object.assign({},event,{ path: '/testEtag2', headers: { 'If-None-Match': '"ad2ba8d138b3cda185243603ec9fcaa7"' }}) + let _event = Object.assign({},event,{ path: '/testEtag2', multiValueHeaders: { 'If-None-Match': ['"ad2ba8d138b3cda185243603ec9fcaa7"'] }}) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { - 'content-type': 'application/json', - 'etag': '"ad2ba8d138b3cda185243603ec9fcaa7"' + expect(result).to.deep.equal({ multiValueHeaders: { + 'content-type': ['application/json'], + 'etag': ['"ad2ba8d138b3cda185243603ec9fcaa7"'] }, statusCode: 304, body: '', isBase64Encoded: false }) }) // end it it('Non-matching Etags', async function() { - let _event = Object.assign({},event,{ path: '/testEtag', headers: { 'If-None-Match': '"ad2ba8d138b3cda185243603ec9fcaa7"' }}) + let _event = Object.assign({},event,{ path: '/testEtag', multiValueHeaders: { 'If-None-Match': ['"ad2ba8d138b3cda185243603ec9fcaa7"'] }}) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { - 'content-type': 'application/json', - 'etag': '"6fd977db9b2afe87a9ceee4843288129"' + expect(result).to.deep.equal({ multiValueHeaders: { + 'content-type': ['application/json'], + 'etag': ['"6fd977db9b2afe87a9ceee4843288129"'] }, statusCode: 200, body: '{"test":true}', isBase64Encoded: false }) }) // end it it('Disable Etag', async function() { let _event = Object.assign({},event,{ path: '/testEtagFalse' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { - 'content-type': 'application/json' + expect(result).to.deep.equal({ multiValueHeaders: { + 'content-type': ['application/json'] }, statusCode: 200, body: '{"noEtag":true}', isBase64Encoded: false }) }) // end it diff --git a/test/finally.js b/test/finally.js index f5e37d8..209d301 100644 --- a/test/finally.js +++ b/test/finally.js @@ -15,7 +15,7 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { + multiValueHeaders: { 'Content-Type': 'application/json' } } @@ -47,13 +47,13 @@ describe('Finally Tests:', function() { it('Connected on first execution and after callback', 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' }, statusCode: 200, body: '{"method":"get","status":"ok","connected":"true"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok","connected":"true"}', isBase64Encoded: false }) }) // end it it('Disconnected on second execution', 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' }, statusCode: 200, body: '{"method":"get","status":"ok","connected":"false"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok","connected":"false"}', isBase64Encoded: false }) }) // end it }) // end FINALLY tests diff --git a/test/getLink.js b/test/getLink.js index c01be12..72d80bc 100644 --- a/test/getLink.js +++ b/test/getLink.js @@ -22,7 +22,7 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { + multiValueHeaders: { 'Content-Type': 'application/json' } } @@ -111,7 +111,7 @@ describe('getLink Tests:', function() { let _event = Object.assign({},event,{ path: '/s3Link' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'https://s3.amazonaws.com/my-test-bucket/test/test.txt?AWSAccessKeyId=AKXYZ&Expires=1534290845&Signature=XYZ', isBase64Encoded: false @@ -123,7 +123,7 @@ describe('getLink Tests:', function() { let _event = Object.assign({},event,{ path: '/s3LinkExpire' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'https://s3.amazonaws.com/my-test-bucket/test/test.txt?AWSAccessKeyId=AKXYZ&Expires=1534290845&Signature=XYZ', isBase64Encoded: false @@ -136,7 +136,7 @@ describe('getLink Tests:', function() { let _event = Object.assign({},event,{ path: '/s3LinkInvalidExpire' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'https://s3.amazonaws.com/my-test-bucket/test/test.txt?AWSAccessKeyId=AKXYZ&Expires=1534290845&Signature=XYZ', isBase64Encoded: false @@ -149,7 +149,7 @@ describe('getLink Tests:', function() { let _event = Object.assign({},event,{ path: '/s3LinkExpireFloat' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'https://s3.amazonaws.com/my-test-bucket/test/test.txt?AWSAccessKeyId=AKXYZ&Expires=1534290845&Signature=XYZ', isBase64Encoded: false @@ -162,7 +162,7 @@ describe('getLink Tests:', function() { let _event = Object.assign({},event,{ path: '/s3LinkError' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"getSignedUrl error"}', isBase64Encoded: false @@ -174,7 +174,7 @@ describe('getLink Tests:', function() { let _event = Object.assign({},event,{ path: '/s3LinkErrorCustom' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"Custom error"}', isBase64Encoded: false @@ -186,7 +186,7 @@ describe('getLink Tests:', function() { let _event = Object.assign({},event,{ path: '/s3LinkErrorStandard' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"getSignedUrl error"}', isBase64Encoded: false @@ -198,7 +198,7 @@ describe('getLink Tests:', function() { let _event = Object.assign({},event,{ path: '/s3LinkInvalid' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"Invalid S3 path"}', isBase64Encoded: false diff --git a/test/headers.js b/test/headers.js index bb65b10..e6f59b8 100644 --- a/test/headers.js +++ b/test/headers.js @@ -5,15 +5,12 @@ const expect = require('chai').expect // Assertion library // Init API instance const api = require('../index')({ version: 'v1.0' }) -// NOTE: Set test to true -api._test = true; - let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -35,12 +32,23 @@ api.get('/testOverride', function(req,res) { res.status(200).send('
testHTML
') }) +api.get('/testAppend', function(req,res) { + res.header('test','testVal1') + res.header('test','testVal2',true) + res.status(200).json({ method: 'get', status: 'ok' }) +}) + +api.get('/testMulti', function(req,res) { + res.header('test',['testVal1','testVal2']) + res.status(200).json({ method: 'get', status: 'ok' }) +}) + api.get('/testHTML', function(req,res) { res.status(200).html('
testHTML
') }) api.get('/testJSONP', function(req,res) { - res.status(200).html({ method: 'get', status: 'ok' }) + res.status(200).jsonp({ method: 'get', status: 'ok' }) }) api.get('/getHeader', function(req,res) { @@ -50,7 +58,20 @@ api.get('/getHeader', function(req,res) { getHeader: res.getHeader('testheader'), getHeaderCase: res.getHeader('coNtEnt-TyPe'), getHeaderMissing: res.getHeader('test') ? false : true, - getHeaderEmpty: res.getHeader() ? false : true + getHeaderEmpty: res.getHeader() ? false : true, + getHeaders: res.getHeaders() + }) +}) + +api.get('/getHeaderArray', function(req,res) { + res.status(200).header('TestHeader','test').header('TestHeader','test2',true) + res.json({ + headers: res.getHeader(undefined,true), + getHeader: res.getHeader('testheader',true), + getHeaderCase: res.getHeader('coNtEnt-TyPe',true), + getHeaderMissing: res.getHeader('test') ? false : true, + getHeaderEmpty: res.getHeader() ? false : true, + getHeaders: res.getHeaders(true) }) }) @@ -121,37 +142,72 @@ describe('Header 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { + 'content-type': ['application/json'], + 'test': ['testVal'] + }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it it('Empty Header - Default', async function() { let _event = Object.assign({},event,{ path: '/testEmpty' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json', 'test': '' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'], 'test': [''] }, 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: '
testHTML
', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['text/html'] }, statusCode: 200, body: '
testHTML
', isBase64Encoded: false }) + }) // end it + + it('Append to Header: /testAppend (multi-header)', async function() { + let _event = Object.assign({},event,{ path: '/testAppend'}) + let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'], 'test': ['testVal1','testVal2'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + }) // end it + + it('Multi-value Header: /testMulti (multi-header)', async function() { + let _event = Object.assign({},event,{ path: '/testMulti'}) + let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'], 'test': ['testVal1','testVal2'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it 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: '
testHTML
', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['text/html'] }, statusCode: 200, body: '
testHTML
', isBase64Encoded: false }) + }) // end it + + it('JSONP Convenience Method: /testJSONP', async function() { + let _event = Object.assign({},event,{ path: '/testJSONP'}) + let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'callback({"method":"get","status":"ok"})', isBase64Encoded: false }) }) // end it - it('Get Header', async function() { + it('Get Header (as string)', 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' + multiValueHeaders: { + '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,"getHeaders":{"content-type":["application/json"],"testheader":["test"]}}', + isBase64Encoded: false + }) + }) // end it + + + it('Get Header (as array)', async function() { + let _event = Object.assign({},event,{ path: '/getHeaderArray'}) + let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) + expect(result).to.deep.equal({ + multiValueHeaders: { + 'content-type': ['application/json'], + 'testheader': ['test','test2'] }, statusCode: 200, - body: '{"headers":{"content-type":"application/json","testheader":"test"},"getHeader":"test","getHeaderCase":"application/json","getHeaderMissing":true,"getHeaderEmpty":false}', + body: '{"headers":{"content-type":["application/json"],"testheader":["test","test2"]},"getHeader":["test","test2"],"getHeaderCase":["application/json"],"getHeaderMissing":true,"getHeaderEmpty":false,"getHeaders":{"content-type":["application/json"],"testheader":["test","test2"]}}', isBase64Encoded: false }) }) // end it @@ -160,9 +216,9 @@ describe('Header Tests:', 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' + multiValueHeaders: { + 'content-type': ['application/json'], + 'testheader': ['test'] }, statusCode: 200, body: '{"hasHeader":true,"hasHeaderCase":true,"hasHeaderMissing":false,"hasHeaderEmpty":false}', isBase64Encoded: false @@ -173,9 +229,9 @@ describe('Header Tests:', 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' + multiValueHeaders: { + 'content-type': ['application/json'], + 'newheader': ['test'] }, statusCode: 200, body: '{"removeHeader":true,"hasHeader":true}', isBase64Encoded: false @@ -190,11 +246,11 @@ describe('Header Tests:', 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': '*' + multiValueHeaders: { + '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 @@ -205,14 +261,14 @@ describe('Header Tests:', 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' + multiValueHeaders: { + '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 @@ -223,12 +279,12 @@ describe('Header Tests:', 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' + multiValueHeaders: { + '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 @@ -239,11 +295,11 @@ describe('Header Tests:', function() { let _event = Object.assign({},event,{ path: '/corsOverride2'}) 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', - 'access-control-allow-origin': '*' + multiValueHeaders: { + 'content-type': ['application/json'], + 'access-control-allow-headers': ['Content-Type, Authorization, Content-Length, X-Requested-With'], + 'access-control-allow-methods': ['GET, PUT, POST'], + 'access-control-allow-origin': ['*'] }, statusCode: 200, body: '{}', isBase64Encoded: false @@ -255,46 +311,46 @@ describe('Header Tests:', function() { describe('Authorization Tests:', function() { it('Bearer (OAuth2/JWT)', async function() { - let _event = Object.assign({},event,{ path: '/auth', headers: { authorization: "Bearer XYZ" } }) + let _event = Object.assign({},event,{ path: '/auth', multiValueHeaders: { authorization: ["Bearer XYZ"] } }) 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: '{"auth":{"type":"Bearer","value":"XYZ"}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"auth":{"type":"Bearer","value":"XYZ"}}', isBase64Encoded: false }) }) // end it it('Digest', async function() { - let _event = Object.assign({},event,{ path: '/auth', headers: { authorization: "Digest XYZ" } }) + let _event = Object.assign({},event,{ path: '/auth', multiValueHeaders: { authorization: ["Digest XYZ"] } }) 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: '{"auth":{"type":"Digest","value":"XYZ"}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"auth":{"type":"Digest","value":"XYZ"}}', isBase64Encoded: false }) }) // end it it('Basic Auth', async function() { let creds = new Buffer('test:testing').toString('base64') - let _event = Object.assign({},event,{ path: '/auth', headers: { authorization: "Basic " + creds } }) + let _event = Object.assign({},event,{ path: '/auth', multiValueHeaders: { authorization: ["Basic " + creds] } }) 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: '{"auth":{"type":"Basic","value":"dGVzdDp0ZXN0aW5n","username":"test","password":"testing"}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"auth":{"type":"Basic","value":"dGVzdDp0ZXN0aW5n","username":"test","password":"testing"}}', isBase64Encoded: false }) }) // end it it('OAuth 1.0', async function() { - let _event = Object.assign({},event,{ path: '/auth', headers: { authorization: 'OAuth realm="Example", oauth_consumer_key="xyz", oauth_token="abc", oauth_version="1.0"' } }) + let _event = Object.assign({},event,{ path: '/auth', multiValueHeaders: { authorization: ['OAuth realm="Example", oauth_consumer_key="xyz", oauth_token="abc", oauth_version="1.0"'] } }) 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: '{\"auth\":{\"type\":\"OAuth\",\"value\":\"realm=\\\"Example\\\", oauth_consumer_key=\\\"xyz\\\", oauth_token=\\\"abc\\\", oauth_version=\\\"1.0\\\"\",\"realm\":\"Example\",\"oauth_consumer_key\":\"xyz\",\"oauth_token\":\"abc\",\"oauth_version\":\"1.0\"}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{\"auth\":{\"type\":\"OAuth\",\"value\":\"realm=\\\"Example\\\", oauth_consumer_key=\\\"xyz\\\", oauth_token=\\\"abc\\\", oauth_version=\\\"1.0\\\"\",\"realm\":\"Example\",\"oauth_consumer_key\":\"xyz\",\"oauth_token\":\"abc\",\"oauth_version\":\"1.0\"}}', isBase64Encoded: false }) }) // end it it('Missing Authorization Header', async function() { - let _event = Object.assign({},event,{ path: '/auth', headers: { } }) + let _event = Object.assign({},event,{ path: '/auth', multiValueHeaders: { } }) 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: '{"auth":{"type":"none","value":null}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"auth":{"type":"none","value":null}}', isBase64Encoded: false }) }) // end it it('Invalid Schema', async function() { - let _event = Object.assign({},event,{ path: '/auth', headers: { authorization: "Test XYZ" } }) + let _event = Object.assign({},event,{ path: '/auth', multiValueHeaders: { authorization: ["Test XYZ"] } }) 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: '{"auth":{"type":"none","value":null}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"auth":{"type":"none","value":null}}', isBase64Encoded: false }) }) // end it it('Incomplete Header', async function() { - let _event = Object.assign({},event,{ path: '/auth', headers: { authorization: "Bearer" } }) + let _event = Object.assign({},event,{ path: '/auth', multiValueHeaders: { authorization: ["Bearer"] } }) 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: '{"auth":{"type":"none","value":null}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"auth":{"type":"none","value":null}}', isBase64Encoded: false }) }) // end it }) // end Auth tests @@ -302,113 +358,113 @@ describe('Header Tests:', function() { describe('CloudFront:', function() { it('clientType (desktop)', async function() { - let _event = Object.assign({},event,{ path: '/cloudfront', headers: { - 'CloudFront-Is-Desktop-Viewer': 'true', - 'CloudFront-Is-Mobile-Viewer': 'false', - 'CloudFront-Is-SmartTV-Viewer': 'false', - 'CloudFront-Is-Tablet-Viewer': 'false', - 'CloudFront-Viewer-Country': 'US' + let _event = Object.assign({},event,{ path: '/cloudfront', multiValueHeaders: { + 'CloudFront-Is-Desktop-Viewer': ['true'], + 'CloudFront-Is-Mobile-Viewer': ['false'], + 'CloudFront-Is-SmartTV-Viewer': ['false'], + 'CloudFront-Is-Tablet-Viewer': ['false'], + 'CloudFront-Viewer-Country': ['US'] } }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"clientType":"desktop","clientCountry":"US"}', isBase64Encoded: false }) }) // end it it('clientType (mobile)', async function() { - let _event = Object.assign({},event,{ path: '/cloudfront', headers: { - 'CloudFront-Is-Desktop-Viewer': 'false', - 'CloudFront-Is-Mobile-Viewer': 'true', - 'CloudFront-Is-SmartTV-Viewer': 'false', - 'CloudFront-Is-Tablet-Viewer': 'false', - 'CloudFront-Viewer-Country': 'US' + let _event = Object.assign({},event,{ path: '/cloudfront', multiValueHeaders: { + 'CloudFront-Is-Desktop-Viewer': ['false'], + 'CloudFront-Is-Mobile-Viewer': ['true'], + 'CloudFront-Is-SmartTV-Viewer': ['false'], + 'CloudFront-Is-Tablet-Viewer': ['false'], + 'CloudFront-Viewer-Country': ['US'] } }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"clientType":"mobile","clientCountry":"US"}', isBase64Encoded: false }) }) // end it it('clientType (tv)', async function() { - let _event = Object.assign({},event,{ path: '/cloudfront', headers: { - 'CloudFront-Is-Desktop-Viewer': 'false', - 'CloudFront-Is-Mobile-Viewer': 'false', - 'CloudFront-Is-SmartTV-Viewer': 'true', - 'CloudFront-Is-Tablet-Viewer': 'false', - 'CloudFront-Viewer-Country': 'US' + let _event = Object.assign({},event,{ path: '/cloudfront', multiValueHeaders: { + 'CloudFront-Is-Desktop-Viewer': ['false'], + 'CloudFront-Is-Mobile-Viewer': ['false'], + 'CloudFront-Is-SmartTV-Viewer': ['true'], + 'CloudFront-Is-Tablet-Viewer': ['false'], + 'CloudFront-Viewer-Country': ['US'] } }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"clientType":"tv","clientCountry":"US"}', isBase64Encoded: false }) }) // end it it('clientType (tablet)', async function() { - let _event = Object.assign({},event,{ path: '/cloudfront', headers: { - 'CloudFront-Is-Desktop-Viewer': 'false', - 'CloudFront-Is-Mobile-Viewer': 'false', - 'CloudFront-Is-SmartTV-Viewer': 'false', - 'CloudFront-Is-Tablet-Viewer': 'true', - 'CloudFront-Viewer-Country': 'US' + let _event = Object.assign({},event,{ path: '/cloudfront', multiValueHeaders: { + 'CloudFront-Is-Desktop-Viewer': ['false'], + 'CloudFront-Is-Mobile-Viewer': ['false'], + 'CloudFront-Is-SmartTV-Viewer': ['false'], + 'CloudFront-Is-Tablet-Viewer': ['true'], + 'CloudFront-Viewer-Country': ['US'] } }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"clientType":"tablet","clientCountry":"US"}', isBase64Encoded: false }) }) // end it it('clientType (unknown)', async function() { - let _event = Object.assign({},event,{ path: '/cloudfront', headers: { - 'CloudFront-Is-Desktop-Viewer': 'false', - 'CloudFront-Is-Mobile-Viewer': 'false', - 'CloudFront-Is-SmartTV-Viewer': 'false', - 'CloudFront-Is-Tablet-Viewer': 'false', - 'CloudFront-Viewer-Country': 'US' + let _event = Object.assign({},event,{ path: '/cloudfront', multiValueHeaders: { + 'CloudFront-Is-Desktop-Viewer': ['false'], + 'CloudFront-Is-Mobile-Viewer': ['false'], + 'CloudFront-Is-SmartTV-Viewer': ['false'], + 'CloudFront-Is-Tablet-Viewer': ['false'], + 'CloudFront-Viewer-Country': ['US'] } }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"clientType":"unknown","clientCountry":"US"}', isBase64Encoded: false }) }) // end it it('clientType (unknown - missing headers)', async function() { - let _event = Object.assign({},event,{ path: '/cloudfront', headers: {} }) + let _event = Object.assign({},event,{ path: '/cloudfront', multiValueHeaders: {} }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"clientType":"unknown","clientCountry":"unknown"}', isBase64Encoded: false }) }) // end it it('clientCountry (UK)', async function() { - let _event = Object.assign({},event,{ path: '/cloudfront', headers: { - 'CloudFront-Is-Desktop-Viewer': 'false', - 'CloudFront-Is-Mobile-Viewer': 'false', - 'CloudFront-Is-SmartTV-Viewer': 'false', - 'CloudFront-Is-Tablet-Viewer': 'false', - 'CloudFront-Viewer-Country': 'uk' + let _event = Object.assign({},event,{ path: '/cloudfront', multiValueHeaders: { + 'CloudFront-Is-Desktop-Viewer': ['false'], + 'CloudFront-Is-Mobile-Viewer': ['false'], + 'CloudFront-Is-SmartTV-Viewer': ['false'], + 'CloudFront-Is-Tablet-Viewer': ['false'], + 'CloudFront-Viewer-Country': ['uk'] } }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"clientType":"unknown","clientCountry":"UK"}', isBase64Encoded: false }) diff --git a/test/lastModified.js b/test/lastModified.js index 4e6231b..26dad7d 100644 --- a/test/lastModified.js +++ b/test/lastModified.js @@ -14,8 +14,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -58,40 +58,40 @@ describe('modified Tests:', function() { let _event = Object.assign({},event,{ path: '/modified' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'application/json', - 'last-modified': result.headers['last-modified'] + multiValueHeaders: { + 'content-type': ['application/json'], + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'cache', isBase64Encoded: false }) - expect(typeof result.headers['last-modified']).to.not.be.null - expect(typeof result.headers['last-modified']).to.not.be.empty + expect(typeof result.multiValueHeaders['last-modified']).to.not.be.null + expect(typeof result.multiValueHeaders['last-modified']).to.not.be.empty }) // end it it('modified (true)', async function() { let _event = Object.assign({},event,{ path: '/modifiedTrue' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'application/json', - 'last-modified': result.headers['last-modified'] + multiValueHeaders: { + 'content-type': ['application/json'], + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'cache', isBase64Encoded: false }) - expect(typeof result.headers['last-modified']).to.not.be.null - expect(typeof result.headers['last-modified']).to.not.be.empty + expect(typeof result.multiValueHeaders['last-modified']).to.not.be.null + expect(typeof result.multiValueHeaders['last-modified']).to.not.be.empty }) // end it it('modified (false)', async function() { let _event = Object.assign({},event,{ path: '/modifiedFalse' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] }, statusCode: 200, body: 'cache', @@ -103,9 +103,9 @@ describe('modified Tests:', function() { let _event = Object.assign({},event,{ path: '/modifiedDate' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'application/json', - 'last-modified': 'Wed, 01 Aug 2018 00:00:00 GMT' + multiValueHeaders: { + 'content-type': ['application/json'], + 'last-modified': ['Wed, 01 Aug 2018 00:00:00 GMT'] }, statusCode: 200, body: 'cache', @@ -117,9 +117,9 @@ describe('modified Tests:', function() { let _event = Object.assign({},event,{ path: '/modifiedString' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'application/json', - 'last-modified': 'Wed, 01 Aug 2018 00:00:00 GMT' + multiValueHeaders: { + 'content-type': ['application/json'], + 'last-modified': ['Wed, 01 Aug 2018 00:00:00 GMT'] }, statusCode: 200, body: 'cache', @@ -132,15 +132,15 @@ describe('modified Tests:', function() { let _event = Object.assign({},event,{ path: '/modifiedBadString' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'application/json', - 'last-modified': result.headers['last-modified'] + multiValueHeaders: { + 'content-type': ['application/json'], + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'cache', isBase64Encoded: false }) - expect(new Date(result.headers['last-modified'])).to.be.above(new Date('2018-08-02')) + expect(new Date(result.multiValueHeaders['last-modified'])).to.be.above(new Date('2018-08-02')) }) // end it diff --git a/test/log.js b/test/log.js index 1b00e10..9db499c 100644 --- a/test/log.js +++ b/test/log.js @@ -61,15 +61,15 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'content-type': 'application/json', - 'x-forwarded-for': '12.34.56.78, 23.45.67.89', - 'User-Agent': 'user-agent-string', - 'CloudFront-Is-Desktop-Viewer': 'false', - 'CloudFront-Is-Mobile-Viewer': 'true', - 'CloudFront-Is-SmartTV-Viewer': 'false', - 'CloudFront-Is-Tablet-Viewer': 'false', - 'CloudFront-Viewer-Country': 'US' + multiValueHeaders: { + 'content-type': ['application/json'], + 'x-forwarded-for': ['12.34.56.78, 23.45.67.89'], + 'user-agent': ['user-agent-string'], + 'cloudfront-is-desktop-viewer': ['false'], + 'cloudfront-is-mobile-viewer': ['true'], + 'cloudfront-is-smarttv-viewer': ['false'], + 'cloudfront-is-tablet-viewer': ['false'], + 'cloudfront-viewer-country': ['US'] } } @@ -213,7 +213,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -250,7 +250,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -266,7 +266,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -302,7 +302,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -318,7 +318,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -355,7 +355,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -393,7 +393,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -430,7 +430,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -467,7 +467,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -505,14 +505,14 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false }) expect(result2).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -563,7 +563,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -598,7 +598,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -637,7 +637,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -685,7 +685,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -729,7 +729,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -776,7 +776,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'done', isBase64Encoded: false @@ -867,7 +867,7 @@ describe('Logging Tests:', function() { console.log = consoleLog expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"undefinedVar is not defined"}', isBase64Encoded: false diff --git a/test/middleware.js b/test/middleware.js index aec66c9..58424df 100644 --- a/test/middleware.js +++ b/test/middleware.js @@ -12,21 +12,12 @@ const api5 = require('../index')({ version: 'v1.0' }) const api6 = require('../index')({ version: 'v1.0' }) const api7 = require('../index')({ version: 'v1.0' }) -// NOTE: Set test to true -api._test = true; -api2._test = true; -api3._test = true; -api4._test = true; -api5._test = true; -api6._test = true; -api7._test = true; - let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -244,45 +235,45 @@ describe('Middleware Tests:', function() { it('Set Values in res object', 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' }, statusCode: 200, body: '{"method":"get","testMiddleware":"123","testMiddleware2":"456"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","testMiddleware":"123","testMiddleware2":"456"}', isBase64Encoded: false }) }) // end it 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" } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","testMiddleware3":"123","testMiddleware4":"456","testMiddleware5":"789"}', isBase64Encoded: false }) }) // end it it('Middleware with Promise/Delay', async function() { let _event = Object.assign({},event,{ path: '/testPromise'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","testMiddlewarePromise":"test"}', isBase64Encoded: false }) }) // end it it('With matching string path', async function() { let _event = Object.assign({},event,{ path: '/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: 200, body: '{"method":"get","middleware":true,"middlewareWildcard":false,"middlewareParam":false,"middlewarePath":false}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware":true,"middlewareWildcard":false,"middlewareParam":false,"middlewarePath":false}', isBase64Encoded: false }) }) // end it it('With non-matching string path', async function() { let _event = Object.assign({},event,{ path: '/test2/xyz' }) 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: '{"method":"get","middleware":false,"middlewareWildcard":false,"middlewareParam":false,"middlewarePath":false}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware":false,"middlewareWildcard":false,"middlewareParam":false,"middlewarePath":false}', isBase64Encoded: false }) }) // end it it('Wildcard match', async function() { let _event = Object.assign({},event,{ path: '/test/xyz' }) 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: '{"method":"get","middleware":false,"middlewareWildcard":true,"middlewareParam":false,"middlewarePath":false}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware":false,"middlewareWildcard":true,"middlewareParam":false,"middlewarePath":false}', isBase64Encoded: false }) }) // end it it('Parameter match', async function() { let _event = Object.assign({},event,{ path: '/test/testing' }) 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: '{"method":"get","middleware":false,"middlewareWildcard":true,"middlewareParam":true,"middlewarePath":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware":false,"middlewareWildcard":true,"middlewareParam":true,"middlewarePath":true}', isBase64Encoded: false }) }) // end it @@ -290,53 +281,53 @@ describe('Middleware Tests:', function() { it('Matching path (array)', async function() { let _event = Object.assign({},event,{ path: '/test' }) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","middleware":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware":true}', isBase64Encoded: false }) }) // end it it('Matching param (array)', async function() { let _event = Object.assign({},event,{ path: '/test/xyz' }) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","middleware":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware":true}', isBase64Encoded: false }) }) // end it it('Matching wildcard (array)', async function() { let _event = Object.assign({},event,{ path: '/test2/test' }) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","middleware":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware":true}', isBase64Encoded: false }) }) // end it it('Non-matching path (array)', async function() { let _event = Object.assign({},event,{ path: '/test3' }) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","middleware":false}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware":false}', isBase64Encoded: false }) }) // end it it('Multiple middlewares (no path)', async function() { let _event = Object.assign({},event,{ path: '/test' }) let result = await new Promise(r => api4.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","middleware1":true,"middleware2":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware1":true,"middleware2":true}', isBase64Encoded: false }) }) // end it it('Multiple middlewares (w/o matching path)', async function() { let _event = Object.assign({},event,{ path: '/test' }) let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","middleware1":false,"middleware2":false}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware1":false,"middleware2":false}', isBase64Encoded: false }) }) // end it it('Multiple middlewares (w/ matching path)', async function() { let _event = Object.assign({},event,{ path: '/test/x' }) let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","middleware1":true,"middleware2":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware1":true,"middleware2":true}', isBase64Encoded: false }) }) // end it it('Single middleware (w/ matching path)', async function() { let _event = Object.assign({},event,{ path: '/test/y' }) let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","middleware1":true,"middleware2":false}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","middleware1":true,"middleware2":false}', isBase64Encoded: false }) }) // end it @@ -344,7 +335,7 @@ describe('Middleware Tests:', function() { let _event = Object.assign({},event,{ path: '/test' }) let result = await new Promise(r => api6.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json', middleware1: true }, + multiValueHeaders: { 'content-type': ['application/json'], middleware1: [true] }, statusCode: 200, body: 'return from middleware', isBase64Encoded: false }) }) // end it @@ -353,7 +344,7 @@ describe('Middleware Tests:', function() { let _event = Object.assign({},event,{ path: '/test' }) let result = await new Promise(r => api7.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json', middleware1: true }, + multiValueHeaders: { 'content-type': ['application/json'], middleware1: [true] }, statusCode: 200, body: 'return from middleware', isBase64Encoded: false }) }) // end it @@ -362,7 +353,7 @@ describe('Middleware Tests:', function() { let _event = Object.assign({},event,{ path: '/test/error' }) let result = await new Promise(r => api2.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 401, body: '{"error":"Not Authorized"}', isBase64Encoded: false }) }) // end it diff --git a/test/modules.js b/test/modules.js index 27da61d..47f4da7 100644 --- a/test/modules.js +++ b/test/modules.js @@ -15,8 +15,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'Content-Type': ['application/json'] } } @@ -52,25 +52,25 @@ describe('Module Tests:', function() { it('Standard module response', async function() { let _event = Object.assign({},event,{ path:'/testApp' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok","app":"app1"}', isBase64Encoded: false }) }) // end it it('Module with promise', async function() { let _event = Object.assign({},event,{ path:'/testAppPromise' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok","app":"app2"}', isBase64Encoded: false }) }) // end it it('Module with called error', async function() { let _event = Object.assign({},event,{ path:'/testAppError' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"This is a called module error"}', isBase64Encoded: false }) }) // end it it('Module with thrown error', async function() { let _event = Object.assign({},event,{ path:'/testAppThrownError' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"This is a thrown module error"}', isBase64Encoded: false }) }) // end it }) // end MODULE tests diff --git a/test/namespaces.js b/test/namespaces.js index 4c04efe..c88fdd9 100644 --- a/test/namespaces.js +++ b/test/namespaces.js @@ -22,8 +22,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -59,13 +59,13 @@ describe('Namespace Tests:', function() { it('Invoke namespace', async function() { let _event = Object.assign({},event,{ path:'/testData' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path:'/testAppData' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 diff --git a/test/register.js b/test/register.js index f7d9cd8..0a1820f 100644 --- a/test/register.js +++ b/test/register.js @@ -10,8 +10,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -36,104 +36,104 @@ describe('Register Tests:', function() { it('No prefix', async function() { let _event = Object.assign({},event,{ path: '/test-register' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"path":"/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false }) }) // end it it('No prefix (nested)', async function() { let _event = Object.assign({},event,{ path: '/test-register/sub1' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/test-register/TEST/test' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/v1/test-register' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"path":"/v1/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false }) }) // end it it('With prefix (nested)', async function() { let _event = Object.assign({},event,{ path: '/v1/test-register/sub1' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/v1/test-register/TEST/test' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/vX/vY/test-register' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/vX/vY/test-register/sub1' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/vX/vY/test-register/TEST/test' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/vX/vY/vZ/test-register' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/vX/vY/vZ/test-register/sub1' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/vX/vY/vZ/test-register/TEST/test' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/vX/vY/test-register/sub2' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/v2/test-register' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"path":"/v2/test-register","route":"/test-register","method":"GET"}', isBase64Encoded: false }) }) // end it it('New prefix (nested)', async function() { let _event = Object.assign({},event,{ path: '/v2/test-register/sub1' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/v2/test-register/TEST/test' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 it('No options/no prefix', async function() { let _event = Object.assign({},event,{ path: '/test-register-no-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: '{"path":"/test-register-no-options","route":"/test-register-no-options","method":"GET"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"path":"/test-register-no-options","route":"/test-register-no-options","method":"GET"}', isBase64Encoded: false }) }) // end it }) // end ROUTE tests diff --git a/test/requests.js b/test/requests.js index 357b8a6..9f2d4d6 100644 --- a/test/requests.js +++ b/test/requests.js @@ -11,6 +11,8 @@ const api = require('../index')({ version: 'v1.0' }) api.get('/test/hello', function(req,res) { let request = Object.assign(req,{app:null}) // console.log(JSON.stringify(request,null,2)); + res.cookie('test','value') + res.cookie('test2','value2') res.status(200).json({ request }) }) @@ -30,7 +32,7 @@ describe('Request Tests:', function() { let body = JSON.parse(result.body) // console.log(body); // console.log(body.request.multiValueHeaders); - expect(result.headers).to.deep.equal({ 'content-type': 'application/json' }) + expect(result.multiValueHeaders).to.deep.equal({ 'content-type': ['application/json'], 'set-cookie': ['test=value; Path=/','test2=value2; Path=/'] }) expect(body).to.have.property('request') expect(body.request.id).is.not.null expect(body.request.interface).to.equal('apigateway') @@ -58,7 +60,7 @@ describe('Request Tests:', function() { delete _event.multiValueHeaders['x-forwarded-for'] // remove the header let result = await new Promise(r => api.run(_event,_context,(e,res) => { r(res) })) let body = JSON.parse(result.body) - expect(result.headers).to.deep.equal({ 'content-type': 'application/json' }) + expect(result.multiValueHeaders).to.deep.equal({ 'content-type': ['application/json'], 'set-cookie': ['test=value; Path=/','test2=value2; Path=/'] }) expect(body).to.have.property('request') expect(body.request.id).is.not.null expect(body.request.interface).to.equal('apigateway') @@ -87,8 +89,7 @@ describe('Request Tests:', function() { let _context = require('./sample-context-alb1.json') let result = await new Promise(r => api.run(_event,_context,(e,res) => { r(res) })) let body = JSON.parse(result.body) - //console.log(body); - expect(result.headers).to.deep.equal({ 'content-type': 'application/json' }) + expect(result.headers).to.deep.equal({ 'content-type': 'application/json', 'set-cookie': 'test2=value2; Path=/' }) expect(body).to.have.property('request') expect(body.request.id).is.not.null expect(body.request.interface).to.equal('alb') @@ -101,11 +102,6 @@ describe('Request Tests:', function() { expect(body.request.route).to.equal('/test/hello') expect(body.request.query.qs1).to.equal('foo') expect(body.request.multiValueQuery.qs1).to.deep.equal(['foo']) - console.log(body.request.multiValueHeaders) - // expect(body.request.query.qs2).to.equal('bar') - // expect(body.request.multiValueQuery.qs2).to.deep.equal(['foo','bar']) - // expect(body.request.multiValueQuery.qs3).to.deep.equal(['bat','baz']) - }) @@ -114,8 +110,8 @@ describe('Request Tests:', function() { let _context = require('./sample-context-alb1.json') let result = await new Promise(r => api.run(_event,_context,(e,res) => { r(res) })) let body = JSON.parse(result.body) - // console.log(body); - expect(result.headers).to.deep.equal({ 'content-type': 'application/json' }) + // console.log(JSON.stringify(result,null,2)); + expect(result.multiValueHeaders).to.deep.equal({ 'content-type': ['application/json'], 'set-cookie': ['test=value; Path=/','test2=value2; Path=/'] }) expect(body).to.have.property('request') expect(body.request.id).is.not.null expect(body.request.interface).to.equal('alb') diff --git a/test/responses.js b/test/responses.js index 7729fe4..2c20b03 100644 --- a/test/responses.js +++ b/test/responses.js @@ -19,8 +19,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'Content-Type': ['application/json'] } } @@ -114,100 +114,100 @@ describe('Response Tests:', function() { it('Object response: convert to string', async function() { let _event = Object.assign({},event,{ path: '/testObjectResponse'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"object":true}', isBase64Encoded: false }) }) // end it it('Numeric response: convert to string', async function() { let _event = Object.assign({},event,{ path: '/testNumberResponse'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '123', isBase64Encoded: false }) }) // end it it('Array response: convert to string', async function() { let _event = Object.assign({},event,{ path: '/testArrayResponse'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '[1,2,3]', isBase64Encoded: false }) }) // end it it('String response: no conversion', async function() { let _event = Object.assign({},event,{ path: '/testStringResponse'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'this is a string', isBase64Encoded: false }) }) // end it it('Empty response', async function() { let _event = Object.assign({},event,{ path: '/testEmptyResponse'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '', isBase64Encoded: false }) }) // end it it('JSONP response (default callback)', async function() { let _event = Object.assign({},event,{ path: '/testJSONPResponse' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'callback({"foo":"bar"})', isBase64Encoded: false }) }) // end it it('JSONP response (using callback URL param)', async function() { let _event = Object.assign({},event,{ path: '/testJSONPResponse', queryStringParameters: { callback: 'foo' }}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'foo({"foo":"bar"})', isBase64Encoded: false }) }) // end it it('JSONP response (using cb URL param)', async function() { let _event = Object.assign({},event,{ path: '/testJSONPResponse', queryStringParameters: { cb: 'bar' }}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'bar({"foo":"bar"})', isBase64Encoded: false }) }) // end it it('JSONP response (using URL param with spaces)', async function() { let _event = Object.assign({},event,{ path: '/testJSONPResponse', queryStringParameters: { callback: 'foo bar'}}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'foo_bar({"foo":"bar"})', isBase64Encoded: false }) }) // end it it('Location method', async function() { let _event = Object.assign({},event,{ path: '/location'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['text/html'], 'location': ['http://www.github.com'] }, statusCode: 200, body: 'Location header set', isBase64Encoded: false }) }) // end it it('Location method (encode URL)', async function() { let _event = Object.assign({},event,{ path: '/locationEncode'}) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/redirect'}) 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: '

302 Redirecting to http://www.github.com

', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['text/html'], 'location': ['http://www.github.com'] }, statusCode: 302, body: '

302 Redirecting to http://www.github.com

', isBase64Encoded: false }) }) // end it 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: '

301 Redirecting to http://www.github.com

', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['text/html'], 'location': ['http://www.github.com'] }, statusCode: 301, body: '

301 Redirecting to http://www.github.com

', isBase64Encoded: false }) }) // end it 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"310 is an invalid redirect status code"}', isBase64Encoded: false }) }) // end it it('Redirect (escape html)', async function() { let _event = Object.assign({},event,{ path: '/redirectHTML'}) 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: '

302 Redirecting to http://www.github.com?foo=bar&bat=baz<script>alert('not good')</script>

', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['text/html'], 'location': ['http://www.github.com?foo=bar&bat=baz%3Cscript%3Ealert(\'not%20good\')%3C/script%3E'] }, statusCode: 302, body: '

302 Redirecting to http://www.github.com?foo=bar&bat=baz<script>alert('not good')</script>

', isBase64Encoded: false }) }) // end it it('S3 Path', async function() { let _event = Object.assign({},event,{ path: '/s3Path' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { - 'content-type': 'text/html', - 'location': 'https://s3.amazonaws.com/my-test-bucket/test/test.txt?AWSAccessKeyId=AKXYZ&Expires=1534290845&Signature=XYZ' + multiValueHeaders: { + 'content-type': ['text/html'], + 'location': ['https://s3.amazonaws.com/my-test-bucket/test/test.txt?AWSAccessKeyId=AKXYZ&Expires=1534290845&Signature=XYZ'] }, statusCode: 302, body: '

302 Redirecting to https://s3.amazonaws.com/my-test-bucket/test/test.txt?AWSAccessKeyId=AKXYZ&Expires=1534290845&Signature=XYZ

', @@ -220,19 +220,19 @@ describe('Response Tests:', function() { it('Custom serializer', async function() { let _event = Object.assign({},event,{ path: '/test'}) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"object":true,"_custom":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"object":true,"_custom":true}', isBase64Encoded: false }) }) // end it it('Custom serializer (JSON)', async function() { let _event = Object.assign({},event,{ path: '/testJSON'}) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"object":true,"_custom":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"object":true,"_custom":true}', isBase64Encoded: false }) }) // end it it('Custom serializer (JSONP)', async function() { let _event = Object.assign({},event,{ path: '/testJSONP'}) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: 'callback({"object":true,"_custom":true})', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: 'callback({"object":true,"_custom":true})', isBase64Encoded: false }) }) // end it after(function() { diff --git a/test/routes.js b/test/routes.js index a0b0ebe..8f078b4 100644 --- a/test/routes.js +++ b/test/routes.js @@ -12,8 +12,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -265,7 +265,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false @@ -275,7 +275,7 @@ describe('Route Tests:', function() { it('Simple path: /test', 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' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it @@ -283,7 +283,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/return' }) let result = await new Promise(r => api.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false @@ -294,70 +294,70 @@ describe('Route Tests:', function() { it('Simple path, no `context`', async function() { let _event = Object.assign({},event,{}) let result = await new Promise(r => api.run(_event,null,(e,res) => { r(res) })) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it it('Simple path w/ trailing slash: /test/', async function() { let _event = Object.assign({},event,{ path: '/test/' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it it('Path with parameter: /test/123', async function() { let _event = Object.assign({},event,{ path: '/test/123' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { - let _event = Object.assign({},event,{ path: '/test/123/query', queryStringParameters: { test: '321' } }) + let _event = Object.assign({},event,{ path: '/test/123/query', queryStringParameters: { test: '321' }, multiValueQueryStringParameters: { 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: '{"method":"get","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) }) // end it it('Path with parameter and multiple querystring: /test/123/query/?test=123&test=321', async function() { let _event = Object.assign({},event,{ path: '/test/123/query', multiValueQueryStringParameters: { test: ['123', '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: '{"method":"get","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["123","321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["123","321"]}}', 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', 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: '{"method":"get","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { - let _event = Object.assign({},event,{ path: '/test/123/query/?test=321', queryStringParameters: { test: '321' } }) + let _event = Object.assign({},event,{ path: '/test/123/query/?test=321', queryStringParameters: { test: '321' }, multiValueQueryStringParameters: { 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: '{"method":"get","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', 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', queryStringParameters: { test: '321' } }) + let _event = Object.assign({},event,{ path: '/test/123/query?test=321', queryStringParameters: { test: '321' }, multiValueQueryStringParameters: { 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: '{"method":"get","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) }) // end it 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) }) // end it 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) }) // end it it('Wildcard: /*', async function() { let _event = Object.assign({},event,{ path: '/foo/bar' }) let result = await new Promise(r => api4.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json', 'wildcard': true }, + multiValueHeaders: { 'content-type': ['application/json'], 'wildcard': [true] }, statusCode: 200, body: '{"method":"GET","path":"/foo/bar"}', isBase64Encoded: false @@ -368,7 +368,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/test/foo/bar' }) let result = await new Promise(r => api4.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json', 'wildcard': true }, + multiValueHeaders: { 'content-type': ['application/json'], 'wildcard': [true] }, statusCode: 200, body: '{"method":"GET","path":"/test/foo/bar","nested":"true"}', isBase64Encoded: false @@ -388,7 +388,7 @@ describe('Route Tests:', 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' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '', isBase64Encoded: false @@ -398,67 +398,67 @@ describe('Route Tests:', function() { 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '', isBase64Encoded: false }) }) // end it it('Path with parameter and multiple querystring: /test/123/query/?test=123&test=321', async function() { let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'head', multiValueQueryStringParameters: { test: ['123', '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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '', isBase64Encoded: false }) }) // end it it('Override HEAD request', async function() { let _event = Object.assign({},event,{ path: '/override/head/request', 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', 'method': 'head' }, statusCode: 200, body: '', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'], 'method': ['head'] }, statusCode: 200, body: '', isBase64Encoded: false }) }) // end it it('Wildcard HEAD request', async function() { let _event = Object.assign({},event,{ path: '/head/override', 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', 'wildcard': true }, statusCode: 200, body: '', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'], 'wildcard': [true] }, statusCode: 200, body: '', isBase64Encoded: false }) }) // end it }) // end HEAD tests @@ -472,92 +472,92 @@ describe('Route Tests:', function() { it('Simple path: /test', async function() { let _event = Object.assign({},event,{ httpMethod: 'post' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"post","status":"ok"}', isBase64Encoded: false }) }) // end it it('Simple path w/ trailing slash: /test/', async function() { let _event = Object.assign({},event,{ path: '/test/', httpMethod: 'post' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"post","status":"ok"}', isBase64Encoded: false }) }) // end it it('Path with parameter: /test/123', async function() { let _event = Object.assign({},event,{ path: '/test/123', httpMethod: 'post' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { - let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'post', queryStringParameters: { test: '321' } }) + let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'post', queryStringParameters: { test: '321' }, multiValueQueryStringParameters: { 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: '{"method":"post","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"post","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) }) // end it it('Path with parameter and multiple querystring: /test/123/query/?test=123&test=321', async function() { let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'post', multiValueQueryStringParameters: { test: ['123', '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: '{"method":"post","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["123","321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"post","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["123","321"]}}', 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: 'post', 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: '{"method":"post","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/test/json', httpMethod: 'post', body: { test: '123' } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/test/json', httpMethod: 'post', body: JSON.stringify({ test: '123' }) }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', 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' } }) + let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'post', body: 'test=123&test2=456', multiValueHeaders: { 'Content-Type': ['application/x-www-form-urlencoded'] } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', 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' } }) + let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'post', body: 'test=123&test2=456', multiValueHeaders: { 'Content-Type': ['application/x-www-form-urlencoded; charset=UTF-8'] } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', 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' } }) + let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'post', body: 'test=123&test2=456', multiValueHeaders: { 'content-type': ['application/x-www-form-urlencoded; charset=UTF-8'] } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', 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' } }) + let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'post', body: 'test=123&test2=456', multiValueHeaders: { 'CoNtEnt-TYPe': ['application/x-www-form-urlencoded'] } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"post","status":"ok","body":{"test":"123","test2":"456"}}', isBase64Encoded: false }) }) // end it it('With base64 encoded body', async function() { let _event = Object.assign({},event,{ path: '/test/base64', httpMethod: 'post', 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' }, statusCode: 200, body: '{"method":"post","status":"ok","body":"Test file for sendFile\\n"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"post","status":"ok","body":"Test file for sendFile\\n"}', isBase64Encoded: false }) }) // end it it('Missing path: /not_found', async function() { let _event = Object.assign({},event,{ path: '/not_found', httpMethod: 'post' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) }) // end it it('Wildcard: /*', async function() { let _event = Object.assign({},event,{ path: '/foo/bar', httpMethod: 'post' }) let result = await new Promise(r => api4.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json', 'wildcard': true }, + multiValueHeaders: { 'content-type': ['application/json'], 'wildcard': [true] }, statusCode: 200, body: '{"method":"POST","path":"/foo/bar"}', isBase64Encoded: false @@ -568,7 +568,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/test/foo/bar', httpMethod: 'post' }) let result = await new Promise(r => api4.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json', 'wildcard': true }, + multiValueHeaders: { 'content-type': ['application/json'], 'wildcard': [true] }, statusCode: 200, body: '{"method":"POST","path":"/test/foo/bar","nested":"true"}', isBase64Encoded: false @@ -587,80 +587,80 @@ describe('Route Tests:', function() { it('Simple path: /test', async function() { let _event = Object.assign({},event,{ httpMethod: 'put' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"put","status":"ok"}', isBase64Encoded: false }) }) // end it it('Simple path w/ trailing slash: /test/', async function() { let _event = Object.assign({},event,{ path: '/test/', httpMethod: 'put' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"put","status":"ok"}', isBase64Encoded: false }) }) // end it it('Path with parameter: /test/123', async function() { let _event = Object.assign({},event,{ path: '/test/123', httpMethod: 'put' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { - let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'put', queryStringParameters: { test: '321' } }) + let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'put', queryStringParameters: { test: '321' }, multiValueQueryStringParameters: { 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: '{"method":"put","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"put","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) }) // end it it('Path with parameter and multiple querystring: /test/123/query/?test=123&test=321', async function() { let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'put', multiValueQueryStringParameters: { test: ['123', '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: '{"method":"put","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["123","321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"put","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["123","321"]}}', 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: 'put', 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: '{"method":"put","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/test/json', httpMethod: 'put', body: { test: '123' } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/test/json', httpMethod: 'put', body: JSON.stringify({ test: '123' }) }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', 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' } }) + let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'put', body: 'test=123&test2=456', multiValueHeaders: { 'content-type': ['application/x-www-form-urlencoded'] } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', 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' } }) + let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'put', body: 'test=123&test2=456', multiValueHeaders: { 'content-type': ['application/x-www-form-urlencoded; charset=UTF-8'] } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', 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' } }) + let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'put', body: 'test=123&test2=456', multiValueHeaders: { 'content-type': ['application/x-www-form-urlencoded; charset=UTF-8'] } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', 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' } }) + let _event = Object.assign({},event,{ path: '/test/form', httpMethod: 'put', body: 'test=123&test2=456', multiValueHeaders: { 'CoNtEnt-TYPe': ['application/x-www-form-urlencoded'] } }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/not_found', httpMethod: 'put' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) }) // end it }) // end PUT tests @@ -675,25 +675,25 @@ describe('Route Tests:', function() { it('Simple path: /test', async function() { let _event = Object.assign({},event,{ path: '/test', httpMethod: 'patch'}) 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":"patch","status":"ok"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"patch","status":"ok"}', isBase64Encoded: false }) }) // end it it('Path with parameter: /test/123', async function() { let _event = Object.assign({},event,{ path: '/test/123', httpMethod: 'patch' }) 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":"patch","status":"ok","param":"123"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"patch","status":"ok","param":"123"}', isBase64Encoded: false }) }) // end it it('Path with multiple parameters: /test/123/456', async function() { let _event = Object.assign({},event,{ path: '/test/123/456', httpMethod: 'patch' }) 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":"patch","status":"ok","params":{"test":"123","test2":"456"}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"patch","status":"ok","params":{"test":"123","test2":"456"}}', isBase64Encoded: false }) }) // end it it('Missing path: /not_found', async function() { let _event = Object.assign({},event,{ path: '/not_found', httpMethod: 'patch' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) }) // end it }) // end PATCH tests @@ -707,19 +707,19 @@ describe('Route Tests:', function() { it('Path with parameter: /test/123', async function() { let _event = Object.assign({},event,{ path: '/test/123', httpMethod: 'delete' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/test/123/456', httpMethod: 'delete' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/not_found', httpMethod: 'delete' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) }) // end it }) // end DELETE tests @@ -734,80 +734,80 @@ describe('Route Tests:', function() { it('Simple path: /test', async function() { let _event = Object.assign({},event,{ 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"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"options","status":"ok"}', isBase64Encoded: false }) }) // end it it('Simple path w/ trailing slash: /test/', async function() { let _event = Object.assign({},event,{ path: '/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"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"options","status":"ok"}', isBase64Encoded: false }) }) // end it it('Path with parameter: /test/123', async function() { let _event = Object.assign({},event,{ path: '/test/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","param":"123"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { - let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'options', queryStringParameters: { test: '321' } }) + let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'options', queryStringParameters: { test: '321' }, multiValueQueryStringParameters: { 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: '{"method":"options","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"options","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["321"]}}', isBase64Encoded: false }) }) // end it it('Path with parameter and multiple querystring: /test/123/query/?test=123&test=321', async function() { let _event = Object.assign({},event,{ path: '/test/123/query', httpMethod: 'options', multiValueQueryStringParameters: { test: ['123', '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: '{"method":"options","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["123","321"]}}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"options","status":"ok","param":"123","query":{"test":"321"},"multiValueQuery":{"test":["123","321"]}}', 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: 'options', 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: '{"method":"options","status":"ok","params":{"test":"123","test2":"456"},"query":"321"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { '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', async function() { let _event = Object.assign({},event,{ path: '/test_options', 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/*"}', isBase64Encoded: false }) }) // end it 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/test_options2/*"}', isBase64Encoded: false }) }) // end it 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/*"}', isBase64Encoded: false }) }) // 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"options","status":"ok","path":"/test_options2/*"}', isBase64Encoded: false }) }) // end it 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) }) // end it it('Wildcard: /test/*', async function() { let _event = Object.assign({},event,{ path: '/test/foo/bar', httpMethod: 'options' }) let result = await new Promise(r => api4.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json', 'wildcard': true }, + multiValueHeaders: { 'content-type': ['application/json'], 'wildcard': [true] }, statusCode: 200, body: '{"method":"OPTIONS","path":"/test/foo/bar","nested":"true"}', isBase64Encoded: false @@ -818,7 +818,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/test/test/foo/bar', httpMethod: 'options' }) let result = await new Promise(r => api4.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json', 'wildcard': true }, + multiValueHeaders: { 'content-type': ['application/json'], 'wildcard': [true] }, statusCode: 200, body: '{"method":"OPTIONS","path":"/test/test/foo/bar","nested":"true"}', isBase64Encoded: false @@ -838,56 +838,56 @@ describe('Route Tests:', function() { it('GET request on ANY route', async function() { let _event = Object.assign({},event,{ path: '/any', httpMethod: 'get' }) 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","path":"/any","anyRoute":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"GET","path":"/any","anyRoute":true}', isBase64Encoded: false }) }) // end it it('POST request on ANY route', async function() { let _event = Object.assign({},event,{ path: '/any', httpMethod: 'post' }) 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","path":"/any","anyRoute":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"POST","path":"/any","anyRoute":true}', isBase64Encoded: false }) }) // end it it('PUT request on ANY route', async function() { let _event = Object.assign({},event,{ path: '/any', httpMethod: 'put' }) 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","path":"/any","anyRoute":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"PUT","path":"/any","anyRoute":true}', isBase64Encoded: false }) }) // end it it('DELETE request on ANY route', async function() { let _event = Object.assign({},event,{ path: '/any', httpMethod: 'delete' }) 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","path":"/any","anyRoute":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"DELETE","path":"/any","anyRoute":true}', isBase64Encoded: false }) }) // end it it('PATCH request on ANY route', async function() { let _event = Object.assign({},event,{ path: '/any', httpMethod: 'patch' }) 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":"PATCH","path":"/any","anyRoute":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"PATCH","path":"/any","anyRoute":true}', isBase64Encoded: false }) }) // end it it('HEAD request on ANY route', async function() { let _event = Object.assign({},event,{ path: '/any', 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '', isBase64Encoded: false }) }) // end it it('GET request on ANY route: /any2', async function() { let _event = Object.assign({},event,{ path: '/any2', httpMethod: 'get' }) 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","path":"/any2","anyRoute":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"GET","path":"/any2","anyRoute":true}', isBase64Encoded: false }) }) // end it it('POST request that overrides ANY route: /any2', async function() { let _event = Object.assign({},event,{ path: '/any2', httpMethod: 'post' }) 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","path":"/any2","anyRoute":false}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"POST","path":"/any2","anyRoute":false}', isBase64Encoded: false }) }) // end it it('GET request on ANY wildcard route: /anywildcard', async function() { let _event = Object.assign({},event,{ path: '/anywildcard/test', httpMethod: 'get' }) 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","path":"/anywildcard","anyRoute":true}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"GET","path":"/anywildcard","anyRoute":true}', isBase64Encoded: false }) }) // end it }) // end ANY tests @@ -900,7 +900,7 @@ describe('Route Tests:', 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' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 405, body: '{"error":"Method not allowed"}', isBase64Encoded: false @@ -911,7 +911,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/multimethod/test', httpMethod: 'get' }) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"GET","path":"/multimethod/test"}', isBase64Encoded: false @@ -922,7 +922,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/multimethod/test', httpMethod: 'post' }) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"POST","path":"/multimethod/test"}', isBase64Encoded: false @@ -933,7 +933,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/multimethod/x', httpMethod: 'get' }) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"GET","path":"/multimethod/:var"}', isBase64Encoded: false @@ -944,7 +944,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/multimethod/x', httpMethod: 'put' }) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"PUT","path":"/multimethod/:var"}', isBase64Encoded: false @@ -955,7 +955,7 @@ describe('Route Tests:', function() { let _event = Object.assign({},event,{ path: '/multimethod/x', httpMethod: 'post' }) let result = await new Promise(r => api3.run(_event,{},(e,res) => { r(res) })) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 405, body: '{"error":"Method not allowed"}', isBase64Encoded: false @@ -997,7 +997,7 @@ describe('Route Tests:', function() { let result = await api.run(_event,{}).then(res => { return res }) expect(result).to.deep.equal({ - headers: { 'content-type': 'application/json' }, + multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false diff --git a/test/run.js b/test/run.js index 81d982a..b716900 100644 --- a/test/run.js +++ b/test/run.js @@ -16,8 +16,8 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'Content-Type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -57,37 +57,37 @@ describe('Main handler Async/Await:', function() { it('With context object', async function() { let _event = Object.assign({},event,{}) let result = await api.run(_event,{}) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it it('Without context object', async function() { let _event = Object.assign({},event,{}) let result = await api.run(_event) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it it('With callback', async function() { let _event = Object.assign({},event,{}) let result = await api.run(_event,{},(err,res) => {}) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false }) }) // end it it('Triggered Error', async function() { let _event = Object.assign({},event,{ path: '/testError' }) let result = await api.run(_event,{}) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"some error"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '{"error":"some error"}', isBase64Encoded: false }) }) // end it it('Thrown Error', async function() { let _event = Object.assign({},event,{ path: '/testErrorThrown' }) let result = await api_error.run(_event,{}) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 500, body: '{"error":"some thrown error"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"some thrown error"}', isBase64Encoded: false }) }) // end it it('Routes Error', async function() { let _event = Object.assign({},event,{ path: '/testRoute' }) let result = await api_error_path.run(_event,{}) - expect(result).to.deep.equal({ headers: { 'content-type': 'application/json' }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 404, body: '{"error":"Route not found"}', isBase64Encoded: false }) }) // end it it('Without event', async function() { diff --git a/test/sampling.js b/test/sampling.js index 08b3c43..864b942 100644 --- a/test/sampling.js +++ b/test/sampling.js @@ -50,10 +50,10 @@ let event = { httpMethod: 'get', path: '/test', body: {}, - headers: { - 'content-type': 'application/json', - 'x-forwarded-for': '12.34.56.78, 23.45.67.89', - 'User-Agent': 'user-agent-string' + multiValueHeaders: { + 'content-type': ['application/json'], + 'x-forwarded-for': ['12.34.56.78, 23.45.67.89'], + 'User-Agent': ['user-agent-string'] } } diff --git a/test/sendFile.js b/test/sendFile.js index 6f7e511..099003a 100644 --- a/test/sendFile.js +++ b/test/sendFile.js @@ -1,4 +1,4 @@ -'use strict'; +multiValueHeaders:'use strict'; const Promise = require('bluebird') // Promise library const expect = require('chai').expect // Assertion library @@ -17,15 +17,12 @@ const S3 = require('../lib/s3-service') // Init S3 Service // Init API instance const api = require('../index')({ version: 'v1.0', mimeTypes: { test: 'text/test' } }) -// NOTE: Set test to true -api._test = true; - let event = { httpMethod: 'get', path: '/', body: {}, - headers: { - 'content-type': 'application/json' + multiValueHeaders: { + 'content-type': ['application/json'] } } @@ -93,12 +90,19 @@ api.get('/sendfile/buffer', function(req,res) { res.sendFile(fs.readFileSync('test/test.txt')) }) -api.get('/sendfile/headers', function(req,res) { +api.get('/sendfile/multiValueHeaders', function(req,res) { res.sendFile('test/test.txt', { headers: { 'x-test': 'test', 'x-timestamp': 1 } }) }) +api.get('/sendfile/headers', function(req,res) { + res.sendFile('test/test.txt', { + headers: { 'x-test': 'test', 'x-timestamp': 1 }, + private: false + }) +}) + api.get('/sendfile/headers-private', function(req,res) { res.sendFile('test/test.txt', { headers: { 'x-test': 'test', 'x-timestamp': 1 }, @@ -200,30 +204,30 @@ describe('SendFile Tests:', function() { it('Bad path', async function() { let _event = Object.assign({},event,{ path: '/sendfile/badpath' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'],'x-error': ['true'] }, statusCode: 500, body: '{"error":"Invalid file"}', isBase64Encoded: false }) }) // end it it('Missing file', async function() { let _event = Object.assign({},event,{ path: '/sendfile' }) 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":"No such file"}', isBase64Encoded: false }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'],'x-error': ['true'] }, statusCode: 500, body: '{"error":"No such file"}', isBase64Encoded: false }) }) // end it it('Missing file with custom catch', async function() { let _event = Object.assign({},event,{ path: '/sendfile/err' }) 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { '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)', async function() { let _event = Object.assign({},event,{ path: '/sendfile/test' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 201, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) @@ -232,24 +236,24 @@ describe('SendFile Tests:', 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'],'x-error': ['true'] }, statusCode: 501, body: '{"error":"Custom File Error"}', isBase64Encoded: false }) }) // end it 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 }) + expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'],'x-error': ['true'] }, statusCode: 500, body: result.body, isBase64Encoded: false }) }) // end it it('Buffer Input', async function() { let _event = Object.assign({},event,{ path: '/sendfile/buffer' }) 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'] + multiValueHeaders: { + 'content-type': ['application/json'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -258,13 +262,13 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/headers' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'x-test': ['test'], + 'x-timestamp': [1], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -273,11 +277,11 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/root' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -286,13 +290,13 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/headers-private' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'x-test': ['test'], + 'x-timestamp': [1], + 'cache-control': ['private, max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -301,11 +305,11 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/last-modified' }) 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' + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires, + 'last-modified': ['Mon, 01 Jan 2018 00:00:00 GMT'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -315,10 +319,10 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/no-last-modified' }) 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 + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders.expires }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -328,9 +332,9 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/no-cache-control' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -340,10 +344,10 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/custom-cache-control' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['no-cache, no-store'], + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -353,12 +357,12 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/s3' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders['expires'], + 'etag': ['"ae771fbbba6a74eeeb77754355831713"'], + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -367,12 +371,12 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/s3path' }) 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'] + multiValueHeaders: { + 'content-type': ['text/plain'], + 'cache-control': ['max-age=0'], + 'expires': result.multiValueHeaders['expires'], + 'etag': ['"ae771fbbba6a74eeeb77754355831713"'], + 'last-modified': result.multiValueHeaders['last-modified'] }, statusCode: 200, body: 'VGVzdCBmaWxlIGZvciBzZW5kRmlsZQo=', isBase64Encoded: true }) }) // end it @@ -381,9 +385,9 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/s3missing' }) 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' + multiValueHeaders: { + 'content-type': ['application/json'], + 'x-error': ['true'] }, statusCode: 500, body: '{"error":"NoSuchKey: The specified key does not exist."}', isBase64Encoded: false }) }) // end it @@ -393,9 +397,9 @@ describe('SendFile Tests:', function() { let _event = Object.assign({},event,{ path: '/sendfile/s3-bad-path' }) 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' + multiValueHeaders: { + 'content-type': ['application/json'], + 'x-error': ['true'] }, statusCode: 500, body: '{"error":"Invalid S3 path"}', isBase64Encoded: false }) }) // end it