'use strict' const chai = require('chai') const sinon = require('sinon') const yaml = require('js-yaml') const fse = require('fs-extra') const proxyquire = require('proxyquire') const fixturesEngine = require('../../fixtures/programmatic') const resolveConfigurationPath = require('../../../lib/cli/resolve-configuration-path') const { expect } = require('chai') chai.use(require('chai-as-promised')) const npmCommand = 'npm' describe('test/unit/commands/plugin-install.test.js', async () => { const spawnFake = sinon.fake() const installPlugin = proxyquire('../../../commands/plugin-install', { 'child-process-ext/spawn': spawnFake, }) const pluginName = 'serverless-plugin-1' afterEach(() => { spawnFake.resetHistory() }) describe('without plugins in configuration', () => { let serviceDir let configurationFilePath before(async () => { const fixture = await fixturesEngine.setup('function') const configuration = fixture.serviceConfig serviceDir = fixture.servicePath configurationFilePath = await resolveConfigurationPath({ cwd: serviceDir, }) const configurationFilename = configurationFilePath.slice( serviceDir.length + 1, ) const options = { name: pluginName, } await installPlugin({ configuration, serviceDir, configurationFilename, options, }) }) it('should install plugin', () => { const firstCall = spawnFake.firstCall const command = [firstCall.args[0], ...firstCall.args[1]].join(' ') const expectedCommand = `${npmCommand} install --save-dev ${pluginName}` expect(command).to.have.string(expectedCommand) }) it('should add plugin to serverless file', async () => { const serverlessFileObj = yaml.load( await fse.readFile(configurationFilePath, 'utf8'), { filename: configurationFilePath, }, ) expect(serverlessFileObj.plugins).to.include(pluginName) }) }) describe('with plugins in configuration', () => { it('should not add plugin to serverless file if it is already present in configuration but configured behind a variable', async () => { const fixture = await fixturesEngine.setup('function', { configExt: { plugins: ['${self:custom.pluginName}'], custom: { pluginName, }, }, }) const configuration = fixture.serviceConfig // Simulate that the variable has been resolved configuration.plugins = [pluginName] const serviceDir = fixture.servicePath const configurationFilePath = await resolveConfigurationPath({ cwd: serviceDir, }) const configurationFilename = configurationFilePath.slice( serviceDir.length + 1, ) const options = { name: pluginName, } await installPlugin({ configuration, serviceDir, configurationFilename, options, }) const serverlessFileObj = yaml.load( await fse.readFile(configurationFilePath, 'utf8'), { filename: configurationFilePath, }, ) expect(serverlessFileObj.plugins).not.to.include(pluginName) }) }) })