alexa-app
Version:
A module to simplify creation of Alexa (Amazon Echo) apps (Skills) using Node.js
765 lines (711 loc) • 22.3 kB
JavaScript
/*jshint expr: true*/
;
var chai = require("chai");
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
var expect = chai.expect;
chai.config.includeStack = true;
import * as Alexa from "..";
describe("Alexa", function() {
describe("app", function() {
var testApp = new Alexa.app("testApp");
beforeEach(function() {
testApp = new Alexa.app("testApp");
});
describe("#schema", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent");
testApp.intent("testIntentTwo", {
"slots": {
"MyCustomSlotType": "CUSTOMTYPE",
"Tubular": "AMAZON.LITERAL",
"Radical": "AMAZON.US_STATE"
}
});
testApp.intent("testIntent", {
"slots": {
"AirportCode": "FAACODES",
"Awesome": "AMAZON.DATE",
"Tubular": "AMAZON.LITERAL"
},
});
});
it("calls the intent schema as the default", function() {
var subject = JSON.parse(testApp.schema());
expect(subject).to.eql({
"intents": [{
"intent": "AMAZON.PauseIntent",
}, {
"intent": "testIntentTwo",
"slots": [{
"name": "MyCustomSlotType",
"type": "CUSTOMTYPE"
}, {
"name": "Tubular",
"type": "AMAZON.LITERAL"
}, {
"name": "Radical",
"type": "AMAZON.US_STATE"
}]
}, {
"intent": "testIntent",
"slots": [{
"name": "AirportCode",
"type": "FAACODES"
}, {
"name": "Awesome",
"type": "AMAZON.DATE"
}, {
"name": "Tubular",
"type": "AMAZON.LITERAL"
}]
}]
});
});
});
describe("#schemas.intent", function() {
describe("with a minimum intent", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent");
});
it("contains no slots", function() {
var subject = JSON.parse(testApp.schemas.intent());
expect(subject).to.eql({
"intents": [{
"intent": "AMAZON.PauseIntent"
}]
});
});
});
describe("with empty slots", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent", {
"slots": {}
});
});
it("contains no slots", function() {
var subject = JSON.parse(testApp.schemas.intent());
expect(subject).to.eql({
"intents": [{
"intent": "AMAZON.PauseIntent"
}]
});
});
});
describe("with a slot", function() {
beforeEach(function() {
testApp.intent("testIntent", {
"slots": {
"MyCustomSlotType": "CUSTOMTYPE",
"Tubular": "AMAZON.LITERAL",
"Radical": "AMAZON.US_STATE",
},
});
});
it("includes slots", function() {
var subject = JSON.parse(testApp.schemas.intent());
expect(subject).to.eql({
"intents": [{
"intent": "testIntent",
"slots": [{
"name": "MyCustomSlotType",
"type": "CUSTOMTYPE"
}, {
"name": "Tubular",
"type": "AMAZON.LITERAL"
}, {
"name": "Radical",
"type": "AMAZON.US_STATE"
}]
}]
});
});
});
describe("with multiple intents", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent");
testApp.intent("testIntentTwo", {
"slots": {
"MyCustomSlotType": "CUSTOMTYPE",
"Tubular": "AMAZON.LITERAL",
"Radical": "AMAZON.US_STATE"
}
});
testApp.intent("testIntent", {
"slots": {
"AirportCode": "FAACODES",
"Awesome": "AMAZON.DATE",
"Tubular": "AMAZON.LITERAL"
},
});
});
it("generates the expected schema", function() {
var subject = JSON.parse(testApp.schemas.intent());
expect(subject).to.eql({
"intents": [{
"intent": "AMAZON.PauseIntent",
}, {
"intent": "testIntentTwo",
"slots": [{
"name": "MyCustomSlotType",
"type": "CUSTOMTYPE"
}, {
"name": "Tubular",
"type": "AMAZON.LITERAL"
}, {
"name": "Radical",
"type": "AMAZON.US_STATE"
}]
}, {
"intent": "testIntent",
"slots": [{
"name": "AirportCode",
"type": "FAACODES"
}, {
"name": "Awesome",
"type": "AMAZON.DATE"
}, {
"name": "Tubular",
"type": "AMAZON.LITERAL"
}]
}]
});
});
});
});
describe("#schemas.skillBuilder", function() {
describe("with a minimum intent", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent");
});
it("contains no slots", function() {
var subject = JSON.parse(testApp.schemas.skillBuilder());
expect(subject).to.eql({
"intents": [{
"name": "AMAZON.PauseIntent",
"samples": []
}],
"types": []
});
});
});
describe("with empty slots", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent", {
"slots": {}
});
});
it("contains no slots", function() {
var subject = JSON.parse(testApp.schemas.skillBuilder());
expect(subject).to.eql({
"intents": [{
"name": "AMAZON.PauseIntent",
"samples": []
}],
"types": []
});
});
});
describe("with a slot", function() {
beforeEach(function() {
testApp.intent("testIntent", {
"slots": {
"Tubular": "AMAZON.LITERAL",
"Radical": "AMAZON.US_STATE"
},
});
});
it("includes slots", function() {
var subject = JSON.parse(testApp.schemas.skillBuilder());
expect(subject).to.eql({
"intents": [{
"name": "testIntent",
"samples": [],
"slots": [{
"name": "Tubular",
"type": "AMAZON.LITERAL",
"samples": []
}, {
"name": "Radical",
"type": "AMAZON.US_STATE",
"samples": []
}]
}],
"types": []
});
});
});
describe("with simple utterances", function() {
beforeEach(function() {
testApp.intent("testIntent", {
"utterances": ["turn on the thermostat", "kill all humans"]
});
});
it("contains utterances", function() {
var subject = JSON.parse(testApp.schemas.skillBuilder());
expect(subject).to.eql({
"intents": [{
"name": "testIntent",
"samples": [
"turn on the thermostat",
"kill all humans"
]
}],
"types": []
});
});
});
describe("with multiple intents", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent");
testApp.intent("testIntentTwo", {
"slots": {
"MyCustomSlotType": "CUSTOMTYPE",
"Tubular": "AMAZON.LITERAL",
"Radical": "AMAZON.US_STATE"
},
});
testApp.intent("testIntent", {
"slots": {
"AirportCode": "FAACODES",
"Awesome": "AMAZON.DATE",
"Tubular": "AMAZON.LITERAL"
},
});
});
it("generates the expected schema", function() {
var subject = JSON.parse(testApp.schemas.skillBuilder());
expect(subject).to.eql({
"intents": [{
"name": "AMAZON.PauseIntent",
"samples": []
}, {
"name": "testIntentTwo",
"samples": [],
"slots": [{
"name": "MyCustomSlotType",
"type": "CUSTOMTYPE",
"samples": []
}, {
"name": "Tubular",
"type": "AMAZON.LITERAL",
"samples": []
}, {
"name": "Radical",
"type": "AMAZON.US_STATE",
"samples": []
}]
}, {
"name": "testIntent",
"samples": [],
"slots": [{
"name": "AirportCode",
"type": "FAACODES",
"samples": []
}, {
"name": "Awesome",
"type": "AMAZON.DATE",
"samples": []
}, {
"name": "Tubular",
"type": "AMAZON.LITERAL",
"samples": []
}]
}],
"types": []
});
});
});
describe("with a custom slot", function() {
beforeEach(function() {
testApp.customSlot("animal", [
"cat", {
value: "dog",
id: "canine",
synonyms: ["doggo", "pupper", "woofmeister"]
}
]);
});
it("includes custom slots", function() {
var subject = JSON.parse(testApp.schemas.skillBuilder());
expect(subject).to.eql({
"intents": [],
"types": [{
"name": "animal",
"values": [{
"id": null,
"name": {
"value": "cat",
"synonyms": []
}
}, {
"id": "canine",
"name": {
"value": "dog",
"synonyms": ["doggo", "pupper", "woofmeister"]
}
}]
}]
});
});
describe("with multiple custom slots", function() {
beforeEach(function() {
testApp.customSlot("animal", [
"cat", {
value: "dog",
id: "canine",
synonyms: ["doggo", "pupper", "woofmeister"]
}
]);
testApp.customSlot("vegetable", ["carrot", "cucumber"]);
});
it("includes all custom slots", function() {
var subject = JSON.parse(testApp.schemas.skillBuilder());
expect(subject).to.eql({
"intents": [],
"types": [{
"name": "animal",
"values": [{
"id": null,
"name": {
"value": "cat",
"synonyms": []
}
}, {
"id": "canine",
"name": {
"value": "dog",
"synonyms": ["doggo", "pupper", "woofmeister"]
}
}]
}, {
"name": "vegetable",
"values": [{
"id": null,
"name": {
"value": "carrot",
"synonyms": []
}
}, {
"id": null,
"name": {
"value": "cucumber",
"synonyms": []
}
}]
}]
});
});
});
});
});
describe("#schemas.askcli", function() {
describe("the invocation name", function() {
context("when no invocation name is set", function() {
it("should use the app name", function() {
var subject = JSON.parse(testApp.schemas.askcli());
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "testApp",
"intents": [],
"types": []
}
}
});
})
})
context("when the app's invocationName is set", function() {
beforeEach(function() {
testApp.invocationName = "my cool skill";
})
it("should use the invocationName", function() {
var subject = JSON.parse(testApp.schemas.askcli());
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "my cool skill",
"intents": [],
"types": []
}
}
});
})
context("when a custom invocation name is passed in", function() {
it("should override the app's setting", function() {
var subject = JSON.parse(testApp.schemas.askcli("my okay skill"));
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "my okay skill",
"intents": [],
"types": []
}
}
});
})
})
})
});
describe("with a minimum intent", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent");
});
it("contains no slots", function() {
var subject = JSON.parse(testApp.schemas.askcli());
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "testApp",
"intents": [{
"name": "AMAZON.PauseIntent",
"samples": []
}],
"types": []
}
}
});
});
});
describe("with empty slots", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent", {
"slots": {}
});
});
it("contains no slots", function() {
var subject = JSON.parse(testApp.schemas.askcli());
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "testApp",
"intents": [{
"name": "AMAZON.PauseIntent",
"samples": []
}],
"types": []
}
}
});
});
});
describe("with a slot", function() {
beforeEach(function() {
testApp.intent("testIntent", {
"slots": {
"Tubular": "AMAZON.LITERAL",
"Radical": "AMAZON.US_STATE"
},
});
});
it("includes slots", function() {
var subject = JSON.parse(testApp.schemas.askcli());
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "testApp",
"intents": [{
"name": "testIntent",
"samples": [],
"slots": [{
"name": "Tubular",
"type": "AMAZON.LITERAL",
"samples": []
}, {
"name": "Radical",
"type": "AMAZON.US_STATE",
"samples": []
}]
}],
"types": []
}
}
});
});
});
describe("with simple utterances", function() {
beforeEach(function() {
testApp.intent("testIntent", {
"utterances": ["turn on the thermostat", "kill all humans"]
});
});
it("contains utterances", function() {
var subject = JSON.parse(testApp.schemas.askcli());
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "testApp",
"intents": [{
"name": "testIntent",
"samples": [
"turn on the thermostat",
"kill all humans"
]
}],
"types": []
}
}
});
});
});
describe("with multiple intents", function() {
beforeEach(function() {
testApp.intent("AMAZON.PauseIntent");
testApp.intent("testIntentTwo", {
"slots": {
"MyCustomSlotType": "CUSTOMTYPE",
"Tubular": "AMAZON.LITERAL",
"Radical": "AMAZON.US_STATE"
},
});
testApp.intent("testIntent", {
"slots": {
"AirportCode": "FAACODES",
"Awesome": "AMAZON.DATE",
"Tubular": "AMAZON.LITERAL"
},
});
});
it("generates the expected schema", function() {
var subject = JSON.parse(testApp.schemas.askcli());
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "testApp",
"intents": [{
"name": "AMAZON.PauseIntent",
"samples": []
}, {
"name": "testIntentTwo",
"samples": [],
"slots": [{
"name": "MyCustomSlotType",
"type": "CUSTOMTYPE",
"samples": []
}, {
"name": "Tubular",
"type": "AMAZON.LITERAL",
"samples": []
}, {
"name": "Radical",
"type": "AMAZON.US_STATE",
"samples": []
}]
}, {
"name": "testIntent",
"samples": [],
"slots": [{
"name": "AirportCode",
"type": "FAACODES",
"samples": []
}, {
"name": "Awesome",
"type": "AMAZON.DATE",
"samples": []
}, {
"name": "Tubular",
"type": "AMAZON.LITERAL",
"samples": []
}]
}],
"types": []
}
}
});
});
});
describe("with a custom slot", function() {
beforeEach(function() {
testApp.customSlot("animal", [
"cat", {
value: "dog",
id: "canine",
synonyms: ["doggo", "pupper", "woofmeister"]
}
]);
});
it("includes custom slots", function() {
var subject = JSON.parse(testApp.schemas.askcli());
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "testApp",
"intents": [],
"types": [{
"name": "animal",
"values": [{
"id": null,
"name": {
"value": "cat",
"synonyms": []
}
}, {
"id": "canine",
"name": {
"value": "dog",
"synonyms": ["doggo", "pupper", "woofmeister"]
}
}]
}]
}
}
});
});
describe("with multiple custom slots", function() {
beforeEach(function() {
testApp.customSlot("animal", [
"cat", {
value: "dog",
id: "canine",
synonyms: ["doggo", "pupper", "woofmeister"]
}
]);
testApp.customSlot("vegetable", ["carrot", "cucumber"]);
});
it("includes all custom slots", function() {
var subject = JSON.parse(testApp.schemas.askcli());
expect(subject).to.eql({
"interactionModel": {
"languageModel": {
"invocationName": "testApp",
"intents": [],
"types": [{
"name": "animal",
"values": [{
"id": null,
"name": {
"value": "cat",
"synonyms": []
}
}, {
"id": "canine",
"name": {
"value": "dog",
"synonyms": ["doggo", "pupper", "woofmeister"]
}
}]
}, {
"name": "vegetable",
"values": [{
"id": null,
"name": {
"value": "carrot",
"synonyms": []
}
}, {
"id": null,
"name": {
"value": "cucumber",
"synonyms": []
}
}]
}]
}
}
});
});
});
});
});
});
});