Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions src/LambdaReq.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import debug from 'debug'
import LambdaReqError from './LambdaReqError'

const log = debug('LambdaReq:')

class LambdaReq {
Expand Down Expand Up @@ -75,6 +74,7 @@ class LambdaReq {

console.assert(typeof event === 'object' && event !== null, 'Malformed Lambda event object.')
console.assert(typeof callback === 'function', 'Malformed Lambda callback.')


log('handling invocation for route %s', this.currentRoute)

Expand All @@ -93,7 +93,8 @@ class LambdaReq {

const reqData = {
params: Object.assign({}, this.params),
headers: this.headers ? Object.assign({}, this.headers) : undefined
headers: this.headers ? Object.assign({}, this.headers) : undefined,
body: this._event.body
}

let result
Expand All @@ -103,7 +104,6 @@ class LambdaReq {
log('handler %s responded with error: %s', this.currentRoute, err)
return this._respond(err)
}

if (result && result.then) {
log('handling an async result for %s', this.currentRoute)
return result.then((res)=> this._respond(null, res)).catch((err)=> this._respond(err))
Expand All @@ -126,9 +126,33 @@ class LambdaReq {
this._routes[id] = handler
}

_parseApiGatewayData (event = this._event) {
_parseApiGatewayBody(event) {
const body = {}
Object.assign(body, JSON.parse(event.body))
const headers = event.headers || {}
const contentType = headers['content-type'] || headers['Content-Type'] || 'application/json'
if (contentType.toLowerCase() === 'application/json') {
Object.assign(body, JSON.parse(event.body || '{}'))
} else if (contentType.toLowerCase() === 'application/x-www-form-urlencoded') {
const pieces = {}
event.body.split('&').forEach(part => {
const keyValue = part.split('=')
pieces[keyValue[0]] = keyValue[1]
})
Object.assign(body, pieces)
} else if (!/multipart/.test(contentType)) {
try {
Object.assign(body, JSON.parse(event.body))
} catch(e) {
//
}
}

return body
}

_parseApiGatewayData (event = this._event) {
const headers = event.headers || {}
const body = this._parseApiGatewayBody(event)

return {
method: event.httpMethod,
Expand Down
32 changes: 26 additions & 6 deletions tests/unit/LambdaReq.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ describe('LambdaReq', () => {
const lambda = new LambdaReq(API_GATEWAY_EVENT, {}, callback)
lambda.get('/v1/test', handler)
lambda.invoke()
should(handler.calledWith(
should(handler.calledWith(sinon.match(
{ params: { name: 'john', id: 'u-123', active: true },
headers: { 'Content-Type': 'application/json' }
},
}),
lambda
)).eql(true)
should(callback.getCall(0).args[1]).containEql({
Expand All @@ -48,6 +48,26 @@ describe('LambdaReq', () => {
})
})

it('responds to x-www-form-urlencoded', () => {
const callback = sinon.stub()
const handler = sinon.stub().returns({ success: true })
const event = Object.assign({}, API_GATEWAY_EVENT, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'active=true'
})

const lambda = new LambdaReq(event, {}, callback)
lambda.get('/v1/test', handler)
lambda.invoke()

should(callback.getCall(0).args[1]).containEql({
statusCode: 200,
body: '{"success":true}'
})
})

describe('when the handler result is a promise', () => {
it('waits for the promise to resolve then it responds', () => {
const callback = sinon.stub()
Expand All @@ -56,10 +76,10 @@ describe('LambdaReq', () => {
lambda.get('/v1/test', handler)
return lambda.invoke()
.then(()=> {
should(handler.calledWith(
should(handler.calledWith(sinon.match(
{ params: { name: 'john', id: 'u-123', active: true },
headers: { 'Content-Type': 'application/json' }
},
}),
lambda
)).eql(true)
should(callback.getCall(0).args[1]).containEql({
Expand Down Expand Up @@ -175,8 +195,8 @@ describe('LambdaReq', () => {
const lambda = new LambdaReq(PROXY_EVENT, {}, callback)
lambda.proxy('commandName', handler)
lambda.invoke()
should(handler.calledWith(
{ params: { id: 'u-123' }, headers: undefined },
should(handler.calledWith(sinon.match(
{ params: { id: 'u-123' }, headers: undefined }),
lambda
)).eql(true)
should(callback.getCall(0).args[1]).containEql('{"success":true}')
Expand Down