From 5b31e84ef93a5b132873b5bc7efeb848de02134d Mon Sep 17 00:00:00 2001 From: Antonio Pintus Date: Tue, 20 Aug 2019 15:44:13 +0200 Subject: [PATCH] feat(dependencies): update @vivocha/public-entities update @vivocha/public-entities and add tests for bot + filter chains --- package-lock.json | 12 +- package.json | 2 +- test/ts/agent-general.test.ts | 3 +- test/ts/bot-filters-chain.test.ts | 315 ++++++++++++++++++++++++++++++ test/ts/dummy-bot.ts | 23 ++- 5 files changed, 341 insertions(+), 14 deletions(-) create mode 100644 test/ts/bot-filters-chain.test.ts diff --git a/package-lock.json b/package-lock.json index 76a10af..186edc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -810,14 +810,14 @@ } }, "@vivocha/public-entities": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@vivocha/public-entities/-/public-entities-6.6.0.tgz", - "integrity": "sha512-2Zu3drdXMcVLfa9DBgL5QAFOnSxPycvZMQvaU3kIf2UZGQmUkHvb5U8RijOSBOoGylkJw24vIMbjUbJNLhVQFw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@vivocha/public-entities/-/public-entities-7.0.6.tgz", + "integrity": "sha512-GAcvq5nQ9TfJViJryr93UssXpzKeAVKQe4q1DWEadeYLLMwHCQOIZcmmelmVLmeyI+zyyeQutixnQt+FHNosjQ==", "requires": { "eredita": "^1.1.4", - "node-sass": "^4.7.2", - "request": "^2.83.0", - "sass.js": "^0.10.7" + "node-sass": "^4.12.0", + "request": "^2.88.0", + "sass.js": "^0.10.13" } }, "JSONStream": { diff --git a/package.json b/package.json index 0d918ea..6257a3c 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ }, "dependencies": { "@types/debug": "0.0.30", - "@vivocha/public-entities": "6.6.0", + "@vivocha/public-entities": "7.0.6", "arrest": "7.5.2", "lodash": "^4.17.15", "node-wit": "5.0.0", diff --git a/test/ts/agent-general.test.ts b/test/ts/agent-general.test.ts index be98ffb..ac0e076 100644 --- a/test/ts/agent-general.test.ts +++ b/test/ts/agent-general.test.ts @@ -1,8 +1,7 @@ import * as chai from 'chai'; -import { BotAgentManager, BotRequest } from '../../dist'; import * as http from 'request-promise-native'; +import { BotAgentManager, BotRequest } from '../../dist'; import { dummyBot } from './dummy-bot'; -import bodyParser = require('body-parser'); chai.should(); diff --git a/test/ts/bot-filters-chain.test.ts b/test/ts/bot-filters-chain.test.ts new file mode 100644 index 0000000..10a51b8 --- /dev/null +++ b/test/ts/bot-filters-chain.test.ts @@ -0,0 +1,315 @@ +import * as chai from 'chai'; +import * as http from 'request-promise-native'; +import { AttachmentMessage, BotFilter, BotRequest, BotResponse, IsWritingMessage, TextMessage } from '../../dist'; +import { dummyBot } from './dummy-bot'; + +chai.should(); + +const engineType = 'custom'; + +const filterOne: BotFilter = new BotFilter(async (req: BotRequest): Promise => { + req.data = Object.assign({}, req.data || {}, { random: Math.round(Math.random() * 1000) }); + return req; +}, undefined); +const filterTwo: BotFilter = new BotFilter(async (req: BotRequest): Promise => { + req.context = Object.assign({}, req.context || {}, { f2Check: 'checked' }); + return req; +}, undefined); +const filterThree: BotFilter = new BotFilter( + undefined, + async (res: BotResponse): Promise => { + res.context = Object.assign({}, res.context || {}, { f3Check: 'checked' }); + const text = (res.messages[0] as TextMessage).body; + (res.messages[0] as TextMessage).body = `${text} Edited by f3.`; + return res; + } +); +const filterFour: BotFilter = new BotFilter( + undefined, + async (res: BotResponse): Promise => { + res.context = Object.assign({}, res.context || {}, { f4Check: 'checked' }); + const text = (res.messages[0] as TextMessage).body; + (res.messages[0] as TextMessage).body = `${text} Edited by f4.`; + res.messages.push({ + code: 'message', + type: 'iswriting' + } as IsWritingMessage); + res.messages.push({ + code: 'message', + type: 'text', + body: 'Done.' + } as TextMessage); + return res; + } +); +const filterFive: BotFilter = new BotFilter( + undefined, + async (res: BotResponse): Promise => { + res.context = Object.assign({}, res.context || {}, { f5Check: 'checked' }); + const text = (res.messages[0] as TextMessage).body; + (res.messages[0] as TextMessage).body = `${text} Edited by f5.`; + res.messages.push({ + code: 'message', + type: 'attachment', + url: 'https://media.giphy.com/media/l1KsqYM8Zt3yG3tVS/giphy.gif', + meta: { + originalUrl: '', + originalName: 'Scream.gif', + mimetype: 'image/gif' + } + } as AttachmentMessage); + return res; + } +); + +const getTextMessage = function(body: string, payload?: string): any { + let msg = { + code: 'message', + type: 'text', + body + }; + if (payload) { + msg['payload'] = payload; + } + return msg; +}; +const getBotHTTPOpts = function getOptions(port: number, body: any) { + return { + method: 'POST', + uri: `http://localhost:${port}/bot/message`, + body: body, + headers: { + 'x-vvc-host': `localhost:${port}`, + 'x-vvc-acct': 'vvc_test1' + }, + json: true + }; +}; +const getFilterHTTPOpts = function getOptions(port: number, body: any, type: 'request' | 'response') { + return { + method: 'POST', + uri: `http://localhost:${port}/filter/${type}`, + body: body, + headers: { + 'x-vvc-host': `localhost:${port}`, + 'x-vvc-acct': 'vvc_test1' + }, + json: true + }; +}; + +//root describe +describe('Testing a bot + filters chain', function() { + describe('Sending a start message to chain f1 -> f2 -> bot -> f3', function() { + const getSettings = function(): any { + return { + engine: { + type: engineType + } + }; + }; + let bot; + let f1, f2, f3; + + before('starting bot and filters', async function() { + // Run the BotManager + const port = (process.env.PORT as any) || 8080; + bot = await dummyBot.listen(port); + // run filter f1 + f1 = await filterOne.listen(8081); + // run filter f2 + f2 = await filterTwo.listen(8082); + // run filter f3 + f3 = await filterThree.listen(8083); + return; + }); + it('should return a continue message data and context properly set', async function() { + const request: BotRequest = { + language: 'en', + event: 'start', + settings: getSettings() + }; + // call f1 + let result = await http(getFilterHTTPOpts(8081, request, 'request')); + // call f2 + result = await http(getFilterHTTPOpts(8082, result, 'request')); + // call bot + const response = await http(getBotHTTPOpts(8080, result)); + // call f3 + const finalResponse: BotResponse = await http(getFilterHTTPOpts(8083, response, 'response')); + + finalResponse.data.should.have.property('random'); + finalResponse.context.should.have.property('f2Check'); + finalResponse.context.should.have.property('f3Check'); + (finalResponse.messages[0] as TextMessage).body.should.include('Edited by f3'); + return; + }); + after('shutdown bot and filters', function() { + bot.close(); + f1.close(); + f2.close(); + f3.close(); + }); + }); + describe('Sending a continue test-chain message to chain f1 -> f2 -> bot -> f3', function() { + const getSettings = function(): any { + return { + engine: { + type: engineType + } + }; + }; + let bot; + let f1, f2, f3; + + before('starting bot and filters', async function() { + // Run the BotManager + const port = (process.env.PORT as any) || 8080; + bot = await dummyBot.listen(port); + // run filter f1 + f1 = await filterOne.listen(8081); + // run filter f2 + f2 = await filterTwo.listen(8082); + // run filter f3 + f3 = await filterThree.listen(8083); + return; + }); + it('should return a continue message data and context properly set', async function() { + const request: BotRequest = { + language: 'en', + event: 'continue', + message: getTextMessage('test-chain'), + settings: getSettings() + }; + // call f1 + let result = await http(getFilterHTTPOpts(8081, request, 'request')); + // call f2 + result = await http(getFilterHTTPOpts(8082, result, 'request')); + // call bot + const response = await http(getBotHTTPOpts(8080, result)); + // call f3 + const finalResponse: BotResponse = await http(getFilterHTTPOpts(8083, response, 'response')); + + finalResponse.data.should.have.property('random'); + finalResponse.context.should.have.property('f2Check'); + finalResponse.context.should.have.property('f3Check'); + (finalResponse.messages[0] as TextMessage).body.should.include('Edited by f3'); + return; + }); + after('shutdown bot and filters', function() { + bot.close(); + f1.close(); + f2.close(); + f3.close(); + }); + }); + describe('Sending a continue test-chain message to chain f1 -> f2 -> bot -> f4', function() { + const getSettings = function(): any { + return { + engine: { + type: engineType + } + }; + }; + let bot; + let f1, f2, f4; + + before('starting bot and filters', async function() { + // Run the BotManager + const port = (process.env.PORT as any) || 8080; + bot = await dummyBot.listen(port); + // run filter f1 + f1 = await filterOne.listen(8081); + // run filter f2 + f2 = await filterTwo.listen(8082); + // run filter f3 + f4 = await filterFour.listen(8084); + return; + }); + it('should return a continue message data and context properly set', async function() { + const request: BotRequest = { + language: 'en', + event: 'continue', + message: getTextMessage('test-chain'), + settings: getSettings() + }; + // call f1 + let result = await http(getFilterHTTPOpts(8081, request, 'request')); + // call f2 + result = await http(getFilterHTTPOpts(8082, result, 'request')); + // call bot + const response = await http(getBotHTTPOpts(8080, result)); + // call f4 + const finalResponse: BotResponse = await http(getFilterHTTPOpts(8084, response, 'response')); + + finalResponse.data.should.have.property('random'); + finalResponse.context.should.have.property('f2Check'); + finalResponse.context.should.have.property('f4Check'); + finalResponse.messages.should.length(3); + (finalResponse.messages[0] as TextMessage).body.should.include('Edited by f4'); + finalResponse.messages[1].type.should.equal('iswriting'); + (finalResponse.messages[2] as TextMessage).body.should.equal('Done.'); + return; + }); + after('shutdown bot and filters', function() { + bot.close(); + f1.close(); + f2.close(); + f4.close(); + }); + }); + describe('Sending a continue test-chain message to chain f1 -> f2 -> bot -> f5', function() { + const getSettings = function(): any { + return { + engine: { + type: engineType + } + }; + }; + let bot; + let f1, f2, f5; + + before('starting bot and filters', async function() { + // Run the BotManager + const port = (process.env.PORT as any) || 8080; + bot = await dummyBot.listen(port); + // run filter f1 + f1 = await filterOne.listen(8081); + // run filter f2 + f2 = await filterTwo.listen(8082); + // run filter f3 + f5 = await filterFive.listen(8085); + return; + }); + it('should return a continue message with an attachment and data and context properly set', async function() { + const request: BotRequest = { + language: 'en', + event: 'continue', + message: getTextMessage('test-chain'), + settings: getSettings() + }; + // call f1 + let result = await http(getFilterHTTPOpts(8081, request, 'request')); + // call f2 + result = await http(getFilterHTTPOpts(8082, result, 'request')); + // call bot + const response = await http(getBotHTTPOpts(8080, result)); + // call f5 + const finalResponse: BotResponse = await http(getFilterHTTPOpts(8085, response, 'response')); + + finalResponse.data.should.have.property('random'); + finalResponse.context.should.have.property('f2Check'); + finalResponse.context.should.have.property('f5Check'); + finalResponse.messages.should.length(2); + (finalResponse.messages[0] as TextMessage).body.should.include('Edited by f5'); + finalResponse.messages[1].type.should.equal('attachment'); + return; + }); + after('shutdown bot and filters', function() { + bot.close(); + f1.close(); + f2.close(); + f5.close(); + }); + }); +}); diff --git a/test/ts/dummy-bot.ts b/test/ts/dummy-bot.ts index 260cfaa..9593787 100644 --- a/test/ts/dummy-bot.ts +++ b/test/ts/dummy-bot.ts @@ -1,11 +1,10 @@ +import { Attachment, AttachmentMessage } from '@vivocha/public-entities'; import * as fs from 'fs'; -import { BotAgentManager, BotRequest, BotResponse, TextMessage, BotMessage } from '../../dist/index'; -import * as request from 'request'; - // got is just a simple library to perform http requests (see below in the BotAgent code) import * as got from 'got'; -import { AttachmentMessage, Attachment } from '@vivocha/public-entities'; +import * as request from 'request'; import { Stream } from 'stream'; +import { BotAgentManager, BotMessage, BotRequest, BotResponse, TextMessage } from '../../dist/index'; // A BotManager is a web server which exposes an API to send messages // to registered BotAgents, it exposes a Swagger description of the API with related JSON Schemas. @@ -53,7 +52,7 @@ dummyBot.registerAgent( body: 'Hello! I am a DummyBot :) Write help to see what I can do for you.' } as TextMessage ]; - response.data = {}; + response.data = msg.data || {}; } else { if (msg.message.type === 'attachment') { // console.log('ATTACHMENT message received'); @@ -1315,6 +1314,17 @@ dummyBot.registerAgent( } as AttachmentMessage ]; break; + case 'test-chain': + response.messages = [ + { + code: 'message', + type: 'text', + body: 'This is the result of a bot filters chain.' + } as TextMessage + ]; + response.data = msg.data || {}; + response.context = msg.context || {}; + break; default: response.messages = [ { @@ -1331,6 +1341,9 @@ dummyBot.registerAgent( if (!response.context && msg.context) { response['context'] = msg.context; } + if (!response.data && msg.data) { + response['data'] = msg.data; + } return response; } );