Skip to content

Commit

Permalink
fix: Wrap native string responses from lambda invocation endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
fernyettheplant authored Sep 13, 2021
1 parent 77b3659 commit 3bd294b
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 1 deletion.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@
"Vasiliy Solovey (https://github.com/miltador)",
"Dima Krutolianov (https://github.com/dimadk24)",
"Bryan Vaz (https://github.com/bryanvaz)",
"Justin Ng (https://github.com/njyjn)"
"Justin Ng (https://github.com/njyjn)",
"Fernando Alvarez (https://github.com/jefer590)"
],
"engines": {
"node": ">=12.0.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { resolve } from 'path'
import LambdaFunction from '../../../LambdaFunction.js'

export default class LambdaFunctionThatReturnsJSONObject {
options = {}
serverless = {
config: {
serverlessPath: '',
servicePath: resolve(__dirname),
},
service: {
provider: {
runtime: 'nodejs12.x',
},
},
}

listFunctionNames() {
return ['foo']
}

getByFunctionName(functionName) {
const functionDefinition = {
handler:
'../../fixtures/lambdaFunction.fixture.asyncFunctionHandlerObject',
}

return new LambdaFunction(
functionName,
functionDefinition,
this.serverless,
this.options,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { resolve } from 'path'
import LambdaFunction from '../../../LambdaFunction.js'

export default class LambdaFunctionThatReturnsNativeString {
options = {}
serverless = {
config: {
serverlessPath: '',
servicePath: resolve(__dirname),
},
service: {
provider: {
runtime: 'nodejs12.x',
},
},
}

listFunctionNames() {
return ['foo']
}

getByFunctionName(functionName) {
const functionDefinition = {
handler: '../../fixtures/lambdaFunction.fixture.asyncFunctionHandler',
}

return new LambdaFunction(
functionName,
functionDefinition,
this.serverless,
this.options,
)
}
}
6 changes: 6 additions & 0 deletions src/lambda/__tests__/fixtures/lambdaFunction.fixture.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ exports.asyncFunctionHandler = async function asyncFunctionHandler() {
return 'foo'
}

exports.asyncFunctionHandlerObject = async function asyncFunctionHandler() {
return {
foo: 'bar',
}
}

// we deliberately test the case where a 'callback' is defined
// in the handler, but a promise is being returned to protect from a
// potential naive implementation, e.g.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import InvocationsController from '../../../routes/invocations/InvocationsController.js'
import LambdaFunctionThatReturnsJSONObject from '../../fixtures/Lambda/LambdaFunctionThatReturnsJSONObject.fixture.js'
import LambdaFunctionThatReturnsNativeString from '../../fixtures/Lambda/LambdaFunctionThatReturnsNativeString.fixture.js'

jest.mock('../../../../serverlessLog')

describe('InvocationController', () => {
const functionName = 'foo'

describe('when event type is "RequestResponse"', () => {
const eventType = 'RequestResponse'

test('should return json object if lambda response is json', async () => {
const expected = {
Payload: {
foo: 'bar',
},
StatusCode: 200,
}

const invocationController = new InvocationsController(
new LambdaFunctionThatReturnsJSONObject(),
)
const result = await invocationController.invoke(functionName, eventType)

expect(result).toStrictEqual(expected)
})

test('should wrap native string responses with ""', async () => {
const expected = {
Payload: '"foo"',
StatusCode: 200,
}

const invocationController = new InvocationsController(
new LambdaFunctionThatReturnsNativeString(),
)
const result = await invocationController.invoke(functionName, eventType)

expect(result).toStrictEqual(expected)
})
})
})
8 changes: 8 additions & 0 deletions src/lambda/routes/invocations/InvocationsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ export default class InvocationsController {
// RequestTooLargeException, InvalidParameterValueException,
// and whatever response is thrown when the response is too large.
}

// Checking if the result of the Lambda Invoke is a primitive string to wrap it. this is for future post-processing such as Step Functions Tasks
if (result) {
if (typeof result === 'string') {
result = `"${result}"`
}
}

// result is actually the Payload.
// So return in a standard structure so Hapi can
// respond with the correct status codes
Expand Down

0 comments on commit 3bd294b

Please sign in to comment.