koala 1.0.0.beta2.1 → 1.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG +6 -1
  3. data/Gemfile +3 -0
  4. data/Rakefile +13 -14
  5. data/koala.gemspec +35 -20
  6. data/lib/koala.rb +8 -17
  7. data/lib/koala/graph_api.rb +2 -2
  8. data/lib/koala/http_services.rb +32 -27
  9. data/lib/koala/test_users.rb +4 -4
  10. data/lib/koala/uploadable_io.rb +1 -1
  11. data/spec/cases/api_base_spec.rb +101 -0
  12. data/spec/cases/graph_and_rest_api_spec.rb +31 -0
  13. data/spec/cases/graph_api_spec.rb +25 -0
  14. data/spec/{koala/http_services/http_service_tests.rb → cases/http_services/http_service_spec.rb} +8 -5
  15. data/spec/cases/http_services/net_http_service_spec.rb +350 -0
  16. data/spec/cases/http_services/typhoeus_service_spec.rb +144 -0
  17. data/spec/cases/oauth_spec.rb +374 -0
  18. data/spec/cases/realtime_updates_spec.rb +184 -0
  19. data/spec/cases/rest_api_spec.rb +25 -0
  20. data/spec/{koala/test_users/test_users_tests.rb → cases/test_users_spec.rb} +34 -29
  21. data/spec/cases/uploadable_io_spec.rb +151 -0
  22. data/spec/{koala/assets → fixtures}/beach.jpg +0 -0
  23. data/spec/{facebook_data.yml → fixtures/facebook_data.yml} +5 -5
  24. data/spec/{mock_facebook_responses.yml → fixtures/mock_facebook_responses.yml} +311 -311
  25. data/spec/spec_helper.rb +18 -0
  26. data/spec/support/graph_api_shared_examples.rb +424 -0
  27. data/spec/{koala → support}/live_testing_data_helper.rb +39 -42
  28. data/spec/{mock_http_service.rb → support/mock_http_service.rb} +94 -94
  29. data/spec/{koala/rest_api/rest_api_tests.rb → support/rest_api_shared_examples.rb} +43 -0
  30. data/spec/support/setup_mocks_or_live.rb +52 -0
  31. data/spec/support/uploadable_io_shared_examples.rb +76 -0
  32. metadata +109 -53
  33. data/init.rb +0 -2
  34. data/spec/koala/api_base_tests.rb +0 -102
  35. data/spec/koala/graph_and_rest_api/graph_and_rest_api_no_token_tests.rb +0 -14
  36. data/spec/koala/graph_and_rest_api/graph_and_rest_api_with_token_tests.rb +0 -16
  37. data/spec/koala/graph_api/graph_api_no_access_token_tests.rb +0 -65
  38. data/spec/koala/graph_api/graph_api_tests.rb +0 -85
  39. data/spec/koala/graph_api/graph_api_with_access_token_tests.rb +0 -194
  40. data/spec/koala/graph_api/graph_collection_tests.rb +0 -104
  41. data/spec/koala/http_services/net_http_service_tests.rb +0 -339
  42. data/spec/koala/http_services/typhoeus_service_tests.rb +0 -162
  43. data/spec/koala/oauth/oauth_tests.rb +0 -372
  44. data/spec/koala/realtime_updates/realtime_updates_tests.rb +0 -187
  45. data/spec/koala/rest_api/rest_api_no_access_token_tests.rb +0 -25
  46. data/spec/koala/rest_api/rest_api_with_access_token_tests.rb +0 -38
  47. data/spec/koala/uploadable_io/uploadable_io_tests.rb +0 -246
  48. data/spec/koala_spec.rb +0 -18
  49. data/spec/koala_spec_helper.rb +0 -74
  50. data/spec/koala_spec_without_mocks.rb +0 -19
@@ -0,0 +1,374 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Koala::Facebook::OAuth" do
4
+ before :each do
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
+
14
+ # 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
+
18
+ # 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 &&
21
+ @raw_offline_access_token_string
22
+
23
+ @oauth = Koala::Facebook::OAuth.new(@app_id, @secret, @callback_url)
24
+
25
+ @time = Time.now
26
+ Time.stub!(:now).and_return(@time)
27
+ @time.stub!(:to_i).and_return(1273363199)
28
+ end
29
+
30
+ # initialization
31
+ it "should properly initialize" do
32
+ @oauth.should
33
+ end
34
+
35
+ it "should properly set attributes" do
36
+ (@oauth.app_id == @app_id &&
37
+ @oauth.app_secret == @secret &&
38
+ @oauth.oauth_callback_url == @callback_url).should be_true
39
+ end
40
+
41
+ it "should properly initialize without a callback_url" do
42
+ @oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
43
+ end
44
+
45
+ it "should properly set attributes without a callback URL" do
46
+ @oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
47
+ (@oauth.app_id == @app_id &&
48
+ @oauth.app_secret == @secret &&
49
+ @oauth.oauth_callback_url == nil).should be_true
50
+ end
51
+
52
+ describe "for cookie parsing" do
53
+ 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
81
+ 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
88
+ end
89
+ end
90
+
91
+ describe "get_user_from_cookies" do
92
+ it "should use get_user_info_from_cookies to parse the cookies" do
93
+ data = @oauth_data["valid_cookies"]
94
+ @oauth.should_receive(:get_user_info_from_cookies).with(data).and_return({})
95
+ @oauth.get_user_from_cookies(data)
96
+ end
97
+
98
+ it "should use return a string if the cookies are valid" do
99
+ result = @oauth.get_user_from_cookies(@oauth_data["valid_cookies"])
100
+ result.should be_a(String)
101
+ end
102
+
103
+ it "should return nil if the cookies are invalid" do
104
+ # 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") }
106
+ result = @oauth.get_user_from_cookies(bad_cookie_hash)
107
+ result.should be_nil
108
+ end
109
+ end
110
+ end
111
+
112
+ # OAuth URLs
113
+
114
+ describe "for URL generation" do
115
+
116
+ describe "for OAuth codes" do
117
+ # url_for_oauth_code
118
+ it "should generate a properly formatted OAuth code URL with the default values" do
119
+ url = @oauth.url_for_oauth_code
120
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}"
121
+ end
122
+
123
+ it "should generate a properly formatted OAuth code URL when a callback is given" do
124
+ callback = "foo.com"
125
+ url = @oauth.url_for_oauth_code(:callback => callback)
126
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}"
127
+ end
128
+
129
+ it "should generate a properly formatted OAuth code URL when permissions are requested as a string" do
130
+ permissions = "publish_stream,read_stream"
131
+ url = @oauth.url_for_oauth_code(:permissions => permissions)
132
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&scope=#{permissions}"
133
+ end
134
+
135
+ it "should generate a properly formatted OAuth code URL when permissions are requested as a string" do
136
+ permissions = ["publish_stream", "read_stream"]
137
+ url = @oauth.url_for_oauth_code(:permissions => permissions)
138
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&scope=#{permissions.join(",")}"
139
+ end
140
+
141
+ it "should generate a properly formatted OAuth code URL when both permissions and callback are provided" do
142
+ permissions = "publish_stream,read_stream"
143
+ callback = "foo.com"
144
+ url = @oauth.url_for_oauth_code(:callback => callback, :permissions => permissions)
145
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{callback}&scope=#{permissions}"
146
+ end
147
+
148
+ it "should generate a properly formatted OAuth code URL when a display is given as a string" do
149
+ url = @oauth.url_for_oauth_code(:display => "page")
150
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/authorize?client_id=#{@app_id}&redirect_uri=#{@callback_url}&display=page"
151
+ end
152
+
153
+ it "should raise an exception if no callback is given in initialization or the call" do
154
+ oauth2 = Koala::Facebook::OAuth.new(@app_id, @secret)
155
+ lambda { oauth2.url_for_oauth_code }.should raise_error(ArgumentError)
156
+ end
157
+ end
158
+
159
+ describe "for access token URLs" do
160
+
161
+ # url_for_access_token
162
+ it "should generate a properly formatted OAuth token URL when provided a code" do
163
+ url = @oauth.url_for_access_token(@code)
164
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{@callback_url}&client_secret=#{@secret}&code=#{@code}"
165
+ end
166
+
167
+ it "should generate a properly formatted OAuth token URL when provided a callback" do
168
+ callback = "foo.com"
169
+ url = @oauth.url_for_access_token(@code, :callback => callback)
170
+ url.should == "https://#{Koala::Facebook::GRAPH_SERVER}/oauth/access_token?client_id=#{@app_id}&redirect_uri=#{callback}&client_secret=#{@secret}&code=#{@code}"
171
+ end
172
+ end
173
+ end
174
+
175
+ describe "for fetching access tokens" do
176
+ describe "get_access_token_info" do
177
+ it "should properly get and parse an access token token results into a hash" do
178
+ result = @oauth.get_access_token_info(@code)
179
+ result.should be_a(Hash)
180
+ end
181
+
182
+ it "should properly include the access token results" do
183
+ result = @oauth.get_access_token_info(@code)
184
+ result["access_token"].should
185
+ end
186
+
187
+ it "should raise an error when get_access_token is called with a bad code" do
188
+ lambda { @oauth.get_access_token_info("foo") }.should raise_error(Koala::Facebook::APIError)
189
+ end
190
+ end
191
+
192
+ describe "get_access_token" do
193
+ it "should use get_access_token_info to get and parse an access token token results" do
194
+ result = @oauth.get_access_token(@code)
195
+ result.should be_a(String)
196
+ end
197
+
198
+ it "should return the access token as a string" do
199
+ result = @oauth.get_access_token(@code)
200
+ original = @oauth.get_access_token_info(@code)
201
+ result.should == original["access_token"]
202
+ end
203
+
204
+ it "should raise an error when get_access_token is called with a bad code" do
205
+ lambda { @oauth.get_access_token("foo") }.should raise_error(Koala::Facebook::APIError)
206
+ end
207
+ end
208
+
209
+ describe "get_app_access_token_info" do
210
+ it "should properly get and parse an app's access token as a hash" do
211
+ result = @oauth.get_app_access_token_info
212
+ result.should be_a(Hash)
213
+ end
214
+
215
+ it "should include the access token" do
216
+ result = @oauth.get_app_access_token_info
217
+ result["access_token"].should
218
+ end
219
+ end
220
+
221
+ describe "get_app_acess_token" do
222
+ it "should use get_access_token_info to get and parse an access token token results" do
223
+ result = @oauth.get_app_access_token
224
+ result.should be_a(String)
225
+ end
226
+
227
+ it "should return the access token as a string" do
228
+ result = @oauth.get_app_access_token
229
+ original = @oauth.get_app_access_token_info
230
+ result.should == original["access_token"]
231
+ end
232
+ end
233
+
234
+ describe "protected methods" do
235
+
236
+ # protected methods
237
+ # since these are pretty fundamental and pretty testable, we want to test them
238
+
239
+ # parse_access_token
240
+ it "should properly parse access token results" do
241
+ result = @oauth.send(:parse_access_token, @raw_token_string)
242
+ has_both_parts = result["access_token"] && result["expires"]
243
+ has_both_parts.should
244
+ end
245
+
246
+ it "should properly parse offline access token results" do
247
+ result = @oauth.send(:parse_access_token, @raw_offline_access_token_string)
248
+ has_both_parts = result["access_token"] && !result["expires"]
249
+ has_both_parts.should
250
+ end
251
+
252
+ # fetch_token_string
253
+ # somewhat duplicative with the tests for get_access_token and get_app_access_token
254
+ # but no harm in thoroughness
255
+ it "should fetch a proper token string from Facebook when given a code" do
256
+ result = @oauth.send(:fetch_token_string, :code => @code, :redirect_uri => @callback_url)
257
+ result.should =~ /^access_token/
258
+ end
259
+
260
+ it "should fetch a proper token string from Facebook when asked for the app token" do
261
+ result = @oauth.send(:fetch_token_string, {:type => 'client_cred'}, true)
262
+ result.should =~ /^access_token/
263
+ end
264
+ end
265
+ end
266
+
267
+ describe "for exchanging session keys" do
268
+ describe "with get_token_info_from_session_keys" do
269
+ it "should get an array of session keys from Facebook when passed a single key" do
270
+ result = @oauth.get_tokens_from_session_keys([@oauth_data["session_key"]])
271
+ result.should be_an(Array)
272
+ result.length.should == 1
273
+ end
274
+
275
+ it "should get an array of session keys from Facebook when passed multiple keys" do
276
+ result = @oauth.get_tokens_from_session_keys(@oauth_data["multiple_session_keys"])
277
+ result.should be_an(Array)
278
+ result.length.should == 2
279
+ end
280
+
281
+ it "should return the original hashes" do
282
+ result = @oauth.get_token_info_from_session_keys(@oauth_data["multiple_session_keys"])
283
+ result[0].should be_a(Hash)
284
+ end
285
+
286
+ it "should properly handle invalid session keys" do
287
+ result = @oauth.get_token_info_from_session_keys(["foo", "bar"])
288
+ #it should return nil for each of the invalid ones
289
+ result.each {|r| r.should be_nil}
290
+ end
291
+
292
+ it "should properly handle a mix of valid and invalid session keys" do
293
+ result = @oauth.get_token_info_from_session_keys(["foo"].concat(@oauth_data["multiple_session_keys"]))
294
+ # it should return nil for each of the invalid ones
295
+ result.each_with_index {|r, index| index > 0 ? r.should(be_a(Hash)) : r.should(be_nil)}
296
+ end
297
+
298
+ it "should throw an APIError if Facebook returns an empty body (as happens for instance when the API breaks)" do
299
+ @oauth.should_receive(:fetch_token_string).and_return("")
300
+ lambda { @oauth.get_token_info_from_session_keys(@oauth_data["multiple_session_keys"]) }.should raise_error(Koala::Facebook::APIError)
301
+ end
302
+ end
303
+
304
+ describe "with get_tokens_from_session_keys" do
305
+ it "should call get_token_info_from_session_keys" do
306
+ args = @oauth_data["multiple_session_keys"]
307
+ @oauth.should_receive(:get_token_info_from_session_keys).with(args).and_return([])
308
+ @oauth.get_tokens_from_session_keys(args)
309
+ end
310
+
311
+ it "should return an array of strings" do
312
+ args = @oauth_data["multiple_session_keys"]
313
+ result = @oauth.get_tokens_from_session_keys(args)
314
+ result.each {|r| r.should be_a(String) }
315
+ end
316
+
317
+ it "should properly handle invalid session keys" do
318
+ result = @oauth.get_tokens_from_session_keys(["foo", "bar"])
319
+ # it should return nil for each of the invalid ones
320
+ result.each {|r| r.should be_nil}
321
+ end
322
+
323
+ it "should properly handle a mix of valid and invalid session keys" do
324
+ result = @oauth.get_tokens_from_session_keys(["foo"].concat(@oauth_data["multiple_session_keys"]))
325
+ # it should return nil for each of the invalid ones
326
+ result.each_with_index {|r, index| index > 0 ? r.should(be_a(String)) : r.should(be_nil)}
327
+ end
328
+ end
329
+
330
+ describe "get_token_from_session_key" do
331
+ it "should call get_tokens_from_session_keys when the get_token_from_session_key is called" do
332
+ key = @oauth_data["session_key"]
333
+ @oauth.should_receive(:get_tokens_from_session_keys).with([key]).and_return([])
334
+ @oauth.get_token_from_session_key(key)
335
+ end
336
+
337
+ it "should get back the access token string from get_token_from_session_key" do
338
+ result = @oauth.get_token_from_session_key(@oauth_data["session_key"])
339
+ result.should be_a(String)
340
+ end
341
+
342
+ it "should be the first value in the array" do
343
+ result = @oauth.get_token_from_session_key(@oauth_data["session_key"])
344
+ array = @oauth.get_tokens_from_session_keys([@oauth_data["session_key"]])
345
+ result.should == array[0]
346
+ end
347
+
348
+ it "should properly handle an invalid session key" do
349
+ result = @oauth.get_token_from_session_key("foo")
350
+ result.should be_nil
351
+ end
352
+ end
353
+ end
354
+
355
+ describe "for parsing signed requests" do
356
+ # the signed request code is ported directly from Facebook
357
+ # so we only need to test at a high level that it works
358
+ it "should throw an error if the algorithm is unsupported" do
359
+ JSON.stub!(:parse).and_return("algorithm" => "my fun algorithm")
360
+ lambda { @oauth.parse_signed_request(@signed_request) }.should raise_error
361
+ end
362
+
363
+ it "should throw an error if the signature is invalid" do
364
+ OpenSSL::HMAC.stub!(:hexdigest).and_return("i'm an invalid signature")
365
+ lambda { @oauth.parse_signed_request(@signed_request) }.should raise_error
366
+ end
367
+
368
+ it "properly parses requests" do
369
+ @oauth = Koala::Facebook::OAuth.new(@app_id, @secret || @app_secret)
370
+ @oauth.parse_signed_request(@signed_params).should == @signed_params_result
371
+ end
372
+ end
373
+
374
+ end # describe
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Koala::Facebook::RealtimeUpdates" do
4
+ before :all do
5
+ # get oauth data
6
+ @oauth_data = $testing_data["oauth_test_data"]
7
+ @app_id = @oauth_data["app_id"]
8
+ @secret = @oauth_data["secret"]
9
+ @callback_url = @oauth_data["callback_url"]
10
+ @app_access_token = @oauth_data["app_access_token"]
11
+
12
+ # check OAuth data
13
+ unless @app_id && @secret && @callback_url && @app_access_token
14
+ raise Exception, "Must supply OAuth app id, secret, app_access_token, and callback to run live subscription tests!"
15
+ end
16
+
17
+ # get subscription data
18
+ @subscription_data = $testing_data["subscription_test_data"]
19
+ @verify_token = @subscription_data["verify_token"]
20
+ @challenge_data = @subscription_data["challenge_data"]
21
+ @subscription_path = @subscription_data["subscription_path"]
22
+
23
+ # check subscription data
24
+ unless @verify_token && @challenge_data && @subscription_path
25
+ raise Exception, "Must supply verify_token and equivalent challenge_data to run live subscription tests!"
26
+ end
27
+ end
28
+
29
+ describe "when initializing" do
30
+ # basic initialization
31
+ it "should initialize properly with an app_id and an app_access_token" do
32
+ updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
33
+ updates.should be_a(Koala::Facebook::RealtimeUpdates)
34
+ end
35
+
36
+ # attributes
37
+ it "should allow read access to app_id, app_access_token, and secret" do
38
+ updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
39
+ # this should not throw errors
40
+ updates.app_id && updates.app_access_token && updates.secret
41
+ end
42
+
43
+ it "should not allow write access to app_id" do
44
+ updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
45
+ # this should not throw errors
46
+ lambda { updates.app_id = 2 }.should raise_error(NoMethodError)
47
+ end
48
+
49
+ it "should not allow write access to app_access_token" do
50
+ updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
51
+ # this should not throw errors
52
+ lambda { updates.app_access_token = 2 }.should raise_error(NoMethodError)
53
+ end
54
+
55
+ it "should not allow write access to secret" do
56
+ updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :app_access_token => @app_access_token)
57
+ # this should not throw errors
58
+ lambda { updates.secret = 2 }.should raise_error(NoMethodError)
59
+ end
60
+
61
+ # init with secret / fetching the token
62
+ it "should initialize properly with an app_id and a secret" do
63
+ updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
64
+ updates.should be_a(Koala::Facebook::RealtimeUpdates)
65
+ end
66
+
67
+ it "should fetch an app_token from Facebook when provided an app_id and a secret" do
68
+ updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
69
+ updates.app_access_token.should_not be_nil
70
+ end
71
+
72
+ it "should use the OAuth class to fetch a token when provided an app_id and a secret" do
73
+ oauth = Koala::Facebook::OAuth.new(@app_id, @secret)
74
+ token = oauth.get_app_access_token
75
+ oauth.should_receive(:get_app_access_token).and_return(token)
76
+ Koala::Facebook::OAuth.should_receive(:new).with(@app_id, @secret).and_return(oauth)
77
+ updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
78
+ end
79
+ end
80
+
81
+ describe "when used" do
82
+ before :each do
83
+ @updates = Koala::Facebook::RealtimeUpdates.new(:app_id => @app_id, :secret => @secret)
84
+ end
85
+
86
+ it "should send a subscription request to a valid server" do
87
+ result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
88
+ result.should be_true
89
+ end
90
+
91
+ it "should send a subscription request to a valid server" do
92
+ result = @updates.subscribe("user", "name", @subscription_path, @verify_token)
93
+ result.should be_true
94
+ end
95
+
96
+ it "should send a subscription request to an invalid path on a valid server" do
97
+ lambda { result = @updates.subscribe("user", "name", @subscription_path + "foo", @verify_token) }.should raise_exception(Koala::Facebook::APIError)
98
+ end
99
+
100
+ it "should fail to send a subscription request to an invalid server" do
101
+ lambda { @updates.subscribe("user", "name", "foo", @verify_token) }.should raise_exception(Koala::Facebook::APIError)
102
+ end
103
+
104
+ it "should unsubscribe a valid individual object successfully" do
105
+ @updates.unsubscribe("user").should be_true
106
+ end
107
+
108
+ it "should unsubscribe all subscriptions successfully" do
109
+ @updates.unsubscribe.should be_true
110
+ end
111
+
112
+ it "should fail when an invalid object is provided to unsubscribe" do
113
+ lambda { @updates.unsubscribe("kittens") }.should raise_error(Koala::Facebook::APIError)
114
+ end
115
+
116
+ it "should is subscriptions properly" do
117
+ @updates.list_subscriptions.should be_a(Array)
118
+ end
119
+ end # describe "when used"
120
+
121
+ describe "when meeting challenge" do
122
+ it "should return false if hub.mode isn't subscribe" do
123
+ params = {'hub.mode' => 'not subscribe'}
124
+ Koala::Facebook::RealtimeUpdates.meet_challenge(params).should be_false
125
+ end
126
+
127
+ it "should return false if not given a verify_token or block" do
128
+ params = {'hub.mode' => 'subscribe'}
129
+ Koala::Facebook::RealtimeUpdates.meet_challenge(params).should be_false
130
+ end
131
+
132
+ describe "and mode is 'subscribe'" do
133
+ before(:each) do
134
+ @params = {'hub.mode' => 'subscribe'}
135
+ end
136
+
137
+ describe "and a token is given" do
138
+ before(:each) do
139
+ @token = 'token'
140
+ @params['hub.verify_token'] = @token
141
+ end
142
+
143
+ it "should return false if the given verify token doesn't match" do
144
+ Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token + '1').should be_false
145
+ end
146
+
147
+ it "should return the challenge if the given verify token matches" do
148
+ @params['hub.challenge'] = 'challenge val'
149
+ Koala::Facebook::RealtimeUpdates.meet_challenge(@params, @token).should == @params['hub.challenge']
150
+ end
151
+ end
152
+
153
+ describe "and a block is given" do
154
+ it "should give the block the token as a parameter" do
155
+ Koala::Facebook::RealtimeUpdates.meet_challenge(@params)do |token|
156
+ token.should == @token
157
+ end
158
+ end
159
+
160
+ it "should return false if the given block return false" do
161
+ Koala::Facebook::RealtimeUpdates.meet_challenge(@params)do |token|
162
+ false
163
+ end.should be_false
164
+ end
165
+
166
+ it "should return false if the given block returns nil" do
167
+ Koala::Facebook::RealtimeUpdates.meet_challenge(@params)do |token|
168
+ nil
169
+ end.should be_false
170
+ end
171
+
172
+ it "should return the challenge if the given block returns true" do
173
+ @params['hub.challenge'] = 'challenge val'
174
+ Koala::Facebook::RealtimeUpdates.meet_challenge(@params) do |token|
175
+ true
176
+ end.should be_true
177
+ end
178
+ end
179
+
180
+ end # describe "and mode is subscribe"
181
+
182
+ end # describe "when meeting challenge"
183
+
184
+ end # describe