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.
- data/.autotest +12 -0
- data/.gitignore +3 -1
- data/.travis.yml +9 -0
- data/CHANGELOG +62 -2
- data/Gemfile +8 -0
- data/Rakefile +0 -1
- data/autotest/discover.rb +1 -0
- data/koala.gemspec +13 -14
- data/lib/koala/batch_operation.rb +74 -0
- data/lib/koala/graph_api.rb +145 -132
- data/lib/koala/graph_batch_api.rb +97 -0
- data/lib/koala/graph_collection.rb +59 -0
- data/lib/koala/http_service.rb +176 -0
- data/lib/koala/oauth.rb +191 -0
- data/lib/koala/realtime_updates.rb +23 -29
- data/lib/koala/rest_api.rb +13 -8
- data/lib/koala/test_users.rb +33 -17
- data/lib/koala/uploadable_io.rb +153 -87
- data/lib/koala/utils.rb +11 -0
- data/lib/koala/version.rb +3 -0
- data/lib/koala.rb +59 -217
- data/readme.md +92 -53
- data/spec/cases/{api_base_spec.rb → api_spec.rb} +31 -6
- data/spec/cases/error_spec.rb +32 -0
- data/spec/cases/graph_and_rest_api_spec.rb +12 -21
- data/spec/cases/graph_api_batch_spec.rb +582 -0
- data/spec/cases/graph_api_spec.rb +11 -14
- data/spec/cases/graph_collection_spec.rb +116 -0
- data/spec/cases/http_service_spec.rb +446 -0
- data/spec/cases/koala_spec.rb +54 -0
- data/spec/cases/oauth_spec.rb +319 -213
- data/spec/cases/realtime_updates_spec.rb +45 -31
- data/spec/cases/rest_api_spec.rb +23 -7
- data/spec/cases/test_users_spec.rb +123 -75
- data/spec/cases/uploadable_io_spec.rb +120 -37
- data/spec/cases/utils_spec.rb +10 -0
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/facebook_data.yml +26 -24
- data/spec/fixtures/mock_facebook_responses.yml +203 -78
- data/spec/spec_helper.rb +30 -5
- data/spec/support/graph_api_shared_examples.rb +149 -118
- data/spec/support/json_testing_fix.rb +42 -0
- data/spec/support/koala_test.rb +187 -0
- data/spec/support/mock_http_service.rb +62 -58
- data/spec/support/ordered_hash.rb +205 -0
- data/spec/support/rest_api_shared_examples.rb +139 -15
- data/spec/support/uploadable_io_shared_examples.rb +2 -8
- metadata +90 -114
- data/lib/koala/http_services.rb +0 -146
- data/spec/cases/http_services/http_service_spec.rb +0 -54
- data/spec/cases/http_services/net_http_service_spec.rb +0 -350
- data/spec/cases/http_services/typhoeus_service_spec.rb +0 -144
- data/spec/support/live_testing_data_helper.rb +0 -40
- data/spec/support/setup_mocks_or_live.rb +0 -52
data/spec/cases/oauth_spec.rb
CHANGED
|
@@ -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
|
-
@
|
|
7
|
-
@
|
|
8
|
-
@
|
|
9
|
-
@
|
|
10
|
-
@
|
|
11
|
-
@
|
|
12
|
-
|
|
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 =
|
|
16
|
-
@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
|
-
@
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 "
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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 "
|
|
187
|
-
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
204
|
-
|
|
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
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
options
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
options
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
-
|
|
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
|