Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add support for the channel REST API endpoint.

  • Loading branch information...
commit 701a0bce1ba5c22d2eafdc3e73c42522295a024a 1 parent 419caeb
@tristandunn authored
View
37 features/channel.feature
@@ -70,3 +70,40 @@ Feature: Requesting channel information
"""
user_count may only be requested for presence channels - please supply filter_by_prefix begining with presence-
"""
+
+ Scenario: Requesting a channel, with no occupants
+ When I request "/channels/empty"
+ Then I should receive the following JSON:
+ """
+ { "occupied" : false }
+ """
+
+ Scenario: Requesting a channel, with an occupant
+ Given I subscribe to the "non-empty" channel
+ When I request "/channels/non-empty"
+ Then I should receive the following JSON:
+ """
+ { "occupied" : true }
+ """
+
+ Scenario: Requesting a channel, with valid info attributes
+ Given I subscribe to the "presence-1" channel
+ And Bob is connected
+ And Bob is subscribed to the "presence-1" channel
+ When I request "/channels/presence-1" with the following options:
+ | info |
+ | user_count |
+ Then I should receive the following JSON:
+ """
+ { "occupied" : true,
+ "user_count" : 2 }
+ """
+
+ Scenario: Requesting a channel, with invalid info attributes
+ When I request "/channels/public-1" with the following options:
+ | info |
+ | user_count |
+ Then I should receive the following error:
+ """
+ Cannot retrieve the user count unless the channel is a presence channel
+ """
View
36 lib/pusher-fake/server/application.rb
@@ -4,6 +4,10 @@ class Application
CHANNEL_FILTER_ERROR = "user_count may only be requested for presence channels - " +
"please supply filter_by_prefix begining with presence-".freeze
+ CHANNEL_USER_COUNT_ERROR = "Cannot retrieve the user count unless the channel is a presence channel".freeze
+
+ PRESENCE_PREFIX_MATCHER = /\Apresence-/.freeze
+
# Process an API request.
#
# @param [Hash] environment The request environment.
@@ -12,10 +16,12 @@ def self.call(environment)
id = PusherFake.configuration.app_id
request = Rack::Request.new(environment)
response = case request.path
- when %r{/apps/#{id}/events}
+ when %r{\A/apps/#{id}/events\Z}
events(request)
- when %r{/apps/#{id}/channels}
+ when %r{\A/apps/#{id}/channels\Z}
channels(request)
+ when %r{\A/apps/#{id}/channels/(.+)\Z}
+ channel($1, request)
end
Rack::Response.new(MultiJson.dump(response)).finish
@@ -36,6 +42,30 @@ def self.events(request)
{}
end
+ # Return a hash of channel information.
+ #
+ # Occupied status is always included. A user count may be requested for
+ # presence channels.
+ #
+ # @param [String] name The channel name.
+ # @params [Rack::Request] request The HTTP request.
+ # @return [Hash] A hash of channel information.
+ def self.channel(name, request)
+ info = request.params["info"].to_s.split(",")
+
+ if info.include?("user_count") && name !~ PRESENCE_PREFIX_MATCHER
+ raise CHANNEL_USER_COUNT_ERROR
+ end
+
+ channels = PusherFake::Channel.channels || {}
+ channel = channels[name]
+
+ {}.tap do |result|
+ result[:occupied] = !channel.nil? && channel.connections.length > 0
+ result[:user_count] = channel.connections.length if channel && info.include?("user_count")
+ end
+ end
+
# Returns a hash of occupied channels, optionally filtering with a prefix.
#
# When filtering to presence chanenls, the user count maybe also be requested.
@@ -46,7 +76,7 @@ def self.channels(request)
info = request.params["info"].to_s.split(",")
prefix = request.params["filter_by_prefix"].to_s
- if info.include?("user_count") && prefix != "presence-"
+ if info.include?("user_count") && prefix !~ PRESENCE_PREFIX_MATCHER
raise CHANNEL_FILTER_ERROR
end
View
80 spec/lib/pusher-fake/server/application_spec.rb
@@ -234,3 +234,83 @@
}.should raise_error(subject::CHANNEL_FILTER_ERROR)
end
end
+
+describe PusherFake::Server::Application, ".channel, for an occupied channel" do
+ let(:name) { "public-1" }
+ let(:request) { stub(params: {}) }
+ let(:channel) { stub(connections: [mock]) }
+ let(:channels) { { name => channel } }
+
+ subject { PusherFake::Server::Application }
+
+ before do
+ PusherFake::Channel.stubs(channels: channels)
+ end
+
+ it "returns a hash with the occupied status" do
+ subject.channel(name, request).should == { occupied: true }
+ end
+end
+
+describe PusherFake::Server::Application, ".channel, for an unoccupied channel" do
+ let(:name) { "public-1" }
+ let(:request) { stub(params: {}) }
+ let(:channel) { stub(connections: []) }
+ let(:channels) { { name => channel } }
+
+ subject { PusherFake::Server::Application }
+
+ before do
+ PusherFake::Channel.stubs(channels: channels)
+ end
+
+ it "returns a hash with the occupied status" do
+ subject.channel(name, request).should == { occupied: false }
+ end
+end
+
+describe PusherFake::Server::Application, ".channel, for an unknown channel" do
+ let(:request) { stub(params: {}) }
+ let(:channels) { {} }
+
+ subject { PusherFake::Server::Application }
+
+ before do
+ PusherFake::Channel.stubs(channels: channels)
+ end
+
+ it "returns a hash with the occupied status" do
+ subject.channel("fake", request).should == { occupied: false }
+ end
+end
+
+describe PusherFake::Server::Application, ".channel, request user count for a presence channel" do
+ let(:name) { "presence-1" }
+ let(:params) { { "info" => "user_count" } }
+ let(:request) { stub(params: params) }
+ let(:channel) { stub(connections: [mock, mock]) }
+ let(:channels) { { name => channel } }
+
+ subject { PusherFake::Server::Application }
+
+ before do
+ PusherFake::Channel.stubs(channels: channels)
+ end
+
+ it "returns a hash with the occupied status" do
+ subject.channel(name, request).should == { occupied: true, user_count: 2 }
+ end
+end
+
+describe PusherFake::Server::Application, ".channel, requesting a user count on a non-presence channel" do
+ let(:params) { { "info" => "user_count" } }
+ let(:request) { stub(params: params) }
+
+ subject { PusherFake::Server::Application }
+
+ it "raises an error" do
+ lambda {
+ subject.channel("public-1", request)
+ }.should raise_error(subject::CHANNEL_USER_COUNT_ERROR)
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.