Skip to content

Commit

Permalink
fix(interactions): check fulfilled state to trigger onComplete callba…
Browse files Browse the repository at this point in the history
…ck (#1122)

* Fulfilled state trigger onComplete callback

* Check onComplete callback is called after sendMessage response

* Removing setTimeout mock for runAllTimers

* Removing setTimeout mock for runAllTimers
  • Loading branch information
elorzafe authored and manueliglesias committed Jun 27, 2018
1 parent 84e5df9 commit c24b1f1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ jest.mock('aws-sdk/clients/lexruntime', () => {
});

import Interactions from '../../src/Interactions/Interactions';
import { findInterfacesAddedToObjectTypes } from 'graphql/utilities/findBreakingChanges';
import Auth from '../../src/Auth/Auth';
import { AWSLexProvider, AbstractInteractionsProvider } from '../../src/Interactions/Providers';

Expand Down Expand Up @@ -156,11 +155,14 @@ describe('Interactions', () => {
});

describe('Sending messages to bot', () => {
test('Interactions configuration and send message to existing bot and call onComplete from Interaction.onComplete', async () => {
test('Interactions configuration and send message to existing bot and call onComplete from Interaction.onComplete', async (done) => {
const curCredSpyOn = jest.spyOn(Auth.prototype, 'currentCredentials')
.mockImplementation(() => Promise.resolve({ identityId: '1234' }));

const onComplete = jest.fn((err, confirmation) => { });
.mockImplementation(() => Promise.resolve({ identityId: '1234' }));

const onCompleteCallback = jest.fn((err, confirmation) => {
expect(confirmation).toEqual({ "slots": { "m1": "hi", "m2": "done" } });
done();
});

const configuration = {
Interactions: {
Expand All @@ -180,10 +182,10 @@ describe('Interactions', () => {
const config = interactions.configure(configuration);

expect(config).toEqual(configuration.Interactions);
interactions.onComplete('BookTripMOBILEHUB', onComplete);
interactions.onComplete('BookTripMOBILEHUB', onCompleteCallback);
await interactions.send('BookTripMOBILEHUB', 'hi')
const response = await interactions.send('BookTripMOBILEHUB', 'done');

jest.runAllTimers();
expect(response).toEqual({
dialogState: 'ReadyForFulfillment',
message: 'echo:done',
Expand All @@ -193,22 +195,24 @@ describe('Interactions', () => {
}
});

expect(onComplete).toBeCalledWith(null, { "slots": { "m1": "hi", "m2": "done" } });
});
test('Interactions configuration and send message to existing bot and call onComplete from configure onComplete', async () => {
test('Interactions configuration and send message to existing bot and call onComplete from configure onComplete', async (done) => {
const curCredSpyOn = jest.spyOn(Auth.prototype, 'currentCredentials')
.mockImplementation(() => Promise.resolve({ identityId: '1234' }));

const onComplete = jest.fn((err, confirmation) => { });

.mockImplementation(() => Promise.resolve({ identityId: '1234' }));

const onCompleteCallback = jest.fn((err, confirmation) => {
expect(confirmation).toEqual({ "slots": { "m1": "hi", "m2": "done" } });
done();
});

const configuration = {
Interactions: {
'bots': {
"BookTripMOBILEHUB": {
"name": "BookTripMOBILEHUB",
"alias": "$LATEST",
"region": "us-east-1",
"onComplete": onComplete
"onComplete": onCompleteCallback
}

}
Expand All @@ -223,7 +227,7 @@ describe('Interactions', () => {

await interactions.send('BookTripMOBILEHUB', 'hi')
const response = await interactions.send('BookTripMOBILEHUB', 'done');

jest.runAllTimers();
expect(response).toEqual({
dialogState: 'ReadyForFulfillment',
message: 'echo:done',
Expand All @@ -233,7 +237,6 @@ describe('Interactions', () => {
}
});

expect(onComplete).toBeCalledWith(null, { "slots": { "m1": "hi", "m2": "done" } });
});

test('aws-exports configuration and send message to not existing bot', async () => {
Expand Down Expand Up @@ -271,7 +274,7 @@ describe('Interactions', () => {
expect(config).toEqual({"aws_bots": "enable", "aws_bots_config": [{"alias": "$LATEST", "bot-template": "bot-trips", "commands-help": ["Book a car", "Reserve a car", "Make a car reservation", "Book a hotel", "Reserve a room", "I want to make a hotel reservation"], "description": "Bot to make reservations for a visit to a city.", "name": "BookTripMOBILEHUB", "region": "us-east-1"}], "aws_project_name": "bots", "aws_project_region": "us-east-1", "bots": {"BookTripMOBILEHUB": {"alias": "$LATEST", "bot-template": "bot-trips", "commands-help": ["Book a car", "Reserve a car", "Make a car reservation", "Book a hotel", "Reserve a room", "I want to make a hotel reservation"], "description": "Bot to make reservations for a visit to a city.", "name": "BookTripMOBILEHUB", "region": "us-east-1"}}});

try {
await interactions.onComplete('BookTrip');
await interactions.onComplete('BookTrip', () => {});
} catch (err) {
expect(err.message).toEqual('Bot BookTrip does not exist');
}
Expand Down
8 changes: 4 additions & 4 deletions packages/aws-amplify/src/Interactions/Interactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default class Interactions {
}

public async send(botname: string, message: string | Object) {
if (!this._options.bots[botname]) {
if (!this._options.bots || !this._options.bots[botname]) {
throw new Error('Bot ' + botname + ' does not exist');
}

Expand All @@ -96,8 +96,8 @@ export default class Interactions {

}

public async onComplete(botname: string, callback: (err, confirmation) => void) {
if (!this._options.bots[botname]) {
public onComplete(botname: string, callback: (err, confirmation) => void) {
if (!this._options.bots || !this._options.bots[botname]) {
throw new Error('Bot ' + botname + ' does not exist');
}
const botProvider = this._options.bots[botname].providerName || 'AWSLexProvider';
Expand All @@ -106,7 +106,7 @@ export default class Interactions {
throw new Error('Bot ' + botProvider +
' does not have valid pluggin did you try addPluggable first?');
}
return this._pluggables[botProvider].onComplete(botname, callback);
this._pluggables[botProvider].onComplete(botname, callback);

}
}
25 changes: 14 additions & 11 deletions packages/aws-amplify/src/Interactions/Providers/AWSLexProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,32 +57,35 @@ export class AWSLexProvider extends AbstractInteractionsProvider {

this.aws_lex.postText(params, (err, data) => {
if (err) {
throw err;
rej(err);
return;

} else {
// Check if state is fulfilled to resolve onFullfilment promise
if (data.dialogState === 'ReadyForFulfillment') {
logger.debug('ReadyForFulfillment');
logger.debug('postText state', data.dialogState);
if (data.dialogState === 'ReadyForFulfillment' || data.dialogState === 'Fulfilled') {
if (typeof this._botsCompleteCallback[botname] === 'function') {
this._botsCompleteCallback[botname](null, { slots: data.slots });
setTimeout(() => this._botsCompleteCallback[botname](null, { slots: data.slots }), 0);
}

if (this._config && typeof this._config[botname].onComplete === 'function') {
this._config[botname].onComplete(null, { slots: data.slots });
setTimeout(() => this._config[botname].onComplete(null, { slots: data.slots }), 0);
}
}


res(data);
if (data.dialogState === 'Failed') {

if (typeof this._botsCompleteCallback[botname] === 'function') {
this._botsCompleteCallback[botname]({ err: 'Bot conversation failed' });
setTimeout(
() => this._botsCompleteCallback[botname]('Bot conversation failed'), 0);
}

if (this._config && typeof this._config[botname].onComplete === 'function') {
this._config[botname].onComplete('Bot conversation failed');
setTimeout(() => this._config[botname].onComplete('Bot conversation failed'), 0);
}
}

res(data);
}
});
} else {
Expand Down

0 comments on commit c24b1f1

Please sign in to comment.