Skip to content

Commit

Permalink
Make Robot self-sustaining
Browse files Browse the repository at this point in the history
Instead of passing in the webhook handler, this adds an EventEmitter on Robot so it can do its own event handling.
  • Loading branch information
bkeepers committed Jun 30, 2017
1 parent aa3146b commit 0e38027
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 24 deletions.
8 changes: 7 additions & 1 deletion index.js
Expand Up @@ -33,6 +33,12 @@ module.exports = (options = {}) => {
const server = createServer(webhook);
const robot = createRobot({app, webhook, cache, logger});

// Forward webhooks to robot
webhook.on('*', event => {
this.log.trace(event, 'webhook received');
robot.receive(event);
});

// Log all webhook errors
webhook.on('error', logger.error.bind(logger));

Expand Down Expand Up @@ -63,7 +69,7 @@ module.exports = (options = {}) => {
},

receive(event) {
return webhook.emit(event.event, event);
return robot.receive(event);
}
};
};
11 changes: 7 additions & 4 deletions lib/robot.js
@@ -1,3 +1,4 @@
const {EventEmitter} = require('events');
const GitHubApi = require('github');
const Bottleneck = require('bottleneck');
const Context = require('./context');
Expand All @@ -8,13 +9,15 @@ const Context = require('./context');
* @property {logger} log - A logger
*/
class Robot {
constructor({app, webhook, cache, logger}) {
constructor({app, cache, logger}) {
this.events = new EventEmitter();
this.app = app;
this.webhook = webhook;
this.cache = cache;
this.log = wrapLogger(logger);
}

this.webhook.on('*', event => this.log.trace(event, 'webhook received'));
receive(event) {
return this.events.emit(event.event, event);
}

/**
Expand Down Expand Up @@ -53,7 +56,7 @@ class Robot {

const [name, action] = event.split('.');

return this.webhook.on(name, async event => {
return this.events.on(name, async event => {
if (!action || action === event.payload.action) {
try {
const github = await this.auth(event.payload.installation.id);
Expand Down
32 changes: 13 additions & 19 deletions test/robot.js
Expand Up @@ -3,29 +3,16 @@ const Context = require('../lib/context');
const createRobot = require('../lib/robot');

describe('Robot', function () {
let webhook;
let robot;
let event;
let callbacks;
let spy;

beforeEach(function () {
callbacks = {};
webhook = {
on: (name, callback) => {
callbacks[name] = callback;
},
emit: (name, event) => {
if (callbacks[name]) {
return callbacks[name](event);
}
}
};

robot = createRobot({webhook});
robot = createRobot({});
robot.auth = () => {};

event = {
event: 'test',
payload: {
action: 'foo',
installation: {id: 1}
Expand All @@ -40,7 +27,7 @@ describe('Robot', function () {
robot.on('test', spy);

expect(spy).toNotHaveBeenCalled();
await webhook.emit('test', event);
await robot.receive(event);
expect(spy).toHaveBeenCalled();
expect(spy.calls[0].arguments[0]).toBeA(Context);
expect(spy.calls[0].arguments[0].payload).toBe(event.payload);
Expand All @@ -49,14 +36,21 @@ describe('Robot', function () {
it('calls callback with same action', async function () {
robot.on('test.foo', spy);

await webhook.emit('test', event);
await robot.receive(event);
expect(spy).toHaveBeenCalled();
});

it('does not call callback with different action', async function () {
robot.on('test.nope', spy);

await webhook.emit('test', event);
await robot.receive(event);
expect(spy).toNotHaveBeenCalled();
});

it('calls callback with *', async function () {
robot.on('*', spy);

await robot.receive(event);
expect(spy).toNotHaveBeenCalled();
});
});
Expand All @@ -70,7 +64,7 @@ describe('Robot', function () {
throw error;
});

await webhook.emit('test', event);
await robot.receive(event);

expect(robot.log.error).toHaveBeenCalledWith(error);
});
Expand Down

0 comments on commit 0e38027

Please sign in to comment.