From cae4137f6667164171c8f4a379cedfd23b81455c Mon Sep 17 00:00:00 2001 From: Victor Borja Date: Wed, 22 Aug 2012 01:21:53 -0500 Subject: [PATCH 1/3] Add `subscription` callback to PrivatePub.sign If options given to `sign` include a `subscription` function, it will be called with the newly created subscription object. This way users can add a Faye callback to know when a subscription is ready or cancel a subscription in the future. --- app/assets/javascripts/private_pub.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/private_pub.js b/app/assets/javascripts/private_pub.js index 8775ca3..3d4878d 100644 --- a/app/assets/javascripts/private_pub.js +++ b/app/assets/javascripts/private_pub.js @@ -49,7 +49,10 @@ function buildPrivatePub(doc) { } self.subscriptions[options.channel] = options; self.faye(function(faye) { - faye.subscribe(options.channel, self.handleResponse); + var sub = faye.subscribe(options.channel, self.handleResponse); + if (options.subscription) { + options.subscription(sub); + } }); }, From 45ef2d336acb0c91d5e326dbda107bb96b07ac50 Mon Sep 17 00:00:00 2001 From: Victor Borja Date: Wed, 22 Aug 2012 08:47:25 -0500 Subject: [PATCH 2/3] Expose methods for unsubscribing and getting a channel subscription object. Store subscription objects on an internal object and expose three new methods: `subscription(channel)`, `unsubscribe(channel)` and `unsubscribeAll()` --- app/assets/javascripts/private_pub.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/assets/javascripts/private_pub.js b/app/assets/javascripts/private_pub.js index 3d4878d..98a6436 100644 --- a/app/assets/javascripts/private_pub.js +++ b/app/assets/javascripts/private_pub.js @@ -4,6 +4,7 @@ function buildPrivatePub(doc) { fayeClient: null, fayeCallbacks: [], subscriptions: {}, + subscriptionObjects: {}, subscriptionCallbacks: {}, faye: function(callback) { @@ -50,6 +51,7 @@ function buildPrivatePub(doc) { self.subscriptions[options.channel] = options; self.faye(function(faye) { var sub = faye.subscribe(options.channel, self.handleResponse); + subscriptionObjects[options.channel] = sub; if (options.subscription) { options.subscription(sub); } @@ -65,6 +67,25 @@ function buildPrivatePub(doc) { } }, + subscription: function(channel) { + return self.subscriptionObjects[channel]; + }, + + unsubscribeAll: function() { + for (var i in self.subscriptionObjects) { + if ( self.subscriptionObjects.hasOwnProperty(i) ) { + self.subscriptionObjects[i].cancel(); + } + } + }, + + unsubscribe: function(channel) { + var sub = self.subscription(channel); + if (sub) { + sub.cancel(); + } + }, + subscribe: function(channel, callback) { self.subscriptionCallbacks[channel] = callback; } From a0abfba2ca774303e00321f9565ec99fea7dc97c Mon Sep 17 00:00:00 2001 From: Victor Borja Date: Wed, 22 Aug 2012 09:50:20 -0500 Subject: [PATCH 3/3] Add specs for options.subscription callback and unsubcribe methods. --- app/assets/javascripts/private_pub.js | 5 ++- spec/javascripts/private_pub_spec.js | 57 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/private_pub.js b/app/assets/javascripts/private_pub.js index 98a6436..43e19e4 100644 --- a/app/assets/javascripts/private_pub.js +++ b/app/assets/javascripts/private_pub.js @@ -51,7 +51,7 @@ function buildPrivatePub(doc) { self.subscriptions[options.channel] = options; self.faye(function(faye) { var sub = faye.subscribe(options.channel, self.handleResponse); - subscriptionObjects[options.channel] = sub; + self.subscriptionObjects[options.channel] = sub; if (options.subscription) { options.subscription(sub); } @@ -74,7 +74,7 @@ function buildPrivatePub(doc) { unsubscribeAll: function() { for (var i in self.subscriptionObjects) { if ( self.subscriptionObjects.hasOwnProperty(i) ) { - self.subscriptionObjects[i].cancel(); + self.unsubscribe(i); } } }, @@ -83,6 +83,7 @@ function buildPrivatePub(doc) { var sub = self.subscription(channel); if (sub) { sub.cancel(); + delete self.subscriptionObjects[channel]; } }, diff --git a/spec/javascripts/private_pub_spec.js b/spec/javascripts/private_pub_spec.js index b309947..fef7523 100644 --- a/spec/javascripts/private_pub_spec.js +++ b/spec/javascripts/private_pub_spec.js @@ -63,6 +63,63 @@ describe("PrivatePub", function() { expect(pub.subscriptions.somechannel).toEqual(options); }); + it("takes a callback for subscription object when signing", function(){ + var faye = {subscribe: function(){ return "subscription"; }}; + spyOn(pub, 'faye').andCallFake(function(callback) { + callback(faye); + }); + var options = { server: "server", channel: "somechannel" }; + options.subscription = jasmine.createSpy(); + pub.sign(options); + expect(options.subscription).toHaveBeenCalledWith("subscription"); + }); + + it("returns the subscription object for a subscribed channel", function(){ + var faye = {subscribe: function(){ return "subscription"; }}; + spyOn(pub, 'faye').andCallFake(function(callback) { + callback(faye); + }); + var options = { server: "server", channel: "somechannel" }; + pub.sign(options); + expect(pub.subscription("somechannel")).toEqual("subscription") + }); + + it("unsubscribes a channel by name", function(){ + var sub = { cancel: jasmine.createSpy() }; + var faye = {subscribe: function(){ return sub; }}; + spyOn(pub, 'faye').andCallFake(function(callback) { + callback(faye); + }); + var options = { server: "server", channel: "somechannel" }; + pub.sign(options); + expect(pub.subscription("somechannel")).toEqual(sub); + pub.unsubscribe("somechannel"); + expect(sub.cancel).toHaveBeenCalled(); + expect(pub.subscription("somechannel")).toBeFalsy(); + }); + + it("unsubscribes all channels", function(){ + var created = 0; + var sub = function() { + created ++; + var sub = { cancel: function(){ created --; } }; + return sub; + }; + var faye = { subscribe: function(){ return sub(); }}; + spyOn(pub, 'faye').andCallFake(function(callback) { + callback(faye); + }); + pub.sign({server: "server", channel: "firstchannel"}); + pub.sign({server: "server", channel: "secondchannel"}); + expect(created).toEqual(2); + expect(pub.subscription("firstchannel")).toBeTruthy(); + expect(pub.subscription("secondchannel")).toBeTruthy(); + pub.unsubscribeAll() + expect(created).toEqual(0); + expect(pub.subscription("firstchannel")).toBeFalsy(); + expect(pub.subscription("secondchannel")).toBeFalsy(); + }); + it("triggers faye callback function immediately when fayeClient is available", function() { var called = false; pub.fayeClient = "faye";