├── .gitignore ├── .npmignore ├── .travis.yml ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yml ├── package.json ├── src └── index.js └── test ├── custom-text-message_test.js ├── enter-leave_test.js ├── events_test.js ├── hello-world-listener_test.js ├── hello-world_test.coffee ├── hello-world_test.js ├── httpd-world_test.js ├── load-multiple-scripts_test.js ├── message-room_test.js ├── mock-response_test.js ├── private-message_test.js ├── scripts ├── bye.js ├── custom-text-message.js ├── enter-leave.js ├── events.js ├── hello-world-listener.js ├── hello-world.coffee ├── hello-world.js ├── httpd-world.js ├── message-room.js ├── mock-response.js ├── private-message.js └── user-params.js └── user-params_test.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /lib 3 | /yarn.lock 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mtsmfm/hubot-test-helper/37b5e99faa2023c95d88c420b2b3bb1f09dd07b1/.npmignore -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | cache: 4 | directories: 5 | - node_modules 6 | notifications: 7 | email: false 8 | node_js: 9 | - '4' 10 | - '8' 11 | before_install: 12 | - npm i -g npm@^2.0.0 13 | before_script: 14 | - npm prune 15 | after_success: 16 | - npm run semantic-release 17 | branches: 18 | except: 19 | - "/^v\\d+\\.\\d+\\.\\d+$/" 20 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:4 2 | 3 | RUN npm install -g yarn 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Fumiaki Matsushima 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hubot test helper 2 | 3 | [![Build Status](https://travis-ci.org/mtsmfm/hubot-test-helper.svg?branch=master)](https://travis-ci.org/mtsmfm/hubot-test-helper) 4 | 5 | Helper for testing Hubot script. 6 | 7 | ## Install 8 | 9 | `npm install hubot-test-helper --save-dev` 10 | 11 | ## Usage 12 | 13 | If you have a following hubot script: 14 | 15 | ```javascript 16 | module.exports = robot => 17 | robot.respond(/hi$/i, msg => msg.reply('hi')) 18 | ``` 19 | 20 | You can test it like: 21 | 22 | ```javascript 23 | const Helper = require('hubot-test-helper'); 24 | // helper loads all scripts passed a directory 25 | const helper = new Helper('./scripts'); 26 | 27 | // helper loads a specific script if it's a file 28 | const scriptHelper = new Helper('./scripts/specific-script.js'); 29 | 30 | const co = require('co'); 31 | const expect = require('chai').expect; 32 | 33 | describe('hello-world', function() { 34 | beforeEach(function() { 35 | this.room = helper.createRoom(); 36 | }); 37 | afterEach(function() { 38 | this.room.destroy(); 39 | }); 40 | 41 | context('user says hi to hubot', function() { 42 | beforeEach(function() { 43 | return co(function*() { 44 | yield this.room.user.say('alice', '@hubot hi'); 45 | yield this.room.user.say('bob', '@hubot hi'); 46 | }.bind(this)); 47 | }); 48 | 49 | it('should reply to user', function() { 50 | expect(this.room.messages).to.eql([ 51 | ['alice', '@hubot hi'], 52 | ['hubot', '@alice hi'], 53 | ['bob', '@hubot hi'], 54 | ['hubot', '@bob hi'] 55 | ]); 56 | }); 57 | }); 58 | }); 59 | ``` 60 | 61 | #### HTTPD 62 | 63 | By default Hubot enables a built in HTTP server. The server continues between 64 | tests and so requires it to be shutdown during teardown using `room.destroy()`. 65 | 66 | This feature can be turned off in tests that don't need it by passing using 67 | `helper.createRoom(httpd: false)`. 68 | 69 | See [the tests](test/httpd-world_test.js) for an example of testing the 70 | HTTP server. 71 | 72 | 73 | #### Manual delay 74 | 75 | Sometimes we can't access callback actions from a script. 76 | Just like in real use-case we may have to wait for a bot to finish processing before replying, 77 | in testing we may anticipate the delayed reply with a manual time delay. 78 | 79 | For example we have the following script: 80 | 81 | ```javascript 82 | module.exports = robot => 83 | robot.hear(/(http(?:s?):\/\/(\S*))/i, res => { 84 | const url = res.match[1]; 85 | res.send(`ok1: ${url}`); 86 | robot.http(url).get()((err, response, body) => res.send(`ok2: ${url}`)); 87 | }); 88 | ``` 89 | 90 | To test the second callback response "ok2: ..." we use the following script: 91 | 92 | ```javascript 93 | const Helper = require('hubot-test-helper'); 94 | const helper = new Helper('../scripts/http.js'); 95 | 96 | const Promise = require('bluebird'); 97 | const co = require('co'); 98 | const expect = require('chai').expect; 99 | 100 | // test ping 101 | describe('http', function() { 102 | beforeEach(function() { 103 | this.room = helper.createRoom({httpd: false}); 104 | }); 105 | 106 | // Test case 107 | context('user posts link', function() { 108 | beforeEach(function() { 109 | return co(function*() { 110 | yield this.room.user.say('user1', 'http://google.com'); 111 | // delay one second for the second 112 | // callback message to be posted to @room 113 | yield new Promise.delay(1000); 114 | }.bind(this)); 115 | }); 116 | 117 | // response 118 | it('expects deplayed callback from ok2', function() { 119 | console.log(this.room.messages); 120 | expect(this.room.messages).to.eql([ 121 | ['user1', 'http://google.com'], 122 | ['hubot', 'ok1: http://google.com'], 123 | ['hubot', 'ok2: http://google.com'] 124 | ]); 125 | }); 126 | }); 127 | }); 128 | ``` 129 | 130 | Note that `yield` and *generators* are part of [**ECMA6**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*), so it may not work on older node.js versions. It will wait for the delay to complete the `beforeEach` before proceeding to the test `it`. 131 | 132 | 133 | #### Testing messages sent to other rooms 134 | 135 | You can also test messages sent by your script to other rooms through Hubot's `robot.messageRoom(...)` method. 136 | 137 | Given the following script: 138 | ```javascript 139 | module.exports = robot => 140 | robot.respond(/announce otherRoom: (.+)$/i, msg => { 141 | robot.messageRoom('otherRoom', "@#{msg.envelope.user.name} said: #{msg.msg.match[1]}"); 142 | }) 143 | ``` 144 | 145 | you could test the messages sent to other rooms like this: 146 | ```javascript 147 | const Helper = require('../src/index'); 148 | const helper = new Helper('../scripts/message-room.js'); 149 | 150 | const expect = require('chai').expect; 151 | 152 | describe('message-room', function() { 153 | beforeEach(function() { 154 | this.room = helper.createRoom({name: 'room', httpd: false}); 155 | }); 156 | 157 | context('user asks hubot to announce something', function() { 158 | beforeEach(function() { 159 | return co(function*() { 160 | yield this.room.user.say('alice', '@hubot announce otherRoom: I love hubot!'); 161 | }.bind(this)); 162 | }); 163 | 164 | it('should not post to this channel', function() { 165 | expect(this.room.messages).to.eql([ 166 | ['alice', '@hubot announce otherRoom: I love hubot!'] 167 | ]); 168 | }); 169 | 170 | it('should post to the other channel', function() { 171 | expect(this.room.robot.messagesTo['otherRoom']).to.eql([ 172 | ['hubot', '@alice says: I love hubot!'] 173 | ]); 174 | }); 175 | }); 176 | }); 177 | ``` 178 | 179 | 180 | #### Testing events 181 | 182 | You can also test events emitted by your script. For example, Slack users 183 | may want to test the creation of a 184 | [message attachment](https://api.slack.com/docs/attachments). 185 | 186 | Given the following script: 187 | 188 | ```javascript 189 | module.exports = robot => 190 | robot.respond(/check status$/i, msg => 191 | robot.emit('slack.attachment', { 192 | message: msg.message, 193 | content: { 194 | color: "good", 195 | text: "It's all good!" 196 | } 197 | }) 198 | ) 199 | ``` 200 | 201 | you could test the emitted event like this: 202 | 203 | ```javascript 204 | const Helper = require('hubot-test-helper'); 205 | const helper = new Helper('../scripts/status_check.js'); 206 | 207 | const expect = require('chai').expect; 208 | 209 | describe('status check', function() { 210 | beforeEach(function() { 211 | this.room = helper.createRoom({httpd: false}); 212 | }); 213 | 214 | it('should send a slack event', function() { 215 | let response = null; 216 | this.room.robot.on('slack.attachment', event => response = event.content); 217 | 218 | this.room.user.say('bob', '@hubot check status').then(() => { 219 | expect(response.text).to.eql("It's all good!"); 220 | }); 221 | }); 222 | }); 223 | ``` 224 | 225 | ## Development 226 | 227 | ### Requirements 228 | 229 | - docker 230 | - docker-compose 231 | 232 | ### Setup 233 | 234 | ``` 235 | git clone https://github.com/mtsmfm/hubot-test-helper 236 | cd hubot-test-helper 237 | docker-compose up -d 238 | docker-compose exec app bash 239 | yarn install 240 | ``` 241 | 242 | ### Run test 243 | 244 | ``` 245 | yarn run test 246 | ``` 247 | 248 | #### Debug 249 | 250 | ``` 251 | yarn run test-unit-debug 252 | ``` 253 | 254 | Above command will output: 255 | 256 | ``` 257 | yarn run v0.18.1 258 | $ mocha --inspect --debug-brk --compilers coffee:coffee-script/register test 259 | Debugger listening on port 9229. 260 | Warning: This is an experimental feature and could change at any time. 261 | To start debugging, open the following URL in Chrome: 262 | chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/59631086-0a0c-424b-8f5b-8828be123894 263 | ``` 264 | 265 | Then open `chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/59631086-0a0c-424b-8f5b-8828be123894` in Chrome. 266 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | app: 4 | build: . 5 | command: 'sh -c "trap : TERM INT; sleep infinity & wait"' 6 | tty: true 7 | stdin_open: true 8 | user: node 9 | working_dir: /app 10 | volumes: 11 | - .:/app:cached 12 | - home:/home/node 13 | ports: 14 | - 9229:9229 15 | 16 | volumes: 17 | home: 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hubot-test-helper", 3 | "description": "Helper for testing hubot script", 4 | "main": "./src/index.js", 5 | "scripts": { 6 | "test": "mocha --compilers coffee:coffee-script/register test", 7 | "autotest": "mocha --compilers coffee:coffee-script/register test -w", 8 | "semantic-release": "semantic-release" 9 | }, 10 | "keywords": [ 11 | "hubot" 12 | ], 13 | "dependencies": { 14 | "hubot": ">=3.0.0 <10 || 0.0.0-development" 15 | }, 16 | "devDependencies": { 17 | "chai": "latest", 18 | "co": "latest", 19 | "mocha": "latest", 20 | "coffee-script": "latest", 21 | "semantic-release": "latest" 22 | }, 23 | "author": "Fumiaki MATSUSHIMA", 24 | "license": "MIT", 25 | "repository": { 26 | "type": "git", 27 | "url": "https://github.com/mtsmfm/hubot-test-helper" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Fs = require('fs'); 4 | const Path = require('path'); 5 | const Hubot = require('hubot/es2015'); 6 | 7 | process.setMaxListeners(0); 8 | 9 | class MockResponse extends Hubot.Response { 10 | sendPrivate(/* ...strings*/) { 11 | const strings = [].slice.call(arguments, 0); 12 | 13 | this.robot.adapter.sendPrivate.apply(this.robot.adapter, [this.envelope].concat(strings)); 14 | } 15 | } 16 | 17 | class MockRobot extends Hubot.Robot { 18 | constructor(httpd) { 19 | if (httpd == null) { httpd = true; } 20 | super(null, null, httpd, 'hubot'); 21 | 22 | this.messagesTo = {}; 23 | 24 | this.Response = MockResponse; 25 | } 26 | 27 | messageRoom(roomName, str) { 28 | if (roomName == this.adapter.name) { 29 | this.adapter.messages.push(['hubot', str]); 30 | } else { 31 | if (!(roomName in this.messagesTo)) { 32 | this.messagesTo[roomName] = []; 33 | } 34 | this.messagesTo[roomName].push(['hubot', str]); 35 | } 36 | } 37 | 38 | loadAdapter() { 39 | this.adapter = new Room(this); 40 | } 41 | } 42 | 43 | class Room extends Hubot.Adapter { 44 | // XXX: https://github.com/hubotio/hubot/pull/1390 45 | static messages(obj) { 46 | if (obj instanceof MockRobot) { 47 | return obj.adapter.messages; 48 | } else { 49 | return obj.messages; 50 | } 51 | } 52 | 53 | constructor(robot) { 54 | super(); 55 | this.robot = robot; 56 | this.messages = []; 57 | 58 | this.privateMessages = {}; 59 | 60 | this.user = { 61 | say: (userName, message, userParams) => this.receive(userName, message, userParams), 62 | enter: (userName, userParams) => this.enter(userName, userParams), 63 | leave: (userName, userParams) => this.leave(userName, userParams) 64 | }; 65 | } 66 | 67 | receive(userName, message, userParams) { 68 | if (userParams == null) { userParams = {}; } 69 | return new Promise(resolve => { 70 | let textMessage = null; 71 | if ((typeof message === 'object') && message) { 72 | textMessage = message; 73 | } else { 74 | userParams.room = this.name; 75 | const user = new Hubot.User(userName, userParams); 76 | textMessage = new Hubot.TextMessage(user, message); 77 | } 78 | 79 | this.messages.push([userName, textMessage.text]); 80 | this.robot.receive(textMessage, resolve); 81 | }); 82 | } 83 | 84 | destroy() { 85 | if (this.robot.server) { this.robot.server.close(); } 86 | } 87 | 88 | reply(envelope/*, ...strings*/) { 89 | const strings = [].slice.call(arguments, 1); 90 | 91 | strings.forEach((str) => Room.messages(this).push(['hubot', `@${envelope.user.name} ${str}`])); 92 | } 93 | 94 | send(envelope/*, ...strings*/) { 95 | const strings = [].slice.call(arguments, 1); 96 | 97 | strings.forEach((str) => Room.messages(this).push(['hubot', str])); 98 | } 99 | 100 | sendPrivate(envelope/*, ...strings*/) { 101 | const strings = [].slice.call(arguments, 1); 102 | 103 | if (!(envelope.user.name in this.privateMessages)) { 104 | this.privateMessages[envelope.user.name] = []; 105 | } 106 | strings.forEach((str) => this.privateMessages[envelope.user.name].push(['hubot', str])); 107 | } 108 | 109 | robotEvent() { 110 | this.robot.emit.apply(this.robot, arguments); 111 | } 112 | 113 | enter(userName, userParams) { 114 | if (userParams == null) { userParams = {}; } 115 | return new Promise(resolve => { 116 | userParams.room = this.name; 117 | const user = new Hubot.User(userName, userParams); 118 | this.robot.receive(new Hubot.EnterMessage(user), resolve); 119 | }); 120 | } 121 | 122 | leave(userName, userParams) { 123 | if (userParams == null) { userParams = {}; } 124 | return new Promise(resolve => { 125 | userParams.room = this.name; 126 | const user = new Hubot.User(userName, userParams); 127 | this.robot.receive(new Hubot.LeaveMessage(user), resolve); 128 | }); 129 | } 130 | } 131 | 132 | class Helper { 133 | constructor(scriptsPaths) { 134 | if (!Array.isArray(scriptsPaths)) { 135 | scriptsPaths = [scriptsPaths]; 136 | } 137 | this.scriptsPaths = scriptsPaths; 138 | } 139 | 140 | createRoom(options) { 141 | if (options == null) { options = {}; } 142 | const robot = new MockRobot(options.httpd); 143 | 144 | if ('response' in options) { 145 | robot.Response = options.response; 146 | } 147 | 148 | for (let script of this.scriptsPaths) { 149 | script = Path.resolve(Path.dirname(module.parent.filename), script); 150 | if (Fs.statSync(script).isDirectory()) { 151 | for (let file of Fs.readdirSync(script).sort()) { 152 | robot.loadFile(script, file); 153 | } 154 | } else { 155 | robot.loadFile(Path.dirname(script), Path.basename(script)); 156 | } 157 | } 158 | 159 | robot.brain.emit('loaded'); 160 | 161 | robot.adapter.name = options.name || 'room1'; 162 | return robot.adapter; 163 | } 164 | } 165 | Helper.Response = MockResponse; 166 | 167 | module.exports = Helper; 168 | -------------------------------------------------------------------------------- /test/custom-text-message_test.js: -------------------------------------------------------------------------------- 1 | const Helper = require('../src/index'); 2 | const helper = new Helper('./scripts/custom-text-message.js'); 3 | const Hubot = require('hubot'); 4 | 5 | const co = require('co'); 6 | const expect = require('chai').expect; 7 | 8 | describe('custom-text-message', function() { 9 | beforeEach(function() { 10 | this.room = helper.createRoom({httpd: false}); 11 | }); 12 | 13 | context('Passing a custom text message object', function() { 14 | beforeEach(function() { 15 | return co(function*() { 16 | const textMessage = new Hubot.TextMessage({}, ''); 17 | textMessage.isCustom = true; 18 | textMessage.custom = 'custom'; 19 | yield this.room.user.say('user', textMessage); 20 | }.bind(this)); 21 | }); 22 | 23 | it('sends back', function() { 24 | expect(this.room.messages[1][1]).to.be.equal('custom'); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/enter-leave_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper('./scripts/enter-leave.js'); 5 | 6 | const co = require('co'); 7 | const expect = require('chai').expect; 8 | 9 | describe('enter-leave', function() { 10 | beforeEach(function() { 11 | this.room = helper.createRoom({httpd: false}); 12 | }); 13 | 14 | context('user entering then leaving the room', function() { 15 | beforeEach(function() { 16 | return co(function*() { 17 | yield this.room.user.enter('user1'); 18 | yield this.room.user.leave('user1'); 19 | }.bind(this)); 20 | }); 21 | 22 | it('greets the user', function() { 23 | expect(this.room.messages).to.eql([ 24 | ['hubot', 'Hi user1!'], 25 | ['hubot', 'Bye user1!'] 26 | ]); 27 | }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /test/events_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper('./scripts/events.js'); 5 | 6 | const co = require('co'); 7 | const expect = require('chai').expect; 8 | 9 | describe('events', function() { 10 | beforeEach(function() { 11 | this.room = helper.createRoom({httpd: false}); 12 | }); 13 | 14 | context('should post on an event', function() { 15 | beforeEach(function() { 16 | this.room.robotEvent('some-event', 'event', 'data'); 17 | }); 18 | 19 | it('should reply to user', function() { 20 | expect(this.room.messages).to.eql([ 21 | ['hubot', 'got event with event data'] 22 | ]); 23 | }); 24 | }); 25 | 26 | context('should hear events emitted by responses', () => 27 | it('should trigger an event', function() { 28 | let response = null; 29 | this.room.robot.on('response-event', event => response = event.content); 30 | 31 | this.room.user.say('bob', '@hubot send event').then(() => { 32 | expect(response).to.eql('hello'); 33 | }); 34 | }) 35 | ); 36 | }); 37 | -------------------------------------------------------------------------------- /test/hello-world-listener_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper('./scripts/hello-world-listener.js'); 5 | 6 | const co = require('co'); 7 | const expect = require('chai').expect; 8 | 9 | describe('hello-world', function() { 10 | beforeEach(function() { 11 | this.room = helper.createRoom({httpd: false}); 12 | }); 13 | 14 | context('user says hi to hubot', function() { 15 | beforeEach(function() { 16 | return co(function*() { 17 | yield this.room.user.say('alice', '@hubot hi'); 18 | yield this.room.user.say('bob', '@hubot hi'); 19 | }.bind(this)); 20 | }); 21 | 22 | it('should reply to user', function() { 23 | expect(this.room.messages).to.eql([ 24 | ['alice', '@hubot hi'], 25 | ['bob', '@hubot hi'], 26 | ['hubot', '@bob hi'] 27 | ]); 28 | }); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /test/hello-world_test.coffee: -------------------------------------------------------------------------------- 1 | Helper = require('../src/index') 2 | helper = new Helper('./scripts/hello-world.coffee') 3 | 4 | co = require('co') 5 | expect = require('chai').expect 6 | 7 | describe 'hello-world', -> 8 | beforeEach -> 9 | @room = helper.createRoom(httpd: false) 10 | afterEach -> 11 | @room.destroy() 12 | 13 | context 'user says hi to hubot', -> 14 | beforeEach -> 15 | co => 16 | yield @room.user.say 'alice', '@hubot hi' 17 | yield @room.user.say 'bob', '@hubot hi' 18 | 19 | it 'should reply to user', -> 20 | expect(@room.messages).to.eql [ 21 | ['alice', '@hubot hi'] 22 | ['hubot', '@alice hi'] 23 | ['bob', '@hubot hi'] 24 | ['hubot', '@bob hi'] 25 | ] 26 | -------------------------------------------------------------------------------- /test/hello-world_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper('./scripts/hello-world.js'); 5 | 6 | const co = require('co'); 7 | const expect = require('chai').expect; 8 | 9 | describe('hello-world', function() { 10 | beforeEach(function() { 11 | this.room = helper.createRoom({httpd: false}); 12 | }); 13 | afterEach(function() { 14 | this.room.destroy(); 15 | }); 16 | 17 | context('user says hi to hubot', function() { 18 | beforeEach(function() { 19 | return co(function*() { 20 | yield this.room.user.say('alice', '@hubot hi'); 21 | yield this.room.user.say('bob', '@hubot hi'); 22 | }.bind(this)); 23 | }); 24 | 25 | it('should reply to user', function() { 26 | expect(this.room.messages).to.eql([ 27 | ['alice', '@hubot hi'], 28 | ['hubot', '@alice hi'], 29 | ['bob', '@hubot hi'], 30 | ['hubot', '@bob hi'] 31 | ]); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /test/httpd-world_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper('./scripts'); 5 | const http = require('http'); 6 | 7 | const expect = require('chai').expect; 8 | 9 | process.env.EXPRESS_PORT = 8080; 10 | 11 | describe('httpd-world', function() { 12 | beforeEach(function() { 13 | this.room = helper.createRoom(); 14 | }); 15 | 16 | afterEach(function() { 17 | this.room.destroy(); 18 | }); 19 | 20 | context('GET /hello/world', function() { 21 | beforeEach(function(done) { 22 | http.get('http://localhost:8080/hello/world', response => { 23 | this.response = response; 24 | done(); 25 | }).on('error', done); 26 | }); 27 | 28 | it('responds with status 200', function() { 29 | expect(this.response.statusCode).to.equal(200); 30 | }); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /test/load-multiple-scripts_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper(['./scripts/hello-world.js', './scripts/bye.js']); 5 | 6 | const co = require('co'); 7 | const expect = require('chai').expect; 8 | 9 | describe('hello-world', function() { 10 | beforeEach(function() { 11 | this.room = helper.createRoom({httpd: false}); 12 | }); 13 | 14 | context('user says hi to hubot', function() { 15 | beforeEach(function() { 16 | return co(function*() { 17 | yield this.room.user.say('alice', '@hubot hi'); 18 | yield this.room.user.say('bob', '@hubot bye'); 19 | }.bind(this)); 20 | }); 21 | 22 | it('should reply to user', function() { 23 | expect(this.room.messages).to.eql([ 24 | ['alice', '@hubot hi'], 25 | ['hubot', '@alice hi'], 26 | ['bob', '@hubot bye'], 27 | ['hubot', '@bob bye'] 28 | ]); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /test/message-room_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper('./scripts/message-room.js'); 5 | 6 | const co = require('co'); 7 | const expect = require('chai').expect; 8 | 9 | describe('message-room', function() { 10 | beforeEach(function() { 11 | this.room = helper.createRoom({name: 'room', httpd: false}); 12 | }); 13 | 14 | context('user asks hubot to announce something', function() { 15 | beforeEach(function() { 16 | return co(function*() { 17 | yield this.room.user.say('alice', '@hubot announce otherRoom: I love hubot!'); 18 | }.bind(this)); 19 | }); 20 | 21 | it('should not post to this channel', function() { 22 | expect(this.room.messages).to.eql([ 23 | ['alice', '@hubot announce otherRoom: I love hubot!'] 24 | ]); 25 | }); 26 | 27 | it('should post to the other channel', function() { 28 | expect(this.room.robot.messagesTo['otherRoom']).to.eql([ 29 | ['hubot', '@alice says: I love hubot!'] 30 | ]); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /test/mock-response_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper('./scripts/mock-response.js'); 5 | 6 | const co = require('co'); 7 | const expect = require('chai').expect; 8 | 9 | class NewMockResponse extends Helper.Response { 10 | random(items) { 11 | return 3; 12 | } 13 | } 14 | 15 | describe('mock-response', function() { 16 | beforeEach(function() { 17 | this.room = helper.createRoom({response: NewMockResponse, httpd: false}); 18 | }); 19 | 20 | context('user says "give me a random" number to hubot', function() { 21 | beforeEach(function() { 22 | return co(function*() { 23 | yield this.room.user.say('alice', '@hubot give me a random number'); 24 | yield this.room.user.say('bob', '@hubot give me a random number'); 25 | }.bind(this)); 26 | }); 27 | 28 | it('should reply to user with a random number', function() { 29 | expect(this.room.messages).to.eql([ 30 | ['alice', '@hubot give me a random number'], 31 | ['hubot', '@alice 3'], 32 | ['bob', '@hubot give me a random number'], 33 | ['hubot', '@bob 3'] 34 | ]); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/private-message_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper('./scripts/private-message.js'); 5 | 6 | const co = require('co'); 7 | const expect = require('chai').expect; 8 | 9 | describe('private-message', function() { 10 | beforeEach(function() { 11 | this.room = helper.createRoom({httpd: false}); 12 | }); 13 | 14 | context('user asks hubot for a secret', function() { 15 | beforeEach(function() { 16 | return co(function*() { 17 | yield this.room.user.say('alice', '@hubot tell me a secret'); 18 | }.bind(this)); 19 | }); 20 | 21 | it('should not post to the public channel', function() { 22 | expect(this.room.messages).to.eql([ 23 | ['alice', '@hubot tell me a secret'] 24 | ]); 25 | }); 26 | 27 | it('should private message user', function() { 28 | expect(this.room.privateMessages).to.eql({ 29 | 'alice': [ 30 | ['hubot', 'whisper whisper whisper'] 31 | ] 32 | }); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/scripts/bye.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = robot => 4 | robot.respond(/bye$/i, msg => msg.reply('bye')) 5 | ; 6 | -------------------------------------------------------------------------------- /test/scripts/custom-text-message.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = robot => 4 | robot.listen( 5 | message => message.isCustom, 6 | response => response.send(response.message.custom)) 7 | ; 8 | -------------------------------------------------------------------------------- /test/scripts/enter-leave.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = function(robot) { 4 | robot.enter(res => res.send(`Hi ${res.message.user.name}!`)); 5 | 6 | return robot.leave(res => res.send(`Bye ${res.message.user.name}!`)); 7 | }; 8 | -------------------------------------------------------------------------------- /test/scripts/events.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = function(robot) { 4 | robot.on('some-event', (some, data) => robot.messageRoom('room1', `got event with ${some} ${data}`)); 5 | 6 | robot.respond(/send event$/i, msg => robot.emit('response-event', {content: 'hello'})); 7 | }; 8 | -------------------------------------------------------------------------------- /test/scripts/hello-world-listener.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = robot => 4 | robot.listen(message => message.user.name === 'bob', response => response.reply('hi')) 5 | -------------------------------------------------------------------------------- /test/scripts/hello-world.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Test script 3 | module.exports = (robot) -> 4 | robot.respond /hi$/i, (msg) -> 5 | msg.reply 'hi' 6 | -------------------------------------------------------------------------------- /test/scripts/hello-world.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = robot => 4 | robot.respond(/hi$/i, msg => msg.reply('hi')) 5 | ; 6 | -------------------------------------------------------------------------------- /test/scripts/httpd-world.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = robot => 4 | robot.router.get("/hello/world", (req, res) => res.status(200).send("Hello World!")) 5 | ; 6 | -------------------------------------------------------------------------------- /test/scripts/message-room.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = robot => 4 | robot.respond(/announce otherRoom: (.+)$/i, msg => { 5 | robot.messageRoom('otherRoom', '@' + msg.envelope.user.name + ' says: ' + msg.match[1]); 6 | }) 7 | -------------------------------------------------------------------------------- /test/scripts/mock-response.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = robot => 4 | robot.respond(/give me a random number$/i, function(msg) { 5 | const randomNumber = msg.random([1, 2, 3, 4, 5]); 6 | msg.reply(randomNumber); 7 | }) 8 | ; 9 | -------------------------------------------------------------------------------- /test/scripts/private-message.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = robot => 4 | robot.respond(/tell me a secret$/i, msg => msg.sendPrivate('whisper whisper whisper')) 5 | ; 6 | -------------------------------------------------------------------------------- /test/scripts/user-params.js: -------------------------------------------------------------------------------- 1 | // Description: 2 | // Test script 3 | module.exports = robot => 4 | robot.listen( 5 | () => true, 6 | response => response.send(JSON.stringify(response.message.user))) 7 | ; 8 | -------------------------------------------------------------------------------- /test/user-params_test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Helper = require('../src/index'); 4 | const helper = new Helper('./scripts/user-params.js'); 5 | 6 | const co = require('co'); 7 | const expect = require('chai').expect; 8 | 9 | describe('enter-leave', function() { 10 | beforeEach(function() { 11 | this.room = helper.createRoom({httpd: false}); 12 | }); 13 | 14 | context('user entering, leaving the room and sending a message', function() { 15 | const params = { id: 1, name: 2, profile: 3 }; 16 | beforeEach(function() { 17 | return co(function*() { 18 | yield this.room.user.enter('user1', params); 19 | yield this.room.user.say('user1', 'Hi', params); 20 | yield this.room.user.leave('user1', params); 21 | }.bind(this)); 22 | }); 23 | 24 | it('sends back', function() { 25 | for (let msg of this.room.messages) { 26 | if (msg[0] === 'hubot') { 27 | expect(JSON.parse(msg[1])).to.include(params) 28 | } 29 | } 30 | }); 31 | }); 32 | }); 33 | --------------------------------------------------------------------------------