@sprucelabs/spruce-cli
Version:
Command line interface for building Spruce skills.
376 lines • 16.3 kB
JavaScript
"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