added tests

This commit is contained in:
Eslam A. Hefnawy 2019-02-27 17:34:29 +03:00
parent e7c5acf6b8
commit 2a8fedc2f3
6 changed files with 429 additions and 2 deletions

View File

@ -283,6 +283,13 @@ describe('#naming()', () => {
});
});
describe('#getWebsocketsAuthorizerLogicalId()', () => {
it('should return the websockets authorizer logical id', () => {
expect(sdk.naming.getWebsocketsAuthorizerLogicalId('auth'))
.to.equal('AuthWebsocketsAuthorizer');
});
});
describe('#getApiGatewayName()', () => {
it('should return the composition of stage & service name if custom name not provided', () => {
serverless.service.service = 'myService';

View File

@ -35,6 +35,7 @@ describe('AwsCompileWebsocketsEvents', () => {
describe('#constructor()', () => {
let compileApiStub;
let compileIntegrationsStub;
let compileAuthorizersStub;
let compilePermissionsStub;
let compileRoutesStub;
let compileDeploymentStub;
@ -45,6 +46,8 @@ describe('AwsCompileWebsocketsEvents', () => {
.stub(awsCompileWebsocketsEvents, 'compileApi').resolves();
compileIntegrationsStub = sinon
.stub(awsCompileWebsocketsEvents, 'compileIntegrations').resolves();
compileAuthorizersStub = sinon
.stub(awsCompileWebsocketsEvents, 'compileAuthorizers').resolves();
compilePermissionsStub = sinon
.stub(awsCompileWebsocketsEvents, 'compilePermissions').resolves();
compileRoutesStub = sinon
@ -58,6 +61,7 @@ describe('AwsCompileWebsocketsEvents', () => {
afterEach(() => {
awsCompileWebsocketsEvents.compileApi.restore();
awsCompileWebsocketsEvents.compileIntegrations.restore();
awsCompileWebsocketsEvents.compileAuthorizers.restore();
awsCompileWebsocketsEvents.compilePermissions.restore();
awsCompileWebsocketsEvents.compileRoutes.restore();
awsCompileWebsocketsEvents.compileDeployment.restore();
@ -91,7 +95,8 @@ describe('AwsCompileWebsocketsEvents', () => {
expect(validateStub.calledOnce).to.be.equal(true);
expect(compileApiStub.calledAfter(validateStub)).to.be.equal(true);
expect(compileIntegrationsStub.calledAfter(compileApiStub)).to.be.equal(true);
expect(compilePermissionsStub.calledAfter(compileIntegrationsStub)).to.be.equal(true);
expect(compileAuthorizersStub.calledAfter(compileIntegrationsStub)).to.be.equal(true);
expect(compilePermissionsStub.calledAfter(compileAuthorizersStub)).to.be.equal(true);
expect(compileRoutesStub.calledAfter(compilePermissionsStub)).to.be.equal(true);
expect(compileDeploymentStub.calledAfter(compileRoutesStub)).to.be.equal(true);
expect(compileStageStub.calledAfter(compileDeploymentStub)).to.be.equal(true);

View File

@ -0,0 +1,109 @@
'use strict';
const expect = require('chai').expect;
const AwsCompileWebsocketsEvents = require('../index');
const Serverless = require('../../../../../../../Serverless');
const AwsProvider = require('../../../../../provider/awsProvider');
describe('#compileAuthorizers()', () => {
let awsCompileWebsocketsEvents;
beforeEach(() => {
const serverless = new Serverless();
serverless.setProvider('aws', new AwsProvider(serverless));
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
awsCompileWebsocketsEvents = new AwsCompileWebsocketsEvents(serverless);
awsCompileWebsocketsEvents.websocketsApiLogicalId
= awsCompileWebsocketsEvents.provider.naming.getWebsocketsApiLogicalId();
});
it('should create an authorizer resource for routes with authorizer definition', () => {
awsCompileWebsocketsEvents.validated = {
events: [
{
functionName: 'First',
route: '$connect',
authorizer: {
name: 'auth',
uri: {
'Fn::Join': ['',
[
'arn:',
{ Ref: 'AWS::Partition' },
':apigateway:',
{ Ref: 'AWS::Region' },
':lambda:path/2015-03-31/functions/',
{ 'Fn::GetAtt': ['AuthLambdaFunction', 'Arn'] },
'/invocations',
],
],
},
identitySource: ['route.request.header.Auth'],
},
},
],
};
return awsCompileWebsocketsEvents.compileAuthorizers().then(() => {
const resources = awsCompileWebsocketsEvents.serverless.service.provider
.compiledCloudFormationTemplate.Resources;
expect(resources).to.deep.equal({
AuthWebsocketsAuthorizer: {
Type: 'AWS::ApiGatewayV2::Authorizer',
Properties: {
ApiId: {
Ref: 'WebsocketsApi',
},
Name: 'auth',
AuthorizerType: 'REQUEST',
AuthorizerUri: {
'Fn::Join': [
'',
[
'arn:',
{
Ref: 'AWS::Partition',
},
':apigateway:',
{
Ref: 'AWS::Region',
},
':lambda:path/2015-03-31/functions/',
{
'Fn::GetAtt': [
'AuthLambdaFunction',
'Arn',
],
},
'/invocations',
],
],
},
IdentitySource: ['route.request.header.Auth'],
},
},
});
});
});
it('should NOT create an authorizer resource for routes with not authorizer definition', () => {
awsCompileWebsocketsEvents.validated = {
events: [
{
functionName: 'First',
route: '$connect',
},
],
};
return awsCompileWebsocketsEvents.compileAuthorizers().then(() => {
const resources = awsCompileWebsocketsEvents.serverless.service.provider
.compiledCloudFormationTemplate.Resources;
expect(resources).to.deep.equal({});
});
});
});

View File

@ -94,4 +94,80 @@ describe('#compilePermissions()', () => {
});
});
});
it('should create a permission resource for authorizer function', () => {
awsCompileWebsocketsEvents.validated = {
events: [
{
functionName: 'First',
route: '$connect',
authorizer: {
name: 'auth',
permission: 'AuthLambdaPermissionWebsockets',
},
},
],
};
return awsCompileWebsocketsEvents.compilePermissions().then(() => {
const resources = awsCompileWebsocketsEvents.serverless.service.provider
.compiledCloudFormationTemplate.Resources;
expect(resources).to.deep.equal({
FirstLambdaPermissionWebsockets: {
Type: 'AWS::Lambda::Permission',
DependsOn: [
'WebsocketsApi',
'FirstLambdaFunction',
],
Properties: {
FunctionName: {
'Fn::GetAtt': [
'FirstLambdaFunction', 'Arn',
],
},
Action: 'lambda:InvokeFunction',
Principal: {
'Fn::Join': [
'',
[
'apigateway.',
{
Ref: 'AWS::URLSuffix',
},
],
],
},
},
},
AuthLambdaPermissionWebsockets: {
Type: 'AWS::Lambda::Permission',
DependsOn: [
'WebsocketsApi',
'AuthLambdaPermissionWebsockets',
],
Properties: {
FunctionName: {
'Fn::GetAtt': [
'AuthLambdaPermissionWebsockets',
'Arn',
],
},
Action: 'lambda:InvokeFunction',
Principal: {
'Fn::Join': [
'',
[
'apigateway.',
{
Ref: 'AWS::URLSuffix',
},
],
],
},
},
},
});
});
});
});

View File

@ -82,4 +82,50 @@ describe('#compileRoutes()', () => {
});
});
});
it('should set authorizer property for the connect route', () => {
awsCompileWebsocketsEvents.validated = {
events: [
{
functionName: 'First',
route: '$connect',
authorizer: {
name: 'auth',
},
},
],
};
return awsCompileWebsocketsEvents.compileRoutes().then(() => {
const resources = awsCompileWebsocketsEvents.serverless.service.provider
.compiledCloudFormationTemplate.Resources;
expect(resources).to.deep.equal({
SconnectWebsocketsRoute: {
Type: 'AWS::ApiGatewayV2::Route',
Properties: {
ApiId: {
Ref: 'WebsocketsApi',
},
RouteKey: '$connect',
AuthorizationType: 'CUSTOM',
AuthorizerId: {
Ref: awsCompileWebsocketsEvents.provider.naming
.getWebsocketsAuthorizerLogicalId('auth'),
},
Target: {
'Fn::Join': [
'/',
[
'integrations', {
Ref: 'FirstWebsocketsIntegration',
},
],
],
},
},
},
});
});
});
});

View File

@ -5,7 +5,7 @@ const AwsCompileWebsocketsEvents = require('../index');
const Serverless = require('../../../../../../../Serverless');
const AwsProvider = require('../../../../../provider/awsProvider');
describe('#validate()', () => {
describe.only('#validate()', () => {
let serverless;
let awsCompileWebsocketsEvents;
@ -59,6 +59,172 @@ describe('#validate()', () => {
]);
});
it('should add authorizer config when authorizer is specified as a string', () => {
awsCompileWebsocketsEvents.serverless.service.functions = {
first: {
events: [
{
websocket: {
route: '$connect',
authorizer: 'auth',
},
},
],
},
};
const validated = awsCompileWebsocketsEvents.validate();
expect(validated.events).to.deep.equal([
{
functionName: 'first',
route: '$connect',
authorizer: {
name: 'auth',
uri: {
'Fn::Join': ['',
[
'arn:',
{ Ref: 'AWS::Partition' },
':apigateway:',
{ Ref: 'AWS::Region' },
':lambda:path/2015-03-31/functions/',
{ 'Fn::GetAtt': ['AuthLambdaFunction', 'Arn'] },
'/invocations',
],
],
},
identitySource: ['route.request.header.Auth'],
permission: 'AuthLambdaFunction',
},
},
]);
});
it('should add authorizer config when authorizer is specified as a string with arn', () => {
awsCompileWebsocketsEvents.serverless.service.functions = {
first: {
events: [
{
websocket: {
route: '$connect',
authorizer: 'arn:aws:auth',
},
},
],
},
};
const validated = awsCompileWebsocketsEvents.validate();
expect(validated.events).to.deep.equal([
{
functionName: 'first',
route: '$connect',
authorizer: {
name: 'auth',
uri: {
'Fn::Join': ['',
[
'arn:',
{ Ref: 'AWS::Partition' },
':apigateway:',
{ Ref: 'AWS::Region' },
':lambda:path/2015-03-31/functions/',
'arn:aws:auth',
'/invocations',
],
],
},
identitySource: ['route.request.header.Auth'],
permission: 'arn:aws:auth',
},
},
]);
});
it('should add authorizer config when authorizer is specified as an object', () => {
awsCompileWebsocketsEvents.serverless.service.functions = {
first: {
events: [
{
websocket: {
route: '$connect',
authorizer: {
name: 'auth',
identitySource: ['route.request.header.Auth', 'route.request.querystring.Auth'],
},
},
},
],
},
};
const validated = awsCompileWebsocketsEvents.validate();
expect(validated.events).to.deep.equal([
{
functionName: 'first',
route: '$connect',
authorizer: {
name: 'auth',
uri: {
'Fn::Join': ['',
[
'arn:',
{ Ref: 'AWS::Partition' },
':apigateway:',
{ Ref: 'AWS::Region' },
':lambda:path/2015-03-31/functions/',
{ 'Fn::GetAtt': ['AuthLambdaFunction', 'Arn'] },
'/invocations',
],
],
},
identitySource: ['route.request.header.Auth', 'route.request.querystring.Auth'],
permission: 'AuthLambdaFunction',
},
},
]);
});
it('should add authorizer config when authorizer is specified as an object with arn', () => {
awsCompileWebsocketsEvents.serverless.service.functions = {
first: {
events: [
{
websocket: {
route: '$connect',
authorizer: {
arn: 'arn:aws:auth',
identitySource: ['route.request.header.Auth', 'route.request.querystring.Auth'],
},
},
},
],
},
};
const validated = awsCompileWebsocketsEvents.validate();
expect(validated.events).to.deep.equal([
{
functionName: 'first',
route: '$connect',
authorizer: {
name: 'auth',
uri: {
'Fn::Join': ['',
[
'arn:',
{ Ref: 'AWS::Partition' },
':apigateway:',
{ Ref: 'AWS::Region' },
':lambda:path/2015-03-31/functions/',
'arn:aws:auth',
'/invocations',
],
],
},
identitySource: ['route.request.header.Auth', 'route.request.querystring.Auth'],
permission: 'arn:aws:auth',
},
},
]);
});
it('should ignore non-websocket events', () => {
awsCompileWebsocketsEvents.serverless.service.functions = {
first: {
@ -86,6 +252,24 @@ describe('#validate()', () => {
expect(() => awsCompileWebsocketsEvents.validate()).to.throw(/set the "route"/);
});
it('should reject an authorizer definition without name nor arn', () => {
awsCompileWebsocketsEvents.serverless.service.functions = {
first: {
events: [
{
websocket: {
route: '$connect',
authorizer: {
identitySource: ['route.request.header.Auth', 'route.request.querystring.Auth'],
},
},
},
],
},
};
expect(() => awsCompileWebsocketsEvents.validate()).to.throw(/You must specify name or arn/);
});
it('should reject a usage of both, http and websocket event types', () => {
awsCompileWebsocketsEvents.serverless.service.functions = {
first: {