koala 1.5.0 → 1.6.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.
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'base64'
2
3
 
3
4
  describe "Koala::Facebook::RealtimeUpdates" do
4
5
  before :all do
@@ -7,24 +8,24 @@ describe "Koala::Facebook::RealtimeUpdates" do
7
8
  @secret = KoalaTest.secret
8
9
  @callback_url = KoalaTest.oauth_test_data["callback_url"]
9
10
  @app_access_token = KoalaTest.app_access_token
10
-
11
+
11
12
  # check OAuth data
12
13
  unless @app_id && @secret && @callback_url && @app_access_token
13
- raise Exception, "Must supply OAuth app id, secret, app_access_token, and callback to run live subscription tests!"
14
+ raise Exception, "Must supply OAuth app id, secret, app_access_token, and callback to run live subscription tests!"
14
15
  end
15
-
16
+
16
17
  # get subscription data
17
18
  @verify_token = KoalaTest.subscription_test_data["verify_token"]
18
19
  @challenge_data = KoalaTest.subscription_test_data["challenge_data"]
19
20
  @subscription_path = KoalaTest.subscription_test_data["subscription_path"]
20
-
21
+
21
22
  # check subscription data
22
23
  unless @verify_token && @challenge_data && @subscription_path
23
- raise Exception, "Must supply verify_token and equivalent challenge_data to run subscription tests!"
24
+ raise Exception, "Must supply verify_token and equivalent challenge_data to run subscription tests!"
24
25
  end
25
26
  end
26
27
 
27
- before :each do
28
+ before :each do
28
29
  @updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
29
30
  end
30
31
 
@@ -34,28 +35,28 @@ describe "Koala::Facebook::RealtimeUpdates" do
34
35
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
35
36
  updates.should be_a(Koala::Facebook::RealtimeUpdates)
36
37
  end
37
-
38
+
38
39
  # attributes
39
40
  it "allows read access to app_id" do
40
- # in Ruby 1.9, .method returns symbols
41
+ # in Ruby 1.9, .method returns symbols
41
42
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:app_id)
42
43
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:app_id=)
43
44
  end
44
45
 
45
46
  it "allows read access to app_access_token" do
46
- # in Ruby 1.9, .method returns symbols
47
+ # in Ruby 1.9, .method returns symbols
47
48
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:app_access_token)
48
49
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:app_access_token=)
49
50
  end
50
51
 
51
52
  it "allows read access to secret" do
52
- # in Ruby 1.9, .method returns symbols
53
+ # in Ruby 1.9, .method returns symbols
53
54
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:secret)
54
55
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:secret=)
55
56
  end
56
57
 
57
58
  it "allows read access to api" do
58
- # in Ruby 1.9, .method returns symbols
59
+ # in Ruby 1.9, .method returns symbols
59
60
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:api)
60
61
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:api=)
61
62
  end
@@ -71,35 +72,35 @@ describe "Koala::Facebook::RealtimeUpdates" do
71
72
  Koala::Utils.should_receive(:deprecate)
72
73
  updates.graph_api
73
74
  end
74
-
75
+
75
76
  # init with secret / fetching the token
76
- it "initializes properly with an app_id and a secret" do
77
+ it "initializes properly with an app_id and a secret" do
77
78
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
78
- updates.should be_a(Koala::Facebook::RealtimeUpdates)
79
+ updates.should be_a(Koala::Facebook::RealtimeUpdates)
79
80
  end
80
81
 
81
- it "fetches an app_token from Facebook when provided an app_id and a secret" do
82
+ it "fetches an app_token from Facebook when provided an app_id and a secret" do
82
83
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
83
84
  updates.app_access_token.should_not be_nil
84
85
  end
85
-
86
+
86
87
  it "uses the OAuth class to fetch a token when provided an app_id and a secret" do
87
88
  oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
88
89
  token = oauth.get_app_access_token
89
90
  oauth.should_receive(:get_app_access_token).and_return(token)
90
- Koala::Facebook::OAuth.should_receive(:new).with(@app_id, @secret).and_return(oauth)
91
+ Koala::Facebook::OAuth.should_receive(:new).with(@app_id, @secret).and_return(oauth)
91
92
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
92
93
  end
93
-
94
- it "sets up the with the app acces token" do
94
+
95
+ it "sets up the with the app acces token" do
95
96
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
96
97
  updates.api.should be_a(Koala::Facebook::API)
97
98
  updates.api.access_token.should == @app_access_token
98
- end
99
-
99
+ end
100
+
100
101
  end
101
102
 
102
- describe "#subscribe" do
103
+ describe "#subscribe" do
103
104
  it "makes a POST to the subscription path" do
104
105
  @updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "post", anything)
105
106
  @updates.subscribe("user", "name", @subscription_path, @verify_token)
@@ -112,11 +113,11 @@ describe "Koala::Facebook::RealtimeUpdates" do
112
113
  :object => obj,
113
114
  :fields => fields,
114
115
  :callback_url => @subscription_path,
115
- :verify_token => @verify_token
116
+ :verify_token => @verify_token
116
117
  ), anything, anything)
117
118
  @updates.subscribe("user", "name", @subscription_path, @verify_token)
118
119
  end
119
-
120
+
120
121
  pending "doesn't require a verify_token" do
121
122
  # see https://github.com/arsduo/koala/issues/150
122
123
  obj = "user"
@@ -124,50 +125,36 @@ describe "Koala::Facebook::RealtimeUpdates" do
124
125
  @updates.api.should_not_receive(:graph_call).with(anything, hash_including(:verify_token => anything), anything, anything)
125
126
  @updates.subscribe("user", "name", @subscription_path)
126
127
  end
127
-
128
+
128
129
  it "requires verify_token" do
129
130
  expect { @updates.subscribe("user", "name", @subscription_path) }.to raise_exception
130
131
  end
131
-
132
- it "requests the status component" do
133
- @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
134
- @updates.subscribe("user", "name", @subscription_path, @verify_token)
135
- end
136
-
132
+
137
133
  it "accepts an options hash" do
138
134
  options = {:a => 2, :b => "c"}
139
135
  @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
140
136
  @updates.subscribe("user", "name", @subscription_path, @verify_token, options)
141
137
  end
142
-
143
- it "overrides any provided http_component" do
144
- # since we test against status, we need to ensure that we get that
145
- options = {:http_component => :body}
146
- @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
147
- @updates.subscribe("user", "name", @subscription_path, @verify_token, options)
148
- end
149
138
 
150
139
  describe "in practice" do
151
140
  it "sends a subscription request" do
152
- result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
153
- result.should be_true
141
+ expect { @updates.subscribe("user", "name", @subscription_path, @verify_token) }.to_not raise_error
154
142
  end
155
-
143
+
156
144
  pending "sends a subscription request without a verify token" do
157
- result = @updates.subscribe("user", "name", @subscription_path)
158
- result.should be_true
145
+ expect { @updates.subscribe("user", "name", @subscription_path) }.to_not raise_error
159
146
  end
160
-
147
+
161
148
  it "fails if you try to hit an invalid path on your valid server" do
162
149
  expect { result = @updates.subscribe("user", "name", @subscription_path + "foo", @verify_token) }.to raise_exception(Koala::Facebook::APIError)
163
150
  end
164
-
151
+
165
152
  it "fails to send a subscription request to an invalid server" do
166
153
  expect { @updates.subscribe("user", "name", "foo", @verify_token) }.to raise_exception(Koala::Facebook::APIError)
167
154
  end
168
155
  end
169
156
  end
170
-
157
+
171
158
  describe "#unsubscribe" do
172
159
  it "makes a DELETE to the subscription path" do
173
160
  @updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "delete", anything)
@@ -179,65 +166,76 @@ describe "Koala::Facebook::RealtimeUpdates" do
179
166
  @updates.api.should_receive(:graph_call).with(anything, hash_including(:object => obj), anything, anything)
180
167
  @updates.unsubscribe(obj)
181
168
  end
182
-
183
- it "requests the status component" do
184
- @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
185
- @updates.unsubscribe("user")
186
- end
187
-
169
+
188
170
  it "accepts an options hash" do
189
171
  options = {:a => 2, :b => "C"}
190
172
  @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
191
173
  @updates.unsubscribe("user", options)
192
174
  end
193
-
194
- it "overrides any provided http_component" do
195
- # since we test against status, we need to ensure that we get that
196
- options = {:http_component => :body}
197
- @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
198
- @updates.unsubscribe("user", options)
199
- end
200
-
175
+
201
176
  describe "in practice" do
202
- it "unsubscribes a valid individual object successfully" do
203
- @updates.unsubscribe("user").should be_true
177
+ it "unsubscribes a valid individual object successfully" do
178
+ expect { @updates.unsubscribe("user") }.to_not raise_error
204
179
  end
205
180
 
206
- it "unsubscribes all subscriptions successfully" do
207
- @updates.unsubscribe.should be_true
181
+ it "unsubscribes all subscriptions successfully" do
182
+ expect { @updates.unsubscribe }.to_not raise_error
208
183
  end
209
184
 
210
- it "fails when an invalid object is provided to unsubscribe" do
185
+ it "fails when an invalid object is provided to unsubscribe" do
211
186
  expect { @updates.unsubscribe("kittens") }.to raise_error(Koala::Facebook::APIError)
212
187
  end
213
188
  end
214
189
  end
215
-
190
+
216
191
  describe "#list_subscriptions" do
217
192
  it "GETs the subscription path" do
218
193
  @updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "get", anything)
219
194
  @updates.list_subscriptions
220
195
  end
221
-
196
+
222
197
  it "accepts options" do
223
- options = {:a => 3, :b => "D"}
198
+ options = {:a => 3, :b => "D"}
224
199
  @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
225
200
  @updates.list_subscriptions(options)
226
201
  end
227
-
202
+
228
203
  describe "in practice" do
229
204
  it "lists subscriptions properly" do
230
205
  @updates.list_subscriptions.should be_a(Array)
231
206
  end
232
207
  end
233
208
  end
234
-
209
+
235
210
  describe "#subscription_path" do
236
211
  it "returns the app_id/subscriptions" do
237
212
  @updates.subscription_path.should == "#{@app_id}/subscriptions"
238
213
  end
239
214
  end
240
-
215
+
216
+ describe ".validate_update" do
217
+ it "returns false if there is no X-Hub-Signature header" do
218
+ @updates.validate_update("", {}).should be_false
219
+ end
220
+
221
+ it "returns false if the signature doesn't match the body" do
222
+ @updates.validate_update("", {"X-Hub-Signature" => "sha1=badsha1"}).should be_false
223
+ end
224
+
225
+ it "results true if the signature matches the body with the secret" do
226
+ body = "BODY"
227
+ signature = OpenSSL::HMAC.hexdigest('sha1', @secret, body).chomp
228
+ @updates.validate_update(body, {"X-Hub-Signature" => "sha1=#{signature}"}).should be_true
229
+ end
230
+
231
+ it "results true with alternate HTTP_X_HUB_SIGNATURE header" do
232
+ body = "BODY"
233
+ signature = OpenSSL::HMAC.hexdigest('sha1', @secret, body).chomp
234
+ @updates.validate_update(body, {"HTTP_X_HUB_SIGNATURE" => "sha1=#{signature}"}).should be_true
235
+ end
236
+
237
+ end
238
+
241
239
  describe ".meet_challenge" do
242
240
  it "returns false if hub.mode isn't subscribe" do
243
241
  params = {'hub.mode' => 'not subscribe'}
@@ -250,56 +248,56 @@ describe "Koala::Facebook::RealtimeUpdates" do
250
248
  Koala::Facebook::RealtimeUpdates.meet_challenge(params){|token| block_evaluated = true}
251
249
  block_evaluated.should be_false
252
250
  end
253
-
251
+
254
252
  it "returns false if not given a verify_token or block" do
255
253
  params = {'hub.mode' => 'subscribe'}
256
254
  Koala::Facebook::RealtimeUpdates.meet_challenge(params).should be_false
257
255
  end
258
-
256
+
259
257
  describe "and mode is 'subscribe'" do
260
- before(:each) do
258
+ before(:each) do
261
259
  @params = {'hub.mode' => 'subscribe'}
262
260
  end
263
-
261
+
264
262
  describe "and a token is given" do
265
263
  before(:each) do
266
264
  @token = 'token'
267
265
  @params['hub.verify_token'] = @token
268
266
  end
269
-
267
+
270
268
  it "returns false if the given verify token doesn't match" do
271
269
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token + '1').should be_false
272
270
  end
273
-
271
+
274
272
  it "returns the challenge if the given verify token matches" do
275
273
  @params['hub.challenge'] = 'challenge val'
276
274
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token).should == @params['hub.challenge']
277
275
  end
278
276
  end
279
-
277
+
280
278
  describe "and a block is given" do
281
279
  before :each do
282
280
  @params['hub.verify_token'] = @token
283
281
  end
284
-
282
+
285
283
  it "gives the block the token as a parameter" do
286
284
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
287
285
  token.should == @token
288
286
  end
289
287
  end
290
-
288
+
291
289
  it "returns false if the given block return false" do
292
290
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
293
291
  false
294
292
  end.should be_false
295
293
  end
296
-
294
+
297
295
  it "returns false if the given block returns nil" do
298
296
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
299
297
  nil
300
298
  end.should be_false
301
299
  end
302
-
300
+
303
301
  it "returns the challenge if the given block returns true" do
304
302
  @params['hub.challenge'] = 'challenge val'
305
303
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
@@ -14,11 +14,16 @@ describe "Koala::Facebook::TestUsers" do
14
14
  raise Exception, "Must supply OAuth app id, secret, app_access_token, and callback to run live subscription tests!"
15
15
  end
16
16
  end
17
-
17
+
18
18
  after :each do
19
19
  # clean up any test users
20
- ((@network || []) + [@user1, @user2]).each do |u|
21
- puts "Unable to delete test user #{u.inspect}" if u && !(@test_users.delete(u) rescue false)
20
+ # Facebook only allows us 500 test users per app, so we have to clean up
21
+ # This would be a good place to clean up and accumulate all of them for
22
+ # later deletion.
23
+ unless KoalaTest.mock_interface?
24
+ ((@network || []) + [@user1, @user2]).each do |u|
25
+ puts "Unable to delete test user #{u.inspect}" if u && !(@test_users.delete(u) rescue false)
26
+ end
22
27
  end
23
28
  end
24
29
 
@@ -128,7 +133,7 @@ describe "Koala::Facebook::TestUsers" do
128
133
  @test_users.create(true, nil, {}, options)
129
134
  end
130
135
  end
131
-
136
+
132
137
  describe "#list" do
133
138
  before :each do
134
139
  @user1 = @test_users.create(true, "read_stream")
@@ -142,9 +147,9 @@ describe "Koala::Facebook::TestUsers" do
142
147
  (first_user["id"] && first_user["access_token"] && first_user["login_url"]).should
143
148
  (second_user["id"] && second_user["access_token"] && second_user["login_url"]).should
144
149
  end
145
-
150
+
146
151
  it "accepts http options" do
147
- options = {:some_http_option => true}
152
+ options = {:some_http_option => true}
148
153
  @test_users.api.should_receive(:graph_call).with(anything, anything, anything, options)
149
154
  @test_users.list(options)
150
155
  end
@@ -169,13 +174,13 @@ describe "Koala::Facebook::TestUsers" do
169
174
  it "does not delete users when provided a false ID" do
170
175
  lambda { @test_users.delete("#{@user1['id']}1") }.should raise_exception(Koala::Facebook::APIError)
171
176
  end
172
-
177
+
173
178
  it "lets you specify http options that get passed through to the graph call" do
174
179
  options = {:some_http_option => true}
175
180
  # technically this goes through delete_object, but this makes it less brittle
176
181
  @test_users.graph_api.should_receive(:graph_call).with(anything, anything, anything, options)
177
182
  @test_users.delete("user", options)
178
- end
183
+ end
179
184
  end
180
185
 
181
186
  describe "#delete_all" do
@@ -187,20 +192,20 @@ describe "Koala::Facebook::TestUsers" do
187
192
  array.each {|item| batch_api.should_receive(:delete_object).with(item["id"]) }
188
193
  @test_users.delete_all
189
194
  end
190
-
195
+
191
196
  it "accepts http options that get passed to both list and the batch call" do
192
197
  options = {:some_http_option => true}
193
198
  @test_users.should_receive(:list).with(options).and_return([{"id" => rand}], [])
194
199
  @test_users.api.should_receive(:batch).with(options)
195
200
  @test_users.delete_all(options)
196
- end
197
-
201
+ end
202
+
198
203
  it "breaks if Facebook sends back the same list twice" do
199
204
  list = [{"id" => rand}]
200
205
  @test_users.should_receive(:list).any_number_of_times.and_return(list)
201
206
  @test_users.api.should_receive(:batch).once
202
207
  @test_users.delete_all
203
- end
208
+ end
204
209
  end
205
210
 
206
211
  describe "#update" do
@@ -221,9 +226,9 @@ describe "Koala::Facebook::TestUsers" do
221
226
  @test_users2.graph_api.should_receive(:graph_call).with(@user1["id"], @updates, anything, anything)
222
227
  @test_users2.update(@user1, @updates)
223
228
  end
224
-
229
+
225
230
  it "accepts an options hash" do
226
- options = {:some_http_option => true}
231
+ options = {:some_http_option => true}
227
232
  @test_users2.graph_api.should_receive(:graph_call).with(anything, anything, anything, options)
228
233
  @test_users2.update("foo", @updates, options)
229
234
  end
@@ -235,13 +240,13 @@ describe "Koala::Facebook::TestUsers" do
235
240
  user_info["name"].should == @updates[:name]
236
241
  end
237
242
  end
238
-
243
+
239
244
  describe "#befriend" do
240
245
  before :each do
241
246
  @user1 = @test_users.create(true, "read_stream")
242
247
  @user2 = @test_users.create(true, "read_stream,user_interests")
243
248
  end
244
-
249
+
245
250
  it "makes two users into friends with string hashes" do
246
251
  result = @test_users.befriend(@user1, @user2)
247
252
  result.should be_true
@@ -260,13 +265,13 @@ describe "Koala::Facebook::TestUsers" do
260
265
  it "does not accept user IDs anymore" do
261
266
  lambda { @test_users.befriend(@user1["id"], @user2["id"]) }.should raise_exception
262
267
  end
263
-
268
+
264
269
  it "accepts http options passed to both calls" do
265
- options = {:some_http_option => true}
270
+ options = {:some_http_option => true}
266
271
  # should come twice, once for each user
267
272
  Koala.http_service.should_receive(:make_request).with(anything, anything, anything, options).twice.and_return(Koala::HTTPService::Response.new(200, "{}", {}))
268
273
  @test_users.befriend(@user1, @user2, options)
269
- end
274
+ end
270
275
  end
271
276
  end # when used without network
272
277
 
@@ -318,7 +323,7 @@ describe "Koala::Facebook::TestUsers" do
318
323
 
319
324
  it "accepts http options that are passed to both the create and befriend calls" do
320
325
  count = 25
321
- options = {:some_http_option => true}
326
+ options = {:some_http_option => true}
322
327
  @test_users.should_receive(:create).exactly(count).times.with(anything, anything, options).and_return({})
323
328
  # there are more befriends than creates, but we don't need to do the extra work to calculate out the exact #
324
329
  @test_users.should_receive(:befriend).at_least(count).times.with(anything, anything, options)