'use strict' const { expect } = require('chai') const log = require('log').get('serverless:test') const fixtures = require('../../fixtures/programmatic') const { confirmCloudWatchLogs } = require('../../utils/misc') const { createSnsTopic, removeSnsTopic, publishSnsMessage, } = require('../../utils/sns') const { deployService, removeService } = require('../../utils/integration') describe('AWS - SNS Integration Test', function () { this.timeout(1000 * 60 * 100) // Involves time-taking deploys let stackName let serviceDir let minimalTopicName let filteredTopicName let existingTopicName const stage = 'dev' before(async () => { const serviceData = await fixtures.setup('sns') ;({ servicePath: serviceDir } = serviceData) const serviceName = serviceData.serviceConfig.service minimalTopicName = `${serviceName}-minimal` filteredTopicName = `${serviceName}-filtered` existingTopicName = `${serviceName}-existing` stackName = `${serviceName}-${stage}` // create "existing" SNS topics // NOTE: deployment can only be done once the SNS topics are created log.notice(`Creating SNS topic "${existingTopicName}"...`) await createSnsTopic(existingTopicName) return deployService(serviceDir) }) after(async () => { await removeService(serviceDir) log.notice('Deleting SNS topics') return removeSnsTopic(existingTopicName) }) describe('Minimal Setup', () => { it('should invoke on a topic message', async () => { const functionName = 'snsMinimal' const message = 'Hello from SNS!' const events = await confirmCloudWatchLogs( `/aws/lambda/${stackName}-${functionName}`, () => publishSnsMessage(minimalTopicName, message), { checkIsComplete: (soFarEvents) => { const logs = soFarEvents.reduce( (data, event) => data + event.message, '', ) return logs.includes(message) }, }, ) const logs = events.reduce((data, event) => data + event.message, '') expect(logs).to.include(functionName) expect(logs).to.include(message) }) }) describe('Multiple and Filtered Setup', async () => { it('should invoke on a topic message that matches filter', async () => { const leftFunctionName = 'snsMultipleFilteredLeft' const rightFunctionName = 'snsMultipleFilteredRight' const leftMessage = 'Hello to the left-side from SNS!' const rightMessage = 'Hello to the right-side from SNS!' const middleMessage = 'Hello to the middle-side from SNS!' const leftAttributes = { side: { DataType: 'String', StringValue: 'left' }, } const middleAttributes = { side: { DataType: 'String', StringValue: 'middle' }, } const rightAttributes = { side: { DataType: 'String', StringValue: 'right' }, } return Promise.all([ confirmCloudWatchLogs( `/aws/lambda/${stackName}-${leftFunctionName}`, async () => { await publishSnsMessage( filteredTopicName, middleMessage, middleAttributes, ) await publishSnsMessage( filteredTopicName, leftMessage, leftAttributes, ) }, { checkIsComplete: (events) => events .reduce((data, event) => data + event.message, '') .includes(leftMessage), }, ).then((events) => { const logs = events.reduce((data, event) => data + event.message, '') expect(logs).to.include(leftFunctionName) expect(logs).to.include(leftMessage) expect(logs).not.to.include(middleMessage) expect(logs).not.to.include(rightMessage) }), confirmCloudWatchLogs( `/aws/lambda/${stackName}-${rightFunctionName}`, async () => { await publishSnsMessage( filteredTopicName, middleMessage, middleAttributes, ) await publishSnsMessage( filteredTopicName, rightMessage, rightAttributes, ) }, { checkIsComplete: (events) => events .reduce((data, event) => data + event.message, '') .includes(rightMessage), }, ).then((events) => { const logs = events.reduce((data, event) => data + event.message, '') expect(logs).to.include(rightFunctionName) expect(logs).not.to.include(leftMessage) expect(logs).not.to.include(middleMessage) expect(logs).to.include(rightMessage) }), ]) }) }) describe('Existing Setup', () => { it('should invoke on an existing topic message', async () => { const functionName = 'snsExisting' const message = 'Hello from an existing SNS!' const events = await confirmCloudWatchLogs( `/aws/lambda/${stackName}-${functionName}`, () => publishSnsMessage(existingTopicName, message), { checkIsComplete: (soFarEvents) => soFarEvents .reduce((data, event) => data + event.message, '') .includes(message), }, ) const logs = events.reduce((data, event) => data + event.message, '') expect(logs).to.include(functionName) expect(logs).to.include(message) }) }) })