mirror of
https://github.com/serverless/serverless.git
synced 2026-02-01 16:07:28 +00:00
Merge pull request #2456 from serverless/add-additional-api-gateway-tests-for-lambda-proxy-integration
Add additional API Gateway tests for lambda proxy integration
This commit is contained in:
commit
afbf7a1b20
@ -14,6 +14,9 @@ require('./aws/api-gateway/integration-lambda/cors/tests');
|
||||
require('./aws/api-gateway/integration-lambda/api-keys/tests');
|
||||
// Integration: Lambda Proxy
|
||||
require('./aws/api-gateway/integration-lambda-proxy/simple-api/tests');
|
||||
require('./aws/api-gateway/integration-lambda-proxy/custom-authorizers/tests');
|
||||
require('./aws/api-gateway/integration-lambda-proxy/cors/tests');
|
||||
require('./aws/api-gateway/integration-lambda-proxy/api-keys/tests');
|
||||
|
||||
// Schedule
|
||||
require('./aws/schedule/multiple-schedules-multiple-functions/tests');
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
module.exports.hello = (event, context, callback) => {
|
||||
const response = {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify({
|
||||
message: 'Hello from API Gateway!',
|
||||
event,
|
||||
}),
|
||||
};
|
||||
|
||||
callback(null, response);
|
||||
};
|
||||
@ -0,0 +1,16 @@
|
||||
service: aws-nodejs # NOTE: update this with your service name
|
||||
|
||||
provider:
|
||||
name: aws
|
||||
runtime: nodejs4.3
|
||||
apiKeys:
|
||||
- WillBeReplacedBeforeDeployment
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
events:
|
||||
- http:
|
||||
path: hello
|
||||
method: GET
|
||||
private: true
|
||||
@ -0,0 +1,85 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const expect = require('chai').expect;
|
||||
const BbPromise = require('bluebird');
|
||||
const execSync = require('child_process').execSync;
|
||||
const AWS = require('aws-sdk');
|
||||
const _ = require('lodash');
|
||||
const fetch = require('node-fetch');
|
||||
const fse = require('fs-extra');
|
||||
const crypto = require('crypto');
|
||||
|
||||
const Utils = require('../../../../../utils/index');
|
||||
|
||||
const CF = new AWS.CloudFormation({ region: 'us-east-1' });
|
||||
const APIG = new AWS.APIGateway({ region: 'us-east-1' });
|
||||
BbPromise.promisifyAll(CF, { suffix: 'Promised' });
|
||||
BbPromise.promisifyAll(APIG, { suffix: 'Promised' });
|
||||
|
||||
describe('AWS - API Gateway (Integration: Lambda Proxy): API keys test', function () {
|
||||
this.timeout(0);
|
||||
|
||||
let stackName;
|
||||
let endpoint;
|
||||
let apiKey;
|
||||
|
||||
before(() => {
|
||||
stackName = Utils.createTestService('aws-nodejs', path.join(__dirname, 'service'));
|
||||
|
||||
// replace name of the API key with something unique
|
||||
const serverlessYmlFilePath = path.join(process.cwd(), 'serverless.yml');
|
||||
let serverlessYmlFileContent = fse.readFileSync(serverlessYmlFilePath).toString();
|
||||
|
||||
const apiKeyName = crypto.randomBytes(8).toString('hex');
|
||||
|
||||
serverlessYmlFileContent = serverlessYmlFileContent
|
||||
.replace(/WillBeReplacedBeforeDeployment/, apiKeyName);
|
||||
|
||||
fse.writeFileSync(serverlessYmlFilePath, serverlessYmlFileContent);
|
||||
|
||||
Utils.deployService();
|
||||
});
|
||||
|
||||
it('should expose the endpoint(s) in the CloudFormation Outputs', () =>
|
||||
CF.describeStacksPromised({ StackName: stackName })
|
||||
.then((result) => _.find(result.Stacks[0].Outputs,
|
||||
{ OutputKey: 'ServiceEndpoint' }).OutputValue)
|
||||
.then((endpointOutput) => {
|
||||
endpoint = endpointOutput.match(/https:\/\/.+\.execute-api\..+\.amazonaws\.com.+/)[0];
|
||||
endpoint = `${endpoint}/hello`;
|
||||
})
|
||||
);
|
||||
|
||||
it('should expose the API key(s) with its values when running the info command', () => {
|
||||
const info = execSync(`${Utils.serverlessExec} info`);
|
||||
|
||||
const stringifiedOutput = (new Buffer(info, 'base64').toString());
|
||||
|
||||
// some regex magic to extract the first API key value from the info output
|
||||
apiKey = stringifiedOutput.match(/(api keys:\n)(\s*)(.+):(\s*)(.+)/)[5];
|
||||
|
||||
expect(apiKey.length).to.be.above(0);
|
||||
});
|
||||
|
||||
it('should reject a request with an invalid API Key', () =>
|
||||
fetch(endpoint)
|
||||
.then((response) => {
|
||||
expect(response.status).to.equal(403);
|
||||
})
|
||||
);
|
||||
|
||||
it('should succeed if correct API key is given', () =>
|
||||
fetch(endpoint, { headers: { 'x-api-key': apiKey } })
|
||||
.then(response => response.json())
|
||||
.then((json) => {
|
||||
expect(json.message).to.equal('Hello from API Gateway!');
|
||||
expect(json.event.requestContext.identity.apiKey).to.equal(apiKey);
|
||||
expect(json.event.headers['x-api-key']).to.equal(apiKey);
|
||||
})
|
||||
);
|
||||
|
||||
after(() => {
|
||||
Utils.removeService();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
module.exports.hello = (event, context, callback) => {
|
||||
const response = {
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
message: 'Hello from API Gateway!',
|
||||
input: event,
|
||||
}),
|
||||
};
|
||||
|
||||
callback(null, response);
|
||||
};
|
||||
@ -0,0 +1,26 @@
|
||||
service: aws-nodejs # NOTE: update this with your service name
|
||||
|
||||
provider:
|
||||
name: aws
|
||||
runtime: nodejs4.3
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
events:
|
||||
- http:
|
||||
method: GET
|
||||
path: simple-cors
|
||||
cors: true
|
||||
- http:
|
||||
method: GET
|
||||
path: complex-cors
|
||||
cors:
|
||||
origins:
|
||||
- '*'
|
||||
headers:
|
||||
- Content-Type
|
||||
- X-Amz-Date
|
||||
- Authorization
|
||||
- X-Api-Key
|
||||
- X-Amz-Security-Token
|
||||
@ -0,0 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const expect = require('chai').expect;
|
||||
const BbPromise = require('bluebird');
|
||||
const AWS = require('aws-sdk');
|
||||
const _ = require('lodash');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
const Utils = require('../../../../../utils/index');
|
||||
|
||||
const CF = new AWS.CloudFormation({ region: 'us-east-1' });
|
||||
BbPromise.promisifyAll(CF, { suffix: 'Promised' });
|
||||
|
||||
describe('AWS - API Gateway (Integration: Lambda Proxy): CORS test', function () {
|
||||
this.timeout(0);
|
||||
|
||||
let stackName;
|
||||
let endpointBase;
|
||||
|
||||
before(() => {
|
||||
stackName = Utils.createTestService('aws-nodejs', path.join(__dirname, 'service'));
|
||||
Utils.deployService();
|
||||
});
|
||||
|
||||
it('should expose the endpoint(s) in the CloudFormation Outputs', () =>
|
||||
CF.describeStacksPromised({ StackName: stackName })
|
||||
.then((result) => _.find(result.Stacks[0].Outputs,
|
||||
{ OutputKey: 'ServiceEndpoint' }).OutputValue)
|
||||
.then((endpointOutput) => {
|
||||
endpointBase = endpointOutput.match(/https:\/\/.+\.execute-api\..+\.amazonaws\.com.+/)[0];
|
||||
})
|
||||
);
|
||||
|
||||
it('should setup CORS support with simple string config', () =>
|
||||
fetch(`${endpointBase}/simple-cors`, { method: 'OPTIONS' })
|
||||
.then((response) => {
|
||||
const headers = response.headers;
|
||||
|
||||
expect(headers.get('access-control-allow-headers'))
|
||||
.to.equal('Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token');
|
||||
expect(headers.get('access-control-allow-methods')).to.equal('OPTIONS,GET');
|
||||
expect(headers.get('access-control-allow-origin')).to.equal('*');
|
||||
})
|
||||
);
|
||||
|
||||
it('should setup CORS support with complex object config', () =>
|
||||
fetch(`${endpointBase}/complex-cors`, { method: 'OPTIONS' })
|
||||
.then((response) => {
|
||||
const headers = response.headers;
|
||||
|
||||
expect(headers.get('access-control-allow-headers'))
|
||||
.to.equal('Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token');
|
||||
expect(headers.get('access-control-allow-methods')).to.equal('OPTIONS,GET');
|
||||
expect(headers.get('access-control-allow-origin')).to.equal('*');
|
||||
})
|
||||
);
|
||||
|
||||
after(() => {
|
||||
Utils.removeService();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,45 @@
|
||||
'use strict';
|
||||
|
||||
const generatePolicy = (principalId, effect, resource) => {
|
||||
const authResponse = {};
|
||||
authResponse.principalId = principalId;
|
||||
|
||||
if (effect && resource) {
|
||||
const policyDocument = {};
|
||||
policyDocument.Version = '2012-10-17';
|
||||
policyDocument.Statement = [];
|
||||
|
||||
const statementOne = {};
|
||||
statementOne.Action = 'execute-api:Invoke';
|
||||
statementOne.Effect = effect;
|
||||
statementOne.Resource = resource;
|
||||
policyDocument.Statement[0] = statementOne;
|
||||
authResponse.policyDocument = policyDocument;
|
||||
}
|
||||
|
||||
return authResponse;
|
||||
};
|
||||
|
||||
// protected function
|
||||
module.exports.hello = (event, context, callback) => {
|
||||
const response = {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify({
|
||||
message: 'Successfully authorized!',
|
||||
event,
|
||||
}),
|
||||
};
|
||||
|
||||
callback(null, response);
|
||||
};
|
||||
|
||||
// auth function
|
||||
module.exports.auth = (event, context) => {
|
||||
const token = event.authorizationToken.split(' ');
|
||||
|
||||
if (token[0] === 'Bearer' && token[1] === 'ShouldBeAuthorized') {
|
||||
context.succeed(generatePolicy('SomeRandomId', 'Allow', '*'));
|
||||
}
|
||||
|
||||
context.fail('Unauthorized');
|
||||
};
|
||||
@ -0,0 +1,16 @@
|
||||
service: aws-nodejs # NOTE: update this with your service name
|
||||
|
||||
provider:
|
||||
name: aws
|
||||
runtime: nodejs4.3
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
events:
|
||||
- http:
|
||||
path: hello
|
||||
method: GET
|
||||
authorizer: auth
|
||||
auth:
|
||||
handler: handler.auth
|
||||
@ -0,0 +1,63 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const expect = require('chai').expect;
|
||||
const BbPromise = require('bluebird');
|
||||
const AWS = require('aws-sdk');
|
||||
const _ = require('lodash');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
const Utils = require('../../../../../utils/index');
|
||||
|
||||
const CF = new AWS.CloudFormation({ region: 'us-east-1' });
|
||||
BbPromise.promisifyAll(CF, { suffix: 'Promised' });
|
||||
|
||||
describe('AWS - API Gateway (Integration: Lambda Proxy): Custom authorizers test', function () {
|
||||
this.timeout(0);
|
||||
|
||||
let stackName;
|
||||
let endpoint;
|
||||
|
||||
before(() => {
|
||||
stackName = Utils.createTestService('aws-nodejs', path.join(__dirname, 'service'));
|
||||
Utils.deployService();
|
||||
});
|
||||
|
||||
it('should expose the endpoint(s) in the CloudFormation Outputs', () =>
|
||||
CF.describeStacksPromised({ StackName: stackName })
|
||||
.then((result) => _.find(result.Stacks[0].Outputs,
|
||||
{ OutputKey: 'ServiceEndpoint' }).OutputValue)
|
||||
.then((endpointOutput) => {
|
||||
endpoint = endpointOutput.match(/https:\/\/.+\.execute-api\..+\.amazonaws\.com.+/)[0];
|
||||
endpoint = `${endpoint}/hello`;
|
||||
})
|
||||
);
|
||||
|
||||
it('should reject requests without authorization', () =>
|
||||
fetch(endpoint)
|
||||
.then((response) => {
|
||||
expect(response.status).to.equal(401);
|
||||
})
|
||||
);
|
||||
|
||||
it('should reject requests with wrong authorization', () =>
|
||||
fetch(endpoint, { headers: { Authorization: 'Bearer ShouldNotBeAuthorized' } })
|
||||
.then((response) => {
|
||||
expect(response.status).to.equal(401);
|
||||
})
|
||||
);
|
||||
|
||||
it('should authorize requests with correct authorization', () =>
|
||||
fetch(endpoint, { headers: { Authorization: 'Bearer ShouldBeAuthorized' } })
|
||||
.then(response => response.json())
|
||||
.then((json) => {
|
||||
expect(json.message).to.equal('Successfully authorized!');
|
||||
expect(json.event.requestContext.authorizer.principalId).to.equal('SomeRandomId');
|
||||
expect(json.event.headers.Authorization).to.equal('Bearer ShouldBeAuthorized');
|
||||
})
|
||||
);
|
||||
|
||||
after(() => {
|
||||
Utils.removeService();
|
||||
});
|
||||
});
|
||||
@ -10,7 +10,4 @@ module.exports.hello = (event, context, callback) => {
|
||||
};
|
||||
|
||||
callback(null, response);
|
||||
|
||||
// Use this code if you don't use the http event with the LAMBDA-PROXY integration
|
||||
// callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event });
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user