Skip to content

Instantly share code, notes, and snippets.

@yaron-idan
Created August 11, 2019 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yaron-idan/e85e9c9fcc1615138bd9ad866115b742 to your computer and use it in GitHub Desktop.
Save yaron-idan/e85e9c9fcc1615138bd9ad866115b742 to your computer and use it in GitHub Desktop.
Botkit-mock tests for dialog
// __ __ ___ ___
// |__) / \ | |__/ | |
// |__) \__/ | | \ | |
// This is the main file for the botium bot.
// Import Botkit's core features
const { Botkit, BotkitConversation } = require('botkit');
const { BotkitCMSHelper } = require('botkit-plugin-cms');
// Import a platform-specific adapter for slack.
const { SlackAdapter, SlackMessageTypeMiddleware, SlackEventMiddleware } = require('botbuilder-adapter-slack');
const { MongoDbStorage } = require('botbuilder-storage-mongodb');
// Load process.env values from .env file
require('dotenv').config();
let storage = null;
if (process.env.MONGO_URI) {
storage = mongoStorage = new MongoDbStorage({
url : process.env.MONGO_URI,
});
}
const adapter = new SlackAdapter({
// REMOVE THIS OPTION AFTER YOU HAVE CONFIGURED YOUR APP!
enable_incomplete: true,
// parameters used to secure webhook endpoint
verificationToken: process.env.verificationToken,
clientSigningSecret: process.env.clientSigningSecret,
// auth token for a single-team app
botToken: process.env.botToken,
// credentials used to set up oauth for multi-team apps
clientId: process.env.clientId,
clientSecret: process.env.clientSecret,
scopes: ['bot'],
redirectUri: process.env.redirectUri,
// functions required for retrieving team-specific info
// for use in multi-team apps
getTokenForTeam: getTokenForTeam,
getBotUserByTeam: getBotUserByTeam,
});
// Use SlackEventMiddleware to emit events that match their original Slack event types.
adapter.use(new SlackEventMiddleware());
// Use SlackMessageType middleware to further classify messages as direct_message, direct_mention, or mention
adapter.use(new SlackMessageTypeMiddleware());
const controller = new Botkit({
webhook_uri: '/api/messages',
adapter: adapter,
storage
});
if (process.env.cms_uri) {
controller.usePlugin(new BotkitCMSHelper({
uri: process.env.cms_uri,
token: process.env.cms_token,
}));
}
// Once the bot has booted up its internal services, you can use them to do stuff.
controller.ready(() => {
// load traditional developer-created local custom feature modules
controller.loadModules(__dirname + '/features');
/* catch-all that uses the CMS to trigger dialogs */
if (controller.plugins.cms) {
controller.on('message,direct_message', async (bot, message) => {
let results = false;
results = await controller.plugins.cms.testTrigger(bot, message);
if (results !== false) {
// do not continue middleware!
return false;
}
});
}
});
controller.webserver.get('/', (req, res) => {
res.send(`This app is running Botkit ${ controller.version }.`);
});
controller.webserver.get('/install', (req, res) => {
// getInstallLink points to slack's oauth endpoint and includes clientId and scopes
res.redirect(controller.adapter.getInstallLink());
});
controller.webserver.get('/install/auth', async (req, res) => {
try {
const results = await controller.adapter.validateOauthCode(req.query.code);
console.log('FULL OAUTH DETAILS', results);
// Store token by team in bot state.
tokenCache[results.team_id] = results.bot.bot_access_token;
// Capture team to bot id
userCache[results.team_id] = results.bot.bot_user_id;
res.json('Success! Bot installed.');
} catch (err) {
console.error('OAUTH ERROR:', err);
res.status(401);
res.send(err.message);
}
});
let tokenCache = {};
let userCache = {};
if (process.env.TOKENS) {
tokenCache = JSON.parse(process.env.TOKENS);
}
if (process.env.USERS) {
userCache = JSON.parse(process.env.USERS);
}
async function getTokenForTeam(teamId) {
if (tokenCache[teamId]) {
return new Promise((resolve) => {
setTimeout(function() {
resolve(tokenCache[teamId]);
}, 150);
});
} else {
console.error('Team not found in tokenCache: ', teamId);
}
}
async function getBotUserByTeam(teamId) {
if (userCache[teamId]) {
return new Promise((resolve) => {
setTimeout(function() {
resolve(userCache[teamId]);
}, 150);
});
} else {
console.error('Team not found in userCache: ', teamId);
}
}
controller.addDialog(createServiceDialog());
function createServiceDialog() {
const MY_DIALOG_ID = 'my-dialog-name-constant';
let convo = new BotkitConversation(MY_DIALOG_ID, controller);
convo.say('Howdy!');
return (convo);
}
const { SlackDialog } = require('botbuilder-adapter-slack');
const { BotkitConversation } = require('botkit');
const MY_DIALOG_ID = 'my-dialog-name-constant';
module.exports = function(controller) {
controller.hears('create_service', 'message', async(bot, message) => {
await bot.startConversationInThread(message.channel, message.user, message.incoming_message.channelData.ts);
await bot.say('Howdy!');
});
}
const { SlackDialog } = require('botbuilder-adapter-slack');
const { BotkitConversation } = require('botkit');
const MY_DIALOG_ID = 'my-dialog-name-constant';
module.exports = function(controller) {
controller.hears('create_dialog_service', 'message', async(bot, message) => {
await bot.startConversationInThread(message.channel, message.user, message.incoming_message.channelData.ts);
await bot.beginDialog(MY_DIALOG_ID);
});
}
'use strict';
const assert = require('assert');
const {BotMock, SlackApiMock} = require('botkit-mock');
const {SlackAdapter, SlackMessageTypeMiddleware, SlackEventMiddleware} = require('botbuilder-adapter-slack');
const fileBeingTested = require('../features/create_service');
async function setTimeoutAsync(timeout = 100) {
return new Promise((r) => setTimeout(r, timeout));
}
describe('create_service file slack-features', () => {
const initController = () => {
const adapter = new SlackAdapter({
clientSigningSecret: "some secret",
botToken: "some token",
debug: true,
});
adapter.use(new SlackEventMiddleware());
adapter.use(new SlackMessageTypeMiddleware());
this.controller = new BotMock({
adapter: adapter,
});
SlackApiMock.bindMockApi(this.controller);
fileBeingTested(this.controller);
};
beforeEach(() => {
this.userInfo = {
slackId: 'user123',
channel: 'channel123',
};
});
describe('create_service', () => {
beforeEach(() => {
initController();
});
it(`should reply in a correct sequence through message`, async () => {
const reply = await this.controller.usersInput([
{
type: 'message',
user: this.userInfo.slackId, //user required for each direct message
channel: this.userInfo.channel, // user channel required for direct message
messages: [
{
text: 'create_service',
isAssertion: true,
}
]
}
]);
assert.strictEqual(this.controller.detailed_answers[this.userInfo.channel][0].text, `Howdy!`);
});
});
});
'use strict';
const assert = require('assert');
const {BotMock, SlackApiMock} = require('botkit-mock');
const {SlackAdapter, SlackMessageTypeMiddleware, SlackEventMiddleware} = require('botbuilder-adapter-slack');
const fileBeingTested = require('../features/create_service_dialog');
async function setTimeoutAsync(timeout = 100) {
return new Promise((r) => setTimeout(r, timeout));
}
describe('create_service file slack-features', () => {
const initController = () => {
const adapter = new SlackAdapter({
clientSigningSecret: "some secret",
botToken: "some token",
debug: true,
});
adapter.use(new SlackEventMiddleware());
adapter.use(new SlackMessageTypeMiddleware());
this.controller = new BotMock({
adapter: adapter,
});
SlackApiMock.bindMockApi(this.controller);
fileBeingTested(this.controller);
};
beforeEach(() => {
this.userInfo = {
slackId: 'user123',
channel: 'channel123',
};
});
describe('create_service', () => {
beforeEach(() => {
initController();
});
it(`should reply in a correct sequence through message`, async () => {
const reply = await this.controller.usersInput([
{
type: 'message',
user: this.userInfo.slackId, //user required for each direct message
channel: this.userInfo.channel, // user channel required for direct message
messages: [
{
text: 'create_dialog_service',
isAssertion: true,
}
]
}
]);
assert.strictEqual(this.controller.detailed_answers[this.userInfo.channel][0].text, `Howdy!`);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment