diff --git a/bot/Jenkinsfile b/bot/Jenkinsfile index f176aa9..0deb795 100644 --- a/bot/Jenkinsfile +++ b/bot/Jenkinsfile @@ -29,26 +29,34 @@ node('build-slave') { println(ANSI_BOLD + ANSI_YELLOW + "github_release_tag specified, building from github_release_tag: " + params.github_release_tag + ANSI_NORMAL) } echo "public_repo_commit_hash: " + public_repo_commit_hash - bot_repo_url = params.diksha_bot_repo - dir('bot_repo') { - if (params.diksha_bot_tag == "") { - def scmVars = checkout scm - checkout scm: ([$class: 'GitSCM', branches: [[name: "refs/heads/master"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'private_repo_credentials', url: "$bot_repo_url"]]]) - private_repo_commit_hash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim() - } - else { - def scmVars = checkout scm - checkout scm: ([$class: 'GitSCM', branches: [[name: "refs/tags/params.diksha_bot_tag"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'private_repo_credentials', url: "$bot_repo_url"]]]) - private_repo_commit_hash = params.diksha_bot_tag - } - } + bot_repo_url = params.private_bot_repo + + if (params.private_bot_repo) { + dir('bot_repo') { + if (params.private_bot_tag == "") { + def scmVars = checkout scm + checkout scm: ([$class: 'GitSCM', branches: [[name: "refs/heads/master"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'private_repo_credentials', url: "$bot_repo_url"]]]) + private_repo_commit_hash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim() + } + else { + def scmVars = checkout scm + checkout scm: ([$class: 'GitSCM', branches: [[name: "refs/tags/params.private_bot_tag"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'private_repo_credentials', url: "$bot_repo_url"]]]) + private_repo_commit_hash = params.private_bot_tag + } + } + + } + } stage('Build') { env.NODE_ENV = "build" print "Environment will be : ${env.NODE_ENV}" - build_tag = public_repo_commit_hash + "_" + private_repo_commit_hash + "_" + env.BUILD_NUMBER + "_bot" - sh('cp -r bot_repo/* .') + build_tag = public_repo_commit_hash + "_" + env.BUILD_NUMBER + "_bot" + if (params.private_bot_repo) { + sh('cp -r bot_repo/* .') + build_tag = public_repo_commit_hash + "_" + private_repo_commit_hash + "_" + env.BUILD_NUMBER + "_bot" + } dir('bot') { sh('chmod 777 build.sh') sh("./build.sh ${build_tag} ${env.NODE_NAME} ${hub_org}") diff --git a/router/Jenkinsfile b/router/Jenkinsfile index a6ae9e2..b1d16bf 100644 --- a/router/Jenkinsfile +++ b/router/Jenkinsfile @@ -30,26 +30,34 @@ node('build-slave') { } echo "public_repo_commit_hash: " + public_repo_commit_hash - bot_repo_url = params.diksha_bot_repo - dir('bot_repo') { - if (params.diksha_bot_tag == "") { + bot_repo_url = params.private_bot_repo + + if (params.private_bot_repo) { + dir('bot_repo') { + if (params.private_bot_tag == "") { def scmVars = checkout scm checkout scm: ([$class: 'GitSCM', branches: [[name: "refs/heads/master"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'private_repo_credentials', url: "$bot_repo_url"]]]) private_repo_commit_hash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim() } else { def scmVars = checkout scm - checkout scm: ([$class: 'GitSCM', branches: [[name: "refs/tags/params.diksha_bot_tag"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'private_repo_credentials', url: "$bot_repo_url"]]]) - private_repo_commit_hash = params.diksha_bot_tag + checkout scm: ([$class: 'GitSCM', branches: [[name: "refs/tags/params.private_bot_tag"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: true]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'private_repo_credentials', url: "$bot_repo_url"]]]) + private_repo_commit_hash = params.private_bot_tag } } + + } } stage('Build') { env.NODE_ENV = "build" print "Environment will be : ${env.NODE_ENV}" - build_tag = public_repo_commit_hash + "_" + private_repo_commit_hash + "_" + env.BUILD_NUMBER + "_router" - sh('cp -r bot_repo/* .') + + build_tag = public_repo_commit_hash + "_" + env.BUILD_NUMBER + "_bot" + if (params.private_bot_repo) { + sh('cp -r bot_repo/* .') + build_tag = public_repo_commit_hash + "_" + private_repo_commit_hash + "_" + env.BUILD_NUMBER + "_bot" + } dir('router') { sh('chmod 777 build.sh') sh("./build.sh ${build_tag} ${env.NODE_NAME} ${hub_org}") diff --git a/router/appRest.js b/router/appRest.js index d5c185f..c9df3e2 100644 --- a/router/appRest.js +++ b/router/appRest.js @@ -269,6 +269,9 @@ function menuDrivenLogic(data, res, chatflowConfig) { menuIntentKnown = true // TODO : Don't call function inside each if/else if it should be called once. telemetryData = createInteractionData({ currentStep: currentFlowStep, responseKey: responseKey }, data, false) + // Telemetry event for Main menu button + var mainMenuEventData = createInteractionData({ currentStep: 'step_0', responseKey: 'MAIN_MENU' }, data, false) + telemetry.logInteraction(mainMenuEventData); } else if (data.message === '99') { if (currentFlowStep.lastIndexOf("_") > 0) { currentFlowStep = currentFlowStep.substring(0, currentFlowStep.lastIndexOf("_")) @@ -276,6 +279,9 @@ function menuDrivenLogic(data, res, chatflowConfig) { menuIntentKnown = true // TODO : Don't call function inside each if/else if it should be called once. telemetryData = createInteractionData({ currentStep: currentFlowStep, responseKey: responseKey }, data, false) + // Telemetry event for Go-back button + var goBackEventData = createInteractionData({ currentStep: 'step_99', responseKey: 'GO_BACK' }, data, false) + telemetry.logInteraction(goBackEventData); } } else { responseKey = getErrorMessageForInvalidInput(currentFlowStep, chatflowConfig, true) @@ -532,9 +538,4 @@ function replaceUserSpecficData(str) { } return str; } - - - - - - +module.exports = appBot; diff --git a/router/package.json b/router/package.json index f820767..e3abbd4 100644 --- a/router/package.json +++ b/router/package.json @@ -4,12 +4,16 @@ "description": "thor bot router", "main": "app.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "router-test": "nyc mocha 'test/**/*.spec.js'", + "coverage": "nyc --reporter=lcov --reporter=text-lcov npm run router-test" }, "author": "waibhav", "license": "ISC", "dependencies": { "axios": "^0.19.2", + "body-parser": "^1.19.0", + "chai": "^4.2.0", + "chai-http": "^4.3.0", "cors": "^2.8.5", "dateformat": "^3.0.3", "elasticsearch": "^16.6.0", @@ -18,15 +22,18 @@ "helmet": "^3.21.2", "lodash": "^4.17.20", "method-override": "^3.0.0", - "ua-parser-js": "^0.7.13", - "sb_telemetry_util": "file:libs/sb_telemetry_util", - "sb_config_util": "file:libs/sb-config-util", - "sb_logger_util": "file:libs/sb_logger_util", + "mocha": "^8.2.1", + "nock": "^13.0.5", + "nyc": "^15.1.0", "redis": "^3.0.2", "request": "^2.88.0", "require-reload": "^0.2.2", + "sb_config_util": "file:libs/sb-config-util", + "sb_logger_util": "file:libs/sb_logger_util", + "sb_telemetry_util": "file:libs/sb_telemetry_util", "socket.io": "^2.3.0", "tz-lookup": "^6.1.25", + "ua-parser-js": "^0.7.13", "uuid": "^3.4.0", "winston": "^3.2.1" } diff --git a/router/test/appRest.spec.js b/router/test/appRest.spec.js new file mode 100644 index 0000000..11f6556 --- /dev/null +++ b/router/test/appRest.spec.js @@ -0,0 +1,78 @@ +const chai = require('chai'); +let chaiHttp = require('chai-http'); +chai.should(); +chai.use(chaiHttp); +let server = require('../appRest'); +const nock = require('nock'); +const mockData = require('./mock.data.spec'); +var expect = require('chai').expect; + +describe('Chatbot router APIs', () => { + it('it should get bot response fot user input on web portal', (done) => { + nock('https://dev.sunbirded.org/chatapi') + .post('/bot') + .reply(200, mockData.botResponse); + const response = {"type":"button","data":{"text":" Hello, I am Tara!
I am your DIKSHA guide
Please select your preference from the options I provide or type your query directly.","buttons":[{"text":"Digital content","value":"1"},{"text":"Courses","value":"2"},{"text":"DIKSHA mobile app","value":"3"},{"text":"Content contribution","value":"4"},{"text":"Other DIKSHA queries","value":"5"}]}} + chai.request(server) + .post('/bot') + .send({ + "Body": "0", + "userId": "449c94833e1caa71aaadfe2567bea945", + "appId": "prod.diksha.portal", + "channel": "505c7c48ac6dc1edc9b08f21db5a571d", + "From": "449c94833e1caa71aaadfe2567bea945" + }) + .end((err, res) => { + expect(res).to.be.a('object'); + expect(res.body).to.be.a('Object'); + expect(JSON.stringify(res.body)).to.equal(JSON.stringify(response)); + done(); + }); + }); + + xit('it should get bot response fot user input in whats app', (done) => { + nock('https://preprod.ntp.net.in/chatapi') + .post('/whatsapp') + .reply(200, mockData.whatsappResponse); + const response = { + "text": "Hi, I’m TARA, your DIKSHA assistant. How may I help you today? \n Select from one of the following options. Send the number corresponding to your choice \n 1- To find and play content \n 2- To download/update the DIKSHA mobile app \n 3- Other Queries", + "intent": "greet", + "type": "buttons", + "buttons": [] + }; + chai.request(server) + .post('/whatsapp') + .send({ + "incoming_message": [{ + "from": "9611654628", + "text_type": { + "text": "0" + } + }] + }) + .end((err, res) => { + expect(res).to.be.a('object'); + expect(res.body).to.be.a('Object'); + expect(JSON.stringify(res.body)).to.equal(JSON.stringify(response)); + done(); + }); + }); + + it('refresh the config', (done) => { + nock('https://dev.sunbirded.org/chatapi') + .post('/refresh') + .reply(200, mockData.refreshAPIResponse); + const response = { + "msg": "ENV configuration blob path is not defined" + } + chai.request(server) + .post('/refresh') + .end((err, res) => { + expect(res).to.be.a('object'); + expect(res.body).to.be.a('Object'); + expect(JSON.stringify(res.body)).to.equal(JSON.stringify(response)); + done(); + }); + }); + +}); \ No newline at end of file diff --git a/router/test/mock.data.spec.js b/router/test/mock.data.spec.js new file mode 100644 index 0000000..a030897 --- /dev/null +++ b/router/test/mock.data.spec.js @@ -0,0 +1,53 @@ +module.exports = { + botResponse:{ + "type": "button", + "data": { + "text": " Hello, I am Tara!
I am your DIKSHA guide
Please select your preference from the options I provide or type your query directly.", + "buttons": [ + { + "text": "Digital content", + "value": "1" + }, + { + "text": "Courses", + "value": "2" + }, + { + "text": "DIKSHA mobile app", + "value": "3" + }, + { + "text": "Content contribution", + "value": "4" + }, + { + "text": "Other DIKSHA queries", + "value": "5" + } + ] + } + }, + whatsappResponse:{ + "text": "Hi, I’m TARA, your DIKSHA assistant. How may I help you today? \n Select from one of the following options. Send the number corresponding to your choice \n 1- To find and play content \n 2- To download/update the DIKSHA mobile app \n 3- Other Queries", + "intent": "greet", + "type": "buttons", + "buttons": [] + }, + refreshAPIResponse: { + "msg": "ENV configuration blob path is not defined" + }, + postRes: { + "code": "ok", + "payload": {} + }, + errorResponse: { + "code": "params-missing", + "message": "Something was wrong with the request payload you passed in. | Required parameters were missing from this API call, please see the \"params\" property", + "params": {} + }, + errorMessage: { + "code": "not-found", + "message": "Invalid API call", + "params": {} +} +} \ No newline at end of file