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.
- data/History +131 -0
- data/MIT-LICENSE +20 -0
- data/Manifest +47 -0
- data/README.rdoc +54 -0
- data/Rakefile +48 -0
- data/bin/httparty +98 -0
- data/cucumber.yml +1 -0
- data/examples/aaws.rb +32 -0
- data/examples/basic.rb +11 -0
- data/examples/delicious.rb +37 -0
- data/examples/google.rb +16 -0
- data/examples/rubyurl.rb +14 -0
- data/examples/twitter.rb +31 -0
- data/examples/whoismyrep.rb +10 -0
- data/features/basic_authentication.feature +20 -0
- data/features/command_line.feature +7 -0
- data/features/deals_with_http_error_codes.feature +26 -0
- data/features/handles_multiple_formats.feature +34 -0
- data/features/steps/env.rb +15 -0
- data/features/steps/httparty_response_steps.rb +26 -0
- data/features/steps/httparty_steps.rb +15 -0
- data/features/steps/mongrel_helper.rb +55 -0
- data/features/steps/remote_service_steps.rb +47 -0
- data/features/supports_redirection.feature +22 -0
- data/lib/httparty.rb +206 -0
- data/lib/httparty/class_inheritable_attributes.rb +25 -0
- data/lib/httparty/cookie_hash.rb +9 -0
- data/lib/httparty/core_extensions.rb +29 -0
- data/lib/httparty/exceptions.rb +7 -0
- data/lib/httparty/request.rb +141 -0
- data/lib/httparty/response.rb +18 -0
- data/lib/httparty/version.rb +3 -0
- data/spec/fixtures/delicious.xml +23 -0
- data/spec/fixtures/empty.xml +0 -0
- data/spec/fixtures/google.html +3 -0
- data/spec/fixtures/twitter.json +1 -0
- data/spec/fixtures/twitter.xml +403 -0
- data/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
- data/spec/httparty/cookie_hash_spec.rb +38 -0
- data/spec/httparty/request_spec.rb +199 -0
- data/spec/httparty/response_spec.rb +62 -0
- data/spec/httparty_spec.rb +307 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +21 -0
- data/website/css/common.css +47 -0
- data/website/index.html +74 -0
- data/yyyc514-httparty.gemspec +40 -0
- metadata +134 -0
@@ -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
|