UNPKG

asksuite-core

Version:
885 lines (746 loc) 35.1 kB
const AsksuiteProcessingNatural = require('../AsksuiteProcessingNatural'); const MockGenerator = require('../mocks/MockGenerator'); const createRedisClient = require('../util/redis'); const mockConfig = require('../mocks/json/config'); const redisDialogflow = { redis: { url: 'redis://localhost', db: 1, // intents }, }; beforeAll(() => { jest.setTimeout(60000); }); describe('Asksuite Processing Natural testing...', () => { it('Should return DialogFlow intent', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Oi'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('saudacao'); expect(result.resolver).toBe('DIALOG_FLOW'); }); it('Should return DialogFlow intent fr', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('bonjour'); data.language = 'fr-fr'; data.languages = [ { formatIso: 'fr-fr', formatGoogle: 'fr', formatDialogflow: 'fr-fr', }, ]; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('saudacao'); expect(result.resolver).toBe('DIALOG_FLOW'); }); it('Should return DialogFlow intent', async () => { const data = MockGenerator.generateIncoming('Oi'); const redis = createRedisClient(redisDialogflow); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('saudacao'); expect(result.resolver).toBe('DIALOG_FLOW'); }); it('Should return intent translated saudacao', async () => { const data = MockGenerator.generateIncoming('hello my lady'); const redis = createRedisClient(redisDialogflow); data.language = 'en'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('saudacao'); // TODO: fix this behavior // This is not working because of deep clone in request object being made on AsksuiteProcessingNatural.js line 288 // expect(result.translated).toBe(true); // Commenting for now. expect(result.dialog).toContain(data.companyId); }); it('Should return DialogFlow intent cotacao_com_datas', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming( 'Preciso de hospedagem na segunda semana de junho para um casal', ); data.language = 'pt'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.extractedData).toStrictEqual({ ArrivalDateString: '2025-06-09', DepartureDateString: '2025-06-15', AmountAdults: 2, }); expect(result.intent).toBe('cotacao_com_datas'); expect(result.resolver).toBe('DIALOG_FLOW'); }); it('Should return cached DialogFlow intent', async () => { const data = MockGenerator.generateIncoming('Oi'); const redis = createRedisClient(redisDialogflow); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); let result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('saudacao'); expect(result.resolver).toBe('DIALOG_FLOW'); result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('saudacao'); expect(result.fromCache).toBe(true); expect(result.resolver).toBe('DIALOG_FLOW'); }, 30000); it('Should return DialogFlow intent with or without accent', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Quero falar com alguém'); data.language = 'pt-br'; const data2 = MockGenerator.generateIncoming('Quero FalaR com Alguem'); data2.language = 'pt-br'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); const result2 = await asksuiteProcessingNatural.findIntent(data2); expect.assertions(4); expect(result.intent).toBe('quero_telefone_hotel'); expect(result.resolver).toBe('DIALOG_FLOW'); expect(result2.intent).toBe('quero_telefone_hotel'); expect(result2.resolver).toBe('DIALOG_FLOW'); }); it('Should return DialogFlow intent trocar_idioma and supported language', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('do you speak Portuguese?'); data.language = 'en-us'; data.companyLanguages = ['pt', 'en', 'fr']; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect.assertions(5); expect(result.intent).toBe('trocar_idioma'); expect(result.languageDetected).not.toBeUndefined(); expect(result.languageDetected.isSupported).toBe(true); expect(result.languageDetected.language).toStrictEqual({ name: 'Português', code: 'pt' }); expect(result.resolver).toBe('DIALOG_FLOW'); }); it('Should return DialogFlow intent trocar_idioma and not supported language with fallback in english', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('do you speak German?'); data.language = 'en-us'; data.companyLanguages = ['pt', 'en']; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect.assertions(6); expect(result.intent).toBe('trocar_idioma'); expect(result.languageDetected).not.toBeUndefined(); expect(result.languageDetected.isSupported).toBe(false); expect(result.languageDetected.language).toStrictEqual({ name: 'German', code: 'de' }); expect(result.languageDetected.fallbackLanguage).toStrictEqual({ name: 'English', code: 'en', }); expect(result.resolver).toBe('DIALOG_FLOW'); }); it('Should return DialogFlow intent trocar_idioma and not supported language with fallback in current language when EN is not supported', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Hablas espanol?'); data.language = 'en-us'; data.companyLanguages = ['pt']; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect.assertions(6); expect(result.intent).toBe('trocar_idioma'); expect(result.languageDetected).not.toBeUndefined(); expect(result.languageDetected.isSupported).toBe(false); expect(result.languageDetected.language).toStrictEqual({ name: 'Spanish', code: 'es' }); expect(result.languageDetected.fallbackLanguage).toStrictEqual({ name: 'English', code: 'en', }); expect(result.resolver).toBe('DIALOG_FLOW'); }); it('Should return KeyMatcher intent convenio_sbtur', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming( 'Vale lembrar que a nossa estadia é pelo convênio com SBTUR', ); data.language = 'pt-br'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('convenio_sbtur'); expect(result.resolver).toBe('KEY_MATCHER'); }); it('Should return KeyMatcher intent translated', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming( 'price price price price price price price price price price price price price price price price price price price price price ', ); data.language = 'en'; data.config.USE_NLP_CLASSIFIER_LAYER = true; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('cotacao'); }); it('Should return RASA intent', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('quero passar no teste do rasa'); data.companyId = 'teste_rasa_core'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.resolver).toBe('RASA'); expect(result.intent).toBe('asksuite_rasa_teste_resort'); }); it('Should return RASA intent with accent and different cases', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('QueRo passar no tesTe do Rása'); data.companyId = 'teste_rasa_core'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.resolver).toBe('RASA'); expect(result.intent).toBe('asksuite_rasa_teste_resort'); }); it('Should return naoentendi', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('HAIA USHAKJHJHZXNC HDSAHF SANFDJKIUHQWDFJAS NKJ'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ config: mockConfig, redis, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('naoentendi'); }); describe('Test with Rasa as first NLP', () => { it('Should return DialogFlow intent', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Oi'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('saudacao'); expect(result.resolver).toBe('DIALOG_FLOW'); }); it('Should return KeyMatcher intent', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming( 'Vale lembrar que a nossa estadia é pelo convênio com SBTUR', ); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.intent).toBe('convenio_sbtur'); expect(result.resolver).toBe('KEY_MATCHER'); }); it('Should return RASA intent', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('quero passar no teste do rasa'); data.companyId = 'teste_rasa_core'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.resolver).toBe('RASA'); expect(result.intent).toBe('asksuite_rasa_teste_resort'); }); it('Should return RASA intent correctly with multiple entities', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('passeio passeio de arvorismo'); data.companyId = 'teste_rasa_core'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.resolver).toBe('RASA'); expect(result.intent).toBe('passeio_de_arvorismo_teste_rasa_core'); }); }); describe('Test with groupId extraction', () => { it('Should return GROUP_ID intent with extracted groupId', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Continuar atendimento #ag46Fc'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.resolver).toBe('GROUP_ID'); expect(result.intent).toBe('continuar_atendimento'); expect(result.groupId).toBe('ag46Fc'); }); it('Should ignore malformed groupId', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Continuar atendimento #aç46Fc'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.resolver).not.toBe('GROUP_ID'); expect(result.intent).not.toBe('continuar_atendimento'); expect(result.groupId).toBe(undefined); }); }); describe('Test processingSteps', () => { it('should add processing steps to DialogFlow - saudacao', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Oi'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); const processingSteps = { fallbackReason: null, intentFound: 'saudacao', isChangeLanguageRequest: false, precision: 1, text: 'oi', }; const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'DIALOG_FLOW'); expect(result.processingSteps[layerIndex].resolver).toBe('DIALOG_FLOW'); expect(result.processingSteps[layerIndex].resolver).toBe('DIALOG_FLOW'); expect(result.processingSteps[layerIndex].processingStep).toStrictEqual(processingSteps); }); it.skip('should add processing steps to DialogFlow - intent_not_mapped', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming(`Olá`); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.intents = data.intents.filter((intent) => intent.intent !== 'saudacao'); const result = await asksuiteProcessingNatural.findIntent(data); const processingSteps = { fallbackReason: 'intent_not_mapped', intentFound: 'saudacao', text: 'ola', isChangeLanguageRequest: false, precision: 1, }; const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'DIALOG_FLOW'); expect(result.processingSteps[layerIndex].resolver).toBe('DIALOG_FLOW'); expect(result.processingSteps[layerIndex].processingStep).toStrictEqual(processingSteps); }); it('should add processing steps to DialogFlow - dialog_empty', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Não'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.intents = data.intents.map((intent) => { if (intent.intent === 'usuario_diz_nao') { intent.dialog = ''; } return intent; }); const result = await asksuiteProcessingNatural.findIntent(data); const processingSteps = { fallbackReason: 'dialog_empty', intentFound: 'usuario_diz_nao', isChangeLanguageRequest: false, precision: 1, text: 'nao', }; const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'DIALOG_FLOW'); expect(result.processingSteps[layerIndex].resolver).toBe('DIALOG_FLOW'); expect(result.processingSteps[layerIndex].processingStep).toStrictEqual(processingSteps); }); it.skip('should add processing steps to DialogFlow - text_not_understandable', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('jq'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.config.OPEN_AI_ENABLED = true; const result = await asksuiteProcessingNatural.findIntent(data); const processingSteps = { fallbackReason: 'text_not_understandable', intentFound: 'naoentendi', isChangeLanguageRequest: false, precision: 1, text: 'jq', }; const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'DIALOG_FLOW'); expect(result.processingSteps[layerIndex].resolver).toBe('DIALOG_FLOW'); expect(result.processingSteps[layerIndex].processingStep).toStrictEqual(processingSteps); }); it('should add processing steps to DialogFlow and KeyMatcher', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming( 'Vale lembrar que a nossa estadia é pelo convênio com SBTUR', ); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.config.OPEN_AI_ENABLED = false; const result = await asksuiteProcessingNatural.findIntent(data); const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'KEY_MATCHER'); expect(result.processingSteps[layerIndex].resolver).toBe('KEY_MATCHER'); expect(result.processingSteps[layerIndex].processingStep.fallbackReason).toBe(null); expect(result.processingSteps[layerIndex].processingStep.intentFound).toBe('convenio_sbtur'); expect(result.resolver).toBe('KEY_MATCHER'); }); it.skip('should add processing steps to KeyMatcher - intent_not_mapped', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming( 'olá, gostaria de saber sobre emprestimo de conversor de voltagem', ); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.intents = data.intents.filter((intent) => intent.intent !== 'convenio_sbtur'); const result = await asksuiteProcessingNatural.findIntent(data); const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'KEY_MATCHER'); expect(result.processingSteps[layerIndex].resolver).toBe('KEY_MATCHER'); expect(result.processingSteps[layerIndex].processingStep.fallbackReason).toBe( 'intent_not_mapped', ); expect(result.processingSteps[3].processingStep.intentFound).toBe('convenio_sbtur'); }); it('should add processing steps to KeyMatcher - dialog_empty', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming( 'Vale lembrar que a nossa estadia é pelo convênio com SBTUR', ); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.intents = data.intents.map((intent) => { if (intent.intent === 'convenio_sbtur') { intent.dialog = ''; } return intent; }); const result = await asksuiteProcessingNatural.findIntent(data); const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'KEY_MATCHER'); expect(result.processingSteps[layerIndex].resolver).toBe('KEY_MATCHER'); expect(result.processingSteps[layerIndex].processingStep.fallbackReason).toBe('dialog_empty'); expect(result.processingSteps[layerIndex].processingStep.intentFound).toBe('convenio_sbtur'); }); it.skip('should add processing steps to KeyMatcher - text_not_understandable', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('!@'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'KEY_MATCHER'); expect(result.processingSteps[layerIndex].resolver).toBe('KEY_MATCHER'); expect(result.processingSteps[layerIndex].processingStep.fallbackReason).toBe( 'text_not_understandable', ); expect(result.processingSteps[3].processingStep.intentFound).toBe(null); }); it('should add processing steps to DialogFlow and KeyMatcher and Rasa', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('quero passar no teste do rasa'); data.companyId = 'teste_rasa_core'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); const rasaIndex = result.processingSteps.findIndex((i) => i.resolver === 'RASA'); expect(result.processingSteps[rasaIndex].resolver).toBe('RASA'); expect(result.processingSteps[rasaIndex].processingStep.fallbackReason).toBe(null); expect(result.processingSteps[rasaIndex].processingStep.intentFound).toBe( 'asksuite_rasa_teste_resort', ); }); it('should add processing steps to Rasa - intent_not_mapped - 1', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('quero passar no teste do rasa'); data.companyId = 'teste_rasa_core'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.intents = data.intents.filter( (intent) => intent.intent !== 'asksuite_rasa_teste_resort', ); const result = await asksuiteProcessingNatural.findIntent(data); const rasaIndex = result.processingSteps.findIndex((i) => i.resolver === 'RASA'); expect(result.processingSteps[rasaIndex].resolver).toBe('RASA'); expect(result.processingSteps[rasaIndex].processingStep.fallbackReason).toBe( 'intent_not_mapped', ); expect(result.processingSteps[rasaIndex].processingStep.intentFound).toBe( 'asksuite_rasa_teste_resort', ); }); it('should add processing steps to Rasa - dialog_empty', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('quero passar no teste do rasa'); data.companyId = 'teste_rasa_core'; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.intents = data.intents.map((intent) => { if (intent.intent === 'asksuite_rasa_teste_resort') { intent.dialog = ''; } return intent; }); const result = await asksuiteProcessingNatural.findIntent(data); expect(result.processingSteps.length).toBe(1); expect(result.processingSteps[0].resolver).toBe('RASA'); expect(result.processingSteps[0].processingStep.fallbackReason).toBe('dialog_empty'); expect(result.processingSteps[0].processingStep.intentFound).toBe( 'asksuite_rasa_teste_resort', ); }); it('should add processing steps to OpenIA - intent_not_found', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('AJSIJASIS😂'); data.config.OPEN_AI_ENABLED = true; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); const result = await asksuiteProcessingNatural.findIntent(data); const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'OPEN_AI'); expect(result.processingSteps[layerIndex].resolver).toBe('OPEN_AI'); expect(result.processingSteps[layerIndex].processingStep.fallbackReason).toBe( 'intent_not_found', ); expect(result.processingSteps[layerIndex].processingStep.intentFound).toBe(null); expect(result.processingSteps[layerIndex].processingStep.extraInfo).toHaveProperty( 'prompt_tokens', ); expect( isNaN(result.processingSteps[layerIndex].processingStep.extraInfo.prompt_tokens), ).toBeFalsy(); expect(result.processingSteps[layerIndex].processingStep.extraInfo).toHaveProperty( 'completion_tokens', ); expect( isNaN(result.processingSteps[layerIndex].processingStep.extraInfo.completion_tokens), ).toBeFalsy(); expect(result.processingSteps[layerIndex].processingStep.extraInfo).toHaveProperty( 'total_tokens', ); expect( isNaN(result.processingSteps[layerIndex].processingStep.extraInfo.total_tokens), ).toBeFalsy(); expect(result.processingSteps[layerIndex].processingStep.text).toBe('AJSIJASIS'); expect(result.processingSteps[layerIndex].processingStep.answer).toContain('naoentendi'); }); it('should add processing steps to DialogFlow and Rasa and OpenIA', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Gostaria de saber mais sobre a acessibilidade'); data.config.OPEN_AI_ENABLED = true; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'OPEN_AI'); expect(result.processingSteps[layerIndex].resolver).toBe('OPEN_AI'); expect(result.processingSteps[layerIndex].processingStep.fallbackReason).toBe(null); expect(result.processingSteps[layerIndex].processingStep.extraInfo).toHaveProperty( 'prompt_tokens', ); expect( isNaN(result.processingSteps[layerIndex].processingStep.extraInfo.prompt_tokens), ).toBeFalsy(); expect(result.processingSteps[layerIndex].processingStep.extraInfo).toHaveProperty( 'completion_tokens', ); expect( isNaN(result.processingSteps[layerIndex].processingStep.extraInfo.completion_tokens), ).toBeFalsy(); expect(result.processingSteps[layerIndex].processingStep.extraInfo).toHaveProperty( 'total_tokens', ); expect( isNaN(result.processingSteps[layerIndex].processingStep.extraInfo.total_tokens), ).toBeFalsy(); expect(result.processingSteps[layerIndex].processingStep.text).toBe( 'Gostaria de saber mais sobre a acessibilidade', ); // expect(result.processingSteps[3].processingStep.answer).toBe( // 'Temos quartos adaptados para portadores de necessidades especiais, rampas de acesso nas áreas comuns e cadeiras de rodas disponíveis para passeio e banho. É necessário avisar na reserva para deixar tudo pronto.', // ); expect(result.resolver).toBe('OPEN_AI'); }); it('should return not understandable when only link', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('https://google.us.edi?34535/534534?dfg=g&fg'); data.config.OPEN_AI_ENABLED = true; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); expect(result.processingSteps[5].resolver).toBe('OPEN_AI'); expect(result.processingSteps[5].processingStep.fallbackReason).toBe( 'text_not_understandable', ); }); it('should return not understandable when only special chars', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('%#(*&#&(*&)&'); data.config.OPEN_AI_ENABLED = true; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); const layerIndex = result.processingSteps.findIndex((i) => i.resolver === 'OPEN_AI'); expect(result.processingSteps[layerIndex].resolver).toBe('OPEN_AI'); expect(result.processingSteps[layerIndex].processingStep.fallbackReason).toBe( 'text_not_understandable', ); }); it('should return not understandable when empty string', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming(''); data.config.OPEN_AI_ENABLED = true; const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); expect(result.processingSteps.length).toBe(6); expect(result.processingSteps[5].resolver).toBe('OPEN_AI'); expect(result.processingSteps[5].processingStep.fallbackReason).toBe( 'text_not_understandable', ); }); it('should not run layer NLPClassifier if feature toggle is off', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming( 'gostaria de cotar um quarto para 2 adultos e 1 criança', ); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.config.USE_NLP_CLASSIFIER_LAYER = false; data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); expect(result.processingSteps.some((step) => step.resolver === 'NLP_CLASSIFIER')).toBe(false); }); it('should return intent cotacao for resolver NLPClassifier in first step', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming( 'gostaria de cotar um quarto para 2 adultos e 1 criança', ); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.config.USE_NLP_CLASSIFIER_LAYER = true; data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); expect(result.processingSteps[2].processingStep.intentFound).toBe('cotacao'); expect(result.extractedData).toStrictEqual({ AmountAdults: 2, AmountChildren: 1, Rooms: 1 }); expect(result.processingSteps[2].resolver).toBe('NLP_CLASSIFIER'); expect(result.processingSteps[2].processingStep).toHaveProperty('extraInfo'); expect(result.processingSteps[2].processingStep.text).toBe(data.text); expect(result.processingSteps[2].processingStep.language).toBe(data.language); expect(result.processingSteps[2].processingStep.fallbackReason).toBe(null); }); it('should return intent naoentendi for resolver NLPClassifier in first step', async function () { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('gostaria de saber o horário de funcionamento'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.config.USE_NLP_CLASSIFIER_LAYER = true; data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); expect(result.processingSteps[2].processingStep.intentFound).toBe('naoentendi'); expect(result.processingSteps[2].resolver).toBe('NLP_CLASSIFIER'); expect(result.processingSteps[2].processingStep).toHaveProperty('extraInfo'); expect(result.processingSteps[2].processingStep.text).toBe(data.text); expect(result.processingSteps[2].processingStep.language).toBe(data.language); expect(result.processingSteps[2].processingStep.fallbackReason).toBe('intent_not_found'); }); it('should have KEYMATCHER fallbackReason as openai_enabled when open ai is enabled', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('gostaria de saber o horário de funcionamento'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.config.USE_NLP_CLASSIFIER_LAYER = true; data.config.OPEN_AI_ENABLED = true; data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); expect(result.processingSteps[4].processingStep.intentFound).toBeUndefined(); expect(result.processingSteps[4].resolver).toBe('KEY_MATCHER'); expect(result.processingSteps[4].processingStep.processingStep.fallbackReason).toBe( 'openai_enabled', ); }); it('should have KEYMATCHER fallbackReason as ignored_quotation_result when received intent is Quotation', async () => { const redis = createRedisClient(redisDialogflow); const data = MockGenerator.generateIncoming('Quero reservar o spa para dia 31/02/2024'); const asksuiteProcessingNatural = new AsksuiteProcessingNatural({ redis, config: mockConfig, }); data.config.USE_NLP_CLASSIFIER_LAYER = true; data.config.OPEN_AI_ENABLED = false; data.language = 'pt-br'; const result = await asksuiteProcessingNatural.findIntent(data); expect(result.processingSteps[4].processingStep.intentFound).toBeUndefined(); expect(result.processingSteps[4].resolver).toBe('KEY_MATCHER'); expect(result.processingSteps[4].processingStep.processingStep.fallbackReason).toBe( 'ignored_quotation_result', ); }); }); });