koala 1.5.0 → 1.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -381,58 +381,56 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
381
381
  }.to raise_exception(Koala::Facebook::APIError)
382
382
  end
383
383
 
384
- it "raises an APIError if the body is empty" do
384
+ it "raises a BadFacebookResponse if the body is empty" do
385
385
  Koala.stub(:make_request).and_return(Koala::HTTPService::Response.new(200, "", {}))
386
386
  expect {
387
387
  Koala::Facebook::API.new("foo").batch {|batch_api| batch_api.get_object('me') }
388
- }.to raise_exception(Koala::Facebook::APIError)
388
+ }.to raise_exception(Koala::Facebook::BadFacebookResponse)
389
389
  end
390
390
 
391
391
  context "with the old style" do
392
392
  before :each do
393
- Koala.stub(:make_request).and_return(Koala::HTTPService::Response.new(200, '{"error":190,"error_description":"Error validating access token."}', {}))
393
+ Koala.stub(:make_request).and_return(Koala::HTTPService::Response.new(400, '{"error_code":190,"error_description":"Error validating access token."}', {}))
394
394
  end
395
395
 
396
- it "throws an error if the response is an old Batch API-style error" do
396
+ it "throws an error" do
397
397
  expect {
398
398
  Koala::Facebook::API.new("foo").batch {|batch_api| batch_api.get_object('me') }
399
399
  }.to raise_exception(Koala::Facebook::APIError)
400
400
  end
401
401
 
402
- it "provides a type for the error if the response is an old Batch API-style error" do
402
+ it "passes all the error details" do
403
403
  begin
404
404
  Koala::Facebook::API.new("foo").batch {|batch_api| batch_api.get_object('me') }
405
405
  rescue Koala::Facebook::APIError => err
406
+ err.fb_error_code.should == 190
407
+ err.fb_error_message.should == "Error validating access token."
408
+ err.http_status == 400
409
+ err.response_body == '{"error_code":190,"error_description":"Error validating access token."}'
406
410
  end
407
- err.fb_error_type.should
408
- end
409
-
410
- it "passes all the error details if an old Batch API-style error is raised" do
411
- begin
412
- Koala::Facebook::API.new("foo").batch {|batch_api| batch_api.get_object('me') }
413
- rescue Koala::Facebook::APIError => err
414
- end
415
- err.raw_response["error"].should == 190
416
411
  end
417
412
  end
418
413
 
419
414
  context "with the new style" do
420
415
  before :each do
421
- Koala.stub(:make_request).and_return(Koala::HTTPService::Response.new(200, '{"error":{"message":"Request 0 cannot depend on an unresolved request with name f. Requests can only depend on preceding requests","type":"GraphBatchException"}}', {}))
416
+ Koala.stub(:make_request).and_return(Koala::HTTPService::Response.new(400, '{"error":{"message":"Request 0 cannot depend on an unresolved request with name f. Requests can only depend on preceding requests","type":"GraphBatchException"}}', {}))
422
417
  end
423
418
 
424
- it "throws an error if the response is a new Graph API-style error" do
419
+ it "throws an error" do
425
420
  expect {
426
421
  Koala::Facebook::API.new("foo").batch {|batch_api| batch_api.get_object('me') }
427
422
  }.to raise_exception(Koala::Facebook::APIError)
428
423
  end
429
424
 
430
- it "passes all the error details if an old Batch API-style error is raised" do
425
+ it "passes all the error details" do
431
426
  begin
432
427
  Koala::Facebook::API.new("foo").batch {|batch_api| batch_api.get_object('me') }
433
428
  rescue Koala::Facebook::APIError => err
429
+ err.fb_error_type.should == "GraphBatchException"
430
+ err.fb_error_message.should == "Request 0 cannot depend on an unresolved request with name f. Requests can only depend on preceding requests"
431
+ err.http_status == 400
432
+ err.response_body == '{"error":{"message":"Request 0 cannot depend on an unresolved request with name f. Requests can only depend on preceding requests","type":"GraphBatchException"}}'
434
433
  end
435
- err.raw_response["message"].should
436
434
  end
437
435
  end
438
436
  end
@@ -509,7 +507,8 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
509
507
  pictures = @api.batch do |batch_api|
510
508
  batch_api.get_picture('me')
511
509
  end
512
- pictures.first.should_not be_empty
510
+ puts pictures.inspect
511
+ pictures.first.should =~ /http\:\/\// # works both live & stubbed
513
512
  end
514
513
 
515
514
  it "handles requests for two different tokens" do
@@ -526,7 +525,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
526
525
  batch_api.get_connection("2", "invalidconnection")
527
526
  batch_api.get_object(KoalaTest.user1, {}, {"access_token" => @app_api.access_token})
528
527
  end
529
- failed_call.should be_a(Koala::Facebook::APIError)
528
+ failed_call.should be_a(Koala::Facebook::ClientError)
530
529
  koppel["id"].should_not be_nil
531
530
  end
532
531
 
@@ -550,6 +549,42 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
550
549
  fql_result[0]["first_name"].should == "Alex"
551
550
  end
552
551
 
552
+ describe 'with post-processing callback' do
553
+ let(:me_result) { stub("me result") }
554
+ let(:friends_result) { stub("friends result") }
555
+
556
+ let(:me_callback) { lambda {|data| me_result } }
557
+ let(:friends_callback) { lambda {|data| friends_result } }
558
+
559
+ it 'calls the callback with the appropriate data' do
560
+ me_callback.should_receive(:call).with(hash_including(
561
+ 'id' => KoalaTest.user1
562
+ ))
563
+ friends_callback.should_receive(:call).with([
564
+ hash_including('id' => KoalaTest.user2)
565
+ ])
566
+ @api.batch do |batch_api|
567
+ batch_api.get_object('me', &me_callback)
568
+ batch_api.get_connections('me', 'friends', &friends_callback)
569
+ end
570
+ end
571
+
572
+ it 'passes GraphCollections, not raw data' do
573
+ friends_callback.should_receive(:call).with(kind_of(Koala::Facebook::API::GraphCollection))
574
+ @api.batch do |batch_api|
575
+ batch_api.get_object('me')
576
+ batch_api.get_connections('me', 'friends', &friends_callback)
577
+ end
578
+ end
579
+
580
+ it "returns the result of the callback" do
581
+ @api.batch do |batch_api|
582
+ batch_api.get_object('me', &me_callback)
583
+ batch_api.get_connections('me', 'friends', &friends_callback)
584
+ end.should == [me_result, friends_result]
585
+ end
586
+ end
587
+
553
588
  describe "binary files" do
554
589
  it "posts binary files" do
555
590
  file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))
@@ -614,7 +649,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
614
649
  batch_api.get_object(KoalaTest.user1, {}, :batch_args => {:depends_on => "getdata"})
615
650
  end
616
651
 
617
- failed_call.should be_a(Koala::Facebook::APIError)
652
+ failed_call.should be_a(Koala::Facebook::ClientError)
618
653
  koppel.should be_nil
619
654
  end
620
655
 
@@ -624,7 +659,7 @@ describe "Koala::Facebook::GraphAPI in batch mode" do
624
659
  batch_api.get_connections("me", "friends", {:limit => 5})
625
660
  batch_api.get_objects("{result=i-dont-exist:$.data.*.id}")
626
661
  end
627
- }.to raise_exception(Koala::Facebook::APIError)
662
+ }.to raise_exception(Koala::Facebook::ClientError)
628
663
  end
629
664
  end
630
665
  end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Koala::Facebook::GraphAPIMethods' do
4
+ before do
5
+ @api = Koala::Facebook::API.new(@token)
6
+ # app API
7
+ @app_id = KoalaTest.app_id
8
+ @app_access_token = KoalaTest.app_access_token
9
+ @app_api = Koala::Facebook::API.new(@app_access_token)
10
+ end
11
+
12
+ describe 'post-processing for' do
13
+ let(:post_processing) { lambda {} }
14
+
15
+ # Most API methods have the same signature, we test get_object representatively
16
+ # and the other methods which do some post-processing locally
17
+ context '#get_object' do
18
+ it 'returns result of block' do
19
+ result = {"id" => 1, "name" => 1, "updated_time" => 1}
20
+ @api.stub(:api).and_return(result)
21
+ post_processing.should_receive(:call).
22
+ with(result).and_return('new result')
23
+ @api.get_object('koppel', &post_processing).should == 'new result'
24
+ end
25
+ end
26
+
27
+ context '#get_picture' do
28
+ it 'returns result of block' do
29
+ result = "http://facebook.com/"
30
+ @api.stub(:api).and_return("Location" => result)
31
+ post_processing.should_receive(:call).
32
+ with(result).and_return('new result')
33
+ @api.get_picture('lukeshepard', &post_processing).should == 'new result'
34
+ end
35
+ end
36
+
37
+ context '#fql_multiquery' do
38
+ before do
39
+ @api.should_receive(:get_object).and_return([
40
+ {"name" => "query1", "fql_result_set" => [{"id" => 123}]},
41
+ {"name" => "query2", "fql_result_set" => ["id" => 456]}
42
+ ])
43
+ end
44
+
45
+ it 'is called with resolved response' do
46
+ resolved_result = {
47
+ 'query1' => [{'id' => 123}],
48
+ 'query2' => [{'id'=>456}]
49
+ }
50
+ post_processing.should_receive(:call).
51
+ with(resolved_result).and_return('id'=>'123', 'id'=>'456')
52
+ @api.fql_multiquery({}, &post_processing).should ==
53
+ {'id'=>'123', 'id'=>'456'}
54
+ end
55
+ end
56
+
57
+ context '#get_page_access_token' do
58
+ it 'returns result of block' do
59
+ token = Koala::MockHTTPService::APP_ACCESS_TOKEN
60
+ @api.stub(:api).and_return("access_token" => token)
61
+ post_processing.should_receive(:call).
62
+ with(token).and_return('base64-encoded access token')
63
+ @api.get_page_access_token('facebook', &post_processing).should ==
64
+ 'base64-encoded access token'
65
+ end
66
+ end
67
+ end
68
+ end
@@ -104,6 +104,12 @@ describe Koala::Facebook::GraphCollection do
104
104
  args_hash = {"one" => "val_one", "two" => "val_two"}
105
105
  Koala::Facebook::GraphCollection.parse_page_url("http://facebook.com/#{base}?#{args_hash.map {|k,v| "#{k}=#{v}" }.join("&")}").should == [base, args_hash]
106
106
  end
107
+
108
+ it "works with addresses with irregular characters" do
109
+ access_token = "appid123a|fdcba"
110
+ base, args_hash = Koala::Facebook::GraphCollection.parse_page_url("http://facebook.com/foo?token=#{access_token}")
111
+ args_hash["token"].should == access_token
112
+ end
107
113
  end
108
114
  end
109
115
 
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Koala::Facebook::OAuth" do
4
- before :each do
4
+ before :all do
5
5
  # make the relevant test data easily accessible
6
6
  @app_id = KoalaTest.app_id
7
7
  @secret = KoalaTest.secret
@@ -24,7 +24,9 @@ describe "Koala::Facebook::OAuth" do
24
24
  @multiple_session_keys = [KoalaTest.session_key, KoalaTest.session_key] if KoalaTest.session_key
25
25
 
26
26
  @oauth = Koala::Facebook::OAuth.new(@app_id, @secret, @callback_url)
27
+ end
27
28
 
29
+ before :each do
28
30
  @time = Time.now
29
31
  Time.stub!(:now).and_return(@time)
30
32
  @time.stub!(:to_i).and_return(1273363199)
@@ -117,19 +119,16 @@ describe "Koala::Facebook::OAuth" do
117
119
  end
118
120
 
119
121
  it "returns nil if the call to FB returns an expired code error" do
120
- @oauth.stub(:get_access_token_info).and_raise(Koala::Facebook::APIError.new(
121
- "type" => "OAuthException",
122
- "message" => "Code was invalid or expired. Session has expired at unix time 1324044000. The current unix time is 1324300957."
122
+ @oauth.stub(:get_access_token_info).and_raise(Koala::Facebook::OAuthTokenRequestError.new(400,
123
+ '{ "error": { "type": "OAuthException", "message": "Code was invalid or expired. Session has expired at unix time 1324044000. The current unix time is 1324300957." } }'
123
124
  ))
124
125
  @oauth.get_user_info_from_cookies(@cookie).should be_nil
125
126
  end
126
127
 
127
128
  it "raises the error if the call to FB returns a different error" do
128
- @oauth.stub(:get_access_token_info).and_raise(Koala::Facebook::APIError.new(
129
- "type" => "OtherError",
130
- "message" => "A Facebook Error"
131
- ))
132
- expect { @oauth.get_user_info_from_cookies(@cookie) }.to raise_exception(Koala::Facebook::APIError)
129
+ @oauth.stub(:get_access_token_info).and_raise(Koala::Facebook::OAuthTokenRequestError.new(400,
130
+ '{ "error": { "type": "OtherError", "message": "A Facebook Error" } }'))
131
+ expect { @oauth.get_user_info_from_cookies(@cookie) }.to raise_exception(Koala::Facebook::OAuthTokenRequestError)
133
132
  end
134
133
  end
135
134
 
@@ -149,6 +148,7 @@ describe "Koala::Facebook::OAuth" do
149
148
 
150
149
  it "returns all the cookie components from valid cookie string" do
151
150
  cookie_data = KoalaTest.oauth_test_data["valid_cookies"]
151
+ puts cookie_data.inspect
152
152
  parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
153
153
  number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
154
154
  parsing_results.length.should == number_of_components
@@ -295,13 +295,13 @@ describe "Koala::Facebook::OAuth" do
295
295
 
296
296
  it "generates a properly formatted OAuth token URL when provided a code" do
297
297
  url = @oauth.url_for_access_token(@code)
298
- 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
298
+ 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}")
299
299
  end
300
300
 
301
301
  it "generates a properly formatted OAuth token URL when provided a callback" do
302
302
  callback = "foo.com"
303
303
  url = @oauth.url_for_access_token(@code, :callback => callback)
304
- 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
304
+ 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}")
305
305
  end
306
306
 
307
307
  it "includes any additional options as URL parameters, appropriately escaped" do
@@ -399,7 +399,7 @@ describe "Koala::Facebook::OAuth" do
399
399
  end
400
400
 
401
401
  it "raises an error when get_access_token is called with a bad code" do
402
- lambda { @oauth.get_access_token_info("foo") }.should raise_error(Koala::Facebook::APIError)
402
+ lambda { @oauth.get_access_token_info("foo") }.should raise_error(Koala::Facebook::OAuthTokenRequestError)
403
403
  end
404
404
  end
405
405
  end
@@ -425,7 +425,7 @@ describe "Koala::Facebook::OAuth" do
425
425
  end
426
426
 
427
427
  it "raises an error when get_access_token is called with a bad code" do
428
- lambda { @oauth.get_access_token("foo") }.should raise_error(Koala::Facebook::APIError)
428
+ lambda { @oauth.get_access_token("foo") }.should raise_error(Koala::Facebook::OAuthTokenRequestError)
429
429
  end
430
430
  end
431
431
  end
@@ -493,7 +493,7 @@ describe "Koala::Facebook::OAuth" do
493
493
  end
494
494
 
495
495
  it "raises an error when exchange_access_token_info is called with a bad code" do
496
- lambda { @oauth.exchange_access_token_info("foo") }.should raise_error(Koala::Facebook::APIError)
496
+ lambda { @oauth.exchange_access_token_info("foo") }.should raise_error(Koala::Facebook::OAuthTokenRequestError)
497
497
  end
498
498
  end
499
499
 
@@ -579,9 +579,9 @@ describe "Koala::Facebook::OAuth" do
579
579
  result.each_with_index {|r, index| index > 0 ? r.should(be_a(Hash)) : r.should(be_nil)}
580
580
  end
581
581
 
582
- it "throws an APIError if Facebook returns an empty body (as happens for instance when the API breaks)" do
582
+ it "throws a BadFacebookResponse if Facebook returns an empty body (as happens for instance when the API breaks)" do
583
583
  @oauth.should_receive(:fetch_token_string).and_return("")
584
- lambda { @oauth.get_token_info_from_session_keys(@multiple_session_keys) }.should raise_error(Koala::Facebook::APIError)
584
+ lambda { @oauth.get_token_info_from_session_keys(@multiple_session_keys) }.should raise_error(Koala::Facebook::BadFacebookResponse)
585
585
  end
586
586
 
587
587
  it "passes on any options provided to make_request" do
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'base64'
2
3
 
3
4
  describe "Koala::Facebook::RealtimeUpdates" do
4
5
  before :all do
@@ -7,24 +8,24 @@ describe "Koala::Facebook::RealtimeUpdates" do
7
8
  @secret = KoalaTest.secret
8
9
  @callback_url = KoalaTest.oauth_test_data["callback_url"]
9
10
  @app_access_token = KoalaTest.app_access_token
10
-
11
+
11
12
  # check OAuth data
12
13
  unless @app_id && @secret && @callback_url && @app_access_token
13
- raise Exception, "Must supply OAuth app id, secret, app_access_token, and callback to run live subscription tests!"
14
+ raise Exception, "Must supply OAuth app id, secret, app_access_token, and callback to run live subscription tests!"
14
15
  end
15
-
16
+
16
17
  # get subscription data
17
18
  @verify_token = KoalaTest.subscription_test_data["verify_token"]
18
19
  @challenge_data = KoalaTest.subscription_test_data["challenge_data"]
19
20
  @subscription_path = KoalaTest.subscription_test_data["subscription_path"]
20
-
21
+
21
22
  # check subscription data
22
23
  unless @verify_token && @challenge_data && @subscription_path
23
- raise Exception, "Must supply verify_token and equivalent challenge_data to run subscription tests!"
24
+ raise Exception, "Must supply verify_token and equivalent challenge_data to run subscription tests!"
24
25
  end
25
26
  end
26
27
 
27
- before :each do
28
+ before :each do
28
29
  @updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
29
30
  end
30
31
 
@@ -34,28 +35,28 @@ describe "Koala::Facebook::RealtimeUpdates" do
34
35
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
35
36
  updates.should be_a(Koala::Facebook::RealtimeUpdates)
36
37
  end
37
-
38
+
38
39
  # attributes
39
40
  it "allows read access to app_id" do
40
- # in Ruby 1.9, .method returns symbols
41
+ # in Ruby 1.9, .method returns symbols
41
42
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:app_id)
42
43
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:app_id=)
43
44
  end
44
45
 
45
46
  it "allows read access to app_access_token" do
46
- # in Ruby 1.9, .method returns symbols
47
+ # in Ruby 1.9, .method returns symbols
47
48
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:app_access_token)
48
49
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:app_access_token=)
49
50
  end
50
51
 
51
52
  it "allows read access to secret" do
52
- # in Ruby 1.9, .method returns symbols
53
+ # in Ruby 1.9, .method returns symbols
53
54
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:secret)
54
55
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:secret=)
55
56
  end
56
57
 
57
58
  it "allows read access to api" do
58
- # in Ruby 1.9, .method returns symbols
59
+ # in Ruby 1.9, .method returns symbols
59
60
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should include(:api)
60
61
  Koala::Facebook::RealtimeUpdates.instance_methods.map(&:to_sym).should_not include(:api=)
61
62
  end
@@ -71,35 +72,35 @@ describe "Koala::Facebook::RealtimeUpdates" do
71
72
  Koala::Utils.should_receive(:deprecate)
72
73
  updates.graph_api
73
74
  end
74
-
75
+
75
76
  # init with secret / fetching the token
76
- it "initializes properly with an app_id and a secret" do
77
+ it "initializes properly with an app_id and a secret" do
77
78
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
78
- updates.should be_a(Koala::Facebook::RealtimeUpdates)
79
+ updates.should be_a(Koala::Facebook::RealtimeUpdates)
79
80
  end
80
81
 
81
- it "fetches an app_token from Facebook when provided an app_id and a secret" do
82
+ it "fetches an app_token from Facebook when provided an app_id and a secret" do
82
83
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
83
84
  updates.app_access_token.should_not be_nil
84
85
  end
85
-
86
+
86
87
  it "uses the OAuth class to fetch a token when provided an app_id and a secret" do
87
88
  oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
88
89
  token = oauth.get_app_access_token
89
90
  oauth.should_receive(:get_app_access_token).and_return(token)
90
- Koala::Facebook::OAuth.should_receive(:new).with(@app_id, @secret).and_return(oauth)
91
+ Koala::Facebook::OAuth.should_receive(:new).with(@app_id, @secret).and_return(oauth)
91
92
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
92
93
  end
93
-
94
- it "sets up the with the app acces token" do
94
+
95
+ it "sets up the with the app acces token" do
95
96
  updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
96
97
  updates.api.should be_a(Koala::Facebook::API)
97
98
  updates.api.access_token.should == @app_access_token
98
- end
99
-
99
+ end
100
+
100
101
  end
101
102
 
102
- describe "#subscribe" do
103
+ describe "#subscribe" do
103
104
  it "makes a POST to the subscription path" do
104
105
  @updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "post", anything)
105
106
  @updates.subscribe("user", "name", @subscription_path, @verify_token)
@@ -112,11 +113,11 @@ describe "Koala::Facebook::RealtimeUpdates" do
112
113
  :object => obj,
113
114
  :fields => fields,
114
115
  :callback_url => @subscription_path,
115
- :verify_token => @verify_token
116
+ :verify_token => @verify_token
116
117
  ), anything, anything)
117
118
  @updates.subscribe("user", "name", @subscription_path, @verify_token)
118
119
  end
119
-
120
+
120
121
  pending "doesn't require a verify_token" do
121
122
  # see https://github.com/arsduo/koala/issues/150
122
123
  obj = "user"
@@ -124,50 +125,36 @@ describe "Koala::Facebook::RealtimeUpdates" do
124
125
  @updates.api.should_not_receive(:graph_call).with(anything, hash_including(:verify_token => anything), anything, anything)
125
126
  @updates.subscribe("user", "name", @subscription_path)
126
127
  end
127
-
128
+
128
129
  it "requires verify_token" do
129
130
  expect { @updates.subscribe("user", "name", @subscription_path) }.to raise_exception
130
131
  end
131
-
132
- it "requests the status component" do
133
- @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
134
- @updates.subscribe("user", "name", @subscription_path, @verify_token)
135
- end
136
-
132
+
137
133
  it "accepts an options hash" do
138
134
  options = {:a => 2, :b => "c"}
139
135
  @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
140
136
  @updates.subscribe("user", "name", @subscription_path, @verify_token, options)
141
137
  end
142
-
143
- it "overrides any provided http_component" do
144
- # since we test against status, we need to ensure that we get that
145
- options = {:http_component => :body}
146
- @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
147
- @updates.subscribe("user", "name", @subscription_path, @verify_token, options)
148
- end
149
138
 
150
139
  describe "in practice" do
151
140
  it "sends a subscription request" do
152
- result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
153
- result.should be_true
141
+ expect { @updates.subscribe("user", "name", @subscription_path, @verify_token) }.to_not raise_error
154
142
  end
155
-
143
+
156
144
  pending "sends a subscription request without a verify token" do
157
- result = @updates.subscribe("user", "name", @subscription_path)
158
- result.should be_true
145
+ expect { @updates.subscribe("user", "name", @subscription_path) }.to_not raise_error
159
146
  end
160
-
147
+
161
148
  it "fails if you try to hit an invalid path on your valid server" do
162
149
  expect { result = @updates.subscribe("user", "name", @subscription_path + "foo", @verify_token) }.to raise_exception(Koala::Facebook::APIError)
163
150
  end
164
-
151
+
165
152
  it "fails to send a subscription request to an invalid server" do
166
153
  expect { @updates.subscribe("user", "name", "foo", @verify_token) }.to raise_exception(Koala::Facebook::APIError)
167
154
  end
168
155
  end
169
156
  end
170
-
157
+
171
158
  describe "#unsubscribe" do
172
159
  it "makes a DELETE to the subscription path" do
173
160
  @updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "delete", anything)
@@ -179,65 +166,76 @@ describe "Koala::Facebook::RealtimeUpdates" do
179
166
  @updates.api.should_receive(:graph_call).with(anything, hash_including(:object => obj), anything, anything)
180
167
  @updates.unsubscribe(obj)
181
168
  end
182
-
183
- it "requests the status component" do
184
- @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
185
- @updates.unsubscribe("user")
186
- end
187
-
169
+
188
170
  it "accepts an options hash" do
189
171
  options = {:a => 2, :b => "C"}
190
172
  @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
191
173
  @updates.unsubscribe("user", options)
192
174
  end
193
-
194
- it "overrides any provided http_component" do
195
- # since we test against status, we need to ensure that we get that
196
- options = {:http_component => :body}
197
- @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(:http_component => :status))
198
- @updates.unsubscribe("user", options)
199
- end
200
-
175
+
201
176
  describe "in practice" do
202
- it "unsubscribes a valid individual object successfully" do
203
- @updates.unsubscribe("user").should be_true
177
+ it "unsubscribes a valid individual object successfully" do
178
+ expect { @updates.unsubscribe("user") }.to_not raise_error
204
179
  end
205
180
 
206
- it "unsubscribes all subscriptions successfully" do
207
- @updates.unsubscribe.should be_true
181
+ it "unsubscribes all subscriptions successfully" do
182
+ expect { @updates.unsubscribe }.to_not raise_error
208
183
  end
209
184
 
210
- it "fails when an invalid object is provided to unsubscribe" do
185
+ it "fails when an invalid object is provided to unsubscribe" do
211
186
  expect { @updates.unsubscribe("kittens") }.to raise_error(Koala::Facebook::APIError)
212
187
  end
213
188
  end
214
189
  end
215
-
190
+
216
191
  describe "#list_subscriptions" do
217
192
  it "GETs the subscription path" do
218
193
  @updates.api.should_receive(:graph_call).with(@updates.subscription_path, anything, "get", anything)
219
194
  @updates.list_subscriptions
220
195
  end
221
-
196
+
222
197
  it "accepts options" do
223
- options = {:a => 3, :b => "D"}
198
+ options = {:a => 3, :b => "D"}
224
199
  @updates.api.should_receive(:graph_call).with(anything, anything, anything, hash_including(options))
225
200
  @updates.list_subscriptions(options)
226
201
  end
227
-
202
+
228
203
  describe "in practice" do
229
204
  it "lists subscriptions properly" do
230
205
  @updates.list_subscriptions.should be_a(Array)
231
206
  end
232
207
  end
233
208
  end
234
-
209
+
235
210
  describe "#subscription_path" do
236
211
  it "returns the app_id/subscriptions" do
237
212
  @updates.subscription_path.should == "#{@app_id}/subscriptions"
238
213
  end
239
214
  end
240
-
215
+
216
+ describe ".validate_update" do
217
+ it "returns false if there is no X-Hub-Signature header" do
218
+ @updates.validate_update("", {}).should be_false
219
+ end
220
+
221
+ it "returns false if the signature doesn't match the body" do
222
+ @updates.validate_update("", {"X-Hub-Signature" => "sha1=badsha1"}).should be_false
223
+ end
224
+
225
+ it "results true if the signature matches the body with the secret" do
226
+ body = "BODY"
227
+ signature = OpenSSL::HMAC.hexdigest('sha1', @secret, body).chomp
228
+ @updates.validate_update(body, {"X-Hub-Signature" => "sha1=#{signature}"}).should be_true
229
+ end
230
+
231
+ it "results true with alternate HTTP_X_HUB_SIGNATURE header" do
232
+ body = "BODY"
233
+ signature = OpenSSL::HMAC.hexdigest('sha1', @secret, body).chomp
234
+ @updates.validate_update(body, {"HTTP_X_HUB_SIGNATURE" => "sha1=#{signature}"}).should be_true
235
+ end
236
+
237
+ end
238
+
241
239
  describe ".meet_challenge" do
242
240
  it "returns false if hub.mode isn't subscribe" do
243
241
  params = {'hub.mode' => 'not subscribe'}
@@ -250,56 +248,56 @@ describe "Koala::Facebook::RealtimeUpdates" do
250
248
  Koala::Facebook::RealtimeUpdates.meet_challenge(params){|token| block_evaluated = true}
251
249
  block_evaluated.should be_false
252
250
  end
253
-
251
+
254
252
  it "returns false if not given a verify_token or block" do
255
253
  params = {'hub.mode' => 'subscribe'}
256
254
  Koala::Facebook::RealtimeUpdates.meet_challenge(params).should be_false
257
255
  end
258
-
256
+
259
257
  describe "and mode is 'subscribe'" do
260
- before(:each) do
258
+ before(:each) do
261
259
  @params = {'hub.mode' => 'subscribe'}
262
260
  end
263
-
261
+
264
262
  describe "and a token is given" do
265
263
  before(:each) do
266
264
  @token = 'token'
267
265
  @params['hub.verify_token'] = @token
268
266
  end
269
-
267
+
270
268
  it "returns false if the given verify token doesn't match" do
271
269
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token + '1').should be_false
272
270
  end
273
-
271
+
274
272
  it "returns the challenge if the given verify token matches" do
275
273
  @params['hub.challenge'] = 'challenge val'
276
274
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token).should == @params['hub.challenge']
277
275
  end
278
276
  end
279
-
277
+
280
278
  describe "and a block is given" do
281
279
  before :each do
282
280
  @params['hub.verify_token'] = @token
283
281
  end
284
-
282
+
285
283
  it "gives the block the token as a parameter" do
286
284
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
287
285
  token.should == @token
288
286
  end
289
287
  end
290
-
288
+
291
289
  it "returns false if the given block return false" do
292
290
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
293
291
  false
294
292
  end.should be_false
295
293
  end
296
-
294
+
297
295
  it "returns false if the given block returns nil" do
298
296
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
299
297
  nil
300
298
  end.should be_false
301
299
  end
302
-
300
+
303
301
  it "returns the challenge if the given block returns true" do
304
302
  @params['hub.challenge'] = 'challenge val'
305
303
  Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|