Skip to content

Commit

Permalink
fix: enable skill for hosted skill init (#96)
Browse files Browse the repository at this point in the history
* fix: enable skill for hosted skill - ask new command
  • Loading branch information
kakhaUrigashvili authored Apr 1, 2020
1 parent d891df8 commit 8dbf91d
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 39 deletions.
5 changes: 5 additions & 0 deletions lib/commands/deploy/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ function deploySkillInfrastructure(profile, doDebug, callback) {
function enableSkill(profile, doDebug, callback) {
const skillMetaController = new SkillMetadataController({ profile, doDebug });
Messenger.getInstance().info('\n==================== Enable Skill ====================');
try {
skillMetaController.validateDomain();
} catch (err) {
return callback(err);
}
skillMetaController.enableSkill((error) => {
if (error) {
return callback(error);
Expand Down
21 changes: 15 additions & 6 deletions lib/commands/v2new/hosted-skill-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const LocalHostServer = require('@src/utils/local-host-server');
const stringUtils = require('@src/utils/string-utils');
const Messenger = require('@src/view/messenger');
const SpinnerView = require('@src/view/spinner-view');
const SkillMetadataController = require('@src/controllers/skill-metadata-controller');

const permissionStatusMap = new Map();
permissionStatusMap.set(CONSTANTS.HOSTED_SKILL.PERMISSION_CHECK_RESULT.NEW_USER_REGISTRATION_REQUIRED,
Expand Down Expand Up @@ -63,6 +64,8 @@ function validateUserQualification(vendorId, hostedSkillController, callback) {
function createHostedSkill(hostedSkillController, userInput, vendorId, callback) {
const rootPath = process.cwd();
const projectPath = path.join(rootPath, userInput.projectFolderName);
const { profile, doDebug } = hostedSkillController;
const skillMetadataController = new SkillMetadataController({ profile, doDebug });
if (fs.existsSync(projectPath)) {
return callback(`${projectPath} directory already exists.`);
}
Expand All @@ -87,13 +90,19 @@ function createHostedSkill(hostedSkillController, userInput, vendorId, callback)
if (cloneErr) {
return callback(cloneErr);
}
const templateUrl = CONSTANTS.HOSTED_SKILL.GIT_HOOKS_TEMPLATES.PRE_PUSH.URL;
const filePath = `${userInput.projectFolderName}/.git/hooks/pre-push`;
hostedSkillController.downloadGitHooksTemplate(templateUrl, filePath, (hooksErr) => {
if (hooksErr) {
return callback(hooksErr);
skillMetadataController.enableSkill((enableErr) => {
if (enableErr) {
Messenger.getInstance().error(enableErr);
return callback(enableErr);
}
callback(null, skillId);
const templateUrl = CONSTANTS.HOSTED_SKILL.GIT_HOOKS_TEMPLATES.PRE_PUSH.URL;
const filePath = `${userInput.projectFolderName}/.git/hooks/pre-push`;
hostedSkillController.downloadGitHooksTemplate(templateUrl, filePath, (hooksErr) => {
if (hooksErr) {
return callback(hooksErr);
}
callback(null, skillId);
});
});
});
});
Expand Down
31 changes: 19 additions & 12 deletions lib/controllers/skill-metadata-controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const stringUtils = require('@src/utils/string-utils');
const zipUtils = require('@src/utils/zip-utils');
const hashUtils = require('@src/utils/hash-utils');
const CONSTANTS = require('@src/utils/constants');
const CLiError = require('@src/exceptions/cli-error');

module.exports = class SkillMetadataController {
/**
Expand Down Expand Up @@ -66,27 +67,33 @@ module.exports = class SkillMetadataController {
}

/**
* Function used to enable skill. It calls smapi getSkillEnablement function first to check if skill is already enabled,
* if not, it will enable the skill by calling smapi enableSkill function.
* @param {Function} callback (err, null)
* Validates domain info
*/
enableSkill(callback) {
const skillId = ResourcesConfig.getInstance().getSkillId(this.profile);
validateDomain() {
const domainInfo = Manifest.getInstance().getApis();
if (!stringUtils.isNonBlankString(skillId)) {
return callback(`[Fatal]: Failed to find the skillId for profile [${this.profile}],
please make sure the skill metadata deployment has succeeded with result of a valid skillId.`);
}
if (!domainInfo || R.isEmpty(domainInfo)) {
return callback('[Error]: Skill information is not valid. Please make sure "apis" field in the skill.json is not empty.');
throw new CLiError('[Error]: Skill information is not valid. Please make sure "apis" field in the skill.json is not empty.');
}

const domainList = R.keys(domainInfo);
if (domainList.length !== 1) {
return callback('[Warn]: Skill with multiple api domains cannot be enabled. Skip the enable process.');
throw new CLiError('[Warn]: Skill with multiple api domains cannot be enabled. Skip the enable process.');
}
if (CONSTANTS.SKILL.DOMAIN.CAN_ENABLE_DOMAIN_LIST.indexOf(domainList[0]) === -1) {
return callback(`[Warn]: Skill api domain "${domainList[0]}" cannot be enabled. Skip the enable process.`);
throw new CLiError(`[Warn]: Skill api domain "${domainList[0]}" cannot be enabled. Skip the enable process.`);
}
}

/**
* Function used to enable skill. It calls smapi getSkillEnablement function first to check if skill is already enabled,
* if not, it will enable the skill by calling smapi enableSkill function.
* @param {Function} callback (err, null)
*/
enableSkill(callback) {
const skillId = ResourcesConfig.getInstance().getSkillId(this.profile);
if (!stringUtils.isNonBlankString(skillId)) {
return callback(`[Fatal]: Failed to find the skillId for profile [${this.profile}],
please make sure the skill metadata deployment has succeeded with result of a valid skillId.`);
}

this.smapiClient.skill.getSkillEnablement(skillId, CONSTANTS.SKILL.STAGE.DEVELOPMENT, (err, response) => {
Expand Down
11 changes: 11 additions & 0 deletions test/unit/commands/deploy/helper-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ describe('Commands deploy test - helper test', () => {
});
});

it('| skillMetaController validateDomain fails, expect callback error', (done) => {
// setup
sinon.stub(SkillMetadataController.prototype, 'validateDomain').throws('test-error');
// call
helper.enableSkill(TEST_PROFILE, TEST_DO_DEBUG, (err) => {
expect(err.name).equal('test-error');
expect(infoStub.args[0][0]).equal('\n==================== Enable Skill ====================');
done();
});
});

it('| skillMetaController enableSkill passes, expect no error callback', (done) => {
// setup
sinon.stub(SkillMetadataController.prototype, 'enableSkill').callsArgWith(0);
Expand Down
18 changes: 18 additions & 0 deletions test/unit/commands/v2new/hosted-skill-helper-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const CONSTANTS = require('@src/utils/constants');
const LocalHostServer = require('@src/utils/local-host-server');
const Messenger = require('@src/view/messenger');
const SpinnerView = require('@src/view/spinner-view');
const SkillMetadataController = require('@src/controllers/skill-metadata-controller');

describe('Commands new test - hosted skill helper test', () => {
const TEST_ERROR = 'TEST_ERROR';
Expand Down Expand Up @@ -412,12 +413,28 @@ describe('Commands new test - hosted skill helper test', () => {
});
});

it('| hostedSkillController clone succeed, enableSkill fails, expect error thrown', (done) => {
// setup
sinon.stub(HostedSkillController.prototype, 'createSkill').callsArgWith(1, null, TEST_SKILL_ID);
sinon.stub(process, 'cwd').returns('root/');
sinon.stub(HostedSkillController.prototype, 'clone').callsArgWith(3, null);
sinon.stub(SkillMetadataController.prototype, 'enableSkill').yields(TEST_ERROR);
// call
hostedSkillHelper.createHostedSkill(HostedSkillController.prototype, TEST_USER_INPUT, TEST_VENDOR_ID, (err, res) => {
// verify
expect(res).equal(undefined);
expect(err).equal(TEST_ERROR);
done();
});
});

it('| hostedSkillController clone succeed, downloadGitHooksTemplate fails, expect error thrown', (done) => {
// setup
sinon.stub(HostedSkillController.prototype, 'createSkill').callsArgWith(1, null, TEST_SKILL_ID);
sinon.stub(process, 'cwd').returns('root/');
sinon.stub(HostedSkillController.prototype, 'clone').callsArgWith(3, null);
sinon.stub(HostedSkillController.prototype, 'downloadGitHooksTemplate').callsArgWith(2, TEST_ERROR);
sinon.stub(SkillMetadataController.prototype, 'enableSkill').yields();
// call
hostedSkillHelper.createHostedSkill(HostedSkillController.prototype, TEST_USER_INPUT, TEST_VENDOR_ID, (err, res) => {
// verify
Expand All @@ -433,6 +450,7 @@ describe('Commands new test - hosted skill helper test', () => {
sinon.stub(process, 'cwd').returns('root/');
sinon.stub(HostedSkillController.prototype, 'clone').callsArgWith(3, null);
sinon.stub(HostedSkillController.prototype, 'downloadGitHooksTemplate').callsArgWith(2, null);
sinon.stub(SkillMetadataController.prototype, 'enableSkill').yields();
// call
hostedSkillHelper.createHostedSkill(HostedSkillController.prototype, TEST_USER_INPUT, TEST_VENDOR_ID, (err, res) => {
// verify
Expand Down
31 changes: 10 additions & 21 deletions test/unit/controller/skill-metadata-controller-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const sinon = require('sinon');
const path = require('path');
const fs = require('fs-extra');
const jsonView = require('@src/view/json-view');
const CLiError = require('@src/exceptions/cli-error');
const ResourcesConfig = require('@src/model/resources-config');
const httpClient = require('@src/clients/http-client');
const SkillMetadataController = require('@src/controllers/skill-metadata-controller');
Expand Down Expand Up @@ -191,45 +192,33 @@ describe('Controller test - skill metadata controller test', () => {
});
});

it('| callback error when dominInfo is not provided', (done) => {
it('| return error when dominInfo is not provided', () => {
// setup
Manifest.getInstance().setApis({});
const expectedErrMessage = '[Error]: Skill information is not valid. Please make sure "apis" field in the skill.json is not empty.';
// call
skillMetaController.enableSkill((err, res) => {
// verify
expect(err).equal('[Error]: Skill information is not valid. Please make sure "apis" field in the skill.json is not empty.');
expect(res).equal(undefined);
done();
});
expect(() => skillMetaController.validateDomain()).to.throw(CLiError, expectedErrMessage);
});

it('| callback error when dominInfo contains more than one domain', (done) => {
it('| return error when dominInfo contains more than one domain', () => {
// setup
Manifest.getInstance().setApis({
custom: {},
smartHome: {}
});
const expectedErrMessage = '[Warn]: Skill with multiple api domains cannot be enabled. Skip the enable process.';
// call
skillMetaController.enableSkill((err, res) => {
// verify
expect(err).equal('[Warn]: Skill with multiple api domains cannot be enabled. Skip the enable process.');
expect(res).equal(undefined);
done();
});
expect(() => skillMetaController.validateDomain()).to.throw(CLiError, expectedErrMessage);
});

it('| callback error when domain cannot be enabled', (done) => {
it('| return error when domain cannot be enabled', () => {
// setup
Manifest.getInstance().setApis({
smartHome: {}
});
const expectedErrMessage = '[Warn]: Skill api domain "smartHome" cannot be enabled. Skip the enable process.';
// call
skillMetaController.enableSkill((err, res) => {
// verify
expect(err).equal('[Warn]: Skill api domain "smartHome" cannot be enabled. Skip the enable process.');
expect(res).equal(undefined);
done();
});
expect(() => skillMetaController.validateDomain()).to.throw(CLiError, expectedErrMessage);
});

it('| callback error when getSkillEnablement return error', (done) => {
Expand Down

0 comments on commit 8dbf91d

Please sign in to comment.