• Stars
    star
    115
  • Rank 305,916 (Top 7 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 10 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Helper for testing hubot script

Hubot test helper

Build Status

Helper for testing Hubot script.

Install

npm install hubot-test-helper --save-dev

Usage

If you have a following hubot script:

module.exports = robot =>
  robot.respond(/hi$/i, msg => msg.reply('hi'))

You can test it like:

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));
    });

    it('should reply to user', function() {
      expect(this.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 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).

See the tests for an example of testing the HTTP server.

Manual delay

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:

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:

const Helper = require('hubot-test-helper');
const helper = new Helper('../scripts/http.js');

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

// 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));
    });

    // 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']
      ]);
    });
  });
});

Note that yield and generators are part of ECMA6, 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:

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:

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));
    });

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

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

Testing events

You can also test events emitted by your script. For example, Slack users may want to test the creation of a message attachment.

Given the following script:

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:

const Helper = require('hubot-test-helper');
const helper = new Helper('../scripts/status_check.js');

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

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

  it('should send a slack event', function() {
    let response = null;
    this.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!");
    });
  });
});

Development

Requirements

  • docker
  • docker-compose

Setup

git clone https://github.com/mtsmfm/hubot-test-helper
cd hubot-test-helper
docker-compose up -d
docker-compose exec app bash
yarn install

Run test

yarn run test

Debug

yarn run test-unit-debug

Above command will output:

yarn run v0.18.1
$ mocha --inspect --debug-brk --compilers coffee:coffee-script/register test
Debugger listening on port 9229.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
    chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/59631086-0a0c-424b-8f5b-8828be123894

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.

More Repositories

1

language_server-ruby

A Ruby Language Server implementation
Ruby
257
star
2

yaichi

Yaichi is a reverse proxy for developers using Docker on development environment.
Ruby
63
star
3

split-test

Splits test files into multiple groups to run tests in parallel nodes
Rust
55
star
4

language_server-protocol-ruby

A Language Server Protocol SDK for Ruby
Ruby
47
star
5

pip-any-site

Picture-in-Picture any site
TypeScript
23
star
6

vanir

Vanir is a database masking tool.
Go
23
star
7

vscode-ruby-lsc

ruby-lsc is a vscode extension to develop ruby application.
TypeScript
14
star
8

graphql-codegen-swift-operations

graphql-codegen Swift plugin for GraphQL operations.
Swift
14
star
9

danger-regexp

Ruby
11
star
10

gh-deck

Ruby
10
star
11

unite-turnip

A unite.vim's source to list your turnip step definitions
Ruby
8
star
12

has-it-failed

Ruby
8
star
13

docker-rails-dev-box

A docker environment for Ruby on Rails core development
Dockerfile
7
star
14

rails-system-test-example

Ruby
7
star
15

dotfiles

dotfiles
Shell
5
star
16

activerecord-aws_data_service_mysql-adapter

An Aurora Serverless ActiveRecord adapter
Ruby
5
star
17

tegaki-jan

Handwriting mahjong font
Ruby
5
star
18

action_dispatch-http-content_disposition

Backport https://github.com/rails/rails/pull/33829 to old Rails
Ruby
5
star
19

embulk-input-travis

Embulk plugin for Travis input
Ruby
4
star
20

node-idobata-client

CoffeeScript
4
star
21

react-masonry

TypeScript
4
star
22

janjan

Ruby
4
star
23

fluent-plugin-google-sheets

Fluentd output plugin to store data on Google Sheets
Ruby
4
star
24

vscode-k8s-quick-attach

TypeScript
4
star
25

annotate_routes

Annotate routes information to your controllers
Ruby
4
star
26

sqlcodegen

Generate Go structs from SQL string literals
Go
4
star
27

contextful_rewriter

Ruby
4
star
28

looks-trombone-to-me

JavaScript
3
star
29

vscode-stl-viewer

TypeScript
3
star
30

docker-wine

Dockerfile
3
star
31

fragile-window

Ruby
3
star
32

devimages

A collection of docker images for development env.
Dockerfile
2
star
33

resque-scheduler-example

Ruby
2
star
34

idobata-graphql-electron-example

JavaScript
2
star
35

circleci-hang-up-with-psql

2
star
36

vim-cursorline-boost

Vim Script
1
star
37

atom-docker-linter

JavaScript
1
star
38

doukaku

Ruby
1
star
39

tumblr_photo_notify

Chrome Extension for Tumblr to watch photoes absently using notification
CoffeeScript
1
star
40

BrowserStackLocal

1
star
41

cuke-kai-romantable

1
star
42

generator-electron

JavaScript
1
star
43

draft-run

Makefile
1
star
44

vscode-jscad-preview

TypeScript
1
star
45

docker-ruby-awscli

1
star
46

mtsmfm-overlay

Shell
1
star
47

mtsmfm.github.io

Ruby
1
star
48

DefinitelyContainer

Dockerfile
1
star
49

parsec-instance-manager

Ruby
1
star
50

poke-party-maker

Ruby
1
star
51

lumia-walker

TypeScript
1
star
52

qwik2md

Convert qwik format document to markdown
Ruby
1
star
53

rails-ci-result-importer

Import https://travis-ci.org/rails/rails to BigQuery public dataset.
Ruby
1
star
54

swagger2hyperschema

Ruby
1
star
55

bslocal-https-non-443-issue

TypeScript
1
star
56

wox-plugin-ghq

Wox plugin for ghq
C#
1
star
57

unofficial_buildkite_client

Unofficial Buildkite API client
Ruby
1
star
58

s3-presigned-url-example

TypeScript
1
star