-
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 all 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?