Skip to content
This repository has been archived by the owner on Aug 30, 2024. It is now read-only.

Commit

Permalink
Tests all paths
Browse files Browse the repository at this point in the history
  • Loading branch information
Oren Montano committed Apr 29, 2022
1 parent fee0452 commit 1752f5a
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 60 deletions.
20 changes: 3 additions & 17 deletions lambda/conversation/reportOutage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,9 @@ const {
guard,
} = require('robot3')
const { utils } = require('@ocelot-consulting/ocelot-voice-framework')
const { reportOutageAPI } = require('../service/reportOutageAPI')
const { fakePhoneNumber, fakeWebsite } = require('../constants')

const callOutageApi = async ({houseNumber, phoneNumber}) => {
console.log('outage reported', houseNumber, phoneNumber)

return [{
result: 'noOutage'
}, {
result: 'yesOutage',
impact: '300',
areaDescription: 'The pines neighborhood north of Park Street',
workDescription: 'Crews are on the scenen and expect repairs to complete in about an hour.'
}, {
result: 'badCombination'
}][houseNumber % 3]
}

const stateMap = {
fresh: state(
transition('processIntent', 'askForHouseNumber')
Expand Down Expand Up @@ -80,7 +66,7 @@ const stateMap = {
transition('processIntent', 'goBack',
guard(({ misunderstandingCount }, { intent }) => intent.name === 'GoBackIntent' || misunderstandingCount > 3)
),
transition('processIntent', 'letYouKnow',
transition('processIntent', 'letYouKnowWOutageReport',
reduce(ctx => ({ ...ctx, misunderstandingCount: ctx.misunderstandingCount + 1 })),
),
),
Expand Down Expand Up @@ -116,7 +102,7 @@ const stateMap = {
reduce(ctx => ({ ...ctx, misunderstandingCount: ctx.misunderstandingCount + 1 })),
),
),
gotAllData: invoke(callOutageApi,
gotAllData: invoke(reportOutageAPI,
transition('done', 'reportAnOutage',
guard((ctx, {data: { result }}) => result === 'noOutage'),
reduce((ctx, { data }) => ({ ...ctx, attemptCount: ctx.attemptCount + 1 })),),
Expand Down
19 changes: 19 additions & 0 deletions lambda/service/reportOutageAPI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@


// replace this with an api call
const reportOutageAPI = async ({houseNumber, phoneNumber}) => {
//console.log('outage reported', houseNumber, phoneNumber)

return [{
result: 'noOutage'
}, {
result: 'yesOutage',
impact: '300',
areaDescription: 'The pines neighborhood north of Park Street',
workDescription: 'Crews are on the scenen and expect repairs to complete in about an hour.'
}, {
result: 'badCombination'
}][houseNumber % 3]
}

module.exports = { reportOutageAPI }
278 changes: 235 additions & 43 deletions lambda/test/conversation/reportOutage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,45 @@ const {

const { defaultNumberIntent, defaultPhoneNumberIntent, defaultYesNoIntent } = require('../util/defaults');

const clearResponseMocks = () => {
handlerInput.responseBuilder.speak.mockClear()
handlerInput.responseBuilder.reprompt.mockClear()
handlerInput.responseBuilder.addElicitSlotDirective.mockClear()
handlerInput.responseBuilder.addConfirmSlotDirective.mockClear()
handlerInput.responseBuilder.withShouldEndSession.mockClear()
handlerInput.responseBuilder.getResponse.mockClear()
}

describe('Report Outage Conversation Tests', () => {
beforeAll(async () => {
handlerInput.attributesManager.setRequestAttributes({
'home.welcome': 'home.welcome',
'home.engage': 'home.engage',
'home.promptResume': 'home.promptResume',
'home.welcome': 'home.welcome',
'home.reEngage': 'home.reEngage',
'home.error': 'home.error',
'confirmAddress.confirm': 'confirmAddress.confirm',
'confirmAddress.misheard': 'confirmAddress.misheard',
'reportOutage.wrongAddress': 'reportOutage.wrongAddress',
'reportOutage.reply.withContact': 'reportOutage.reply.withContact',
'reportOutage.reply.noContact': 'reportOutage.reply.noContact',
'reportOutage.askForHouseNumber.confirm': 'reportOutage.askForHouseNumber.confirm',
'reportOutage.askForHouseNumber.misheard': 'reportOutage.askForHouseNumber.misheard',
'reportOutage.askForTelephoneNumber.confirm': 'reportOutage.askForTelephoneNumber.confirm',
'reportOutage.askForTelephoneNumber.misheard': 'reportOutage.askForTelephoneNumber.misheard',
'reportOutage.letYouKnowWOutageReport.confirm': 'reportOutage.letYouKnowWOutageReport.confirm',
'reportOutage.letYouKnowWOutageReport.misheard': 'reportOutage.letYouKnowWOutageReport.misheard',
'reportOutage.tryAgain.confirm': 'reportOutage.tryAgain.confirm',
'reportOutage.tryAgain.misheard': 'reportOutage.tryAgain.misheard',
'reportOutage.reportAnOutage.confirm': 'reportOutage.reportAnOutage.confirm',
'reportOutage.reportAnOutage.misheard': 'reportOutage.reportAnOutage.misheard',
'reportOutage.reply.haveANiceDay': 'reportOutage.reply.haveANiceDay',
'reportOutage.letYouKnow.confirm': 'reportOutage.letYouKnow.confirm',
'reportOutage.letYouKnow.misheard': 'reportOutage.letYouKnow.misheard'
})
handlerInput.requestEnvelope.request.type = 'LaunchRequest'
await run(handlerInput)
handlerInput.requestEnvelope.request.type = 'IntentRequest'
})

beforeEach(async () => {
handlerInput.responseBuilder.speak.mockClear()
handlerInput.responseBuilder.reprompt.mockClear()
handlerInput.responseBuilder.addElicitSlotDirective.mockClear()
handlerInput.responseBuilder.addConfirmSlotDirective.mockClear()
handlerInput.responseBuilder.withShouldEndSession.mockClear()
handlerInput.responseBuilder.getResponse.mockClear()
clearResponseMocks()
handlerInput.requestEnvelope.request.type = 'IntentRequest'
mockGetSession.mockClear()
mockSaveSession.mockClear()
Expand Down Expand Up @@ -66,6 +77,9 @@ describe('Report Outage Conversation Tests', () => {
it('Sends machine to saying house number sends them to ask for phone', async () => {

handlerInput.requestEnvelope.request.intent.name = 'ANumber'
//1233 % 3 = 0 => No outage in your area
//1234 % 3 = 1 => There is an outage
//1235 % 3 = 2 => Not matching number
setSlots(defaultNumberIntent(1234).slots);

await run(handlerInput)
Expand All @@ -82,41 +96,219 @@ describe('Report Outage Conversation Tests', () => {
expect(getResponse()[0][0]).toEqual('reportOutage.askForTelephoneNumber.misheard')
})

it('when address is correct, tells the user thanks for reporting(thanksForReporting)', async () => {
handlerInput.attributesManager.setSessionAttributes({
...handlerInput.attributesManager.getSessionAttributes(),
state: {
...handlerInput.attributesManager.getSessionAttributes().state,
currentSubConversation: {
reportOutage: {
machineState: 'thanksForReporting',
machineContext: {
conversationAttributes: {
confirmAddress: {
confirmedAddress: true,
correctAddress: true,
resuming: true
},
},
},
},
},
conversationStack: [],
},
conversationAttributes: {
confirmAddress: {
confirmedAddress: true,
correctAddress: true,
resuming: true,
},
},
})
it('Sends machine to calling API when getting phone number', async () => {

handlerInput.requestEnvelope.request.intent.name = 'APhoneNumber'
setSlots(defaultPhoneNumberIntent('3143225555').slots);

await run(handlerInput)

expect(getMockState().machineState).toEqual('thanksForReporting')
expect(getResponse()[0][0]).toEqual('reportOutage.reply.noContact')
});
expect(getMockState().machineState).toEqual('letYouKnowWOutageReport')
expect(getResponse()[0][0]).toEqual('reportOutage.letYouKnowWOutageReport.confirm')
})

it('Sends machine to calling API when getting phone number', async () => {

handlerInput.requestEnvelope.request.intent.name = 'ANumber'
setSlots(defaultNumberIntent('10').slots);

await run(handlerInput)

expect(getMockState().machineState).toEqual('letYouKnowWOutageReport')
expect(getResponse()[0][0]).toEqual('reportOutage.letYouKnowWOutageReport.misheard')
})

it('Thank them with contact', async () => {

handlerInput.requestEnvelope.request.intent.name = 'YesNoIntent'
setSlots(defaultYesNoIntent('yes').slots);
//console.log(`before ${JSON.stringify(handlerInput.attributesManager.getSessionAttributes().state, null, 2)}`)
await run(handlerInput)
//console.log(`after ${JSON.stringify(handlerInput.attributesManager.getSessionAttributes().state, null, 2)}`)

expect(getMockState().machineState).toEqual('resume') //we should be at home now
expect(getResponse()[0][0]).toEqual('reportOutage.reply.withContact home.reEngage')
})

it('test mismatching numbers path', async () => {
handlerInput.requestEnvelope.request.intent.name = 'ReportOutage'
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'ANumber'
//1235 % 3 = 2 => Not matching number
setSlots(defaultNumberIntent(1235).slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'APhoneNumber'
setSlots(defaultPhoneNumberIntent('3143225555').slots);
clearResponseMocks()
await run(handlerInput)

expect(getMockState().machineState).toEqual('tryAgain')
expect(getResponse()[0][0]).toEqual('reportOutage.tryAgain.confirm')

clearResponseMocks()
await run(handlerInput) //Wrong intent

expect(getMockState().machineState).toEqual('tryAgain')
expect(getResponse()[0][0]).toEqual('reportOutage.tryAgain.misheard')

handlerInput.requestEnvelope.request.intent.name = 'YesNoIntent'
setSlots(defaultYesNoIntent('yes').slots);

clearResponseMocks()
await run(handlerInput) //Try again

expect(getMockState().machineState).toEqual('askForHouseNumber')
expect(getResponse()[0][0]).toEqual('reportOutage.askForHouseNumber.confirm')

handlerInput.requestEnvelope.request.intent.name = 'ANumber'
//1235 % 3 = 2 => Not matching number
setSlots(defaultNumberIntent(1235).slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'APhoneNumber'
setSlots(defaultPhoneNumberIntent('3143225555').slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'YesNoIntent'
setSlots(defaultYesNoIntent('no').slots);

clearResponseMocks()
await run(handlerInput) //Done

expect(getMockState().machineState).toEqual('resume') //we should be at home now
expect(getResponse()[0][0]).toEqual('home.reEngage')

})

it('test the no side of the let you know for an outage', async () => {
handlerInput.requestEnvelope.request.intent.name = 'ReportOutage'
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'ANumber'
//1234 % 3 = 1 => There is an outage
setSlots(defaultNumberIntent(1234).slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'APhoneNumber'
setSlots(defaultPhoneNumberIntent('3143225555').slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'YesNoIntent'
setSlots(defaultYesNoIntent('no').slots);
clearResponseMocks()
await run(handlerInput)

expect(getMockState().machineState).toEqual('resume')
expect(getResponse()[0][0]).toEqual('reportOutage.reply.noContact home.reEngage')

})

it('test the no side of would you like to report an outage', async () => {
handlerInput.requestEnvelope.request.intent.name = 'ReportOutage'
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'ANumber'
//1233 % 3 = 1 => There is not an outage
setSlots(defaultNumberIntent(1233).slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'APhoneNumber'
setSlots(defaultPhoneNumberIntent('3143225555').slots);
clearResponseMocks()
await run(handlerInput)

expect(getMockState().machineState).toEqual('reportAnOutage')
expect(getResponse()[0][0]).toEqual('reportOutage.reportAnOutage.confirm')

handlerInput.requestEnvelope.request.intent.name = 'YesNoIntent'
setSlots(defaultYesNoIntent('no').slots);
clearResponseMocks()
await run(handlerInput)

expect(getMockState().machineState).toEqual('resume')
expect(getResponse()[0][0]).toEqual('reportOutage.reply.haveANiceDay home.reEngage')

})

it('test the yes side of would you like to report an outage with contact', async () => {
handlerInput.requestEnvelope.request.intent.name = 'ReportOutage'
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'ANumber'
//1233 % 3 = 1 => There is not an outage
setSlots(defaultNumberIntent(1233).slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'APhoneNumber'
setSlots(defaultPhoneNumberIntent('3143225555').slots);
clearResponseMocks()
await run(handlerInput)

expect(getMockState().machineState).toEqual('reportAnOutage')
expect(getResponse()[0][0]).toEqual('reportOutage.reportAnOutage.confirm')

clearResponseMocks()
await run(handlerInput) //wrong intent

expect(getMockState().machineState).toEqual('reportAnOutage')
expect(getResponse()[0][0]).toEqual('reportOutage.reportAnOutage.misheard')

handlerInput.requestEnvelope.request.intent.name = 'YesNoIntent'
setSlots(defaultYesNoIntent('yes').slots);
clearResponseMocks()
await run(handlerInput)

expect(getMockState().machineState).toEqual('letYouKnow')
expect(getResponse()[0][0]).toEqual('reportOutage.letYouKnow.confirm')

handlerInput.requestEnvelope.request.intent.name = 'APhoneNumber'
setSlots(defaultPhoneNumberIntent('3143225555').slots);
clearResponseMocks()
await run(handlerInput) //wrong intent

expect(getMockState().machineState).toEqual('letYouKnow')
expect(getResponse()[0][0]).toEqual('reportOutage.letYouKnow.misheard')

handlerInput.requestEnvelope.request.intent.name = 'YesNoIntent'
setSlots(defaultYesNoIntent('yes').slots);
clearResponseMocks()
await run(handlerInput)

expect(getMockState().machineState).toEqual('resume')
expect(getResponse()[0][0]).toEqual('reportOutage.reply.withContact home.reEngage')

})

it('test the yes side of would you like to report an outage with no contact', async () => {
handlerInput.requestEnvelope.request.intent.name = 'ReportOutage'
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'ANumber'
//1233 % 3 = 1 => There is not an outage
setSlots(defaultNumberIntent(1233).slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'APhoneNumber'
setSlots(defaultPhoneNumberIntent('3143225555').slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'YesNoIntent'
setSlots(defaultYesNoIntent('yes').slots);
await run(handlerInput)

handlerInput.requestEnvelope.request.intent.name = 'YesNoIntent'
setSlots(defaultYesNoIntent('no').slots);
clearResponseMocks()
await run(handlerInput)

expect(getMockState().machineState).toEqual('resume')
expect(getResponse()[0][0]).toEqual('reportOutage.reply.noContact home.reEngage')

})



it('gives the generic error response on errors (error)', async () => {
handlerInput.attributesManager.setSessionAttributes({
Expand Down

0 comments on commit 1752f5a

Please sign in to comment.