# Pastebin eRspClC6 diff --git a/lib/gitter-adapter.js b/lib/gitter-adapter.js --- a/lib/gitter-adapter.js +++ b/lib/gitter-adapter.js @@ -30,6 +30,9 @@ function obfuscateToken(token) { return repeat('*', token.length - 8) + token.slice(token.length - 8); } +function nickToMask(nick) { + return ':' + nick + '!' + nick + '@irc.gitter.im'; +} var cacheDelegate = new LruCacheDelegate({ max: 2048, @@ -82,7 +85,7 @@ Adapter.prototype.listenForOneToOnes = f .then(function(room) { if (!room.oneToOne) return; var nick = room.user.username; - var mask = ':' + nick + '!' + nick + '@irc.gitter.im'; + var mask = nickToMask(nick); msg.text.split('\n').forEach(function(line) { c.send(mask, 'PRIVMSG', c.nick, ':' + line); }); @@ -168,12 +171,37 @@ Adapter.prototype.setup = function(token }.bind(this)); }; +Adapter.prototype.getOurRoom = function getOurRoom(room) { + var uri = room.uri.toLowerCase(); + if (!this.rooms[uri]) + this.rooms[uri] = room; + return this.rooms[uri]; +}; + Adapter.prototype.subscribeToRoom = function(room) { var self = this; var c = this.client; debug('Subscribing to room ' + room.uri, { token: this.loggableToken}); + var ourroom = this.getOurRoom(room); + ourroom._users = {}; + ourroom.hasUser = function hasUser(nick) { + ourroom._users[nick] = true; + } + ourroom.addUser = function addUser(nick) { + if (nick in ourroom._users) + return; + this.hasUser(nick); + c.send(nickToMask(nick), 'JOIN', '#' + room.uri); + } + ourroom.delUser = function delUser(nick) { + if (nick in ourroom._users) { + delete ourroom._users[nick]; + c.send(nickToMask(nick), 'PART', '#' + room.uri); + } + } + room.subscribe(); room.on('chatMessages', function(evt) { @@ -183,7 +211,9 @@ Adapter.prototype.subscribeToRoom = func var nick = message.fromUser.username; if (nick === c.nick) return; // User's own message - var mask = ':' + nick + '!' + nick + '@irc.gitter.im'; + var ourroom = this.getOurRoom(room); + ourroom.addUser(nick); + var mask = nickToMask(nick); var text; message.text.split('\n').forEach(function(line) { @@ -212,13 +242,11 @@ Adapter.prototype.subscribeToRoom = func var nick, mask; if (evt.operation === 'create') { nick = evt.model.username; - mask = ':' + nick + '!' + nick + '@irc.gitter.im'; - c.send(mask, 'JOIN', '#' + room.uri); + room.addUser(nick); } if (evt.operation === 'remove') { nick = evt.model.username; - mask = ':' + nick + '!' + nick + '@irc.gitter.im'; - c.send(mask, 'PART', '#' + room.uri); + room.delUser(nick); } }.bind(this)); @@ -348,7 +376,9 @@ Adapter.prototype.listUsers = function(c }.bind(this)); getRoomMembers.then(function(users) { + var room = this.rooms[uri]; (users || []).forEach(function(user) { + room.hasUser(user.username); c.send(c.host, irc.reply.who, c.nick, channel, user.username, c.hostname, c.hostname, user.username, 'H', ':0', user.displayName); }); c.send(c.host, irc.reply.who, c.nick, channel, 'gitter', c.hostname, c.hostname, 'gitter', 'H', ':0', 'Gitter Bot'); diff --git a/test/gitter-adapter_test.js b/test/gitter-adapter_test.js --- a/test/gitter-adapter_test.js +++ b/test/gitter-adapter_test.js @@ -59,4 +59,68 @@ describe('Gitter Adapter', function(){ return adapter.sendPromiseChain; }); + it('Should report users for who', function() { + client.authenticated = true; + client.nick = 'bar'; // obtained after auth + var spy = sinon.spy(); + var stub = sinon.stub(socket, 'write', spy); + adapter.sendMessage = spy; + adapter.setup("fake-token"); + var eventMap = {}; + adapter.subscribeToRoom({ + 'uri':'hello', + 'id':'hello-room', + subscribe:function(){}, + on:function(event, cb) { + eventMap[event] = cb; + } + }); + client.parse('WHO hello'); + eventMap['users']({ + 'operation': 'create', + 'model': { + 'username': 'test' + } + }); + adapter.sendPromiseChain = adapter.sendPromiseChain.then(function() { + assert(spy.firstCall.calledWith(':bar!bar@irc.gitter.im WHO :hello\r\n')); + assert(spy.secondCall.calledWith(':test!test@irc.gitter.im JOIN #hello\r\n')); + assert(spy.calledTwice); + }); + return adapter.sendPromiseChain; + }); + + it('Should report users for messages', function() { + client.authenticated = true; + client.nick = 'bar'; // obtained after auth + var spy = sinon.spy(); + var stub = sinon.stub(socket, 'write', spy); + adapter.sendMessage = spy; + adapter.setup("fake-token"); + var eventMap = {}; + adapter.subscribeToRoom({ + 'uri':'hello', + 'id':'hello-room', + subscribe:function(){}, + on:function(event, cb) { + eventMap[event] = cb; + } + }); + eventMap['chatMessages']({ + 'operation': 'create', + 'model': { + 'fromUser': { + 'username': 'test' + }, + 'text': 'hello', + 'id': 1000, + }, + }); + adapter.sendPromiseChain = adapter.sendPromiseChain.then(function() { + assert(spy.firstCall.calledWith(':test!test@irc.gitter.im JOIN #hello\r\n')); + assert(spy.secondCall.calledWith(':test!test@irc.gitter.im PRIVMSG #hello :hello\r\n')); + assert(spy.calledTwice); + }); + return adapter.sendPromiseChain; + }); });