Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: removing restriction for replay file to have .json extension #354

Merged
merged 2 commits into from
Dec 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/commands/dialog/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')));
Expand Down
12 changes: 4 additions & 8 deletions lib/commands/option-model.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,15 @@
},
"skill-id": {
"name": "skill-id",
"description": "The skill ID.",
"description": "Skill id",
"alias": "s",
"stringInput": "REQUIRED"
},
"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",
Expand All @@ -64,7 +60,7 @@
},
"stage": {
"name": "stage",
"description": "Stage for skill.",
"description": "Skill stage",
"alias": "g",
"stringInput": "REQUIRED",
"rule": [{
Expand Down
6 changes: 0 additions & 6 deletions lib/controllers/dialog-controller/index.js
Original file line number Diff line number Diff line change
@@ -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');
Expand Down Expand Up @@ -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}`);
Expand Down
23 changes: 3 additions & 20 deletions lib/model/dialog-replay-file.js
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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}`;
}
}

Expand All @@ -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}`;
}
Expand Down
18 changes: 18 additions & 0 deletions test/unit/commands/dialog/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -220,6 +221,23 @@ 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(profileHelper, 'runtimeProfile').returns(TEST_PROFILE);
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 = {
Expand Down
16 changes: 0 additions & 16 deletions test/unit/controller/dialog-controller/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
90 changes: 3 additions & 87 deletions test/unit/model/dialog-replay-file-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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.`);
}
});
Expand All @@ -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);
Expand All @@ -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', () => {
Expand Down Expand Up @@ -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.');
}
});
});
});
});