8000 added test coverage and misc fixes · jthomerson/lambda-api@149ff6c · GitHub
[go: up one dir, main page]

Skip to content

Commit 149ff6c

Browse files
committed
added test coverage and misc fixes
1 parent ebbb62e commit 149ff6c

File tree

10 files changed

+180
-16
lines changed

10 files changed

+180
-16
lines changed

index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,10 @@ class API {
141141

142142
// Inherit middleware
143143
if (routes['ROUTES']['*']['MIDDLEWARE']) {
144-
_stack[method] = _stack[method] ?
145-
_stack[method].concat(routes['ROUTES']['*']['MIDDLEWARE'].stack)
146-
: routes['ROUTES']['*']['MIDDLEWARE'].stack
144+
_stack[method] = routes['ROUTES']['*']['MIDDLEWARE'].stack
145+
//_stack[method] ?
146+
// _stack[method].concat(routes['ROUTES']['*']['MIDDLEWARE'].stack)
147+
// : routes['ROUTES']['*']['MIDDLEWARE'].stack
147148
}
148149

149150
// Inherit methods and ANY
@@ -380,7 +381,7 @@ class API {
380381
setRoute(obj, method, value, path) {
381382
if (path.length > 1) {
382383
let p = path.shift()
383-
if (p === '*') { throw new ConfigurationError('Wildcards can only be at the end of a route definition.') }
384+
if (p === '*') { throw new ConfigurationError('Wildcards can only be at the end of a route definition') }
384385
this.setRoute(obj['ROUTES'][p], method, value, path)
385386
} else {
386387
// Create routes and add path if they don't exist

lib/request.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class REQUEST {
196196
} else if (
197197
wc[wc.length-1]
198198
&& wc[wc.length-1]['METHODS']
199-
&& wc[wc.length-1]['METHODS'][this.method]
199+
&& (wc[wc.length-1]['METHODS'][this.method] || wc[wc.length-1]['METHODS']['ANY'])
200200
&& (this.method !== 'OPTIONS' || this.validWildcard(wc,this.method))
201201
) {
202202
routes = wc[wc.length-1]

lib/utils.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,12 @@ exports.deepMerge = (a,b) => {
144144

145145
exports.mergeObjects = (obj1,obj2) =>
146146
Object.keys(Object.assign({},obj1,obj2)).reduce((acc,key) => {
147-
if (obj1[key] !== obj2[key]) {
148-
return Object.assign(acc,{ [key]: obj1[key] ? obj1[key].concat(obj2[key]) : obj2[key] })
147+
if (obj1[key] && obj2[key] && obj1[key].every(e => obj2[key].includes(e))) {
148+
return Object.assign(acc,{ [key]: obj1[key] })
149149
} else {
150-
return Object.assign(acc,{ [key]: obj1[key] ? obj1[key] : obj2[key] })
150+
return Object.assign(acc,{
151+
[key]: obj1[key] ? obj2[key] ? obj1[key].concat(obj2[key]) : obj1[key] : obj2[key]
152+
})
151153
}
152154
},{})
153155

test/errorHandling.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ api5.get('/testErrorThrow', function(req,res) {
132132
throw new Error('This is a test thrown error')
133133
})
134134

135+
api5.get('/testErrorDetail', function(req,res) {
136+
res.error('This is a test error message','details')
137+
})
135138

136139
api_errors.use(function(err,req,res,next) {
137140
res.send({ errorType: err.name })
@@ -250,10 +253,8 @@ describe('Error Handling Tests:', function() {
250253
let _log
251254
let _event = Object.assign({},event,{ path: '/testErrorThrow'})
252255
let logger = console.log
253-
api._test = false
254256
console.log = log => { try { _log = JSON.parse(log) } catch(e) { _log = log } }
255257
let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) }))
256-
api._test = true
257258
console.log = logger
258259
expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"This is a test thrown error"}', isBase64Encoded: false })
259260
expect(_log.level).to.equal('fatal')
@@ -265,16 +266,27 @@ describe('Error Handling Tests:', function() {
265266
let _log
266267
let _event = Object.assign({},event,{ path: '/testError'})
267268
let logger = console.log
268-
api._test = false
269269
console.log = log => { try { _log = JSON.parse(log) } catch(e) { _log = log } }
270270
let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) }))
271-
api._test = true
272271
console.log = logger
273272
expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"This is a test error message"}', isBase64Encoded: false })
274273
expect(_log.level).to.equal('error')
275274
expect(_log.msg).to.equal('This is a test error message')
276275
}) // end it
277276

277+
it('Error with Detail', async function() {
278+
let _log
279+
let _event = Object.assign({},event,{ path: '/testErrorDetail'})
280+
let logger = console.log
281+
console.log = log => { try { _log = JSON.parse(log) } catch(e) { _log = log } }
282+
let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) }))
283+
console.log = logger
284+
expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 500, body: '{"error":"This is a test error message"}', isBase64Encoded: false })
285+
expect(_log.level).to.equal('error')
286+
expect(_log.msg).to.equal('This is a test error message')
287+
expect(_log.detail).to.equal('details')
288+
}) // end it
289+
278290
})
279291

280292
}) // end ERROR HANDLING tests

test/log.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,43 @@ describe('Logging Tests:', function() {
293293
expect(_log[4]).to.have.property('country')
294294
}) // end it
295295

296+
it('Multi-value support (no parameters)', async function() {
297+
console.log = logger
298+
let _event = Object.assign({},event,{ path: '/', multiValueQueryStringParameters: { } })
299+
let result = await new Promise(r => api_multi.run(_event,context,(e,res) => { r(res) }))
300+
console.log = consoleLog
301+
302+
expect(result).to.deep.equal({
303+
multiValueHeaders: { 'content-type': ['application/json'] },
304+
statusCode: 200,
305+
body: 'done',
306+
isBase64Encoded: false
307+
})
308+
expect(_log).to.have.length(5)
309+
expect(_log[0].level).to.equal('info')
310+
expect(_log[4].level).to.equal('access')
311+
// standard log
312+
expect(_log[0]).to.have.property('time')
313+
expect(_log[0]).to.have.property('id')
314+
expect(_log[0]).to.have.property('route')
315+
expect(_log[0]).to.have.property('msg')
316+
expect(_log[0]).to.have.property('timer')
317+
expect(_log[0]).to.have.property('remaining')
318+
expect(_log[0]).to.have.property('function')
319+
expect(_log[0]).to.have.property('memory')
320+
expect(_log[0]).to.have.property('int')
321+
// access log
322+
expect(_log[4]).to.have.property('coldStart')
323+
expect(_log[4]).to.have.property('statusCode')
324+
expect(_log[4]).to.have.property('path')
325+
expect(_log[4]).to.have.property('ip')
326+
expect(_log[4]).to.have.property('ua')
327+
expect(_log[4]).to.have.property('version')
328+
expect(_log[4]).to.not.have.property('qs')
329+
expect(_log[4]).to.have.property('device')
330+
expect(_log[4]).to.have.property('country')
331+
}) // end it
332+
296333
it('Default options (no logs in routes)', async function() {
297334
console.log = logger
298335
let _event = Object.assign({},event,{ path: '/test' })

test/middleware.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ api2.use('/test/*',function testMiddlewareWildcard(req,res,next) {
6868
next()
6969
})
7070

71+
api2.use('/test/test2/*',function testMiddlewareWildcard2(req,res,next) {
72+
req.testMiddlewareWildcard2 = true
73+
next()
74+
})
75+
7176
api2.use('/test/:param1',function testMiddlewareParam(req,res,next) {
7277
req.testMiddlewareParam = true
7378
next()

test/modules.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ const api = require('../index')({ version: 'v1.0' })
88

99
const appTest = require('./_testApp')
1010

11-
// NOTE: Set test to true
12-
api._test = true;
13-
1411
let event = {
1512
httpMethod: 'get',
1613
path: '/test',

test/namespaces.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ api.app({
1414
'data3': require('./_testData')
1515
})
1616

17-
1817
// NOTE: Set test to true
1918
api._test = true;
2019

test/routes.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const api = require('../index')({ version: 'v1.0', logger: false })
77
const api2 = require('../index')({ version: 'v1.0', logger: false })
88
const api3 = require('../index')({ version: 'v1.0', logger: false })
99
const api4 = require('../index')({ version: 'v1.0', logger: false })
10+
const api5 = require('../index')({ version: 'v1.0', logger: false })
11+
const api6 = require('../index')({ version: 'v1.0', logger: false })
1012

1113
let event = {
1214
httpMethod: 'get',
@@ -241,6 +243,22 @@ api4.post('/*', (req,res) => {
241243
res.status(200).header('wildcard',true).json({ method: req.method, path: req.path })
242244
})
243245

246+
// Default route
247+
api5.get(function(req,res) {
248+
res.status(200).json({ method: 'get', status: 'ok' 10000 })
249+
})
250+
251+
api5.METHOD('any',function(req,res) {
252+
res.status(200).json({ method: 'any', status: 'ok' })
253+
})
254+
255+
api6.any('/*', function anyWildcard(req,res,next) { next() })
256+
api6.get('/*', function getWildcard(req,res,next) { next() })
257+
api6.get('/test', function testHandler(req,res) {
258+
res.send({ status: 'ok' })
259+
})
260+
261+
244262
/******************************************************************************/
245263
/*** BEGIN TESTS ***/
246264
/******************************************************************************/
@@ -368,6 +386,12 @@ describe('Route Tests:', function() {
368386
})
369387
}) // end it
370388

389+
it('Default path', async function() {
390+
let _event = Object.assign({},event,{ path: '/test' })
391+
let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) }))
392+
expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"get","status":"ok"}', isBase64Encoded: false })
393+
}) // end it
394+
371395
}) // end GET tests
372396

373397

@@ -955,6 +979,12 @@ describe('Route Tests:', function() {
955979
})
956980
}) // end it
957981

982+
it('Default path', async function() {
983+
let _event = Object.assign({},event,{ path: '/test', httpMethod: 'post' })
984+
let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) }))
985+
expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"method":"any","status":"ok"}', isBase64Encoded: false })
986+
}) // end it
987+
958988
it('Expected routes', function() {
959989
expect(api3.routes()).to.deep.equal([
960990
[ 'GET', '/multimethod/test' ],
@@ -1024,8 +1054,32 @@ describe('Route Tests:', function() {
10241054
expect(error.message).to.equal('Route-based middleware must have 3 parameters')
10251055
}) // end it
10261056

1057+
it('Invalid wildcard (mid-route)', async function() {
1058+
let error
1059+
try {
1060+
const api_error2 = require('../index')({ version: 'v1.0' })
1061+
api_error2.get('/test/*/test',(res,req) => {})
1062+
} catch(e) {
1063+
// console.log(e);
1064+
error = e
1065+
}
1066+
expect(error.name).to.equal('ConfigurationError')
1067+
expect(error.message).to.equal('Wildcards can only be at the end of a route definition')
1068+
}) // end it
1069+
10271070
}) // end Configuration errors
10281071

1072+
describe('Route Method Inheritance', function() {
1073+
1074+
it('Inherit multiple wildcard routes', async function() {
1075+
let _event = Object.assign({},event,{ path: '/test' })
1076+
let result = await new Promise(r => api6.run(_event,{},(e,res) => { r(res) }))
1077+
expect(api6._response._request._stack.map(x => x.name)).to.deep.equal([ 'anyWildcard', 'getWildcard', 'testHandler' ])
1078+
expect(result).to.deep.equal({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body: '{"status":"ok"}', isBase64Encoded: false })
1079+
}) // end it
1080+
1081+
}) // end Route Method Inheritance
1082+
10291083
describe('routes() (debug method)', function() {
10301084

10311085
it('Sample routes', function() {
@@ -1043,6 +1097,25 @@ describe('Route Tests:', function() {
10431097
[ 'DELETE', '/test/:var/delete' ]
10441098
])
10451099
}) // end it
1100+
1101+
it('Sample routes (print)', function() {
1102+
// Create an api instance
1103+
let api2 = require('../index')()
1104+
api2.get('/', (req,res) => {})
1105+
api2.post('/test', (req,res) => {})
1106+
api2.put('/test/put', (req,res) => {})
1107+
api2.delete('/test/:var/delete', (req,res) => {})
1108+
1109+
1110+
let _log
1111+
let logger = console.log
1112+
console.log = log => { try { _log = JSON.parse(log) } catch(e) { _log = log } }
1113+
api2.routes(true)
1114+
console.log = logger
1115+
1116+
expect(_log).to.equal('╔══════════╤═════════════════════╗\n║ \u001b[1mMETHOD\u001b[0m │ \u001b[1mROUTE \u001b[0m ║\n╟──────────┼─────────────────────╢\n║ GET │ / ║\n╟──────────┼─────────────────────╢\n║ POST │ /test ║\n╟──────────┼─────────────────────╢\n║ PUT │ /test/put ║\n╟──────────┼─────────────────────╢\n║ DELETE │ /test/:var/delete ║\n╚══════════╧═════════════════════╝')
1117+
}) // end it
1118+
10461119
}) // end routes() test
10471120

10481121
}) // end ROUTE tests

test/utils.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,4 +384,42 @@ describe('Utility Function Tests:', function() {
384384

385385
}) // end parseS3 tests
386386

387+
describe('mergeObjects:', function() {
388+
it('Duplicate Items', function() {
389+
let obj1 = { 1: ['test'] }
390+
let obj2 = { 1: ['test'] }
391+
expect(utils.mergeObjects(obj1,obj2)).to.deep.equal({ 1: ['test'] })
392+
})
393+
394+
it('Single Items', function() {
395+
let obj1 = { 1: ['test'] }
396+
let obj2 = { 1: ['test2'] }
397+
expect(utils.mergeObjects(obj1,obj2)).to.deep.equal({ 1: ['test','test2'] })
398+
})
399+
400+
it('Multiple Items', function() {
401+
let obj1 = { 1: ['test'], 2: ['testA'] }
402+
let obj2 = { 1: ['test2'], 2: ['testB'] }
403+
expect(utils.mergeObjects(obj1,obj2)).to.deep.equal({ 1: ['test','test2'], 2: ['testA','testB'] })
404+
})
405+
406+
it('Missing Items (obj1)', function() {
407+
let obj1 = { 1: ['test'] }
408+
let obj2 = { 1: ['test2'], 2: ['testB'] }
409+
expect(utils.mergeObjects(obj1,obj2)).to.deep.equal({ 1: ['test','test2'], 2: ['testB'] })
410+
})
411+
412+
it('Missing Items (obj2)', function() {
413+
let obj1 = { 1: ['test'], 2: ['testA'] }
414+
let obj2 = { 1: ['test2'] }
415+
expect(utils.mergeObjects(obj1,obj2)).to.deep.equal({ 1: ['test','test2'], 2: ['testA'] })
416+
})
417+
418+
it('No similarities', function() {
419+
let obj1 = { 1: ['test'] }
420+
let obj2 = { 2: ['testA'] }
421+
expect(utils.mergeObjects(obj1,obj2)).to.deep.equal({ 1: ['test'], 2: ['testA'] })
422+
})
423+
}) // end parseS3 tests
424+
387425
}) // end UTILITY tests

0 commit comments

Comments
 (0)
0