From 3f311ded31f416de5cc53b5bad82fbaad85cecdc Mon Sep 17 00:00:00 2001 From: kakha urigashvili Date: Thu, 3 Dec 2020 11:34:15 -0800 Subject: [PATCH] fix: remove restriction for replay file to have .json extension; removed redundant code to handle yml files --- lib/commands/dialog/index.js | 7 +- lib/commands/option-model.json | 8 +- lib/controllers/dialog-controller/index.js | 6 -- lib/model/dialog-replay-file.js | 23 +---- test/unit/commands/dialog/index-test.js | 17 ++++ .../dialog-controller/index-test.js | 16 ---- test/unit/model/dialog-replay-file-test.js | 90 +------------------ 7 files changed, 31 insertions(+), 136 deletions(-) diff --git a/lib/commands/dialog/index.js b/lib/commands/dialog/index.js index 7f07c35b..4a345466 100644 --- a/lib/commands/dialog/index.js +++ b/lib/commands/dialog/index.js @@ -78,7 +78,12 @@ class DialogCommand extends AbstractCommand { let userInputs; const smapiClient = new SmapiClient({ profile, doDebug: debug }); if (cmd.replay) { - const dialogReplayConfig = new DialogReplayFile(cmd.replay); + let dialogReplayConfig; + try { + dialogReplayConfig = new DialogReplayFile(cmd.replay); + } catch (err) { + return callback(err); + } skillId = dialogReplayConfig.getSkillId(); if (!stringUtils.isNonBlankString(skillId)) { return process.nextTick(callback(new CliError('Replay file must contain skillId'))); diff --git a/lib/commands/option-model.json b/lib/commands/option-model.json index 490cb372..06b3eb4c 100644 --- a/lib/commands/option-model.json +++ b/lib/commands/option-model.json @@ -43,13 +43,9 @@ }, "replay": { "name": "replay", - "description": "Specify a replay file to simulate dialog with Alexa", + "description": "Specify a replay file (JSON file) to simulate dialog with Alexa", "alias": "r", - "stringInput": "REQUIRED", - "rule": [{ - "type": "REGEX", - "regex": "^[./]?[\\w\\-. /]+\\.(json)" - }] + "stringInput": "REQUIRED" }, "save-skill-io": { "name": "save-skill-io", diff --git a/lib/controllers/dialog-controller/index.js b/lib/controllers/dialog-controller/index.js index 2e5a9113..5ef11cfc 100644 --- a/lib/controllers/dialog-controller/index.js +++ b/lib/controllers/dialog-controller/index.js @@ -1,7 +1,6 @@ const chalk = require('chalk'); const fs = require('fs-extra'); const R = require('ramda'); -const path = require('path'); const stringUtils = require('@src/utils/string-utils'); const Messenger = require('@src/view/messenger'); @@ -102,12 +101,7 @@ module.exports = class DialogController extends SkillSimulationController { const filePath = recordArgsList[0]; const appendQuitArgument = recordArgsList[1]; let shouldAppendQuit = false; - const JSON_FILE_EXTENSION = '.json'; - if (path.extname(filePath).toLowerCase() !== JSON_FILE_EXTENSION) { - Messenger.getInstance().warn(`File should be of type '${JSON_FILE_EXTENSION}'`); - return {}; - } if (stringUtils.isNonBlankString(appendQuitArgument)) { if (appendQuitArgument !== '--append-quit') { Messenger.getInstance().warn(`Unable to validate arguments: "${appendQuitArgument}". ${RECORD_FORMAT}`); diff --git a/lib/model/dialog-replay-file.js b/lib/model/dialog-replay-file.js index 8b6e38fc..abfa2868 100644 --- a/lib/model/dialog-replay-file.js +++ b/lib/model/dialog-replay-file.js @@ -1,9 +1,7 @@ const fs = require('fs-extra'); -const path = require('path'); const R = require('ramda'); const CliFileNotFoundError = require('@src/exceptions/cli-file-not-found-error'); -const yaml = require('@src/model/yaml-parser'); const jsonView = require('@src/view/json-view'); module.exports = class DialogReplayFile { @@ -59,20 +57,12 @@ module.exports = class DialogReplayFile { * @param {String} filePath path to the given file. */ readFileContent(filePath) { - let fileType; try { - fileType = path.extname(filePath).toLowerCase(); this.doesFileExist(filePath); fs.accessSync(filePath, fs.constants.R_OK); - if (fileType === '.json') { - return JSON.parse(fs.readFileSync(filePath, 'utf-8')); - } - if (fileType === '.yaml' || fileType === '.yml') { - return yaml.load(filePath); - } - throw new Error('ASK CLI does not support this file type.'); + return fs.readJsonSync(filePath); } catch (error) { - throw `Failed to parse ${fileType} file ${filePath}.\n${error.message}`; + throw `Failed to parse file: ${filePath}.\n${error.message}`; } } @@ -86,14 +76,7 @@ module.exports = class DialogReplayFile { try { this.doesFileExist(filePath); fs.accessSync(filePath, fs.constants.W_OK); - const fileType = path.extname(filePath).toLowerCase(); - if (fileType === '.json') { - fs.writeFileSync(filePath, jsonView.toString(content), 'utf-8'); - } else if (fileType === '.yaml' || fileType === '.yml') { - yaml.dump(filePath, content); - } else { - throw new Error('ASK CLI does not support this file type.'); - } + fs.writeFileSync(filePath, jsonView.toString(content), 'utf-8'); } catch (error) { throw `Failed to write to file ${filePath}.\n${error.message}`; } diff --git a/test/unit/commands/dialog/index-test.js b/test/unit/commands/dialog/index-test.js index acb02ca8..bfb6239f 100644 --- a/test/unit/commands/dialog/index-test.js +++ b/test/unit/commands/dialog/index-test.js @@ -4,6 +4,7 @@ const path = require('path'); const AuthorizationController = require('@src/controllers/authorization-controller'); const DialogCommand = require('@src/commands/dialog'); +const DialogReplayFile = require('@src/model/dialog-replay-file'); const helper = require('@src/commands/dialog/helper'); const httpClient = require('@src/clients/http-client'); const InteractiveMode = require('@src/commands/dialog/interactive-mode'); @@ -220,6 +221,22 @@ describe('Commands Dialog test - command class test', () => { }); }); + it('| returns error when initialization of DialogReplayFile fails', (done) => { + // setup + const TEST_CMD_WITH_VALUES = { + stage: '', + replay: DIALOG_REPLAY_FILE_JSON_PATH + }; + const error = 'error'; + sinon.stub(DialogReplayFile.prototype, 'readFileContent').throws(new Error(error)); + // call + instance._getDialogConfig(TEST_CMD_WITH_VALUES, (err) => { + // verify + expect(err.message).eq(error); + done(); + }); + }); + it('| returns return error when smapi get manifest call fails', (done) => { // setup const TEST_CMD_WITH_VALUES = { diff --git a/test/unit/controller/dialog-controller/index-test.js b/test/unit/controller/dialog-controller/index-test.js index 88d3a3a1..03d487d0 100644 --- a/test/unit/controller/dialog-controller/index-test.js +++ b/test/unit/controller/dialog-controller/index-test.js @@ -244,22 +244,6 @@ describe('Controller test - dialog controller test', () => { expect(warnStub.args[0][0]).equal(`Unable to validate arguments: "${malFormedAppendQuitArgument}". ${RECORD_FORMAT}`); }); - it('| file is not of JSON type', () => { - // setup - const warnStub = sinon.stub(); - sinon.stub(Messenger, 'getInstance').returns({ - warn: warnStub - }); - sinon.stub(DialogReplView.prototype, 'registerRecordCommand'); - DialogReplView.prototype.registerRecordCommand.callsArgWith(0, 'file.yml'); - - // call - dialogController.setupSpecialCommands(dialogReplView, () => {}); - - // verify - expect(warnStub.args[0][0]).equal("File should be of type '.json'"); - }); - it('| replay file creation throws error', (done) => { // setup const infoStub = sinon.stub().throws(new Error(TEST_MSG)); diff --git a/test/unit/model/dialog-replay-file-test.js b/test/unit/model/dialog-replay-file-test.js index 96325fbe..71071c9b 100644 --- a/test/unit/model/dialog-replay-file-test.js +++ b/test/unit/model/dialog-replay-file-test.js @@ -2,7 +2,6 @@ const { expect } = require('chai'); const fs = require('fs-extra'); const path = require('path'); const sinon = require('sinon'); -const yaml = require('@src/model/yaml-parser'); const DialogReplayFile = require('@src/model/dialog-replay-file'); @@ -166,7 +165,7 @@ describe('Model test - dialog replay file test', () => { dialogReplayFile = new DialogReplayFile(NOT_EXISTING_DIALOG_REPLAY_FILE_PATH); } catch (error) { // verify - expect(error).equal(`Failed to parse .json file ${NOT_EXISTING_DIALOG_REPLAY_FILE_PATH}.` + expect(error).equal(`Failed to parse file: ${NOT_EXISTING_DIALOG_REPLAY_FILE_PATH}.` + `\nFile ${NOT_EXISTING_DIALOG_REPLAY_FILE_PATH} not exists.`); } }); @@ -179,14 +178,14 @@ describe('Model test - dialog replay file test', () => { dialogReplayFile = new DialogReplayFile(INVALID_JSON_DIALOG_REPLAY_FILE_PATH); } catch (error) { // verify - expect(error).equal(`Failed to parse .json file ${INVALID_JSON_DIALOG_REPLAY_FILE_PATH}.` + expect(error).equal(`Failed to parse file: ${INVALID_JSON_DIALOG_REPLAY_FILE_PATH}.` + `\n${TEST_ERROR}`); } }); it('| test JSON file path extension', () => { // setup - sinon.stub(fs, 'readFileSync').returns('{"skillId":"amzn1.ask.skill.1234567890"}'); + sinon.stub(fs, 'readJsonSync').returns({ skillId: 'amzn1.ask.skill.1234567890' }); // call dialogReplayFile = new DialogReplayFile(DIALOG_REPLAY_FILE_JSON_PATH); @@ -196,46 +195,6 @@ describe('Model test - dialog replay file test', () => { skillId: 'amzn1.ask.skill.1234567890' }); }); - - it('| test YAML file path extension', () => { - // setup - const YAML_FILE_PATH = path.join(FIXTURE_PATH, 'yaml-config.yaml'); - const yamlStub = sinon.stub(yaml, 'load'); - - // call - dialogReplayFile = new DialogReplayFile(YAML_FILE_PATH); - - // verify - expect(yamlStub.calledOnce).equal(true); - }); - - it('| test YML file path extension', () => { - // setup - const YML_FILE_PATH = path.join(FIXTURE_PATH, 'yaml-config.yml'); - const ymlStub = sinon.stub(yaml, 'load'); - - // call - dialogReplayFile = new DialogReplayFile(YML_FILE_PATH); - - // verify - expect(ymlStub.calledOnce).equal(true); - }); - - it(' throws error if neither JSON nor YAML/YML file path extension', () => { - // setup - sinon.stub(DialogReplayFile.prototype, 'doesFileExist'); - sinon.stub(fs, 'accessSync'); - const UNSUPPORTED_EXTENSION_FILE_PATH = path.join(FIXTURE_PATH, 'yaml-config.random'); - - try { - // call - dialogReplayFile = new DialogReplayFile(UNSUPPORTED_EXTENSION_FILE_PATH); - } catch (error) { - // verify - expect(error).equal(`Failed to parse .random file ${UNSUPPORTED_EXTENSION_FILE_PATH}.` - + '\nASK CLI does not support this file type.'); - } - }); }); describe('# test write file content', () => { @@ -288,49 +247,6 @@ describe('Model test - dialog replay file test', () => { // verify expect(writeFileStub.calledOnce).equal(true); }); - - it('| test YAML file path extension', () => { - // setup - const YAML_FILE_PATH = path.join(FIXTURE_PATH, 'yaml-config.yaml'); - const yamlStub = sinon.stub(yaml, 'dump'); - - // call - dialogReplayFile = new DialogReplayFile(YAML_FILE_PATH); - dialogReplayFile.writeContentToFile('', YAML_FILE_PATH); - - // verify - expect(yamlStub.calledOnce).equal(true); - }); - - it('| test YML file path extension', () => { - // setup - const YML_FILE_PATH = path.join(FIXTURE_PATH, 'yaml-config.yml'); - const ymlStub = sinon.stub(yaml, 'dump'); - - // call - dialogReplayFile = new DialogReplayFile(YML_FILE_PATH); - dialogReplayFile.writeContentToFile('', YML_FILE_PATH); - - // verify - expect(ymlStub.calledOnce).equal(true); - }); - - it(' throws error if neither JSON nor YAML/YML file path extension', () => { - // setup - sinon.stub(DialogReplayFile.prototype, 'doesFileExist'); - sinon.stub(fs, 'accessSync'); - const UNSUPPORTED_EXTENSION_FILE_PATH = path.join(FIXTURE_PATH, 'yaml-config.random'); - - try { - // call - dialogReplayFile = new DialogReplayFile(UNSUPPORTED_EXTENSION_FILE_PATH); - dialogReplayFile.writeContentToFile('', UNSUPPORTED_EXTENSION_FILE_PATH); - } catch (error) { - // verify - expect(error).equal(`Failed to write to file ${UNSUPPORTED_EXTENSION_FILE_PATH}.` - + '\nASK CLI does not support this file type.'); - } - }); }); }); });