Skip to content

Commit bba947e

Browse files
authored
Merge pull request #6 from horike37/setup-cicd
Add test
2 parents 52df11f + b4d0e95 commit bba947e

23 files changed

+4902
-4528
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ lib-cov
1313

1414
# Coverage directory used by tools like istanbul
1515
coverage
16+
.nyc_output
1617

1718
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
1819
.grunt

.travis.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
language: node_js
2+
3+
matrix:
4+
include:
5+
- node_js: '8.9'
6+
- node_js: '10.6'
7+
- node_js: '10.6'
8+
env:
9+
- DISABLE_TESTS=true
10+
- LINTING=true
11+
12+
sudo: false
13+
14+
install:
15+
- travis_retry npm install
16+
17+
script:
18+
- if [[ -z "$DISABLE_TESTS" ]]; then npm run test; fi
19+
- if [[ ! -z "$DISABLE_TESTS" && ! -z "$LINTING" ]]; then npm run lint; fi
20+
21+
after_success:
22+
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
![serverless](http://public.serverless.com/badges/v3.svg)
2+
[![Build Status](https://travis-ci.org/horike37/serverless-apigateway-service-proxy.svg?branch=master)](https://travis-ci.org/horike37/serverless-apigateway-service-proxy) [![npm version](https://badge.fury.io/js/serverless-apigateway-service-proxy.svg)](https://badge.fury.io/js/serverless-apigateway-service-proxy) [![Coverage Status](https://coveralls.io/repos/github/horike37/serverless-apigateway-service-proxy/badge.svg?branch=master)](https://coveralls.io/github/horike37/serverless-apigateway-service-proxy?branch=master) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
23

34
# Serverless APIGateway Service Proxy(BETA)
45
This Serverless Framewrok plugin supports the AWS service proxy integration feature of API Gateway. You can directly connect API Gateway to AWS services without Lambda.

lib/apiGateway/methods.test.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
'use strict'
2+
3+
const chai = require('chai')
4+
const Serverless = require('serverless/lib/Serverless')
5+
const AwsProvider = require('serverless/lib/plugins/aws/provider/awsProvider')
6+
const ServerlessApigatewayServiceProxy = require('./../index')
7+
8+
chai.use(require('chai-as-promised'))
9+
const expect = require('chai').expect
10+
11+
describe('#getAllServiceProxies()', () => {
12+
let serverless
13+
let serverlessApigatewayServiceProxy
14+
15+
beforeEach(() => {
16+
serverless = new Serverless()
17+
serverless.servicePath = true
18+
serverless.service.service = 'apigw-service-proxy'
19+
const options = {
20+
stage: 'dev',
21+
region: 'us-east-1'
22+
}
23+
serverless.setProvider('aws', new AwsProvider(serverless))
24+
serverlessApigatewayServiceProxy = new ServerlessApigatewayServiceProxy(serverless, options)
25+
})
26+
27+
describe('#getMethodResponses()', () => {
28+
it('should return a corresponding methodResponses resource', async () => {
29+
await expect(
30+
serverlessApigatewayServiceProxy.getMethodResponses()
31+
).to.eventually.have.nested.property('Properties.MethodResponses')
32+
})
33+
34+
it('should set Access-Control-Allow-Origin header when cors is true', async () => {
35+
await expect(
36+
serverlessApigatewayServiceProxy.getMethodResponses({
37+
cors: {
38+
origin: '*'
39+
}
40+
})
41+
).to.be.fulfilled.then((json) => {
42+
expect(
43+
json.Properties.MethodResponses[0].ResponseParameters[
44+
'method.response.header.Access-Control-Allow-Origin'
45+
]
46+
).to.equal("'*'")
47+
})
48+
49+
await expect(
50+
serverlessApigatewayServiceProxy.getMethodResponses({
51+
cors: {
52+
origins: ['*', 'http://example.com']
53+
}
54+
})
55+
).to.be.fulfilled.then((json) => {
56+
expect(
57+
json.Properties.MethodResponses[0].ResponseParameters[
58+
'method.response.header.Access-Control-Allow-Origin'
59+
]
60+
).to.equal("'*,http://example.com'")
61+
})
62+
})
63+
})
64+
})

lib/apiGateway/validate.js

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,36 @@ module.exports = {
99
const corsPreflight = {}
1010
await BbPromise.all(
1111
this.getAllServiceProxies().map(async (serviceProxy) => {
12-
Object.keys(serviceProxy).forEach(async (functionName) => {
13-
await this.checkAllowedService(functionName)
14-
const http = serviceProxy[functionName]
15-
http.path = await this.getProxyPath(serviceProxy[functionName])
16-
http.method = await this.getProxyMethod(serviceProxy[functionName])
17-
18-
if (serviceProxy[functionName].cors) {
19-
http.cors = await this.getCors(serviceProxy[functionName])
20-
21-
const cors = corsPreflight[http.path] || {}
22-
23-
cors.headers = _.union(http.cors.headers, cors.headers)
24-
cors.methods = _.union(http.cors.methods, cors.methods)
25-
cors.origins = _.union(http.cors.origins, cors.origins)
26-
cors.origin = http.cors.origin || '*'
27-
cors.allowCredentials = cors.allowCredentials || http.cors.allowCredentials
28-
29-
// when merging, last one defined wins
30-
if (_.has(http.cors, 'maxAge')) {
31-
cors.maxAge = http.cors.maxAge
32-
}
12+
const serviceName = this.getServiceName(serviceProxy)
13+
await this.checkAllowedService(serviceName)
14+
const http = serviceProxy[serviceName]
15+
http.path = await this.getProxyPath(serviceProxy[serviceName], serviceName)
16+
http.method = await this.getProxyMethod(serviceProxy[serviceName], serviceName)
17+
18+
if (serviceProxy[serviceName].cors) {
19+
http.cors = await this.getCors(serviceProxy[serviceName])
20+
21+
const cors = corsPreflight[http.path] || {}
22+
23+
cors.headers = _.union(http.cors.headers, cors.headers)
24+
cors.methods = _.union(http.cors.methods, cors.methods)
25+
cors.origins = _.union(http.cors.origins, cors.origins)
26+
cors.origin = http.cors.origin || '*'
27+
cors.allowCredentials = cors.allowCredentials || http.cors.allowCredentials
28+
29+
// when merging, last one defined wins
30+
if (_.has(http.cors, 'maxAge')) {
31+
cors.maxAge = http.cors.maxAge
32+
}
3333

34-
corsPreflight[http.path] = cors
34+
if (_.has(http.cors, 'cacheControl')) {
35+
cors.cacheControl = http.cors.cacheControl
3536
}
3637

37-
events.push({ functionName, http })
38-
})
38+
corsPreflight[http.path] = cors
39+
}
40+
41+
events.push({ serviceName, http })
3942
})
4043
)
4144
return {
@@ -55,15 +58,20 @@ module.exports = {
5558
}
5659
},
5760

58-
async getProxyPath(proxy) {
59-
if (typeof proxy.path === 'string') {
61+
async getProxyPath(proxy, serviceName) {
62+
if (proxy.path && typeof proxy.path === 'string') {
6063
return proxy.path.replace(/^\//, '').replace(/\/$/, '')
6164
}
62-
return BbPromise.reject(new this.serverless.classes.Error('Invalid service proxy syntax'))
65+
66+
return BbPromise.reject(
67+
new this.serverless.classes.Error(
68+
`Missing or invalid "path" property in ${serviceName} proxy`
69+
)
70+
)
6371
},
6472

65-
async getProxyMethod(proxy) {
66-
if (typeof proxy.method === 'string') {
73+
async getProxyMethod(proxy, serviceName) {
74+
if (proxy.method && typeof proxy.method === 'string') {
6775
const method = proxy.method.toLowerCase()
6876

6977
const allowedMethods = ['get', 'post', 'put', 'patch', 'options', 'head', 'delete', 'any']
@@ -76,7 +84,11 @@ module.exports = {
7684
}
7785
return method
7886
}
79-
return BbPromise.reject(new this.serverless.classes.Error('Invalid service proxy syntax'))
87+
return BbPromise.reject(
88+
new this.serverless.classes.Error(
89+
`Missing or invalid "method" property in ${serviceName} proxy`
90+
)
91+
)
8092
},
8193

8294
async getCors(proxy) {
@@ -130,6 +142,13 @@ module.exports = {
130142
if (cors.methods.indexOf(proxy.method.toUpperCase()) === NOT_FOUND) {
131143
cors.methods.push(proxy.method.toUpperCase())
132144
}
145+
146+
if (_.has(cors, 'maxAge')) {
147+
if (!_.isInteger(cors.maxAge) || cors.maxAge < 1) {
148+
const errorMessage = 'maxAge should be an integer over 0'
149+
return BbPromise.reject(new this.serverless.classes.Error(errorMessage))
150+
}
151+
}
133152
} else {
134153
cors.methods.push(proxy.method.toUpperCase())
135154
}

0 commit comments

Comments
 (0)