Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for hubot 10 #63

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/node_modules
/lib
/yarn.lock

.idea
*.iml
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20
264 changes: 134 additions & 130 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,59 +12,63 @@ Helper for testing Hubot script.

If you have a following hubot script:

```javascript
module.exports = robot =>
robot.respond(/hi$/i, msg => msg.reply('hi'))
```js
module.exports = robot => {
robot.respond(/hi$/i, msg => {
msg.reply('hi');
});
}
```

You can test it like:

```javascript
```js
const Helper = require('hubot-test-helper');
// helper loads all scripts passed a directory
const helper = new Helper('./scripts');

// helper loads a specific script if it's a file
const scriptHelper = new Helper('./scripts/specific-script.js');

const co = require('co');
const expect = require('chai').expect;

describe('hello-world', function() {
beforeEach(function() {
this.room = helper.createRoom();
});
afterEach(function() {
this.room.destroy();
});

context('user says hi to hubot', function() {
beforeEach(function() {
return co(function*() {
yield this.room.user.say('alice', '@hubot hi');
yield this.room.user.say('bob', '@hubot hi');
}.bind(this));
const { expect } = require('chai');

describe('hello-world', () => {
let room;

beforeEach(async () => {
room = await helper.createRoom();
});
afterEach(() => {
room.destroy();
});

it('should reply to user', function() {
expect(this.room.messages).to.eql([
['alice', '@hubot hi'],
['hubot', '@alice hi'],
['bob', '@hubot hi'],
['hubot', '@bob hi']
]);
context('user says hi to hubot', () => {
beforeEach(async () => {
await room.user.say('alice', '@hubot hi');
await room.user.say('bob', '@hubot hi');
});

it('should reply to user', () => {
expect(room.messages).to.eql([
['alice', '@hubot hi'],
['hubot', '@alice hi'],
['bob', '@hubot hi'],
['hubot', '@bob hi']
]);
});
});
});
});
```

#### HTTPD

By default Hubot enables a built in HTTP server. The server continues between
By default, Hubot enables a built-in HTTP server. The server continues between
tests and so requires it to be shutdown during teardown using `room.destroy()`.

This feature can be turned off in tests that don't need it by passing using
`helper.createRoom(httpd: false)`.
This feature is turned off in tests by default but can be turned on by using
```js
helper.createRoom({httpd: true})
```

See [the tests](test/httpd-world_test.js) for an example of testing the
HTTP server.
Expand All @@ -76,103 +80,100 @@ Sometimes we can't access callback actions from a script.
Just like in real use-case we may have to wait for a bot to finish processing before replying,
in testing we may anticipate the delayed reply with a manual time delay.

For example we have the following script:
For example, we have the following script:

```javascript
module.exports = robot =>
robot.hear(/(http(?:s?):\/\/(\S*))/i, res => {
const url = res.match[1];
res.send(`ok1: ${url}`);
robot.http(url).get()((err, response, body) => res.send(`ok2: ${url}`));
});
```js
module.exports = robot => {
robot.hear(/(http(?:s?):\/\/(\S*))/i, res => {
const url = res.match[1];
res.send(`ok1: ${url}`);
robot.http(url).get()((err, response, body) => res.send(`ok2: ${url}`));
});
}
```

To test the second callback response "ok2: ..." we use the following script:

```javascript
```js
const Helper = require('hubot-test-helper');
const helper = new Helper('../scripts/http.js');
const { expect } = require('chai');

const Promise = require('bluebird');
const co = require('co');
const expect = require('chai').expect;
const helper = new Helper('./scripts/http.js');

// test ping
describe('http', function() {
beforeEach(function() {
this.room = helper.createRoom({httpd: false});
});

// Test case
context('user posts link', function() {
beforeEach(function() {
return co(function*() {
yield this.room.user.say('user1', 'http://google.com');
// delay one second for the second
// callback message to be posted to @room
yield new Promise.delay(1000);
}.bind(this));
describe('http', () => {
let room;

beforeEach(async () => {
room = await helper.createRoom();
});

// response
it('expects deplayed callback from ok2', function() {
console.log(this.room.messages);
expect(this.room.messages).to.eql([
['user1', 'http://google.com'],
['hubot', 'ok1: http://google.com'],
['hubot', 'ok2: http://google.com']
]);
// Test case
context('user posts link', () => {
beforeEach(async () => {
await room.user.say('user1', 'http://google.com');
// delay one second for the second
// callback message to be posted to @room
await new Promise.delay(1000);
});

// response
it('expects deplayed callback from ok2', () => {
console.log(room.messages);
expect(room.messages).to.eql([
['user1', 'http://google.com'],
['hubot', 'ok1: http://google.com'],
['hubot', 'ok2: http://google.com']
]);
});
});
});
});
```

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`.


#### Testing messages sent to other rooms

You can also test messages sent by your script to other rooms through Hubot's `robot.messageRoom(...)` method.

Given the following script:
```javascript
module.exports = robot =>
robot.respond(/announce otherRoom: (.+)$/i, msg => {
robot.messageRoom('otherRoom', "@#{msg.envelope.user.name} said: #{msg.msg.match[1]}");
})
```js
module.exports = robot => {
robot.respond(/announce otherRoom: (.+)$/i, msg => {
robot.messageRoom('otherRoom', `@${msg.envelope.user.name} said: ${msg.msg.match[1]}`);
});
}
```

you could test the messages sent to other rooms like this:
```javascript
const Helper = require('../src/index');
const helper = new Helper('../scripts/message-room.js');

const expect = require('chai').expect;

describe('message-room', function() {
beforeEach(function() {
this.room = helper.createRoom({name: 'room', httpd: false});
});

context('user asks hubot to announce something', function() {
beforeEach(function() {
return co(function*() {
yield this.room.user.say('alice', '@hubot announce otherRoom: I love hubot!');
}.bind(this));
});
```js
const Helper = require('hubot-test-helper');
const { expect } = require('chai');

const helper = new Helper('./scripts/message-room.js');

describe('message-room', () => {
let room;

it('should not post to this channel', function() {
expect(this.room.messages).to.eql([
['alice', '@hubot announce otherRoom: I love hubot!']
]);
beforeEach(async () => {
room = await helper.createRoom();
});

it('should post to the other channel', function() {
expect(this.room.robot.messagesTo['otherRoom']).to.eql([
['hubot', '@alice says: I love hubot!']
]);
context('user asks hubot to announce something', () => {
beforeEach(async () => {
await room.user.say('alice', '@hubot announce otherRoom: I love hubot!');
});

it('should not post to this channel', () => {
expect(room.messages).to.eql([
['alice', '@hubot announce otherRoom: I love hubot!']
]);
});

it('should post to the other channel', () => {
expect(room.robot.messagesTo['otherRoom']).to.eql([
['hubot', '@alice says: I love hubot!']
]);
});
});
});
});
```

Expand All @@ -185,40 +186,43 @@ may want to test the creation of a

Given the following script:

```javascript
module.exports = robot =>
robot.respond(/check status$/i, msg =>
robot.emit('slack.attachment', {
message: msg.message,
content: {
color: "good",
text: "It's all good!"
}
})
)
```js
module.exports = (robot) => {
robot.respond(/check status$/i, msg => {
robot.emit('slack.attachment', {
message: msg.message,
content: {
color: "good",
text: "It's all good!"
}
});
});
}
```

you could test the emitted event like this:

```javascript
```js
const Helper = require('hubot-test-helper');
const helper = new Helper('../scripts/status_check.js');
const { expect } = require('chai');

const helper = new Helper('./scripts/status_check-room.js');

const expect = require('chai').expect;
describe('status check', () => {
let room;

describe('status check', function() {
beforeEach(function() {
this.room = helper.createRoom({httpd: false});
});
beforeEach(async () => {
room = await helper.createRoom();
});

it('should send a slack event', function() {
let response = null;
this.room.robot.on('slack.attachment', event => response = event.content);
it('should send a slack event', () => {
let response = null;
room.robot.on('slack.attachment', event => response = event.content);

this.room.user.say('bob', '@hubot check status').then(() => {
expect(response.text).to.eql("It's all good!");
room.user.say('bob', '@hubot check status').then(() => {
expect(response.text).to.eql("It's all good!");
});
});
});
});
```

Expand All @@ -231,7 +235,7 @@ describe('status check', function() {

### Setup

```
```shell
git clone https://github.com/mtsmfm/hubot-test-helper
cd hubot-test-helper
docker-compose up -d
Expand All @@ -241,19 +245,19 @@ yarn install

### Run test

```
```shell
yarn run test
```

#### Debug

```
```shell
yarn run test-unit-debug
```

Above command will output:

```
```shell
yarn run v0.18.1
$ mocha --inspect --debug-brk --compilers coffee:coffee-script/register test
Debugger listening on port 9229.
Expand Down
Loading