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.
Files changed (55) hide show
  1. data/.gitignore +3 -1
  2. data/.rspec +1 -0
  3. data/.travis.yml +4 -0
  4. data/.yardopts +3 -0
  5. data/CHANGELOG +25 -0
  6. data/Gemfile +14 -0
  7. data/Guardfile +6 -0
  8. data/koala.gemspec +3 -3
  9. data/lib/koala/api/batch_operation.rb +83 -0
  10. data/lib/koala/api/graph_api.rb +476 -0
  11. data/lib/koala/{graph_batch_api.rb → api/graph_batch_api.rb} +22 -17
  12. data/lib/koala/api/graph_collection.rb +107 -0
  13. data/lib/koala/api/legacy.rb +26 -0
  14. data/lib/koala/{rest_api.rb → api/rest_api.rb} +32 -13
  15. data/lib/koala/api.rb +93 -0
  16. data/lib/koala/http_service/multipart_request.rb +41 -0
  17. data/lib/koala/http_service/response.rb +18 -0
  18. data/lib/koala/http_service/uploadable_io.rb +187 -0
  19. data/lib/koala/http_service.rb +69 -20
  20. data/lib/koala/oauth.rb +150 -27
  21. data/lib/koala/realtime_updates.rb +89 -51
  22. data/lib/koala/test_users.rb +109 -33
  23. data/lib/koala/utils.rb +11 -4
  24. data/lib/koala/version.rb +1 -1
  25. data/lib/koala.rb +16 -96
  26. data/readme.md +9 -9
  27. data/spec/cases/api_spec.rb +19 -12
  28. data/spec/cases/error_spec.rb +10 -0
  29. data/spec/cases/graph_api_batch_spec.rb +100 -58
  30. data/spec/cases/graph_collection_spec.rb +23 -7
  31. data/spec/cases/http_service_spec.rb +5 -26
  32. data/spec/cases/koala_spec.rb +22 -4
  33. data/spec/cases/legacy_spec.rb +107 -0
  34. data/spec/cases/multipart_request_spec.rb +7 -7
  35. data/spec/cases/oauth_spec.rb +114 -44
  36. data/spec/cases/realtime_updates_spec.rb +154 -47
  37. data/spec/cases/test_users_spec.rb +268 -219
  38. data/spec/cases/uploadable_io_spec.rb +1 -1
  39. data/spec/cases/utils_spec.rb +29 -5
  40. data/spec/fixtures/mock_facebook_responses.yml +40 -29
  41. data/spec/spec_helper.rb +3 -0
  42. data/spec/support/custom_matchers.rb +28 -0
  43. data/spec/support/graph_api_shared_examples.rb +192 -14
  44. data/spec/support/koala_test.rb +10 -1
  45. data/spec/support/mock_http_service.rb +2 -2
  46. data/spec/support/rest_api_shared_examples.rb +5 -165
  47. metadata +76 -100
  48. data/lib/koala/batch_operation.rb +0 -74
  49. data/lib/koala/graph_api.rb +0 -270
  50. data/lib/koala/graph_collection.rb +0 -59
  51. data/lib/koala/multipart_request.rb +0 -35
  52. data/lib/koala/uploadable_io.rb +0 -181
  53. data/spec/cases/graph_and_rest_api_spec.rb +0 -22
  54. data/spec/cases/graph_api_spec.rb +0 -22
  55. data/spec/cases/rest_api_spec.rb +0 -22
@@ -29,26 +29,27 @@ describe "Koala::Facebook::OAuth" do
29
29
  @time.stub!(:to_i).and_return(1273363199)
30
30
  end
31
31
 
32
- # initialization
33
- it "properly initializes" do
34
- @oauth.should
35
- end
32
+ describe ".new" do
33
+ it "properly initializes" do
34
+ @oauth.should
35
+ end
36
36
 
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
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
- it "properly initializes without a callback_url" do
44
- @oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
45
- end
43
+ it "properly initializes without a callback_url" do
44
+ @oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
45
+ end
46
46
 
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
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 == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}"
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 == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}"
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 == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&scope=#{permissions}"
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 == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&scope=#{permissions.join(",")}"
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 == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}&scope=#{permissions}"
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 == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&display=page"
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 "for access token URLs" do
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 == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{@callback_url}&client_secret=#{@secret}&code=#{@code}"
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 == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{callback}&client_secret=#{@secret}&code=#{@code}"
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 ".get_access_token_info" do
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 ".get_access_token" do
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
- describe "when initializing" do
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 "should initialize properly with an app_id and an app_access_token" do
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 "should allow read access to app_id" do
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 "should allow read access to app_access_token" do
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 "should allow read access to secret" do
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 "should allow read access to api" do
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 "should initialize properly with an app_id and a secret" do
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 "should fetch an app_token from Facebook when provided an app_id and a secret" do
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 "should use the OAuth class to fetch a token when provided an app_id and a secret" do
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 "when used" do
92
- before :each do
93
- @updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
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 "should send a subscription request to a valid server" do
97
- result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
98
- result.should be_true
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 "should send a subscription request to a valid server" do
102
- result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
103
- result.should be_true
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 "should send a subscription request to an invalid path on a valid server" do
107
- lambda { result = @updates.subscribe("user", "name", @subscription_path + "foo", @verify_token) }.should raise_exception(Koala::Facebook::APIError)
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
- it "should fail to send a subscription request to an invalid server" do
111
- lambda { @updates.subscribe("user", "name", "foo", @verify_token) }.should raise_exception(Koala::Facebook::APIError)
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
- it "should unsubscribe a valid individual object successfully" do
115
- @updates.unsubscribe("user").should be_true
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 "should unsubscribe all subscriptions successfully" do
119
- @updates.unsubscribe.should be_true
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
- it "should fail when an invalid object is provided to unsubscribe" do
123
- lambda { @updates.unsubscribe("kittens") }.should raise_error(Koala::Facebook::APIError)
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 "should is subscriptions properly" do
127
- @updates.list_subscriptions.should be_a(Array)
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
- end # describe "when used"
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 "when meeting challenge" do
132
- it "should return false if hub.mode isn't subscribe" do
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 "should return false if not given a verify_token or block" do
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 "should return false if the given verify token doesn't match" do
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 "should return the challenge if the given verify token matches" do
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 "should give the block the token as a parameter" do
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 "should return false if the given block return false" do
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 "should return false if the given block returns nil" do
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 "should return the challenge if the given block returns true" do
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
- end # describe "and mode is subscribe"
195
-
196
- end # describe "when meeting challenge"
197
-
198
- end # describe
303
+ end
304
+ end
305
+ end