diff --git a/.env.sample b/.env.sample index 92347a9..0a0d4ba 100644 --- a/.env.sample +++ b/.env.sample @@ -1,7 +1,7 @@ # PORT=10011 -# Application (expertise) name +# Application (skill) name APP_NAME= # diff --git a/actions.js b/actions.js index ad91523..9d7aa39 100755 --- a/actions.js +++ b/actions.js @@ -100,7 +100,7 @@ const stateDefaultActions = handler.createActionsHandler({ evaluation: (request, evaluationResponse, context) => { handler.evaluateRequest(request, evaluationResponse, context, evaluationCallback); }, - // pre processing for entity based routing + // this is the entities action, routing by entity will lead here entities: (request, response, context) => { handler.converse(request, response, context, converseCallback); } diff --git a/package.json b/package.json index 0905bb3..956afd9 100755 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "scripts": { "start": "node index.js", "debug": "node $NODE_DEBUG_OPTION index.js", - "test": "mocha 'test/**/*.js' && ./node_modules/jscs/bin/jscs . && ./node_modules/jshint/bin/jshint ." + "test": "mocha 'test/**/*.js'" }, "engines": { "node": "6.10.0" diff --git a/res/assets/manifest.json b/res/assets/manifest.json index 2424f2b..eb06fc7 100755 --- a/res/assets/manifest.json +++ b/res/assets/manifest.json @@ -9,7 +9,7 @@ "en-US" ], "nlu": [ - "skill", "regexp", "wcs" + "skill", "regexp" ], "tags": [ "hello world" diff --git a/res/nlu/engines/example/nlu.js b/res/nlu/engines/example/nlu.js index 05752b8..574a5a3 100644 --- a/res/nlu/engines/example/nlu.js +++ b/res/nlu/engines/example/nlu.js @@ -35,7 +35,12 @@ class Nlu extends Base { * @param cb - is expected to be called with the following parameters: * 1. err * 2. an intentity object - * 3. output/response - this is optional, this could save a call to the nlu in the actions.js file + * 3. output/response - this is optional, this could save a call to the nlu in the actions.js file, + * it needs to be and object with the following structure: + * { + * text: "string", + * context: {} + * } */ evaluate(request, cb) { let confidence = request.retext === 'hello' ? 1 : 0; diff --git a/setup-wizard.js b/setup-wizard.js index 0d3274c..7de1ad2 100755 --- a/setup-wizard.js +++ b/setup-wizard.js @@ -203,8 +203,24 @@ inquirer.prompt(questions).then(function(response) { } console.log('Push script saved'); }); + } + fs.readFile('package.json', 'utf8', function (err, data) { + if (err) { + return console.log(err); + } + let packageJSON = JSON.parse(data); + packageJSON.name = skillName; + packageJSON.author = author; + fs.writeFile('package.json', JSON.stringify(packageJSON, null, 2), function (err) { + if (err) { + return console.log(err); + } + console.log('package.json saved'); + }); + }); + setTimeout(function() { console.log('\n----------- Your skill is ready to go! ------------\n'); }, 500); diff --git a/skill_debugger_tool/README.txt b/skill_debugger_tool/README.txt new file mode 100644 index 0000000..a583073 --- /dev/null +++ b/skill_debugger_tool/README.txt @@ -0,0 +1,24 @@ + + +---------------------------------------- Skill Debugger Tool --------------------------------------------------- + +The Skill Debugger Tool is a standalone app that can be used to converse with your skill when your are running +it locally, it handles all requests to the skill and manages the context. + + +-- Usage -- + +1. Run your skill (using npm start) +2. Open the Skill Debugger Tool file according to your operating system +3. Make sure the skill url is set to the correct url + 3.1 The default skill url is http://localhost:10011 + 3.2 If you would like to change the url go to File -> Skill url +4. If your skill uses authentication make sure to add the skill key, go to File -> Skill key +5. In the Converse request box enter your request + 5.1 If you would like to add/change context for your request you can do so in the Context box +6. Click Submit request to send your request to the skill +7. See the result + 7.1 You can toggle between the Converse response and the Evaluation response + 7.2 The context will be updated automatically + 7.3 All previous requests are shown in the Previous requests box - the Previous requests list can be cleared, + just go to File -> Clear previous requests \ No newline at end of file diff --git a/skill_debugger_tool/Windows/skill_debugger.exe b/skill_debugger_tool/Windows/skill_debugger.exe new file mode 100644 index 0000000..ddc9831 Binary files /dev/null and b/skill_debugger_tool/Windows/skill_debugger.exe differ diff --git a/skill_debugger_tool/macOS/skill_debugger b/skill_debugger_tool/macOS/skill_debugger new file mode 100755 index 0000000..22b9f71 Binary files /dev/null and b/skill_debugger_tool/macOS/skill_debugger differ diff --git a/test/actions.js b/test/actions.js index d5d9738..e24fd65 100755 --- a/test/actions.js +++ b/test/actions.js @@ -7,55 +7,135 @@ const should = require('should'); const request = require('supertest'); const {server} = require('skill-sdk-nodejs'); - +const utteranceFile = require('./utterance-tests.json'); +const skillManifest = require(process.env.skillSDKResDir + '/assets/manifest'); // Bring the actions require('..'); describe('actions', function() { - describe('converse', function() { - - it('intent hello-world us-EN', function(done) { + describe('converse', function() { + for (let test of utteranceFile.tests) { + it('Test description: ' + test.testDescription +', intent ' + test.intent + ' with utterance: ' + '\'' + + test.utterance + '\'' + ', should return: '+ '\'' +test.expectedResponse + '\'', function(done) { + let attributes = { + "intent": test.intent + }; + for (let entity of test.entities) { + attributes[entity.entity] = entity.value; + } + request(server) + .post('/v1/api/converse') + .send({ + id: '001', + text: test.utterance, + retext: test.utterance, + version: '1.0', + language: 'en-US', + attributes: attributes, + context: { + user: { + id: '12345678', + }, + application: { + id: '002', + attributes: {} + }, + session: { + new: true, + attributes: { + }, + version: '1.0' + } + } + }) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .end(function(err, res) { + should.not.exist(err); + res.body.should.have.property('speech'); + res.body.speech.text.should.match(test.expectedResponse); + done(); + }); + }); + } + }); - request(server) - .post('/v1/api/converse') - .send({ - id: '001', - text: 'hello world', - retext: 'hello world', - version: '1.0', - language: 'en-US', - attributes: { - intent: 'hello-world' - }, - context: { - user: { - id: '12345678', - }, - application: { - id: '002', - attributes: {} - }, - session: { - new: true, - attributes: { - }, - version: '1.0' - } - } - }) - .set('Accept', 'application/json') - .expect('Content-Type', /json/) - .expect(200) - .end(function(err, res) { - should.not.exist(err); - res.body.should.have.property('speech'); - res.body.speech.text.should.match('Hello world'); - res.body.should.have.property('deleteSkillSession').which.be.exactly(true); - done(); +}); +describe('Manifest', function() { + it('Exists', function(done) { + request(server) + .get('/v1/api/manifest') + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .end(function(err, res) { + should.not.exist(err); + res.body.should.have.property('author'); + res.body.should.have.property('description'); + res.body.should.have.property('threshold'); + res.body.should.have.property('nlu'); + res.body.should.have.property('version'); + done(); + }); + }); +}); +describe('NLU', function() { + if(skillManifest.nlu.indexOf('wcs') !== -1) { + it('wcs', function (done) { + request(server) + .get('/v1/api/nlu?type=wcs') + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + should.not.exist(err); + res.body.should.have.property('workspace'); + res.body.should.have.property('credentials'); + res.body.credentials.should.have.property('url'); + res.body.credentials.should.have.property('version'); + res.body.credentials.should.have.property('version_date'); + should.notEqual(res.body.credentials.username, 'your wcs username', 'Username is not set.'); + should.notEqual(res.body.credentials.password, 'your wcs password', 'Password is not set.'); + should.notEqual(res.body.credentials.url, 'your wcs url', 'Url is not set.'); + should.equal(res.body.credentials.version, 'v1', 'Should be \'v1\'.'); + done(); + }); }); + } + if(skillManifest.nlu.indexOf('regexp') !== -1) { + it('regexp', function (done) { + request(server) + .get('/v1/api/nlu?type=regexp') + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .end(function (err, res) { + should.not.exist(err); + done(); + }); + }); + } + it('intents', function(done) { + request(server) + .get('/v1/api/intents') + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200) + .end(function(err, res) { + should.not.exist(err); + done(); + }); + }); +}); +describe('Healthcheck', function() { + it('Healthcheck', function(done) { + request(server) + .get('/v1/api/healthcheck') + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200); + done(); }); - - }); - }); diff --git a/test/utterance-tests.json b/test/utterance-tests.json new file mode 100644 index 0000000..d9231c3 --- /dev/null +++ b/test/utterance-tests.json @@ -0,0 +1,12 @@ +{ + "tests": + [ + { + "testDescription": "Testing hello world", + "utterance": "Hello", + "intent" : "hello-world", + "entities" : [{"entity":"hello", "value": "world"}], + "expectedResponse": "Hello world" + } + ] +}