-
Notifications
You must be signed in to change notification settings - Fork 4
Fix headers; Small improvements; Add integration tests; #20
base: master
Are you sure you want to change the base?
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,3 +60,6 @@ typings/ | |
| # dotenv environment variables file | ||
| .env | ||
|
|
||
| # IDE | ||
| .idea/ | ||
|
|
||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
|
||
| exports[`fetches google.com 1`] = ` | ||
| Object { | ||
| "status": 200, | ||
| "statusText": "OK", | ||
| "url": "https://www.google.com/", | ||
| } | ||
| `; | ||
|
|
||
| exports[`returns error when href is invalid 1`] = ` | ||
| Object { | ||
| "error": Object { | ||
| "message": "Only absolute URLs are supported", | ||
| }, | ||
| } | ||
| `; | ||
|
|
||
| exports[`returns error when href is not passed 1`] = ` | ||
| Object { | ||
| "error": Object { | ||
| "message": "Cannot read property 'href' of null", | ||
| }, | ||
| } | ||
| `; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| const childProcess = require('child_process'); | ||
| const fetch = require('node-fetch'); | ||
|
|
||
| let samProcess; | ||
| const port = 5000; | ||
| let lambdaUrl = `http://127.0.0.1:${port}/`; | ||
| function localApiStarted(processOutput) { | ||
| // Example output when local function started - "Running on http://127.0.0.1:5000/" | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| const urlRegex = /(Running on )(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*))/gm; | ||
| const matches = urlRegex.exec(processOutput); | ||
| return matches && matches.length >= 3; | ||
| } | ||
|
|
||
| function startLambda(done) { | ||
| samProcess = childProcess.spawn( | ||
| 'sam', | ||
| ['local', 'start-api', '--port', port] | ||
| ); | ||
| // The runtime output (for example, logs) is output to stderr, and the Lambda function result is output to stdout. | ||
| // https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html | ||
| samProcess.stderr.on('data', data => { | ||
| if (localApiStarted(data.toString())) { | ||
| done(); | ||
| } | ||
| }); | ||
| samProcess.on('error', error => { | ||
| done(new Error(`SAM invoke error: ${error}`)); | ||
| }); | ||
| } | ||
|
|
||
| function stopLambda() { | ||
| samProcess.kill(); | ||
| } | ||
|
|
||
| beforeAll((done) => { | ||
| startLambda(done); | ||
| }); | ||
|
|
||
| afterAll(() => { | ||
| stopLambda(); | ||
| }); | ||
|
|
||
| test('returns error when href is not passed', (done) => { | ||
| fetch(`${lambdaUrl}`) | ||
| .then(res => { | ||
| expect(res.status).toEqual(500); | ||
| return res.json(); | ||
| }) | ||
| .then(res => { | ||
| expect(res).toMatchSnapshot(); | ||
| done(); | ||
| }); | ||
| }); | ||
|
|
||
| test('returns error when href is invalid', (done) => { | ||
| const qs = new URLSearchParams({ href: 'google.com' }); | ||
| fetch(`${lambdaUrl}?${qs}`) | ||
| .then(res => { | ||
| expect(res.status).toEqual(500); | ||
| return res.json(); | ||
| }) | ||
| .then(res => { | ||
| expect(res).toMatchSnapshot(); | ||
| done(); | ||
| }); | ||
| }); | ||
|
|
||
| test('fetches google.com', (done) => { | ||
| const qs = new URLSearchParams({ href: 'https://google.com' }); | ||
| fetch(`${lambdaUrl}?${qs}`) | ||
| .then(res => { | ||
| expect(res.status).toEqual(200); | ||
| return res.json(); | ||
| }) | ||
| .then(res => { | ||
| expect(res).toMatchSnapshot(); | ||
| done(); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| module.exports = { | ||
| testEnvironment: 'node', | ||
| testMatch: [ | ||
| '**/integration/**/*.test.js' | ||
| ], | ||
| "rootDir": "./" | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,9 @@ | |
| "test:debug": "echo '/*' && echo ' Navigate to about:inspect in Chrome' && echo '*/' && node --inspect node_modules/.bin/jest --runInBand", | ||
| "test:ci": "CI=true jest --verbose=false --config ./jest.config.js", | ||
| "test:watch": "jest --watch --verbose=false --config ./jest.config.js", | ||
| "start": "sam local start-api --port 5000", | ||
| "test:integration": "npm run build && jest --verbose=false --config ./jest.config.integration.js", | ||
| "test:watch:integration": "npm run build && jest --watch --verbose=false --config ./jest.config.integration.js", | ||
| "start": "sam local start-api --port 5000 2>&1 | tr \"\\r\" \"\\n\"", | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added this part |
||
| "dist": "rm -f dist.zip && zip -jq dist.zip build/index.js", | ||
| "update": "aws lambda update-function-code --function-name FooBarExample --zip-file fileb://dist.zip --publish", | ||
| "deploy": "npm run build && npm run test:ci && npm run dist && npm run update" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,27 @@ | ||
| import fetch from 'node-fetch'; | ||
|
|
||
| exports.handler = async (event, context, callback) => { | ||
| // Request headers for a mock 200 response | ||
| const request = fetch(decodeURIComponent(event.queryStringParameters.href), { | ||
| method: 'HEAD' | ||
| }); | ||
| function createResponse(statusCode, body) { | ||
| return { | ||
| statusCode: statusCode, | ||
| headers: {'Content-Type': 'application/json'}, | ||
| body: JSON.stringify(body) | ||
| } | ||
| } | ||
|
|
||
| let data; | ||
| exports.handler = async ({queryStringParameters}, context) => { | ||
| // TODO: Validate body or query params with some kind of json schema. AJV? | ||
| try { | ||
| const response = await request; | ||
| // Request headers for a mock 200 response | ||
| const response = await fetch(decodeURIComponent(queryStringParameters.href), { | ||
| method: 'HEAD' | ||
| }); | ||
|
|
||
| data = { | ||
| return createResponse(200, { | ||
| url: response.url, | ||
| status: response.status, | ||
| statusText: response.statusText | ||
| }; | ||
| } catch (e) { | ||
| console.log(e); | ||
| }); | ||
| } catch (error) { | ||
| return createResponse(500, {error: {message: error.message}}); | ||
| } | ||
|
|
||
| return callback(null, { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When function is |
||
| statusCode: 200, | ||
| header: { | ||
| 'Content-Type': 'application/json' | ||
| }, | ||
| body: JSON.stringify(data) | ||
| }); | ||
| } | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this port is used only for local development, but does it make sense to come from an environment variable, from
.envfile or something?