ddollar-httparty 0.4.6

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