koala 1.3.0 → 1.4.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/.travis.yml +6 -9
- data/CHANGELOG +15 -1
- data/Gemfile +3 -4
- data/koala.gemspec +1 -2
- data/lib/koala/api/graph_api.rb +57 -53
- data/lib/koala/http_service.rb +2 -2
- data/lib/koala/oauth.rb +63 -36
- data/lib/koala/realtime_updates.rb +2 -2
- data/lib/koala/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/cases/graph_api_batch_spec.rb +19 -19
- data/spec/cases/http_service_spec.rb +7 -0
- data/spec/cases/koala_test_spec.rb +5 -0
- data/spec/cases/oauth_spec.rb +72 -32
- data/spec/cases/realtime_updates_spec.rb +7 -0
- data/spec/fixtures/facebook_data.yml +1 -1
- data/spec/fixtures/mock_facebook_responses.yml +12 -3
- data/spec/support/graph_api_shared_examples.rb +19 -21
- data/spec/support/mock_http_service.rb +1 -1
- metadata +14 -12
data/spec/cases/oauth_spec.rb
CHANGED
|
@@ -7,6 +7,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
7
7
|
@secret = KoalaTest.secret
|
|
8
8
|
@code = KoalaTest.code
|
|
9
9
|
@callback_url = KoalaTest.oauth_test_data["callback_url"]
|
|
10
|
+
@access_token = KoalaTest.oauth_test_data["access_token"]
|
|
10
11
|
@raw_token_string = KoalaTest.oauth_test_data["raw_token_string"]
|
|
11
12
|
@raw_offline_access_token_string = KoalaTest.oauth_test_data["raw_offline_access_token_string"]
|
|
12
13
|
|
|
@@ -61,7 +62,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
61
62
|
@token = "my token"
|
|
62
63
|
@oauth.stub(:get_access_token_info).and_return("access_token" => @token)
|
|
63
64
|
end
|
|
64
|
-
|
|
65
|
+
|
|
65
66
|
it "parses valid cookies" do
|
|
66
67
|
result = @oauth.get_user_info_from_cookies(@cookie)
|
|
67
68
|
result.should be_a(Hash)
|
|
@@ -71,9 +72,9 @@ describe "Koala::Facebook::OAuth" do
|
|
|
71
72
|
result = @oauth.get_user_info_from_cookies(@cookie)
|
|
72
73
|
@oauth.parse_signed_request(@cookie.values.first).each_pair do |k, v|
|
|
73
74
|
result[k].should == v
|
|
74
|
-
end
|
|
75
|
+
end
|
|
75
76
|
end
|
|
76
|
-
|
|
77
|
+
|
|
77
78
|
it "makes a request to Facebook to redeem the code if present" do
|
|
78
79
|
code = "foo"
|
|
79
80
|
@oauth.stub(:parse_signed_request).and_return({"code" => code})
|
|
@@ -98,12 +99,12 @@ describe "Koala::Facebook::OAuth" do
|
|
|
98
99
|
@oauth.get_user_info_from_cookies(@cookie).should be_nil
|
|
99
100
|
end
|
|
100
101
|
end
|
|
101
|
-
|
|
102
|
+
|
|
102
103
|
context "if the code is present" do
|
|
103
104
|
it "adds the access_token into the hash" do
|
|
104
105
|
@oauth.get_user_info_from_cookies(@cookie)["access_token"].should == @token
|
|
105
106
|
end
|
|
106
|
-
|
|
107
|
+
|
|
107
108
|
it "returns nil if the call to FB returns no data" do
|
|
108
109
|
@oauth.stub(:get_access_token_info).and_return(nil)
|
|
109
110
|
@oauth.get_user_info_from_cookies(@cookie).should be_nil
|
|
@@ -125,7 +126,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
125
126
|
expect { @oauth.get_user_info_from_cookies(@cookie) }.to raise_exception(Koala::Facebook::APIError)
|
|
126
127
|
end
|
|
127
128
|
end
|
|
128
|
-
|
|
129
|
+
|
|
129
130
|
it "doesn't parse invalid cookies" do
|
|
130
131
|
# make an invalid string by replacing some values
|
|
131
132
|
bad_cookie_hash = @cookie.inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
|
|
@@ -133,7 +134,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
133
134
|
result.should be_nil
|
|
134
135
|
end
|
|
135
136
|
end
|
|
136
|
-
|
|
137
|
+
|
|
137
138
|
context "for unsigned cookies" do
|
|
138
139
|
it "properly parses valid cookies" do
|
|
139
140
|
result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["valid_cookies"])
|
|
@@ -161,7 +162,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
161
162
|
|
|
162
163
|
it "doesn't parse expired cookies" do
|
|
163
164
|
new_time = @time.to_i * 2
|
|
164
|
-
@time.stub(:to_i).and_return(new_time)
|
|
165
|
+
@time.stub(:to_i).and_return(new_time)
|
|
165
166
|
@oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["valid_cookies"]).should be_nil
|
|
166
167
|
end
|
|
167
168
|
|
|
@@ -179,7 +180,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
179
180
|
before :each do
|
|
180
181
|
# we don't actually want to make requests to Facebook to redeem the code
|
|
181
182
|
@cookie = KoalaTest.oauth_test_data["valid_signed_cookies"]
|
|
182
|
-
@oauth.stub(:get_access_token_info).and_return("access_token" => "my token")
|
|
183
|
+
@oauth.stub(:get_access_token_info).and_return("access_token" => "my token")
|
|
183
184
|
end
|
|
184
185
|
|
|
185
186
|
it "does not uses get_user_info_from_cookies to parse the cookies" do
|
|
@@ -199,7 +200,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
199
200
|
result.should be_nil
|
|
200
201
|
end
|
|
201
202
|
end
|
|
202
|
-
|
|
203
|
+
|
|
203
204
|
describe "for unsigned cookies" do
|
|
204
205
|
before :each do
|
|
205
206
|
# we don't actually want to make requests to Facebook to redeem the code
|
|
@@ -267,14 +268,14 @@ describe "Koala::Facebook::OAuth" do
|
|
|
267
268
|
oauth2 = Koala::Facebook::OAuth.new(@app_id, @secret)
|
|
268
269
|
lambda { oauth2.url_for_oauth_code }.should raise_error(ArgumentError)
|
|
269
270
|
end
|
|
270
|
-
|
|
271
|
+
|
|
271
272
|
it "includes any additional options as URL parameters, appropriately escaped" do
|
|
272
273
|
params = {
|
|
273
274
|
:url => "http://foo.bar?c=2",
|
|
274
275
|
:email => "cdc@b.com"
|
|
275
276
|
}
|
|
276
277
|
url = @oauth.url_for_oauth_code(params)
|
|
277
|
-
params.each_pair do |key, value|
|
|
278
|
+
params.each_pair do |key, value|
|
|
278
279
|
url.should =~ /[\&\?]#{key}=#{CGI.escape value}/
|
|
279
280
|
end
|
|
280
281
|
end
|
|
@@ -285,7 +286,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
285
286
|
# since we're just composing a URL here, we don't need to have a real code
|
|
286
287
|
@code ||= "test_code"
|
|
287
288
|
end
|
|
288
|
-
|
|
289
|
+
|
|
289
290
|
it "generates a properly formatted OAuth token URL when provided a code" do
|
|
290
291
|
url = @oauth.url_for_access_token(@code)
|
|
291
292
|
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
|
|
@@ -303,18 +304,18 @@ describe "Koala::Facebook::OAuth" do
|
|
|
303
304
|
:email => "cdc@b.com"
|
|
304
305
|
}
|
|
305
306
|
url = @oauth.url_for_access_token(@code, params)
|
|
306
|
-
params.each_pair do |key, value|
|
|
307
|
+
params.each_pair do |key, value|
|
|
307
308
|
url.should =~ /[\&\?]#{key}=#{CGI.escape value}/
|
|
308
309
|
end
|
|
309
310
|
end
|
|
310
311
|
end
|
|
311
|
-
|
|
312
|
+
|
|
312
313
|
describe "#url_for_dialog" do
|
|
313
314
|
it "builds the base properly" do
|
|
314
315
|
dialog_type = "my_dialog_type"
|
|
315
316
|
@oauth.url_for_dialog(dialog_type).should =~ /^http:\/\/#{Koala::Facebook::DIALOG_HOST}\/dialog\/#{dialog_type}/
|
|
316
317
|
end
|
|
317
|
-
|
|
318
|
+
|
|
318
319
|
it "adds the app_id/client_id to the url" do
|
|
319
320
|
automatic_params = {:app_id => @app_id, :client_id => @client_id}
|
|
320
321
|
url = @oauth.url_for_dialog("foo", automatic_params)
|
|
@@ -323,19 +324,19 @@ describe "Koala::Facebook::OAuth" do
|
|
|
323
324
|
url.should =~ /[\&\?]#{key}=#{CGI.escape value.to_s}/
|
|
324
325
|
end
|
|
325
326
|
end
|
|
326
|
-
|
|
327
|
+
|
|
327
328
|
it "includes any additional options as URL parameters, appropriately escaped" do
|
|
328
329
|
params = {
|
|
329
330
|
:url => "http://foo.bar?c=2",
|
|
330
331
|
:email => "cdc@b.com"
|
|
331
332
|
}
|
|
332
333
|
url = @oauth.url_for_dialog("friends", params)
|
|
333
|
-
params.each_pair do |key, value|
|
|
334
|
+
params.each_pair do |key, value|
|
|
334
335
|
# we're slightly simplifying how encode_params works, but strings/ints, it's okay
|
|
335
336
|
url.should =~ /[\&\?]#{key}=#{CGI.escape value.to_s}/
|
|
336
337
|
end
|
|
337
338
|
end
|
|
338
|
-
|
|
339
|
+
|
|
339
340
|
describe "real examples from FB documentation" do
|
|
340
341
|
# see http://developers.facebook.com/docs/reference/dialogs/
|
|
341
342
|
# slightly brittle (e.g. if parameter order changes), but still useful
|
|
@@ -343,17 +344,17 @@ describe "Koala::Facebook::OAuth" do
|
|
|
343
344
|
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")
|
|
344
345
|
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}")
|
|
345
346
|
end
|
|
346
|
-
|
|
347
|
+
|
|
347
348
|
it "can generate a feed dialog" do
|
|
348
349
|
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")
|
|
349
350
|
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}")
|
|
350
351
|
end
|
|
351
|
-
|
|
352
|
+
|
|
352
353
|
it "can generate a oauth dialog" do
|
|
353
354
|
url = @oauth.url_for_dialog("oauth", :scope => "email", :response_type => "token")
|
|
354
355
|
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")
|
|
355
356
|
end
|
|
356
|
-
|
|
357
|
+
|
|
357
358
|
it "can generate a pay dialog" do
|
|
358
359
|
url = @oauth.url_for_dialog("pay", :order_id => "foo", :credits_purchase => false)
|
|
359
360
|
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}")
|
|
@@ -369,15 +370,15 @@ describe "Koala::Facebook::OAuth" do
|
|
|
369
370
|
Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => uri), anything, anything).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
370
371
|
@oauth.get_access_token_info(@code, :redirect_uri => uri)
|
|
371
372
|
end
|
|
372
|
-
|
|
373
|
+
|
|
373
374
|
it "uses the redirect_uri used to create the @oauth if no :redirect_uri option is provided" do
|
|
374
375
|
Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => @callback_url), anything, anything).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
375
|
-
@oauth.get_access_token_info(@code)
|
|
376
|
+
@oauth.get_access_token_info(@code)
|
|
376
377
|
end
|
|
377
|
-
|
|
378
|
+
|
|
378
379
|
it "makes a GET request" do
|
|
379
380
|
Koala.should_receive(:make_request).with(anything, anything, "get", anything).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
380
|
-
@oauth.get_access_token_info(@code)
|
|
381
|
+
@oauth.get_access_token_info(@code)
|
|
381
382
|
end
|
|
382
383
|
|
|
383
384
|
if KoalaTest.code
|
|
@@ -390,13 +391,13 @@ describe "Koala::Facebook::OAuth" do
|
|
|
390
391
|
result = @oauth.get_access_token_info(@code)
|
|
391
392
|
result["access_token"].should
|
|
392
393
|
end
|
|
393
|
-
|
|
394
|
+
|
|
394
395
|
it "raises an error when get_access_token is called with a bad code" do
|
|
395
396
|
lambda { @oauth.get_access_token_info("foo") }.should raise_error(Koala::Facebook::APIError)
|
|
396
397
|
end
|
|
397
398
|
end
|
|
398
399
|
end
|
|
399
|
-
|
|
400
|
+
|
|
400
401
|
describe "#get_access_token" do
|
|
401
402
|
# TODO refactor these to be proper tests with stubs and tests against real data
|
|
402
403
|
it "passes on any options provided to make_request" do
|
|
@@ -422,7 +423,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
422
423
|
end
|
|
423
424
|
end
|
|
424
425
|
end
|
|
425
|
-
|
|
426
|
+
|
|
426
427
|
unless KoalaTest.code
|
|
427
428
|
it "Some OAuth code tests will not be run since the code field in facebook_data.yml is blank."
|
|
428
429
|
end
|
|
@@ -445,7 +446,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
445
446
|
end
|
|
446
447
|
end
|
|
447
448
|
|
|
448
|
-
describe "
|
|
449
|
+
describe "get_app_access_token" do
|
|
449
450
|
it "uses get_access_token_info to get and parse an access token token results" do
|
|
450
451
|
result = @oauth.get_app_access_token
|
|
451
452
|
result.should be_a(String)
|
|
@@ -464,8 +465,47 @@ describe "Koala::Facebook::OAuth" do
|
|
|
464
465
|
end
|
|
465
466
|
end
|
|
466
467
|
|
|
467
|
-
describe "
|
|
468
|
+
describe "exchange_access_token_info" do
|
|
469
|
+
if KoalaTest.mock_interface? || KoalaTest.oauth_token
|
|
470
|
+
it "properly gets and parses an app's access token as a hash" do
|
|
471
|
+
result = @oauth.exchange_access_token_info(KoalaTest.oauth_token)
|
|
472
|
+
result.should be_a(Hash)
|
|
473
|
+
end
|
|
468
474
|
|
|
475
|
+
it "includes the access token" do
|
|
476
|
+
result = @oauth.exchange_access_token_info(KoalaTest.oauth_token)
|
|
477
|
+
result["access_token"].should
|
|
478
|
+
end
|
|
479
|
+
else
|
|
480
|
+
pending "Some OAuth token exchange tests will not be run since the access token field in facebook_data.yml is blank."
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
it "passes on any options provided to make_request" do
|
|
484
|
+
options = {:a => 2}
|
|
485
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
486
|
+
@oauth.exchange_access_token_info(KoalaTest.oauth_token, options)
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
it "raises an error when exchange_access_token_info is called with a bad code" do
|
|
490
|
+
lambda { @oauth.exchange_access_token_info("foo") }.should raise_error(Koala::Facebook::APIError)
|
|
491
|
+
end
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
describe "exchange_access_token" do
|
|
495
|
+
it "uses get_access_token_info to get and parse an access token token results" do
|
|
496
|
+
hash = {"access_token" => Time.now.to_i * rand}
|
|
497
|
+
@oauth.stub(:exchange_access_token_info).and_return(hash)
|
|
498
|
+
@oauth.exchange_access_token(KoalaTest.oauth_token).should == hash["access_token"]
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
it "passes on any options provided to make_request" do
|
|
502
|
+
options = {:a => 2}
|
|
503
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::HTTPService::Response.new(200, "", {}))
|
|
504
|
+
@oauth.exchange_access_token(KoalaTest.oauth_token, options)
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
describe "protected methods" do
|
|
469
509
|
# protected methods
|
|
470
510
|
# since these are pretty fundamental and pretty testable, we want to test them
|
|
471
511
|
|
|
@@ -623,7 +663,7 @@ describe "Koala::Facebook::OAuth" do
|
|
|
623
663
|
OpenSSL::HMAC.stub!(:hexdigest).and_return("i'm an invalid signature")
|
|
624
664
|
lambda { @oauth.parse_signed_request(@signed_request) }.should raise_error
|
|
625
665
|
end
|
|
626
|
-
|
|
666
|
+
|
|
627
667
|
it "throws an error if the signature string is empty" do
|
|
628
668
|
# this occasionally happens due to Facebook error
|
|
629
669
|
lambda { @oauth.parse_signed_request("") }.should raise_error
|
|
@@ -243,6 +243,13 @@ describe "Koala::Facebook::RealtimeUpdates" do
|
|
|
243
243
|
params = {'hub.mode' => 'not subscribe'}
|
|
244
244
|
Koala::Facebook::RealtimeUpdates.meet_challenge(params).should be_false
|
|
245
245
|
end
|
|
246
|
+
|
|
247
|
+
it "doesn't evaluate the block if hub.mode isn't subscribe" do
|
|
248
|
+
params = {'hub.mode' => 'not subscribe'}
|
|
249
|
+
block_evaluated = false
|
|
250
|
+
Koala::Facebook::RealtimeUpdates.meet_challenge(params){|token| block_evaluated = true}
|
|
251
|
+
block_evaluated.should be_false
|
|
252
|
+
end
|
|
246
253
|
|
|
247
254
|
it "returns false if not given a verify_token or block" do
|
|
248
255
|
params = {'hub.mode' => 'subscribe'}
|
|
@@ -33,7 +33,7 @@ oauth_test_data:
|
|
|
33
33
|
offline_access_cookies:
|
|
34
34
|
# note: I've revoked the offline access for security reasons, so you can't make calls against this :)
|
|
35
35
|
fbs_119908831367602: '"access_token=119908831367602|08170230801eb225068e7a70-2905623|Q3LDCYYF8CX9cstxnZLsxiR0nwg.&expires=0&secret=78abaee300b392e275072a9f2727d436&session_key=08170230801eb225068e7a70-2905623&sig=423b8aa4b6fa1f9a571955f8e929d567&uid=2905623"'
|
|
36
|
-
valid_signed_cookies:
|
|
36
|
+
valid_signed_cookies:
|
|
37
37
|
"fbsr_119908831367602": "f1--LHwjHVCxfs97hRHL-4cF-0jNxZRc6MGzo1qHLb0.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiIyLkFRQm90a0pBWlhVY1l3RkMuMzYwMC4xMzE0ODEzNjAwLjEtMjkwNTYyM3x4V2xya0d0UmJIZlpIclRnVWwxQmxJcVhRbjQiLCJpc3N1ZWRfYXQiOjEzMTQ4MDY2NTUsInVzZXJfaWQiOiIyOTA1NjIzIn0"
|
|
38
38
|
|
|
39
39
|
|
|
@@ -80,7 +80,7 @@ graph_api:
|
|
|
80
80
|
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"me"}, {"method"=>"get", "relative_url"=>"#{OAUTH_DATA["app_id"]}/insights?access_token=#{CGI.escape APP_ACCESS_TOKEN}"}]) %>:
|
|
81
81
|
post:
|
|
82
82
|
with_token: '[{"body":"{\"id\":\"123\"}"}, {"body":"{\"data\":[],\"paging\":{}}"}]'
|
|
83
|
-
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"
|
|
83
|
+
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"2/invalidconnection"}, {"method"=>"get", "relative_url"=>"koppel?access_token=#{CGI.escape APP_ACCESS_TOKEN}"}]) %>:
|
|
84
84
|
post:
|
|
85
85
|
with_token: '[{"body": "{\"error\":{\"type\":\"AnError\", \"message\":\"An error occurred!.\"}}"},{"body":"{\"id\":\"123\"}"}]'
|
|
86
86
|
batch=<%= MultiJson.encode([{"method"=>"post", "relative_url"=>"FEED_ITEM_BATCH/likes"}, {"method"=>"delete", "relative_url"=> "FEED_ITEM_BATCH"}]) %>:
|
|
@@ -94,7 +94,7 @@ graph_api:
|
|
|
94
94
|
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"me", "name" => "getme"}, {"method"=>"get", "relative_url"=>"koppel", "depends_on" => "getme"}]) %>:
|
|
95
95
|
post:
|
|
96
96
|
with_token: '[null,{"body":"{\"id\":\"123\"}"}]'
|
|
97
|
-
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"
|
|
97
|
+
batch=<%= MultiJson.encode([{"method"=>"get", "relative_url"=>"2/invalidconnection", "name" => "getdata"}, {"method"=>"get", "relative_url"=>"koppel", "depends_on" => "getdata"}]) %>:
|
|
98
98
|
post:
|
|
99
99
|
with_token: '[{"body": "{\"error\":{\"type\":\"AnError\", \"message\":\"An error occurred!.\"}}"},null]'
|
|
100
100
|
batch=<%= MultiJson.encode([{"method" => "get", "relative_url" => "me/friends?limit=5", "name" => "get-friends"}, {"method" => "get", "relative_url" => "?ids=#{CGI.escape "{result=get-friends:$.data.*.id}"}"}]) %>:
|
|
@@ -149,6 +149,9 @@ graph_api:
|
|
|
149
149
|
message=Hello, world, from the test suite delete method!:
|
|
150
150
|
post:
|
|
151
151
|
with_token: '{"id": "FEED_ITEM_DELETE"}'
|
|
152
|
+
message=Hello, world, from the test suite delete like method!:
|
|
153
|
+
post:
|
|
154
|
+
with_token: '{"id": "FEED_ITEM_DELETE"}'
|
|
152
155
|
message=Hello, world, from the test suite batch API!:
|
|
153
156
|
post:
|
|
154
157
|
with_token: '{"id": "FEED_ITEM_BATCH"}'
|
|
@@ -157,7 +160,7 @@ graph_api:
|
|
|
157
160
|
with_token: '{"id": "FEED_ITEM_CONTEXT"}'
|
|
158
161
|
link=http://oauth.twoalex.com/&message=body&name=It's a big question&picture=http://oauth.twoalex.com//images/logo.png&properties=<%= {"name"=>"Link1'", "text"=>"Left", "href"=>"http://oauth.twoalex.com/"}.to_s %>=<%= {"name"=>"other", "text"=>"Straight ahead"}.to_s %>&type=link:
|
|
159
162
|
post:
|
|
160
|
-
with_token: '{"id": "FEED_ITEM_CONTEXT"}'
|
|
163
|
+
with_token: '{"id": "FEED_ITEM_CONTEXT"}'
|
|
161
164
|
|
|
162
165
|
/me/photos:
|
|
163
166
|
source=[FILE]:
|
|
@@ -308,6 +311,12 @@ graph_api:
|
|
|
308
311
|
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&type=client_cred:
|
|
309
312
|
post:
|
|
310
313
|
no_token: access_token=<%= APP_ACCESS_TOKEN %>
|
|
314
|
+
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&fb_exchange_token=<%= ACCESS_TOKEN %>&grant_type=fb_exchange_token:
|
|
315
|
+
post:
|
|
316
|
+
no_token: access_token=<%= ACCESS_TOKEN %>&expires=5184000
|
|
317
|
+
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&fb_exchange_token=foo&grant_type=fb_exchange_token:
|
|
318
|
+
post:
|
|
319
|
+
<<: *oauth_error
|
|
311
320
|
/oauth/exchange_sessions:
|
|
312
321
|
client_id=<%= APP_ID %>&client_secret=<%= SECRET %>&sessions=<%= OAUTH_DATA["session_key"] %>&type=client_cred:
|
|
313
322
|
post:
|
|
@@ -25,27 +25,27 @@ shared_examples_for "Koala GraphAPI" do
|
|
|
25
25
|
Koala.stub(:make_request).and_return(Koala::HTTPService::Response.new(500, {"error" => "An error occurred!"}, {}))
|
|
26
26
|
lambda { @api.graph_call(KoalaTest.user1, {}) }.should raise_exception(Koala::Facebook::APIError)
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
it "passes the results through GraphCollection.evaluate" do
|
|
30
30
|
result = {}
|
|
31
31
|
@api.stub(:api).and_return(result)
|
|
32
32
|
Koala::Facebook::GraphCollection.should_receive(:evaluate).with(result, @api)
|
|
33
33
|
@api.graph_call("/me")
|
|
34
34
|
end
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
it "returns the results of GraphCollection.evaluate" do
|
|
37
37
|
expected = {}
|
|
38
38
|
@api.stub(:api).and_return([])
|
|
39
39
|
Koala::Facebook::GraphCollection.should_receive(:evaluate).and_return(expected)
|
|
40
40
|
@api.graph_call("/me").should == expected
|
|
41
41
|
end
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
it "returns the post_processing block's results if one is supplied" do
|
|
44
44
|
other_result = [:a, 2, :three]
|
|
45
45
|
block = Proc.new {|r| other_result}
|
|
46
46
|
@api.stub(:api).and_return({})
|
|
47
47
|
@api.graph_call("/me", {}, "get", {}, &block).should == other_result
|
|
48
|
-
end
|
|
48
|
+
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
# SEARCH
|
|
@@ -121,15 +121,15 @@ shared_examples_for "Koala GraphAPI" do
|
|
|
121
121
|
@api.should_receive(:graph_call).with(*query)
|
|
122
122
|
@api.get_page(query)
|
|
123
123
|
end
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
# Beta tier
|
|
126
126
|
it "can use the beta tier" do
|
|
127
127
|
result = @api.get_object(KoalaTest.user1, {}, :beta => true)
|
|
128
128
|
# the results should have an ID and a name, among other things
|
|
129
129
|
(result["id"] && result["name"]).should_not be_nil
|
|
130
130
|
end
|
|
131
|
-
|
|
132
|
-
# FQL
|
|
131
|
+
|
|
132
|
+
# FQL
|
|
133
133
|
describe "#fql_query" do
|
|
134
134
|
it "makes a request to /fql" do
|
|
135
135
|
@api.should_receive(:get_object).with("fql", anything, anything)
|
|
@@ -225,7 +225,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
|
225
225
|
end
|
|
226
226
|
|
|
227
227
|
it "can delete likes" do
|
|
228
|
-
result = @api.put_wall_post("Hello, world, from the test suite delete method!")
|
|
228
|
+
result = @api.put_wall_post("Hello, world, from the test suite delete like method!")
|
|
229
229
|
@temporary_object_id = result["id"]
|
|
230
230
|
@api.put_like(@temporary_object_id)
|
|
231
231
|
delete_like_result = @api.delete_like(@temporary_object_id)
|
|
@@ -248,7 +248,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
|
248
248
|
@temporary_object_id = result["id"]
|
|
249
249
|
@temporary_object_id.should_not be_nil
|
|
250
250
|
end
|
|
251
|
-
|
|
251
|
+
|
|
252
252
|
it "can post a message whose attachment has a properties dictionary" do
|
|
253
253
|
url = KoalaTest.oauth_test_data["callback_url"]
|
|
254
254
|
options = {
|
|
@@ -259,14 +259,14 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
|
259
259
|
"properties" => [
|
|
260
260
|
{"name" => "Link1'", "text" => "Left", "href" => url},
|
|
261
261
|
{"name" => "other", "text" => "Straight ahead"}
|
|
262
|
-
]
|
|
262
|
+
]
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
result = @api.put_wall_post("body", options)
|
|
266
266
|
@temporary_object_id = result["id"]
|
|
267
267
|
@temporary_object_id.should_not be_nil
|
|
268
268
|
end
|
|
269
|
-
|
|
269
|
+
|
|
270
270
|
|
|
271
271
|
describe "#put_picture" do
|
|
272
272
|
it "can post photos to the user's wall with an open file object" do
|
|
@@ -403,13 +403,13 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
|
403
403
|
@api.should_receive(:api).with("my_page", hash_including({:fields => "access_token"}), "get", anything)
|
|
404
404
|
@api.get_page_access_token("my_page")
|
|
405
405
|
end
|
|
406
|
-
|
|
406
|
+
|
|
407
407
|
it "merges in any other arguments" do
|
|
408
408
|
# we can't test this live since test users (or random real users) can't be guaranteed to have pages to manage
|
|
409
409
|
args = {:a => 3}
|
|
410
410
|
@api.should_receive(:api).with("my_page", hash_including(args), "get", anything)
|
|
411
411
|
@api.get_page_access_token("my_page", args)
|
|
412
|
-
end
|
|
412
|
+
end
|
|
413
413
|
end
|
|
414
414
|
|
|
415
415
|
describe "#set_app_restrictions" do
|
|
@@ -424,32 +424,30 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
|
424
424
|
@app_api.should_receive(:graph_call).with(KoalaTest.app_id, anything, "post", anything)
|
|
425
425
|
@app_api.set_app_restrictions(KoalaTest.app_id, @restrictions)
|
|
426
426
|
end
|
|
427
|
-
|
|
427
|
+
|
|
428
428
|
it "JSON-encodes the restrictions" do
|
|
429
429
|
@app_api.should_receive(:graph_call).with(anything, hash_including(:restrictions => MultiJson.encode(@restrictions)), anything, anything)
|
|
430
430
|
@app_api.set_app_restrictions(KoalaTest.app_id, @restrictions)
|
|
431
431
|
end
|
|
432
|
-
|
|
432
|
+
|
|
433
433
|
it "includes the other arguments" do
|
|
434
434
|
args = {:a => 2}
|
|
435
435
|
@app_api.should_receive(:graph_call).with(anything, hash_including(args), anything, anything)
|
|
436
436
|
@app_api.set_app_restrictions(KoalaTest.app_id, @restrictions, args)
|
|
437
437
|
end
|
|
438
|
-
|
|
438
|
+
|
|
439
439
|
it "works" do
|
|
440
440
|
@app_api.set_app_restrictions(KoalaTest.app_id, @restrictions).should be_true
|
|
441
441
|
end
|
|
442
442
|
end
|
|
443
443
|
|
|
444
|
-
it "changes tests to first_name when FB repairs its bug"
|
|
445
|
-
|
|
446
444
|
it "can access public information via FQL" do
|
|
447
445
|
result = @api.fql_query("select uid, first_name from user where uid = #{KoalaTest.user2_id}")
|
|
448
446
|
result.size.should == 1
|
|
449
|
-
|
|
447
|
+
result.first['first_name'].should == KoalaTest.user2_name
|
|
450
448
|
result.first['uid'].should == KoalaTest.user2_id.to_i
|
|
451
449
|
end
|
|
452
|
-
|
|
450
|
+
|
|
453
451
|
it "can access public information via FQL.multiquery" do
|
|
454
452
|
result = @api.fql_multiquery(
|
|
455
453
|
:query1 => "select uid, first_name from user where uid = #{KoalaTest.user2_id}",
|
|
@@ -623,7 +621,7 @@ shared_examples_for "Koala GraphAPI without an access token" do
|
|
|
623
621
|
it "can't delete a like" do
|
|
624
622
|
lambda { @api.delete_like("7204941866_119776748033392") }.should raise_error(Koala::Facebook::APIError)
|
|
625
623
|
end
|
|
626
|
-
|
|
624
|
+
|
|
627
625
|
# FQL_QUERY
|
|
628
626
|
describe "when making a FQL request" do
|
|
629
627
|
it "can access public information via FQL" do
|
|
@@ -19,7 +19,7 @@ module Koala
|
|
|
19
19
|
TEST_DATA.merge!('oauth_token' => Koala::MockHTTPService::ACCESS_TOKEN)
|
|
20
20
|
TEST_DATA['oauth_test_data'].merge!('code' => Koala::MockHTTPService::OAUTH_CODE)
|
|
21
21
|
TEST_DATA['search_time'] = (Time.now - 3600).to_s
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
# Useful in mock_facebook_responses.yml
|
|
24
24
|
OAUTH_DATA = TEST_DATA['oauth_test_data']
|
|
25
25
|
OAUTH_DATA.merge!({
|
metadata
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: koala
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
|
-
- Alex Koppel
|
|
8
|
+
- Alex Koppel
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2012-03-11 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: multi_json
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &70104159239520 !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: *70104159239520
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
26
26
|
name: faraday
|
|
27
|
-
requirement: &
|
|
27
|
+
requirement: &70104159238080 !ruby/object:Gem::Requirement
|
|
28
28
|
none: false
|
|
29
29
|
requirements:
|
|
30
30
|
- - ~>
|
|
@@ -32,10 +32,10 @@ dependencies:
|
|
|
32
32
|
version: 0.7.0
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
35
|
+
version_requirements: *70104159238080
|
|
36
36
|
- !ruby/object:Gem::Dependency
|
|
37
37
|
name: rspec
|
|
38
|
-
requirement: &
|
|
38
|
+
requirement: &70104159236640 !ruby/object:Gem::Requirement
|
|
39
39
|
none: false
|
|
40
40
|
requirements:
|
|
41
41
|
- - ~>
|
|
@@ -43,10 +43,10 @@ dependencies:
|
|
|
43
43
|
version: 2.8.0rc1
|
|
44
44
|
type: :development
|
|
45
45
|
prerelease: false
|
|
46
|
-
version_requirements: *
|
|
46
|
+
version_requirements: *70104159236640
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
48
|
name: rake
|
|
49
|
-
requirement: &
|
|
49
|
+
requirement: &70104159224060 !ruby/object:Gem::Requirement
|
|
50
50
|
none: false
|
|
51
51
|
requirements:
|
|
52
52
|
- - ~>
|
|
@@ -54,7 +54,7 @@ dependencies:
|
|
|
54
54
|
version: 0.8.7
|
|
55
55
|
type: :development
|
|
56
56
|
prerelease: false
|
|
57
|
-
version_requirements: *
|
|
57
|
+
version_requirements: *70104159224060
|
|
58
58
|
description: Koala is a lightweight, flexible Ruby SDK for Facebook. It allows read/write
|
|
59
59
|
access to the social graph via the Graph and REST APIs, as well as support for realtime
|
|
60
60
|
updates and OAuth and Facebook Connect authentication. Koala is fully tested and
|
|
@@ -104,6 +104,7 @@ files:
|
|
|
104
104
|
- spec/cases/graph_collection_spec.rb
|
|
105
105
|
- spec/cases/http_service_spec.rb
|
|
106
106
|
- spec/cases/koala_spec.rb
|
|
107
|
+
- spec/cases/koala_test_spec.rb
|
|
107
108
|
- spec/cases/legacy_spec.rb
|
|
108
109
|
- spec/cases/multipart_request_spec.rb
|
|
109
110
|
- spec/cases/oauth_spec.rb
|
|
@@ -142,7 +143,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
142
143
|
version: '0'
|
|
143
144
|
segments:
|
|
144
145
|
- 0
|
|
145
|
-
hash:
|
|
146
|
+
hash: 3977306572275608217
|
|
146
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
148
|
none: false
|
|
148
149
|
requirements:
|
|
@@ -163,6 +164,7 @@ test_files:
|
|
|
163
164
|
- spec/cases/graph_collection_spec.rb
|
|
164
165
|
- spec/cases/http_service_spec.rb
|
|
165
166
|
- spec/cases/koala_spec.rb
|
|
167
|
+
- spec/cases/koala_test_spec.rb
|
|
166
168
|
- spec/cases/legacy_spec.rb
|
|
167
169
|
- spec/cases/multipart_request_spec.rb
|
|
168
170
|
- spec/cases/oauth_spec.rb
|