Skip to content

Commit 173ce1d

Browse files
committed
update api wrapper signature for easier testing in apps
1 parent 218f0b0 commit 173ce1d

File tree

14 files changed

+257
-178
lines changed

14 files changed

+257
-178
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html)
66

7+
## [1.0.7]  (2019-09-04)
8+
9+
### Changed
10+
11+
- Update the api wrapper signature for easier testing in applications
12+
713
## [1.0.1]  (2019-09-04)
814

915
### Fixed
@@ -32,5 +38,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/),
3238
- Update older libraries
3339
- Now publish from Git tags instead of master pushes
3440

41+
[1.0.7]: https://github.com/manwaring/lambda-wrapper/compare/v1.0.1...v1.0.7
3542
[1.0.1]: https://github.com/manwaring/lambda-wrapper/compare/v1.0.0...v1.0.1
3643
[1.0.0]: https://github.com/manwaring/lambda-wrapper/compare/v0.3.8...v1.0.0

__mocks__/@iopipe/iopipe.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

__mocks__/epsagon.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"name": "@manwaring/lambda-wrapper",
33
"description": "A lambda handler wrapper to abstract common functionality and provide useful defaults",
4-
"version": "1.0.6",
4+
"version": "1.0.7",
55
"scripts": {
66
"publish-please-dry-run": "publish-please --dry-run",
77
"publish-please": "publish-please",
88
"prepublishOnly": "publish-please guard && npm run build",
99
"build": "rimraf dist && tsc -p ./tsconfig.build.json",
1010
"test": "jest --coverage",
11+
"watch-tests": "jest --watch",
1112
"codecov": "codecov -f coverage/*.json"
1213
},
1314
"dependencies": {

src/api/responses.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ describe('API responses', () => {
55
const metrics = new Metrics('API Gateway');
66
const callback = jest.fn((err, result) => (err ? new Error(err) : result));
77

8-
beforeEach(() => jest.resetAllMocks());
8+
beforeEach(() => {
9+
jest.resetAllMocks();
10+
});
911

1012
it('Handles success response', () => {
1113
const success = successWrapper(metrics, callback);

src/api/wrapper.test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,20 @@ describe('API wrapper', () => {
99
queryStringParameters: { name: 'a test' },
1010
headers: { 'content-type': 'application/json', 'Test-Request': 'true' }
1111
});
12-
const context = {};
12+
const context = {
13+
callbackWaitsForEmptyEventLoop: false,
14+
functionName: 'function-name',
15+
functionVersion: '$LATEST',
16+
invokedFunctionArn: 'arn:',
17+
memoryLimitInMB: 128,
18+
awsRequestId: 'request',
19+
logGroupName: 'group',
20+
logStreamName: 'stream',
21+
getRemainingTimeInMillis: () => 2,
22+
done: () => {},
23+
fail: () => {},
24+
succeed: () => {}
25+
};
1326
const callback = jest.fn((err, result) => (err ? new Error(err) : result));
1427

1528
it('Has expected properties and response functions', () => {
@@ -39,7 +52,6 @@ describe('API wrapper', () => {
3952
expect(error).toBeInstanceOf(Function);
4053
success('success');
4154
}
42-
// @ts-ignore
4355
api(mockHandler)(requestEvent, context, callback);
4456
});
4557
});

src/api/wrapper.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import { successWrapper, invalidWrapper, errorWrapper, redirectWrapper } from '.
55

66
const metrics = new Metrics('API Gateway');
77

8-
export function api<T extends Function>(fn: T): T {
9-
return <any>function(event: APIGatewayEvent, context: Context, callback: Callback) {
10-
// const responses = new Responses(metrics, callback).getResponses();
8+
export function api(
9+
custom: (props: ApiSignature) => any
10+
): (event: APIGatewayEvent, context: Context, callback: Callback) => any {
11+
return function handler(event: APIGatewayEvent, context: Context, callback: Callback) {
1112
const { body, path, query, auth, headers, testRequest } = new Request(event).getProperties();
1213

13-
const signature: ApiSignature = {
14+
const signature = {
1415
event,
1516
body,
1617
path,
@@ -23,7 +24,7 @@ export function api<T extends Function>(fn: T): T {
2324
error: errorWrapper(metrics, callback),
2425
redirect: redirectWrapper(metrics, callback)
2526
};
26-
return fn(signature);
27+
return custom(signature);
2728
};
2829
}
2930

src/common/environment.test.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
import { isRunningInAwsLambdaEnvironment } from './environment';
1+
import { isRunningInAwsLambdaEnvironment, EXPECTED_ENV_VARS } from './environment';
2+
3+
export const FULL_LAMBDA_RUNTIME = {
4+
_HANDLER: 'index.handler',
5+
AWS_REGION: 'us-east-1',
6+
AWS_EXECUTION_ENV: 'AWS_Lambda_nodejs10.x',
7+
AWS_LAMBDA_FUNCTION_NAME: 'sample-function-name',
8+
AWS_LAMBDA_FUNCTION_MEMORY_SIZE: '128',
9+
AWS_LAMBDA_FUNCTION_VERSION: '$LATEST',
10+
LAMBDA_TASK_ROOT: '/var/task',
11+
LAMBDA_RUNTIME_DIR: '/var/runtime'
12+
};
213

314
describe('Runtime environment determination', () => {
415
const ORIGINAL_ENVS = process.env;
5-
const FULL_LAMBDA_RUNTIME = {
6-
_HANDLER: 'index.handler',
7-
AWS_REGION: 'us-east-1',
8-
AWS_EXECUTION_ENV: 'AWS_Lambda_nodejs10.x',
9-
AWS_LAMBDA_FUNCTION_NAME: 'sample-function-name',
10-
AWS_LAMBDA_FUNCTION_MEMORY_SIZE: '128',
11-
AWS_LAMBDA_FUNCTION_VERSION: '$LATEST',
12-
LAMBDA_TASK_ROOT: '/var/task',
13-
LAMBDA_RUNTIME_DIR: '/var/runtime'
14-
};
1516

1617
beforeEach(() => {
1718
jest.resetModules();
1819
process.env = { ...ORIGINAL_ENVS };
20+
console.debug = jest.fn();
1921
});
2022

2123
it('Default environment is recognized as not AWS Lambda runtime', () => {
@@ -29,9 +31,21 @@ describe('Runtime environment determination', () => {
2931

3032
it('Partially modified environment is not recognized as AWS Lambda runtime', () => {
3133
// Delete a random property from the lambda runtime object
32-
const keys = Object.keys(FULL_LAMBDA_RUNTIME);
33-
delete FULL_LAMBDA_RUNTIME[keys[(Math.random() * keys.length) << 0]];
3434
process.env = { ...ORIGINAL_ENVS, ...FULL_LAMBDA_RUNTIME };
35+
const varToRemove = EXPECTED_ENV_VARS[(Math.random() * EXPECTED_ENV_VARS.length) << 0];
36+
delete process.env[varToRemove];
37+
expect(isRunningInAwsLambdaEnvironment()).toBe(false);
38+
});
39+
40+
it('Logs about why not recognized as AWS Lambda runtime given proper DEBUG flag', () => {
41+
// Delete a random property from the lambda runtime object
42+
process.env = { ...ORIGINAL_ENVS, ...FULL_LAMBDA_RUNTIME, ...{ DEBUG: 'true' } };
43+
const varToRemove = EXPECTED_ENV_VARS[(Math.random() * EXPECTED_ENV_VARS.length) << 0];
44+
delete process.env[varToRemove];
3545
expect(isRunningInAwsLambdaEnvironment()).toBe(false);
46+
expect(console.debug).toHaveBeenCalledWith(
47+
'Code is not running in an AWS Lambda Environment, missing the following environment variables:',
48+
[varToRemove]
49+
);
3650
});
3751
});

src/common/environment.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1+
export const EXPECTED_ENV_VARS = [
2+
'_HANDLER',
3+
'AWS_REGION',
4+
'AWS_EXECUTION_ENV',
5+
'AWS_LAMBDA_FUNCTION_NAME',
6+
'AWS_LAMBDA_FUNCTION_MEMORY_SIZE',
7+
'AWS_LAMBDA_FUNCTION_VERSION',
8+
'LAMBDA_TASK_ROOT',
9+
'LAMBDA_RUNTIME_DIR'
10+
];
11+
112
export function isRunningInAwsLambdaEnvironment(): boolean {
2-
const {
3-
_HANDLER,
4-
AWS_REGION,
5-
AWS_EXECUTION_ENV,
6-
AWS_LAMBDA_FUNCTION_NAME,
7-
AWS_LAMBDA_FUNCTION_MEMORY_SIZE,
8-
AWS_LAMBDA_FUNCTION_VERSION,
9-
LAMBDA_TASK_ROOT,
10-
LAMBDA_RUNTIME_DIR
11-
} = process.env;
12-
return (
13-
!!_HANDLER &&
14-
!!AWS_REGION &&
15-
!!AWS_EXECUTION_ENV &&
16-
!!AWS_LAMBDA_FUNCTION_NAME &&
17-
!!AWS_LAMBDA_FUNCTION_MEMORY_SIZE &&
18-
!!AWS_LAMBDA_FUNCTION_VERSION &&
19-
!!LAMBDA_TASK_ROOT &&
20-
!!LAMBDA_RUNTIME_DIR
21-
);
13+
const missingEnvVars = EXPECTED_ENV_VARS.filter(expected => !process.env[expected]);
14+
if (missingEnvVars.length > 0 && process.env.DEBUG) {
15+
console.debug(
16+
'Code is not running in an AWS Lambda Environment, missing the following environment variables:',
17+
missingEnvVars
18+
);
19+
}
20+
return missingEnvVars.length === 0;
2221
}

0 commit comments

Comments
 (0)