pusher 0.8.5 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|