koala 1.2.1 → 1.3.0rc2
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/.gitignore +3 -1
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/.yardopts +3 -0
- data/CHANGELOG +25 -0
- data/Gemfile +14 -0
- data/Guardfile +6 -0
- data/koala.gemspec +3 -3
- data/lib/koala/api/batch_operation.rb +83 -0
- data/lib/koala/api/graph_api.rb +476 -0
- data/lib/koala/{graph_batch_api.rb → api/graph_batch_api.rb} +22 -17
- data/lib/koala/api/graph_collection.rb +107 -0
- data/lib/koala/api/legacy.rb +26 -0
- data/lib/koala/{rest_api.rb → api/rest_api.rb} +32 -13
- data/lib/koala/api.rb +93 -0
- data/lib/koala/http_service/multipart_request.rb +41 -0
- data/lib/koala/http_service/response.rb +18 -0
- data/lib/koala/http_service/uploadable_io.rb +187 -0
- data/lib/koala/http_service.rb +69 -20
- data/lib/koala/oauth.rb +150 -27
- data/lib/koala/realtime_updates.rb +89 -51
- data/lib/koala/test_users.rb +109 -33
- data/lib/koala/utils.rb +11 -4
- data/lib/koala/version.rb +1 -1
- data/lib/koala.rb +16 -96
- data/readme.md +9 -9
- data/spec/cases/api_spec.rb +19 -12
- data/spec/cases/error_spec.rb +10 -0
- data/spec/cases/graph_api_batch_spec.rb +100 -58
- data/spec/cases/graph_collection_spec.rb +23 -7
- data/spec/cases/http_service_spec.rb +5 -26
- data/spec/cases/koala_spec.rb +22 -4
- data/spec/cases/legacy_spec.rb +107 -0
- data/spec/cases/multipart_request_spec.rb +7 -7
- data/spec/cases/oauth_spec.rb +114 -44
- data/spec/cases/realtime_updates_spec.rb +154 -47
- data/spec/cases/test_users_spec.rb +268 -219
- data/spec/cases/uploadable_io_spec.rb +1 -1
- data/spec/cases/utils_spec.rb +29 -5
- data/spec/fixtures/mock_facebook_responses.yml +40 -29
- data/spec/spec_helper.rb +3 -0
- data/spec/support/custom_matchers.rb +28 -0
- data/spec/support/graph_api_shared_examples.rb +192 -14
- data/spec/support/koala_test.rb +10 -1
- data/spec/support/mock_http_service.rb +2 -2
- data/spec/support/rest_api_shared_examples.rb +5 -165
- metadata +76 -100
- data/lib/koala/batch_operation.rb +0 -74
- data/lib/koala/graph_api.rb +0 -270
- data/lib/koala/graph_collection.rb +0 -59
- data/lib/koala/multipart_request.rb +0 -35
- data/lib/koala/uploadable_io.rb +0 -181
- data/spec/cases/graph_and_rest_api_spec.rb +0 -22
- data/spec/cases/graph_api_spec.rb +0 -22
- data/spec/cases/rest_api_spec.rb +0 -22
data/spec/cases/oauth_spec.rb
CHANGED
|
@@ -29,26 +29,27 @@ describe "Koala::Facebook::OAuth" do
|
|
|
29
29
|
@time.stub!(:to_i).and_return(1273363199)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
describe ".new" do
|
|
33
|
+
it "properly initializes" do
|
|
34
|
+
@oauth.should
|
|
35
|
+
end
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
it "properly sets attributes" do
|
|
38
|
+
(@oauth.app_id == @app_id &&
|
|
39
|
+
@oauth.app_secret == @secret &&
|
|
40
|
+
@oauth.oauth_callback_url == @callback_url).should be_true
|
|
41
|
+
end
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
it "properly initializes without a callback_url" do
|
|
44
|
+
@oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
|
|
45
|
+
end
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
it "properly sets attributes without a callback URL" do
|
|
48
|
+
@oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
|
|
49
|
+
(@oauth.app_id == @app_id &&
|
|
50
|
+
@oauth.app_secret == @secret &&
|
|
51
|
+
@oauth.oauth_callback_url == nil).should be_true
|
|
52
|
+
end
|
|
52
53
|
end
|
|
53
54
|
|
|
54
55
|
describe "for cookie parsing" do
|
|
@@ -209,88 +210,157 @@ describe "Koala::Facebook::OAuth" do
|
|
|
209
210
|
end
|
|
210
211
|
end
|
|
211
212
|
|
|
212
|
-
# OAuth URLs
|
|
213
|
-
|
|
214
213
|
describe "for URL generation" do
|
|
215
|
-
|
|
216
|
-
describe "for OAuth codes" do
|
|
217
|
-
# url_for_oauth_code
|
|
214
|
+
describe "#url_for_oauth_code" do
|
|
218
215
|
it "generates a properly formatted OAuth code URL with the default values" do
|
|
219
216
|
url = @oauth.url_for_oauth_code
|
|
220
|
-
url.should
|
|
217
|
+
url.should match_url("https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{CGI.escape @callback_url}")
|
|
221
218
|
end
|
|
222
219
|
|
|
223
220
|
it "generates a properly formatted OAuth code URL when a callback is given" do
|
|
224
221
|
callback = "foo.com"
|
|
225
222
|
url = @oauth.url_for_oauth_code(:callback => callback)
|
|
226
|
-
url.should
|
|
223
|
+
url.should match_url("https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}")
|
|
227
224
|
end
|
|
228
225
|
|
|
229
226
|
it "generates a properly formatted OAuth code URL when permissions are requested as a string" do
|
|
230
227
|
permissions = "publish_stream,read_stream"
|
|
231
228
|
url = @oauth.url_for_oauth_code(:permissions => permissions)
|
|
232
|
-
url.should
|
|
229
|
+
url.should match_url("https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&scope=#{CGI.escape permissions}&redirect_uri=#{CGI.escape @callback_url}")
|
|
233
230
|
end
|
|
234
231
|
|
|
235
232
|
it "generates a properly formatted OAuth code URL when permissions are requested as a string" do
|
|
236
233
|
permissions = ["publish_stream", "read_stream"]
|
|
237
234
|
url = @oauth.url_for_oauth_code(:permissions => permissions)
|
|
238
|
-
url.should
|
|
235
|
+
url.should match_url("https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&scope=#{CGI.escape permissions.join(",")}&redirect_uri=#{CGI.escape @callback_url}")
|
|
239
236
|
end
|
|
240
237
|
|
|
241
238
|
it "generates a properly formatted OAuth code URL when both permissions and callback are provided" do
|
|
242
239
|
permissions = "publish_stream,read_stream"
|
|
243
240
|
callback = "foo.com"
|
|
244
241
|
url = @oauth.url_for_oauth_code(:callback => callback, :permissions => permissions)
|
|
245
|
-
url.should
|
|
242
|
+
url.should match_url("https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&scope=#{CGI.escape permissions}&redirect_uri=#{CGI.escape callback}")
|
|
246
243
|
end
|
|
247
244
|
|
|
248
245
|
it "generates a properly formatted OAuth code URL when a display is given as a string" do
|
|
249
246
|
url = @oauth.url_for_oauth_code(:display => "page")
|
|
250
|
-
url.should
|
|
247
|
+
url.should match_url("https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&display=page&redirect_uri=#{CGI.escape @callback_url}")
|
|
251
248
|
end
|
|
252
249
|
|
|
253
250
|
it "raises an exception if no callback is given in initialization or the call" do
|
|
254
251
|
oauth2 = Koala::Facebook::OAuth.new(@app_id, @secret)
|
|
255
252
|
lambda { oauth2.url_for_oauth_code }.should raise_error(ArgumentError)
|
|
256
253
|
end
|
|
254
|
+
|
|
255
|
+
it "includes any additional options as URL parameters, appropriately escaped" do
|
|
256
|
+
params = {
|
|
257
|
+
:url => "http://foo.bar?c=2",
|
|
258
|
+
:email => "cdc@b.com"
|
|
259
|
+
}
|
|
260
|
+
url = @oauth.url_for_oauth_code(params)
|
|
261
|
+
params.each_pair do |key, value|
|
|
262
|
+
url.should =~ /[\&\?]#{key}=#{CGI.escape value}/
|
|
263
|
+
end
|
|
264
|
+
end
|
|
257
265
|
end
|
|
258
266
|
|
|
259
|
-
describe "
|
|
267
|
+
describe "#url_for_access_token" do
|
|
260
268
|
before :each do
|
|
261
269
|
# since we're just composing a URL here, we don't need to have a real code
|
|
262
270
|
@code ||= "test_code"
|
|
263
271
|
end
|
|
264
|
-
|
|
265
|
-
# url_for_access_token
|
|
272
|
+
|
|
266
273
|
it "generates a properly formatted OAuth token URL when provided a code" do
|
|
267
274
|
url = @oauth.url_for_access_token(@code)
|
|
268
|
-
url.should
|
|
275
|
+
url.should match_url("https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&code=#{@code}&client_secret=#{@secret}&redirect_uri=#{CGI.escape @callback_url}").should be_true
|
|
269
276
|
end
|
|
270
277
|
|
|
271
278
|
it "generates a properly formatted OAuth token URL when provided a callback" do
|
|
272
279
|
callback = "foo.com"
|
|
273
280
|
url = @oauth.url_for_access_token(@code, :callback => callback)
|
|
274
|
-
url.should
|
|
281
|
+
url.should match_url("https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&code=#{@code}&client_secret=#{@secret}&redirect_uri=#{CGI.escape callback}").should be_true
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
it "includes any additional options as URL parameters, appropriately escaped" do
|
|
285
|
+
params = {
|
|
286
|
+
:url => "http://foo.bar?c=2",
|
|
287
|
+
:email => "cdc@b.com"
|
|
288
|
+
}
|
|
289
|
+
url = @oauth.url_for_access_token(@code, params)
|
|
290
|
+
params.each_pair do |key, value|
|
|
291
|
+
url.should =~ /[\&\?]#{key}=#{CGI.escape value}/
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
describe "#url_for_dialog" do
|
|
297
|
+
it "builds the base properly" do
|
|
298
|
+
dialog_type = "my_dialog_type"
|
|
299
|
+
@oauth.url_for_dialog(dialog_type).should =~ /^http:\/\/#{Koala::Facebook::DIALOG_HOST}\/dialog\/#{dialog_type}/
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it "adds the app_id/client_id to the url" do
|
|
303
|
+
automatic_params = {:app_id => @app_id, :client_id => @client_id}
|
|
304
|
+
url = @oauth.url_for_dialog("foo", automatic_params)
|
|
305
|
+
automatic_params.each_pair do |key, value|
|
|
306
|
+
# we're slightly simplifying how encode_params works, but for strings/ints, it's okay
|
|
307
|
+
url.should =~ /[\&\?]#{key}=#{CGI.escape value.to_s}/
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
it "includes any additional options as URL parameters, appropriately escaped" do
|
|
312
|
+
params = {
|
|
313
|
+
:url => "http://foo.bar?c=2",
|
|
314
|
+
:email => "cdc@b.com"
|
|
315
|
+
}
|
|
316
|
+
url = @oauth.url_for_dialog("friends", params)
|
|
317
|
+
params.each_pair do |key, value|
|
|
318
|
+
# we're slightly simplifying how encode_params works, but strings/ints, it's okay
|
|
319
|
+
url.should =~ /[\&\?]#{key}=#{CGI.escape value.to_s}/
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
describe "real examples from FB documentation" do
|
|
324
|
+
# see http://developers.facebook.com/docs/reference/dialogs/
|
|
325
|
+
# slightly brittle (e.g. if parameter order changes), but still useful
|
|
326
|
+
it "can generate a send dialog" do
|
|
327
|
+
url = @oauth.url_for_dialog("send", :name => "People Argue Just to Win", :link => "http://www.nytimes.com/2011/06/15/arts/people-argue-just-to-win-scholars-assert.html")
|
|
328
|
+
url.should match_url("http://www.facebook.com/dialog/send?app_id=#{@app_id}&client_id=#{@app_id}&link=http%3A%2F%2Fwww.nytimes.com%2F2011%2F06%2F15%2Farts%2Fpeople-argue-just-to-win-scholars-assert.html&name=People+Argue+Just+to+Win&redirect_uri=#{CGI.escape @callback_url}")
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
it "can generate a feed dialog" do
|
|
332
|
+
url = @oauth.url_for_dialog("feed", :name => "People Argue Just to Win", :link => "http://www.nytimes.com/2011/06/15/arts/people-argue-just-to-win-scholars-assert.html")
|
|
333
|
+
url.should match_url("http://www.facebook.com/dialog/feed?app_id=#{@app_id}&client_id=#{@app_id}&link=http%3A%2F%2Fwww.nytimes.com%2F2011%2F06%2F15%2Farts%2Fpeople-argue-just-to-win-scholars-assert.html&name=People+Argue+Just+to+Win&redirect_uri=#{CGI.escape @callback_url}")
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it "can generate a oauth dialog" do
|
|
337
|
+
url = @oauth.url_for_dialog("oauth", :scope => "email", :response_type => "token")
|
|
338
|
+
url.should match_url("http://www.facebook.com/dialog/oauth?app_id=#{@app_id}&client_id=#{@app_id}&redirect_uri=#{CGI.escape @callback_url}&response_type=token&scope=email")
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it "can generate a pay dialog" do
|
|
342
|
+
url = @oauth.url_for_dialog("pay", :order_id => "foo", :credits_purchase => false)
|
|
343
|
+
url.should match_url("http://www.facebook.com/dialog/pay?app_id=#{@app_id}&client_id=#{@app_id}&order_id=foo&credits_purchase=false&redirect_uri=#{CGI.escape @callback_url}")
|
|
344
|
+
end
|
|
275
345
|
end
|
|
276
346
|
end
|
|
277
347
|
end
|
|
278
348
|
|
|
279
349
|
describe "for fetching access tokens" do
|
|
280
|
-
describe "
|
|
350
|
+
describe "#get_access_token_info" do
|
|
281
351
|
it "uses options[:redirect_uri] if provided" do
|
|
282
352
|
uri = "foo"
|
|
283
|
-
Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => uri), anything, anything).and_return(Koala::Response.new(200, "", {}))
|
|
353
|
+
Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => uri), anything, anything).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
284
354
|
@oauth.get_access_token_info(@code, :redirect_uri => uri)
|
|
285
355
|
end
|
|
286
356
|
|
|
287
357
|
it "uses the redirect_uri used to create the @oauth if no :redirect_uri option is provided" do
|
|
288
|
-
Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => @callback_url), anything, anything).and_return(Koala::Response.new(200, "", {}))
|
|
358
|
+
Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => @callback_url), anything, anything).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
289
359
|
@oauth.get_access_token_info(@code)
|
|
290
360
|
end
|
|
291
361
|
|
|
292
362
|
it "makes a GET request" do
|
|
293
|
-
Koala.should_receive(:make_request).with(anything, anything, "get", anything).and_return(Koala::Response.new(200, "", {}))
|
|
363
|
+
Koala.should_receive(:make_request).with(anything, anything, "get", anything).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
294
364
|
@oauth.get_access_token_info(@code)
|
|
295
365
|
end
|
|
296
366
|
|
|
@@ -311,11 +381,11 @@ describe "Koala::Facebook::OAuth" do
|
|
|
311
381
|
end
|
|
312
382
|
end
|
|
313
383
|
|
|
314
|
-
describe "
|
|
384
|
+
describe "#get_access_token" do
|
|
315
385
|
# TODO refactor these to be proper tests with stubs and tests against real data
|
|
316
386
|
it "passes on any options provided to make_request" do
|
|
317
387
|
options = {:a => 2}
|
|
318
|
-
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
|
|
388
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
319
389
|
@oauth.get_access_token(@code, options)
|
|
320
390
|
end
|
|
321
391
|
|
|
@@ -354,7 +424,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
354
424
|
|
|
355
425
|
it "passes on any options provided to make_request" do
|
|
356
426
|
options = {:a => 2}
|
|
357
|
-
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
|
|
427
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
358
428
|
@oauth.get_app_access_token_info(options)
|
|
359
429
|
end
|
|
360
430
|
end
|
|
@@ -373,7 +443,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
373
443
|
|
|
374
444
|
it "passes on any options provided to make_request" do
|
|
375
445
|
options = {:a => 2}
|
|
376
|
-
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
|
|
446
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
377
447
|
@oauth.get_app_access_token(options)
|
|
378
448
|
end
|
|
379
449
|
end
|
|
@@ -454,7 +524,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
454
524
|
|
|
455
525
|
it "passes on any options provided to make_request" do
|
|
456
526
|
options = {:a => 2}
|
|
457
|
-
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "[{}]", {}))
|
|
527
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::HTTPService::Response.new(200, "[{}]", {}))
|
|
458
528
|
@oauth.get_token_info_from_session_keys([], options)
|
|
459
529
|
end
|
|
460
530
|
end
|
|
@@ -486,7 +556,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
486
556
|
|
|
487
557
|
it "passes on any options provided to make_request" do
|
|
488
558
|
options = {:a => 2}
|
|
489
|
-
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "[{}]", {}))
|
|
559
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::HTTPService::Response.new(200, "[{}]", {}))
|
|
490
560
|
@oauth.get_tokens_from_session_keys([], options)
|
|
491
561
|
end
|
|
492
562
|
end
|
|
@@ -516,7 +586,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
516
586
|
|
|
517
587
|
it "passes on any options provided to make_request" do
|
|
518
588
|
options = {:a => 2}
|
|
519
|
-
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "[{}]", {}))
|
|
589
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::HTTPService::Response.new(200, "[{}]", {}))
|
|
520
590
|
@oauth.get_token_from_session_key("", options)
|
|
521
591
|
end
|
|
522
592
|
end
|
|
@@ -24,33 +24,37 @@ describe "Koala::Facebook::RealtimeUpdates" do
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
before :each do
|
|
28
|
+
@updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe ".new" do
|
|
28
32
|
# basic initialization
|
|
29
|
-
it "
|
|
33
|
+
it "initializes properly with an app_id and an app_access_token" do
|
|
30
34
|
updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
|
|
31
35
|
updates.should be_a(Koala::Facebook::RealtimeUpdates)
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
# attributes
|
|
35
|
-
it "
|
|
39
|
+
it "allows read access to app_id" do
|
|
36
40
|
# in Ruby 1.9, .method returns symbols
|
|
37
41
|
Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:app_id)
|
|
38
42
|
Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:app_id=)
|
|
39
43
|
end
|
|
40
44
|
|
|
41
|
-
it "
|
|
45
|
+
it "allows read access to app_access_token" do
|
|
42
46
|
# in Ruby 1.9, .method returns symbols
|
|
43
47
|
Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:app_access_token)
|
|
44
48
|
Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:app_access_token=)
|
|
45
49
|
end
|
|
46
50
|
|
|
47
|
-
it "
|
|
51
|
+
it "allows read access to secret" do
|
|
48
52
|
# in Ruby 1.9, .method returns symbols
|
|
49
53
|
Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:secret)
|
|
50
54
|
Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:secret=)
|
|
51
55
|
end
|
|
52
56
|
|
|
53
|
-
it "
|
|
57
|
+
it "allows read access to api" do
|
|
54
58
|
# in Ruby 1.9, .method returns symbols
|
|
55
59
|
Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:api)
|
|
56
60
|
Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:api=)
|
|
@@ -69,72 +73,178 @@ describe "Koala::Facebook::RealtimeUpdates" do
|
|
|
69
73
|
end
|
|
70
74
|
|
|
71
75
|
# init with secret / fetching the token
|
|
72
|
-
it "
|
|
76
|
+
it "initializes properly with an app_id and a secret" do
|
|
73
77
|
updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
|
|
74
78
|
updates.should be_a(Koala::Facebook::RealtimeUpdates)
|
|
75
79
|
end
|
|
76
80
|
|
|
77
|
-
it "
|
|
81
|
+
it "fetches an app_token from Facebook when provided an app_id and a secret" do
|
|
78
82
|
updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
|
|
79
83
|
updates.app_access_token.should_not be_nil
|
|
80
84
|
end
|
|
81
|
-
|
|
82
|
-
it "
|
|
85
|
+
|
|
86
|
+
it "uses the OAuth class to fetch a token when provided an app_id and a secret" do
|
|
83
87
|
oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
|
|
84
88
|
token = oauth.get_app_access_token
|
|
85
89
|
oauth.should_receive(:get_app_access_token).and_return(token)
|
|
86
90
|
Koala::Facebook::OAuth.should_receive(:new).with(@app_id, @secret).and_return(oauth)
|
|
87
91
|
updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
|
|
88
92
|
end
|
|
93
|
+
|
|
94
|
+
it "sets up the with the app acces token" do
|
|
95
|
+
updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
|
|
96
|
+
updates.api.should be_a(Koala::Facebook::API)
|
|
97
|
+
updates.api.access_token.should == @app_access_token
|
|
98
|
+
end
|
|
99
|
+
|
|
89
100
|
end
|
|
90
101
|
|
|
91
|
-
describe "
|
|
92
|
-
|
|
93
|
-
@updates
|
|
102
|
+
describe "#subscribe" do
|
|
103
|
+
it "makes a POST to the subscription path" do
|
|
104
|
+
@updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "post", anything)
|
|
105
|
+
@updates.subscribe("user", "name", @subscription_path, @verify_token)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "properly formats the subscription request" do
|
|
109
|
+
obj = "user"
|
|
110
|
+
fields = "name"
|
|
111
|
+
@updates.api.should_receive(:graph_call).with(anything, hash_including(
|
|
112
|
+
:object => obj,
|
|
113
|
+
:fields => fields,
|
|
114
|
+
:callback_url => @subscription_path,
|
|
115
|
+
:verify_token => @verify_token
|
|
116
|
+
), anything, anything)
|
|
117
|
+
@updates.subscribe("user", "name", @subscription_path, @verify_token)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
pending "doesn't require a verify_token" do
|
|
121
|
+
# see https://github.com/arsduo/koala/issues/150
|
|
122
|
+
obj = "user"
|
|
123
|
+
fields = "name"
|
|
124
|
+
@updates.api.should_not_receive(:graph_call).with(anything, hash_including(:verify_token => anything), anything, anything)
|
|
125
|
+
@updates.subscribe("user", "name", @subscription_path)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "requires verify_token" do
|
|
129
|
+
expect { @updates.subscribe("user", "name", @subscription_path) }.to raise_exception
|
|
94
130
|
end
|
|
95
131
|
|
|
96
|
-
it "
|
|
97
|
-
|
|
98
|
-
|
|
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)
|
|
99
135
|
end
|
|
100
136
|
|
|
101
|
-
it "
|
|
102
|
-
|
|
103
|
-
|
|
137
|
+
it "accepts an options hash" do
|
|
138
|
+
options = {:a => 2, :b => "c"}
|
|
139
|
+
@updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
|
|
140
|
+
@updates.subscribe("user", "name", @subscription_path, @verify_token, options)
|
|
104
141
|
end
|
|
105
142
|
|
|
106
|
-
it "
|
|
107
|
-
|
|
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)
|
|
108
148
|
end
|
|
149
|
+
|
|
150
|
+
describe "in practice" do
|
|
151
|
+
it "sends a subscription request" do
|
|
152
|
+
result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
|
|
153
|
+
result.should be_true
|
|
154
|
+
end
|
|
109
155
|
|
|
110
|
-
|
|
111
|
-
|
|
156
|
+
pending "sends a subscription request without a verify token" do
|
|
157
|
+
result = @updates.subscribe("user", "name", @subscription_path)
|
|
158
|
+
result.should be_true
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "fails if you try to hit an invalid path on your valid server" do
|
|
162
|
+
expect { result = @updates.subscribe("user", "name", @subscription_path + "foo", @verify_token) }.to raise_exception(Koala::Facebook::APIError)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "fails to send a subscription request to an invalid server" do
|
|
166
|
+
expect { @updates.subscribe("user", "name", "foo", @verify_token) }.to raise_exception(Koala::Facebook::APIError)
|
|
167
|
+
end
|
|
112
168
|
end
|
|
169
|
+
end
|
|
113
170
|
|
|
114
|
-
|
|
115
|
-
|
|
171
|
+
describe "#unsubscribe" do
|
|
172
|
+
it "makes a DELETE to the subscription path" do
|
|
173
|
+
@updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "delete", anything)
|
|
174
|
+
@updates.unsubscribe("user")
|
|
116
175
|
end
|
|
117
176
|
|
|
118
|
-
it "
|
|
119
|
-
|
|
177
|
+
it "includes the object if provided" do
|
|
178
|
+
obj = "user"
|
|
179
|
+
@updates.api.should_receive(:graph_call).with(anything, hash_including(:object => obj), anything, anything)
|
|
180
|
+
@updates.unsubscribe(obj)
|
|
120
181
|
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
|
+
|
|
188
|
+
it "accepts an options hash" do
|
|
189
|
+
options = {:a => 2, :b => "C"}
|
|
190
|
+
@updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
|
|
191
|
+
@updates.unsubscribe("user", options)
|
|
192
|
+
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
|
+
|
|
201
|
+
describe "in practice" do
|
|
202
|
+
it "unsubscribes a valid individual object successfully" do
|
|
203
|
+
@updates.unsubscribe("user").should be_true
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "unsubscribes all subscriptions successfully" do
|
|
207
|
+
@updates.unsubscribe.should be_true
|
|
208
|
+
end
|
|
121
209
|
|
|
122
|
-
|
|
123
|
-
|
|
210
|
+
it "fails when an invalid object is provided to unsubscribe" do
|
|
211
|
+
expect { @updates.unsubscribe("kittens") }.to raise_error(Koala::Facebook::APIError)
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
describe "#list_subscriptions" do
|
|
217
|
+
it "GETs the subscription path" do
|
|
218
|
+
@updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "get", anything)
|
|
219
|
+
@updates.list_subscriptions
|
|
124
220
|
end
|
|
125
221
|
|
|
126
|
-
it "
|
|
127
|
-
|
|
222
|
+
it "accepts options" do
|
|
223
|
+
options = {:a => 3, :b => "D"}
|
|
224
|
+
@updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
|
|
225
|
+
@updates.list_subscriptions(options)
|
|
128
226
|
end
|
|
129
|
-
|
|
227
|
+
|
|
228
|
+
describe "in practice" do
|
|
229
|
+
it "lists subscriptions properly" do
|
|
230
|
+
@updates.list_subscriptions.should be_a(Array)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
describe "#subscription_path" do
|
|
236
|
+
it "returns the app_id/subscriptions" do
|
|
237
|
+
@updates.subscription_path.should == "#{@app_id}/subscriptions"
|
|
238
|
+
end
|
|
239
|
+
end
|
|
130
240
|
|
|
131
|
-
describe "
|
|
132
|
-
it "
|
|
241
|
+
describe ".meet_challenge" do
|
|
242
|
+
it "returns false if hub.mode isn't subscribe" do
|
|
133
243
|
params = {'hub.mode' => 'not subscribe'}
|
|
134
244
|
Koala::Facebook::RealtimeUpdates.meet_challenge(params).should be_false
|
|
135
245
|
end
|
|
136
246
|
|
|
137
|
-
it "
|
|
247
|
+
it "returns false if not given a verify_token or block" do
|
|
138
248
|
params = {'hub.mode' => 'subscribe'}
|
|
139
249
|
Koala::Facebook::RealtimeUpdates.meet_challenge(params).should be_false
|
|
140
250
|
end
|
|
@@ -150,11 +260,11 @@ describe "Koala::Facebook::RealtimeUpdates" do
|
|
|
150
260
|
@params['hub.verify_token'] = @token
|
|
151
261
|
end
|
|
152
262
|
|
|
153
|
-
it "
|
|
263
|
+
it "returns false if the given verify token doesn't match" do
|
|
154
264
|
Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token + '1').should be_false
|
|
155
265
|
end
|
|
156
266
|
|
|
157
|
-
it "
|
|
267
|
+
it "returns the challenge if the given verify token matches" do
|
|
158
268
|
@params['hub.challenge'] = 'challenge val'
|
|
159
269
|
Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token).should == @params['hub.challenge']
|
|
160
270
|
end
|
|
@@ -165,34 +275,31 @@ describe "Koala::Facebook::RealtimeUpdates" do
|
|
|
165
275
|
@params['hub.verify_token'] = @token
|
|
166
276
|
end
|
|
167
277
|
|
|
168
|
-
it "
|
|
278
|
+
it "gives the block the token as a parameter" do
|
|
169
279
|
Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
|
|
170
280
|
token.should == @token
|
|
171
281
|
end
|
|
172
282
|
end
|
|
173
283
|
|
|
174
|
-
it "
|
|
284
|
+
it "returns false if the given block return false" do
|
|
175
285
|
Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
|
|
176
286
|
false
|
|
177
287
|
end.should be_false
|
|
178
288
|
end
|
|
179
289
|
|
|
180
|
-
it "
|
|
290
|
+
it "returns false if the given block returns nil" do
|
|
181
291
|
Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
|
|
182
292
|
nil
|
|
183
293
|
end.should be_false
|
|
184
294
|
end
|
|
185
295
|
|
|
186
|
-
it "
|
|
296
|
+
it "returns the challenge if the given block returns true" do
|
|
187
297
|
@params['hub.challenge'] = 'challenge val'
|
|
188
298
|
Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
|
|
189
299
|
true
|
|
190
300
|
end.should be_true
|
|
191
301
|
end
|
|
192
302
|
end
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
end # describe "when meeting challenge"
|
|
197
|
-
|
|
198
|
-
end # describe
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|