koala 1.0.0 → 1.2.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.
Files changed (54) hide show
  1. data/.autotest +12 -0
  2. data/.gitignore +3 -1
  3. data/.travis.yml +9 -0
  4. data/CHANGELOG +62 -2
  5. data/Gemfile +8 -0
  6. data/Rakefile +0 -1
  7. data/autotest/discover.rb +1 -0
  8. data/koala.gemspec +13 -14
  9. data/lib/koala/batch_operation.rb +74 -0
  10. data/lib/koala/graph_api.rb +145 -132
  11. data/lib/koala/graph_batch_api.rb +97 -0
  12. data/lib/koala/graph_collection.rb +59 -0
  13. data/lib/koala/http_service.rb +176 -0
  14. data/lib/koala/oauth.rb +191 -0
  15. data/lib/koala/realtime_updates.rb +23 -29
  16. data/lib/koala/rest_api.rb +13 -8
  17. data/lib/koala/test_users.rb +33 -17
  18. data/lib/koala/uploadable_io.rb +153 -87
  19. data/lib/koala/utils.rb +11 -0
  20. data/lib/koala/version.rb +3 -0
  21. data/lib/koala.rb +59 -217
  22. data/readme.md +92 -53
  23. data/spec/cases/{api_base_spec.rb → api_spec.rb} +31 -6
  24. data/spec/cases/error_spec.rb +32 -0
  25. data/spec/cases/graph_and_rest_api_spec.rb +12 -21
  26. data/spec/cases/graph_api_batch_spec.rb +582 -0
  27. data/spec/cases/graph_api_spec.rb +11 -14
  28. data/spec/cases/graph_collection_spec.rb +116 -0
  29. data/spec/cases/http_service_spec.rb +446 -0
  30. data/spec/cases/koala_spec.rb +54 -0
  31. data/spec/cases/oauth_spec.rb +319 -213
  32. data/spec/cases/realtime_updates_spec.rb +45 -31
  33. data/spec/cases/rest_api_spec.rb +23 -7
  34. data/spec/cases/test_users_spec.rb +123 -75
  35. data/spec/cases/uploadable_io_spec.rb +120 -37
  36. data/spec/cases/utils_spec.rb +10 -0
  37. data/spec/fixtures/cat.m4v +0 -0
  38. data/spec/fixtures/facebook_data.yml +26 -24
  39. data/spec/fixtures/mock_facebook_responses.yml +203 -78
  40. data/spec/spec_helper.rb +30 -5
  41. data/spec/support/graph_api_shared_examples.rb +149 -118
  42. data/spec/support/json_testing_fix.rb +42 -0
  43. data/spec/support/koala_test.rb +187 -0
  44. data/spec/support/mock_http_service.rb +62 -58
  45. data/spec/support/ordered_hash.rb +205 -0
  46. data/spec/support/rest_api_shared_examples.rb +139 -15
  47. data/spec/support/uploadable_io_shared_examples.rb +2 -8
  48. metadata +90 -114
  49. data/lib/koala/http_services.rb +0 -146
  50. data/spec/cases/http_services/http_service_spec.rb +0 -54
  51. data/spec/cases/http_services/net_http_service_spec.rb +0 -350
  52. data/spec/cases/http_services/typhoeus_service_spec.rb +0 -144
  53. data/spec/support/live_testing_data_helper.rb +0 -40
  54. data/spec/support/setup_mocks_or_live.rb +0 -52
@@ -3,38 +3,40 @@ require 'spec_helper'
3
3
  describe "Koala::Facebook::OAuth" do
4
4
  before :each do
5
5
  # make the relevant test data easily accessible
6
- @oauth_data = $testing_data["oauth_test_data"]
7
- @app_id = @oauth_data["app_id"]
8
- @secret = @oauth_data["secret"]
9
- @code = @oauth_data["code"]
10
- @callback_url = @oauth_data["callback_url"]
11
- @raw_token_string = @oauth_data["raw_token_string"]
12
- @raw_offline_access_token_string = @oauth_data["raw_offline_access_token_string"]
13
-
6
+ @app_id = KoalaTest.app_id
7
+ @secret = KoalaTest.secret
8
+ @code = KoalaTest.code
9
+ @callback_url = KoalaTest.oauth_test_data["callback_url"]
10
+ @raw_token_string = KoalaTest.oauth_test_data["raw_token_string"]
11
+ @raw_offline_access_token_string = KoalaTest.oauth_test_data["raw_offline_access_token_string"]
12
+
14
13
  # for signed requests (http://developers.facebook.com/docs/authentication/canvas/encryption_proposal)
15
- @signed_params = @oauth_data["signed_params"]
16
- @signed_params_result = @oauth_data["signed_params_result"]
17
-
14
+ @signed_params = KoalaTest.oauth_test_data["signed_params"]
15
+ @signed_params_result = KoalaTest.oauth_test_data["signed_params_result"]
16
+
18
17
  # this should expanded to cover all variables
19
- raise Exception, "Must supply app data to run FacebookOAuthTests!" unless @app_id && @secret && @callback_url &&
20
- @code && @raw_token_string &&
18
+ raise Exception, "Must supply app data to run FacebookOAuthTests!" unless @app_id && @secret && @callback_url &&
19
+ @raw_token_string &&
21
20
  @raw_offline_access_token_string
22
21
 
22
+ # we can just test against the same key twice
23
+ @multiple_session_keys = [KoalaTest.session_key, KoalaTest.session_key] if KoalaTest.session_key
24
+
23
25
  @oauth = Koala::Facebook::OAuth.new(@app_id, @secret, @callback_url)
24
26
 
25
27
  @time = Time.now
26
28
  Time.stub!(:now).and_return(@time)
27
29
  @time.stub!(:to_i).and_return(1273363199)
28
30
  end
29
-
31
+
30
32
  # initialization
31
33
  it "should properly initialize" do
32
34
  @oauth.should
33
35
  end
34
36
 
35
37
  it "should properly set attributes" do
36
- (@oauth.app_id == @app_id &&
37
- @oauth.app_secret == @secret &&
38
+ (@oauth.app_id == @app_id &&
39
+ @oauth.app_secret == @secret &&
38
40
  @oauth.oauth_callback_url == @callback_url).should be_true
39
41
  end
40
42
 
@@ -44,126 +46,198 @@ describe "Koala::Facebook::OAuth" do
44
46
 
45
47
  it "should properly set attributes without a callback URL" do
46
48
  @oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
47
- (@oauth.app_id == @app_id &&
48
- @oauth.app_secret == @secret &&
49
+ (@oauth.app_id == @app_id &&
50
+ @oauth.app_secret == @secret &&
49
51
  @oauth.oauth_callback_url == nil).should be_true
50
52
  end
51
-
53
+
52
54
  describe "for cookie parsing" do
53
55
  describe "get_user_info_from_cookies" do
54
- it "should properly parse valid cookies" do
55
- result = @oauth.get_user_info_from_cookies(@oauth_data["valid_cookies"])
56
- result.should be_a(Hash)
57
- end
58
-
59
- it "should return all the cookie components from valid cookie string" do
60
- cookie_data = @oauth_data["valid_cookies"]
61
- parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
62
- number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
63
- parsing_results.length.should == number_of_components
64
- end
65
-
66
- it "should properly parse valid offline access cookies (e.g. no expiration)" do
67
- result = @oauth.get_user_info_from_cookies(@oauth_data["offline_access_cookies"])
68
- result["uid"].should
69
- end
70
-
71
- it "should return all the cookie components from offline access cookies" do
72
- cookie_data = @oauth_data["offline_access_cookies"]
73
- parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
74
- number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
75
- parsing_results.length.should == number_of_components
76
- end
77
-
78
- it "shouldn't parse expired cookies" do
79
- result = @oauth.get_user_info_from_cookies(@oauth_data["expired_cookies"])
80
- result.should be_nil
56
+ context "for signed cookies" do
57
+ before :each do
58
+ # we don't actually want to make requests to Facebook to redeem the code
59
+ @cookie = KoalaTest.oauth_test_data["valid_signed_cookies"]
60
+ @token = "my token"
61
+ @oauth.stub(:get_access_token_info).and_return("access_token" => @token)
62
+ end
63
+
64
+ it "parses valid cookies" do
65
+ result = @oauth.get_user_info_from_cookies(@cookie)
66
+ result.should be_a(Hash)
67
+ end
68
+
69
+ it "returns all the components in the signed request" do
70
+ result = @oauth.get_user_info_from_cookies(@cookie)
71
+ @oauth.parse_signed_request(@cookie.values.first).each_pair do |k, v|
72
+ result[k].should == v
73
+ end
74
+ end
75
+
76
+ it "makes a request to Facebook to redeem the code if present" do
77
+ code = "foo"
78
+ @oauth.stub(:parse_signed_request).and_return({"code" => code})
79
+ @oauth.should_receive(:get_access_token_info).with(code, anything)
80
+ @oauth.get_user_info_from_cookies(@cookie)
81
+ end
82
+
83
+ it "sets the code redemption redirect_uri to ''" do
84
+ @oauth.should_receive(:get_access_token_info).with(anything, :redirect_uri => '')
85
+ @oauth.get_user_info_from_cookies(@cookie)
86
+ end
87
+
88
+ context "if the code is missing" do
89
+ it "doesn't make a request to Facebook" do
90
+ @oauth.stub(:parse_signed_request).and_return({})
91
+ @oauth.should_receive(:get_access_token_info).never
92
+ @oauth.get_user_info_from_cookies(@cookie)
93
+ end
94
+
95
+ it "returns nil" do
96
+ @oauth.stub(:parse_signed_request).and_return({})
97
+ @oauth.get_user_info_from_cookies(@cookie).should be_nil
98
+ end
99
+ end
100
+
101
+ context "if the code is present" do
102
+ it "adds the access_token into the hash" do
103
+ @oauth.get_user_info_from_cookies(@cookie)["access_token"].should == @token
104
+ end
105
+
106
+ it "returns nil if the call to FB fails" do
107
+ @oauth.stub(:get_access_token_info).and_return(nil)
108
+ @oauth.get_user_info_from_cookies(@cookie).should be_nil
109
+ end
110
+ end
111
+
112
+ it "shouldn't parse invalid cookies" do
113
+ # make an invalid string by replacing some values
114
+ bad_cookie_hash = @cookie.inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
115
+ result = @oauth.get_user_info_from_cookies(bad_cookie_hash)
116
+ result.should be_nil
117
+ end
81
118
  end
82
-
83
- it "shouldn't parse invalid cookies" do
84
- # make an invalid string by replacing some values
85
- bad_cookie_hash = @oauth_data["valid_cookies"].inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
86
- result = @oauth.get_user_info_from_cookies(bad_cookie_hash)
87
- result.should be_nil
119
+
120
+ context "for unsigned cookies" do
121
+ it "should properly parse valid cookies" do
122
+ result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["valid_cookies"])
123
+ result.should be_a(Hash)
124
+ end
125
+
126
+ it "should return all the cookie components from valid cookie string" do
127
+ cookie_data = KoalaTest.oauth_test_data["valid_cookies"]
128
+ parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
129
+ number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
130
+ parsing_results.length.should == number_of_components
131
+ end
132
+
133
+ it "should properly parse valid offline access cookies (e.g. no expiration)" do
134
+ result = @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["offline_access_cookies"])
135
+ result["uid"].should
136
+ end
137
+
138
+ it "should return all the cookie components from offline access cookies" do
139
+ cookie_data = KoalaTest.oauth_test_data["offline_access_cookies"]
140
+ parsing_results = @oauth.get_user_info_from_cookies(cookie_data)
141
+ number_of_components = cookie_data["fbs_#{@app_id.to_s}"].scan(/\=/).length
142
+ parsing_results.length.should == number_of_components
143
+ end
144
+
145
+ it "shouldn't parse expired cookies" do
146
+ new_time = @time.to_i * 2
147
+ @time.stub(:to_i).and_return(new_time)
148
+ @oauth.get_user_info_from_cookies(KoalaTest.oauth_test_data["valid_cookies"]).should be_nil
149
+ end
150
+
151
+ it "shouldn't parse invalid cookies" do
152
+ # make an invalid string by replacing some values
153
+ bad_cookie_hash = KoalaTest.oauth_test_data["valid_cookies"].inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
154
+ result = @oauth.get_user_info_from_cookies(bad_cookie_hash)
155
+ result.should be_nil
156
+ end
88
157
  end
89
158
  end
90
-
159
+
91
160
  describe "get_user_from_cookies" do
92
161
  it "should use get_user_info_from_cookies to parse the cookies" do
93
- data = @oauth_data["valid_cookies"]
162
+ data = KoalaTest.oauth_test_data["valid_cookies"]
94
163
  @oauth.should_receive(:get_user_info_from_cookies).with(data).and_return({})
95
164
  @oauth.get_user_from_cookies(data)
96
165
  end
97
166
 
98
167
  it "should use return a string if the cookies are valid" do
99
- result = @oauth.get_user_from_cookies(@oauth_data["valid_cookies"])
168
+ result = @oauth.get_user_from_cookies(KoalaTest.oauth_test_data["valid_cookies"])
100
169
  result.should be_a(String)
101
170
  end
102
-
171
+
103
172
  it "should return nil if the cookies are invalid" do
104
173
  # make an invalid string by replacing some values
105
- bad_cookie_hash = @oauth_data["valid_cookies"].inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
174
+ bad_cookie_hash = KoalaTest.oauth_test_data["valid_cookies"].inject({}) { |hash, value| hash[value[0]] = value[1].gsub(/[0-9]/, "3") }
106
175
  result = @oauth.get_user_from_cookies(bad_cookie_hash)
107
176
  result.should be_nil
108
- end
177
+ end
109
178
  end
110
179
  end
111
-
180
+
112
181
  # OAuth URLs
113
-
182
+
114
183
  describe "for URL generation" do
115
184
 
116
- describe "for OAuth codes" do
185
+ describe "for OAuth codes" do
117
186
  # url_for_oauth_code
118
- it "should generate a properly formatted OAuth code URL with the default values" do
187
+ it "should generate a properly formatted OAuth code URL with the default values" do
119
188
  url = @oauth.url_for_oauth_code
120
189
  url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}"
121
190
  end
122
191
 
123
- it "should generate a properly formatted OAuth code URL when a callback is given" do
192
+ it "should generate a properly formatted OAuth code URL when a callback is given" do
124
193
  callback = "foo.com"
125
194
  url = @oauth.url_for_oauth_code(:callback => callback)
126
195
  url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}"
127
196
  end
128
197
 
129
- it "should generate a properly formatted OAuth code URL when permissions are requested as a string" do
198
+ it "should generate a properly formatted OAuth code URL when permissions are requested as a string" do
130
199
  permissions = "publish_stream,read_stream"
131
200
  url = @oauth.url_for_oauth_code(:permissions => permissions)
132
201
  url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&scope=#{permissions}"
133
202
  end
134
203
 
135
- it "should generate a properly formatted OAuth code URL when permissions are requested as a string" do
204
+ it "should generate a properly formatted OAuth code URL when permissions are requested as a string" do
136
205
  permissions = ["publish_stream", "read_stream"]
137
206
  url = @oauth.url_for_oauth_code(:permissions => permissions)
138
207
  url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&scope=#{permissions.join(",")}"
139
208
  end
140
209
 
141
- it "should generate a properly formatted OAuth code URL when both permissions and callback are provided" do
210
+ it "should generate a properly formatted OAuth code URL when both permissions and callback are provided" do
142
211
  permissions = "publish_stream,read_stream"
143
212
  callback = "foo.com"
144
213
  url = @oauth.url_for_oauth_code(:callback => callback, :permissions => permissions)
145
214
  url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}&scope=#{permissions}"
146
215
  end
147
216
 
148
- it "should generate a properly formatted OAuth code URL when a display is given as a string" do
217
+ it "should generate a properly formatted OAuth code URL when a display is given as a string" do
149
218
  url = @oauth.url_for_oauth_code(:display => "page")
150
219
  url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&display=page"
151
220
  end
152
221
 
153
- it "should raise an exception if no callback is given in initialization or the call" do
222
+ it "should raise an exception if no callback is given in initialization or the call" do
154
223
  oauth2 = Koala::Facebook::OAuth.new(@app_id, @secret)
155
224
  lambda { oauth2.url_for_oauth_code }.should raise_error(ArgumentError)
156
225
  end
157
226
  end
158
-
227
+
159
228
  describe "for access token URLs" do
229
+ before :each do
230
+ # since we're just composing a URL here, we don't need to have a real code
231
+ @code ||= "test_code"
232
+ end
233
+
160
234
  # url_for_access_token
161
- it "should generate a properly formatted OAuth token URL when provided a code" do
235
+ it "should generate a properly formatted OAuth token URL when provided a code" do
162
236
  url = @oauth.url_for_access_token(@code)
163
237
  url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{@callback_url}&client_secret=#{@secret}&code=#{@code}"
164
238
  end
165
239
 
166
- it "should generate a properly formatted OAuth token URL when provided a callback" do
240
+ it "should generate a properly formatted OAuth token URL when provided a callback" do
167
241
  callback = "foo.com"
168
242
  url = @oauth.url_for_access_token(@code, :callback => callback)
169
243
  url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{callback}&client_secret=#{@secret}&code=#{@code}"
@@ -171,44 +245,68 @@ describe "Koala::Facebook::OAuth" do
171
245
  end
172
246
  end
173
247
 
174
- describe "for fetching access tokens" do
175
- describe "get_access_token_info" do
176
- it "should properly get and parse an access token token results into a hash" do
177
- result = @oauth.get_access_token_info(@code)
178
- result.should be_a(Hash)
179
- end
180
-
181
- it "should properly include the access token results" do
182
- result = @oauth.get_access_token_info(@code)
183
- result["access_token"].should
248
+ describe "for fetching access tokens" do
249
+ describe ".get_access_token_info" do
250
+ it "uses options[:redirect_uri] if provided" do
251
+ uri = "foo"
252
+ Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => uri), anything, anything).and_return(Koala::Response.new(200, "", {}))
253
+ @oauth.get_access_token_info(@code, :redirect_uri => uri)
184
254
  end
185
-
186
- it "should raise an error when get_access_token is called with a bad code" do
187
- lambda { @oauth.get_access_token_info("foo") }.should raise_error(Koala::Facebook::APIError)
255
+
256
+ it "uses the redirect_uri used to create the @oauth if no :redirect_uri option is provided" do
257
+ Koala.should_receive(:make_request).with(anything, hash_including(:redirect_uri => @callback_url), anything, anything).and_return(Koala::Response.new(200, "", {}))
258
+ @oauth.get_access_token_info(@code)
188
259
  end
189
- end
190
-
191
- describe "get_access_token" do
192
- it "should use get_access_token_info to get and parse an access token token results" do
193
- result = @oauth.get_access_token(@code)
194
- result.should be_a(String)
260
+
261
+ it "makes a GET request" do
262
+ Koala.should_receive(:make_request).with(anything, anything, "get", anything).and_return(Koala::Response.new(200, "", {}))
263
+ @oauth.get_access_token_info(@code)
195
264
  end
196
265
 
197
- it "should return the access token as a string" do
198
- result = @oauth.get_access_token(@code)
199
- original = @oauth.get_access_token_info(@code)
200
- result.should == original["access_token"]
201
- end
266
+ if KoalaTest.code
267
+ it "should properly get and parse an access token token results into a hash" do
268
+ result = @oauth.get_access_token_info(@code)
269
+ result.should be_a(Hash)
270
+ end
202
271
 
203
- it "should raise an error when get_access_token is called with a bad code" do
204
- lambda { @oauth.get_access_token("foo") }.should raise_error(Koala::Facebook::APIError)
272
+ it "should properly include the access token results" do
273
+ result = @oauth.get_access_token_info(@code)
274
+ result["access_token"].should
275
+ end
276
+ it "should raise an error when get_access_token is called with a bad code" do
277
+ lambda { @oauth.get_access_token_info("foo") }.should raise_error(Koala::Facebook::APIError)
278
+ end
205
279
  end
206
-
280
+ end
281
+
282
+ describe ".get_access_token" do
283
+ # TODO refactor these to be proper tests with stubs and tests against real data
207
284
  it "should pass on any options provided to make_request" do
208
285
  options = {:a => 2}
209
286
  Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
210
287
  @oauth.get_access_token(@code, options)
211
288
  end
289
+
290
+ if KoalaTest.code
291
+ it "uses get_access_token_info to get and parse an access token token results" do
292
+ result = @oauth.get_access_token(@code)
293
+ result.should be_a(String)
294
+ end
295
+
296
+ it "returns the access token as a string" do
297
+ result = @oauth.get_access_token(@code)
298
+ original = @oauth.get_access_token_info(@code)
299
+ result.should == original["access_token"]
300
+ end
301
+
302
+ it "raises an error when get_access_token is called with a bad code" do
303
+ lambda { @oauth.get_access_token("foo") }.should raise_error(Koala::Facebook::APIError)
304
+ end
305
+ end
306
+ end
307
+
308
+ unless KoalaTest.code
309
+ it "Some OAuth code tests will not be run since the code field in facebook_data.yml is blank."
212
310
  end
213
311
 
214
312
  describe "get_app_access_token_info" do
@@ -216,19 +314,19 @@ describe "Koala::Facebook::OAuth" do
216
314
  result = @oauth.get_app_access_token_info
217
315
  result.should be_a(Hash)
218
316
  end
219
-
317
+
220
318
  it "should include the access token" do
221
319
  result = @oauth.get_app_access_token_info
222
320
  result["access_token"].should
223
321
  end
224
-
322
+
225
323
  it "should pass on any options provided to make_request" do
226
324
  options = {:a => 2}
227
325
  Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
228
326
  @oauth.get_app_access_token_info(options)
229
327
  end
230
328
  end
231
-
329
+
232
330
  describe "get_app_acess_token" do
233
331
  it "should use get_access_token_info to get and parse an access token token results" do
234
332
  result = @oauth.get_app_access_token
@@ -240,16 +338,16 @@ describe "Koala::Facebook::OAuth" do
240
338
  original = @oauth.get_app_access_token_info
241
339
  result.should == original["access_token"]
242
340
  end
243
-
341
+
244
342
  it "should pass on any options provided to make_request" do
245
343
  options = {:a => 2}
246
344
  Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "", {}))
247
345
  @oauth.get_app_access_token(options)
248
346
  end
249
347
  end
250
-
348
+
251
349
  describe "protected methods" do
252
-
350
+
253
351
  # protected methods
254
352
  # since these are pretty fundamental and pretty testable, we want to test them
255
353
 
@@ -269,9 +367,13 @@ describe "Koala::Facebook::OAuth" do
269
367
  # fetch_token_string
270
368
  # somewhat duplicative with the tests for get_access_token and get_app_access_token
271
369
  # but no harm in thoroughness
272
- it "should fetch a proper token string from Facebook when given a code" do
273
- result = @oauth.send(:fetch_token_string, :code => @code, :redirect_uri => @callback_url)
274
- result.should =~ /^access_token/
370
+ if KoalaTest.code
371
+ it "should fetch a proper token string from Facebook when given a code" do
372
+ result = @oauth.send(:fetch_token_string, :code => @code, :redirect_uri => @callback_url)
373
+ result.should =~ /^access_token/
374
+ end
375
+ else
376
+ it "fetch_token_string code test will not be run since the code field in facebook_data.yml is blank."
275
377
  end
276
378
 
277
379
  it "should fetch a proper token string from Facebook when asked for the app token" do
@@ -282,119 +384,123 @@ describe "Koala::Facebook::OAuth" do
282
384
  end
283
385
 
284
386
  describe "for exchanging session keys" do
285
- describe "with get_token_info_from_session_keys" do
286
- it "should get an array of session keys from Facebook when passed a single key" do
287
- result = @oauth.get_tokens_from_session_keys([@oauth_data["session_key"]])
288
- result.should be_an(Array)
289
- result.length.should == 1
290
- end
291
-
292
- it "should get an array of session keys from Facebook when passed multiple keys" do
293
- result = @oauth.get_tokens_from_session_keys(@oauth_data["multiple_session_keys"])
294
- result.should be_an(Array)
295
- result.length.should == 2
296
- end
297
-
298
- it "should return the original hashes" do
299
- result = @oauth.get_token_info_from_session_keys(@oauth_data["multiple_session_keys"])
300
- result[0].should be_a(Hash)
301
- end
302
-
303
- it "should properly handle invalid session keys" do
304
- result = @oauth.get_token_info_from_session_keys(["foo", "bar"])
305
- #it should return nil for each of the invalid ones
306
- result.each {|r| r.should be_nil}
307
- end
308
-
309
- it "should properly handle a mix of valid and invalid session keys" do
310
- result = @oauth.get_token_info_from_session_keys(["foo"].concat(@oauth_data["multiple_session_keys"]))
311
- # it should return nil for each of the invalid ones
312
- result.each_with_index {|r, index| index > 0 ? r.should(be_a(Hash)) : r.should(be_nil)}
313
- end
314
-
315
- it "should throw an APIError if Facebook returns an empty body (as happens for instance when the API breaks)" do
316
- @oauth.should_receive(:fetch_token_string).and_return("")
317
- lambda { @oauth.get_token_info_from_session_keys(@oauth_data["multiple_session_keys"]) }.should raise_error(Koala::Facebook::APIError)
318
- end
319
-
320
- it "should pass on any options provided to make_request" do
321
- options = {:a => 2}
322
- Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "[{}]", {}))
323
- @oauth.get_token_info_from_session_keys([], options)
324
- end
325
- end
326
-
327
- describe "with get_tokens_from_session_keys" do
328
- it "should call get_token_info_from_session_keys" do
329
- args = @oauth_data["multiple_session_keys"]
330
- @oauth.should_receive(:get_token_info_from_session_keys).with(args, anything).and_return([])
331
- @oauth.get_tokens_from_session_keys(args)
332
- end
333
-
334
- it "should return an array of strings" do
335
- args = @oauth_data["multiple_session_keys"]
336
- result = @oauth.get_tokens_from_session_keys(args)
337
- result.each {|r| r.should be_a(String) }
338
- end
339
-
340
- it "should properly handle invalid session keys" do
341
- result = @oauth.get_tokens_from_session_keys(["foo", "bar"])
342
- # it should return nil for each of the invalid ones
343
- result.each {|r| r.should be_nil}
344
- end
345
-
346
- it "should properly handle a mix of valid and invalid session keys" do
347
- result = @oauth.get_tokens_from_session_keys(["foo"].concat(@oauth_data["multiple_session_keys"]))
348
- # it should return nil for each of the invalid ones
349
- result.each_with_index {|r, index| index > 0 ? r.should(be_a(String)) : r.should(be_nil)}
350
- end
351
-
352
- it "should pass on any options provided to make_request" do
353
- options = {:a => 2}
354
- Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "[{}]", {}))
355
- @oauth.get_tokens_from_session_keys([], options)
356
- end
387
+ if KoalaTest.session_key
388
+ describe "with get_token_info_from_session_keys" do
389
+ it "should get an array of session keys from Facebook when passed a single key" do
390
+ result = @oauth.get_tokens_from_session_keys([KoalaTest.session_key])
391
+ result.should be_an(Array)
392
+ result.length.should == 1
393
+ end
394
+
395
+ it "should get an array of session keys from Facebook when passed multiple keys" do
396
+ result = @oauth.get_tokens_from_session_keys(@multiple_session_keys)
397
+ result.should be_an(Array)
398
+ result.length.should == 2
399
+ end
400
+
401
+ it "should return the original hashes" do
402
+ result = @oauth.get_token_info_from_session_keys(@multiple_session_keys)
403
+ result[0].should be_a(Hash)
404
+ end
405
+
406
+ it "should properly handle invalid session keys" do
407
+ result = @oauth.get_token_info_from_session_keys(["foo", "bar"])
408
+ #it should return nil for each of the invalid ones
409
+ result.each {|r| r.should be_nil}
410
+ end
411
+
412
+ it "should properly handle a mix of valid and invalid session keys" do
413
+ result = @oauth.get_token_info_from_session_keys(["foo"].concat(@multiple_session_keys))
414
+ # it should return nil for each of the invalid ones
415
+ result.each_with_index {|r, index| index > 0 ? r.should(be_a(Hash)) : r.should(be_nil)}
416
+ end
417
+
418
+ it "should throw an APIError if Facebook returns an empty body (as happens for instance when the API breaks)" do
419
+ @oauth.should_receive(:fetch_token_string).and_return("")
420
+ lambda { @oauth.get_token_info_from_session_keys(@multiple_session_keys) }.should raise_error(Koala::Facebook::APIError)
421
+ end
422
+
423
+ it "should pass on any options provided to make_request" do
424
+ options = {:a => 2}
425
+ Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "[{}]", {}))
426
+ @oauth.get_token_info_from_session_keys([], options)
427
+ end
428
+ end
429
+
430
+ describe "with get_tokens_from_session_keys" do
431
+ it "should call get_token_info_from_session_keys" do
432
+ args = @multiple_session_keys
433
+ @oauth.should_receive(:get_token_info_from_session_keys).with(args, anything).and_return([])
434
+ @oauth.get_tokens_from_session_keys(args)
435
+ end
436
+
437
+ it "should return an array of strings" do
438
+ args = @multiple_session_keys
439
+ result = @oauth.get_tokens_from_session_keys(args)
440
+ result.each {|r| r.should be_a(String) }
441
+ end
442
+
443
+ it "should properly handle invalid session keys" do
444
+ result = @oauth.get_tokens_from_session_keys(["foo", "bar"])
445
+ # it should return nil for each of the invalid ones
446
+ result.each {|r| r.should be_nil}
447
+ end
448
+
449
+ it "should properly handle a mix of valid and invalid session keys" do
450
+ result = @oauth.get_tokens_from_session_keys(["foo"].concat(@multiple_session_keys))
451
+ # it should return nil for each of the invalid ones
452
+ result.each_with_index {|r, index| index > 0 ? r.should(be_a(String)) : r.should(be_nil)}
453
+ end
454
+
455
+ it "should pass on any options provided to make_request" do
456
+ options = {:a => 2}
457
+ Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "[{}]", {}))
458
+ @oauth.get_tokens_from_session_keys([], options)
459
+ end
460
+ end
461
+
462
+ describe "get_token_from_session_key" do
463
+ it "should call get_tokens_from_session_keys when the get_token_from_session_key is called" do
464
+ key = KoalaTest.session_key
465
+ @oauth.should_receive(:get_tokens_from_session_keys).with([key], anything).and_return([])
466
+ @oauth.get_token_from_session_key(key)
467
+ end
468
+
469
+ it "should get back the access token string from get_token_from_session_key" do
470
+ result = @oauth.get_token_from_session_key(KoalaTest.session_key)
471
+ result.should be_a(String)
472
+ end
473
+
474
+ it "should be the first value in the array" do
475
+ result = @oauth.get_token_from_session_key(KoalaTest.session_key)
476
+ array = @oauth.get_tokens_from_session_keys([KoalaTest.session_key])
477
+ result.should == array[0]
478
+ end
479
+
480
+ it "should properly handle an invalid session key" do
481
+ result = @oauth.get_token_from_session_key("foo")
482
+ result.should be_nil
483
+ end
484
+
485
+ it "should pass on any options provided to make_request" do
486
+ options = {:a => 2}
487
+ Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "[{}]", {}))
488
+ @oauth.get_token_from_session_key("", options)
489
+ end
490
+ end
491
+ else
492
+ it "Session key exchange tests will not be run since the session key in facebook_data.yml is blank."
357
493
  end
358
-
359
- describe "get_token_from_session_key" do
360
- it "should call get_tokens_from_session_keys when the get_token_from_session_key is called" do
361
- key = @oauth_data["session_key"]
362
- @oauth.should_receive(:get_tokens_from_session_keys).with([key], anything).and_return([])
363
- @oauth.get_token_from_session_key(key)
364
- end
365
-
366
- it "should get back the access token string from get_token_from_session_key" do
367
- result = @oauth.get_token_from_session_key(@oauth_data["session_key"])
368
- result.should be_a(String)
369
- end
370
-
371
- it "should be the first value in the array" do
372
- result = @oauth.get_token_from_session_key(@oauth_data["session_key"])
373
- array = @oauth.get_tokens_from_session_keys([@oauth_data["session_key"]])
374
- result.should == array[0]
375
- end
376
-
377
- it "should properly handle an invalid session key" do
378
- result = @oauth.get_token_from_session_key("foo")
379
- result.should be_nil
380
- end
381
-
382
- it "should pass on any options provided to make_request" do
383
- options = {:a => 2}
384
- Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(options)).and_return(Koala::Response.new(200, "[{}]", {}))
385
- @oauth.get_token_from_session_key("", options)
386
- end
387
- end
388
494
  end
389
-
495
+
390
496
  describe "for parsing signed requests" do
391
497
  # the signed request code is ported directly from Facebook
392
- # so we only need to test at a high level that it works
498
+ # so we only need to test at a high level that it works
393
499
  it "should throw an error if the algorithm is unsupported" do
394
- JSON.stub!(:parse).and_return("algorithm" => "my fun algorithm")
500
+ MultiJson.stub(:decode).and_return("algorithm" => "my fun algorithm")
395
501
  lambda { @oauth.parse_signed_request(@signed_request) }.should raise_error
396
502
  end
397
-
503
+
398
504
  it "should throw an error if the signature is invalid" do
399
505
  OpenSSL::HMAC.stub!(:hexdigest).and_return("i'm an invalid signature")
400
506
  lambda { @oauth.parse_signed_request(@signed_request) }.should raise_error