'use strict' const { expect } = require('chai') const path = require('path') const fsp = require('fs').promises const spawn = require('child-process-ext/spawn') const fetch = require('node-fetch') const AdmZip = require('adm-zip') const { deployService, removeService } = require('../utils/integration') const fixturesEngine = require('../fixtures/programmatic') const serverlessExec = require('../serverless-binary') describe('test/integration/curated-plugins.test.js', function () { this.timeout(1000 * 60 * 10) // Involves time-taking npm install let serviceDir let updateConfig let serviceConfig let isDeployed = false before(async () => { ;({ servicePath: serviceDir, updateConfig, serviceConfig, } = await fixturesEngine.setup('curated-plugins')) // Needed to test "serverless-domain-manager" await deployService(serviceDir) isDeployed = true }) after(async () => { if (!isDeployed) return await removeService(serviceDir) }) afterEach(async () => updateConfig({ plugins: null })) it('should be extended by "serverless-offline"', async () => { await updateConfig({ plugins: ['serverless-offline'] }) const slsProcessPromise = spawn(serverlessExec, ['offline'], { cwd: serviceDir, }) const slsProcess = slsProcessPromise.child let output = '' slsProcess.stderr.on('data', function self(data) { output += data if (output.includes('Server ready:')) { slsProcess.stderr.off('data', self) fetch('http://localhost:3000/dev/foo') .then(async (response) => { const responseBody = await response.json() expect(responseBody.message).to.equal('Test') }) .finally(() => slsProcess.kill('SIGINT')) } }) await slsProcessPromise }) it('should be extended by "serverless-webpack"', async () => { await spawn(serverlessExec, ['package'], { cwd: serviceDir }) const packagePath = path.resolve( serviceDir, '.serverless', `${serviceConfig.service}.zip`, ) const originalPackageSize = (await fsp.stat(packagePath)).size await updateConfig({ plugins: ['serverless-webpack'] }) await spawn(serverlessExec, ['package'], { cwd: serviceDir }) const bundledPackageSize = (await fsp.stat(packagePath)).size expect(originalPackageSize / 10).to.be.above(bundledPackageSize) }) it('should be extended by "serverless-domain-manager"', async () => { await updateConfig({ plugins: ['serverless-domain-manager'] }) const { stderrBuffer } = await spawn(serverlessExec, ['info'], { cwd: serviceDir, }) expect(String(stderrBuffer)).to.include('Serverless Domain Manager:') }) it('should be extended by "serverless-prune-plugin"', async () => { await updateConfig({ plugins: ['serverless-prune-plugin'] }) const { stderrBuffer } = await spawn( serverlessExec, ['prune', '-n', '10'], { cwd: serviceDir, }, ) expect(String(stderrBuffer)).to.include('Pruning of functions complete') }) it('should be extended by "serverless-dotenv-plugin"', async () => { await updateConfig({ plugins: ['serverless-dotenv-plugin'] }) const { stderrBuffer } = await spawn(serverlessExec, ['package'], { cwd: serviceDir, }) expect(String(stderrBuffer)).to.include( 'DOTENV: Loading environment variables', ) const cfTemplate = JSON.parse( await fsp.readFile( path.resolve( serviceDir, '.serverless/cloudformation-template-update-stack.json', ), ), ) expect( cfTemplate.Resources.FunctionLambdaFunction.Properties.Environment .Variables.DOTENV_PLUGIN_TEST, ).to.equal('passed') }) it('should be extended by "serverless-iam-roles-per-function"', async () => { await updateConfig({ plugins: ['serverless-iam-roles-per-function'], functions: { function: { iamRoleStatementsName: 'fn-plugin-role-name', iamRoleStatements: [ { Effect: 'Allow', Action: ['dynamodb:GetItem'], Resource: 'arn:aws:dynamodb:${aws:region}:*:table/mytable', }, ], }, }, }) try { await spawn(serverlessExec, ['package'], { cwd: serviceDir }) const cfTemplate = JSON.parse( await fsp.readFile( path.resolve( serviceDir, '.serverless/cloudformation-template-update-stack.json', ), ), ) expect( cfTemplate.Resources.FunctionIamRoleLambdaExecution.Properties.RoleName, ).to.equal('fn-plugin-role-name') } finally { await updateConfig({ functions: { function: { iamRoleStatementsName: null, iamRoleStatements: null }, }, }) } }) it('should be extended by "serverless-plugin-typescript"', async () => { await updateConfig({ plugins: ['serverless-plugin-typescript'], functions: { functionTs: { handler: 'index-ts.handler', }, }, }) try { await spawn(serverlessExec, ['package'], { cwd: serviceDir }) const zip = new AdmZip( path.resolve(serviceDir, `.serverless/${serviceConfig.service}.zip`), ) const zipEntry = zip .getEntries() .find(({ entryName }) => entryName === 'index-ts.js') const tmpModulePath = path.resolve(serviceDir, '.serverless/test-ts.js') await fsp.writeFile(tmpModulePath, zipEntry.getData()) expect(require(tmpModulePath).testData).to.deep.equal({ value: 'test-ts-compilation', }) } finally { await updateConfig({ functions: { functionTs: null }, }) } }) it('should be extended by "serverless-step-functions"', async () => { await updateConfig({ plugins: ['serverless-step-functions'], stepFunctions: { stateMachines: { testMachine: { definition: { StartAt: 'FirstState', States: { FirstState: { Type: 'Task', Resource: { 'Fn::GetAtt': ['entry', 'Arn'], }, Next: 'mapped_task', }, mapped_task: { Type: 'Map', Iterator: { StartAt: 'FirstMapTask', States: { FirstMapTask: { Type: 'Task', Resource: { 'Fn::GetAtt': ['mapTask', 'Arn'], }, End: true, }, }, }, End: true, }, }, }, }, }, validate: true, }, }) try { await spawn(serverlessExec, ['package'], { cwd: serviceDir }) const cfTemplate = JSON.parse( await fsp.readFile( path.resolve( serviceDir, '.serverless/cloudformation-template-update-stack.json', ), ), ) expect( cfTemplate.Resources.TestMachineStepFunctionsStateMachine.Type, ).to.equal('AWS::StepFunctions::StateMachine') } finally { await updateConfig({ stepFunctions: null, }) } }) })