koala 1.0.0 → 1.1.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 (39) hide show
  1. data/.autotest +12 -0
  2. data/.gitignore +3 -1
  3. data/.travis.yml +8 -0
  4. data/CHANGELOG +26 -2
  5. data/Gemfile +4 -0
  6. data/autotest/discover.rb +1 -0
  7. data/koala.gemspec +8 -8
  8. data/lib/koala/batch_operation.rb +74 -0
  9. data/lib/koala/graph_api.rb +103 -102
  10. data/lib/koala/graph_batch_api.rb +87 -0
  11. data/lib/koala/graph_collection.rb +54 -0
  12. data/lib/koala/http_services/net_http_service.rb +92 -0
  13. data/lib/koala/http_services/typhoeus_service.rb +37 -0
  14. data/lib/koala/http_services.rb +13 -113
  15. data/lib/koala/oauth.rb +181 -0
  16. data/lib/koala/realtime_updates.rb +5 -14
  17. data/lib/koala/rest_api.rb +13 -8
  18. data/lib/koala/uploadable_io.rb +137 -77
  19. data/lib/koala.rb +36 -196
  20. data/readme.md +51 -32
  21. data/spec/cases/api_base_spec.rb +4 -4
  22. data/spec/cases/graph_api_batch_spec.rb +609 -0
  23. data/spec/cases/http_services/http_service_spec.rb +87 -12
  24. data/spec/cases/http_services/net_http_service_spec.rb +259 -77
  25. data/spec/cases/http_services/typhoeus_service_spec.rb +29 -21
  26. data/spec/cases/koala_spec.rb +55 -0
  27. data/spec/cases/oauth_spec.rb +1 -1
  28. data/spec/cases/realtime_updates_spec.rb +3 -3
  29. data/spec/cases/test_users_spec.rb +1 -1
  30. data/spec/cases/uploadable_io_spec.rb +56 -14
  31. data/spec/fixtures/cat.m4v +0 -0
  32. data/spec/fixtures/mock_facebook_responses.yml +100 -5
  33. data/spec/spec_helper.rb +2 -1
  34. data/spec/support/graph_api_shared_examples.rb +106 -35
  35. data/spec/support/json_testing_fix.rb +18 -0
  36. data/spec/support/mock_http_service.rb +57 -56
  37. data/spec/support/rest_api_shared_examples.rb +131 -7
  38. data/spec/support/setup_mocks_or_live.rb +3 -4
  39. metadata +34 -47
@@ -17,38 +17,113 @@ describe "Koala::HTTPService" do
17
17
  end
18
18
  end
19
19
 
20
+ describe "proxy accessor" do
21
+ it "should be added" do
22
+ # in Ruby 1.8, .methods returns strings
23
+ # in Ruby 1.9, .method returns symbols
24
+ Bear.methods.collect {|m| m.to_sym}.should include(:proxy)
25
+ Bear.methods.collect {|m| m.to_sym}.should include(:proxy=)
26
+ end
27
+ end
28
+
29
+ describe "timeout accessor" do
30
+ it "should be added" do
31
+ # in Ruby 1.8, .methods returns strings
32
+ # in Ruby 1.9, .method returns symbols
33
+ Bear.methods.collect {|m| m.to_sym}.should include(:timeout)
34
+ Bear.methods.collect {|m| m.to_sym}.should include(:timeout=)
35
+ end
36
+ end
37
+
20
38
  describe "server" do
21
- describe "without options[:beta]" do
22
- it "should return the rest server if options[:rest_api]" do
39
+ describe "with no options" do
40
+ it "returns the REST server if options[:rest_api]" do
23
41
  Bear.server(:rest_api => true).should == Koala::Facebook::REST_SERVER
24
42
  end
25
43
 
26
- it "should return the rest server if !options[:rest_api]" do
44
+ it "returns the graph server if !options[:rest_api]" do
27
45
  Bear.server(:rest_api => false).should == Koala::Facebook::GRAPH_SERVER
28
46
  Bear.server({}).should == Koala::Facebook::GRAPH_SERVER
29
47
  end
30
48
  end
31
-
32
- describe "without options[:beta]" do
49
+
50
+ describe "with options[:beta]" do
33
51
  before :each do
34
52
  @options = {:beta => true}
35
53
  end
36
54
 
37
- it "should return the rest server if options[:rest_api]" do
55
+ it "returns the beta REST server if options[:rest_api]" do
38
56
  server = Bear.server(@options.merge(:rest_api => true))
39
- server.should =~ Regexp.new(Koala::Facebook::REST_SERVER)
40
- server.should =~ /beta\./
57
+ server.should =~ Regexp.new("beta.#{Koala::Facebook::REST_SERVER}")
41
58
  end
42
59
 
43
- it "should return the rest server if !options[:rest_api]" do
44
- server = Bear.server(:beta => true)
45
- server.should =~ Regexp.new(Koala::Facebook::GRAPH_SERVER)
46
- server.should =~ /beta\./
60
+ it "returns the beta rest server if !options[:rest_api]" do
61
+ server = Bear.server(@options)
62
+ server.should =~ Regexp.new("beta.#{Koala::Facebook::GRAPH_SERVER}")
47
63
  end
48
64
  end
49
65
 
66
+ describe "with options[:video]" do
67
+ before :each do
68
+ @options = {:video => true}
69
+ end
70
+
71
+ it "should return the REST video server if options[:rest_api]" do
72
+ server = Bear.server(@options.merge(:rest_api => true))
73
+ server.should =~ Regexp.new(Koala::Facebook::REST_SERVER.gsub(/\.facebook/, "-video.facebook"))
74
+ end
75
+
76
+ it "should return the graph video server if !options[:rest_api]" do
77
+ server = Bear.server(@options)
78
+ server.should =~ Regexp.new(Koala::Facebook::GRAPH_SERVER.gsub(/\.facebook/, "-video.facebook"))
79
+ end
80
+ end
50
81
  end
51
82
 
83
+ describe "#encode_params" do
84
+ it "should return an empty string if param_hash evaluates to false" do
85
+ Bear.encode_params(nil).should == ''
86
+ end
87
+
88
+ it "should convert values to JSON if the value is not a String" do
89
+ val = 'json_value'
90
+ not_a_string = 'not_a_string'
91
+ not_a_string.stub(:is_a?).and_return(false)
92
+ MultiJson.should_receive(:encode).with(not_a_string).and_return(val)
93
+
94
+ string = "hi"
95
+
96
+ args = {
97
+ not_a_string => not_a_string,
98
+ string => string
99
+ }
100
+
101
+ result = Bear.encode_params(args)
102
+ result.split('&').find do |key_and_val|
103
+ key_and_val.match("#{not_a_string}=#{val}")
104
+ end.should be_true
105
+ end
106
+
107
+ it "should escape all values" do
108
+ args = Hash[*(1..4).map {|i| [i.to_s, "Value #{i}($"]}.flatten]
109
+
110
+ result = Bear.encode_params(args)
111
+ result.split('&').each do |key_val|
112
+ key, val = key_val.split('=')
113
+ val.should == CGI.escape(args[key])
114
+ end
115
+ end
116
+
117
+ it "should convert all keys to Strings" do
118
+ args = Hash[*(1..4).map {|i| [i, "val#{i}"]}.flatten]
119
+
120
+ result = Bear.encode_params(args)
121
+ result.split('&').each do |key_val|
122
+ key, val = key_val.split('=')
123
+ key.should == args.find{|key_val_arr| key_val_arr.last == val}.first.to_s
124
+ end
125
+ end
126
+ end
52
127
  end
53
128
 
54
129
  end
@@ -1,14 +1,27 @@
1
1
  require 'spec_helper'
2
2
 
3
3
 
4
- module Horse
5
- include Koala::NetHTTPService
6
- end
4
+ Horse = Koala::NetHTTPService
7
5
 
8
6
  describe "NetHTTPService module holder class Horse" do
9
7
  before :each do
10
- # reset the always_use_ssl parameter
11
- Horse.always_use_ssl = nil
8
+ # reset global settings
9
+ Horse.always_use_ssl = Horse.proxy = Horse.timeout = nil
10
+ end
11
+
12
+ it "has a ca_file accessor" do
13
+ Horse.methods.collect {|m| m.to_sym}.should include(:ca_file)
14
+ Horse.methods.collect {|m| m.to_sym}.should include(:ca_file=)
15
+ end
16
+
17
+ it "has a ca_path accessor" do
18
+ Horse.methods.collect {|m| m.to_sym}.should include(:ca_path)
19
+ Horse.methods.collect {|m| m.to_sym}.should include(:ca_path=)
20
+ end
21
+
22
+ it "has a verify_mode accessor" do
23
+ Horse.methods.collect {|m| m.to_sym}.should include(:verify_mode)
24
+ Horse.methods.collect {|m| m.to_sym}.should include(:verify_mode=)
12
25
  end
13
26
 
14
27
  it "should define a make_request static module method" do
@@ -22,21 +35,19 @@ describe "NetHTTPService module holder class Horse" do
22
35
  describe "when making a request" do
23
36
  before(:each) do
24
37
  # Setup stubs for make_request to execute without exceptions
25
- @mock_http_response = stub('Net::HTTPResponse', :code => 1)
26
38
  @mock_body = stub('Net::HTTPResponse body')
27
- @http_request_result = [@mock_http_response, @mock_body]
28
-
29
- # to_ary is called in Ruby 1.9 to provide backwards compatibility
30
- # with the response, body = http.get() syntax we use
31
- @mock_http_response.stub!(:to_ary).and_return(@http_request_result)
39
+ @mock_http_response = stub('Net::HTTPResponse', :code => 1, :body => @mock_body)
32
40
 
33
41
  @http_yield_mock = mock('Net::HTTP start yielded object')
34
42
 
35
- @http_yield_mock.stub(:post).and_return(@http_request_result)
36
- @http_yield_mock.stub(:get).and_return(@http_request_result)
43
+ @http_yield_mock.stub(:post).and_return(@mock_http_response)
44
+ @http_yield_mock.stub(:get).and_return(@mock_http_response)
37
45
 
38
46
  @http_mock = stub('Net::HTTP object', 'use_ssl=' => true, 'verify_mode=' => true)
39
47
  @http_mock.stub(:start).and_yield(@http_yield_mock)
48
+ @http_mock.stub(:ca_path=)
49
+ @http_mock.stub(:ca_file=)
50
+ @http_mock.stub(:verify_mode=)
40
51
 
41
52
  Net::HTTP.stub(:new).and_return(@http_mock)
42
53
  end
@@ -84,7 +95,7 @@ describe "NetHTTPService module holder class Horse" do
84
95
  Horse.make_request('anything', @args, 'anything')
85
96
  end
86
97
  end
87
-
98
+
88
99
  describe "if always_use_ssl is true" do
89
100
  before :each do
90
101
  Horse.always_use_ssl = true
@@ -129,6 +140,228 @@ describe "NetHTTPService module holder class Horse" do
129
140
  end
130
141
  end
131
142
 
143
+ describe "proxy options" do
144
+ before :each do
145
+ Horse.proxy = "http://defaultproxy"
146
+ end
147
+ after :all do
148
+ Horse.proxy = nil
149
+ end
150
+
151
+ it "should use passed proxy option if provided" do
152
+ Net::HTTP.should_receive(:new).with(Koala::Facebook::GRAPH_SERVER, anything, "passedproxy", 80, nil, nil).and_return(@http_mock)
153
+ Horse.make_request('anything', {} , 'anything', {:proxy => "http://passedproxy"})
154
+ end
155
+
156
+ it "should use default proxy if default is provided and NO proxy option passed" do
157
+ Net::HTTP.should_receive(:new).with(Koala::Facebook::GRAPH_SERVER, anything, "defaultproxy", 80, nil, nil).and_return(@http_mock)
158
+ Horse.make_request('anything', {} , 'anything', {})
159
+ end
160
+
161
+ it "should NOT use a proxy if default is NOT provided and NO proxy option passed" do
162
+ Horse.proxy = nil
163
+ Net::HTTP.should_receive(:new).with(Koala::Facebook::GRAPH_SERVER, anything).and_return(@http_mock)
164
+ Horse.make_request('anything', {} , 'anything', {})
165
+ end
166
+ end
167
+
168
+ describe "timeout options" do
169
+ before :each do
170
+ Horse.timeout = 20 # seconds
171
+ end
172
+ after :all do
173
+ Horse.timeout = nil # seconds
174
+ end
175
+
176
+ it "should use passed timeout option if provided" do
177
+ @http_mock.should_receive('open_timeout=').with(10)
178
+ @http_mock.should_receive('read_timeout=').with(10)
179
+ Horse.make_request('anything', {} , 'anything', {:timeout => 10})
180
+ end
181
+
182
+ it "should use default timout if default is provided and NO timeout option passed" do
183
+ @http_mock.should_receive('open_timeout=').with(20)
184
+ @http_mock.should_receive('read_timeout=').with(20)
185
+ Horse.make_request('anything', {} , 'anything', {})
186
+ end
187
+
188
+ it "should NOT use a timeout if default is NOT provided and NO timeout option passed" do
189
+ Horse.timeout = nil # seconds
190
+ @http_mock.should_not_receive('open_timeout=')
191
+ @http_mock.should_not_receive('read_timeout=')
192
+ Horse.make_request('anything', {} , 'anything', {})
193
+ end
194
+ end
195
+
196
+ describe "ca_file options" do
197
+ after :each do
198
+ Horse.always_use_ssl = nil
199
+ Horse.ca_file = nil
200
+ end
201
+
202
+ it "should not use a ca_file if the request is not via SSL" do
203
+ Horse.always_use_ssl = false
204
+ @http_mock.should_not_receive(:ca_file=)
205
+ Horse.make_request('anything', {} , 'anything', {:ca_file => '/no/file'})
206
+ end
207
+
208
+ describe "when via SSL" do
209
+ before :each do
210
+ Horse.always_use_ssl = true
211
+ @global_ca_file_path = '/global/ca/file/path'
212
+ end
213
+
214
+ context "if the file doesn't exist" do
215
+ it "raises Errno::ENOENT if the default ca_file does not exist" do
216
+ Horse.ca_file = @global_ca_file_path
217
+
218
+ File.should_receive(:exists?).with(@global_ca_file_path).and_return(false)
219
+ expect { Horse.make_request('anything', {} , 'anything', {}) }.to raise_exception(Errno::ENOENT)
220
+ end
221
+
222
+ it "raises Errno::ENOENT if options[:ca_file] does not exist" do
223
+ File.should_receive(:exists?).with(@global_ca_file_path).and_return(false)
224
+ expect { Horse.make_request('anything', {} , 'anything', {:ca_file => @global_ca_file_path}) }.to raise_exception(Errno::ENOENT)
225
+ end
226
+ end
227
+
228
+ context "if the file exists" do
229
+ before :each do
230
+ File.stub(:exists?).and_return(true)
231
+ end
232
+
233
+ it "should use options[:ca_file] if provided" do
234
+ given_ca_file = '/ca/file'
235
+
236
+ Horse.ca_file = @global_ca_file_path
237
+ @http_mock.should_not_receive(:ca_file=).with(@global_ca_file_path)
238
+ @http_mock.should_receive(:ca_file=).with(given_ca_file)
239
+
240
+ Horse.make_request('anything', {} , 'anything', {:ca_file => given_ca_file})
241
+ end
242
+
243
+ it "should use default ca_file if default is provided and NO ca_file option is passed" do
244
+ Horse.ca_file = @global_ca_file_path
245
+ @http_mock.should_receive(:ca_file=).with(@global_ca_file_path)
246
+
247
+ Horse.make_request('anything', {} , 'anything', {})
248
+ end
249
+
250
+ it "should NOT use a ca_file if default is NOT provided and NO ca_file option is passed" do
251
+ @http_mock.should_not_receive(:ca_file=)
252
+
253
+ Horse.make_request('anything', {} , 'anything', {})
254
+ end
255
+ end
256
+ end
257
+ end
258
+
259
+ describe "ca_path options" do
260
+ after :each do
261
+ Horse.always_use_ssl = nil
262
+ Horse.ca_path = nil
263
+ end
264
+
265
+ it "should not use a ca_path if the request is not via SSL" do
266
+ Horse.always_use_ssl = false
267
+ @http_mock.should_not_receive('ca_path=')
268
+ Horse.make_request('anything', {} , 'anything', {:ca_file => '/no/file'})
269
+ end
270
+
271
+ describe "when via SSL" do
272
+ before :each do
273
+ Horse.always_use_ssl = true
274
+ @global_ca_path = '/global/ca/path'
275
+ end
276
+
277
+ context "if the directory doesn't exist" do
278
+ it "should not use a default ca_path if the default ca_path does not exist" do
279
+ Horse.ca_path = @global_ca_path
280
+
281
+ File.should_receive(:directory?).with(@global_ca_path).and_return(false)
282
+ expect { Horse.make_request('anything', {} , 'anything', {}) }.to raise_exception(Errno::ENOENT)
283
+ end
284
+
285
+ it "should not use a default ca_path if the default ca_path does not exist" do
286
+ File.should_receive(:directory?).with(@global_ca_path).and_return(false)
287
+ expect { Horse.make_request('anything', {} , 'anything', {:ca_path => @global_ca_path}) }.to raise_exception(Errno::ENOENT)
288
+ end
289
+ end
290
+
291
+ context "if the directory exists" do
292
+ before :each do
293
+ File.stub(:directory?).and_return(true)
294
+ end
295
+
296
+ it "should use passed ca_path options if provided" do
297
+ given_ca_path = '/ca/path'
298
+
299
+ Horse.ca_path = @global_ca_path
300
+ @http_mock.should_not_receive(:ca_ath=).with(@global_ca_path)
301
+ @http_mock.should_receive(:ca_path=).with(given_ca_path)
302
+
303
+ Horse.make_request('anything', {} , 'anything', {:ca_path => given_ca_path})
304
+ end
305
+
306
+ it "should use default ca_path if default is provided and NO ca_path option is passed" do
307
+ Horse.ca_path = @global_ca_path
308
+ @http_mock.should_receive(:ca_path=).with(@global_ca_path)
309
+
310
+ Horse.make_request('anything', {} , 'anything', {})
311
+ end
312
+
313
+ it "should NOT use a ca_path if default is NOT provided and NO ca_path option is passed" do
314
+ @http_mock.should_not_receive(:ca_path=)
315
+
316
+ Horse.make_request('anything', {} , 'anything', {})
317
+ end
318
+ end
319
+ end
320
+ end
321
+
322
+ describe "verify_mode options" do
323
+ after :each do
324
+ Horse.always_use_ssl = nil
325
+ Horse.verify_mode = nil
326
+ end
327
+
328
+ it "does not set verify mode if it's not SSL" do
329
+ Horse.always_use_ssl = nil
330
+ @http_mock.should_not_receive(:verify_mode=)
331
+ Horse.make_request('anything', {} , 'anything', {:verify_mode => "abc"})
332
+ end
333
+
334
+ context "when making an SSL request" do
335
+ before :each do
336
+ Horse.always_use_ssl = true
337
+ end
338
+
339
+ it "sets verify mode if provided in the options" do
340
+ mode = "foo"
341
+ @http_mock.should_receive(:verify_mode=).with(mode)
342
+ Horse.make_request('anything', {} , 'anything', {:verify_mode => mode})
343
+ end
344
+
345
+ it "sets verify mode to the default if provided (and none set in options)" do
346
+ Horse.verify_mode = "foo"
347
+ @http_mock.should_receive(:verify_mode=).with(Horse.verify_mode)
348
+ Horse.make_request('anything', {} , 'anything', {})
349
+ end
350
+
351
+ it "sets verify mode to the default if provided (and none set in options)" do
352
+ mode = "bar"
353
+ Horse.verify_mode = "foo"
354
+ @http_mock.should_receive(:verify_mode=).with(mode)
355
+ Horse.make_request('anything', {} , 'anything', {:verify_mode => mode})
356
+ end
357
+
358
+ it "sets verify mode to OpenSSL::SSL::VERIFY_PEER if no default or option is provided" do
359
+ @http_mock.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
360
+ Horse.make_request('anything', {} , 'anything', {})
361
+ end
362
+ end
363
+ end
364
+
132
365
  it "should use the graph server by default" do
133
366
  Net::HTTP.should_receive(:new).with(Koala::Facebook::GRAPH_SERVER, anything).and_return(@http_mock)
134
367
  Horse.make_request('anything', {}, 'anything')
@@ -139,17 +372,11 @@ describe "NetHTTPService module holder class Horse" do
139
372
  Horse.make_request('anything', {}, 'anything', :rest_api => true)
140
373
  end
141
374
 
142
- it "no longer sets verify_mode to no verification" do
143
- @http_mock.should_not_receive('verify_mode=')
144
-
145
- Horse.make_request('anything', {}, 'anything')
146
- end
147
-
148
375
  it "should start an HTTP connection" do
149
376
  @http_mock.should_receive(:start).and_yield(@http_yield_mock)
150
377
  Horse.make_request('anything', {}, 'anything')
151
378
  end
152
-
379
+
153
380
  it 'creates a HTTP Proxy object when options contain a proxy' do
154
381
  Net::HTTP.should_receive(:new).with(anything, anything, 'proxy', 1234, 'user', 'pass').and_return(@http_mock)
155
382
  Horse.make_request('anything', {}, 'anything', {:proxy => 'http://user:pass@proxy:1234'})
@@ -163,14 +390,14 @@ describe "NetHTTPService module holder class Horse" do
163
390
 
164
391
  describe "via POST" do
165
392
  it "should use Net::HTTP to make a POST request" do
166
- @http_yield_mock.should_receive(:post).and_return(@http_request_result)
393
+ @http_yield_mock.should_receive(:post).and_return(@mock_http_response)
167
394
 
168
395
  Horse.make_request('anything', {}, 'post')
169
396
  end
170
397
 
171
398
  it "should go to the specified path adding a / if it doesn't exist" do
172
399
  path = mock('Path')
173
- @http_yield_mock.should_receive(:post).with(path, anything).and_return(@http_request_result)
400
+ @http_yield_mock.should_receive(:post).with(path, anything).and_return(@mock_http_response)
174
401
 
175
402
  Horse.make_request(path, {}, 'post')
176
403
  end
@@ -180,7 +407,7 @@ describe "NetHTTPService module holder class Horse" do
180
407
  params = mock('Encoded parameters')
181
408
  Horse.should_receive(:encode_params).with(args).and_return(params)
182
409
 
183
- @http_yield_mock.should_receive(:post).with(anything, params).and_return(@http_request_result)
410
+ @http_yield_mock.should_receive(:post).with(anything, params).and_return(@mock_http_response)
184
411
 
185
412
  Horse.make_request('anything', args, 'post')
186
413
  end
@@ -195,11 +422,11 @@ describe "NetHTTPService module holder class Horse" do
195
422
 
196
423
  @file_stub = stub('fake File', "kind_of?" => true, "path" => 'anypath.jpg')
197
424
 
198
- @http_yield_mock.stub(:request).with(@multipart_request_stub).and_return(@http_request_result)
425
+ @http_yield_mock.stub(:request).with(@multipart_request_stub).and_return(@mock_http_response)
199
426
  end
200
427
 
201
428
  it "should use multipart/form-data if any parameter is a valid file hash" do
202
- @http_yield_mock.should_receive(:request).with(@multipart_request_stub).and_return(@http_request_result)
429
+ @http_yield_mock.should_receive(:request).with(@multipart_request_stub).and_return(@mock_http_response)
203
430
 
204
431
  Horse.make_request('anything', {}, 'post')
205
432
  end
@@ -227,7 +454,7 @@ describe "NetHTTPService module holder class Horse" do
227
454
 
228
455
  describe "via GET" do
229
456
  it "should use Net::HTTP to make a GET request" do
230
- @http_yield_mock.should_receive(:get).and_return(@http_request_result)
457
+ @http_yield_mock.should_receive(:get).and_return(@mock_http_response)
231
458
 
232
459
  Horse.make_request('anything', {}, 'get')
233
460
  end
@@ -238,7 +465,7 @@ describe "NetHTTPService module holder class Horse" do
238
465
  args = {}
239
466
 
240
467
  Horse.should_receive(:encode_params).with(args).and_return(params)
241
- @http_yield_mock.should_receive(:get).with("#{path}?#{params}").and_return(@http_request_result)
468
+ @http_yield_mock.should_receive(:get).with("#{path}?#{params}").and_return(@mock_http_response)
242
469
 
243
470
  Horse.make_request(path, args, 'get')
244
471
  end
@@ -267,51 +494,6 @@ describe "NetHTTPService module holder class Horse" do
267
494
  end # describe return value
268
495
  end # describe when making a request
269
496
 
270
- describe "when encoding parameters" do
271
- it "should return an empty string if param_hash evaluates to false" do
272
- Horse.encode_params(nil).should == ''
273
- end
274
-
275
- it "should convert values to JSON if the value is not a String" do
276
- val = 'json_value'
277
- not_a_string = 'not_a_string'
278
- not_a_string.stub(:class).and_return('NotAString')
279
- not_a_string.should_receive(:to_json).and_return(val)
280
-
281
- string = "hi"
282
-
283
- args = {
284
- not_a_string => not_a_string,
285
- string => string
286
- }
287
-
288
- result = Horse.encode_params(args)
289
- result.split('&').find do |key_and_val|
290
- key_and_val.match("#{not_a_string}=#{val}")
291
- end.should be_true
292
- end
293
-
294
- it "should escape all values" do
295
- args = Hash[*(1..4).map {|i| [i.to_s, "Value #{i}($"]}.flatten]
296
-
297
- result = Horse.encode_params(args)
298
- result.split('&').each do |key_val|
299
- key, val = key_val.split('=')
300
- val.should == CGI.escape(args[key])
301
- end
302
- end
303
-
304
- it "should convert all keys to Strings" do
305
- args = Hash[*(1..4).map {|i| [i, "val#{i}"]}.flatten]
306
-
307
- result = Horse.encode_params(args)
308
- result.split('&').each do |key_val|
309
- key, val = key_val.split('=')
310
- key.should == args.find{|key_val_arr| key_val_arr.last == val}.first.to_s
311
- end
312
- end
313
- end
314
-
315
497
  describe "when detecting if multipart posting is needed" do
316
498
  it "should be true if any parameter value requires multipart post" do
317
499
  koala_io = mock("Koala::IO")
@@ -326,11 +508,11 @@ describe "NetHTTPService module holder class Horse" do
326
508
 
327
509
  Horse.params_require_multipart?(args).should be_true
328
510
  end
329
-
511
+
330
512
  describe "when encoding multipart/form-data params" do
331
513
  it "should replace Koala::UploadableIO values with UploadIO values" do
332
514
  upload_io = UploadIO.new(__FILE__, "fake type")
333
-
515
+
334
516
  uploadable_io = stub('Koala::UploadableIO')
335
517
  uploadable_io.should_receive(:kind_of?).with(Koala::UploadableIO).and_return(true)
336
518
  uploadable_io.should_receive(:to_upload_io).and_return(upload_io)
@@ -338,13 +520,13 @@ describe "NetHTTPService module holder class Horse" do
338
520
  "not_a_file" => "not a file",
339
521
  "file" => uploadable_io
340
522
  }
341
-
523
+
342
524
  result = Horse.encode_multipart_params(args)
343
525
 
344
526
  result["not_a_file"] == args["not_a_file"]
345
527
  result["file"] == upload_io
346
528
  end
347
529
  end
348
-
530
+
349
531
  end
350
532
  end