yyyc514-httparty 0.4.4.2

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 (48) hide show
  1. data/History +131 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Manifest +47 -0
  4. data/README.rdoc +54 -0
  5. data/Rakefile +48 -0
  6. data/bin/httparty +98 -0
  7. data/cucumber.yml +1 -0
  8. data/examples/aaws.rb +32 -0
  9. data/examples/basic.rb +11 -0
  10. data/examples/delicious.rb +37 -0
  11. data/examples/google.rb +16 -0
  12. data/examples/rubyurl.rb +14 -0
  13. data/examples/twitter.rb +31 -0
  14. data/examples/whoismyrep.rb +10 -0
  15. data/features/basic_authentication.feature +20 -0
  16. data/features/command_line.feature +7 -0
  17. data/features/deals_with_http_error_codes.feature +26 -0
  18. data/features/handles_multiple_formats.feature +34 -0
  19. data/features/steps/env.rb +15 -0
  20. data/features/steps/httparty_response_steps.rb +26 -0
  21. data/features/steps/httparty_steps.rb +15 -0
  22. data/features/steps/mongrel_helper.rb +55 -0
  23. data/features/steps/remote_service_steps.rb +47 -0
  24. data/features/supports_redirection.feature +22 -0
  25. data/lib/httparty.rb +206 -0
  26. data/lib/httparty/class_inheritable_attributes.rb +25 -0
  27. data/lib/httparty/cookie_hash.rb +9 -0
  28. data/lib/httparty/core_extensions.rb +29 -0
  29. data/lib/httparty/exceptions.rb +7 -0
  30. data/lib/httparty/request.rb +141 -0
  31. data/lib/httparty/response.rb +18 -0
  32. data/lib/httparty/version.rb +3 -0
  33. data/spec/fixtures/delicious.xml +23 -0
  34. data/spec/fixtures/empty.xml +0 -0
  35. data/spec/fixtures/google.html +3 -0
  36. data/spec/fixtures/twitter.json +1 -0
  37. data/spec/fixtures/twitter.xml +403 -0
  38. data/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
  39. data/spec/httparty/cookie_hash_spec.rb +38 -0
  40. data/spec/httparty/request_spec.rb +199 -0
  41. data/spec/httparty/response_spec.rb +62 -0
  42. data/spec/httparty_spec.rb +307 -0
  43. data/spec/spec.opts +3 -0
  44. data/spec/spec_helper.rb +21 -0
  45. data/website/css/common.css +47 -0
  46. data/website/index.html +74 -0
  47. data/yyyc514-httparty.gemspec +40 -0
  48. metadata +134 -0
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <Entities total="0" results="0" page="1" page-size="25" href="https://s3-sandbox.parature.com/api/v1/5578/5633/Account" />
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
2
+
3
+ describe HTTParty::CookieHash do
4
+ before(:each) do
5
+ @cookie_hash = HTTParty::CookieHash.new
6
+ end
7
+
8
+ describe "#add_cookies" do
9
+ it "should add new key/value pairs to the hash" do
10
+ @cookie_hash.add_cookies(:foo => "bar")
11
+ @cookie_hash.add_cookies(:rofl => "copter")
12
+ @cookie_hash.length.should eql(2)
13
+ end
14
+
15
+ it "should overwrite any existing key" do
16
+ @cookie_hash.add_cookies(:foo => "bar")
17
+ @cookie_hash.add_cookies(:foo => "copter")
18
+ @cookie_hash.length.should eql(1)
19
+ @cookie_hash[:foo].should eql("copter")
20
+ end
21
+ end
22
+
23
+ # The regexen are required because Hashes aren't ordered, so a test against
24
+ # a hardcoded string was randomly failing.
25
+ describe "#to_cookie_string" do
26
+ before(:each) do
27
+ @cookie_hash.add_cookies(:foo => "bar")
28
+ @cookie_hash.add_cookies(:rofl => "copter")
29
+ @s = @cookie_hash.to_cookie_string
30
+ end
31
+
32
+ it "should format the key/value pairs, delimited by semi-colons" do
33
+ @s.should match(/foo=bar/)
34
+ @s.should match(/rofl=copter/)
35
+ @s.should match(/^\w+=\w+; \w+=\w+$/)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,199 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe HTTParty::Request do
4
+ def stub_response(body, code = 200)
5
+ unless @http
6
+ @http = Net::HTTP.new('localhost', 80)
7
+ @request.stub!(:http).and_return(@http)
8
+ @request.stub!(:uri).and_return(URI.parse("http://foo.com/foobar"))
9
+ end
10
+
11
+ response = Net::HTTPResponse::CODE_TO_OBJ[code.to_s].new("1.1", code, body)
12
+ response.stub!(:body).and_return(body)
13
+
14
+ @http.stub!(:request).and_return(response)
15
+ response
16
+ end
17
+
18
+ before do
19
+ @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
20
+ end
21
+
22
+ describe "#format" do
23
+ it "should return the correct parsing format" do
24
+ @request.format.should == :xml
25
+ end
26
+ end
27
+
28
+ describe 'http' do
29
+ it "should use ssl for port 443" do
30
+ request = HTTParty::Request.new(Net::HTTP::Get, 'https://api.foo.com/v1:443')
31
+ request.send(:http).use_ssl?.should == true
32
+ end
33
+
34
+ it 'should not use ssl for port 80' do
35
+ request = HTTParty::Request.new(Net::HTTP::Get, 'http://foobar.com')
36
+ request.send(:http).use_ssl?.should == false
37
+ end
38
+
39
+ it "should use ssl for https scheme" do
40
+ request = HTTParty::Request.new(Net::HTTP::Get, 'https://foobar.com')
41
+ request.send(:http).use_ssl?.should == true
42
+ end
43
+
44
+ it "should use basic auth when configured" do
45
+ @request.options[:basic_auth] = {:username => 'foobar', :password => 'secret'}
46
+ @request.send(:setup_raw_request)
47
+ @request.instance_variable_get(:@raw_request)['authorization'].should_not be_nil
48
+ end
49
+ end
50
+
51
+ describe '#format_from_mimetype' do
52
+ it 'should handle text/xml' do
53
+ ["text/xml", "text/xml; charset=iso8859-1"].each do |ct|
54
+ @request.send(:format_from_mimetype, ct).should == :xml
55
+ end
56
+ end
57
+
58
+ it 'should handle application/xml' do
59
+ ["application/xml", "application/xml; charset=iso8859-1"].each do |ct|
60
+ @request.send(:format_from_mimetype, ct).should == :xml
61
+ end
62
+ end
63
+
64
+ it 'should handle text/json' do
65
+ ["text/json", "text/json; charset=iso8859-1"].each do |ct|
66
+ @request.send(:format_from_mimetype, ct).should == :json
67
+ end
68
+ end
69
+
70
+ it 'should handle application/json' do
71
+ ["application/json", "application/json; charset=iso8859-1"].each do |ct|
72
+ @request.send(:format_from_mimetype, ct).should == :json
73
+ end
74
+ end
75
+
76
+ it 'should handle text/javascript' do
77
+ ["text/javascript", "text/javascript; charset=iso8859-1"].each do |ct|
78
+ @request.send(:format_from_mimetype, ct).should == :json
79
+ end
80
+ end
81
+
82
+ it 'should handle application/javascript' do
83
+ ["application/javascript", "application/javascript; charset=iso8859-1"].each do |ct|
84
+ @request.send(:format_from_mimetype, ct).should == :json
85
+ end
86
+ end
87
+ end
88
+
89
+ describe 'parsing responses' do
90
+ it 'should handle xml automatically' do
91
+ xml = %q[<books><book><id>1234</id><name>Foo Bar!</name></book></books>]
92
+ @request.options[:format] = :xml
93
+ @request.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
94
+ end
95
+
96
+ it 'should handle json automatically' do
97
+ json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}]
98
+ @request.options[:format] = :json
99
+ @request.send(:parse_response, json).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
100
+ end
101
+
102
+ it 'should handle yaml automatically' do
103
+ yaml = "books: \n book: \n name: Foo Bar!\n id: \"1234\"\n"
104
+ @request.options[:format] = :yaml
105
+ @request.send(:parse_response, yaml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}}
106
+ end
107
+
108
+ it "should include any HTTP headers in the returned response" do
109
+ @request.options[:format] = :html
110
+ response = stub_response "Content"
111
+ response.initialize_http_header("key" => "value")
112
+
113
+ @request.perform.headers.should == { "key" => ["value"] }
114
+ end
115
+
116
+ describe 'with non-200 responses' do
117
+ it 'should return a valid object for 4xx response' do
118
+ stub_response '<foo><bar>yes</bar></foo>', 401
119
+ resp = @request.perform
120
+ resp.code.should == 401
121
+ resp.body.should == "<foo><bar>yes</bar></foo>"
122
+ resp['foo']['bar'].should == "yes"
123
+ end
124
+
125
+ it 'should return a valid object for 5xx response' do
126
+ stub_response '<foo><bar>error</bar></foo>', 500
127
+ resp = @request.perform
128
+ resp.code.should == 500
129
+ resp.body.should == "<foo><bar>error</bar></foo>"
130
+ resp['foo']['bar'].should == "error"
131
+ end
132
+ end
133
+ end
134
+
135
+ it "should not attempt to parse empty responses" do
136
+ stub_response "", 204
137
+
138
+ @request.options[:format] = :xml
139
+ @request.perform.should be_nil
140
+ end
141
+
142
+ it "should not fail for missing mime type" do
143
+ stub_response "Content for you"
144
+ @request.options[:format] = :html
145
+ @request.perform.should == 'Content for you'
146
+ end
147
+
148
+ describe "a request that redirects" do
149
+ before(:each) do
150
+ @redirect = stub_response("", 302)
151
+ @redirect['location'] = '/foo'
152
+
153
+ @ok = stub_response('<hash><foo>bar</foo></hash>', 200)
154
+ end
155
+
156
+ describe "once" do
157
+ before(:each) do
158
+ @http.stub!(:request).and_return(@redirect, @ok)
159
+ end
160
+
161
+ it "should be handled by GET transparently" do
162
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
163
+ end
164
+
165
+ it "should be handled by POST transparently" do
166
+ @request.http_method = Net::HTTP::Post
167
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
168
+ end
169
+
170
+ it "should be handled by DELETE transparently" do
171
+ @request.http_method = Net::HTTP::Delete
172
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
173
+ end
174
+
175
+ it "should be handled by PUT transparently" do
176
+ @request.http_method = Net::HTTP::Put
177
+ @request.perform.should == {"hash" => {"foo" => "bar"}}
178
+ end
179
+ end
180
+
181
+ describe "infinitely" do
182
+ before(:each) do
183
+ @http.stub!(:request).and_return(@redirect)
184
+ end
185
+
186
+ it "should raise an exception" do
187
+ lambda { @request.perform }.should raise_error(HTTParty::RedirectionTooDeep)
188
+ end
189
+ end
190
+ end
191
+ end
192
+
193
+ describe HTTParty::Request, "with POST http method" do
194
+ it "should raise argument error if query is not a hash" do
195
+ lambda {
196
+ HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :format => :xml, :query => 'astring').perform
197
+ }.should raise_error(ArgumentError)
198
+ end
199
+ end
@@ -0,0 +1,62 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe HTTParty::Response do
4
+ describe "initialization" do
5
+ before do
6
+ @response_object = {'foo' => 'bar'}
7
+ @body = "{foo:'bar'}"
8
+ @code = '200'
9
+ @message = 'OK'
10
+ @response = HTTParty::Response.new(@response_object, @body, @code, @message)
11
+ end
12
+
13
+ it "should set delegate" do
14
+ @response.delegate.should == @response_object
15
+ end
16
+
17
+ it "should set body" do
18
+ @response.body.should == @body
19
+ end
20
+
21
+ it "should set code" do
22
+ @response.code.should.to_s == @code
23
+ end
24
+
25
+ it "should set code as a Fixnum" do
26
+ @response.code.should be_an_instance_of(Fixnum)
27
+ end
28
+
29
+ it "should set body" do
30
+ @response.body.should == @body
31
+ end
32
+ end
33
+
34
+ it "should be able to set headers during initialization" do
35
+ response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200, 'OK', {'foo' => 'bar'})
36
+ response.headers.should == {'foo' => 'bar'}
37
+ end
38
+
39
+ it "should send missing methods to delegate" do
40
+ response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200, 'OK')
41
+ response['foo'].should == 'bar'
42
+ end
43
+
44
+ it "should be able to iterate delegate if it is array" do
45
+ response = HTTParty::Response.new([{'foo' => 'bar'}, {'foo' => 'baz'}], "[{foo:'bar'}, {foo:'baz'}]", 200, 'OK')
46
+ response.size.should == 2
47
+ lambda {
48
+ response.each { |item| }
49
+ }.should_not raise_error
50
+ end
51
+
52
+ xit "should allow hashes to be accessed with dot notation" do
53
+ response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200, 'OK')
54
+ response.foo.should == 'bar'
55
+ end
56
+
57
+ xit "should allow nested hashes to be accessed with dot notation" do
58
+ response = HTTParty::Response.new({'foo' => {'bar' => 'baz'}}, "{foo: {bar:'baz'}}", 200, 'OK')
59
+ response.foo.should == {'bar' => 'baz'}
60
+ response.foo.bar.should == 'baz'
61
+ end
62
+ end
@@ -0,0 +1,307 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ describe HTTParty do
4
+ before(:each) do
5
+ @klass = Class.new
6
+ @klass.instance_eval { include HTTParty }
7
+ end
8
+
9
+ describe "base uri" do
10
+ before(:each) do
11
+ @klass.base_uri('api.foo.com/v1')
12
+ end
13
+
14
+ it "should have reader" do
15
+ @klass.base_uri.should == 'http://api.foo.com/v1'
16
+ end
17
+
18
+ it 'should have writer' do
19
+ @klass.base_uri('http://api.foobar.com')
20
+ @klass.base_uri.should == 'http://api.foobar.com'
21
+ end
22
+
23
+ it 'should not modify the parameter during assignment' do
24
+ uri = 'http://api.foobar.com'
25
+ @klass.base_uri(uri)
26
+ uri.should == 'http://api.foobar.com'
27
+ end
28
+ end
29
+
30
+ describe "#normalize_base_uri" do
31
+ it "should add http if not present for non ssl requests" do
32
+ uri = HTTParty.normalize_base_uri('api.foobar.com')
33
+ uri.should == 'http://api.foobar.com'
34
+ end
35
+
36
+ it "should add https if not present for ssl requests" do
37
+ uri = HTTParty.normalize_base_uri('api.foo.com/v1:443')
38
+ uri.should == 'https://api.foo.com/v1:443'
39
+ end
40
+
41
+ it "should not remove https for ssl requests" do
42
+ uri = HTTParty.normalize_base_uri('https://api.foo.com/v1:443')
43
+ uri.should == 'https://api.foo.com/v1:443'
44
+ end
45
+
46
+ it 'should not modify the parameter' do
47
+ uri = 'http://api.foobar.com'
48
+ HTTParty.normalize_base_uri(uri)
49
+ uri.should == 'http://api.foobar.com'
50
+ end
51
+ end
52
+
53
+ describe "headers" do
54
+ it "should default to empty hash" do
55
+ @klass.headers.should == {}
56
+ end
57
+
58
+ it "should be able to be updated" do
59
+ init_headers = {:foo => 'bar', :baz => 'spax'}
60
+ @klass.headers init_headers
61
+ @klass.headers.should == init_headers
62
+ end
63
+ end
64
+
65
+ describe "cookies" do
66
+ def expect_cookie_header(s)
67
+ HTTParty::Request.should_receive(:new) \
68
+ .with(anything, anything, hash_including({ :headers => { "cookie" => s } })) \
69
+ .and_return(mock("mock response", :perform => nil))
70
+ end
71
+
72
+ it "should not be in the headers by default" do
73
+ HTTParty::Request.stub!(:new).and_return(stub(nil, :perform => nil))
74
+ @klass.get("")
75
+ @klass.headers.keys.should_not include("cookie")
76
+ end
77
+
78
+ it "should raise an ArgumentError if passed a non-Hash" do
79
+ lambda do
80
+ @klass.cookies("nonsense")
81
+ end.should raise_error(ArgumentError)
82
+ end
83
+
84
+ it "should allow a cookie to be specified with a one-off request" do
85
+ expect_cookie_header "type=snickerdoodle"
86
+ @klass.get("", :cookies => { :type => "snickerdoodle" })
87
+ end
88
+
89
+ describe "when a cookie is set at the class level" do
90
+ before(:each) do
91
+ @klass.cookies({ :type => "snickerdoodle" })
92
+ end
93
+
94
+ it "should include that cookie in the request" do
95
+ expect_cookie_header "type=snickerdoodle"
96
+ @klass.get("")
97
+ end
98
+
99
+ it "should pass the proper cookies when requested multiple times" do
100
+ 2.times do
101
+ expect_cookie_header "type=snickerdoodle"
102
+ @klass.get("")
103
+ end
104
+ end
105
+
106
+ it "should allow the class defaults to be overridden" do
107
+ expect_cookie_header "type=chocolate_chip"
108
+
109
+ @klass.get("", :cookies => { :type => "chocolate_chip" })
110
+ end
111
+ end
112
+
113
+ describe "in a class with multiple methods that use different cookies" do
114
+ before(:each) do
115
+ @klass.instance_eval do
116
+ def first_method
117
+ get("first_method", :cookies => { :first_method_cookie => "foo" })
118
+ end
119
+
120
+ def second_method
121
+ get("second_method", :cookies => { :second_method_cookie => "foo" })
122
+ end
123
+ end
124
+ end
125
+
126
+ it "should not allow cookies used in one method to carry over into other methods" do
127
+ expect_cookie_header "first_method_cookie=foo"
128
+ @klass.first_method
129
+
130
+ expect_cookie_header "second_method_cookie=foo"
131
+ @klass.second_method
132
+ end
133
+ end
134
+ end
135
+
136
+ describe "default params" do
137
+ it "should default to empty hash" do
138
+ @klass.default_params.should == {}
139
+ end
140
+
141
+ it "should be able to be updated" do
142
+ new_defaults = {:foo => 'bar', :baz => 'spax'}
143
+ @klass.default_params new_defaults
144
+ @klass.default_params.should == new_defaults
145
+ end
146
+ end
147
+
148
+ describe "basic http authentication" do
149
+ it "should work" do
150
+ @klass.basic_auth 'foobar', 'secret'
151
+ @klass.default_options[:basic_auth].should == {:username => 'foobar', :password => 'secret'}
152
+ end
153
+ end
154
+
155
+ describe "format" do
156
+ it "should allow xml" do
157
+ @klass.format :xml
158
+ @klass.default_options[:format].should == :xml
159
+ end
160
+
161
+ it "should allow json" do
162
+ @klass.format :json
163
+ @klass.default_options[:format].should == :json
164
+ end
165
+
166
+ it "should allow yaml" do
167
+ @klass.format :yaml
168
+ @klass.default_options[:format].should == :yaml
169
+ end
170
+
171
+ it "should allow plain" do
172
+ @klass.format :plain
173
+ @klass.default_options[:format].should == :plain
174
+ end
175
+
176
+ it 'should not allow funky format' do
177
+ lambda do
178
+ @klass.format :foobar
179
+ end.should raise_error(HTTParty::UnsupportedFormat)
180
+ end
181
+
182
+ it 'should only print each format once with an exception' do
183
+ lambda do
184
+ @klass.format :foobar
185
+ end.should raise_error(HTTParty::UnsupportedFormat, "Must be one of: html, json, plain, xml, yaml")
186
+ end
187
+
188
+ end
189
+
190
+ describe "with explicit override of automatic redirect handling" do
191
+
192
+ it "should fail with redirected GET" do
193
+ lambda do
194
+ @klass.get('/foo', :no_follow => true)
195
+ end.should raise_error(HTTParty::RedirectionTooDeep)
196
+ end
197
+
198
+ it "should fail with redirected POST" do
199
+ lambda do
200
+ @klass.post('/foo', :no_follow => true)
201
+ end.should raise_error(HTTParty::RedirectionTooDeep)
202
+ end
203
+
204
+ it "should fail with redirected DELETE" do
205
+ lambda do
206
+ @klass.delete('/foo', :no_follow => true)
207
+ end.should raise_error(HTTParty::RedirectionTooDeep)
208
+ end
209
+
210
+ it "should fail with redirected PUT" do
211
+ lambda do
212
+ @klass.put('/foo', :no_follow => true)
213
+ end.should raise_error(HTTParty::RedirectionTooDeep)
214
+ end
215
+ end
216
+
217
+ describe "with multiple class definitions" do
218
+ before(:each) do
219
+ @klass.instance_eval do
220
+ base_uri "http://first.com"
221
+ default_params :one => 1
222
+ end
223
+
224
+ @additional_klass = Class.new
225
+ @additional_klass.instance_eval do
226
+ include HTTParty
227
+ base_uri "http://second.com"
228
+ default_params :two => 2
229
+ end
230
+ end
231
+
232
+ it "should not run over each others options" do
233
+ @klass.default_options.should == { :base_uri => 'http://first.com', :default_params => { :one => 1 } }
234
+ @additional_klass.default_options.should == { :base_uri => 'http://second.com', :default_params => { :two => 2 } }
235
+ end
236
+ end
237
+
238
+ describe "#get" do
239
+ it "should be able to get html" do
240
+ stub_http_response_with('google.html')
241
+ HTTParty.get('http://www.google.com').should == file_fixture('google.html')
242
+ end
243
+
244
+ it "should be able parse response type json automatically" do
245
+ stub_http_response_with('twitter.json')
246
+ tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
247
+ tweets.size.should == 20
248
+ tweets.first['user'].should == {
249
+ "name" => "Pyk",
250
+ "url" => nil,
251
+ "id" => "7694602",
252
+ "description" => nil,
253
+ "protected" => false,
254
+ "screen_name" => "Pyk",
255
+ "followers_count" => 1,
256
+ "location" => "Opera Plaza, California",
257
+ "profile_image_url" => "http://static.twitter.com/images/default_profile_normal.png"
258
+ }
259
+ end
260
+
261
+ it "should be able parse response type xml automatically" do
262
+ stub_http_response_with('twitter.xml')
263
+ tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.xml')
264
+ tweets['statuses'].size.should == 20
265
+ tweets['statuses'].first['user'].should == {
266
+ "name" => "Magic 8 Bot",
267
+ "url" => nil,
268
+ "id" => "17656026",
269
+ "description" => "ask me a question",
270
+ "protected" => "false",
271
+ "screen_name" => "magic8bot",
272
+ "followers_count" => "90",
273
+ "profile_image_url" => "http://s3.amazonaws.com/twitter_production/profile_images/65565851/8ball_large_normal.jpg",
274
+ "location" => nil
275
+ }
276
+ end
277
+
278
+ it "should not get undefined method add_node for nil class for the following xml" do
279
+ stub_http_response_with('undefined_method_add_node_for_nil.xml')
280
+ result = HTTParty.get('http://foobar.com')
281
+ result.should == {"Entities"=>{"href"=>"https://s3-sandbox.parature.com/api/v1/5578/5633/Account", "results"=>"0", "total"=>"0", "page_size"=>"25", "page"=>"1"}}
282
+ end
283
+
284
+ it "should parse empty response fine" do
285
+ stub_http_response_with('empty.xml')
286
+ result = HTTParty.get('http://foobar.com')
287
+ result.should == nil
288
+ end
289
+ end
290
+
291
+ describe "two child classes from one parent" do
292
+ before(:each) do
293
+ @parent = Class.new
294
+ @parent.instance_eval { include HTTParty }
295
+ @child1 = Class.new(@parent)
296
+ @child2 = Class.new(@parent)
297
+ @child1.instance_eval { default_params({ :joe => "alive" })}
298
+ @child2.instance_eval { default_params({ :joe => "dead" })}
299
+ end
300
+
301
+ it "should not muck with each others inherited attributes" do
302
+ @child1.default_options.should == { :default_params => {:joe => "alive"} }
303
+ @child2.default_options.should == { :default_params => {:joe => "dead"} }
304
+ end
305
+ end
306
+
307
+ end