httparty 0.13.3 → 0.13.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of httparty might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +92 -0
- data/.rubocop_todo.yml +124 -0
- data/.simplecov +1 -0
- data/Gemfile +8 -3
- data/Guardfile +1 -1
- data/README.md +1 -0
- data/Rakefile +4 -5
- data/bin/httparty +9 -10
- data/examples/README.md +3 -0
- data/examples/aaws.rb +2 -2
- data/examples/crack.rb +1 -1
- data/examples/custom_parsers.rb +1 -4
- data/examples/delicious.rb +3 -3
- data/examples/google.rb +2 -2
- data/examples/logging.rb +5 -7
- data/examples/nokogiri_html_parser.rb +0 -3
- data/examples/rescue_json.rb +17 -0
- data/examples/rubyurl.rb +3 -3
- data/examples/twitter.rb +2 -2
- data/examples/whoismyrep.rb +1 -1
- data/features/command_line.feature +85 -2
- data/features/steps/env.rb +16 -11
- data/features/steps/httparty_response_steps.rb +13 -13
- data/features/steps/mongrel_helper.rb +2 -2
- data/features/steps/remote_service_steps.rb +18 -6
- data/httparty.gemspec +4 -4
- data/lib/httparty.rb +37 -56
- data/lib/httparty/connection_adapter.rb +3 -4
- data/lib/httparty/cookie_hash.rb +2 -3
- data/lib/httparty/hash_conversions.rb +3 -5
- data/lib/httparty/logger/apache_logger.rb +1 -1
- data/lib/httparty/logger/logger.rb +1 -1
- data/lib/httparty/module_inheritable_attributes.rb +1 -1
- data/lib/httparty/net_digest_auth.rb +46 -16
- data/lib/httparty/request.rb +16 -16
- data/lib/httparty/response.rb +9 -4
- data/lib/httparty/version.rb +1 -1
- data/spec/httparty/connection_adapter_spec.rb +184 -100
- data/spec/httparty/cookie_hash_spec.rb +21 -21
- data/spec/httparty/exception_spec.rb +22 -7
- data/spec/httparty/hash_conversions_spec.rb +41 -0
- data/spec/httparty/logger/apache_logger_spec.rb +3 -3
- data/spec/httparty/logger/curl_logger_spec.rb +2 -2
- data/spec/httparty/logger/logger_spec.rb +7 -7
- data/spec/httparty/net_digest_auth_spec.rb +60 -32
- data/spec/httparty/parser_spec.rb +37 -35
- data/spec/httparty/request_spec.rb +249 -193
- data/spec/httparty/response_spec.rb +37 -29
- data/spec/httparty/ssl_spec.rb +21 -21
- data/spec/httparty_spec.rb +153 -164
- data/spec/spec_helper.rb +34 -12
- data/spec/support/ssl_test_helper.rb +2 -2
- data/spec/support/ssl_test_server.rb +21 -21
- data/spec/support/stub_response.rb +10 -10
- metadata +9 -4
- data/lib/httparty/core_extensions.rb +0 -32
@@ -1,64 +1,64 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
|
-
describe HTTParty::Parser do
|
3
|
+
RSpec.describe HTTParty::Parser do
|
4
4
|
describe ".SupportedFormats" do
|
5
5
|
it "returns a hash" do
|
6
|
-
HTTParty::Parser::SupportedFormats.
|
6
|
+
expect(HTTParty::Parser::SupportedFormats).to be_instance_of(Hash)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
describe ".call" do
|
11
11
|
it "generates an HTTParty::Parser instance with the given body and format" do
|
12
|
-
HTTParty::Parser.
|
12
|
+
expect(HTTParty::Parser).to receive(:new).with('body', :plain).and_return(double(parse: nil))
|
13
13
|
HTTParty::Parser.call('body', :plain)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "calls #parse on the parser" do
|
17
|
-
parser =
|
18
|
-
parser.
|
19
|
-
HTTParty::Parser.
|
17
|
+
parser = double('Parser')
|
18
|
+
expect(parser).to receive(:parse)
|
19
|
+
allow(HTTParty::Parser).to receive_messages(new: parser)
|
20
20
|
parser = HTTParty::Parser.call('body', :plain)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
describe ".formats" do
|
25
25
|
it "returns the SupportedFormats constant" do
|
26
|
-
HTTParty::Parser.formats.
|
26
|
+
expect(HTTParty::Parser.formats).to eq(HTTParty::Parser::SupportedFormats)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "returns the SupportedFormats constant for subclasses" do
|
30
30
|
class MyParser < HTTParty::Parser
|
31
31
|
SupportedFormats = {"application/atom+xml" => :atom}
|
32
32
|
end
|
33
|
-
MyParser.formats.
|
33
|
+
expect(MyParser.formats).to eq({"application/atom+xml" => :atom})
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
describe ".format_from_mimetype" do
|
38
38
|
it "returns a symbol representing the format mimetype" do
|
39
|
-
HTTParty::Parser.format_from_mimetype("text/plain").
|
39
|
+
expect(HTTParty::Parser.format_from_mimetype("text/plain")).to eq(:plain)
|
40
40
|
end
|
41
41
|
|
42
42
|
it "returns nil when the mimetype is not supported" do
|
43
|
-
HTTParty::Parser.format_from_mimetype("application/atom+xml").
|
43
|
+
expect(HTTParty::Parser.format_from_mimetype("application/atom+xml")).to be_nil
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
describe ".supported_formats" do
|
48
48
|
it "returns a unique set of supported formats represented by symbols" do
|
49
|
-
HTTParty::Parser.supported_formats.
|
49
|
+
expect(HTTParty::Parser.supported_formats).to eq(HTTParty::Parser::SupportedFormats.values.uniq)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
describe ".supports_format?" do
|
54
54
|
it "returns true for a supported format" do
|
55
|
-
HTTParty::Parser.
|
56
|
-
HTTParty::Parser.supports_format?(:json).
|
55
|
+
allow(HTTParty::Parser).to receive_messages(supported_formats: [:json])
|
56
|
+
expect(HTTParty::Parser.supports_format?(:json)).to be_truthy
|
57
57
|
end
|
58
58
|
|
59
59
|
it "returns false for an unsupported format" do
|
60
|
-
HTTParty::Parser.
|
61
|
-
HTTParty::Parser.supports_format?(:json).
|
60
|
+
allow(HTTParty::Parser).to receive_messages(supported_formats: [])
|
61
|
+
expect(HTTParty::Parser.supports_format?(:json)).to be_falsey
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -68,40 +68,40 @@ describe HTTParty::Parser do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
it "attempts to parse supported formats" do
|
71
|
-
@parser.
|
72
|
-
@parser.
|
71
|
+
allow(@parser).to receive_messages(supports_format?: true)
|
72
|
+
expect(@parser).to receive(:parse_supported_format)
|
73
73
|
@parser.parse
|
74
74
|
end
|
75
75
|
|
76
76
|
it "returns the unparsed body when the format is unsupported" do
|
77
|
-
@parser.
|
78
|
-
@parser.parse.
|
77
|
+
allow(@parser).to receive_messages(supports_format?: false)
|
78
|
+
expect(@parser.parse).to eq(@parser.body)
|
79
79
|
end
|
80
80
|
|
81
81
|
it "returns nil for an empty body" do
|
82
|
-
@parser.
|
83
|
-
@parser.parse.
|
82
|
+
allow(@parser).to receive_messages(body: '')
|
83
|
+
expect(@parser.parse).to be_nil
|
84
84
|
end
|
85
85
|
|
86
86
|
it "returns nil for a nil body" do
|
87
|
-
@parser.
|
88
|
-
@parser.parse.
|
87
|
+
allow(@parser).to receive_messages(body: nil)
|
88
|
+
expect(@parser.parse).to be_nil
|
89
89
|
end
|
90
90
|
|
91
91
|
it "returns nil for a 'null' body" do
|
92
|
-
@parser.
|
93
|
-
@parser.parse.
|
92
|
+
allow(@parser).to receive_messages(body: "null")
|
93
|
+
expect(@parser.parse).to be_nil
|
94
94
|
end
|
95
95
|
|
96
96
|
it "returns nil for a body with spaces only" do
|
97
|
-
@parser.
|
98
|
-
@parser.parse.
|
97
|
+
allow(@parser).to receive_messages(body: " ")
|
98
|
+
expect(@parser.parse).to be_nil
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
102
|
describe "#supports_format?" do
|
103
103
|
it "utilizes the class method to determine if the format is supported" do
|
104
|
-
HTTParty::Parser.
|
104
|
+
expect(HTTParty::Parser).to receive(:supports_format?).with(:json)
|
105
105
|
parser = HTTParty::Parser.new('body', :json)
|
106
106
|
parser.send(:supports_format?)
|
107
107
|
end
|
@@ -110,7 +110,7 @@ describe HTTParty::Parser do
|
|
110
110
|
describe "#parse_supported_format" do
|
111
111
|
it "calls the parser for the given format" do
|
112
112
|
parser = HTTParty::Parser.new('body', :json)
|
113
|
-
parser.
|
113
|
+
expect(parser).to receive(:json)
|
114
114
|
parser.send(:parse_supported_format)
|
115
115
|
end
|
116
116
|
|
@@ -124,7 +124,9 @@ describe HTTParty::Parser do
|
|
124
124
|
|
125
125
|
it "raises a useful exception message for subclasses" do
|
126
126
|
atom_parser = Class.new(HTTParty::Parser) do
|
127
|
-
def self.name
|
127
|
+
def self.name
|
128
|
+
'AtomParser'
|
129
|
+
end
|
128
130
|
end
|
129
131
|
parser = atom_parser.new 'body', :atom
|
130
132
|
expect do
|
@@ -140,25 +142,25 @@ describe HTTParty::Parser do
|
|
140
142
|
end
|
141
143
|
|
142
144
|
it "parses xml with MultiXml" do
|
143
|
-
MultiXml.
|
145
|
+
expect(MultiXml).to receive(:parse).with('body')
|
144
146
|
subject.send(:xml)
|
145
147
|
end
|
146
148
|
|
147
149
|
it "parses json with JSON" do
|
148
|
-
JSON.
|
150
|
+
expect(JSON).to receive(:load).with('body', nil)
|
149
151
|
subject.send(:json)
|
150
152
|
end
|
151
153
|
|
152
154
|
it "parses html by simply returning the body" do
|
153
|
-
subject.send(:html).
|
155
|
+
expect(subject.send(:html)).to eq('body')
|
154
156
|
end
|
155
157
|
|
156
158
|
it "parses plain text by simply returning the body" do
|
157
|
-
subject.send(:plain).
|
159
|
+
expect(subject.send(:plain)).to eq('body')
|
158
160
|
end
|
159
161
|
|
160
162
|
it "parses csv with CSV" do
|
161
|
-
CSV.
|
163
|
+
expect(CSV).to receive(:parse).with('body')
|
162
164
|
subject.send(:csv)
|
163
165
|
end
|
164
166
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
|
-
describe HTTParty::Request do
|
3
|
+
RSpec.describe HTTParty::Request do
|
4
4
|
before do
|
5
5
|
@request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', format: :xml)
|
6
6
|
end
|
@@ -10,26 +10,25 @@ describe HTTParty::Request do
|
|
10
10
|
|
11
11
|
it "doesn't modify strings" do
|
12
12
|
query_string = normalizer["foo=bar&foo=baz"]
|
13
|
-
|
13
|
+
expect(CGI.unescape(query_string)).to eq("foo=bar&foo=baz")
|
14
14
|
end
|
15
15
|
|
16
16
|
context "when the query is an array" do
|
17
|
-
|
18
17
|
it "doesn't include brackets" do
|
19
18
|
query_string = normalizer[{page: 1, foo: %w(bar baz)}]
|
20
|
-
|
19
|
+
expect(CGI.unescape(query_string)).to eq("foo=bar&foo=baz&page=1")
|
21
20
|
end
|
22
21
|
|
23
22
|
it "URI encodes array values" do
|
24
23
|
query_string = normalizer[{people: ["Otis Redding", "Bob Marley", "Tim & Jon"], page: 1, xyzzy: 3}]
|
25
|
-
query_string.
|
24
|
+
expect(query_string).to eq("page=1&people=Otis%20Redding&people=Bob%20Marley&people=Tim%20%26%20Jon&xyzzy=3")
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
28
|
context "when the query is a hash" do
|
30
29
|
it "correctly handles nil values" do
|
31
30
|
query_string = normalizer[{page: 1, per_page: nil}]
|
32
|
-
query_string.
|
31
|
+
expect(query_string).to eq("page=1&per_page")
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
@@ -37,39 +36,39 @@ describe HTTParty::Request do
|
|
37
36
|
describe "initialization" do
|
38
37
|
it "sets parser to HTTParty::Parser" do
|
39
38
|
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
|
40
|
-
request.parser.
|
39
|
+
expect(request.parser).to eq(HTTParty::Parser)
|
41
40
|
end
|
42
41
|
|
43
42
|
it "sets parser to the optional parser" do
|
44
43
|
my_parser = lambda {}
|
45
44
|
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', parser: my_parser)
|
46
|
-
request.parser.
|
45
|
+
expect(request.parser).to eq(my_parser)
|
47
46
|
end
|
48
47
|
|
49
48
|
it "sets connection_adapter to HTTPParty::ConnectionAdapter" do
|
50
49
|
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
|
51
|
-
request.connection_adapter.
|
50
|
+
expect(request.connection_adapter).to eq(HTTParty::ConnectionAdapter)
|
52
51
|
end
|
53
52
|
|
54
53
|
it "sets connection_adapter to the optional connection_adapter" do
|
55
54
|
my_adapter = lambda {}
|
56
55
|
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', connection_adapter: my_adapter)
|
57
|
-
request.connection_adapter.
|
56
|
+
expect(request.connection_adapter).to eq(my_adapter)
|
58
57
|
end
|
59
58
|
|
60
59
|
context "when basic authentication credentials provided in uri" do
|
61
60
|
context "when basic auth options wasn't set explicitly" do
|
62
61
|
it "sets basic auth from uri" do
|
63
62
|
request = HTTParty::Request.new(Net::HTTP::Get, 'http://user1:pass1@example.com')
|
64
|
-
request.options[:basic_auth].
|
63
|
+
expect(request.options[:basic_auth]).to eq({username: 'user1', password: 'pass1'})
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
68
67
|
context "when basic auth options was set explicitly" do
|
69
68
|
it "uses basic auth from url anyway" do
|
70
|
-
basic_auth = {:
|
71
|
-
request = HTTParty::Request.new(Net::HTTP::Get, 'http://user1:pass1@example.com', :
|
72
|
-
request.options[:basic_auth].
|
69
|
+
basic_auth = {username: 'user2', password: 'pass2'}
|
70
|
+
request = HTTParty::Request.new(Net::HTTP::Get, 'http://user1:pass1@example.com', basic_auth: basic_auth)
|
71
|
+
expect(request.options[:basic_auth]).to eq({username: 'user1', password: 'pass1'})
|
73
72
|
end
|
74
73
|
end
|
75
74
|
end
|
@@ -79,49 +78,48 @@ describe HTTParty::Request do
|
|
79
78
|
context "request yet to be made" do
|
80
79
|
it "returns format option" do
|
81
80
|
request = HTTParty::Request.new 'get', '/', format: :xml
|
82
|
-
request.format.
|
81
|
+
expect(request.format).to eq(:xml)
|
83
82
|
end
|
84
83
|
|
85
84
|
it "returns nil format" do
|
86
85
|
request = HTTParty::Request.new 'get', '/'
|
87
|
-
request.format.
|
86
|
+
expect(request.format).to be_nil
|
88
87
|
end
|
89
88
|
end
|
90
89
|
|
91
90
|
context "request has been made" do
|
92
91
|
it "returns format option" do
|
93
92
|
request = HTTParty::Request.new 'get', '/', format: :xml
|
94
|
-
request.last_response =
|
95
|
-
request.format.
|
93
|
+
request.last_response = double
|
94
|
+
expect(request.format).to eq(:xml)
|
96
95
|
end
|
97
96
|
|
98
97
|
it "returns the content-type from the last response when the option is not set" do
|
99
98
|
request = HTTParty::Request.new 'get', '/'
|
100
|
-
response =
|
101
|
-
response.
|
99
|
+
response = double
|
100
|
+
expect(response).to receive(:[]).with('content-type').and_return('text/json')
|
102
101
|
request.last_response = response
|
103
|
-
request.format.
|
102
|
+
expect(request.format).to eq(:json)
|
104
103
|
end
|
105
104
|
end
|
106
|
-
|
107
105
|
end
|
108
106
|
|
109
107
|
context "options" do
|
110
108
|
it "should use basic auth when configured" do
|
111
109
|
@request.options[:basic_auth] = {username: 'foobar', password: 'secret'}
|
112
110
|
@request.send(:setup_raw_request)
|
113
|
-
@request.instance_variable_get(:@raw_request)['authorization'].
|
111
|
+
expect(@request.instance_variable_get(:@raw_request)['authorization']).not_to be_nil
|
114
112
|
end
|
115
113
|
|
116
114
|
it "should use digest auth when configured" do
|
117
115
|
FakeWeb.register_uri(:get, "http://api.foo.com/v1",
|
118
|
-
|
116
|
+
www_authenticate: 'Digest realm="Log Viewer", qop="auth", nonce="2CA0EC6B0E126C4800E56BA0C0003D3C", opaque="5ccc069c403ebaf9f0171e9517f40e41", stale=false')
|
119
117
|
|
120
118
|
@request.options[:digest_auth] = {username: 'foobar', password: 'secret'}
|
121
119
|
@request.send(:setup_raw_request)
|
122
120
|
|
123
121
|
raw_request = @request.instance_variable_get(:@raw_request)
|
124
|
-
raw_request.instance_variable_get(:@header)['Authorization'].
|
122
|
+
expect(raw_request.instance_variable_get(:@header)['Authorization']).not_to be_nil
|
125
123
|
end
|
126
124
|
|
127
125
|
it "should use the right http method for digest authentication" do
|
@@ -129,17 +127,46 @@ describe HTTParty::Request do
|
|
129
127
|
FakeWeb.register_uri(:post, "http://api.foo.com/v1", {})
|
130
128
|
|
131
129
|
http = @post_request.send(:http)
|
132
|
-
@post_request.
|
133
|
-
http.
|
130
|
+
expect(@post_request).to receive(:http).and_return(http)
|
131
|
+
expect(http).not_to receive(:head).with({'www-authenticate' => nil})
|
134
132
|
@post_request.options[:digest_auth] = {username: 'foobar', password: 'secret'}
|
135
133
|
@post_request.send(:setup_raw_request)
|
136
134
|
end
|
137
135
|
|
136
|
+
it 'should maintain cookies returned from setup_digest_auth' do
|
137
|
+
FakeWeb.register_uri(
|
138
|
+
:get, "http://api.foo.com/v1",
|
139
|
+
set_cookie: 'custom-cookie=1234567',
|
140
|
+
www_authenticate: 'Digest realm="Log Viewer", qop="auth", nonce="2CA0EC6B0E126C4800E56BA0C0003D3C", opaque="5ccc069c403ebaf9f0171e9517f40e41", stale=false'
|
141
|
+
)
|
142
|
+
|
143
|
+
@request.options[:digest_auth] = {username: 'foobar', password: 'secret'}
|
144
|
+
@request.send(:setup_raw_request)
|
145
|
+
|
146
|
+
raw_request = @request.instance_variable_get(:@raw_request)
|
147
|
+
expect(raw_request.instance_variable_get(:@header)['cookie']).to eql ["custom-cookie=1234567"]
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should merge cookies from setup_digest_auth and request' do
|
151
|
+
FakeWeb.register_uri(
|
152
|
+
:get, "http://api.foo.com/v1",
|
153
|
+
set_cookie: 'custom-cookie=1234567',
|
154
|
+
www_authenticate: 'Digest realm="Log Viewer", qop="auth", nonce="2CA0EC6B0E126C4800E56BA0C0003D3C", opaque="5ccc069c403ebaf9f0171e9517f40e41", stale=false'
|
155
|
+
)
|
156
|
+
|
157
|
+
@request.options[:digest_auth] = {username: 'foobar', password: 'secret'}
|
158
|
+
@request.options[:headers] = {'cookie' => 'request-cookie=test'}
|
159
|
+
@request.send(:setup_raw_request)
|
160
|
+
|
161
|
+
raw_request = @request.instance_variable_get(:@raw_request)
|
162
|
+
expect(raw_request.instance_variable_get(:@header)['cookie']).to eql ['request-cookie=test', 'custom-cookie=1234567']
|
163
|
+
end
|
164
|
+
|
138
165
|
it 'should use body_stream when configured' do
|
139
166
|
stream = StringIO.new('foo')
|
140
167
|
request = HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', body_stream: stream)
|
141
168
|
request.send(:setup_raw_request)
|
142
|
-
request.instance_variable_get(:@raw_request).body_stream.
|
169
|
+
expect(request.instance_variable_get(:@raw_request).body_stream).to eq(stream)
|
143
170
|
end
|
144
171
|
end
|
145
172
|
|
@@ -150,58 +177,66 @@ describe HTTParty::Request do
|
|
150
177
|
@request.path = URI.parse("bar?foo=bar")
|
151
178
|
@request.redirect = true
|
152
179
|
|
153
|
-
@request.uri.
|
180
|
+
expect(@request.uri).to eq(URI.parse("http://example.com/foo/bar?foo=bar"))
|
154
181
|
end
|
155
182
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
183
|
+
context "location header is an absolute path" do
|
184
|
+
it "returns correct path when location has leading slash" do
|
185
|
+
@request.last_uri = URI.parse("http://example.com/foo/bar")
|
186
|
+
@request.path = URI.parse("/bar?foo=bar")
|
187
|
+
@request.redirect = true
|
160
188
|
|
161
|
-
|
162
|
-
|
189
|
+
expect(@request.uri).to eq(URI.parse("http://example.com/bar?foo=bar"))
|
190
|
+
end
|
191
|
+
|
192
|
+
it "returns the correct path when location has no leading slash" do
|
193
|
+
@request.last_uri = URI.parse("http://example.com")
|
194
|
+
@request.path = URI.parse("bar/")
|
195
|
+
@request.redirect = true
|
163
196
|
|
197
|
+
expect(@request.uri).to eq(URI.parse("http://example.com/bar/"))
|
198
|
+
end
|
199
|
+
end
|
164
200
|
it "returns correct path when the server sets the location header to a full uri" do
|
165
201
|
@request.last_uri = URI.parse("http://example.com/foo/bar")
|
166
202
|
@request.path = URI.parse("http://example.com/bar?foo=bar")
|
167
203
|
@request.redirect = true
|
168
204
|
|
169
|
-
@request.uri.
|
205
|
+
expect(@request.uri).to eq(URI.parse("http://example.com/bar?foo=bar"))
|
170
206
|
end
|
171
207
|
end
|
172
208
|
|
173
209
|
context "query strings" do
|
174
210
|
it "does not add an empty query string when default_params are blank" do
|
175
211
|
@request.options[:default_params] = {}
|
176
|
-
@request.uri.query.
|
212
|
+
expect(@request.uri.query).to be_nil
|
177
213
|
end
|
178
214
|
|
179
215
|
it "respects the query string normalization proc" do
|
180
216
|
empty_proc = lambda {|qs| ""}
|
181
217
|
@request.options[:query_string_normalizer] = empty_proc
|
182
218
|
@request.options[:query] = {foo: :bar}
|
183
|
-
|
219
|
+
expect(CGI.unescape(@request.uri.query)).to eq("")
|
184
220
|
end
|
185
221
|
|
186
222
|
it "does not append an ampersand when queries are embedded in paths" do
|
187
223
|
@request.path = "/path?a=1"
|
188
224
|
@request.options[:query] = {}
|
189
|
-
@request.uri.query.
|
225
|
+
expect(@request.uri.query).to eq("a=1")
|
190
226
|
end
|
191
227
|
|
192
228
|
it "does not duplicate query string parameters when uri is called twice" do
|
193
229
|
@request.options[:query] = {foo: :bar}
|
194
230
|
@request.uri
|
195
|
-
@request.uri.query.
|
231
|
+
expect(@request.uri.query).to eq("foo=bar")
|
196
232
|
end
|
197
233
|
|
198
234
|
context "when representing an array" do
|
199
235
|
it "returns a Rails style query string" do
|
200
236
|
@request.options[:query] = {foo: %w(bar baz)}
|
201
|
-
|
237
|
+
expect(CGI.unescape(@request.uri.query)).to eq("foo[]=bar&foo[]=baz")
|
202
238
|
end
|
203
239
|
end
|
204
|
-
|
205
240
|
end
|
206
241
|
end
|
207
242
|
|
@@ -212,7 +247,7 @@ describe HTTParty::Request do
|
|
212
247
|
@request.options[:body] = {page: 1, foo: %w(bar baz)}
|
213
248
|
@request.send(:setup_raw_request)
|
214
249
|
body = @request.instance_variable_get(:@raw_request).body
|
215
|
-
|
250
|
+
expect(CGI.unescape(body)).to eq("foo=bar&foo=baz&page=1")
|
216
251
|
end
|
217
252
|
end
|
218
253
|
end
|
@@ -220,95 +255,95 @@ describe HTTParty::Request do
|
|
220
255
|
describe 'http' do
|
221
256
|
it "should get a connection from the connection_adapter" do
|
222
257
|
http = Net::HTTP.new('google.com')
|
223
|
-
adapter =
|
258
|
+
adapter = double('adapter')
|
224
259
|
request = HTTParty::Request.new(Net::HTTP::Get, 'https://api.foo.com/v1:443', connection_adapter: adapter)
|
225
|
-
adapter.
|
226
|
-
request.send(:http).
|
260
|
+
expect(adapter).to receive(:call).with(request.uri, request.options).and_return(http)
|
261
|
+
expect(request.send(:http)).to be http
|
227
262
|
end
|
228
263
|
end
|
229
264
|
|
230
265
|
describe '#format_from_mimetype' do
|
231
266
|
it 'should handle text/xml' do
|
232
267
|
["text/xml", "text/xml; charset=iso8859-1"].each do |ct|
|
233
|
-
@request.send(:format_from_mimetype, ct).
|
268
|
+
expect(@request.send(:format_from_mimetype, ct)).to eq(:xml)
|
234
269
|
end
|
235
270
|
end
|
236
271
|
|
237
272
|
it 'should handle application/xml' do
|
238
273
|
["application/xml", "application/xml; charset=iso8859-1"].each do |ct|
|
239
|
-
@request.send(:format_from_mimetype, ct).
|
274
|
+
expect(@request.send(:format_from_mimetype, ct)).to eq(:xml)
|
240
275
|
end
|
241
276
|
end
|
242
277
|
|
243
278
|
it 'should handle text/json' do
|
244
279
|
["text/json", "text/json; charset=iso8859-1"].each do |ct|
|
245
|
-
@request.send(:format_from_mimetype, ct).
|
280
|
+
expect(@request.send(:format_from_mimetype, ct)).to eq(:json)
|
246
281
|
end
|
247
282
|
end
|
248
283
|
|
249
284
|
it 'should handle application/json' do
|
250
285
|
["application/json", "application/json; charset=iso8859-1"].each do |ct|
|
251
|
-
@request.send(:format_from_mimetype, ct).
|
286
|
+
expect(@request.send(:format_from_mimetype, ct)).to eq(:json)
|
252
287
|
end
|
253
288
|
end
|
254
289
|
|
255
290
|
it 'should handle text/csv' do
|
256
291
|
["text/csv", "text/csv; charset=iso8859-1"].each do |ct|
|
257
|
-
@request.send(:format_from_mimetype, ct).
|
292
|
+
expect(@request.send(:format_from_mimetype, ct)).to eq(:csv)
|
258
293
|
end
|
259
294
|
end
|
260
295
|
|
261
296
|
it 'should handle application/csv' do
|
262
297
|
["application/csv", "application/csv; charset=iso8859-1"].each do |ct|
|
263
|
-
@request.send(:format_from_mimetype, ct).
|
298
|
+
expect(@request.send(:format_from_mimetype, ct)).to eq(:csv)
|
264
299
|
end
|
265
300
|
end
|
266
301
|
|
267
302
|
it 'should handle text/comma-separated-values' do
|
268
303
|
["text/comma-separated-values", "text/comma-separated-values; charset=iso8859-1"].each do |ct|
|
269
|
-
@request.send(:format_from_mimetype, ct).
|
304
|
+
expect(@request.send(:format_from_mimetype, ct)).to eq(:csv)
|
270
305
|
end
|
271
306
|
end
|
272
307
|
|
273
308
|
it 'should handle text/javascript' do
|
274
309
|
["text/javascript", "text/javascript; charset=iso8859-1"].each do |ct|
|
275
|
-
@request.send(:format_from_mimetype, ct).
|
310
|
+
expect(@request.send(:format_from_mimetype, ct)).to eq(:plain)
|
276
311
|
end
|
277
312
|
end
|
278
313
|
|
279
314
|
it 'should handle application/javascript' do
|
280
315
|
["application/javascript", "application/javascript; charset=iso8859-1"].each do |ct|
|
281
|
-
@request.send(:format_from_mimetype, ct).
|
316
|
+
expect(@request.send(:format_from_mimetype, ct)).to eq(:plain)
|
282
317
|
end
|
283
318
|
end
|
284
319
|
|
285
320
|
it "returns nil for an unrecognized mimetype" do
|
286
|
-
@request.send(:format_from_mimetype, "application/atom+xml").
|
321
|
+
expect(@request.send(:format_from_mimetype, "application/atom+xml")).to be_nil
|
287
322
|
end
|
288
323
|
|
289
324
|
it "returns nil when using a default parser" do
|
290
325
|
@request.options[:parser] = lambda {}
|
291
|
-
@request.send(:format_from_mimetype, "text/json").
|
326
|
+
expect(@request.send(:format_from_mimetype, "text/json")).to be_nil
|
292
327
|
end
|
293
328
|
end
|
294
329
|
|
295
330
|
describe 'parsing responses' do
|
296
331
|
it 'should handle xml automatically' do
|
297
|
-
xml =
|
332
|
+
xml = '<books><book><id>1234</id><name>Foo Bar!</name></book></books>'
|
298
333
|
@request.options[:format] = :xml
|
299
|
-
@request.send(:parse_response, xml).
|
334
|
+
expect(@request.send(:parse_response, xml)).to eq({'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}})
|
300
335
|
end
|
301
336
|
|
302
337
|
it 'should handle csv automatically' do
|
303
|
-
csv=[
|
338
|
+
csv = ['"id","Name"', '"1234","Foo Bar!"'].join("\n")
|
304
339
|
@request.options[:format] = :csv
|
305
|
-
@request.send(:parse_response, csv).
|
340
|
+
expect(@request.send(:parse_response, csv)).to eq([%w(id Name), ["1234", "Foo Bar!"]])
|
306
341
|
end
|
307
342
|
|
308
343
|
it 'should handle json automatically' do
|
309
|
-
json =
|
344
|
+
json = '{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}'
|
310
345
|
@request.options[:format] = :json
|
311
|
-
@request.send(:parse_response, json).
|
346
|
+
expect(@request.send(:parse_response, json)).to eq({'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}})
|
312
347
|
end
|
313
348
|
|
314
349
|
it "should include any HTTP headers in the returned response" do
|
@@ -316,7 +351,7 @@ describe HTTParty::Request do
|
|
316
351
|
response = stub_response "Content"
|
317
352
|
response.initialize_http_header("key" => "value")
|
318
353
|
|
319
|
-
@request.perform.headers.
|
354
|
+
expect(@request.perform.headers).to eq({ "key" => ["value"] })
|
320
355
|
end
|
321
356
|
|
322
357
|
if "".respond_to?(:encoding)
|
@@ -325,21 +360,21 @@ describe HTTParty::Request do
|
|
325
360
|
response = stub_response "Content"
|
326
361
|
response.initialize_http_header("Content-Type" => "text/plain;charset = utf-8")
|
327
362
|
resp = @request.perform
|
328
|
-
resp.body.encoding.
|
363
|
+
expect(resp.body.encoding).to eq(Encoding.find("UTF-8"))
|
329
364
|
end
|
330
365
|
|
331
366
|
it "should process charset in content type properly if it has a different case" do
|
332
367
|
response = stub_response "Content"
|
333
368
|
response.initialize_http_header("Content-Type" => "text/plain;CHARSET = utf-8")
|
334
369
|
resp = @request.perform
|
335
|
-
resp.body.encoding.
|
370
|
+
expect(resp.body.encoding).to eq(Encoding.find("UTF-8"))
|
336
371
|
end
|
337
372
|
|
338
373
|
it "should process quoted charset in content type properly" do
|
339
374
|
response = stub_response "Content"
|
340
375
|
response.initialize_http_header("Content-Type" => "text/plain;charset = \"utf-8\"")
|
341
376
|
resp = @request.perform
|
342
|
-
resp.body.encoding.
|
377
|
+
expect(resp.body.encoding).to eq(Encoding.find("UTF-8"))
|
343
378
|
end
|
344
379
|
|
345
380
|
it "should process utf-16 charset with little endian bom correctly" do
|
@@ -348,7 +383,7 @@ describe HTTParty::Request do
|
|
348
383
|
response = stub_response "\xFF\xFEC\x00o\x00n\x00t\x00e\x00n\x00t\x00"
|
349
384
|
response.initialize_http_header("Content-Type" => "text/plain;charset = utf-16")
|
350
385
|
resp = @request.perform
|
351
|
-
resp.body.encoding.
|
386
|
+
expect(resp.body.encoding).to eq(Encoding.find("UTF-16LE"))
|
352
387
|
end
|
353
388
|
|
354
389
|
it "should process utf-16 charset with big endian bom correctly" do
|
@@ -357,7 +392,7 @@ describe HTTParty::Request do
|
|
357
392
|
response = stub_response "\xFE\xFF\x00C\x00o\x00n\x00t\x00e\x00n\x00t"
|
358
393
|
response.initialize_http_header("Content-Type" => "text/plain;charset = utf-16")
|
359
394
|
resp = @request.perform
|
360
|
-
resp.body.encoding.
|
395
|
+
expect(resp.body.encoding).to eq(Encoding.find("UTF-16BE"))
|
361
396
|
end
|
362
397
|
|
363
398
|
it "should assume utf-16 little endian if options has been chosen" do
|
@@ -366,26 +401,23 @@ describe HTTParty::Request do
|
|
366
401
|
response = stub_response "C\x00o\x00n\x00t\x00e\x00n\x00t\x00"
|
367
402
|
response.initialize_http_header("Content-Type" => "text/plain;charset = utf-16")
|
368
403
|
resp = @request.perform
|
369
|
-
resp.body.encoding.
|
404
|
+
expect(resp.body.encoding).to eq(Encoding.find("UTF-16LE"))
|
370
405
|
end
|
371
406
|
|
372
|
-
|
373
407
|
it "should perform no encoding if the charset is not available" do
|
374
|
-
|
375
408
|
response = stub_response "Content"
|
376
409
|
response.initialize_http_header("Content-Type" => "text/plain;charset = utf-lols")
|
377
410
|
resp = @request.perform
|
378
|
-
resp.body.
|
379
|
-
resp.body.encoding.
|
411
|
+
expect(resp.body).to eq("Content")
|
412
|
+
expect(resp.body.encoding).to eq("Content".encoding)
|
380
413
|
end
|
381
414
|
|
382
415
|
it "should perform no encoding if the content type is specified but no charset is specified" do
|
383
|
-
|
384
416
|
response = stub_response "Content"
|
385
417
|
response.initialize_http_header("Content-Type" => "text/plain")
|
386
418
|
resp = @request.perform
|
387
|
-
resp.body.
|
388
|
-
resp.body.encoding.
|
419
|
+
expect(resp.body).to eq("Content")
|
420
|
+
expect(resp.body.encoding).to eq("Content".encoding)
|
389
421
|
end
|
390
422
|
end
|
391
423
|
|
@@ -394,22 +426,22 @@ describe HTTParty::Request do
|
|
394
426
|
it 'returns a valid object for 304 not modified' do
|
395
427
|
stub_response '', 304
|
396
428
|
resp = @request.perform
|
397
|
-
resp.code.
|
398
|
-
resp.body.
|
399
|
-
resp.
|
429
|
+
expect(resp.code).to eq(304)
|
430
|
+
expect(resp.body).to eq('')
|
431
|
+
expect(resp).to be_nil
|
400
432
|
end
|
401
433
|
|
402
434
|
it "redirects if a 300 contains a location header" do
|
403
435
|
redirect = stub_response '', 300
|
404
436
|
redirect['location'] = 'http://foo.com/foo'
|
405
437
|
ok = stub_response('<hash><foo>bar</foo></hash>', 200)
|
406
|
-
@http.
|
438
|
+
allow(@http).to receive(:request).and_return(redirect, ok)
|
407
439
|
response = @request.perform
|
408
|
-
response.request.base_uri.to_s.
|
409
|
-
response.request.path.to_s.
|
410
|
-
response.request.uri.request_uri.
|
411
|
-
response.request.uri.to_s.
|
412
|
-
response.
|
440
|
+
expect(response.request.base_uri.to_s).to eq("http://foo.com")
|
441
|
+
expect(response.request.path.to_s).to eq("http://foo.com/foo")
|
442
|
+
expect(response.request.uri.request_uri).to eq("/foo")
|
443
|
+
expect(response.request.uri.to_s).to eq("http://foo.com/foo")
|
444
|
+
expect(response.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
413
445
|
end
|
414
446
|
|
415
447
|
it "calls block given to perform with each redirect" do
|
@@ -418,20 +450,20 @@ describe HTTParty::Request do
|
|
418
450
|
FakeWeb.register_uri(:get, "http://api.foo.com/v2", body: "<hash><foo>bar</foo></hash>")
|
419
451
|
body = ""
|
420
452
|
response = @request.perform { |chunk| body += chunk }
|
421
|
-
body.length.
|
453
|
+
expect(body.length).to eq(27)
|
422
454
|
end
|
423
455
|
|
424
456
|
it "redirects if a 300 contains a relative location header" do
|
425
457
|
redirect = stub_response '', 300
|
426
458
|
redirect['location'] = '/foo/bar'
|
427
459
|
ok = stub_response('<hash><foo>bar</foo></hash>', 200)
|
428
|
-
@http.
|
460
|
+
allow(@http).to receive(:request).and_return(redirect, ok)
|
429
461
|
response = @request.perform
|
430
|
-
response.request.base_uri.to_s.
|
431
|
-
response.request.path.to_s.
|
432
|
-
response.request.uri.request_uri.
|
433
|
-
response.request.uri.to_s.
|
434
|
-
response.
|
462
|
+
expect(response.request.base_uri.to_s).to eq("http://api.foo.com")
|
463
|
+
expect(response.request.path.to_s).to eq("/foo/bar")
|
464
|
+
expect(response.request.uri.request_uri).to eq("/foo/bar")
|
465
|
+
expect(response.request.uri.to_s).to eq("http://api.foo.com/foo/bar")
|
466
|
+
expect(response.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
435
467
|
end
|
436
468
|
|
437
469
|
it "handles multiple redirects and relative location headers on different hosts" do
|
@@ -440,43 +472,43 @@ describe HTTParty::Request do
|
|
440
472
|
FakeWeb.register_uri(:get, "http://api.foo.com/v2", status: [300, "REDIRECT"], location: "/v3")
|
441
473
|
FakeWeb.register_uri(:get, "http://api.foo.com/v3", body: "<hash><foo>bar</foo></hash>")
|
442
474
|
response = @request.perform
|
443
|
-
response.request.base_uri.to_s.
|
444
|
-
response.request.path.to_s.
|
445
|
-
response.request.uri.request_uri.
|
446
|
-
response.request.uri.to_s.
|
447
|
-
response.
|
475
|
+
expect(response.request.base_uri.to_s).to eq("http://api.foo.com")
|
476
|
+
expect(response.request.path.to_s).to eq("/v3")
|
477
|
+
expect(response.request.uri.request_uri).to eq("/v3")
|
478
|
+
expect(response.request.uri.to_s).to eq("http://api.foo.com/v3")
|
479
|
+
expect(response.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
448
480
|
end
|
449
481
|
|
450
482
|
it "returns the HTTParty::Response when the 300 does not contain a location header" do
|
451
483
|
stub_response '', 300
|
452
|
-
HTTParty::Response.
|
484
|
+
expect(HTTParty::Response).to be === @request.perform
|
453
485
|
end
|
454
486
|
end
|
455
487
|
|
456
488
|
it 'should return a valid object for 4xx response' do
|
457
489
|
stub_response '<foo><bar>yes</bar></foo>', 401
|
458
490
|
resp = @request.perform
|
459
|
-
resp.code.
|
460
|
-
resp.body.
|
461
|
-
resp['foo']['bar'].
|
491
|
+
expect(resp.code).to eq(401)
|
492
|
+
expect(resp.body).to eq("<foo><bar>yes</bar></foo>")
|
493
|
+
expect(resp['foo']['bar']).to eq("yes")
|
462
494
|
end
|
463
495
|
|
464
496
|
it 'should return a valid object for 5xx response' do
|
465
497
|
stub_response '<foo><bar>error</bar></foo>', 500
|
466
498
|
resp = @request.perform
|
467
|
-
resp.code.
|
468
|
-
resp.body.
|
469
|
-
resp['foo']['bar'].
|
499
|
+
expect(resp.code).to eq(500)
|
500
|
+
expect(resp.body).to eq("<foo><bar>error</bar></foo>")
|
501
|
+
expect(resp['foo']['bar']).to eq("error")
|
470
502
|
end
|
471
503
|
|
472
504
|
it "parses response lazily so codes can be checked prior" do
|
473
505
|
stub_response 'not xml', 500
|
474
506
|
@request.options[:format] = :xml
|
475
|
-
|
507
|
+
expect {
|
476
508
|
response = @request.perform
|
477
|
-
response.code.
|
478
|
-
response.body.
|
479
|
-
}.
|
509
|
+
expect(response.code).to eq(500)
|
510
|
+
expect(response.body).to eq('not xml')
|
511
|
+
}.not_to raise_error
|
480
512
|
end
|
481
513
|
end
|
482
514
|
end
|
@@ -486,14 +518,14 @@ describe HTTParty::Request do
|
|
486
518
|
stub_response "", code
|
487
519
|
|
488
520
|
@request.options[:format] = :xml
|
489
|
-
@request.perform.
|
521
|
+
expect(@request.perform).to be_nil
|
490
522
|
end
|
491
523
|
end
|
492
524
|
|
493
525
|
it "should not fail for missing mime type" do
|
494
526
|
stub_response "Content for you"
|
495
527
|
@request.options[:format] = :html
|
496
|
-
@request.perform.
|
528
|
+
expect(@request.perform.parsed_response).to eq('Content for you')
|
497
529
|
end
|
498
530
|
|
499
531
|
describe "a request that 302 redirects" do
|
@@ -506,100 +538,100 @@ describe HTTParty::Request do
|
|
506
538
|
|
507
539
|
describe "once" do
|
508
540
|
before(:each) do
|
509
|
-
@http.
|
541
|
+
allow(@http).to receive(:request).and_return(@redirect, @ok)
|
510
542
|
end
|
511
543
|
|
512
544
|
it "should be handled by GET transparently" do
|
513
|
-
@request.perform.
|
545
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
514
546
|
end
|
515
547
|
|
516
548
|
it "should be handled by POST transparently" do
|
517
549
|
@request.http_method = Net::HTTP::Post
|
518
|
-
@request.perform.
|
550
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
519
551
|
end
|
520
552
|
|
521
553
|
it "should be handled by DELETE transparently" do
|
522
554
|
@request.http_method = Net::HTTP::Delete
|
523
|
-
@request.perform.
|
555
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
524
556
|
end
|
525
557
|
|
526
558
|
it "should be handled by MOVE transparently" do
|
527
559
|
@request.http_method = Net::HTTP::Move
|
528
|
-
@request.perform.
|
560
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
529
561
|
end
|
530
562
|
|
531
563
|
it "should be handled by COPY transparently" do
|
532
564
|
@request.http_method = Net::HTTP::Copy
|
533
|
-
@request.perform.
|
565
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
534
566
|
end
|
535
567
|
|
536
568
|
it "should be handled by PATCH transparently" do
|
537
569
|
@request.http_method = Net::HTTP::Patch
|
538
|
-
@request.perform.
|
570
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
539
571
|
end
|
540
572
|
|
541
573
|
it "should be handled by PUT transparently" do
|
542
574
|
@request.http_method = Net::HTTP::Put
|
543
|
-
@request.perform.
|
575
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
544
576
|
end
|
545
577
|
|
546
578
|
it "should be handled by HEAD transparently" do
|
547
579
|
@request.http_method = Net::HTTP::Head
|
548
|
-
@request.perform.
|
580
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
549
581
|
end
|
550
582
|
|
551
583
|
it "should be handled by OPTIONS transparently" do
|
552
584
|
@request.http_method = Net::HTTP::Options
|
553
|
-
@request.perform.
|
585
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
554
586
|
end
|
555
587
|
|
556
588
|
it "should keep track of cookies between redirects" do
|
557
589
|
@redirect['Set-Cookie'] = 'foo=bar; name=value; HTTPOnly'
|
558
590
|
@request.perform
|
559
|
-
@request.options[:headers]['Cookie'].
|
560
|
-
@request.options[:headers]['Cookie'].
|
591
|
+
expect(@request.options[:headers]['Cookie']).to match(/foo=bar/)
|
592
|
+
expect(@request.options[:headers]['Cookie']).to match(/name=value/)
|
561
593
|
end
|
562
594
|
|
563
595
|
it 'should update cookies with rediects' do
|
564
|
-
@request.options[:headers] = {'Cookie'=> 'foo=bar;'}
|
596
|
+
@request.options[:headers] = {'Cookie' => 'foo=bar;'}
|
565
597
|
@redirect['Set-Cookie'] = 'foo=tar;'
|
566
598
|
@request.perform
|
567
|
-
@request.options[:headers]['Cookie'].
|
599
|
+
expect(@request.options[:headers]['Cookie']).to match(/foo=tar/)
|
568
600
|
end
|
569
601
|
|
570
602
|
it 'should keep cookies between rediects' do
|
571
|
-
@request.options[:headers] = {'Cookie'=> 'keep=me'}
|
603
|
+
@request.options[:headers] = {'Cookie' => 'keep=me'}
|
572
604
|
@redirect['Set-Cookie'] = 'foo=tar;'
|
573
605
|
@request.perform
|
574
|
-
@request.options[:headers]['Cookie'].
|
606
|
+
expect(@request.options[:headers]['Cookie']).to match(/keep=me/)
|
575
607
|
end
|
576
608
|
|
577
609
|
it "should handle multiple Set-Cookie headers between redirects" do
|
578
610
|
@redirect.add_field 'set-cookie', 'foo=bar; name=value; HTTPOnly'
|
579
611
|
@redirect.add_field 'set-cookie', 'one=1; two=2; HTTPOnly'
|
580
612
|
@request.perform
|
581
|
-
@request.options[:headers]['Cookie'].
|
582
|
-
@request.options[:headers]['Cookie'].
|
583
|
-
@request.options[:headers]['Cookie'].
|
584
|
-
@request.options[:headers]['Cookie'].
|
613
|
+
expect(@request.options[:headers]['Cookie']).to match(/foo=bar/)
|
614
|
+
expect(@request.options[:headers]['Cookie']).to match(/name=value/)
|
615
|
+
expect(@request.options[:headers]['Cookie']).to match(/one=1/)
|
616
|
+
expect(@request.options[:headers]['Cookie']).to match(/two=2/)
|
585
617
|
end
|
586
618
|
|
587
619
|
it 'should make resulting request a get request if it not already' do
|
588
620
|
@request.http_method = Net::HTTP::Delete
|
589
|
-
@request.perform.
|
590
|
-
@request.http_method.
|
621
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
622
|
+
expect(@request.http_method).to eq(Net::HTTP::Get)
|
591
623
|
end
|
592
624
|
|
593
625
|
it 'should not make resulting request a get request if options[:maintain_method_across_redirects] is true' do
|
594
626
|
@request.options[:maintain_method_across_redirects] = true
|
595
627
|
@request.http_method = Net::HTTP::Delete
|
596
|
-
@request.perform.
|
597
|
-
@request.http_method.
|
628
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
629
|
+
expect(@request.http_method).to eq(Net::HTTP::Delete)
|
598
630
|
end
|
599
631
|
|
600
632
|
it 'should log the redirection' do
|
601
633
|
logger_double = double
|
602
|
-
logger_double.
|
634
|
+
expect(logger_double).to receive(:info).twice
|
603
635
|
@request.options[:logger] = logger_double
|
604
636
|
@request.perform
|
605
637
|
end
|
@@ -607,11 +639,11 @@ describe HTTParty::Request do
|
|
607
639
|
|
608
640
|
describe "infinitely" do
|
609
641
|
before(:each) do
|
610
|
-
@http.
|
642
|
+
allow(@http).to receive(:request).and_return(@redirect)
|
611
643
|
end
|
612
644
|
|
613
645
|
it "should raise an exception" do
|
614
|
-
|
646
|
+
expect { @request.perform }.to raise_error(HTTParty::RedirectionTooDeep)
|
615
647
|
end
|
616
648
|
end
|
617
649
|
end
|
@@ -626,116 +658,116 @@ describe HTTParty::Request do
|
|
626
658
|
|
627
659
|
describe "once" do
|
628
660
|
before(:each) do
|
629
|
-
@http.
|
661
|
+
allow(@http).to receive(:request).and_return(@redirect, @ok)
|
630
662
|
end
|
631
663
|
|
632
664
|
it "should be handled by GET transparently" do
|
633
|
-
@request.perform.
|
665
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
634
666
|
end
|
635
667
|
|
636
668
|
it "should be handled by POST transparently" do
|
637
669
|
@request.http_method = Net::HTTP::Post
|
638
|
-
@request.perform.
|
670
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
639
671
|
end
|
640
672
|
|
641
673
|
it "should be handled by DELETE transparently" do
|
642
674
|
@request.http_method = Net::HTTP::Delete
|
643
|
-
@request.perform.
|
675
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
644
676
|
end
|
645
677
|
|
646
678
|
it "should be handled by MOVE transparently" do
|
647
679
|
@request.http_method = Net::HTTP::Move
|
648
|
-
@request.perform.
|
680
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
649
681
|
end
|
650
682
|
|
651
683
|
it "should be handled by COPY transparently" do
|
652
684
|
@request.http_method = Net::HTTP::Copy
|
653
|
-
@request.perform.
|
685
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
654
686
|
end
|
655
687
|
|
656
688
|
it "should be handled by PATCH transparently" do
|
657
689
|
@request.http_method = Net::HTTP::Patch
|
658
|
-
@request.perform.
|
690
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
659
691
|
end
|
660
692
|
|
661
693
|
it "should be handled by PUT transparently" do
|
662
694
|
@request.http_method = Net::HTTP::Put
|
663
|
-
@request.perform.
|
695
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
664
696
|
end
|
665
697
|
|
666
698
|
it "should be handled by HEAD transparently" do
|
667
699
|
@request.http_method = Net::HTTP::Head
|
668
|
-
@request.perform.
|
700
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
669
701
|
end
|
670
702
|
|
671
703
|
it "should be handled by OPTIONS transparently" do
|
672
704
|
@request.http_method = Net::HTTP::Options
|
673
|
-
@request.perform.
|
705
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
674
706
|
end
|
675
707
|
|
676
708
|
it "should keep track of cookies between redirects" do
|
677
709
|
@redirect['Set-Cookie'] = 'foo=bar; name=value; HTTPOnly'
|
678
710
|
@request.perform
|
679
|
-
@request.options[:headers]['Cookie'].
|
680
|
-
@request.options[:headers]['Cookie'].
|
711
|
+
expect(@request.options[:headers]['Cookie']).to match(/foo=bar/)
|
712
|
+
expect(@request.options[:headers]['Cookie']).to match(/name=value/)
|
681
713
|
end
|
682
714
|
|
683
715
|
it 'should update cookies with rediects' do
|
684
|
-
@request.options[:headers] = {'Cookie'=> 'foo=bar;'}
|
716
|
+
@request.options[:headers] = {'Cookie' => 'foo=bar;'}
|
685
717
|
@redirect['Set-Cookie'] = 'foo=tar;'
|
686
718
|
@request.perform
|
687
|
-
@request.options[:headers]['Cookie'].
|
719
|
+
expect(@request.options[:headers]['Cookie']).to match(/foo=tar/)
|
688
720
|
end
|
689
721
|
|
690
722
|
it 'should keep cookies between rediects' do
|
691
|
-
@request.options[:headers] = {'Cookie'=> 'keep=me'}
|
723
|
+
@request.options[:headers] = {'Cookie' => 'keep=me'}
|
692
724
|
@redirect['Set-Cookie'] = 'foo=tar;'
|
693
725
|
@request.perform
|
694
|
-
@request.options[:headers]['Cookie'].
|
726
|
+
expect(@request.options[:headers]['Cookie']).to match(/keep=me/)
|
695
727
|
end
|
696
728
|
|
697
729
|
it "should handle multiple Set-Cookie headers between redirects" do
|
698
730
|
@redirect.add_field 'set-cookie', 'foo=bar; name=value; HTTPOnly'
|
699
731
|
@redirect.add_field 'set-cookie', 'one=1; two=2; HTTPOnly'
|
700
732
|
@request.perform
|
701
|
-
@request.options[:headers]['Cookie'].
|
702
|
-
@request.options[:headers]['Cookie'].
|
703
|
-
@request.options[:headers]['Cookie'].
|
704
|
-
@request.options[:headers]['Cookie'].
|
733
|
+
expect(@request.options[:headers]['Cookie']).to match(/foo=bar/)
|
734
|
+
expect(@request.options[:headers]['Cookie']).to match(/name=value/)
|
735
|
+
expect(@request.options[:headers]['Cookie']).to match(/one=1/)
|
736
|
+
expect(@request.options[:headers]['Cookie']).to match(/two=2/)
|
705
737
|
end
|
706
738
|
|
707
739
|
it 'should make resulting request a get request if it not already' do
|
708
740
|
@request.http_method = Net::HTTP::Delete
|
709
|
-
@request.perform.
|
710
|
-
@request.http_method.
|
741
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
742
|
+
expect(@request.http_method).to eq(Net::HTTP::Get)
|
711
743
|
end
|
712
744
|
|
713
745
|
it 'should make resulting request a get request if options[:maintain_method_across_redirects] is false' do
|
714
746
|
@request.options[:maintain_method_across_redirects] = false
|
715
747
|
@request.http_method = Net::HTTP::Delete
|
716
|
-
@request.perform.
|
717
|
-
@request.http_method.
|
748
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
749
|
+
expect(@request.http_method).to eq(Net::HTTP::Get)
|
718
750
|
end
|
719
751
|
|
720
752
|
it 'should make resulting request a get request if options[:maintain_method_across_redirects] is true but options[:resend_on_redirect] is false' do
|
721
753
|
@request.options[:maintain_method_across_redirects] = true
|
722
754
|
@request.options[:resend_on_redirect] = false
|
723
755
|
@request.http_method = Net::HTTP::Delete
|
724
|
-
@request.perform.
|
725
|
-
@request.http_method.
|
756
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
757
|
+
expect(@request.http_method).to eq(Net::HTTP::Get)
|
726
758
|
end
|
727
759
|
|
728
760
|
it 'should not make resulting request a get request if options[:maintain_method_across_redirects] and options[:resend_on_redirect] is true' do
|
729
761
|
@request.options[:maintain_method_across_redirects] = true
|
730
762
|
@request.options[:resend_on_redirect] = true
|
731
763
|
@request.http_method = Net::HTTP::Delete
|
732
|
-
@request.perform.
|
733
|
-
@request.http_method.
|
764
|
+
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
|
765
|
+
expect(@request.http_method).to eq(Net::HTTP::Delete)
|
734
766
|
end
|
735
767
|
|
736
768
|
it 'should log the redirection' do
|
737
769
|
logger_double = double
|
738
|
-
logger_double.
|
770
|
+
expect(logger_double).to receive(:info).twice
|
739
771
|
@request.options[:logger] = logger_double
|
740
772
|
@request.perform
|
741
773
|
end
|
@@ -743,11 +775,11 @@ describe HTTParty::Request do
|
|
743
775
|
|
744
776
|
describe "infinitely" do
|
745
777
|
before(:each) do
|
746
|
-
@http.
|
778
|
+
allow(@http).to receive(:request).and_return(@redirect)
|
747
779
|
end
|
748
780
|
|
749
781
|
it "should raise an exception" do
|
750
|
-
|
782
|
+
expect { @request.perform }.to raise_error(HTTParty::RedirectionTooDeep)
|
751
783
|
end
|
752
784
|
end
|
753
785
|
end
|
@@ -756,31 +788,31 @@ describe HTTParty::Request do
|
|
756
788
|
context "context-encoding" do
|
757
789
|
before do
|
758
790
|
@request.options[:format] = :html
|
759
|
-
@last_response =
|
760
|
-
@last_response.
|
791
|
+
@last_response = double
|
792
|
+
allow(@last_response).to receive(:body).and_return('')
|
761
793
|
end
|
762
794
|
|
763
795
|
it "should inflate the gzipped body with content-encoding: gzip" do
|
764
|
-
@last_response.
|
765
|
-
@request.
|
766
|
-
Zlib::GzipReader.
|
767
|
-
@request.last_response.
|
796
|
+
allow(@last_response).to receive(:[]).with("content-encoding").and_return("gzip")
|
797
|
+
allow(@request).to receive(:last_response).and_return(@last_response)
|
798
|
+
expect(Zlib::GzipReader).to receive(:new).and_return(StringIO.new(''))
|
799
|
+
expect(@request.last_response).to receive(:delete).with('content-encoding')
|
768
800
|
@request.send(:handle_deflation)
|
769
801
|
end
|
770
802
|
|
771
803
|
it "should inflate the gzipped body with content-encoding: x-gzip" do
|
772
|
-
@last_response.
|
773
|
-
@request.
|
774
|
-
Zlib::GzipReader.
|
775
|
-
@request.last_response.
|
804
|
+
allow(@last_response).to receive(:[]).with("content-encoding").and_return("x-gzip")
|
805
|
+
allow(@request).to receive(:last_response).and_return(@last_response)
|
806
|
+
expect(Zlib::GzipReader).to receive(:new).and_return(StringIO.new(''))
|
807
|
+
expect(@request.last_response).to receive(:delete).with('content-encoding')
|
776
808
|
@request.send(:handle_deflation)
|
777
809
|
end
|
778
810
|
|
779
811
|
it "should inflate the deflated body" do
|
780
|
-
@last_response.
|
781
|
-
@request.
|
782
|
-
Zlib::Inflate.
|
783
|
-
@request.last_response.
|
812
|
+
allow(@last_response).to receive(:[]).with("content-encoding").and_return("deflate")
|
813
|
+
allow(@request).to receive(:last_response).and_return(@last_response)
|
814
|
+
expect(Zlib::Inflate).to receive(:inflate).and_return('')
|
815
|
+
expect(@request.last_response).to receive(:delete).with('content-encoding')
|
784
816
|
@request.send(:handle_deflation)
|
785
817
|
end
|
786
818
|
end
|
@@ -788,29 +820,53 @@ describe HTTParty::Request do
|
|
788
820
|
|
789
821
|
context "with POST http method" do
|
790
822
|
it "should raise argument error if query is not a hash" do
|
791
|
-
|
823
|
+
expect {
|
792
824
|
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', format: :xml, query: 'astring').perform
|
793
|
-
}.
|
825
|
+
}.to raise_error(ArgumentError)
|
794
826
|
end
|
795
827
|
end
|
796
828
|
|
797
829
|
describe "argument validation" do
|
798
830
|
it "should raise argument error if basic_auth and digest_auth are both present" do
|
799
|
-
|
831
|
+
expect {
|
800
832
|
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', basic_auth: {}, digest_auth: {}).perform
|
801
|
-
}.
|
833
|
+
}.to raise_error(ArgumentError, "only one authentication method, :basic_auth or :digest_auth may be used at a time")
|
802
834
|
end
|
803
835
|
|
804
836
|
it "should raise argument error if basic_auth is not a hash" do
|
805
|
-
|
806
|
-
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', basic_auth:
|
807
|
-
}.
|
837
|
+
expect {
|
838
|
+
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', basic_auth: %w(foo bar)).perform
|
839
|
+
}.to raise_error(ArgumentError, ":basic_auth must be a hash")
|
808
840
|
end
|
809
841
|
|
810
842
|
it "should raise argument error if digest_auth is not a hash" do
|
811
|
-
|
812
|
-
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', digest_auth:
|
813
|
-
}.
|
843
|
+
expect {
|
844
|
+
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', digest_auth: %w(foo bar)).perform
|
845
|
+
}.to raise_error(ArgumentError, ":digest_auth must be a hash")
|
846
|
+
end
|
847
|
+
|
848
|
+
it "should raise argument error if headers is not a hash" do
|
849
|
+
expect {
|
850
|
+
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', headers: %w(foo bar)).perform
|
851
|
+
}.to raise_error(ArgumentError, ":headers must be a hash")
|
852
|
+
end
|
853
|
+
|
854
|
+
it "should raise argument error if options method is not http accepted method" do
|
855
|
+
expect {
|
856
|
+
HTTParty::Request.new('SuperPost', 'http://api.foo.com/v1').perform
|
857
|
+
}.to raise_error(ArgumentError, "only get, post, patch, put, delete, head, and options methods are supported")
|
858
|
+
end
|
859
|
+
|
860
|
+
it "should raise argument error if http method is post and query is not hash" do
|
861
|
+
expect {
|
862
|
+
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', query: "message: hello").perform
|
863
|
+
}.to raise_error(ArgumentError, ":query must be hash if using HTTP Post")
|
864
|
+
end
|
865
|
+
|
866
|
+
it "should raise RedirectionTooDeep error if limit is negative" do
|
867
|
+
expect {
|
868
|
+
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', limit: -1).perform
|
869
|
+
}.to raise_error(HTTParty::RedirectionTooDeep, 'HTTP redirects too deep')
|
814
870
|
end
|
815
871
|
end
|
816
872
|
end
|