pusher 0.8.5 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +5 -5
- data/lib/pusher.rb +28 -65
- data/lib/pusher/channel.rb +5 -4
- data/lib/pusher/client.rb +81 -0
- data/lib/pusher/request.rb +5 -2
- data/lib/pusher/webhook.rb +110 -0
- data/pusher.gemspec +2 -1
- data/spec/channel_spec.rb +31 -32
- data/spec/client_spec.rb +159 -0
- data/spec/web_hook_spec.rb +115 -0
- metadata +34 -19
- data/spec/pusher_spec.rb +0 -87
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -66,6 +66,11 @@ The Pusher Gem also deals with signing requests for authenticated private channe
|
|
66
66
|
|
67
67
|
Read more about private channels in [the docs](http://pusher.com/docs/client_api_guide/client_channels#subscribe-private-channels) and under {Pusher::Channel#authenticate}.
|
68
68
|
|
69
|
+
WebHooks
|
70
|
+
--------
|
71
|
+
|
72
|
+
See {Pusher::WebHook}
|
73
|
+
|
69
74
|
Developing
|
70
75
|
----------
|
71
76
|
|
@@ -73,8 +78,3 @@ Use bundler in order to run specs with the correct dependencies.
|
|
73
78
|
|
74
79
|
bundle
|
75
80
|
bundle exec rspec spec/*_spec.rb
|
76
|
-
|
77
|
-
Copyright
|
78
|
-
---------
|
79
|
-
|
80
|
-
Copyright (c) 2010 New Bamboo. See LICENSE for details.
|
data/lib/pusher.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
autoload 'Logger', 'logger'
|
2
2
|
require 'uri'
|
3
|
+
require 'pusher/client'
|
3
4
|
|
4
5
|
# Used for configuring API credentials and creating Channel objects
|
5
6
|
#
|
@@ -19,89 +20,51 @@ module Pusher
|
|
19
20
|
class HTTPError < Error; attr_accessor :original_error; end
|
20
21
|
|
21
22
|
class << self
|
22
|
-
|
23
|
-
attr_writer :logger
|
24
|
-
attr_accessor :app_id, :key, :secret
|
23
|
+
extend Forwardable
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
@logger ||= begin
|
29
|
-
log = Logger.new($stdout)
|
30
|
-
log.level = Logger::INFO
|
31
|
-
log
|
32
|
-
end
|
33
|
-
end
|
25
|
+
def_delegators :default_client, :scheme, :host, :port, :app_id, :key, :secret
|
26
|
+
def_delegators :default_client, :scheme, :host=, :port=, :app_id=, :key=, :secret=
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
Signature::Token.new(@key, @secret)
|
38
|
-
end
|
28
|
+
def_delegators :default_client, :authentication_token, :url
|
29
|
+
def_delegators :default_client, :encrypted=, :url=
|
39
30
|
|
40
|
-
|
41
|
-
def url
|
42
|
-
URI::Generic.build({
|
43
|
-
:scheme => self.scheme,
|
44
|
-
:host => self.host,
|
45
|
-
:port => self.port,
|
46
|
-
:path => "/apps/#{self.app_id}"
|
47
|
-
})
|
48
|
-
end
|
31
|
+
attr_writer :logger
|
49
32
|
|
50
|
-
#
|
51
|
-
# scheme, key, secret, and app_id separately.
|
33
|
+
# Return a channel by name
|
52
34
|
#
|
53
35
|
# @example
|
54
|
-
# Pusher
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
36
|
+
# Pusher['my-channel']
|
37
|
+
# @return [Channel]
|
38
|
+
# @raise [ConfigurationError] unless key, secret and app_id have been
|
39
|
+
# configured
|
40
|
+
def [](channel_name)
|
41
|
+
begin
|
42
|
+
default_client[channel_name]
|
43
|
+
rescue ConfigurationError
|
44
|
+
raise ConfigurationError, 'Missing configuration: please check that Pusher.key, Pusher.secret and Pusher.app_id are configured.'
|
45
|
+
end
|
63
46
|
end
|
64
47
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
def encrypted=(boolean)
|
72
|
-
Pusher.scheme = boolean ? 'https' : 'http'
|
73
|
-
# Configure port if it hasn't already been configured
|
74
|
-
Pusher.port ||= boolean ? 443 : 80
|
48
|
+
def logger
|
49
|
+
@logger ||= begin
|
50
|
+
log = Logger.new($stdout)
|
51
|
+
log.level = Logger::INFO
|
52
|
+
log
|
53
|
+
end
|
75
54
|
end
|
76
55
|
|
77
56
|
private
|
78
57
|
|
79
|
-
def
|
80
|
-
|
58
|
+
def default_client
|
59
|
+
@default_client ||= Pusher::Client.new
|
81
60
|
end
|
82
61
|
end
|
83
62
|
|
84
|
-
# Defaults
|
85
|
-
self.scheme = 'http'
|
86
|
-
self.host = 'api.pusherapp.com'
|
87
|
-
|
88
63
|
if ENV['PUSHER_URL']
|
89
64
|
self.url = ENV['PUSHER_URL']
|
90
65
|
end
|
91
|
-
|
92
|
-
# Return a channel by name
|
93
|
-
#
|
94
|
-
# @example
|
95
|
-
# Pusher['my-channel']
|
96
|
-
# @return [Channel]
|
97
|
-
# @raise [ConfigurationError] unless key, secret and app_id have been
|
98
|
-
# configured
|
99
|
-
def self.[](channel_name)
|
100
|
-
raise ConfigurationError, 'Missing configuration: please check that Pusher.key, Pusher.secret and Pusher.app_id are configured.' unless configured?
|
101
|
-
@channels ||= {}
|
102
|
-
@channels[channel_name.to_s] ||= Channel.new(url, channel_name)
|
103
|
-
end
|
104
66
|
end
|
105
67
|
|
106
68
|
require 'pusher/channel'
|
107
|
-
require 'pusher/request'
|
69
|
+
require 'pusher/request'
|
70
|
+
require 'pusher/webhook'
|
data/lib/pusher/channel.rb
CHANGED
@@ -6,10 +6,11 @@ module Pusher
|
|
6
6
|
class Channel
|
7
7
|
attr_reader :name
|
8
8
|
|
9
|
-
def initialize(base_url, name)
|
9
|
+
def initialize(base_url, name, client = Pusher)
|
10
10
|
@uri = base_url.dup
|
11
11
|
@uri.path = @uri.path + "/channels/#{name}/"
|
12
12
|
@name = name
|
13
|
+
@client = client
|
13
14
|
end
|
14
15
|
|
15
16
|
# Trigger event asynchronously using EventMachine::HttpRequest
|
@@ -69,7 +70,7 @@ module Pusher
|
|
69
70
|
# @raise [Pusher::HTTPError] on any error raised inside Net::HTTP - the original error is available in the original_error attribute
|
70
71
|
#
|
71
72
|
def stats
|
72
|
-
request = Pusher::Request.new(:get, @uri + 'stats', {})
|
73
|
+
request = Pusher::Request.new(:get, @uri + 'stats', {}, nil, nil, @client)
|
73
74
|
return request.send_sync
|
74
75
|
end
|
75
76
|
|
@@ -89,7 +90,7 @@ module Pusher
|
|
89
90
|
|
90
91
|
string_to_sign = [socket_id, name, custom_string].compact.map{|e|e.to_s}.join(':')
|
91
92
|
Pusher.logger.debug "Signing #{string_to_sign}"
|
92
|
-
token =
|
93
|
+
token = @client.authentication_token
|
93
94
|
signature = HMAC::SHA256.hexdigest(token.secret, string_to_sign)
|
94
95
|
|
95
96
|
return "#{token.key}:#{signature}"
|
@@ -147,7 +148,7 @@ module Pusher
|
|
147
148
|
end
|
148
149
|
end
|
149
150
|
|
150
|
-
request = Pusher::Request.new(:post, @uri + 'events', params, body)
|
151
|
+
request = Pusher::Request.new(:post, @uri + 'events', params, body, nil, @client)
|
151
152
|
end
|
152
153
|
end
|
153
154
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'signature'
|
2
|
+
|
3
|
+
module Pusher
|
4
|
+
class Client
|
5
|
+
attr_accessor :scheme, :host, :port, :app_id, :key, :secret
|
6
|
+
|
7
|
+
# Initializes the client object.
|
8
|
+
def initialize(options = {})
|
9
|
+
options = {
|
10
|
+
scheme: 'http',
|
11
|
+
host: 'api.pusherapp.com',
|
12
|
+
port: 80,
|
13
|
+
}.merge(options)
|
14
|
+
@scheme, @host, @port, @app_id, @key, @secret = options.values_at(
|
15
|
+
:scheme, :host, :port, :app_id, :key, :secret
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
# @private Returns the authentication token for the client
|
20
|
+
def authentication_token
|
21
|
+
Signature::Token.new(@key, @secret)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @private Builds a connection url for Pusherapp
|
25
|
+
def url
|
26
|
+
URI::Generic.build({
|
27
|
+
:scheme => @scheme,
|
28
|
+
:host => @host,
|
29
|
+
:port => @port,
|
30
|
+
:path => "/apps/#{@app_id}"
|
31
|
+
})
|
32
|
+
end
|
33
|
+
|
34
|
+
# Configure Pusher connection by providing a url rather than specifying
|
35
|
+
# scheme, key, secret, and app_id separately.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# Pusher.url = http://KEY:SECRET@api.pusherapp.com/apps/APP_ID
|
39
|
+
#
|
40
|
+
def url=(url)
|
41
|
+
uri = URI.parse(url)
|
42
|
+
@scheme = uri.scheme
|
43
|
+
@app_id = uri.path.split('/').last
|
44
|
+
@key = uri.user
|
45
|
+
@secret = uri.password
|
46
|
+
@host = uri.host
|
47
|
+
@port = uri.port
|
48
|
+
end
|
49
|
+
|
50
|
+
# Configure whether Pusher API calls should be made over SSL
|
51
|
+
# (default false)
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# Pusher.encrypted = true
|
55
|
+
#
|
56
|
+
def encrypted=(boolean)
|
57
|
+
@scheme = boolean ? 'https' : 'http'
|
58
|
+
# Configure port if it hasn't already been configured
|
59
|
+
@port = boolean ? 443 : 80
|
60
|
+
end
|
61
|
+
|
62
|
+
# Return a channel by name
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
# Pusher['my-channel']
|
66
|
+
# @return [Channel]
|
67
|
+
# @raise [ConfigurationError] unless key, secret and app_id have been
|
68
|
+
# configured
|
69
|
+
def [](channel_name)
|
70
|
+
raise ConfigurationError, 'Missing client configuration: please check that key, secret and app_id are configured.' unless configured?
|
71
|
+
@channels ||= {}
|
72
|
+
@channels[channel_name.to_s] ||= Channel.new(url, channel_name, self)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def configured?
|
78
|
+
host && scheme && key && secret && app_id
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/pusher/request.rb
CHANGED
@@ -52,9 +52,12 @@ module Pusher
|
|
52
52
|
|
53
53
|
include QueryEncoder
|
54
54
|
|
55
|
-
|
55
|
+
attr_reader :body, :params
|
56
|
+
|
57
|
+
def initialize(verb, uri, params, body = nil, token = nil, client = Pusher)
|
56
58
|
@verb = verb
|
57
59
|
@uri = uri
|
60
|
+
@client = client
|
58
61
|
|
59
62
|
if body
|
60
63
|
@body = body
|
@@ -62,7 +65,7 @@ module Pusher
|
|
62
65
|
end
|
63
66
|
|
64
67
|
request = Signature::Request.new(verb.to_s.upcase, uri.path, params)
|
65
|
-
auth_hash = request.sign(token ||
|
68
|
+
auth_hash = request.sign(token || @client.authentication_token)
|
66
69
|
@params = params.merge(auth_hash)
|
67
70
|
end
|
68
71
|
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'hmac-sha2'
|
3
|
+
|
4
|
+
module Pusher
|
5
|
+
# Used to parse and authenticate WebHooks
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# post '/webhooks' do
|
9
|
+
# webhook = Pusher::WebHook.new(request)
|
10
|
+
# if webhook.valid?
|
11
|
+
# webhook.events.each do |event|
|
12
|
+
# case event["name"]
|
13
|
+
# when 'channel_occupied'
|
14
|
+
# puts "Channel occupied: #{event["channel"]}"
|
15
|
+
# when 'channel_vacated'
|
16
|
+
# puts "Channel vacated: #{event["channel"]}"
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
# else
|
20
|
+
# status 401
|
21
|
+
# end
|
22
|
+
# return
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
class WebHook
|
26
|
+
attr_reader :key, :signature
|
27
|
+
|
28
|
+
# Provide either a Rack::Request or a Hash containing :key, :signature,
|
29
|
+
# :body, and :content_type (optional)
|
30
|
+
#
|
31
|
+
def initialize(request, client = Pusher)
|
32
|
+
@client = client
|
33
|
+
if request.kind_of?(Rack::Request)
|
34
|
+
@key = request.env['HTTP_X_PUSHER_KEY']
|
35
|
+
@signature = request.env["HTTP_X_PUSHER_SIGNATURE"]
|
36
|
+
@content_type = request.content_type
|
37
|
+
|
38
|
+
request.body.rewind
|
39
|
+
@body = request.body.read
|
40
|
+
request.body.rewind
|
41
|
+
else
|
42
|
+
@key, @signature, @body = request.values_at(:key, :signature, :body)
|
43
|
+
@content_type = request[:content_type] || 'application/json'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns whether the WebHook is valid by checking that the signature
|
48
|
+
# matches the configured key & secret. In the case that the webhook is
|
49
|
+
# invalid, the reason is logged
|
50
|
+
#
|
51
|
+
# @param extra_tokens [Hash] If you have extra tokens for your Pusher
|
52
|
+
# app, you can specify them here so that they're used to attempt
|
53
|
+
# validation.
|
54
|
+
#
|
55
|
+
def valid?(extra_tokens = nil)
|
56
|
+
extra_tokens = [extra_tokens] if extra_tokens.kind_of?(Hash)
|
57
|
+
if @key == @client.key
|
58
|
+
return check_signature(@client.secret)
|
59
|
+
elsif extra_tokens
|
60
|
+
extra_tokens.each do |token|
|
61
|
+
return check_signature(token[:secret]) if @key == token[:key]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
Pusher.logger.warn "Received webhook with unknown key: #{key}"
|
65
|
+
return false
|
66
|
+
end
|
67
|
+
|
68
|
+
# Array of events (as Hashes) contained inside the webhook
|
69
|
+
#
|
70
|
+
def events
|
71
|
+
data["events"]
|
72
|
+
end
|
73
|
+
|
74
|
+
# The time at which the WebHook was initially triggered by Pusher, i.e.
|
75
|
+
# when the event occurred
|
76
|
+
#
|
77
|
+
# @return [Time]
|
78
|
+
#
|
79
|
+
def time
|
80
|
+
Time.at(data["time_ms"].to_f/1000)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Access the parsed WebHook body
|
84
|
+
#
|
85
|
+
def data
|
86
|
+
@data ||= begin
|
87
|
+
case @content_type
|
88
|
+
when 'application/json'
|
89
|
+
MultiJson.decode(@body)
|
90
|
+
else
|
91
|
+
raise "Unknown Content-Type (#{@content_type})"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
# Checks signature against secret and returns boolean
|
99
|
+
#
|
100
|
+
def check_signature(secret)
|
101
|
+
expected = HMAC::SHA256.hexdigest(secret, @body)
|
102
|
+
if @signature == expected
|
103
|
+
return true
|
104
|
+
else
|
105
|
+
Pusher.logger.warn "Received WebHook with invalid signature: got #{@signature}, expected #{expected}"
|
106
|
+
return false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/pusher.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "pusher"
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.9.0"
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Pusher"]
|
9
9
|
s.email = ["support@pusher.com"]
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_development_dependency "webmock"
|
20
20
|
s.add_development_dependency "em-http-request", "~> 1.0.0"
|
21
21
|
s.add_development_dependency "rake"
|
22
|
+
s.add_development_dependency "rack"
|
22
23
|
|
23
24
|
s.files = `git ls-files`.split("\n")
|
24
25
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/spec/channel_spec.rb
CHANGED
@@ -2,12 +2,14 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Pusher::Channel do
|
4
4
|
before do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
@client = Pusher::Client.new(
|
6
|
+
app_id: '20',
|
7
|
+
key: '12345678900000001',
|
8
|
+
secret: '12345678900000001',
|
9
|
+
host: 'api.pusherapp.com',
|
10
|
+
port: 80,
|
11
|
+
)
|
12
|
+
@client.encrypted = false
|
11
13
|
|
12
14
|
WebMock.reset!
|
13
15
|
WebMock.disable_net_connect!
|
@@ -15,17 +17,11 @@ describe Pusher::Channel do
|
|
15
17
|
@pusher_url_regexp = %r{/apps/20/channels/test_channel/events}
|
16
18
|
end
|
17
19
|
|
18
|
-
after do
|
19
|
-
Pusher.app_id = nil
|
20
|
-
Pusher.key = nil
|
21
|
-
Pusher.secret = nil
|
22
|
-
end
|
23
|
-
|
24
20
|
describe 'trigger!' do
|
25
21
|
before :each do
|
26
22
|
WebMock.stub_request(:post, @pusher_url_regexp).
|
27
23
|
to_return(:status => 202)
|
28
|
-
@channel =
|
24
|
+
@channel = @client['test_channel']
|
29
25
|
end
|
30
26
|
|
31
27
|
it 'should configure HTTP library to talk to pusher API' do
|
@@ -34,8 +30,9 @@ describe Pusher::Channel do
|
|
34
30
|
end
|
35
31
|
|
36
32
|
it "should POST to https api if ssl enabled" do
|
37
|
-
|
38
|
-
Pusher::Channel.new(
|
33
|
+
@client.encrypted = true
|
34
|
+
encrypted_channel = Pusher::Channel.new(@client.url, 'test_channel', @client)
|
35
|
+
encrypted_channel.trigger('new_event', 'Some data')
|
39
36
|
WebMock.should have_requested(:post, %r{https://api.pusherapp.com})
|
40
37
|
end
|
41
38
|
|
@@ -47,7 +44,7 @@ describe Pusher::Channel do
|
|
47
44
|
WebMock.should have_requested(:post, %r{/apps/20/channels/test_channel/events}).with do |req|
|
48
45
|
query_hash = req.uri.query_values
|
49
46
|
query_hash["name"].should == 'new_event'
|
50
|
-
query_hash["auth_key"].should ==
|
47
|
+
query_hash["auth_key"].should == @client.key
|
51
48
|
query_hash["auth_timestamp"].should_not be_nil
|
52
49
|
|
53
50
|
parsed = MultiJson.decode(req.body)
|
@@ -75,7 +72,7 @@ describe Pusher::Channel do
|
|
75
72
|
|
76
73
|
error_raised = nil
|
77
74
|
begin
|
78
|
-
|
75
|
+
@client['test_channel'].trigger!('new_event', 'Some data')
|
79
76
|
rescue => e
|
80
77
|
error_raised = e
|
81
78
|
end
|
@@ -90,7 +87,7 @@ describe Pusher::Channel do
|
|
90
87
|
%r{/apps/20/channels/test_channel/events}
|
91
88
|
).to_return(:status => 401)
|
92
89
|
lambda {
|
93
|
-
|
90
|
+
@client['test_channel'].trigger!('new_event', 'Some data')
|
94
91
|
}.should raise_error(Pusher::AuthenticationError)
|
95
92
|
end
|
96
93
|
|
@@ -99,7 +96,7 @@ describe Pusher::Channel do
|
|
99
96
|
:post, %r{/apps/20/channels/test_channel/events}
|
100
97
|
).to_return(:status => 404)
|
101
98
|
lambda {
|
102
|
-
|
99
|
+
@client['test_channel'].trigger!('new_event', 'Some data')
|
103
100
|
}.should raise_error(Pusher::Error, 'Resource not found: app_id is probably invalid')
|
104
101
|
end
|
105
102
|
|
@@ -108,7 +105,7 @@ describe Pusher::Channel do
|
|
108
105
|
:post, %r{/apps/20/channels/test_channel/events}
|
109
106
|
).to_return(:status => 500, :body => "some error")
|
110
107
|
lambda {
|
111
|
-
|
108
|
+
@client['test_channel'].trigger!('new_event', 'Some data')
|
112
109
|
}.should raise_error(Pusher::Error, 'Unknown error (status code 500): some error')
|
113
110
|
end
|
114
111
|
end
|
@@ -118,7 +115,8 @@ describe Pusher::Channel do
|
|
118
115
|
stub_request(:post, @pusher_url_regexp).to_raise(Net::HTTPBadResponse)
|
119
116
|
Pusher.logger.should_receive(:error).with("Exception from WebMock (Net::HTTPBadResponse) (Pusher::HTTPError)")
|
120
117
|
Pusher.logger.should_receive(:debug) #backtrace
|
121
|
-
Pusher::Channel.new(
|
118
|
+
channel = Pusher::Channel.new(@client.url, 'test_channel', @client)
|
119
|
+
channel.trigger('new_event', 'Some data')
|
122
120
|
end
|
123
121
|
|
124
122
|
it "should log failure if Pusher returns an error response" do
|
@@ -126,7 +124,8 @@ describe Pusher::Channel do
|
|
126
124
|
# @http.should_receive(:post).and_raise(Net::HTTPBadResponse)
|
127
125
|
Pusher.logger.should_receive(:error).with(" (Pusher::AuthenticationError)")
|
128
126
|
Pusher.logger.should_receive(:debug) #backtrace
|
129
|
-
Pusher::Channel.new(
|
127
|
+
channel = Pusher::Channel.new(@client.url, 'test_channel', @client)
|
128
|
+
channel.trigger('new_event', 'Some data')
|
130
129
|
end
|
131
130
|
end
|
132
131
|
|
@@ -134,7 +133,7 @@ describe Pusher::Channel do
|
|
134
133
|
it "should by default POST to http api" do
|
135
134
|
EM.run {
|
136
135
|
stub_request(:post, @pusher_url_regexp).to_return(:status => 202)
|
137
|
-
channel = Pusher::Channel.new(
|
136
|
+
channel = Pusher::Channel.new(@client.url, 'test_channel', @client)
|
138
137
|
channel.trigger_async('new_event', 'Some data').callback {
|
139
138
|
WebMock.should have_requested(:post, %r{http://api.pusherapp.com})
|
140
139
|
EM.stop
|
@@ -143,10 +142,10 @@ describe Pusher::Channel do
|
|
143
142
|
end
|
144
143
|
|
145
144
|
it "should POST to https api if ssl enabled" do
|
146
|
-
|
145
|
+
@client.encrypted = true
|
147
146
|
EM.run {
|
148
147
|
stub_request(:post, @pusher_url_regexp).to_return(:status => 202)
|
149
|
-
channel = Pusher::Channel.new(
|
148
|
+
channel = Pusher::Channel.new(@client.url, 'test_channel', @client)
|
150
149
|
channel.trigger_async('new_event', 'Some data').callback {
|
151
150
|
WebMock.should have_requested(:post, %r{https://api.pusherapp.com})
|
152
151
|
EM.stop
|
@@ -158,7 +157,7 @@ describe Pusher::Channel do
|
|
158
157
|
stub_request(:post, @pusher_url_regexp).to_return(:status => 202)
|
159
158
|
|
160
159
|
EM.run {
|
161
|
-
d =
|
160
|
+
d = @client['test_channel'].trigger_async('new_event', 'Some data')
|
162
161
|
d.callback {
|
163
162
|
WebMock.should have_requested(:post, @pusher_url_regexp)
|
164
163
|
EM.stop
|
@@ -174,7 +173,7 @@ describe Pusher::Channel do
|
|
174
173
|
stub_request(:post, @pusher_url_regexp).to_return(:status => 401)
|
175
174
|
|
176
175
|
EM.run {
|
177
|
-
d =
|
176
|
+
d = @client['test_channel'].trigger_async('new_event', 'Some data')
|
178
177
|
d.callback {
|
179
178
|
fail
|
180
179
|
}
|
@@ -197,7 +196,7 @@ describe Pusher::Channel do
|
|
197
196
|
:status => 200,
|
198
197
|
:body => JSON.generate(:user_count => 1)
|
199
198
|
})
|
200
|
-
@channel =
|
199
|
+
@channel = @client['presence-test_channel']
|
201
200
|
|
202
201
|
@channel.stats.should == {
|
203
202
|
:user_count => 1
|
@@ -207,7 +206,7 @@ describe Pusher::Channel do
|
|
207
206
|
|
208
207
|
describe "socket_auth" do
|
209
208
|
before :each do
|
210
|
-
@channel =
|
209
|
+
@channel = @client['test_channel']
|
211
210
|
end
|
212
211
|
|
213
212
|
it "should return an authentication string given a socket id" do
|
@@ -247,7 +246,7 @@ describe Pusher::Channel do
|
|
247
246
|
it "should return an authentication string given a socket id and custom args" do
|
248
247
|
auth = @channel.socket_auth('socketid', 'foobar')
|
249
248
|
|
250
|
-
auth.should == "12345678900000001:#{HMAC::SHA256.hexdigest(
|
249
|
+
auth.should == "12345678900000001:#{HMAC::SHA256.hexdigest(@client.secret, "socketid:test_channel:foobar")}"
|
251
250
|
end
|
252
251
|
|
253
252
|
end
|
@@ -256,7 +255,7 @@ describe Pusher::Channel do
|
|
256
255
|
describe '#authenticate' do
|
257
256
|
|
258
257
|
before :each do
|
259
|
-
@channel =
|
258
|
+
@channel = @client['test_channel']
|
260
259
|
@custom_data = {:uid => 123, :info => {:name => 'Foo'}}
|
261
260
|
end
|
262
261
|
|
@@ -266,7 +265,7 @@ describe Pusher::Channel do
|
|
266
265
|
response = @channel.authenticate('socketid', @custom_data)
|
267
266
|
|
268
267
|
response.should == {
|
269
|
-
:auth => "12345678900000001:#{HMAC::SHA256.hexdigest(
|
268
|
+
:auth => "12345678900000001:#{HMAC::SHA256.hexdigest(@client.secret, "socketid:test_channel:a json string")}",
|
270
269
|
:channel_data => 'a json string'
|
271
270
|
}
|
272
271
|
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'em-http'
|
4
|
+
|
5
|
+
describe Pusher do
|
6
|
+
describe 'different clients' do
|
7
|
+
before :each do
|
8
|
+
@client1 = Pusher::Client.new
|
9
|
+
@client2 = Pusher::Client.new
|
10
|
+
|
11
|
+
@client1.scheme = 'ws'
|
12
|
+
@client2.scheme = 'wss'
|
13
|
+
@client1.host = 'one'
|
14
|
+
@client2.host = 'two'
|
15
|
+
@client1.port = 81
|
16
|
+
@client2.port = 82
|
17
|
+
@client1.app_id = '1111'
|
18
|
+
@client2.app_id = '2222'
|
19
|
+
@client1.key = 'AAAA'
|
20
|
+
@client2.key = 'BBBB'
|
21
|
+
@client1.secret = 'aaaaaaaa'
|
22
|
+
@client2.secret = 'bbbbbbbb'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should send scheme messages to different objects" do
|
26
|
+
@client1.scheme.should_not == @client2.scheme
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should send host messages to different objects" do
|
30
|
+
@client1.host.should_not == @client2.host
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should send port messages to different objects" do
|
34
|
+
@client1.port.should_not == @client2.port
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should send app_id messages to different objects" do
|
38
|
+
@client1.app_id.should_not == @client2.app_id
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should send app_id messages to different objects" do
|
42
|
+
@client1.key.should_not == @client2.key
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should send app_id messages to different objects" do
|
46
|
+
@client1.secret.should_not == @client2.secret
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should send app_id messages to different objects" do
|
50
|
+
@client1.authentication_token.key.should_not == @client2.authentication_token.key
|
51
|
+
@client1.authentication_token.secret.should_not == @client2.authentication_token.secret
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should send url messages to different objects" do
|
55
|
+
@client1.url.to_s.should_not == @client2.url.to_s
|
56
|
+
@client1.url = 'ws://one/apps/111'
|
57
|
+
@client2.url = 'wss://two/apps/222'
|
58
|
+
@client1.scheme.should_not == @client2.scheme
|
59
|
+
@client1.host.should_not == @client2.host
|
60
|
+
@client1.app_id.should_not == @client2.app_id
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should send encrypted messages to different objects" do
|
64
|
+
@client1.encrypted = false
|
65
|
+
@client2.encrypted = true
|
66
|
+
@client1.scheme.should_not == @client2.scheme
|
67
|
+
@client1.port.should_not == @client2.port
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should send [] messages to different objects" do
|
71
|
+
@client1['test'].should_not == @client2['test']
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
[lambda { Pusher }, lambda { Pusher::Client.new }].each do |client_gen|
|
76
|
+
before :each do
|
77
|
+
@client = client_gen.call
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'default configuration' do
|
81
|
+
it 'should be preconfigured for api host' do
|
82
|
+
@client.host.should == 'api.pusherapp.com'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should be preconfigured for port 80' do
|
86
|
+
@client.port.should == 80
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should use standard logger if no other logger if defined' do
|
90
|
+
Pusher.logger.debug('foo')
|
91
|
+
Pusher.logger.should be_kind_of(Logger)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe 'logging configuration' do
|
96
|
+
it "can be configured to use any logger" do
|
97
|
+
logger = mock("ALogger")
|
98
|
+
logger.should_receive(:debug).with('foo')
|
99
|
+
Pusher.logger = logger
|
100
|
+
Pusher.logger.debug('foo')
|
101
|
+
Pusher.logger = nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "configuration using url" do
|
106
|
+
it "should be possible to configure everything by setting the url" do
|
107
|
+
@client.url = "test://somekey:somesecret@api.staging.pusherapp.com:8080/apps/87"
|
108
|
+
|
109
|
+
@client.scheme.should == 'test'
|
110
|
+
@client.host.should == 'api.staging.pusherapp.com'
|
111
|
+
@client.port.should == 8080
|
112
|
+
@client.key.should == 'somekey'
|
113
|
+
@client.secret.should == 'somesecret'
|
114
|
+
@client.app_id.should == '87'
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should override scheme and port when setting encrypted=true after url" do
|
118
|
+
@client.url = "http://somekey:somesecret@api.staging.pusherapp.com:8080/apps/87"
|
119
|
+
@client.encrypted = true
|
120
|
+
|
121
|
+
@client.scheme.should == 'https'
|
122
|
+
@client.port.should == 443
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe 'when configured' do
|
127
|
+
before :each do
|
128
|
+
@client.app_id = '20'
|
129
|
+
@client.key = '12345678900000001'
|
130
|
+
@client.secret = '12345678900000001'
|
131
|
+
end
|
132
|
+
|
133
|
+
describe '.[]' do
|
134
|
+
before do
|
135
|
+
@channel = @client['test_channel']
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should return a channel' do
|
139
|
+
@channel.should be_kind_of(Pusher::Channel)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should reuse the same channel objects" do
|
143
|
+
channel1, channel2 = @client['test_channel'], @client['test_channel']
|
144
|
+
|
145
|
+
channel1.object_id.should == channel2.object_id
|
146
|
+
end
|
147
|
+
|
148
|
+
%w{app_id key secret}.each do |config|
|
149
|
+
it "should raise exception if #{config} not configured" do
|
150
|
+
@client.send("#{config}=", nil)
|
151
|
+
lambda {
|
152
|
+
@client['test_channel']
|
153
|
+
}.should raise_error(Pusher::ConfigurationError)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
describe Pusher::WebHook do
|
7
|
+
before :each do
|
8
|
+
@hook_data = {
|
9
|
+
"time_ms" => 123456,
|
10
|
+
"events" => [
|
11
|
+
{"name" => 'foo'}
|
12
|
+
]
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "initialization" do
|
17
|
+
it "can be initialized with Rack::Request" do
|
18
|
+
request = Rack::Request.new({
|
19
|
+
'HTTP_X_PUSHER_KEY' => '1234',
|
20
|
+
'HTTP_X_PUSHER_SIGNATURE' => 'asdf',
|
21
|
+
'CONTENT_TYPE' => 'application/json',
|
22
|
+
'rack.input' => StringIO.new(MultiJson.encode(@hook_data))
|
23
|
+
})
|
24
|
+
wh = Pusher::WebHook.new(request)
|
25
|
+
wh.key.should == '1234'
|
26
|
+
wh.signature.should == 'asdf'
|
27
|
+
wh.data.should == @hook_data
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can be initialized with a hash" do
|
31
|
+
request = {
|
32
|
+
key: '1234',
|
33
|
+
signature: 'asdf',
|
34
|
+
content_type: 'application/json',
|
35
|
+
body: MultiJson.encode(@hook_data),
|
36
|
+
}
|
37
|
+
wh = Pusher::WebHook.new(request)
|
38
|
+
wh.key.should == '1234'
|
39
|
+
wh.signature.should == 'asdf'
|
40
|
+
wh.data.should == @hook_data
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "after initialization" do
|
45
|
+
before :each do
|
46
|
+
body = MultiJson.encode(@hook_data)
|
47
|
+
request = {
|
48
|
+
key: '1234',
|
49
|
+
signature: HMAC::SHA256.hexdigest('asdf', body),
|
50
|
+
content_type: 'application/json',
|
51
|
+
body: body
|
52
|
+
}
|
53
|
+
|
54
|
+
@client = Pusher::Client.new
|
55
|
+
@wh = Pusher::WebHook.new(request, @client)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should validate" do
|
59
|
+
@client.key = '1234'
|
60
|
+
@client.secret = 'asdf'
|
61
|
+
@wh.should be_valid
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should not validate if key is wrong" do
|
65
|
+
@client.key = '12345'
|
66
|
+
@client.secret = 'asdf'
|
67
|
+
Pusher.logger.should_receive(:warn).with("Received webhook with unknown key: 1234")
|
68
|
+
@wh.should_not be_valid
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not validate if secret is wrong" do
|
72
|
+
@client.key = '1234'
|
73
|
+
@client.secret = 'asdfxxx'
|
74
|
+
Pusher.logger.should_receive(:warn).with("Received WebHook with invalid signature: got a18bd1374b3b198ec457fb11d636ee2024d8077fc542829443729988bd1e4aa4, expected bb81a112a46dee1e4154ee4f328621f32558192c7af12adfc0395082cfcd3c6c")
|
75
|
+
@wh.should_not be_valid
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should validate with an extra token" do
|
79
|
+
@client.key = '12345'
|
80
|
+
@client.secret = 'xxx'
|
81
|
+
@wh.valid?({key: '1234', secret: 'asdf'}).should be_true
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should validate with an array of extra tokens" do
|
85
|
+
@client.key = '123456'
|
86
|
+
@client.secret = 'xxx'
|
87
|
+
@wh.valid?([
|
88
|
+
{key: '12345', secret: 'wtf'},
|
89
|
+
{key: '1234', secret: 'asdf'}
|
90
|
+
]).should be_true
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should not validate if all keys are wrong with extra tokens" do
|
94
|
+
@client.key = '123456'
|
95
|
+
@client.secret = 'asdf'
|
96
|
+
Pusher.logger.should_receive(:warn).with("Received webhook with unknown key: 1234")
|
97
|
+
@wh.valid?({key: '12345', secret: 'asdf'}).should be_false
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should not validate if secret is wrong with extra tokens" do
|
101
|
+
@client.key = '123456'
|
102
|
+
@client.secret = 'asdfxxx'
|
103
|
+
Pusher.logger.should_receive(:warn).with(/Received WebHook with invalid signature/)
|
104
|
+
@wh.valid?({key: '1234', secret: 'wtf'}).should be_false
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should expose events" do
|
108
|
+
@wh.events.should == @hook_data["events"]
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should expose time" do
|
112
|
+
@wh.time.should == Time.at(123.456)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pusher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
16
|
-
requirement: &
|
16
|
+
requirement: &70115752741600 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '1.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70115752741600
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: ruby-hmac
|
27
|
-
requirement: &
|
27
|
+
requirement: &70115752779060 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.4.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70115752779060
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: signature
|
38
|
-
requirement: &
|
38
|
+
requirement: &70115752776600 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.1.2
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70115752776600
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &70115752774560 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '2.0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70115752774560
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: webmock
|
60
|
-
requirement: &
|
60
|
+
requirement: &70115752772240 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70115752772240
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: em-http-request
|
71
|
-
requirement: &
|
71
|
+
requirement: &70115752784600 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 1.0.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70115752784600
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rake
|
82
|
-
requirement: &
|
82
|
+
requirement: &70115752779980 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,18 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70115752779980
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rack
|
93
|
+
requirement: &70115752793240 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70115752793240
|
91
102
|
description: Wrapper for pusher.com REST api
|
92
103
|
email:
|
93
104
|
- support@pusher.com
|
@@ -106,11 +117,14 @@ files:
|
|
106
117
|
- examples/async_message.rb
|
107
118
|
- lib/pusher.rb
|
108
119
|
- lib/pusher/channel.rb
|
120
|
+
- lib/pusher/client.rb
|
109
121
|
- lib/pusher/request.rb
|
122
|
+
- lib/pusher/webhook.rb
|
110
123
|
- pusher.gemspec
|
111
124
|
- spec/channel_spec.rb
|
112
|
-
- spec/
|
125
|
+
- spec/client_spec.rb
|
113
126
|
- spec/spec_helper.rb
|
127
|
+
- spec/web_hook_spec.rb
|
114
128
|
homepage: http://github.com/pusher/pusher-gem
|
115
129
|
licenses: []
|
116
130
|
post_install_message:
|
@@ -131,11 +145,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
145
|
version: '0'
|
132
146
|
requirements: []
|
133
147
|
rubyforge_project:
|
134
|
-
rubygems_version: 1.8.
|
148
|
+
rubygems_version: 1.8.10
|
135
149
|
signing_key:
|
136
150
|
specification_version: 3
|
137
151
|
summary: Pusher API client
|
138
152
|
test_files:
|
139
153
|
- spec/channel_spec.rb
|
140
|
-
- spec/
|
154
|
+
- spec/client_spec.rb
|
141
155
|
- spec/spec_helper.rb
|
156
|
+
- spec/web_hook_spec.rb
|
data/spec/pusher_spec.rb
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'em-http'
|
4
|
-
|
5
|
-
describe Pusher do
|
6
|
-
describe 'configuration' do
|
7
|
-
it 'should be preconfigured for api host' do
|
8
|
-
Pusher.host.should == 'api.pusherapp.com'
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'should be preconfigured for port 80' do
|
12
|
-
Pusher.port.should == 80
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should use standard logger if no other logger if defined' do
|
16
|
-
Pusher.logger.debug('foo')
|
17
|
-
Pusher.logger.should be_kind_of(Logger)
|
18
|
-
end
|
19
|
-
|
20
|
-
it "can be configured to use any logger" do
|
21
|
-
logger = mock("ALogger")
|
22
|
-
logger.should_receive(:debug).with('foo')
|
23
|
-
Pusher.logger = logger
|
24
|
-
Pusher.logger.debug('foo')
|
25
|
-
Pusher.logger = nil
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "configuration using url" do
|
30
|
-
after do
|
31
|
-
Pusher.app_id = nil
|
32
|
-
Pusher.key = nil
|
33
|
-
Pusher.secret = nil
|
34
|
-
Pusher.host = 'api.pusherapp.com'
|
35
|
-
Pusher.port = 80
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should be possible to configure everything by setting the url" do
|
39
|
-
Pusher.url = "http://somekey:somesecret@api.staging.pusherapp.com:8080/apps/87"
|
40
|
-
|
41
|
-
Pusher.host.should == 'api.staging.pusherapp.com'
|
42
|
-
Pusher.port.should == 8080
|
43
|
-
Pusher.key.should == 'somekey'
|
44
|
-
Pusher.secret.should == 'somesecret'
|
45
|
-
Pusher.app_id.should == '87'
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe 'when configured' do
|
50
|
-
before do
|
51
|
-
Pusher.app_id = '20'
|
52
|
-
Pusher.key = '12345678900000001'
|
53
|
-
Pusher.secret = '12345678900000001'
|
54
|
-
end
|
55
|
-
|
56
|
-
after do
|
57
|
-
Pusher.app_id = nil
|
58
|
-
Pusher.key = nil
|
59
|
-
Pusher.secret = nil
|
60
|
-
end
|
61
|
-
|
62
|
-
describe '.[]' do
|
63
|
-
before do
|
64
|
-
@channel = Pusher['test_channel']
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'should return a channel' do
|
68
|
-
@channel.should be_kind_of(Pusher::Channel)
|
69
|
-
end
|
70
|
-
|
71
|
-
it "should reuse the same channel objects" do
|
72
|
-
channel1, channel2 = Pusher['test_channel'], Pusher['test_channel']
|
73
|
-
|
74
|
-
channel1.object_id.should == channel2.object_id
|
75
|
-
end
|
76
|
-
|
77
|
-
%w{app_id key secret}.each do |config|
|
78
|
-
it "should raise exception if #{config} not configured" do
|
79
|
-
Pusher.send("#{config}=", nil)
|
80
|
-
lambda {
|
81
|
-
Pusher['test_channel']
|
82
|
-
}.should raise_error(Pusher::ConfigurationError)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|