UNPKG

@sprucelabs/spruce-cli

Version:

Command line interface for building Spruce skills.

376 lines • 16.3 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils"); const test_utils_1 = require("@sprucelabs/test-utils"); const test_utils_2 = require("@sprucelabs/test-utils"); const CommandService_1 = __importDefault(require("../../../services/CommandService")); const LintService_1 = __importDefault(require("../../../services/LintService")); const AbstractCliTest_1 = __importDefault(require("../../../tests/AbstractCliTest")); const test_utility_1 = __importDefault(require("../../../tests/utilities/test.utility")); class DeployingASkillTest extends AbstractCliTest_1.default { static fastHerokuOptions = { teamName: process.env.HEROKU_TEAM_NAME ?? '', shouldBuildAndLint: false, shouldRunTests: false, }; static async beforeEach() { await super.beforeEach(); CommandService_1.default.fakeCommand('which heroku', { code: 0, }); CommandService_1.default.fakeCommand('grep api.heroku.com ~/.netrc', { code: 0, }); CommandService_1.default.fakeCommand('git status', { code: 0, }); CommandService_1.default.fakeCommand('git init', { code: 0, stdout: 'Initialized empty Git repository in', }); CommandService_1.default.fakeCommand('git ls-remote heroku', { code: 0, }); CommandService_1.default.fakeCommand('which git', { code: 0, }); CommandService_1.default.fakeCommand('heroku create good-heroku-name', { code: 0, }); CommandService_1.default.fakeCommand('heroku create bad-heroku-name', { code: 1, }); CommandService_1.default.fakeCommand('heroku buildpacks:set heroku/nodejs', { code: 0, }); CommandService_1.default.fakeCommand('git push --set-upstream heroku master', { code: 0, }); spruce_skill_utils_1.diskUtil.writeFile(this.resolvePath('Procfile'), 'web: npm run boot'); } static async hasDeployAction() { test_utils_1.assert.isFunction(this.Action('deploy', 'heroku').execute); } static async deployHaltedBecauseNotRegistered() { await this.FeatureFixture().installCachedFeatures('deploy'); spruce_skill_utils_1.diskUtil.writeFile(this.resolvePath('src/index.ts'), 'aoeustahoesuntao'); const results = await this.Action('deploy', 'heroku').execute({ teamName: process.env.HEROKU_TEAM_NAME ?? '', }); test_utils_1.assert.isTruthy(results.errors); test_utils_1.assert.isArray(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'DEPLOY_FAILED', { stage: 'skill', }); } static async deployHaltedWithBadBuild() { await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'haulted wth bad build', }); spruce_skill_utils_1.diskUtil.writeFile(this.resolvePath('src/index.ts'), 'aoeustahoesuntao'); const results = await this.Action('deploy', 'heroku').execute({ teamName: process.env.HEROKU_TEAM_NAME ?? '', }); test_utils_1.assert.isTruthy(results.errors); test_utils_1.assert.isArray(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'DEPLOY_FAILED', { stage: 'building', }); } static async healthCheckReportsNotDeployed() { const cli = await this.FeatureFixture().installCachedFeatures('deploy'); const health = (await cli.checkHealth()); test_utils_1.assert.isFalsy(health.errors); test_utils_1.assert.isTruthy(health.deploy); test_utils_1.assert.isEqual(health.deploy.status, 'passed'); test_utils_1.assert.isLength(health.deploy.deploys, 0); } static async deployHaltedWithBadTest() { await this.FeatureFixture().installCachedFeatures('deployWithTests'); LintService_1.default.enableLinting(); await this.getSkillFixture().registerCurrentSkill({ name: 'haulted wth bad test', }); const promise = this.Action('test', 'create').execute({ nameReadable: 'Test failed', nameCamel: 'testFailed', type: 'behavioral', }); await this.waitForInput(); await this.ui.sendInput(''); await promise; const results = await this.Action('deploy', 'heroku').execute({ teamName: process.env.HEROKU_TEAM_NAME ?? '', }); test_utils_1.assert.isTruthy(results.errors); test_utils_1.assert.isArray(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'TEST_FAILED'); } static async errorsIfHerokuClientNotInstalled() { CommandService_1.default.fakeCommand('which heroku', { code: 1, }); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'heroku not installed', }); const results = await this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); test_utils_1.assert.isTruthy(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'MISSING_DEPENDENCIES', { 'dependencies[0].name': 'heroku', }); } static async errorsIfGitNotInstalled() { CommandService_1.default.fakeCommand('which git', { code: 1, }); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'git not installed', }); const results = await this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); test_utils_1.assert.isTruthy(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'MISSING_DEPENDENCIES', { 'dependencies[0].name': 'git', }); } static async errorsIfNotInGitRepo() { CommandService_1.default.fakeCommand('git status', { code: 128, stderr: 'fatal: not a git repository (or any of the parent directories): .git', }); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'not in git repo', }); const promise = this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); await this.waitForInput(); await this.ui.sendInput('n'); const results = await promise; test_utils_1.assert.isTruthy(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'DEPLOY_FAILED', { stage: 'git', }); } static async canCreateGitRepoIfNeeded() { CommandService_1.default.fakeCommand('git status', { code: 128, }); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'creates git repo', }); const promise = this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); await this.waitForInput(); CommandService_1.default.fakeCommand('git status', { code: 0, }); await this.ui.sendInput('y'); const results = await promise; test_utils_1.assert.isFalsy(results.errors); } static async errorsWhenNotLoggedIntoHerkou() { CommandService_1.default.fakeCommand('grep api.heroku.com ~/.netrc', { code: 1, }); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'not logged into heroku', }); const results = await this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); test_utils_1.assert.isTruthy(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'DEPLOY_FAILED', { stage: 'heroku', }); } static async failsWhenDeclineToCreateProcFile() { spruce_skill_utils_1.diskUtil.deleteFile(this.resolvePath('Procfile')); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'decline proc file', }); const promise = this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); await this.waitForInput(); test_utils_1.assert.doesInclude(this.ui.invocations, { command: 'confirm', }); await this.ui.sendInput('n'); const results = await promise; test_utils_1.assert.isTruthy(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'DEPLOY_FAILED', { stage: 'procfile', }); } static async createsValidProcFile() { spruce_skill_utils_1.diskUtil.deleteFile(this.resolvePath('Procfile')); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'valid proc file', }); const promise = this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); await this.waitForInput(); await this.ui.sendInput('y'); const results = await promise; test_utils_1.assert.isFalsy(results.errors); const match = test_utility_1.default.assertFileByNameInGeneratedFiles('Procfile', results.files); const contents = spruce_skill_utils_1.diskUtil.readFile(match); test_utils_1.assert.isEqual(contents, 'worker: npm run boot'); } static async failsWhenDeclineToCreateRemoteBranch() { CommandService_1.default.fakeCommand('git ls-remote heroku', { code: 128, }); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'decline to create remote branch', }); const promise = this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); await this.waitForInput(); test_utils_1.assert.doesInclude(this.ui.invocations, { command: 'confirm', }); await this.ui.sendInput('n'); const results = await promise; test_utils_1.assert.isTruthy(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'DEPLOY_FAILED', { stage: 'remote', }); } static async asksForHerokuAppName() { CommandService_1.default.fakeCommand('git ls-remote heroku', { code: 128, }); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'ask for app name', }); const promise = this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); await this.waitForInput(); await this.ui.sendInput('y'); await this.waitForInput(); test_utils_1.assert.doesInclude(this.ui.invocations, { command: 'prompt', options: { type: 'text', }, }); await this.ui.sendInput(`good-heroku-name`); const results = await promise; test_utils_1.assert.isFalsy(results.errors); } static async keepsAskingForAppNameUntilAGoodOneIsSelected() { CommandService_1.default.fakeCommand('git ls-remote heroku', { code: 128, }); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'haulted wth bad build', }); const promise = this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); await this.waitForInput(); test_utils_1.assert.doesInclude(this.ui.invocations, { command: 'confirm', }); await this.ui.sendInput('y'); await this.waitForInput(); test_utils_1.assert.doesInclude(this.ui.invocations, { command: 'prompt', options: { type: 'text', }, }); await this.ui.sendInput(`bad-heroku-name`); await this.waitForInput(); await this.ui.sendInput('bad-heroku-name'); await this.waitForInput(); await this.ui.sendInput('good-heroku-name'); const results = await promise; test_utils_1.assert.isFalsy(results.errors); } static async failsWithPendingChangesToCommit() { CommandService_1.default.fakeCommand('git status', { code: 0, stdout: 'Changes not staged for commit', }); await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'pending changes to commit', }); const results = await this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); test_utils_1.assert.isTruthy(results.errors); test_utils_2.errorAssert.assertError(results.errors[0], 'DEPLOY_FAILED', { stage: 'git', }); } static async canDeploySkill() { await this.FeatureFixture().installCachedFeatures('deploy'); await this.getSkillFixture().registerCurrentSkill({ name: 'can deploy', }); const results = await this.Action('deploy', 'heroku').execute(this.fastHerokuOptions); test_utils_1.assert.isFalsy(results.errors); } } exports.default = DeployingASkillTest; __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "hasDeployAction", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "deployHaltedBecauseNotRegistered", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "deployHaltedWithBadBuild", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "healthCheckReportsNotDeployed", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "deployHaltedWithBadTest", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "errorsIfHerokuClientNotInstalled", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "errorsIfGitNotInstalled", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "errorsIfNotInGitRepo", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "canCreateGitRepoIfNeeded", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "errorsWhenNotLoggedIntoHerkou", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "failsWhenDeclineToCreateProcFile", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "createsValidProcFile", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "failsWhenDeclineToCreateRemoteBranch", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "asksForHerokuAppName", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "keepsAskingForAppNameUntilAGoodOneIsSelected", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "failsWithPendingChangesToCommit", null); __decorate([ (0, test_utils_1.test)() ], DeployingASkillTest, "canDeploySkill", null); //# sourceMappingURL=DeployingASkill.test.js.map