UNPKG

serverless

Version:

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

1,337 lines (1,287 loc) • 43 kB
'use strict'; /* eslint-disable no-unused-expressions */ const sinon = require('sinon'); const chai = require('chai'); const proxyquire = require('proxyquire').noCallThru(); const AwsProvider = require('../../../../provider/awsProvider'); const Serverless = require('../../../../../../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 throw if the eventBridge config is a string', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: 'some-config', }, ], }, }; expect(() => awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.throw( /not an object/ ); }); it('should throw if neither the pattern nor the schedule config is given', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: {}, }, ], }, }; expect(() => awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.throw( /need to configure the pattern or schedule property/ ); }); 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/first-rule-1', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', 'first', ], ], }, }, ]); 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 RuleNameFromLambdaConf = addCustomResourceToServiceStub.args[0][2][0].Resource[ 'Fn::Join' ][1] .pop() .replace('rule/', ''); expect(RuleNameFromLambdaConf.endsWith('rule-1')).to.be.true; expect(RuleNameFromLambdaConf).lengthOf.lte(64); 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/some-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/some-event-bus/first-rule-1', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', 'first', ], ], }, }, ]); 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/some-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/some-event-bus/first-rule-1', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition', }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', 'first', ], ], }, }, { 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/some-event-bus/second-rule-1', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition', }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', 'second', ], ], }, }, ]); 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/some-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/some-event-bus/first-rule-1', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', 'first', ], ], }, }, ]); 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/aws.partner/partner.com/12345', ], ], }, }, { 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/aws.partner/partner.com/12345/first-rule-1', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', 'first', ], ], }, }, ]); 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/first-rule-1', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', 'first', ], ], }, }, ]); 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/first-rule-1', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', 'first', ], ], }, }, ]); 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/first-rule-1', ], ], }, }, { Action: ['lambda:AddPermission', 'lambda:RemovePermission'], Effect: 'Allow', Resource: { 'Fn::Join': [ ':', [ 'arn', { Ref: 'AWS::Partition' }, 'lambda', { Ref: 'AWS::Region', }, { Ref: 'AWS::AccountId', }, 'function', 'first', ], ], }, }, ]); 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, }, }, }); } ); }); it('should throw if the inputTemplate configuration is missing', () => { 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"}', }, }, }, ], }, }; expect(() => awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.throw( /inputTemplate key is required/ ); }); }); describe('when using different input configurations', () => { it('should throw when using input and inputTransformer', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { schedule: 'rate(10 minutes)', input: 'some-input', inputTransformer: { InputTemplate: '{"time": <eventTime>, "key1": "value1"}', }, }, }, ], }, }; expect(() => awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.throw( /can only set one of/ ); }); it('should throw when using input and inputPath', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { schedule: 'rate(10 minutes)', input: 'some-input', inputPath: '$.stageVariables', }, }, ], }, }; expect(() => awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.throw( /can only set one of/ ); }); it('should throw when using inputPath and inputTransformer', () => { awsCompileEventBridgeEvents.serverless.service.functions = { first: { name: 'first', events: [ { eventBridge: { schedule: 'rate(10 minutes)', inputPath: '$.stageVariables', inputTransformer: { InputTemplate: '{"time": <eventTime>, "key1": "value1"}', }, }, }, ], }, }; expect(() => awsCompileEventBridgeEvents.compileEventBridgeEvents()).to.throw( /can only set one of/ ); }); }); }); });