dkastner-httparty 0.9.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 (80) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +8 -0
  3. data/Gemfile +15 -0
  4. data/Guardfile +16 -0
  5. data/History +293 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +79 -0
  8. data/Rakefile +15 -0
  9. data/bin/httparty +114 -0
  10. data/cucumber.yml +1 -0
  11. data/examples/aaws.rb +32 -0
  12. data/examples/basic.rb +32 -0
  13. data/examples/crack.rb +19 -0
  14. data/examples/custom_parsers.rb +67 -0
  15. data/examples/delicious.rb +37 -0
  16. data/examples/google.rb +16 -0
  17. data/examples/headers_and_user_agents.rb +6 -0
  18. data/examples/nokogiri_html_parser.rb +22 -0
  19. data/examples/rubyurl.rb +14 -0
  20. data/examples/tripit_sign_in.rb +33 -0
  21. data/examples/twitter.rb +31 -0
  22. data/examples/whoismyrep.rb +10 -0
  23. data/features/basic_authentication.feature +20 -0
  24. data/features/command_line.feature +7 -0
  25. data/features/deals_with_http_error_codes.feature +26 -0
  26. data/features/digest_authentication.feature +20 -0
  27. data/features/handles_compressed_responses.feature +19 -0
  28. data/features/handles_multiple_formats.feature +34 -0
  29. data/features/steps/env.rb +22 -0
  30. data/features/steps/httparty_response_steps.rb +26 -0
  31. data/features/steps/httparty_steps.rb +27 -0
  32. data/features/steps/mongrel_helper.rb +94 -0
  33. data/features/steps/remote_service_steps.rb +69 -0
  34. data/features/supports_redirection.feature +22 -0
  35. data/features/supports_timeout_option.feature +13 -0
  36. data/httparty.gemspec +24 -0
  37. data/lib/httparty.rb +503 -0
  38. data/lib/httparty/connection_adapter.rb +116 -0
  39. data/lib/httparty/cookie_hash.rb +22 -0
  40. data/lib/httparty/core_extensions.rb +32 -0
  41. data/lib/httparty/exceptions.rb +26 -0
  42. data/lib/httparty/hash_conversions.rb +51 -0
  43. data/lib/httparty/module_inheritable_attributes.rb +44 -0
  44. data/lib/httparty/net_digest_auth.rb +84 -0
  45. data/lib/httparty/parser.rb +145 -0
  46. data/lib/httparty/request.rb +243 -0
  47. data/lib/httparty/response.rb +62 -0
  48. data/lib/httparty/response/headers.rb +31 -0
  49. data/lib/httparty/version.rb +3 -0
  50. data/spec/fixtures/delicious.xml +23 -0
  51. data/spec/fixtures/empty.xml +0 -0
  52. data/spec/fixtures/google.html +3 -0
  53. data/spec/fixtures/ssl/generate.sh +29 -0
  54. data/spec/fixtures/ssl/generated/1fe462c2.0 +16 -0
  55. data/spec/fixtures/ssl/generated/bogushost.crt +13 -0
  56. data/spec/fixtures/ssl/generated/ca.crt +16 -0
  57. data/spec/fixtures/ssl/generated/ca.key +15 -0
  58. data/spec/fixtures/ssl/generated/selfsigned.crt +14 -0
  59. data/spec/fixtures/ssl/generated/server.crt +13 -0
  60. data/spec/fixtures/ssl/generated/server.key +15 -0
  61. data/spec/fixtures/ssl/openssl-exts.cnf +9 -0
  62. data/spec/fixtures/twitter.json +1 -0
  63. data/spec/fixtures/twitter.xml +403 -0
  64. data/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
  65. data/spec/httparty/connection_adapter_spec.rb +206 -0
  66. data/spec/httparty/cookie_hash_spec.rb +70 -0
  67. data/spec/httparty/net_digest_auth_spec.rb +115 -0
  68. data/spec/httparty/parser_spec.rb +171 -0
  69. data/spec/httparty/request_spec.rb +507 -0
  70. data/spec/httparty/response_spec.rb +214 -0
  71. data/spec/httparty/ssl_spec.rb +62 -0
  72. data/spec/httparty_spec.rb +703 -0
  73. data/spec/spec.opts +2 -0
  74. data/spec/spec_helper.rb +30 -0
  75. data/spec/support/ssl_test_helper.rb +47 -0
  76. data/spec/support/ssl_test_server.rb +80 -0
  77. data/spec/support/stub_response.rb +43 -0
  78. data/website/css/common.css +47 -0
  79. data/website/index.html +73 -0
  80. metadata +190 -0
@@ -0,0 +1,507 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe HTTParty::Request do
4
+ before do
5
+ @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
6
+ end
7
+
8
+ describe "::NON_RAILS_QUERY_STRING_NORMALIZER" do
9
+ let(:normalizer) { HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER }
10
+
11
+ it "doesn't modify strings" do
12
+ query_string = normalizer["foo=bar&foo=baz"]
13
+ URI.unescape(query_string).should == "foo=bar&foo=baz"
14
+ end
15
+
16
+ context "when the query is an array" do
17
+
18
+ it "doesn't include brackets" do
19
+ query_string = normalizer[{:page => 1, :foo => %w(bar baz)}]
20
+ URI.unescape(query_string).should == "foo=bar&foo=baz&page=1"
21
+ end
22
+
23
+ it "URI encodes array values" do
24
+ query_string = normalizer[{:people => ["Bob Marley", "Tim & Jon"]}]
25
+ query_string.should == "people=Bob%20Marley&people=Tim%20%26%20Jon"
26
+ end
27
+ end
28
+
29
+ context "when the query is a hash" do
30
+ it "correctly handles nil values" do
31
+ query_string = normalizer[{:page => 1, :per_page => nil}]
32
+ query_string.should == "page=1&per_page"
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "initialization" do
38
+ it "sets parser to HTTParty::Parser" do
39
+ request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
40
+ request.parser.should == HTTParty::Parser
41
+ end
42
+
43
+ it "sets parser to the optional parser" do
44
+ my_parser = lambda {}
45
+ request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', :parser => my_parser)
46
+ request.parser.should == my_parser
47
+ end
48
+
49
+ it "sets connection_adapter to HTTPParty::ConnectionAdapter" do
50
+ request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
51
+ request.connection_adapter.should == HTTParty::ConnectionAdapter
52
+ end
53
+
54
+ it "sets connection_adapter to the optional connection_adapter" do
55
+ my_adapter = lambda {}
56
+ request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', :connection_adapter => my_adapter)
57
+ request.connection_adapter.should == my_adapter
58
+ end
59
+ end
60
+
61
+ describe "#format" do
62
+ context "request yet to be made" do
63
+ it "returns format option" do
64
+ request = HTTParty::Request.new 'get', '/', :format => :xml
65
+ request.format.should == :xml
66
+ end
67
+
68
+ it "returns nil format" do
69
+ request = HTTParty::Request.new 'get', '/'
70
+ request.format.should be_nil
71
+ end
72
+ end
73
+
74
+ context "request has been made" do
75
+ it "returns format option" do
76
+ request = HTTParty::Request.new 'get', '/', :format => :xml
77
+ request.last_response = stub
78
+ request.format.should == :xml
79
+ end
80
+
81
+ it "returns the content-type from the last response when the option is not set" do
82
+ request = HTTParty::Request.new 'get', '/'
83
+ response = stub
84
+ response.should_receive(:[]).with('content-type').and_return('text/json')
85
+ request.last_response = response
86
+ request.format.should == :json
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ context "options" do
93
+ it "should use basic auth when configured" do
94
+ @request.options[:basic_auth] = {:username => 'foobar', :password => 'secret'}
95
+ @request.send(:setup_raw_request)
96
+ @request.instance_variable_get(:@raw_request)['authorization'].should_not be_nil
97
+ end
98
+
99
+ it "should use digest auth when configured" do
100
+ FakeWeb.register_uri(:get, "http://api.foo.com/v1",
101
+ :www_authenticate => 'Digest realm="Log Viewer", qop="auth", nonce="2CA0EC6B0E126C4800E56BA0C0003D3C", opaque="5ccc069c403ebaf9f0171e9517f40e41", stale=false')
102
+
103
+ @request.options[:digest_auth] = {:username => 'foobar', :password => 'secret'}
104
+ @request.send(:setup_raw_request)
105
+
106
+ raw_request = @request.instance_variable_get(:@raw_request)
107
+ raw_request.instance_variable_get(:@header)['Authorization'].should_not be_nil
108
+ end
109
+
110
+ it "should use the right http method for digest authentication" do
111
+ @post_request = HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :format => :xml)
112
+ FakeWeb.register_uri(:post, "http://api.foo.com/v1", {})
113
+
114
+ http = @post_request.send(:http)
115
+ @post_request.should_receive(:http).and_return(http)
116
+ http.should_not_receive(:head).and_return({'www-authenticate' => nil})
117
+ @post_request.options[:digest_auth] = {:username => 'foobar', :password => 'secret'}
118
+ @post_request.send(:setup_raw_request)
119
+ end
120
+ end
121
+
122
+ describe "#uri" do
123
+ context "query strings" do
124
+ it "does not add an empty query string when default_params are blank" do
125
+ @request.options[:default_params] = {}
126
+ @request.uri.query.should be_nil
127
+ end
128
+
129
+ it "respects the query string normalization proc" do
130
+ empty_proc = lambda {|qs| ""}
131
+ @request.options[:query_string_normalizer] = empty_proc
132
+ @request.options[:query] = {:foo => :bar}
133
+ URI.unescape(@request.uri.query).should == ""
134
+ end
135
+
136
+ context "when representing an array" do
137
+ it "returns a Rails style query string" do
138
+ @request.options[:query] = {:foo => %w(bar baz)}
139
+ URI.unescape(@request.uri.query).should == "foo[]=bar&foo[]=baz"
140
+ end
141
+ end
142
+
143
+ end
144
+ end
145
+
146
+ describe "#setup_raw_request" do
147
+ context "when query_string_normalizer is set" do
148
+ it "sets the body to the return value of the proc" do
149
+ @request.options[:query_string_normalizer] = HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER
150
+ @request.options[:body] = {:page => 1, :foo => %w(bar baz)}
151
+ @request.send(:setup_raw_request)
152
+ body = @request.instance_variable_get(:@raw_request).body
153
+ URI.unescape(body).should == "foo=bar&foo=baz&page=1"
154
+ end
155
+ end
156
+ end
157
+
158
+ describe 'http' do
159
+ it "should get a connection from the connection_adapter" do
160
+ http = Net::HTTP.new('google.com')
161
+ adapter = mock('adapter')
162
+ request = HTTParty::Request.new(Net::HTTP::Get, 'https://api.foo.com/v1:443', :connection_adapter => adapter)
163
+ adapter.should_receive(:call).with(request.uri, request.options).and_return(http)
164
+ request.send(:http).should be http
165
+ end
166
+ end
167
+
168
+ describe '#format_from_mimetype' do
169
+ it 'should handle text/xml' do
170
+ ["text/xml", "text/xml; charset=iso8859-1"].each do |ct|
171
+ @request.send(:format_from_mimetype, ct).should == :xml
172
+ end
173
+ end
174
+
175
+ it 'should handle application/xml' do
176
+ ["application/xml", "application/xml; charset=iso8859-1"].each do |ct|
177
+ @request.send(:format_from_mimetype, ct).should == :xml
178
+ end
179
+ end
180
+
181
+ it 'should handle text/json' do
182
+ ["text/json", "text/json; charset=iso8859-1"].each do |ct|
183
+ @request.send(:format_from_mimetype, ct).should == :json
184
+ end
185
+ end
186
+
187
+ it 'should handle application/json' do
188
+ ["application/json", "application/json; charset=iso8859-1"].each do |ct|
189
+ @request.send(:format_from_mimetype, ct).should == :json
190
+ end
191
+ end
192
+
193
+ it 'should handle text/javascript' do
194
+ ["text/javascript", "text/javascript; charset=iso8859-1"].each do |ct|
195
+ @request.send(:format_from_mimetype, ct).should == :json
196
+ end
197
+ end
198
+
199
+ it 'should handle application/javascript' do
200
+ ["application/javascript", "application/javascript; charset=iso8859-1"].each do |ct|
201
+ @request.send(:format_from_mimetype, ct).should == :json
202
+ end
203
+ end
204
+
205
+ it "returns nil for an unrecognized mimetype" do
206
+ @request.send(:format_from_mimetype, "application/atom+xml").should be_nil
207
+ end
208
+
209
+ it "returns nil when using a default parser" do
210
+ @request.options[:parser] = lambda {}
211
+ @request.send(:format_from_mimetype, "text/json").should be_nil
212
+ end
213
+ end
214
+
215
+ describe 'parsing responses' do
216
+ it 'should handle xml automatically' do
217
+ xml = %q[<books><book><id>1234</id><name>Foo Bar!</name></book></books>]
218
+ @request.options[:format] = :xml
219
+ @request.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
220
+ end
221
+
222
+ it 'should handle json automatically' do
223
+ json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}]
224
+ @request.options[:format] = :json
225
+ @request.send(:parse_response, json).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
226
+ end
227
+
228
+ it 'should handle yaml automatically' do
229
+ yaml = "books: \n book: \n name: Foo Bar!\n id: \"1234\"\n"
230
+ @request.options[:format] = :yaml
231
+ @request.send(:parse_response, yaml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
232
+ end
233
+
234
+ it "should include any HTTP headers in the returned response" do
235
+ @request.options[:format] = :html
236
+ response = stub_response "Content"
237
+ response.initialize_http_header("key" => "value")
238
+
239
+ @request.perform.headers.should == { "key" => ["value"] }
240
+ end
241
+
242
+ describe 'with non-200 responses' do
243
+ context "3xx responses" do
244
+ it 'returns a valid object for 304 not modified' do
245
+ stub_response '', 304
246
+ resp = @request.perform
247
+ resp.code.should == 304
248
+ resp.body.should == ''
249
+ resp.should be_nil
250
+ end
251
+
252
+ it "redirects if a 300 contains a location header" do
253
+ redirect = stub_response '', 300
254
+ redirect['location'] = 'http://foo.com/foo'
255
+ ok = stub_response('<hash><foo>bar</foo></hash>', 200)
256
+ @http.stub!(:request).and_return(redirect, ok)
257
+ response = @request.perform
258
+ response.request.base_uri.to_s.should == "http://foo.com"
259
+ response.request.path.to_s.should == "http://foo.com/foo"
260
+ response.request.uri.request_uri.should == "/foo"
261
+ response.request.uri.to_s.should == "http://foo.com/foo"
262
+ response.should == {"hash" => {"foo" => "bar"}}
263
+ end
264
+
265
+ it "redirects if a 300 contains a relative location header" do
266
+ redirect = stub_response '', 300
267
+ redirect['location'] = '/foo/bar'
268
+ ok = stub_response('<hash><foo>bar</foo></hash>', 200)
269
+ @http.stub!(:request).and_return(redirect, ok)
270
+ response = @request.perform
271
+ response.request.base_uri.to_s.should == "http://api.foo.com"
272
+ response.request.path.to_s.should == "/foo/bar"
273
+ response.request.uri.request_uri.should == "/foo/bar"
274
+ response.request.uri.to_s.should == "http://api.foo.com/foo/bar"
275
+ response.should == {"hash" => {"foo" => "bar"}}
276
+ end
277
+
278
+ it "redirects to bad URIs if a 300 contains a malformed location header" do
279
+ redirect = stub_response '', 300
280
+ redirect['location'] = '/foo/bar?q=search term'
281
+ ok = stub_response('<hash><foo>bar</foo></hash>', 200)
282
+ @http.stub!(:request).and_return(redirect, ok)
283
+ response = @request.perform
284
+ response.request.base_uri.to_s.should == "http://api.foo.com"
285
+ response.request.path.to_s.should == "/foo/bar?q=search%20term"
286
+ response.request.uri.request_uri.should == "/foo/bar?q=search%20term"
287
+ response.request.uri.to_s.should == "http://api.foo.com/foo/bar?q=search%20term"
288
+ end
289
+
290
+ it "handles multiple redirects and relative location headers on different hosts" do
291
+ @request = HTTParty::Request.new(Net::HTTP::Get, 'http://test.com/redirect', :format => :xml)
292
+ FakeWeb.register_uri(:get, "http://test.com/redirect", :status => [300, "REDIRECT"], :location => "http://api.foo.com/v2")
293
+ FakeWeb.register_uri(:get, "http://api.foo.com/v2", :status => [300, "REDIRECT"], :location => "/v3")
294
+ FakeWeb.register_uri(:get, "http://api.foo.com/v3", :body => "<hash><foo>bar</foo></hash>")
295
+ response = @request.perform
296
+ response.request.base_uri.to_s.should == "http://api.foo.com"
297
+ response.request.path.to_s.should == "/v3"
298
+ response.request.uri.request_uri.should == "/v3"
299
+ response.request.uri.to_s.should == "http://api.foo.com/v3"
300
+ response.should == {"hash" => {"foo" => "bar"}}
301
+ end
302
+
303
+ it "returns the HTTParty::Response when the 300 does not contain a location header" do
304
+ net_response = stub_response '', 300
305
+ HTTParty::Response.should === @request.perform
306
+ end
307
+ end
308
+
309
+ it 'should return a valid object for 4xx response' do
310
+ stub_response '<foo><bar>yes</bar></foo>', 401
311
+ resp = @request.perform
312
+ resp.code.should == 401
313
+ resp.body.should == "<foo><bar>yes</bar></foo>"
314
+ resp['foo']['bar'].should == "yes"
315
+ end
316
+
317
+ it 'should return a valid object for 5xx response' do
318
+ stub_response '<foo><bar>error</bar></foo>', 500
319
+ resp = @request.perform
320
+ resp.code.should == 500
321
+ resp.body.should == "<foo><bar>error</bar></foo>"
322
+ resp['foo']['bar'].should == "error"
323
+ end
324
+
325
+ it "parses response lazily so codes can be checked prior" do
326
+ stub_response 'not xml', 500
327
+ @request.options[:format] = :xml
328
+ lambda {
329
+ response = @request.perform
330
+ response.code.should == 500
331
+ response.body.should == 'not xml'
332
+ }.should_not raise_error
333
+ end
334
+ end
335
+ end
336
+
337
+ it "should not attempt to parse empty responses" do
338
+ [204, 304].each do |code|
339
+ stub_response "", code
340
+
341
+ @request.options[:format] = :xml
342
+ @request.perform.should be_nil
343
+ end
344
+ end
345
+
346
+ it "should not fail for missing mime type" do
347
+ stub_response "Content for you"
348
+ @request.options[:format] = :html
349
+ @request.perform.should == 'Content for you'
350
+ end
351
+
352
+ describe "a request that redirects" do
353
+ before(:each) do
354
+ @redirect = stub_response("", 302)
355
+ @redirect['location'] = '/foo'
356
+
357
+ @ok = stub_response('<hash><foo>bar</foo></hash>', 200)
358
+ end
359
+
360
+ describe "once" do
361
+ before(:each) do
362
+ @http.stub!(:request).and_return(@redirect, @ok)
363
+ end
364
+
365
+ it "should be handled by GET transparently" do
366
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
367
+ end
368
+
369
+ it "should be handled by POST transparently" do
370
+ @request.http_method = Net::HTTP::Post
371
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
372
+ end
373
+
374
+ it "should be handled by DELETE transparently" do
375
+ @request.http_method = Net::HTTP::Delete
376
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
377
+ end
378
+
379
+ it "should be handled by PATCH transparently" do
380
+ @request.http_method = Net::HTTP::Patch
381
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
382
+ end
383
+
384
+ it "should be handled by PUT transparently" do
385
+ @request.http_method = Net::HTTP::Put
386
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
387
+ end
388
+
389
+ it "should be handled by HEAD transparently" do
390
+ @request.http_method = Net::HTTP::Head
391
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
392
+ end
393
+
394
+ it "should be handled by OPTIONS transparently" do
395
+ @request.http_method = Net::HTTP::Options
396
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
397
+ end
398
+
399
+ it "should keep track of cookies between redirects" do
400
+ @redirect['Set-Cookie'] = 'foo=bar; name=value; HTTPOnly'
401
+ @request.perform
402
+ @request.options[:headers]['Cookie'].should match(/foo=bar/)
403
+ @request.options[:headers]['Cookie'].should match(/name=value/)
404
+ end
405
+
406
+ it 'should update cookies with rediects' do
407
+ @request.options[:headers] = {'Cookie'=> 'foo=bar;'}
408
+ @redirect['Set-Cookie'] = 'foo=tar;'
409
+ @request.perform
410
+ @request.options[:headers]['Cookie'].should match(/foo=tar/)
411
+ end
412
+
413
+ it 'should keep cookies between rediects' do
414
+ @request.options[:headers] = {'Cookie'=> 'keep=me'}
415
+ @redirect['Set-Cookie'] = 'foo=tar;'
416
+ @request.perform
417
+ @request.options[:headers]['Cookie'].should match(/keep=me/)
418
+ end
419
+
420
+ it 'should make resulting request a get request if it not already' do
421
+ @request.http_method = Net::HTTP::Delete
422
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
423
+ @request.http_method.should == Net::HTTP::Get
424
+ end
425
+
426
+ it 'should not make resulting request a get request if options[:maintain_method_across_redirects] is true' do
427
+ @request.options[:maintain_method_across_redirects] = true
428
+ @request.http_method = Net::HTTP::Delete
429
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
430
+ @request.http_method.should == Net::HTTP::Delete
431
+ end
432
+ end
433
+
434
+ describe "infinitely" do
435
+ before(:each) do
436
+ @http.stub!(:request).and_return(@redirect)
437
+ end
438
+
439
+ it "should raise an exception" do
440
+ lambda { @request.perform }.should raise_error(HTTParty::RedirectionTooDeep)
441
+ end
442
+ end
443
+ end
444
+
445
+ describe "#handle_deflation" do
446
+ context "context-encoding" do
447
+ before do
448
+ @request.options[:format] = :html
449
+ @last_response = mock()
450
+ @last_response.stub!(:body).and_return('')
451
+ end
452
+
453
+ it "should inflate the gzipped body with content-encoding: gzip" do
454
+ @last_response.stub!(:[]).with("content-encoding").and_return("gzip")
455
+ @request.stub!(:last_response).and_return(@last_response)
456
+ Zlib::GzipReader.should_receive(:new).and_return(StringIO.new(''))
457
+ @request.last_response.should_receive(:delete).with('content-encoding')
458
+ @request.send(:handle_deflation)
459
+ end
460
+
461
+ it "should inflate the gzipped body with content-encoding: x-gzip" do
462
+ @last_response.stub!(:[]).with("content-encoding").and_return("x-gzip")
463
+ @request.stub!(:last_response).and_return(@last_response)
464
+ Zlib::GzipReader.should_receive(:new).and_return(StringIO.new(''))
465
+ @request.last_response.should_receive(:delete).with('content-encoding')
466
+ @request.send(:handle_deflation)
467
+ end
468
+
469
+ it "should inflate the deflated body" do
470
+ @last_response.stub!(:[]).with("content-encoding").and_return("deflate")
471
+ @request.stub!(:last_response).and_return(@last_response)
472
+ Zlib::Inflate.should_receive(:inflate).and_return('')
473
+ @request.last_response.should_receive(:delete).with('content-encoding')
474
+ @request.send(:handle_deflation)
475
+ end
476
+ end
477
+ end
478
+
479
+ context "with POST http method" do
480
+ it "should raise argument error if query is not a hash" do
481
+ lambda {
482
+ HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :format => :xml, :query => 'astring').perform
483
+ }.should raise_error(ArgumentError)
484
+ end
485
+ end
486
+
487
+ describe "argument validation" do
488
+ it "should raise argument error if basic_auth and digest_auth are both present" do
489
+ lambda {
490
+ HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :basic_auth => {}, :digest_auth => {}).perform
491
+ }.should raise_error(ArgumentError, "only one authentication method, :basic_auth or :digest_auth may be used at a time")
492
+ end
493
+
494
+ it "should raise argument error if basic_auth is not a hash" do
495
+ lambda {
496
+ HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :basic_auth => ["foo", "bar"]).perform
497
+ }.should raise_error(ArgumentError, ":basic_auth must be a hash")
498
+ end
499
+
500
+ it "should raise argument error if digest_auth is not a hash" do
501
+ lambda {
502
+ HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :digest_auth => ["foo", "bar"]).perform
503
+ }.should raise_error(ArgumentError, ":digest_auth must be a hash")
504
+ end
505
+ end
506
+ end
507
+