koala 0.10.0 → 1.0.0.beta2
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/CHANGELOG +33 -7
- data/Manifest +8 -1
- data/Rakefile +4 -4
- data/koala.gemspec +10 -8
- data/lib/koala/graph_api.rb +188 -123
- data/lib/koala/http_services.rb +93 -17
- data/lib/koala/rest_api.rb +73 -6
- data/lib/koala/test_users.rb +18 -5
- data/lib/koala/uploadable_io.rb +115 -0
- data/lib/koala.rb +95 -72
- data/readme.md +18 -12
- data/spec/facebook_data.yml +9 -3
- data/spec/koala/assets/beach.jpg +0 -0
- data/spec/koala/graph_and_rest_api/graph_and_rest_api_no_token_tests.rb +5 -1
- data/spec/koala/graph_and_rest_api/graph_and_rest_api_with_token_tests.rb +8 -3
- data/spec/koala/graph_api/graph_api_no_access_token_tests.rb +12 -61
- data/spec/koala/graph_api/graph_api_tests.rb +85 -0
- data/spec/koala/graph_api/graph_api_with_access_token_tests.rb +167 -123
- data/spec/koala/http_services/http_service_tests.rb +51 -0
- data/spec/koala/http_services/net_http_service_tests.rb +339 -0
- data/spec/koala/http_services/typhoeus_service_tests.rb +162 -0
- data/spec/koala/live_testing_data_helper.rb +1 -1
- data/spec/koala/oauth/oauth_tests.rb +35 -64
- data/spec/koala/rest_api/rest_api_no_access_token_tests.rb +5 -74
- data/spec/koala/rest_api/rest_api_tests.rb +118 -0
- data/spec/koala/rest_api/rest_api_with_access_token_tests.rb +5 -3
- data/spec/koala/test_users/test_users_tests.rb +49 -48
- data/spec/koala/uploadable_io/uploadable_io_tests.rb +246 -0
- data/spec/koala_spec_helper.rb +30 -4
- data/spec/koala_spec_without_mocks.rb +3 -3
- data/spec/mock_facebook_responses.yml +41 -18
- data/spec/mock_http_service.rb +16 -3
- metadata +38 -8
- data/spec/koala/net_http_service_tests.rb +0 -186
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
require 'koala/http_services'
|
|
2
|
+
class NetHTTPServiceTests < Test::Unit::TestCase
|
|
3
|
+
module Bear
|
|
4
|
+
include Koala::NetHTTPService
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
describe "NetHTTPService module holder class Bear" do
|
|
8
|
+
before :each do
|
|
9
|
+
# reset the always_use_ssl parameter
|
|
10
|
+
Bear.always_use_ssl = nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should define a make_request static module method" do
|
|
14
|
+
Bear.respond_to?(:make_request).should be_true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should include the Koala::HTTPService module defining common features" do
|
|
18
|
+
Bear.included_modules.include?(Koala::HTTPService).should be_true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe "when making a request" do
|
|
22
|
+
before(:each) do
|
|
23
|
+
# Setup stubs for make_request to execute without exceptions
|
|
24
|
+
@mock_http_response = stub('Net::HTTPResponse', :code => 1)
|
|
25
|
+
@mock_body = stub('Net::HTTPResponse body')
|
|
26
|
+
@http_request_result = [@mock_http_response, @mock_body]
|
|
27
|
+
|
|
28
|
+
# to_ary is called in Ruby 1.9 to provide backwards compatibility
|
|
29
|
+
# with the response, body = http.get() syntax we use
|
|
30
|
+
@mock_http_response.stub!(:to_ary).and_return(@http_request_result)
|
|
31
|
+
|
|
32
|
+
@http_yield_mock = mock('Net::HTTP start yielded object')
|
|
33
|
+
|
|
34
|
+
@http_yield_mock.stub(:post).and_return(@http_request_result)
|
|
35
|
+
@http_yield_mock.stub(:get).and_return(@http_request_result)
|
|
36
|
+
|
|
37
|
+
@http_mock = stub('Net::HTTP object', 'use_ssl=' => true, 'verify_mode=' => true)
|
|
38
|
+
@http_mock.stub(:start).and_yield(@http_yield_mock)
|
|
39
|
+
|
|
40
|
+
Net::HTTP.stub(:new).and_return(@http_mock)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "the connection" do
|
|
44
|
+
it "should use POST if verb is not GET" do
|
|
45
|
+
@http_yield_mock.should_receive(:post).and_return(@mock_http_response)
|
|
46
|
+
@http_mock.should_receive(:start).and_yield(@http_yield_mock)
|
|
47
|
+
|
|
48
|
+
Bear.make_request('anything', {}, 'anything')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should use GET if that verb is specified" do
|
|
52
|
+
@http_yield_mock.should_receive(:get).and_return(@mock_http_response)
|
|
53
|
+
@http_mock.should_receive(:start).and_yield(@http_yield_mock)
|
|
54
|
+
|
|
55
|
+
Bear.make_request('anything', {}, 'get')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should add the method to the arguments if it's not get or post" do
|
|
59
|
+
args = {}
|
|
60
|
+
method = "telekenesis"
|
|
61
|
+
# since the arguments get encoded later, we'll test for merge!
|
|
62
|
+
# even though that's somewhat testing internal implementation
|
|
63
|
+
args.should_receive(:merge!).with(:method => method)
|
|
64
|
+
|
|
65
|
+
Bear.make_request('anything', args, method)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe "if the request has an access token" do
|
|
70
|
+
before :each do
|
|
71
|
+
@args = {"access_token" => "123"}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should use SSL" do
|
|
75
|
+
@http_mock.should_receive('use_ssl=').with(true)
|
|
76
|
+
|
|
77
|
+
Bear.make_request('anything', @args, 'anything')
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should set the port to 443" do
|
|
81
|
+
Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
|
|
82
|
+
|
|
83
|
+
Bear.make_request('anything', @args, 'anything')
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe "if always_use_ssl is true" do
|
|
88
|
+
before :each do
|
|
89
|
+
Bear.always_use_ssl = true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should use SSL" do
|
|
93
|
+
@http_mock.should_receive('use_ssl=').with(true)
|
|
94
|
+
|
|
95
|
+
Bear.make_request('anything', {}, 'anything')
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should set the port to 443" do
|
|
99
|
+
Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
|
|
100
|
+
|
|
101
|
+
Bear.make_request('anything', {}, 'anything')
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe "if the use_ssl option is provided" do
|
|
106
|
+
it "should use SSL" do
|
|
107
|
+
@http_mock.should_receive('use_ssl=').with(true)
|
|
108
|
+
|
|
109
|
+
Bear.make_request('anything', {}, 'anything', :use_ssl => true)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "should set the port to 443" do
|
|
113
|
+
Net::HTTP.should_receive(:new).with(anything, 443).and_return(@http_mock)
|
|
114
|
+
|
|
115
|
+
Bear.make_request('anything', {}, 'anything', :use_ssl => true)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe "if there's no token and always_use_ssl isn't true" do
|
|
120
|
+
it "should not use SSL" do
|
|
121
|
+
@http_mock.should_not_receive('use_ssl=')
|
|
122
|
+
Bear.make_request('anything', {}, 'anything')
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "should not set the port" do
|
|
126
|
+
Net::HTTP.should_receive(:new).with(anything, nil).and_return(@http_mock)
|
|
127
|
+
Bear.make_request('anything', {}, 'anything')
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "should use the graph server by default" do
|
|
132
|
+
Net::HTTP.should_receive(:new).with(Koala::Facebook::GRAPH_SERVER, anything).and_return(@http_mock)
|
|
133
|
+
Bear.make_request('anything', {}, 'anything')
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "should use the REST server if the :rest_api option is true" do
|
|
137
|
+
Net::HTTP.should_receive(:new).with(Koala::Facebook::REST_SERVER, anything).and_return(@http_mock)
|
|
138
|
+
Bear.make_request('anything', {}, 'anything', :rest_api => true)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "should turn off vertificate validaiton warnings" do
|
|
142
|
+
@http_mock.should_receive('verify_mode=').with(OpenSSL::SSL::VERIFY_NONE)
|
|
143
|
+
|
|
144
|
+
Bear.make_request('anything', {}, 'anything')
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "should start an HTTP connection" do
|
|
148
|
+
@http_mock.should_receive(:start).and_yield(@http_yield_mock)
|
|
149
|
+
Bear.make_request('anything', {}, 'anything')
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe "via POST" do
|
|
153
|
+
it "should use Net::HTTP to make a POST request" do
|
|
154
|
+
@http_yield_mock.should_receive(:post).and_return(@http_request_result)
|
|
155
|
+
|
|
156
|
+
Bear.make_request('anything', {}, 'post')
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "should go to the specified path adding a / if it doesn't exist" do
|
|
160
|
+
path = mock('Path')
|
|
161
|
+
@http_yield_mock.should_receive(:post).with(path, anything).and_return(@http_request_result)
|
|
162
|
+
|
|
163
|
+
Bear.make_request(path, {}, 'post')
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "should use encoded parameters" do
|
|
167
|
+
args = {}
|
|
168
|
+
params = mock('Encoded parameters')
|
|
169
|
+
Bear.should_receive(:encode_params).with(args).and_return(params)
|
|
170
|
+
|
|
171
|
+
@http_yield_mock.should_receive(:post).with(anything, params).and_return(@http_request_result)
|
|
172
|
+
|
|
173
|
+
Bear.make_request('anything', args, 'post')
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
describe "with multipart/form-data" do
|
|
177
|
+
before(:each) do
|
|
178
|
+
Bear.stub(:encode_multipart_params)
|
|
179
|
+
Bear.stub("params_require_multipart?").and_return(true)
|
|
180
|
+
|
|
181
|
+
@multipart_request_stub = stub('Stub Multipart Request')
|
|
182
|
+
Net::HTTP::Post::Multipart.stub(:new).and_return(@multipart_request_stub)
|
|
183
|
+
|
|
184
|
+
@file_stub = stub('fake File', "kind_of?" => true, "path" => 'anypath.jpg')
|
|
185
|
+
|
|
186
|
+
@http_yield_mock.stub(:request).with(@multipart_request_stub).and_return(@http_request_result)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "should use multipart/form-data if any parameter is a valid file hash" do
|
|
190
|
+
@http_yield_mock.should_receive(:request).with(@multipart_request_stub).and_return(@http_request_result)
|
|
191
|
+
|
|
192
|
+
Bear.make_request('anything', {}, 'post')
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "should use the given request path for the request" do
|
|
196
|
+
args = {"file" => @file_stub}
|
|
197
|
+
expected_path = 'expected/path'
|
|
198
|
+
|
|
199
|
+
Net::HTTP::Post::Multipart.should_receive(:new).with(expected_path, anything).and_return(@multipart_request_stub)
|
|
200
|
+
|
|
201
|
+
Bear.make_request(expected_path, {}, 'post')
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "should use multipart encoded arguments for the request" do
|
|
205
|
+
args = {"file" => @file_stub}
|
|
206
|
+
expected_params = stub('Stub Multipart Params')
|
|
207
|
+
|
|
208
|
+
Bear.should_receive(:encode_multipart_params).with(args).and_return(expected_params)
|
|
209
|
+
Net::HTTP::Post::Multipart.should_receive(:new).with(anything, expected_params).and_return(@multipart_request_stub)
|
|
210
|
+
|
|
211
|
+
Bear.make_request('anything', args, 'post')
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
describe "via GET" do
|
|
217
|
+
it "should use Net::HTTP to make a GET request" do
|
|
218
|
+
@http_yield_mock.should_receive(:get).and_return(@http_request_result)
|
|
219
|
+
|
|
220
|
+
Bear.make_request('anything', {}, 'get')
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "should use the correct path, including arguments" do
|
|
224
|
+
path = mock('Path')
|
|
225
|
+
params = mock('Encoded parameters')
|
|
226
|
+
args = {}
|
|
227
|
+
|
|
228
|
+
Bear.should_receive(:encode_params).with(args).and_return(params)
|
|
229
|
+
@http_yield_mock.should_receive(:get).with("#{path}?#{params}").and_return(@http_request_result)
|
|
230
|
+
|
|
231
|
+
Bear.make_request(path, args, 'get')
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
describe "the returned value" do
|
|
236
|
+
before(:each) do
|
|
237
|
+
@response = Bear.make_request('anything', {}, 'anything')
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "should return a Koala::Response object" do
|
|
241
|
+
@response.class.should == Koala::Response
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it "should return a Koala::Response with the right status" do
|
|
245
|
+
@response.status.should == @mock_http_response.code
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "should reutrn a Koala::Response with the right body" do
|
|
249
|
+
@response.body.should == @mock_body
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "should return a Koala::Response with the Net::HTTPResponse object as headers" do
|
|
253
|
+
@response.headers.should == @mock_http_response
|
|
254
|
+
end
|
|
255
|
+
end # describe return value
|
|
256
|
+
end # describe when making a request
|
|
257
|
+
|
|
258
|
+
describe "when encoding parameters" do
|
|
259
|
+
it "should return an empty string if param_hash evaluates to false" do
|
|
260
|
+
Bear.encode_params(nil).should == ''
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it "should convert values to JSON if the value is not a String" do
|
|
264
|
+
val = 'json_value'
|
|
265
|
+
not_a_string = 'not_a_string'
|
|
266
|
+
not_a_string.stub(:class).and_return('NotAString')
|
|
267
|
+
not_a_string.should_receive(:to_json).and_return(val)
|
|
268
|
+
|
|
269
|
+
string = "hi"
|
|
270
|
+
|
|
271
|
+
args = {
|
|
272
|
+
not_a_string => not_a_string,
|
|
273
|
+
string => string
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
result = Bear.encode_params(args)
|
|
277
|
+
result.split('&').find do |key_and_val|
|
|
278
|
+
key_and_val.match("#{not_a_string}=#{val}")
|
|
279
|
+
end.should be_true
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "should escape all values" do
|
|
283
|
+
args = Hash[*(1..4).map {|i| [i.to_s, "Value #{i}($"]}.flatten]
|
|
284
|
+
|
|
285
|
+
result = Bear.encode_params(args)
|
|
286
|
+
result.split('&').each do |key_val|
|
|
287
|
+
key, val = key_val.split('=')
|
|
288
|
+
val.should == CGI.escape(args[key])
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it "should convert all keys to Strings" do
|
|
293
|
+
args = Hash[*(1..4).map {|i| [i, "val#{i}"]}.flatten]
|
|
294
|
+
|
|
295
|
+
result = Bear.encode_params(args)
|
|
296
|
+
result.split('&').each do |key_val|
|
|
297
|
+
key, val = key_val.split('=')
|
|
298
|
+
key.should == args.find{|key_val_arr| key_val_arr.last == val}.first.to_s
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
describe "when detecting if multipart posting is needed" do
|
|
304
|
+
it "should be true if any parameter value requires multipart post" do
|
|
305
|
+
koala_io = mock("Koala::IO")
|
|
306
|
+
koala_io.should_receive(:kind_of?).with(Koala::UploadableIO).and_return(true)
|
|
307
|
+
|
|
308
|
+
args = {
|
|
309
|
+
"key1" => "val",
|
|
310
|
+
"key2" => "val",
|
|
311
|
+
"key3" => koala_io,
|
|
312
|
+
"key4" => "val"
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
Bear.params_require_multipart?(args).should be_true
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
describe "when encoding multipart/form-data params" do
|
|
319
|
+
it "should replace Koala::UploadableIO values with UploadIO values" do
|
|
320
|
+
upload_io = UploadIO.new(__FILE__, "fake type")
|
|
321
|
+
|
|
322
|
+
uploadable_io = stub('Koala::UploadableIO')
|
|
323
|
+
uploadable_io.should_receive(:kind_of?).with(Koala::UploadableIO).and_return(true)
|
|
324
|
+
uploadable_io.should_receive(:to_upload_io).and_return(upload_io)
|
|
325
|
+
args = {
|
|
326
|
+
"not_a_file" => "not a file",
|
|
327
|
+
"file" => uploadable_io
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
result = Bear.encode_multipart_params(args)
|
|
331
|
+
|
|
332
|
+
result["not_a_file"] == args["not_a_file"]
|
|
333
|
+
result["file"] == upload_io
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
require 'koala/http_services'
|
|
2
|
+
class TyphoeusServiceTests < Test::Unit::TestCase
|
|
3
|
+
module Bear
|
|
4
|
+
include Koala::TyphoeusService
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
describe "TyphoeusService module holder class Bear" do
|
|
8
|
+
before :each do
|
|
9
|
+
# reset the always_use_ssl parameter
|
|
10
|
+
Bear.always_use_ssl = nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should define a make_request static module method" do
|
|
14
|
+
Bear.respond_to?(:make_request).should be_true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should include the Koala::HTTPService module defining common features" do
|
|
18
|
+
Bear.included_modules.include?(Koala::HTTPService).should be_true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe "when making a request" do
|
|
22
|
+
before(:each) do
|
|
23
|
+
# Setup stubs for make_request to execute without exceptions
|
|
24
|
+
@mock_body = stub('Typhoeus response body')
|
|
25
|
+
@mock_headers_hash = stub({:value => "headers hash"})
|
|
26
|
+
@mock_http_response = stub(Typhoeus::Response, :code => 1, :headers_hash => @mock_headers_hash, :body => @mock_body)
|
|
27
|
+
|
|
28
|
+
# Typhoeus is an included module, so we stub methods on Bear itself
|
|
29
|
+
Bear.stub(:post).and_return(@mock_http_response)
|
|
30
|
+
Bear.stub(:get).and_return(@mock_http_response)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should use POST if verb is not GET" do
|
|
34
|
+
Bear.should_receive(:post).and_return(@mock_http_response)
|
|
35
|
+
Bear.make_request('anything', {}, 'anything')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should use GET if that verb is specified" do
|
|
39
|
+
Bear.should_receive(:get).and_return(@mock_http_response)
|
|
40
|
+
Bear.make_request('anything', {}, 'get')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "the connection" do
|
|
44
|
+
it "should use SSL if the request has an access token" do
|
|
45
|
+
Bear.should_receive(:post).with(/https\:/, anything)
|
|
46
|
+
|
|
47
|
+
Bear.make_request('anything', {"access_token" => "123"}, 'anything')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should use SSL if always_use_ssl is true, even if there's no token" do
|
|
51
|
+
Bear.should_receive(:post).with(/https\:/, anything)
|
|
52
|
+
|
|
53
|
+
Bear.always_use_ssl = true
|
|
54
|
+
Bear.make_request('anything', {}, 'anything')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "should use SSL if the :use_ssl option is provided, even if there's no token" do
|
|
58
|
+
Bear.should_receive(:post).with(/https\:/, anything)
|
|
59
|
+
|
|
60
|
+
Bear.always_use_ssl = true
|
|
61
|
+
Bear.make_request('anything', {}, 'anything', :use_ssl => true)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should not use SSL if always_use_ssl is false and there's no token" do
|
|
65
|
+
Bear.should_receive(:post).with(/http\:/, anything)
|
|
66
|
+
|
|
67
|
+
Bear.make_request('anything', {}, 'anything')
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "should use the graph server by default" do
|
|
71
|
+
Bear.should_receive(:post).with(Regexp.new(Koala::Facebook::GRAPH_SERVER), anything)
|
|
72
|
+
|
|
73
|
+
Bear.make_request('anything', {}, 'anything')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should use the REST server if the :rest_api option is true" do
|
|
77
|
+
Bear.should_receive(:post).with(Regexp.new(Koala::Facebook::REST_SERVER), anything)
|
|
78
|
+
|
|
79
|
+
Bear.make_request('anything', {}, 'anything', :rest_api => true)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "should pass the arguments to Typhoeus under the :params key" do
|
|
84
|
+
args = {:a => 2}
|
|
85
|
+
Bear.should_receive(:post).with(anything, hash_including(:params => args))
|
|
86
|
+
|
|
87
|
+
Bear.make_request('anything', args, "post")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "should add the method to the arguments if the method isn't get or post" do
|
|
91
|
+
method = "telekenesis"
|
|
92
|
+
Bear.should_receive(:post).with(anything, hash_including(:params => {:method => method}))
|
|
93
|
+
|
|
94
|
+
Bear.make_request('anything', {}, method)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should pass :typhoeus_options to Typhoeus if provided" do
|
|
98
|
+
t_options = {:a => :b}
|
|
99
|
+
Bear.should_receive(:post).with(anything, hash_including(t_options))
|
|
100
|
+
|
|
101
|
+
Bear.make_request("anything", {}, "post", :typhoeus_options => t_options)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "should include the path in the request" do
|
|
105
|
+
path = "/a/b/c/1"
|
|
106
|
+
Bear.should_receive(:post).with(Regexp.new(path), anything)
|
|
107
|
+
|
|
108
|
+
Bear.make_request(path, {}, "post")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe "the returned value" do
|
|
112
|
+
before(:each) do
|
|
113
|
+
@response = Bear.make_request('anything', {}, 'anything')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "should return a Koala::Response object" do
|
|
117
|
+
@response.class.should == Koala::Response
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "should return a Koala::Response with the right status" do
|
|
121
|
+
@response.status.should == @mock_http_response.code
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "should reutrn a Koala::Response with the right body" do
|
|
125
|
+
@response.body.should == @mock_body
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should return a Koala::Response with the Net::HTTPResponse object as headers" do
|
|
129
|
+
@response.headers.should == @mock_headers_hash
|
|
130
|
+
end
|
|
131
|
+
end # describe return value
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
describe "with file upload" do
|
|
135
|
+
it "should include an interface to NetHTTPService called NetHTTPInterface" do
|
|
136
|
+
# we should be able to access it
|
|
137
|
+
lambda { Koala::TyphoeusService::NetHTTPInterface }.should_not raise_exception(Exception)
|
|
138
|
+
Koala::TyphoeusService::NetHTTPInterface.included_modules.include?(Koala::NetHTTPService).should be_true
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "should call the NetHTTPInterface if multipart is required" do
|
|
142
|
+
method = "any_method"
|
|
143
|
+
args = {}
|
|
144
|
+
verb = "get"
|
|
145
|
+
options = {}
|
|
146
|
+
|
|
147
|
+
Bear.stub(:params_require_multipart?).and_return(true)
|
|
148
|
+
Koala::TyphoeusService::NetHTTPInterface.should_receive(:make_request).with(method, args, verb, options)
|
|
149
|
+
|
|
150
|
+
Bear.make_request(method, args, verb, options)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Typhoeus file uploads currently don't work
|
|
154
|
+
# for live tests, run the Graph API tests with Typhoues, which will run file uploads
|
|
155
|
+
# it "should pass any files directly on to Typhoues" do
|
|
156
|
+
# args = {:file => File.new(__FILE__, "r")}
|
|
157
|
+
# Bear.should_receive(:post).with(anything, hash_including(:params => args)).and_return(Typhoeus::Response.new)
|
|
158
|
+
# Bear.make_request("anything", args, :post)
|
|
159
|
+
# end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -19,7 +19,7 @@ module LiveTestingDataHelper
|
|
|
19
19
|
errors = []
|
|
20
20
|
|
|
21
21
|
if count > 0
|
|
22
|
-
print "\nCleaning up #{count} temporary #{count > 1 ? "objects" : "object"}..."
|
|
22
|
+
print "\nCleaning up #{count} temporary #{count > 1 ? "objects" : "object (#{@temporary_object_ids.first})"}..."
|
|
23
23
|
@temporary_object_ids.each do |id|
|
|
24
24
|
# get our API
|
|
25
25
|
api = @api || (@test_users ? @test_users.graph_api : nil)
|
|
@@ -16,6 +16,10 @@ class FacebookOAuthTests < Test::Unit::TestCase
|
|
|
16
16
|
@request_secret = @oauth_data["request_secret"] || @secret
|
|
17
17
|
@signed_request = @oauth_data["signed_request"]
|
|
18
18
|
@signed_request_result = @oauth_data["signed_request_result"]
|
|
19
|
+
# for signed requests (http://developers.facebook.com/docs/authentication/canvas/encryption_proposal)
|
|
20
|
+
@signed_params_secret = @oauth_data["signed_params_secret"] || @secret
|
|
21
|
+
@signed_params = @oauth_data["signed_params"]
|
|
22
|
+
@signed_params_result = @oauth_data["signed_params_result"]
|
|
19
23
|
|
|
20
24
|
# this should expanded to cover all variables
|
|
21
25
|
raise Exception, "Must supply app data to run FacebookOAuthTests!" unless @app_id && @secret && @callback_url &&
|
|
@@ -24,9 +28,9 @@ class FacebookOAuthTests < Test::Unit::TestCase
|
|
|
24
28
|
|
|
25
29
|
@oauth = Koala::Facebook::OAuth.new(@app_id, @secret, @callback_url)
|
|
26
30
|
|
|
27
|
-
time = Time.now
|
|
28
|
-
Time.stub!(:now).and_return(time)
|
|
29
|
-
time.stub!(:to_i).and_return(1273363199)
|
|
31
|
+
@time = Time.now
|
|
32
|
+
Time.stub!(:now).and_return(@time)
|
|
33
|
+
@time.stub!(:to_i).and_return(1273363199)
|
|
30
34
|
end
|
|
31
35
|
|
|
32
36
|
# initialization
|
|
@@ -356,81 +360,48 @@ class FacebookOAuthTests < Test::Unit::TestCase
|
|
|
356
360
|
@oauth = Koala::Facebook::OAuth.new(@app_id, @request_secret || @app_secret)
|
|
357
361
|
end
|
|
358
362
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
363
|
+
# the signed request code comes directly from Facebook
|
|
364
|
+
# so we only need to test at a high level that it works
|
|
365
|
+
# signed params refers to http://developers.facebook.com/docs/authentication/canvas
|
|
366
|
+
# signed request refers to http://developers.facebook.com/docs/authentication/canvas/encryption_proposal
|
|
367
|
+
it "should throw an error if the algorithm is unsupported" do
|
|
368
|
+
JSON.stub!(:parse).and_return("algorithm" => "my fun algorithm")
|
|
369
|
+
lambda { @oauth.parse_signed_request(@signed_request) }.should raise_error
|
|
362
370
|
end
|
|
363
371
|
|
|
364
|
-
it "should
|
|
365
|
-
|
|
366
|
-
@
|
|
367
|
-
@oauth.should_receive(:base64_url_decode).with(sig).and_return("4")
|
|
368
|
-
@oauth.parse_signed_request(@signed_request)
|
|
372
|
+
it "should throw an error if the signature is invalid" do
|
|
373
|
+
OpenSSL::HMAC.stub!(:hexdigest).and_return("i'm an invalid signature")
|
|
374
|
+
lambda { @oauth.parse_signed_request(@signed_request) }.should raise_error
|
|
369
375
|
end
|
|
370
376
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
end
|
|
376
|
-
|
|
377
|
-
it "should get the sha64 encoded payload using proper arguments from OpenSSL::HMAC" do
|
|
378
|
-
payload = ""
|
|
379
|
-
@signed_request.should_receive(:split).with(".").and_return(["1", payload])
|
|
380
|
-
OpenSSL::HMAC.should_receive(:digest).with("sha256", @request_secret, payload)
|
|
381
|
-
@oauth.parse_signed_request(@signed_request)
|
|
377
|
+
describe "for signed params" do
|
|
378
|
+
it "should work" do
|
|
379
|
+
@oauth.parse_signed_request(@signed_request).should == @signed_request_result
|
|
380
|
+
end
|
|
382
381
|
end
|
|
383
382
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
OpenSSL::HMAC.should_receive(:digest).with(anything, anything, anything).and_return(encoded_payload)
|
|
389
|
-
encoded_payload.should_receive(:==).with(sig)
|
|
390
|
-
@oauth.parse_signed_request(@signed_request)
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
describe "if the encoded payload matches the signature" do
|
|
394
|
-
before :each do
|
|
395
|
-
# set it up so the sig will match the encoded payload
|
|
396
|
-
raw_sig = ""
|
|
397
|
-
@sig = "2"
|
|
398
|
-
@payload = "1"
|
|
399
|
-
@signed_request.should_receive(:split).and_return([raw_sig, @payload])
|
|
400
|
-
@oauth.should_receive(:base64_url_decode).with(raw_sig).and_return(@sig)
|
|
401
|
-
OpenSSL::HMAC.should_receive(:digest).with(anything, anything, anything).and_return(@sig.dup)
|
|
383
|
+
describe "for signed requests" do
|
|
384
|
+
it "should work" do
|
|
385
|
+
@oauth = Koala::Facebook::OAuth.new(@app_id, @signed_params_secret || @app_secret)
|
|
386
|
+
@oauth.parse_signed_request(@signed_params).should == @signed_params_result
|
|
402
387
|
end
|
|
403
388
|
|
|
404
|
-
it "should
|
|
405
|
-
@
|
|
406
|
-
@oauth.
|
|
389
|
+
it "should throw an error if the params are too old" do
|
|
390
|
+
@time.stub!(:to_i).and_return(1287601988 + 4000)
|
|
391
|
+
@oauth = Koala::Facebook::OAuth.new(@app_id, @signed_params_secret || @app_secret)
|
|
392
|
+
|
|
393
|
+
lambda { @oauth.parse_signed_request(@signed_params) }.should raise_error
|
|
407
394
|
end
|
|
408
395
|
|
|
409
|
-
it "should
|
|
410
|
-
|
|
411
|
-
@oauth.
|
|
412
|
-
|
|
413
|
-
@oauth.parse_signed_request(@
|
|
414
|
-
end
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
describe "if the encoded payload does not match the signature" do
|
|
418
|
-
before :each do
|
|
419
|
-
sig = ""
|
|
420
|
-
@signed_request.should_receive(:split).and_return([sig, ""])
|
|
421
|
-
OpenSSL::HMAC.should_receive(:digest).with(anything, anything, anything).and_return("hi")
|
|
396
|
+
it "should let you specify the max age for a request" do
|
|
397
|
+
@time.stub!(:to_i).and_return(1287601988 + 4000)
|
|
398
|
+
@oauth = Koala::Facebook::OAuth.new(@app_id, @signed_params_secret || @app_secret)
|
|
399
|
+
|
|
400
|
+
lambda { @oauth.parse_signed_request(@signed_params, 4001) }.should_not raise_error
|
|
422
401
|
end
|
|
423
402
|
|
|
424
|
-
it "should return nil" do
|
|
425
|
-
@oauth.parse_signed_request(@signed_request).should be_nil
|
|
426
|
-
end
|
|
427
403
|
end
|
|
428
404
|
|
|
429
|
-
describe "run against data" do
|
|
430
|
-
it "should work" do
|
|
431
|
-
@oauth.parse_signed_request(@signed_request).should == @signed_request_result
|
|
432
|
-
end
|
|
433
|
-
end
|
|
434
405
|
end
|
|
435
406
|
|
|
436
407
|
end # describe
|