From 66c40db49addbd91ba5844bda0ab41b9a4efad6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20M=C3=A9taireau?= Date: Tue, 11 Feb 2014 15:21:50 +0100 Subject: [PATCH] Add an event routing mechanism. This is done in order to simplify how messages are sent and routed trough the application. `eventrouter.js` contains all the routing information, and the consumers should send the messages to the router instead of the ports. Something like this:: this.router = new EventRouter("SidebarApp", this.appPort, this); this.router.send("message"); The router object takes a reference to the routed object in order to call its methods directly (rather than having to listen to events from within the object). --- static/chat.html | 1 + static/js/eventrouter.js | 94 +++++++++++++++++ static/js/worker.js | 95 +++++++++-------- static/sidebar.html | 1 + test/frontend/eventrouter_test.js | 108 ++++++++++++++++++++ test/frontend/index.html | 2 + test/frontend/worker/handlers_test.js | 4 +- test/frontend/worker/index.html | 1 + test/frontend/worker/portcollection_test.js | 8 +- test/frontend/worker/spa_events_test.js | 57 +++++------ test/frontend/worker/tkworker_test.js | 28 ++--- test/frontend/worker/userdata_test.js | 31 +++--- 12 files changed, 321 insertions(+), 109 deletions(-) create mode 100644 static/js/eventrouter.js create mode 100644 test/frontend/eventrouter_test.js diff --git a/static/chat.html b/static/chat.html index 1bebc06e..f8e0a721 100644 --- a/static/chat.html +++ b/static/chat.html @@ -122,6 +122,7 @@

<%= filename %>

+ diff --git a/static/js/eventrouter.js b/static/js/eventrouter.js new file mode 100644 index 00000000..d10696dc --- /dev/null +++ b/static/js/eventrouter.js @@ -0,0 +1,94 @@ +/* jshint unused:false, maxlen: 200 */ + +/** + * The general event router. + * + * All the events that are passed by an app port (worker to subworker, + * application to worker, etc.) sould be routed with this event router. + */ + +var EventRouter = (function() { + "use strict"; + + var DEFAULT_ROUTES = [ + // Worker → SidebarApp + {from: "Worker", topic: "social.user-profile", to: "SidebarApp"}, + {from: "Worker", topic: "talkilla.worker-ready", to: "SidebarApp"}, + {from: "Worker", topic: "talkilla.spa-connected", to: "SidebarApp"}, + {from: "Worker", topic: "talkilla.users", to: "SidebarApp", callable: "userListReceived"}, + {from: "Worker", topic: "talkilla.error", to: "SidebarApp"}, + {from: "Worker", topic: "talkilla.server-reconnection", to: "SidebarApp"}, + {from: "Worker", topic: "talkilla.reauth-needed", to: "SidebarApp"}, + + // Worker → ChatApp + {from: "Worker", topic: "talkilla.user-joined", to: "ChatApp"}, + {from: "Worker", topic: "talkilla.user-left", to: "ChatApp"}, + {from: "Worker", topic: "talkilla.move-accept", to: "ChatApp"}, + ]; + + + /** + * Route the events to the appropriate context, using appPorts. + * + * @param {String} name Name of the context. To be matched with the + * ones in the from/to/via of the routes. + * @param {Object} context Object the router is routing for. + * @param {AppPort} appPort AppPort to send and receive message from/to. + * @param {List} routes List of routes + */ + function EventRouter(name, context, appPort, routes) { + this.routes = routes || DEFAULT_ROUTES; + this.name = name; + this.appPort = appPort; + this.context = context; + + // Starts to listen to the appPort. + appPort.onmessage = function(topic, event) { + event.topic = topic; + this._onMessage(event); + }.bind(this); + } + + /** + * Route a message to the appropriate context. + * + * @param {String} topic Topic of the event. + * @param {Object} data The data to send trough. + */ + EventRouter.prototype.send = function(topic, data) { + // XXX Serialize data. + var route = this._findRoute(topic); + this.appPort.postMessage({ + "from": this.name, + "to": route.to, + "topic": topic, + "callable": route.callable, + "data": data + }); + }; + + EventRouter.prototype._onMessage = function(routeEvent){ + if (routeEvent.to === this.name) { + // XXX Deserialize data. + this.context[routeEvent.callable](routeEvent.data); + } else if (routeEvent.via === this.name) { + // Relay the message to the real destination in case we are a proxy. + routeEvent.from = this.name; + this.appPort.postMessage(routeEvent); + } + }; + + EventRouter.prototype._findRoute = function(topic) { + var route = this.routes.filter(function(route) { + return route.topic === topic; + }).shift(); + + if (!route){ + throw "Event route not found for topic " + topic; + } + return route; + }; + + return EventRouter; +})(); + diff --git a/static/js/worker.js b/static/js/worker.js index 20d0d608..9ae077ef 100644 --- a/static/js/worker.js +++ b/static/js/worker.js @@ -1,5 +1,6 @@ /* global indexedDB, importScripts, SPA, HTTP, ContactsDB, SPADB, - CurrentUsers, loadConfig, payloads, Conversation, dump, ConversationList */ + CurrentUsers, loadConfig, payloads, Conversation, dump, ConversationList, + EventRouter */ /* jshint unused:false */ "use strict"; @@ -15,7 +16,8 @@ importScripts( 'worker/users.js', 'worker/spa.js', 'worker/conversation.js', - 'worker/conversationList.js' + 'worker/conversationList.js', + 'eventrouter.js' ); var gConfig = loadConfig(); @@ -121,13 +123,13 @@ UserData.prototype = { // This needs to be sent to the browser for Firefox 28 and earlier // (pre bug 935640). - browserPort.postEvent('social.user-profile', userData); + browserPort.postMessage('social.user-profile', userData); // XXX This could be simplified to just send the userName (and renamed). - tkWorker.ports.broadcastEvent('social.user-profile', userData); + tkWorker.router.send('social.user-profile', userData); // This is needed for Firefox 29 onwards (post bug 935640). - browserPort.postEvent('social.ambient-notification', { + browserPort.postMessage('social.ambient-notification', { iconURL: iconURL }); } @@ -149,7 +151,7 @@ function _setupSPA(spa) { // but we don't have enough info for the worker for that yet tkWorker.loadContacts(); - tkWorker.ports.broadcastEvent("talkilla.spa-connected", + tkWorker.router.send("talkilla.spa-connected", {"capabilities": data.capabilities}); }); @@ -165,15 +167,15 @@ function _setupSPA(spa) { tkWorker.spa.usernameFieldType); }); - tkWorker.ports.broadcastEvent("talkilla.users", tkWorker.users.toArray()); + tkWorker.router.send("talkilla.users", tkWorker.users.toArray()); }); spa.on("userJoined", function(userId) { tkWorker.users.set(userId, {presence: "connected"}, tkWorker.spa.usernameFieldType); - tkWorker.ports.broadcastEvent("talkilla.users", tkWorker.users.toArray()); - tkWorker.ports.broadcastEvent("talkilla.user-joined", userId); + tkWorker.router.send("talkilla.users", tkWorker.users.toArray()); + tkWorker.router.send("talkilla.user-joined", userId); }); spa.on("userLeft", function(userId) { @@ -183,8 +185,8 @@ function _setupSPA(spa) { tkWorker.users.set(userId, {presence: "disconnected"}, tkWorker.spa.usernameFieldType); - tkWorker.ports.broadcastEvent("talkilla.users", tkWorker.users.toArray()); - tkWorker.ports.broadcastEvent("talkilla.user-left", userId); + tkWorker.router.send("talkilla.users", tkWorker.users.toArray()); + tkWorker.router.send("talkilla.user-left", userId); }); spa.on("offer", function(offerMsg) { @@ -214,21 +216,21 @@ function _setupSPA(spa) { }); spa.on("move-accept", function(moveAcceptMsg) { - tkWorker.ports.broadcastEvent("talkilla.move-accept", + tkWorker.router.send("talkilla.move-accept", moveAcceptMsg); }); spa.on("error", function(event) { - tkWorker.ports.broadcastEvent("talkilla.error", event); + tkWorker.router.send("talkilla.error", event); }); spa.on("reconnection", function(reconnectionMsg) { - tkWorker.ports.broadcastEvent('talkilla.server-reconnection', + tkWorker.router.send('talkilla.server-reconnection', reconnectionMsg); }); spa.on("reauth-needed", function(event) { - tkWorker.ports.broadcastEvent('talkilla.reauth-needed'); + tkWorker.router.send('talkilla.reauth-needed'); tkWorker.closeSession(); }); @@ -241,7 +243,7 @@ function _setupSPA(spa) { var handlers = { // SocialAPI events 'social.port-closing': function() { - // broadcastDebug won't work here, because the port is dead, so we + // debug won't work here, because the port is dead, so we // use dump dump("social.port-closing called; about to remove port. this = " + this); tkWorker.ports.remove(this); @@ -263,7 +265,7 @@ var handlers = { // Talkilla events 'talkilla.contacts': function(event) { - tkWorker.ports.broadcastDebug('talkilla.contacts', event.data.contacts); + // XXX REFACTOR tkWorker.router.debug('talkilla.contacts', event.data.contacts); tkWorker.updateContactsFromSource(event.data.contacts, event.data.source); }, @@ -348,7 +350,8 @@ var handlers = { tkWorker.spaDb.store(spec, function(err) { if (err) - return tkWorker.ports.broadcastError("Error adding SPA", err); + dump("error adding spa" + err); + // XXX Refactor return tkWorker.router.broadcastError("Error adding SPA", err); // Try starting the SPA even if there's an error adding it - at least // the user can possibly get into it. @@ -395,7 +398,7 @@ Port.prototype = { * @param {String} error */ error: function(error) { - this.postEvent("talkilla.error", error); + this.postMessage("talkilla.error", error); }, /** @@ -415,13 +418,16 @@ Port.prototype = { * @param {String} topic * @param {Mixed} data */ - postEvent: function(topic, data) { + postMessage: function(topic, data) { // FIXME: for no obvious reason, this may eventually fail if the port is // closed, while it should never be the case this.port.postMessage({topic: topic, data: data}); } }; +/** + * Mimics the ports API but broadcast messages to a collection of ports. + **/ function PortCollection() { this.ports = {}; } @@ -467,28 +473,27 @@ PortCollection.prototype = { * @param {String} topic * @param {Mixed} data */ - broadcastEvent: function(topic, data) { + postMessage: function(topic, data) { for (var id in this.ports) - this.ports[id].postEvent(topic, data); + this.ports[id].postMessage(topic, data); }, /** * Broadcast debug informations to all ports. */ - broadcastDebug: function(label, data) { + debug: function(label, data) { if (!gConfig.DEBUG) return; - for (var id in this.ports) - this.ports[id].postEvent("talkilla.debug", {label: label, data: data}); + this.postMessage("talkilla.debug", {label: label, data: data}); }, - /** - * Broadcasts an error message to all ports. - * @param {String} message - */ - broadcastError: function(message) { + error: function(message) { + this.postMessage("talkilla.error", message); + }, + + onmessage: function(cb) { for (var id in this.ports) - this.ports[id].error(message); + this.ports[id].onmessage(cb); } }; @@ -515,6 +520,7 @@ function TkWorker(options) { this.user = options.user || new UserData({}, gConfig); this.users = options.users || new CurrentUsers(); this.ports = options.ports; + this.router = new EventRouter("Worker", this, this.ports); this.initialized = false; // XXX In future, this may switch to supporting multiple SPAs this.spa = undefined; @@ -537,7 +543,9 @@ TkWorker.prototype = { // Now we're set up load the spa info this.loadSPAs(function(err) { if (err) - tkWorker.ports.broadcastError("Error loading spa specs"); + dump("Error loading spa specs"); + // XXX Refactor tkWorker.router.broadcastError("Error loading spa specs"); + // Even if there were errors, assume initialization is complete // so that we can continue to function. @@ -557,21 +565,21 @@ TkWorker.prototype = { onInitializationComplete: function(port) { // Post to the port if specified, else to all ports. if (port) - port.postEvent('talkilla.worker-ready'); + port.postMessage('talkilla.worker-ready'); else - this.ports.broadcastEvent('talkilla.worker-ready'); + this.router.send('talkilla.worker-ready'); if (this.spa && this.spa.connected) { this.user.send(); if (port) { - port.postEvent("talkilla.spa-connected", + port.postMessage("talkilla.spa-connected", {capabilities: this.spa.capabilities}); - port.postEvent('talkilla.users', this.users.toArray()); + port.postMessage('talkilla.users', this.users.toArray()); } else { - this.ports.broadcastEvent("talkilla.spa-connected", + this.router.send("talkilla.spa-connected", {capabilities: this.spa.capabilities}); - this.ports.broadcastEvent('talkilla.users', this.users.toArray()); + this.router.send('talkilla.users', this.users.toArray()); } } }, @@ -596,7 +604,8 @@ TkWorker.prototype = { loadContacts: function(cb) { this.contactsDb.all(function(err, contacts) { if (err) { - this.ports.broadcastError(err); + // XXX Refactor this.router.broadcastError(err); + dump(err); if (typeof cb === "function") return cb.call(this, err); return; @@ -624,7 +633,7 @@ TkWorker.prototype = { this.contactsDb.add(contact, function(err) { if (err) - tkWorker.ports.broadcastError(err); + tkWorker.router.broadcastError(err); callback(err); }); @@ -644,7 +653,7 @@ TkWorker.prototype = { */ updateContactList: function(contacts) { this.users.updateContacts(contacts, this.spa.usernameFieldType); - this.ports.broadcastEvent("talkilla.users", this.users.toArray()); + this.router.send("talkilla.users", this.users.toArray()); }, /** @@ -673,8 +682,8 @@ TkWorker.prototype = { */ loadSPAs: function(callback) { this.spaDb.all(function(err, specs) { - tkWorker.ports.broadcastDebug("loaded specs", specs); - + // XXX Refactor tkWorker.router.broadcastDebug("loaded specs", specs); + dump("loaded specs" + specs); if (err) { if (callback) callback(err); diff --git a/static/sidebar.html b/static/sidebar.html index f35600c0..961acbb7 100644 --- a/static/sidebar.html +++ b/static/sidebar.html @@ -86,6 +86,7 @@ + diff --git a/test/frontend/eventrouter_test.js b/test/frontend/eventrouter_test.js new file mode 100644 index 00000000..38788a2e --- /dev/null +++ b/test/frontend/eventrouter_test.js @@ -0,0 +1,108 @@ +/*global chai, sinon, EventRouter */ +"use strict"; + +var expect = chai.expect; + +describe("EventRouter", function() { + var sandbox, obj, appPort; + + beforeEach(function() { + sandbox = sinon.sandbox.create(); + obj = {}; + appPort = { + 'postMessage': sandbox.spy(), + }; + }); + + afterEach(function() { + sandbox.restore(); + }); + + describe("Initialisation", function() { + it("Should default to globally defined routes if none is passed", + function() { + + var router = new EventRouter("Alice", obj, appPort); + expect(router.routes).to.exist; + }); + + it("Should use the given routes object if one is given", function() { + var sentinel = "this is a test"; + var router = new EventRouter("Alice", obj, appPort, sentinel); + expect(router.routes).to.equal(sentinel); + }); + + it("Should listen to events from the appPort", function() { + var onMessage = sandbox.stub(EventRouter.prototype, "_onMessage"); + new EventRouter("Alice", obj, appPort); + + var data = { + from: "Alice", + to: "Bob", + callable: "feedMe" + }; + + appPort.onmessage("feedMe", data); + sinon.assert.calledOnce(onMessage); + + // The onMessage method should be called with the topic set. + data.topic = "feedMe"; + sinon.assert.calledWithExactly(onMessage, data); + }); + + }); + + describe("appPort events", function() { + it("Should trigger the right function of the context if it exists", + function() { + var routes = [{ + from: "Alice", + topic: "feedme", + to: "Bob", + callable: "feedMe" + }]; + obj.feedMe = sandbox.spy(); + + new EventRouter("Bob", obj, appPort, routes); + appPort.onmessage("feedMe", { + from: "Alice", + to: "Bob", + callable: "feedMe", + data: "sandwich" + }); + + sinon.assert.calledOnce(obj.feedMe); + sinon.assert.calledWithExactly(obj.feedMe, "sandwich"); + }); + + it("Should proxy events when in the 'via' property", function() { + + }); + }); + + describe("#send", function() { + it("Should call appPort with the proper route", function() { + var routes = [{ + from: "Alice", + topic: "feedme", + to: "Bob", + callable: "feedMe" + }]; + var router = new EventRouter("Alice", obj, appPort, routes); + router.send("feedme", "sandwich"); + sinon.assert.calledOnce(appPort.postMessage); + + var route = routes[0]; + route.data = "sandwich"; + sinon.assert.calledWithExactly(appPort.postMessage, route); + }); + + it("Should error-out when no route exists for the given event", function() { + var router = new EventRouter("Alice", obj, appPort, []); + expect(function() { + // This route doesn't exist. + router.send("feedme", "sandwich"); + }).to.throw("route not found"); + }); + }); +}); diff --git a/test/frontend/index.html b/test/frontend/index.html index 62cc4fe7..d3ec4e43 100644 --- a/test/frontend/index.html +++ b/test/frontend/index.html @@ -26,6 +26,7 @@ + @@ -39,6 +40,7 @@ + diff --git a/test/frontend/worker/handlers_test.js b/test/frontend/worker/handlers_test.js index 4d98e760..01da53b6 100644 --- a/test/frontend/worker/handlers_test.js +++ b/test/frontend/worker/handlers_test.js @@ -17,7 +17,7 @@ describe('handlers', function() { sandbox.stub(window, "Server"); sandbox.stub(window, "Worker").returns({postMessage: sinon.spy()}); tkWorker.spa = new SPA({src: "example.com"}); - browserPort = {postEvent: sandbox.spy()}; + browserPort = {postMessage: sandbox.spy()}; }); afterEach(function() { @@ -119,7 +119,7 @@ describe('handlers', function() { describe("talkilla.chat-window-ready", function() { it("should pass the event to the conversationList", function () { - var chatAppPort = {postEvent: sinon.spy()}; + var chatAppPort = {postMessage: sinon.spy()}; sandbox.stub(tkWorker.conversationList, "windowReady"); handlers['talkilla.chat-window-ready'].bind(chatAppPort)(); diff --git a/test/frontend/worker/index.html b/test/frontend/worker/index.html index 4e0b75a8..40dd1046 100644 --- a/test/frontend/worker/index.html +++ b/test/frontend/worker/index.html @@ -29,6 +29,7 @@ + diff --git a/test/frontend/worker/portcollection_test.js b/test/frontend/worker/portcollection_test.js index 5b58cc85..a2413290 100644 --- a/test/frontend/worker/portcollection_test.js +++ b/test/frontend/worker/portcollection_test.js @@ -14,7 +14,7 @@ describe('Port', function() { it("should post a message", function() { var spy = sinon.spy(); var port = new Port({_portid: 1, postMessage: spy}); - port.postEvent('foo', 'bar'); + port.postMessage('foo', 'bar'); expect(spy.calledWith({topic: 'foo', data: 'bar'})).to.be.ok; }); @@ -74,7 +74,7 @@ describe('PortCollection', function() { var spy2 = sinon.spy(); coll.add(new Port({_portid: 1, postMessage: spy1})); coll.add(new Port({_portid: 2, postMessage: spy2})); - coll.find(2).postEvent('foo', 'bar'); + coll.find(2).postMessage('foo', 'bar'); expect(spy1.called).to.equal(false); expect(spy2.calledWith({topic: 'foo', data: 'bar'})).to.be.ok; }); @@ -85,7 +85,7 @@ describe('PortCollection', function() { var spy2 = sinon.spy(); coll.add(new Port({_portid: 1, postMessage: spy1})); coll.add(new Port({_portid: 2, postMessage: spy2})); - coll.broadcastEvent('foo', 'bar'); + coll.postMessage('foo', 'bar'); expect(spy1.calledWith({topic: 'foo', data: 'bar'})).to.be.ok; expect(spy2.calledWith({topic: 'foo', data: 'bar'})).to.be.ok; }); @@ -96,7 +96,7 @@ describe('PortCollection', function() { var spy2 = sinon.spy(); coll.add(new Port({_portid: 1, postMessage: spy1})); coll.add(new Port({_portid: 2, postMessage: spy2})); - coll.broadcastError('error'); + coll.error('error'); expect(spy1.calledWith({topic: 'talkilla.error', data: 'error'})).to.be.ok; expect(spy2.calledWith({topic: 'talkilla.error', diff --git a/test/frontend/worker/spa_events_test.js b/test/frontend/worker/spa_events_test.js index 87dd14ce..e79a2f6e 100644 --- a/test/frontend/worker/spa_events_test.js +++ b/test/frontend/worker/spa_events_test.js @@ -39,14 +39,13 @@ describe("SPA events", function() { }); it("should broadcast a `talkilla.spa-connected` event", function() { - sandbox.stub(tkWorker.ports, "broadcastEvent"); + sandbox.stub(tkWorker.router, "send"); tkWorker.spa.trigger("connected", data); - sinon.assert.calledOnce(tkWorker.ports.broadcastEvent); - sinon.assert.calledWithExactly(tkWorker.ports.broadcastEvent, - "talkilla.spa-connected", - {capabilities: data.capabilities}); + sinon.assert.calledOnce(tkWorker.router.send); + sinon.assert.calledWithExactly(tkWorker.router.send, + "talkilla.spa-connected", {capabilities: data.capabilities}); }); it("should load the contacts database", function() { @@ -93,7 +92,7 @@ describe("SPA events", function() { describe("`users` event", function() { beforeEach(function() { - sandbox.stub(tkWorker.ports, "broadcastEvent"); + sandbox.stub(tkWorker.router, "send"); }); afterEach(function() { @@ -119,9 +118,9 @@ describe("SPA events", function() { function() { tkWorker.spa.trigger("users", [{nick: "jb"}]); - sinon.assert.calledOnce(tkWorker.ports.broadcastEvent); + sinon.assert.calledOnce(tkWorker.router.send); sinon.assert.calledWith( - tkWorker.ports.broadcastEvent, "talkilla.users", [ + tkWorker.router.send, "talkilla.users", [ { email: "jb", username: "jb", presence: "connected" } ]); }); @@ -132,24 +131,24 @@ describe("SPA events", function() { it("should broadcast a `talkilla.users` event", function() { tkWorker.users.reset(); - sandbox.stub(tkWorker.ports, "broadcastEvent"); + sandbox.stub(tkWorker.router, "send"); tkWorker.spa.trigger("userJoined", "foo"); - sinon.assert.called(tkWorker.ports.broadcastEvent); - sinon.assert.calledWith(tkWorker.ports.broadcastEvent, "talkilla.users", [ + sinon.assert.called(tkWorker.router.send); + sinon.assert.calledWith(tkWorker.router.send, "talkilla.users", [ {email: "foo", username: "foo", presence: "connected"} ]); }); it("should broadcast a `talkilla.user-joined` event", function() { tkWorker.users.reset(); - sandbox.stub(tkWorker.ports, "broadcastEvent"); + sandbox.stub(tkWorker.router, "send"); tkWorker.spa.trigger("userJoined", "foo"); - sinon.assert.called(tkWorker.ports.broadcastEvent); - sinon.assert.calledWith(tkWorker.ports.broadcastEvent, + sinon.assert.called(tkWorker.router.send); + sinon.assert.calledWith(tkWorker.router.send, "talkilla.user-joined", "foo"); }); @@ -157,7 +156,7 @@ describe("SPA events", function() { describe("`userLeft` event", function() { beforeEach(function () { - sandbox.stub(tkWorker.ports, "broadcastEvent"); + sandbox.stub(tkWorker.router, "send"); }); it("should not broadcast anything if the user is not in the " + @@ -165,7 +164,7 @@ describe("SPA events", function() { tkWorker.spa.trigger("userLeft", "foo"); - sinon.assert.notCalled(tkWorker.ports.broadcastEvent); + sinon.assert.notCalled(tkWorker.router.send); }); it("should broadcast a `talkilla.users` event", function() { @@ -173,8 +172,8 @@ describe("SPA events", function() { tkWorker.spa.trigger("userLeft", "foo"); - sinon.assert.called(tkWorker.ports.broadcastEvent); - sinon.assert.calledWith(tkWorker.ports.broadcastEvent, "talkilla.users", [ + sinon.assert.called(tkWorker.router.send); + sinon.assert.calledWith(tkWorker.router.send, "talkilla.users", [ {email: "foo", username: "foo", presence: "disconnected"} ]); }); @@ -184,8 +183,8 @@ describe("SPA events", function() { tkWorker.spa.trigger("userLeft", "foo"); - sinon.assert.called(tkWorker.ports.broadcastEvent); - sinon.assert.calledWith(tkWorker.ports.broadcastEvent, + sinon.assert.called(tkWorker.router.send); + sinon.assert.calledWith(tkWorker.router.send, "talkilla.user-left", "foo"); }); @@ -313,7 +312,7 @@ describe("SPA events", function() { describe("`move-accept` event", function() { it("should broadcast a `talkilla.move-accept` event", function() { - sandbox.stub(tkWorker.ports, "broadcastEvent"); + sandbox.stub(tkWorker.router, "send"); var moveAcceptMsg = new payloads.MoveAccept({ peer: "frank", callid: 42 @@ -321,8 +320,8 @@ describe("SPA events", function() { tkWorker.spa.trigger("move-accept", moveAcceptMsg); - sinon.assert.calledOnce(tkWorker.ports.broadcastEvent); - sinon.assert.calledWithExactly(tkWorker.ports.broadcastEvent, + sinon.assert.calledOnce(tkWorker.router.send); + sinon.assert.calledWithExactly(tkWorker.router.send, "talkilla.move-accept", moveAcceptMsg); }); @@ -336,13 +335,13 @@ describe("SPA events", function() { it("should broadcast a `talkilla.server-reconnection` event", function() { tkWorker.user.name = "harvey"; - sandbox.stub(tkWorker.ports, "broadcastEvent"); + sandbox.stub(tkWorker.router, "send"); tkWorker.spa.trigger("reconnection", {timeout: 42, attempt: 1}); - sinon.assert.calledOnce(tkWorker.ports.broadcastEvent); + sinon.assert.calledOnce(tkWorker.router.send); sinon.assert.calledWithExactly( - tkWorker.ports.broadcastEvent, "talkilla.server-reconnection", + tkWorker.router.send, "talkilla.server-reconnection", {timeout:42, attempt: 1} ); }); @@ -358,13 +357,13 @@ describe("SPA events", function() { describe("`reauth-needed event", function() { it("should foward the event to all ports", function() { - sandbox.stub(tkWorker.ports, "broadcastEvent"); + sandbox.stub(tkWorker.router, "send"); tkWorker.spa.trigger("reauth-needed"); - sinon.assert.calledOnce(tkWorker.ports.broadcastEvent); + sinon.assert.calledOnce(tkWorker.router.send); sinon.assert.calledWithExactly( - tkWorker.ports.broadcastEvent, "talkilla.reauth-needed"); + tkWorker.router.send, "talkilla.reauth-needed"); }); it("should close the current worker session", function() { diff --git a/test/frontend/worker/tkworker_test.js b/test/frontend/worker/tkworker_test.js index 285e8f8a..bb9265f3 100644 --- a/test/frontend/worker/tkworker_test.js +++ b/test/frontend/worker/tkworker_test.js @@ -9,7 +9,7 @@ describe("tkWorker", function() { beforeEach(function () { sandbox = sinon.sandbox.create(); - browserPort = {postEvent: sandbox.spy()}; + browserPort = {postMessage: sandbox.spy()}; worker = new TkWorker({ ports: new PortCollection(), user: new UserData({}, {}), @@ -61,7 +61,7 @@ describe("tkWorker", function() { describe("#onInitializationComplete", function() { beforeEach(function() { - sandbox.stub(worker.ports, "broadcastEvent"); + sandbox.stub(worker.router, "send"); sandbox.stub(worker, "loadSPAs", function(callback) { callback(); }); @@ -71,8 +71,8 @@ describe("tkWorker", function() { it("should send talkilla.worker-ready", function() { worker.initialize(); - sinon.assert.calledOnce(worker.ports.broadcastEvent); - sinon.assert.calledWithExactly(worker.ports.broadcastEvent, + sinon.assert.calledOnce(worker.router.send); + sinon.assert.calledWithExactly(worker.router.send, "talkilla.worker-ready" ); }); @@ -96,8 +96,8 @@ describe("tkWorker", function() { worker.initialize(); - sinon.assert.called(worker.ports.broadcastEvent); - sinon.assert.calledWithExactly(worker.ports.broadcastEvent, + sinon.assert.called(worker.router.send); + sinon.assert.calledWithExactly(worker.router.send, "talkilla.spa-connected", {capabilities: worker.spa.capabilities} ); @@ -110,8 +110,8 @@ describe("tkWorker", function() { worker.initialize(); - sinon.assert.called(worker.ports.broadcastEvent); - sinon.assert.calledWithExactly(worker.ports.broadcastEvent, + sinon.assert.called(worker.router.send); + sinon.assert.calledWithExactly(worker.router.send, "talkilla.users", fakeUsersList ); }); @@ -185,15 +185,15 @@ describe("tkWorker", function() { it("should broadcast an error message on failure", function() { var err = new Error("ko"); - sandbox.stub(worker.ports, "broadcastError"); + sandbox.stub(worker.router, "error"); sandbox.stub(worker.contactsDb, "all", function(cb) { cb(err); }); worker.loadContacts(); - sinon.assert.calledOnce(worker.ports.broadcastError); - sinon.assert.calledWithExactly(worker.ports.broadcastError, err); + sinon.assert.calledOnce(worker.router.error); + sinon.assert.calledWithExactly(worker.router.error, err); }); }); @@ -260,14 +260,14 @@ describe("tkWorker", function() { }); it("should broadcast a talkilla.users event", function() { - sandbox.stub(worker.ports, "broadcastEvent"); + sandbox.stub(worker.router, "send"); worker.updateContactList([{email: "foo"}, {email: "bar"}]); - sinon.assert.calledOnce(worker.ports.broadcastEvent); + sinon.assert.calledOnce(worker.router.send); // XXX email and username are effectively duplicates, waiting on // refactoring CurrentUsers. - sinon.assert.calledWith(worker.ports.broadcastEvent, "talkilla.users", [ + sinon.assert.calledWith(worker.router.send, "talkilla.users", [ {email: "foo", username: "foo", presence: "disconnected"}, {email: "bar", username: "bar", presence: "disconnected"} ]); diff --git a/test/frontend/worker/userdata_test.js b/test/frontend/worker/userdata_test.js index d105826d..19b98d63 100644 --- a/test/frontend/worker/userdata_test.js +++ b/test/frontend/worker/userdata_test.js @@ -8,7 +8,7 @@ describe('UserData', function() { beforeEach(function () { sandbox = sinon.sandbox.create(); - browserPort = {postEvent: sandbox.spy()}; + browserPort = {postMessage: sandbox.spy()}; }); afterEach(function () { @@ -111,7 +111,7 @@ describe('UserData', function() { var userData; beforeEach(function() { userData = new UserData({name: 'jb'}, {ROOTURL: "http://fake"}); - browserPort.postEvent.reset(); + browserPort.postMessage.reset(); }); afterEach(function() { @@ -120,9 +120,9 @@ describe('UserData', function() { it("should send a social.user-profile event to the browser", function () { userData.send(); - sinon.assert.called(browserPort.postEvent); + sinon.assert.called(browserPort.postMessage); - var data = browserPort.postEvent.args[0][1]; + var data = browserPort.postMessage.args[0][1]; expect(data.userName).to.be.equal('jb'); expect(data.displayName).to.be.equal('jb'); expect(data.portrait).to.be @@ -134,23 +134,20 @@ describe('UserData', function() { it("should broadcast social.user-profile event to the port collection", function () { var userNameMatcher = sinon.match({userName: "jb"}); - sandbox.stub(tkWorker.ports, "broadcastEvent"); + sandbox.stub(tkWorker.router, "send"); userData.send(); - sinon.assert.called(tkWorker.ports.broadcastEvent); - sinon.assert.calledWithExactly( - tkWorker.ports.broadcastEvent, - "social.user-profile", - userNameMatcher - ); + sinon.assert.called(tkWorker.router.send); + sinon.assert.calledWithExactly(tkWorker.router.send, + "social.user-profile", userNameMatcher); }); it("should send an online image url if connected", function() { // Connected automatically calls send() userData.connected = true; - sinon.assert.called(browserPort.postEvent); + sinon.assert.called(browserPort.postMessage); - var data = browserPort.postEvent.args[0][1]; + var data = browserPort.postMessage.args[0][1]; expect(data.iconURL).to.contain('online'); }); @@ -158,8 +155,8 @@ describe('UserData', function() { "url to the browser when disconnected", function() { userData.send(); - sinon.assert.called(browserPort.postEvent); - sinon.assert.calledWithExactly(browserPort.postEvent, + sinon.assert.called(browserPort.postMessage); + sinon.assert.calledWithExactly(browserPort.postMessage, "social.ambient-notification", { iconURL: "http://fake/img/talkilla16.png" } @@ -171,8 +168,8 @@ describe('UserData', function() { // Connected automatically calls send() userData.connected = true; - sinon.assert.called(browserPort.postEvent); - sinon.assert.calledWithExactly(browserPort.postEvent, + sinon.assert.called(browserPort.postMessage); + sinon.assert.calledWithExactly(browserPort.postMessage, "social.ambient-notification", { iconURL: "http://fake/img/talkilla16-online.png" }