UNPKG

serverless

Version:

Serverless Framework - Build web, mobile and IoT applications with serverless architectures using AWS Lambda, Azure Functions, Google CloudFunctions & more

1,209 lines (1,167 loc) • 39.3 kB
'use strict'; /* eslint-disable no-unused-expressions */ const sinon = require('sinon'); const chai = require('chai'); const BbPromise = require('bluebird'); const childProcess = BbPromise.promisifyAll(require('child_process')); const proxyquire = require('proxyquire').noCallThru(); const AwsProvider = require('../../../../provider/awsProvider'); const Serverless = require('../../../../../../Serverless'); const runServerless = require('../../../../../../../test/utils/run-serverless'); const { expect } = chai; chai.use(require('sinon-chai')); chai.use(require('chai-as-promised')); describe('AwsCompileEventBridgeEvents', () => { let serverless; let awsCompileEventBridgeEvents; let addCustomResourceToServiceStub; beforeEach(() => { addCustomResourceToServiceStub = sinon.stub().resolves(); const AwsCompileEventBridgeEvents = proxyquire('./index', { '../../../../customResources': { addCustomResourceToService: addCustomResourceToServiceStub, }, }); serverless = new Serverless(); serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} }; serverless.setProvider('aws', new AwsProvider(serverless)); awsCompileEventBridgeEvents = new AwsCompileEventBridgeEvents(serverless); awsCompileEventBridgeEvents.serverless.service.service = 'new-service'; }); describe('#constructor()', () => { it('should set the provider variable to an instance of AwsProvider', () => expect(awsCompileEventBridgeEvents.provider).to.be.instanceof(AwsProvider)); }); describe('#compileEventBridgeEvents()', () => { it('should not throw if the eventBridge config is an object and used with another event source', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { s3: { bucket: 'some-bucket', }, }, { eventBridge: { pattern: {}, }, }, ], }, }; expect(() => awsCompileEventBridgeEvents.compileEventBridgeEvents()).not.to.throw(); }); it('should create the necessary resources for the most minimal configuration', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { schedule: 'rate(10 minutes)', pattern: { 'source': ['aws.cloudformation'], 'detail-type': ['AWS API Call via CloudTrail'], 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, }, }, }, ], }, }; return expect(awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.be.fulfilled.then( () => { const { Resources, } = awsCompileEventBridgeEvents.serverless.service.provider.compiledCloudFormationTemplate; expect(addCustomResourceToServiceStub).to.have.been.calledOnce; expect(addCustomResourceToServiceStub.args[0][1]).to.equal('eventBridge'); expect(addCustomResourceToServiceStub.args[0][2]).to.deep.equal([ { Action: [ 'events:PutRule', 'events:RemoveTargets', 'events:PutTargets', 'events:DeleteRule', ], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'rule/*', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', '*', ], ], }, }, ]); expect(Resources.FirstCustomEventBridge1).to.deep.equal({ Type: 'Custom::EventBridge', Version: 1, DependsOn: [ 'FirstLambdaFunction', 'CustomDashresourceDasheventDashbridgeLambdaFunction', ], Properties: { ServiceToken: { 'Fn::GetAtt': ['CustomDashresourceDasheventDashbridgeLambdaFunction', 'Arn'], }, FunctionName: 'first', EventBridgeConfig: { EventBus: undefined, Input: undefined, InputPath: undefined, InputTransformer: undefined, Pattern: { 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, 'detail-type': ['AWS API Call via CloudTrail'], 'source': ['aws.cloudformation'], }, RuleName: 'first-rule-1', Schedule: 'rate(10 minutes)', }, }, }); } ); }); it('should shorten the rule name if it exceeds 64 chars', () => { awsCompileEventBridgeEvents.serverless.service.functions = { oneVeryLongAndVeryStrangeAndVeryComplicatedFunctionNameOver64Chars: { name: 'one-very-long-and-very-strange-and-very-complicated-function-name-over-64-chars', events: [ { eventBridge: { schedule: 'rate(10 minutes)', pattern: { 'source': ['aws.cloudformation'], 'detail-type': ['AWS API Call via CloudTrail'], 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, }, }, }, ], }, }; return expect(awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.be.fulfilled.then( () => { const { Resources, } = awsCompileEventBridgeEvents.serverless.service.provider.compiledCloudFormationTemplate; const RuleNameFromCustomResource = Resources .OneVeryLongAndVeryStrangeAndVeryComplicatedFunctionNameOver64CharsCustomEventBridge1 .Properties.EventBridgeConfig.RuleName; expect(RuleNameFromCustomResource.endsWith('rule-1')).to.be.true; expect(RuleNameFromCustomResource).lengthOf.lte(64); } ); }); it('should create the necessary resources when using a complex configuration', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { eventBus: 'some-event-bus', schedule: 'rate(10 minutes)', pattern: { 'source': ['aws.cloudformation'], 'detail-type': ['AWS API Call via CloudTrail'], 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, }, input: { key1: 'value1', key2: { nested: 'value2', }, }, }, }, ], }, }; return expect(awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.be.fulfilled.then( () => { const { Resources, } = awsCompileEventBridgeEvents.serverless.service.provider.compiledCloudFormationTemplate; expect(addCustomResourceToServiceStub).to.have.been.calledOnce; expect(addCustomResourceToServiceStub.args[0][1]).to.equal('eventBridge'); expect(addCustomResourceToServiceStub.args[0][2]).to.deep.equal([ { Action: ['events:CreateEventBus', 'events:DeleteEventBus'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'event-bus/*', ], ], }, }, { Action: [ 'events:PutRule', 'events:RemoveTargets', 'events:PutTargets', 'events:DeleteRule', ], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'rule/*', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', '*', ], ], }, }, ]); expect(Resources.FirstCustomEventBridge1).to.deep.equal({ Type: 'Custom::EventBridge', Version: 1, DependsOn: [ 'FirstLambdaFunction', 'CustomDashresourceDasheventDashbridgeLambdaFunction', ], Properties: { ServiceToken: { 'Fn::GetAtt': ['CustomDashresourceDasheventDashbridgeLambdaFunction', 'Arn'], }, FunctionName: 'first', EventBridgeConfig: { EventBus: 'some-event-bus', Input: { key1: 'value1', key2: { nested: 'value2', }, }, InputPath: undefined, InputTransformer: undefined, Pattern: { 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, 'detail-type': ['AWS API Call via CloudTrail'], 'source': ['aws.cloudformation'], }, RuleName: 'first-rule-1', Schedule: 'rate(10 minutes)', }, }, }); } ); }); it('should create the necessary resources with only one create/delete event bus policy', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { eventBus: 'some-event-bus', schedule: 'rate(10 minutes)', pattern: { 'source': ['aws.cloudformation'], 'detail-type': ['AWS API Call via CloudTrail'], 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, }, }, }, ], }, second: { name: 'second', events: [ { eventBridge: { eventBus: 'some-event-bus', schedule: 'rate(10 minutes)', pattern: { 'source': ['aws.cloudformation'], 'detail-type': ['AWS API Call via CloudTrail'], 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, }, }, }, ], }, }; return expect(awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.be.fulfilled.then( () => { const { Resources, } = awsCompileEventBridgeEvents.serverless.service.provider.compiledCloudFormationTemplate; expect(addCustomResourceToServiceStub).to.have.been.calledOnce; expect(addCustomResourceToServiceStub.args[0][1]).to.equal('eventBridge'); expect(addCustomResourceToServiceStub.args[0][2]).to.deep.equal([ { Action: ['events:CreateEventBus', 'events:DeleteEventBus'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition', }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'event-bus/*', ], ], }, }, { Action: [ 'events:PutRule', 'events:RemoveTargets', 'events:PutTargets', 'events:DeleteRule', ], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition', }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'rule/*', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition', }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', '*', ], ], }, }, ]); expect(Resources.FirstCustomEventBridge1).to.deep.equal({ Type: 'Custom::EventBridge', Version: 1, DependsOn: [ 'FirstLambdaFunction', 'CustomDashresourceDasheventDashbridgeLambdaFunction', ], Properties: { ServiceToken: { 'Fn::GetAtt': ['CustomDashresourceDasheventDashbridgeLambdaFunction', 'Arn'], }, FunctionName: 'first', EventBridgeConfig: { EventBus: 'some-event-bus', Input: undefined, InputPath: undefined, InputTransformer: undefined, Pattern: { 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, 'detail-type': ['AWS API Call via CloudTrail'], 'source': ['aws.cloudformation'], }, RuleName: 'first-rule-1', Schedule: 'rate(10 minutes)', }, }, }); } ); }); it('should create the necessary resources when using an own event bus arn', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { eventBus: 'arn:aws:events:us-east-1:12345:event-bus/some-event-bus', schedule: 'rate(10 minutes)', pattern: { 'source': ['aws.cloudformation'], 'detail-type': ['AWS API Call via CloudTrail'], 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, }, input: { key1: 'value1', key2: { nested: 'value2', }, }, }, }, ], }, }; return expect(awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.be.fulfilled.then( () => { const { Resources, } = awsCompileEventBridgeEvents.serverless.service.provider.compiledCloudFormationTemplate; expect(addCustomResourceToServiceStub).to.have.been.calledOnce; expect(addCustomResourceToServiceStub.args[0][1]).to.equal('eventBridge'); expect(addCustomResourceToServiceStub.args[0][2]).to.deep.equal([ { Action: ['events:CreateEventBus', 'events:DeleteEventBus'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'event-bus/*', ], ], }, }, { Action: [ 'events:PutRule', 'events:RemoveTargets', 'events:PutTargets', 'events:DeleteRule', ], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'rule/*', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', '*', ], ], }, }, ]); expect(Resources.FirstCustomEventBridge1).to.deep.equal({ Type: 'Custom::EventBridge', Version: 1, DependsOn: [ 'FirstLambdaFunction', 'CustomDashresourceDasheventDashbridgeLambdaFunction', ], Properties: { ServiceToken: { 'Fn::GetAtt': ['CustomDashresourceDasheventDashbridgeLambdaFunction', 'Arn'], }, FunctionName: 'first', EventBridgeConfig: { EventBus: 'arn:aws:events:us-east-1:12345:event-bus/some-event-bus', Input: { key1: 'value1', key2: { nested: 'value2', }, }, InputPath: undefined, InputTransformer: undefined, Pattern: { 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, 'detail-type': ['AWS API Call via CloudTrail'], 'source': ['aws.cloudformation'], }, RuleName: 'first-rule-1', Schedule: 'rate(10 minutes)', }, }, }); } ); }); it('should create the necessary resources when using a partner event bus arn', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { eventBus: 'arn:aws:events:us-east-1:12345:event-bus/aws.partner/partner.com/12345', pattern: { source: ['aws.partner/partner.com/12345'], detail: { event: ['My Event'], type: ['track'], }, }, }, }, ], }, }; return expect(awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.be.fulfilled.then( () => { const { Resources, } = awsCompileEventBridgeEvents.serverless.service.provider.compiledCloudFormationTemplate; expect(addCustomResourceToServiceStub).to.have.been.calledOnce; expect(addCustomResourceToServiceStub.args[0][1]).to.equal('eventBridge'); expect(addCustomResourceToServiceStub.args[0][2]).to.deep.equal([ { Action: ['events:CreateEventBus', 'events:DeleteEventBus'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'event-bus/*', ], ], }, }, { Action: [ 'events:PutRule', 'events:RemoveTargets', 'events:PutTargets', 'events:DeleteRule', ], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'rule/*', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', '*', ], ], }, }, ]); expect(Resources.FirstCustomEventBridge1).to.deep.equal({ Type: 'Custom::EventBridge', Version: 1, DependsOn: [ 'FirstLambdaFunction', 'CustomDashresourceDasheventDashbridgeLambdaFunction', ], Properties: { ServiceToken: { 'Fn::GetAtt': ['CustomDashresourceDasheventDashbridgeLambdaFunction', 'Arn'], }, FunctionName: 'first', EventBridgeConfig: { EventBus: 'arn:aws:events:us-east-1:12345:event-bus/aws.partner/partner.com/12345', Input: undefined, InputPath: undefined, InputTransformer: undefined, Pattern: { detail: { event: ['My Event'], type: ['track'], }, source: ['aws.partner/partner.com/12345'], }, Schedule: undefined, RuleName: 'first-rule-1', }, }, }); } ); }); it('should create the necessary resources when using an input configuration', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { pattern: { 'source': ['aws.cloudformation'], 'detail-type': ['AWS API Call via CloudTrail'], 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, }, input: { key1: 'value1', }, }, }, ], }, }; return expect(awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.be.fulfilled.then( () => { const { Resources, } = awsCompileEventBridgeEvents.serverless.service.provider.compiledCloudFormationTemplate; expect(addCustomResourceToServiceStub).to.have.been.calledOnce; expect(addCustomResourceToServiceStub.args[0][1]).to.equal('eventBridge'); expect(addCustomResourceToServiceStub.args[0][2]).to.deep.equal([ { Action: [ 'events:PutRule', 'events:RemoveTargets', 'events:PutTargets', 'events:DeleteRule', ], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'rule/*', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', '*', ], ], }, }, ]); expect(Resources.FirstCustomEventBridge1).to.deep.equal({ Type: 'Custom::EventBridge', Version: 1, DependsOn: [ 'FirstLambdaFunction', 'CustomDashresourceDasheventDashbridgeLambdaFunction', ], Properties: { ServiceToken: { 'Fn::GetAtt': ['CustomDashresourceDasheventDashbridgeLambdaFunction', 'Arn'], }, FunctionName: 'first', EventBridgeConfig: { EventBus: undefined, Input: { key1: 'value1', }, InputPath: undefined, InputTransformer: undefined, Pattern: { 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, 'detail-type': ['AWS API Call via CloudTrail'], 'source': ['aws.cloudformation'], }, RuleName: 'first-rule-1', Schedule: undefined, }, }, }); } ); }); it('should create the necessary resources when using an inputPath configuration', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { pattern: { 'source': ['aws.cloudformation'], 'detail-type': ['AWS API Call via CloudTrail'], 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, }, inputPath: '$.stageVariables', }, }, ], }, }; return expect(awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.be.fulfilled.then( () => { const { Resources, } = awsCompileEventBridgeEvents.serverless.service.provider.compiledCloudFormationTemplate; expect(addCustomResourceToServiceStub).to.have.been.calledOnce; expect(addCustomResourceToServiceStub.args[0][1]).to.equal('eventBridge'); expect(addCustomResourceToServiceStub.args[0][2]).to.deep.equal([ { Action: [ 'events:PutRule', 'events:RemoveTargets', 'events:PutTargets', 'events:DeleteRule', ], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'rule/*', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', '*', ], ], }, }, ]); expect(Resources.FirstCustomEventBridge1).to.deep.equal({ Type: 'Custom::EventBridge', Version: 1, DependsOn: [ 'FirstLambdaFunction', 'CustomDashresourceDasheventDashbridgeLambdaFunction', ], Properties: { ServiceToken: { 'Fn::GetAtt': ['CustomDashresourceDasheventDashbridgeLambdaFunction', 'Arn'], }, FunctionName: 'first', EventBridgeConfig: { EventBus: undefined, Input: undefined, InputPath: '$.stageVariables', InputTransformer: undefined, Pattern: { 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, 'detail-type': ['AWS API Call via CloudTrail'], 'source': ['aws.cloudformation'], }, RuleName: 'first-rule-1', Schedule: undefined, }, }, }); } ); }); describe('when using an inputTransformer configuration', () => { it('should create the necessary resources', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { pattern: { 'source': ['aws.cloudformation'], 'detail-type': ['AWS API Call via CloudTrail'], 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, }, inputTransformer: { inputTemplate: '{"time": <eventTime>, "key1": "value1"}', inputPathsMap: { eventTime: '$.time', }, }, }, }, ], }, }; return expect(awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.be.fulfilled.then( () => { const { Resources, } = awsCompileEventBridgeEvents.serverless.service.provider.compiledCloudFormationTemplate; expect(addCustomResourceToServiceStub).to.have.been.calledOnce; expect(addCustomResourceToServiceStub.args[0][1]).to.equal('eventBridge'); expect(addCustomResourceToServiceStub.args[0][2]).to.deep.equal([ { Action: [ 'events:PutRule', 'events:RemoveTargets', 'events:PutTargets', 'events:DeleteRule', ], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'events', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'rule/*', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', '*', ], ], }, }, ]); expect(Resources.FirstCustomEventBridge1).to.deep.equal({ Type: 'Custom::EventBridge', Version: 1, DependsOn: [ 'FirstLambdaFunction', 'CustomDashresourceDasheventDashbridgeLambdaFunction', ], Properties: { ServiceToken: { 'Fn::GetAtt': ['CustomDashresourceDasheventDashbridgeLambdaFunction', 'Arn'], }, FunctionName: 'first', EventBridgeConfig: { EventBus: undefined, Input: undefined, InputPath: undefined, InputTransformer: { InputPathsMap: { eventTime: '$.time', }, InputTemplate: '{"time": <eventTime>, "key1": "value1"}', }, Pattern: { 'detail': { eventSource: ['cloudformation.amazonaws.com'], }, 'detail-type': ['AWS API Call via CloudTrail'], 'source': ['aws.cloudformation'], }, RuleName: 'first-rule-1', Schedule: undefined, }, }, }); } ); }); }); }); }); describe('EventBridgeEvents', () => { after(() => { sinon.restore(); }); describe('when using the default event bus arn', () => { const functionName = 'foo'; let cfResources; let naming; before(() => { // Prevent `npm install` in custom resource setup sinon.stub(childProcess, 'execAsync'); // Stubbing removes bluebird marker, which will result in bluebird crash on repeated // promisification attempton. Ensure blubird marker to prevent that childProcess.execAsync.__isPromisified__ = true; return runServerless({ fixture: 'function', configExt: { functions: { [functionName]: { events: [ { eventBridge: { eventBus: 'arn:aws:events:us-east-1:12345:event-bus/default', schedule: 'rate(10 minutes)', }, }, ], }, }, }, cliArgs: ['package'], }).then(({ cfTemplate, awsNaming }) => { ({ Resources: cfResources } = cfTemplate); naming = awsNaming; }); }); it('should create the correct execution role', () => { const roleId = naming.getCustomResourcesRoleLogicalId(); const executionRolePolicyStatements = cfResources[roleId].Properties.Policies[0].PolicyDocument.Statement; expect(executionRolePolicyStatements[0].Action).to.include('events:PutRule'); expect(executionRolePolicyStatements[0].Resource['Fn::Join'][1]).to.deep.include('rule/*'); }); it('should create the necessary resources', () => { const normalizedFunctionName = naming.getNormalizedFunctionName(functionName); const eventBridgeId = naming.getCustomResourceEventBridgeResourceLogicalId( normalizedFunctionName, 1 ); expect(cfResources[eventBridgeId].Properties.EventBridgeConfig.RuleName).to.include( `dev-${functionName}-rule-1` ); }); }); });