rest-client 1.8.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.mailmap +10 -0
  4. data/.rspec +2 -1
  5. data/.rubocop +2 -0
  6. data/.rubocop-disables.yml +386 -0
  7. data/.rubocop.yml +8 -0
  8. data/.travis.yml +56 -8
  9. data/AUTHORS +26 -1
  10. data/README.md +901 -0
  11. data/Rakefile +27 -3
  12. data/bin/restclient +3 -5
  13. data/history.md +181 -0
  14. data/lib/restclient/abstract_response.rb +172 -55
  15. data/lib/restclient/exceptions.rb +96 -55
  16. data/lib/restclient/params_array.rb +72 -0
  17. data/lib/restclient/payload.rb +70 -74
  18. data/lib/restclient/platform.rb +19 -0
  19. data/lib/restclient/raw_response.rb +21 -7
  20. data/lib/restclient/request.rb +540 -281
  21. data/lib/restclient/resource.rb +19 -9
  22. data/lib/restclient/response.rb +75 -6
  23. data/lib/restclient/utils.rb +274 -0
  24. data/lib/restclient/version.rb +2 -1
  25. data/lib/restclient.rb +21 -3
  26. data/rest-client.gemspec +12 -10
  27. data/spec/ISS.jpg +0 -0
  28. data/spec/helpers.rb +54 -0
  29. data/spec/integration/_lib.rb +1 -0
  30. data/spec/integration/capath_digicert/3513523f.0 +22 -0
  31. data/spec/integration/capath_digicert/399e7759.0 +22 -0
  32. data/spec/integration/capath_digicert/digicert.crt +20 -17
  33. data/spec/integration/certs/digicert.crt +20 -17
  34. data/spec/integration/httpbin_spec.rb +128 -0
  35. data/spec/integration/integration_spec.rb +97 -14
  36. data/spec/integration/request_spec.rb +25 -2
  37. data/spec/spec_helper.rb +28 -1
  38. data/spec/unit/_lib.rb +1 -0
  39. data/spec/unit/abstract_response_spec.rb +95 -38
  40. data/spec/unit/exceptions_spec.rb +41 -28
  41. data/spec/unit/params_array_spec.rb +36 -0
  42. data/spec/unit/payload_spec.rb +118 -68
  43. data/spec/unit/raw_response_spec.rb +10 -6
  44. data/spec/unit/request2_spec.rb +34 -12
  45. data/spec/unit/request_spec.rb +745 -424
  46. data/spec/unit/resource_spec.rb +31 -27
  47. data/spec/unit/response_spec.rb +134 -57
  48. data/spec/unit/restclient_spec.rb +16 -15
  49. data/spec/unit/utils_spec.rb +147 -0
  50. data/spec/unit/windows/root_certs_spec.rb +3 -3
  51. metadata +79 -29
  52. data/README.rdoc +0 -324
  53. data/spec/integration/capath_digicert/244b5494.0 +0 -19
  54. data/spec/integration/capath_digicert/81b9768f.0 +0 -19
  55. data/spec/unit/master_shake.jpg +0 -0
@@ -1,120 +1,206 @@
1
- require 'spec_helper'
1
+ require_relative './_lib'
2
2
 
3
- describe RestClient::Request do
3
+ describe RestClient::Request, :include_helpers do
4
4
  before do
5
5
  @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
6
6
 
7
7
  @uri = double("uri")
8
- @uri.stub(:request_uri).and_return('/resource')
9
- @uri.stub(:host).and_return('some')
10
- @uri.stub(:port).and_return(80)
8
+ allow(@uri).to receive(:request_uri).and_return('/resource')
9
+ allow(@uri).to receive(:hostname).and_return('some')
10
+ allow(@uri).to receive(:port).and_return(80)
11
11
 
12
12
  @net = double("net::http base")
13
13
  @http = double("net::http connection")
14
- Net::HTTP.stub(:new).and_return(@net)
15
- @net.stub(:start).and_yield(@http)
16
- @net.stub(:use_ssl=)
17
- @net.stub(:verify_mode=)
18
- @net.stub(:verify_callback=)
14
+
15
+ allow(Net::HTTP).to receive(:new).and_return(@net)
16
+
17
+ allow(@net).to receive(:start).and_yield(@http)
18
+ allow(@net).to receive(:use_ssl=)
19
+ allow(@net).to receive(:verify_mode=)
20
+ allow(@net).to receive(:verify_callback=)
19
21
  allow(@net).to receive(:ciphers=)
20
22
  allow(@net).to receive(:cert_store=)
21
23
  RestClient.log = nil
22
24
  end
23
25
 
24
- it "accept */* mimetype, preferring xml" do
25
- @request.default_headers[:accept].should eq '*/*; q=0.5, application/xml'
26
+ it "accept */* mimetype" do
27
+ expect(@request.default_headers[:accept]).to eq '*/*'
26
28
  end
27
29
 
28
- describe "compression" do
30
+ it "processes a successful result" do
31
+ res = res_double
32
+ allow(res).to receive(:code).and_return("200")
33
+ allow(res).to receive(:body).and_return('body')
34
+ allow(res).to receive(:[]).with('content-encoding').and_return(nil)
35
+ expect(@request.send(:process_result, res, Time.now).body).to eq 'body'
36
+ expect(@request.send(:process_result, res, Time.now).to_s).to eq 'body'
37
+ end
29
38
 
30
- it "decodes an uncompressed result body by passing it straight through" do
31
- RestClient::Request.decode(nil, 'xyz').should eq 'xyz'
39
+ it "doesn't classify successful requests as failed" do
40
+ 203.upto(207) do |code|
41
+ res = res_double
42
+ allow(res).to receive(:code).and_return(code.to_s)
43
+ allow(res).to receive(:body).and_return("")
44
+ allow(res).to receive(:[]).with('content-encoding').and_return(nil)
45
+ expect(@request.send(:process_result, res, Time.now)).to be_empty
32
46
  end
47
+ end
33
48
 
34
- it "doesn't fail for nil bodies" do
35
- RestClient::Request.decode('gzip', nil).should be_nil
49
+ describe '.normalize_url' do
50
+ it "adds http:// to the front of resources specified in the syntax example.com/resource" do
51
+ expect(@request.normalize_url('example.com/resource')).to eq 'http://example.com/resource'
36
52
  end
37
53
 
38
-
39
- it "decodes a gzip body" do
40
- RestClient::Request.decode('gzip', "\037\213\b\b\006'\252H\000\003t\000\313T\317UH\257\312,HM\341\002\000G\242(\r\v\000\000\000").should eq "i'm gziped\n"
54
+ it 'adds http:// to resources containing a colon' do
55
+ expect(@request.normalize_url('example.com:1234')).to eq 'http://example.com:1234'
41
56
  end
42
57
 
43
- it "ingores gzip for empty bodies" do
44
- RestClient::Request.decode('gzip', '').should be_empty
58
+ it 'does not add http:// to the front of https resources' do
59
+ expect(@request.normalize_url('https://example.com/resource')).to eq 'https://example.com/resource'
45
60
  end
46
61
 
47
- it "decodes a deflated body" do
48
- RestClient::Request.decode('deflate', "x\234+\316\317MUHIM\313I,IMQ(I\255(\001\000A\223\006\363").should eq "some deflated text"
62
+ it 'does not add http:// to the front of capital HTTP resources' do
63
+ expect(@request.normalize_url('HTTP://example.com/resource')).to eq 'HTTP://example.com/resource'
49
64
  end
50
- end
51
65
 
52
- it "processes a successful result" do
53
- res = double("result")
54
- res.stub(:code).and_return("200")
55
- res.stub(:body).and_return('body')
56
- res.stub(:[]).with('content-encoding').and_return(nil)
57
- @request.process_result(res).body.should eq 'body'
58
- @request.process_result(res).to_s.should eq 'body'
59
- end
60
-
61
- it "doesn't classify successful requests as failed" do
62
- 203.upto(207) do |code|
63
- res = double("result")
64
- res.stub(:code).and_return(code.to_s)
65
- res.stub(:body).and_return("")
66
- res.stub(:[]).with('content-encoding').and_return(nil)
67
- @request.process_result(res).should be_empty
66
+ it 'does not add http:// to the front of capital HTTPS resources' do
67
+ expect(@request.normalize_url('HTTPS://example.com/resource')).to eq 'HTTPS://example.com/resource'
68
68
  end
69
- end
70
-
71
- it "parses a url into a URI object" do
72
- URI.should_receive(:parse).with('http://example.com/resource')
73
- @request.parse_url('http://example.com/resource')
74
- end
75
69
 
76
- it "adds http:// to the front of resources specified in the syntax example.com/resource" do
77
- URI.should_receive(:parse).with('http://example.com/resource')
78
- @request.parse_url('example.com/resource')
70
+ it 'raises with invalid URI' do
71
+ expect {
72
+ RestClient::Request.new(method: :get, url: 'http://a@b:c')
73
+ }.to raise_error(URI::InvalidURIError)
74
+ expect {
75
+ RestClient::Request.new(method: :get, url: 'http://::')
76
+ }.to raise_error(URI::InvalidURIError)
77
+ end
79
78
  end
80
79
 
81
80
  describe "user - password" do
82
81
  it "extracts the username and password when parsing http://user:password@example.com/" do
83
- URI.stub(:parse).and_return(double('uri', :user => 'joe', :password => 'pass1'))
84
- @request.parse_url_with_auth('http://joe:pass1@example.com/resource')
85
- @request.user.should eq 'joe'
86
- @request.password.should eq 'pass1'
82
+ @request.send(:parse_url_with_auth!, 'http://joe:pass1@example.com/resource')
83
+ expect(@request.user).to eq 'joe'
84
+ expect(@request.password).to eq 'pass1'
87
85
  end
88
86
 
89
87
  it "extracts with escaping the username and password when parsing http://user:password@example.com/" do
90
- URI.stub(:parse).and_return(double('uri', :user => 'joe%20', :password => 'pass1'))
91
- @request.parse_url_with_auth('http://joe%20:pass1@example.com/resource')
92
- @request.user.should eq 'joe '
93
- @request.password.should eq 'pass1'
88
+ @request.send(:parse_url_with_auth!, 'http://joe%20:pass1@example.com/resource')
89
+ expect(@request.user).to eq 'joe '
90
+ expect(@request.password).to eq 'pass1'
94
91
  end
95
92
 
96
93
  it "doesn't overwrite user and password (which may have already been set by the Resource constructor) if there is no user/password in the url" do
97
- URI.stub(:parse).and_return(double('uri', :user => nil, :password => nil))
98
- @request = RestClient::Request.new(:method => 'get', :url => 'example.com', :user => 'beth', :password => 'pass2')
99
- @request.parse_url_with_auth('http://example.com/resource')
100
- @request.user.should eq 'beth'
101
- @request.password.should eq 'pass2'
94
+ request = RestClient::Request.new(method: :get, url: 'http://example.com/resource', user: 'beth', password: 'pass2')
95
+ expect(request.user).to eq 'beth'
96
+ expect(request.password).to eq 'pass2'
97
+ end
98
+
99
+ it 'uses the username and password from the URL' do
100
+ request = RestClient::Request.new(method: :get, url: 'http://person:secret@example.com/resource')
101
+ expect(request.user).to eq 'person'
102
+ expect(request.password).to eq 'secret'
103
+ end
104
+
105
+ it 'overrides URL user/pass with explicit options' do
106
+ request = RestClient::Request.new(method: :get, url: 'http://person:secret@example.com/resource', user: 'beth', password: 'pass2')
107
+ expect(request.user).to eq 'beth'
108
+ expect(request.password).to eq 'pass2'
102
109
  end
103
110
  end
104
111
 
105
112
  it "correctly formats cookies provided to the constructor" do
106
- URI.stub(:parse).and_return(double('uri', :user => nil, :password => nil))
107
- @request = RestClient::Request.new(:method => 'get', :url => 'example.com', :cookies => {:session_id => '1', :user_id => "someone" })
108
- @request.should_receive(:default_headers).and_return({'Foo' => 'bar'})
109
- @request.make_headers({}).should eq({ 'Foo' => 'bar', 'Cookie' => 'session_id=1; user_id=someone'})
113
+ cookies_arr = [
114
+ HTTP::Cookie.new('session_id', '1', domain: 'example.com', path: '/'),
115
+ HTTP::Cookie.new('user_id', 'someone', domain: 'example.com', path: '/'),
116
+ ]
117
+
118
+ jar = HTTP::CookieJar.new
119
+ cookies_arr.each {|c| jar << c }
120
+
121
+ # test Hash, HTTP::CookieJar, and Array<HTTP::Cookie> modes
122
+ [
123
+ {session_id: '1', user_id: 'someone'},
124
+ jar,
125
+ cookies_arr
126
+ ].each do |cookies|
127
+ [true, false].each do |in_headers|
128
+ if in_headers
129
+ opts = {headers: {cookies: cookies}}
130
+ else
131
+ opts = {cookies: cookies}
132
+ end
133
+
134
+ request = RestClient::Request.new(method: :get, url: 'example.com', **opts)
135
+ expect(request).to receive(:default_headers).and_return({'Foo' => 'bar'})
136
+ expect(request.make_headers({})).to eq({'Foo' => 'bar', 'Cookie' => 'session_id=1; user_id=someone'})
137
+ expect(request.make_cookie_header).to eq 'session_id=1; user_id=someone'
138
+ expect(request.cookies).to eq({'session_id' => '1', 'user_id' => 'someone'})
139
+ expect(request.cookie_jar.cookies.length).to eq 2
140
+ expect(request.cookie_jar.object_id).not_to eq jar.object_id # make sure we dup it
141
+ end
142
+ end
143
+
144
+ # test with no cookies
145
+ request = RestClient::Request.new(method: :get, url: 'example.com')
146
+ expect(request).to receive(:default_headers).and_return({'Foo' => 'bar'})
147
+ expect(request.make_headers({})).to eq({'Foo' => 'bar'})
148
+ expect(request.make_cookie_header).to be_nil
149
+ expect(request.cookies).to eq({})
150
+ expect(request.cookie_jar.cookies.length).to eq 0
151
+ end
152
+
153
+ it 'strips out cookies set for a different domain name' do
154
+ jar = HTTP::CookieJar.new
155
+ jar << HTTP::Cookie.new('session_id', '1', domain: 'other.example.com', path: '/')
156
+ jar << HTTP::Cookie.new('user_id', 'someone', domain: 'other.example.com', path: '/')
157
+
158
+ request = RestClient::Request.new(method: :get, url: 'www.example.com', cookies: jar)
159
+ expect(request).to receive(:default_headers).and_return({'Foo' => 'bar'})
160
+ expect(request.make_headers({})).to eq({'Foo' => 'bar'})
161
+ expect(request.make_cookie_header).to eq nil
162
+ expect(request.cookies).to eq({})
163
+ expect(request.cookie_jar.cookies.length).to eq 2
164
+ end
165
+
166
+ it 'assumes default domain and path for cookies set by hash' do
167
+ request = RestClient::Request.new(method: :get, url: 'www.example.com', cookies: {'session_id' => '1'})
168
+ expect(request.cookie_jar.cookies.length).to eq 1
169
+
170
+ cookie = request.cookie_jar.cookies.first
171
+ expect(cookie).to be_a(HTTP::Cookie)
172
+ expect(cookie.domain).to eq('www.example.com')
173
+ expect(cookie.for_domain?).to be_truthy
174
+ expect(cookie.path).to eq('/')
175
+ end
176
+
177
+ it 'rejects or warns with contradictory cookie options' do
178
+ # same opt in two different places
179
+ expect {
180
+ RestClient::Request.new(method: :get, url: 'example.com',
181
+ cookies: {bar: '456'},
182
+ headers: {cookies: {foo: '123'}})
183
+ }.to raise_error(ArgumentError, /Cannot pass :cookies in Request.*headers/)
184
+
185
+ # :cookies opt and Cookie header
186
+ [
187
+ {cookies: {foo: '123'}, headers: {cookie: 'foo'}},
188
+ {cookies: {foo: '123'}, headers: {'Cookie' => 'foo'}},
189
+ {headers: {cookies: {foo: '123'}, cookie: 'foo'}},
190
+ {headers: {cookies: {foo: '123'}, 'Cookie' => 'foo'}},
191
+ ].each do |opts|
192
+ expect(fake_stderr {
193
+ RestClient::Request.new(method: :get, url: 'example.com', **opts)
194
+ }).to match(/warning: overriding "Cookie" header with :cookies option/)
195
+ end
110
196
  end
111
197
 
112
198
  it "does not escape or unescape cookies" do
113
199
  cookie = 'Foo%20:Bar%0A~'
114
200
  @request = RestClient::Request.new(:method => 'get', :url => 'example.com',
115
201
  :cookies => {:test => cookie})
116
- @request.should_receive(:default_headers).and_return({'Foo' => 'bar'})
117
- @request.make_headers({}).should eq({
202
+ expect(@request).to receive(:default_headers).and_return({'Foo' => 'bar'})
203
+ expect(@request.make_headers({})).to eq({
118
204
  'Foo' => 'bar',
119
205
  'Cookie' => "test=#{cookie}"
120
206
  })
@@ -124,244 +210,409 @@ describe RestClient::Request do
124
210
  # Cookie validity is something of a mess, but we should reject the worst of
125
211
  # the RFC 6265 (4.1.1) prohibited characters such as control characters.
126
212
 
127
- ['', 'foo=bar', 'foo;bar', "foo\nbar"].each do |cookie_name|
128
- lambda {
213
+ ['foo=bar', 'foo;bar', "foo\nbar"].each do |cookie_name|
214
+ expect {
129
215
  RestClient::Request.new(:method => 'get', :url => 'example.com',
130
216
  :cookies => {cookie_name => 'value'})
131
- }.should raise_error(ArgumentError, /\AInvalid cookie name/)
217
+ }.to raise_error(ArgumentError, /\AInvalid cookie name/i)
132
218
  end
219
+
220
+ cookie_name = ''
221
+ expect {
222
+ RestClient::Request.new(:method => 'get', :url => 'example.com',
223
+ :cookies => {cookie_name => 'value'})
224
+ }.to raise_error(ArgumentError, /cookie name cannot be empty/i)
133
225
  end
134
226
 
135
227
  it "rejects cookie values containing invalid characters" do
136
228
  # Cookie validity is something of a mess, but we should reject the worst of
137
229
  # the RFC 6265 (4.1.1) prohibited characters such as control characters.
138
230
 
139
- ['foo,bar', 'foo;bar', "foo\nbar"].each do |cookie_value|
140
- lambda {
231
+ ["foo\tbar", "foo\nbar"].each do |cookie_value|
232
+ expect {
141
233
  RestClient::Request.new(:method => 'get', :url => 'example.com',
142
234
  :cookies => {'test' => cookie_value})
143
- }.should raise_error(ArgumentError, /\AInvalid cookie value/)
235
+ }.to raise_error(ArgumentError, /\AInvalid cookie value/i)
144
236
  end
145
237
  end
146
238
 
239
+ it 'warns when overriding existing headers via payload' do
240
+ expect(fake_stderr {
241
+ RestClient::Request.new(method: :post, url: 'example.com',
242
+ payload: {'foo' => 1}, headers: {content_type: :json})
243
+ }).to match(/warning: Overriding "Content-Type" header/i)
244
+ expect(fake_stderr {
245
+ RestClient::Request.new(method: :post, url: 'example.com',
246
+ payload: {'foo' => 1}, headers: {'Content-Type' => 'application/json'})
247
+ }).to match(/warning: Overriding "Content-Type" header/i)
248
+
249
+ expect(fake_stderr {
250
+ RestClient::Request.new(method: :post, url: 'example.com',
251
+ payload: '123456', headers: {content_length: '20'})
252
+ }).to match(/warning: Overriding "Content-Length" header/i)
253
+ expect(fake_stderr {
254
+ RestClient::Request.new(method: :post, url: 'example.com',
255
+ payload: '123456', headers: {'Content-Length' => '20'})
256
+ }).to match(/warning: Overriding "Content-Length" header/i)
257
+ end
258
+
259
+ it "does not warn when overriding user header with header derived from payload if those header values were identical" do
260
+ expect(fake_stderr {
261
+ RestClient::Request.new(method: :post, url: 'example.com',
262
+ payload: {'foo' => '123456'}, headers: { 'Content-Type' => 'application/x-www-form-urlencoded' })
263
+ }).not_to match(/warning: Overriding "Content-Type" header/i)
264
+ end
265
+
266
+ it 'does not warn for a normal looking payload' do
267
+ expect(fake_stderr {
268
+ RestClient::Request.new(method: :post, url: 'example.com', payload: 'payload')
269
+ RestClient::Request.new(method: :post, url: 'example.com', payload: 'payload', headers: {content_type: :json})
270
+ RestClient::Request.new(method: :post, url: 'example.com', payload: {'foo' => 'bar'})
271
+ }).to eq ''
272
+ end
273
+
147
274
  it "uses netrc credentials" do
148
- URI.stub(:parse).and_return(double('uri', :user => nil, :password => nil, :host => 'example.com'))
149
- Netrc.stub(:read).and_return('example.com' => ['a', 'b'])
150
- @request.parse_url_with_auth('http://example.com/resource')
151
- @request.user.should eq 'a'
152
- @request.password.should eq 'b'
275
+ expect(Netrc).to receive(:read).and_return('example.com' => ['a', 'b'])
276
+ request = RestClient::Request.new(:method => :put, :url => 'http://example.com/', :payload => 'payload')
277
+ expect(request.user).to eq 'a'
278
+ expect(request.password).to eq 'b'
153
279
  end
154
280
 
155
281
  it "uses credentials in the url in preference to netrc" do
156
- URI.stub(:parse).and_return(double('uri', :user => 'joe%20', :password => 'pass1', :host => 'example.com'))
157
- Netrc.stub(:read).and_return('example.com' => ['a', 'b'])
158
- @request.parse_url_with_auth('http://joe%20:pass1@example.com/resource')
159
- @request.user.should eq 'joe '
160
- @request.password.should eq 'pass1'
282
+ allow(Netrc).to receive(:read).and_return('example.com' => ['a', 'b'])
283
+ request = RestClient::Request.new(:method => :put, :url => 'http://joe%20:pass1@example.com/', :payload => 'payload')
284
+ expect(request.user).to eq 'joe '
285
+ expect(request.password).to eq 'pass1'
161
286
  end
162
287
 
163
288
  it "determines the Net::HTTP class to instantiate by the method name" do
164
- @request.net_http_request_class(:put).should eq Net::HTTP::Put
289
+ expect(@request.net_http_request_class(:put)).to eq Net::HTTP::Put
165
290
  end
166
291
 
167
292
  describe "user headers" do
168
293
  it "merges user headers with the default headers" do
169
- @request.should_receive(:default_headers).and_return({ :accept => '*/*; q=0.5, application/xml', :accept_encoding => 'gzip, deflate' })
294
+ expect(@request).to receive(:default_headers).and_return({:accept => '*/*'})
170
295
  headers = @request.make_headers("Accept" => "application/json", :accept_encoding => 'gzip')
171
- headers.should have_key "Accept-Encoding"
172
- headers["Accept-Encoding"].should eq "gzip"
173
- headers.should have_key "Accept"
174
- headers["Accept"].should eq "application/json"
296
+ expect(headers).to have_key "Accept-Encoding"
297
+ expect(headers["Accept-Encoding"]).to eq "gzip"
298
+ expect(headers).to have_key "Accept"
299
+ expect(headers["Accept"]).to eq "application/json"
175
300
  end
176
301
 
177
302
  it "prefers the user header when the same header exists in the defaults" do
178
- @request.should_receive(:default_headers).and_return({ '1' => '2' })
303
+ expect(@request).to receive(:default_headers).and_return({ '1' => '2' })
179
304
  headers = @request.make_headers('1' => '3')
180
- headers.should have_key('1')
181
- headers['1'].should eq '3'
305
+ expect(headers).to have_key('1')
306
+ expect(headers['1']).to eq '3'
182
307
  end
183
308
 
184
309
  it "converts user headers to string before calling CGI::unescape which fails on non string values" do
185
- @request.should_receive(:default_headers).and_return({ '1' => '2' })
310
+ expect(@request).to receive(:default_headers).and_return({ '1' => '2' })
186
311
  headers = @request.make_headers('1' => 3)
187
- headers.should have_key('1')
188
- headers['1'].should eq '3'
312
+ expect(headers).to have_key('1')
313
+ expect(headers['1']).to eq '3'
189
314
  end
190
315
  end
191
316
 
192
317
  describe "header symbols" do
193
318
 
194
319
  it "converts header symbols from :content_type to 'Content-Type'" do
195
- @request.should_receive(:default_headers).and_return({})
320
+ expect(@request).to receive(:default_headers).and_return({})
196
321
  headers = @request.make_headers(:content_type => 'abc')
197
- headers.should have_key('Content-Type')
198
- headers['Content-Type'].should eq 'abc'
322
+ expect(headers).to have_key('Content-Type')
323
+ expect(headers['Content-Type']).to eq 'abc'
199
324
  end
200
325
 
201
326
  it "converts content-type from extension to real content-type" do
202
- @request.should_receive(:default_headers).and_return({})
327
+ expect(@request).to receive(:default_headers).and_return({})
203
328
  headers = @request.make_headers(:content_type => 'json')
204
- headers.should have_key('Content-Type')
205
- headers['Content-Type'].should eq 'application/json'
329
+ expect(headers).to have_key('Content-Type')
330
+ expect(headers['Content-Type']).to eq 'application/json'
206
331
  end
207
332
 
208
333
  it "converts accept from extension(s) to real content-type(s)" do
209
- @request.should_receive(:default_headers).and_return({})
334
+ expect(@request).to receive(:default_headers).and_return({})
210
335
  headers = @request.make_headers(:accept => 'json, mp3')
211
- headers.should have_key('Accept')
212
- headers['Accept'].should eq 'application/json, audio/mpeg'
336
+ expect(headers).to have_key('Accept')
337
+ expect(headers['Accept']).to eq 'application/json, audio/mpeg'
213
338
 
214
- @request.should_receive(:default_headers).and_return({})
339
+ expect(@request).to receive(:default_headers).and_return({})
215
340
  headers = @request.make_headers(:accept => :json)
216
- headers.should have_key('Accept')
217
- headers['Accept'].should eq 'application/json'
341
+ expect(headers).to have_key('Accept')
342
+ expect(headers['Accept']).to eq 'application/json'
218
343
  end
219
344
 
220
345
  it "only convert symbols in header" do
221
- @request.should_receive(:default_headers).and_return({})
346
+ expect(@request).to receive(:default_headers).and_return({})
222
347
  headers = @request.make_headers({:foo_bar => 'value', "bar_bar" => 'value'})
223
- headers['Foo-Bar'].should eq 'value'
224
- headers['bar_bar'].should eq 'value'
348
+ expect(headers['Foo-Bar']).to eq 'value'
349
+ expect(headers['bar_bar']).to eq 'value'
225
350
  end
226
351
 
227
352
  it "converts header values to strings" do
228
- @request.make_headers('A' => 1)['A'].should eq '1'
353
+ expect(@request.make_headers('A' => 1)['A']).to eq '1'
229
354
  end
230
355
  end
231
356
 
232
357
  it "executes by constructing the Net::HTTP object, headers, and payload and calling transmit" do
233
- @request.should_receive(:parse_url_with_auth).with('http://some/resource').and_return(@uri)
234
358
  klass = double("net:http class")
235
- @request.should_receive(:net_http_request_class).with(:put).and_return(klass)
236
- klass.should_receive(:new).and_return('result')
237
- @request.should_receive(:transmit).with(@uri, 'result', kind_of(RestClient::Payload::Base))
359
+ expect(@request).to receive(:net_http_request_class).with('put').and_return(klass)
360
+ expect(klass).to receive(:new).and_return('result')
361
+ expect(@request).to receive(:transmit).with(@request.uri, 'result', kind_of(RestClient::Payload::Base))
362
+ @request.execute
363
+ end
364
+
365
+ it "IPv6: executes by constructing the Net::HTTP object, headers, and payload and calling transmit" do
366
+ @request = RestClient::Request.new(:method => :put, :url => 'http://[::1]/some/resource', :payload => 'payload')
367
+ klass = double("net:http class")
368
+ expect(@request).to receive(:net_http_request_class).with('put').and_return(klass)
369
+
370
+ if RUBY_VERSION >= "2.0.0"
371
+ expect(klass).to receive(:new).with(kind_of(URI), kind_of(Hash)).and_return('result')
372
+ else
373
+ expect(klass).to receive(:new).with(kind_of(String), kind_of(Hash)).and_return('result')
374
+ end
375
+
376
+ expect(@request).to receive(:transmit)
238
377
  @request.execute
239
378
  end
240
379
 
380
+ # TODO: almost none of these tests should actually call transmit, which is
381
+ # part of the private API
382
+
241
383
  it "transmits the request with Net::HTTP" do
242
- @http.should_receive(:request).with('req', 'payload')
243
- @request.should_receive(:process_result)
244
- @request.transmit(@uri, 'req', 'payload')
384
+ expect(@http).to receive(:request).with('req', 'payload')
385
+ expect(@request).to receive(:process_result)
386
+ @request.send(:transmit, @uri, 'req', 'payload')
245
387
  end
246
388
 
389
+ # TODO: most of these payload tests are historical relics that actually
390
+ # belong in payload_spec.rb. Or we need new tests that actually cover the way
391
+ # that Request#initialize or Request#execute uses the payload.
247
392
  describe "payload" do
248
393
  it "sends nil payloads" do
249
- @http.should_receive(:request).with('req', nil)
250
- @request.should_receive(:process_result)
251
- @request.stub(:response_log)
252
- @request.transmit(@uri, 'req', nil)
394
+ expect(@http).to receive(:request).with('req', nil)
395
+ expect(@request).to receive(:process_result)
396
+ allow(@request).to receive(:response_log)
397
+ @request.send(:transmit, @uri, 'req', nil)
253
398
  end
254
399
 
255
400
  it "passes non-hash payloads straight through" do
256
- @request.process_payload("x").should eq "x"
401
+ expect(RestClient::Payload.generate("x").to_s).to eq "x"
257
402
  end
258
403
 
259
404
  it "converts a hash payload to urlencoded data" do
260
- @request.process_payload(:a => 'b c+d').should eq "a=b%20c%2Bd"
405
+ expect(RestClient::Payload.generate(:a => 'b c+d').to_s).to eq "a=b+c%2Bd"
261
406
  end
262
407
 
263
408
  it "accepts nested hashes in payload" do
264
- payload = @request.process_payload(:user => { :name => 'joe', :location => { :country => 'USA', :state => 'CA' }})
265
- payload.should include('user[name]=joe')
266
- payload.should include('user[location][country]=USA')
267
- payload.should include('user[location][state]=CA')
409
+ payload = RestClient::Payload.generate(:user => { :name => 'joe', :location => { :country => 'USA', :state => 'CA' }}).to_s
410
+ expect(payload).to include('user[name]=joe')
411
+ expect(payload).to include('user[location][country]=USA')
412
+ expect(payload).to include('user[location][state]=CA')
268
413
  end
269
414
  end
270
415
 
271
416
  it "set urlencoded content_type header on hash payloads" do
272
- @request.process_payload(:a => 1)
273
- @request.headers[:content_type].should eq 'application/x-www-form-urlencoded'
417
+ req = RestClient::Request.new(method: :post, url: 'http://some/resource', payload: {a: 1})
418
+ expect(req.processed_headers.fetch('Content-Type')).to eq 'application/x-www-form-urlencoded'
274
419
  end
275
420
 
276
421
  describe "credentials" do
277
422
  it "sets up the credentials prior to the request" do
278
- @http.stub(:request)
423
+ allow(@http).to receive(:request)
279
424
 
280
- @request.stub(:process_result)
281
- @request.stub(:response_log)
425
+ allow(@request).to receive(:process_result)
426
+ allow(@request).to receive(:response_log)
282
427
 
283
- @request.stub(:user).and_return('joe')
284
- @request.stub(:password).and_return('mypass')
285
- @request.should_receive(:setup_credentials).with('req')
428
+ allow(@request).to receive(:user).and_return('joe')
429
+ allow(@request).to receive(:password).and_return('mypass')
430
+ expect(@request).to receive(:setup_credentials).with('req')
286
431
 
287
- @request.transmit(@uri, 'req', nil)
432
+ @request.send(:transmit, @uri, 'req', nil)
288
433
  end
289
434
 
290
435
  it "does not attempt to send any credentials if user is nil" do
291
- @request.stub(:user).and_return(nil)
436
+ allow(@request).to receive(:user).and_return(nil)
292
437
  req = double("request")
293
- req.should_not_receive(:basic_auth)
294
- @request.setup_credentials(req)
438
+ expect(req).not_to receive(:basic_auth)
439
+ @request.send(:setup_credentials, req)
295
440
  end
296
441
 
297
442
  it "setup credentials when there's a user" do
298
- @request.stub(:user).and_return('joe')
299
- @request.stub(:password).and_return('mypass')
443
+ allow(@request).to receive(:user).and_return('joe')
444
+ allow(@request).to receive(:password).and_return('mypass')
300
445
  req = double("request")
301
- req.should_receive(:basic_auth).with('joe', 'mypass')
302
- @request.setup_credentials(req)
446
+ expect(req).to receive(:basic_auth).with('joe', 'mypass')
447
+ @request.send(:setup_credentials, req)
448
+ end
449
+
450
+ it "does not attempt to send credentials if Authorization header is set" do
451
+ ['Authorization', 'authorization', 'auTHORization', :authorization].each do |authorization|
452
+ headers = {authorization => 'Token abc123'}
453
+ request = RestClient::Request.new(method: :get, url: 'http://some/resource', headers: headers, user: 'joe', password: 'mypass')
454
+ req = double("net::http request")
455
+ expect(req).not_to receive(:basic_auth)
456
+ request.send(:setup_credentials, req)
457
+ end
303
458
  end
304
459
  end
305
460
 
306
461
  it "catches EOFError and shows the more informative ServerBrokeConnection" do
307
- @http.stub(:request).and_raise(EOFError)
308
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::ServerBrokeConnection)
462
+ allow(@http).to receive(:request).and_raise(EOFError)
463
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::ServerBrokeConnection)
309
464
  end
310
465
 
311
466
  it "catches OpenSSL::SSL::SSLError and raise it back without more informative message" do
312
- @http.stub(:request).and_raise(OpenSSL::SSL::SSLError)
313
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(OpenSSL::SSL::SSLError)
467
+ allow(@http).to receive(:request).and_raise(OpenSSL::SSL::SSLError)
468
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(OpenSSL::SSL::SSLError)
469
+ end
470
+
471
+ it "catches Timeout::Error and raise the more informative ReadTimeout" do
472
+ allow(@http).to receive(:request).and_raise(Timeout::Error)
473
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::ReadTimeout)
314
474
  end
315
475
 
316
- it "catches Timeout::Error and raise the more informative RequestTimeout" do
317
- @http.stub(:request).and_raise(Timeout::Error)
318
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::RequestTimeout)
476
+ it "catches Errno::ETIMEDOUT and raise the more informative ReadTimeout" do
477
+ allow(@http).to receive(:request).and_raise(Errno::ETIMEDOUT)
478
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::ReadTimeout)
319
479
  end
320
480
 
321
- it "catches Timeout::Error and raise the more informative RequestTimeout" do
322
- @http.stub(:request).and_raise(Errno::ETIMEDOUT)
323
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::RequestTimeout)
481
+ it "catches Net::ReadTimeout and raises RestClient's ReadTimeout",
482
+ :if => defined?(Net::ReadTimeout) do
483
+ allow(@http).to receive(:request).and_raise(Net::ReadTimeout)
484
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::ReadTimeout)
324
485
  end
325
486
 
487
+ it "catches Net::OpenTimeout and raises RestClient's OpenTimeout",
488
+ :if => defined?(Net::OpenTimeout) do
489
+ allow(@http).to receive(:request).and_raise(Net::OpenTimeout)
490
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::OpenTimeout)
491
+ end
492
+
493
+ it "uses correct error message for ReadTimeout",
494
+ :if => defined?(Net::ReadTimeout) do
495
+ allow(@http).to receive(:request).and_raise(Net::ReadTimeout)
496
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::ReadTimeout, 'Timed out reading data from server')
497
+ end
498
+
499
+ it "uses correct error message for OpenTimeout",
500
+ :if => defined?(Net::OpenTimeout) do
501
+ allow(@http).to receive(:request).and_raise(Net::OpenTimeout)
502
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::OpenTimeout, 'Timed out connecting to server')
503
+ end
504
+
505
+
326
506
  it "class method execute wraps constructor" do
327
507
  req = double("rest request")
328
- RestClient::Request.should_receive(:new).with(1 => 2).and_return(req)
329
- req.should_receive(:execute)
508
+ expect(RestClient::Request).to receive(:new).with(1 => 2).and_return(req)
509
+ expect(req).to receive(:execute)
330
510
  RestClient::Request.execute(1 => 2)
331
511
  end
332
512
 
333
513
  describe "exception" do
334
514
  it "raises Unauthorized when the response is 401" do
335
- res = double('response', :code => '401', :[] => ['content-encoding' => ''], :body => '' )
336
- lambda { @request.process_result(res) }.should raise_error(RestClient::Unauthorized)
515
+ res = res_double(:code => '401', :[] => ['content-encoding' => ''], :body => '' )
516
+ expect { @request.send(:process_result, res, Time.now) }.to raise_error(RestClient::Unauthorized)
337
517
  end
338
518
 
339
519
  it "raises ResourceNotFound when the response is 404" do
340
- res = double('response', :code => '404', :[] => ['content-encoding' => ''], :body => '' )
341
- lambda { @request.process_result(res) }.should raise_error(RestClient::ResourceNotFound)
520
+ res = res_double(:code => '404', :[] => ['content-encoding' => ''], :body => '' )
521
+ expect { @request.send(:process_result, res, Time.now) }.to raise_error(RestClient::ResourceNotFound)
342
522
  end
343
523
 
344
524
  it "raises RequestFailed otherwise" do
345
- res = double('response', :code => '500', :[] => ['content-encoding' => ''], :body => '' )
346
- lambda { @request.process_result(res) }.should raise_error(RestClient::InternalServerError)
525
+ res = res_double(:code => '500', :[] => ['content-encoding' => ''], :body => '' )
526
+ expect { @request.send(:process_result, res, Time.now) }.to raise_error(RestClient::InternalServerError)
347
527
  end
348
528
  end
349
529
 
350
530
  describe "block usage" do
351
531
  it "returns what asked to" do
352
- res = double('response', :code => '401', :[] => ['content-encoding' => ''], :body => '' )
353
- @request.process_result(res){|response, request| "foo"}.should eq "foo"
532
+ res = res_double(:code => '401', :[] => ['content-encoding' => ''], :body => '' )
533
+ expect(@request.send(:process_result, res, Time.now){|response, request| "foo"}).to eq "foo"
354
534
  end
355
535
  end
356
536
 
357
537
  describe "proxy" do
538
+ before do
539
+ # unstub Net::HTTP creation since we need to test it
540
+ allow(Net::HTTP).to receive(:new).and_call_original
541
+
542
+ @proxy_req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
543
+ end
544
+
358
545
  it "creates a proxy class if a proxy url is given" do
359
- RestClient.stub(:proxy).and_return("http://example.com/")
360
- @request.net_http_class.proxy_class?.should be_true
546
+ allow(RestClient).to receive(:proxy).and_return("http://example.com/")
547
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
548
+ expect(@proxy_req.net_http_object('host', 80).proxy?).to be true
549
+ end
550
+
551
+ it "creates a proxy class with the correct address if a IPv6 proxy url is given" do
552
+ allow(RestClient).to receive(:proxy).and_return("http://[::1]/")
553
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
554
+ expect(@proxy_req.net_http_object('host', 80).proxy?).to be true
555
+ expect(@proxy_req.net_http_object('host', 80).proxy_address).to eq('::1')
361
556
  end
362
557
 
363
558
  it "creates a non-proxy class if a proxy url is not given" do
364
- @request.net_http_class.proxy_class?.should be_false
559
+ expect(@proxy_req.net_http_object('host', 80).proxy?).to be_falsey
560
+ end
561
+
562
+ it "disables proxy on a per-request basis" do
563
+ allow(RestClient).to receive(:proxy).and_return('http://example.com')
564
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
565
+ expect(@proxy_req.net_http_object('host', 80).proxy?).to be true
566
+
567
+ disabled_req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil)
568
+ expect(disabled_req.net_http_object('host', 80).proxy?).to be_falsey
569
+ end
570
+
571
+ it "sets proxy on a per-request basis" do
572
+ expect(@proxy_req.net_http_object('some', 80).proxy?).to be_falsey
573
+
574
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => 'http://example.com')
575
+ expect(req.net_http_object('host', 80).proxy?).to be true
576
+ end
577
+
578
+ it "overrides proxy from environment", if: RUBY_VERSION >= '2.0' do
579
+ allow(ENV).to receive(:[]).with("http_proxy").and_return("http://127.0.0.1")
580
+ allow(ENV).to receive(:[]).with("no_proxy").and_return(nil)
581
+ allow(ENV).to receive(:[]).with("NO_PROXY").and_return(nil)
582
+ allow(Netrc).to receive(:read).and_return({})
583
+
584
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
585
+ obj = req.net_http_object('host', 80)
586
+ expect(obj.proxy?).to be true
587
+ expect(obj.proxy_address).to eq '127.0.0.1'
588
+
589
+ # test original method .proxy?
590
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil)
591
+ obj = req.net_http_object('host', 80)
592
+ expect(obj.proxy?).to be_falsey
593
+
594
+ # stub RestClient.proxy_set? to peek into implementation
595
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
596
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
597
+ obj = req.net_http_object('host', 80)
598
+ expect(obj.proxy?).to be_falsey
599
+
600
+ # test stubbed Net::HTTP.new
601
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil)
602
+ expect(Net::HTTP).to receive(:new).with('host', 80, nil, nil, nil, nil)
603
+ req.net_http_object('host', 80)
604
+ end
605
+
606
+ it "overrides global proxy with per-request proxy" do
607
+ allow(RestClient).to receive(:proxy).and_return('http://example.com')
608
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
609
+ obj = @proxy_req.net_http_object('host', 80)
610
+ expect(obj.proxy?).to be true
611
+ expect(obj.proxy_address).to eq 'example.com'
612
+
613
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => 'http://127.0.0.1/')
614
+ expect(req.net_http_object('host', 80).proxy?).to be true
615
+ expect(req.net_http_object('host', 80).proxy_address).to eq('127.0.0.1')
365
616
  end
366
617
  end
367
618
 
@@ -369,189 +620,231 @@ describe RestClient::Request do
369
620
  describe "logging" do
370
621
  it "logs a get request" do
371
622
  log = RestClient.log = []
372
- RestClient::Request.new(:method => :get, :url => 'http://url').log_request
373
- log[0].should eq %Q{RestClient.get "http://url", "Accept"=>"*/*; q=0.5, application/xml", "Accept-Encoding"=>"gzip, deflate"\n}
623
+ RestClient::Request.new(:method => :get, :url => 'http://url', :headers => {:user_agent => 'rest-client'}).log_request
624
+ expect(log[0]).to eq %Q{RestClient.get "http://url", "Accept"=>"*/*", "User-Agent"=>"rest-client"\n}
374
625
  end
375
626
 
376
627
  it "logs a post request with a small payload" do
377
628
  log = RestClient.log = []
378
- RestClient::Request.new(:method => :post, :url => 'http://url', :payload => 'foo').log_request
379
- log[0].should eq %Q{RestClient.post "http://url", "foo", "Accept"=>"*/*; q=0.5, application/xml", "Accept-Encoding"=>"gzip, deflate", "Content-Length"=>"3"\n}
629
+ RestClient::Request.new(:method => :post, :url => 'http://url', :payload => 'foo', :headers => {:user_agent => 'rest-client'}).log_request
630
+ expect(log[0]).to eq %Q{RestClient.post "http://url", "foo", "Accept"=>"*/*", "Content-Length"=>"3", "User-Agent"=>"rest-client"\n}
380
631
  end
381
632
 
382
633
  it "logs a post request with a large payload" do
383
634
  log = RestClient.log = []
384
- RestClient::Request.new(:method => :post, :url => 'http://url', :payload => ('x' * 1000)).log_request
385
- log[0].should eq %Q{RestClient.post "http://url", 1000 byte(s) length, "Accept"=>"*/*; q=0.5, application/xml", "Accept-Encoding"=>"gzip, deflate", "Content-Length"=>"1000"\n}
635
+ RestClient::Request.new(:method => :post, :url => 'http://url', :payload => ('x' * 1000), :headers => {:user_agent => 'rest-client'}).log_request
636
+ expect(log[0]).to eq %Q{RestClient.post "http://url", 1000 byte(s) length, "Accept"=>"*/*", "Content-Length"=>"1000", "User-Agent"=>"rest-client"\n}
386
637
  end
387
638
 
388
639
  it "logs input headers as a hash" do
389
640
  log = RestClient.log = []
390
- RestClient::Request.new(:method => :get, :url => 'http://url', :headers => { :accept => 'text/plain' }).log_request
391
- log[0].should eq %Q{RestClient.get "http://url", "Accept"=>"text/plain", "Accept-Encoding"=>"gzip, deflate"\n}
641
+ RestClient::Request.new(:method => :get, :url => 'http://url', :headers => { :accept => 'text/plain', :user_agent => 'rest-client' }).log_request
642
+ expect(log[0]).to eq %Q{RestClient.get "http://url", "Accept"=>"text/plain", "User-Agent"=>"rest-client"\n}
392
643
  end
393
644
 
394
645
  it "logs a response including the status code, content type, and result body size in bytes" do
395
646
  log = RestClient.log = []
396
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
397
- res.stub(:[]).with('Content-type').and_return('text/html')
398
- @request.log_response res
399
- log[0].should eq "# => 200 OK | text/html 4 bytes\n"
647
+ res = res_double(code: '200', class: Net::HTTPOK, body: 'abcd')
648
+ allow(res).to receive(:[]).with('Content-type').and_return('text/html')
649
+ response = response_from_res_double(res, @request)
650
+ response.log_response
651
+ expect(log).to eq ["# => 200 OK | text/html 4 bytes, 1.00s\n"]
400
652
  end
401
653
 
402
654
  it "logs a response with a nil Content-type" do
403
655
  log = RestClient.log = []
404
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
405
- res.stub(:[]).with('Content-type').and_return(nil)
406
- @request.log_response res
407
- log[0].should eq "# => 200 OK | 4 bytes\n"
656
+ res = res_double(code: '200', class: Net::HTTPOK, body: 'abcd')
657
+ allow(res).to receive(:[]).with('Content-type').and_return(nil)
658
+ response = response_from_res_double(res, @request)
659
+ response.log_response
660
+ expect(log).to eq ["# => 200 OK | 4 bytes, 1.00s\n"]
408
661
  end
409
662
 
410
663
  it "logs a response with a nil body" do
411
664
  log = RestClient.log = []
412
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => nil)
413
- res.stub(:[]).with('Content-type').and_return('text/html; charset=utf-8')
414
- @request.log_response res
415
- log[0].should eq "# => 200 OK | text/html 0 bytes\n"
665
+ res = res_double(code: '200', class: Net::HTTPOK, body: nil)
666
+ allow(res).to receive(:[]).with('Content-type').and_return('text/html; charset=utf-8')
667
+ response = response_from_res_double(res, @request)
668
+ response.log_response
669
+ expect(log).to eq ["# => 200 OK | text/html 0 bytes, 1.00s\n"]
416
670
  end
417
671
 
418
672
  it 'does not log request password' do
419
673
  log = RestClient.log = []
420
- RestClient::Request.new(:method => :get, :url => 'http://user:password@url', :headers => {:user_agent => 'rest-client', :accept => '*/*'}).log_request
421
- log[0].should eq %Q{RestClient.get "http://user:REDACTED@url", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
674
+ RestClient::Request.new(:method => :get, :url => 'http://user:password@url', :headers => {:user_agent => 'rest-client'}).log_request
675
+ expect(log[0]).to eq %Q{RestClient.get "http://user:REDACTED@url", "Accept"=>"*/*", "User-Agent"=>"rest-client"\n}
422
676
  end
423
677
 
424
- it 'logs invalid URIs, even though they will fail elsewhere' do
425
- log = RestClient.log = []
426
- RestClient::Request.new(:method => :get, :url => 'http://a@b:c', :headers => {:user_agent => 'rest-client', :accept => '*/*'}).log_request
427
- log[0].should eq %Q{RestClient.get "[invalid uri]", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
678
+ it 'logs to a passed logger, if provided' do
679
+ logger = double('logger', '<<' => true)
680
+ expect(logger).to receive(:<<)
681
+ RestClient::Request.new(:method => :get, :url => 'http://user:password@url', log: logger).log_request
428
682
  end
429
683
  end
430
684
 
431
685
  it "strips the charset from the response content type" do
432
686
  log = RestClient.log = []
433
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
434
- res.stub(:[]).with('Content-type').and_return('text/html; charset=utf-8')
435
- @request.log_response res
436
- log[0].should eq "# => 200 OK | text/html 4 bytes\n"
687
+ res = res_double(code: '200', class: Net::HTTPOK, body: 'abcd')
688
+ allow(res).to receive(:[]).with('Content-type').and_return('text/html; charset=utf-8')
689
+ response = response_from_res_double(res, @request)
690
+ response.log_response
691
+ expect(log).to eq ["# => 200 OK | text/html 4 bytes, 1.00s\n"]
437
692
  end
438
693
 
439
694
  describe "timeout" do
440
695
  it "does not set timeouts if not specified" do
441
696
  @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
442
- @http.stub(:request)
443
- @request.stub(:process_result)
444
- @request.stub(:response_log)
697
+ allow(@http).to receive(:request)
698
+ allow(@request).to receive(:process_result)
699
+ allow(@request).to receive(:response_log)
445
700
 
446
- @net.should_not_receive(:read_timeout=)
447
- @net.should_not_receive(:open_timeout=)
701
+ expect(@net).not_to receive(:read_timeout=)
702
+ expect(@net).not_to receive(:open_timeout=)
448
703
 
449
- @request.transmit(@uri, 'req', nil)
704
+ @request.send(:transmit, @uri, 'req', nil)
450
705
  end
451
706
 
452
- it "set read_timeout" do
453
- @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123)
454
- @http.stub(:request)
455
- @request.stub(:process_result)
456
- @request.stub(:response_log)
707
+ it 'sets read_timeout' do
708
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => 123)
709
+ allow(@http).to receive(:request)
710
+ allow(@request).to receive(:process_result)
711
+ allow(@request).to receive(:response_log)
457
712
 
458
- @net.should_receive(:read_timeout=).with(123)
713
+ expect(@net).to receive(:read_timeout=).with(123)
459
714
 
460
- @request.transmit(@uri, 'req', nil)
715
+ @request.send(:transmit, @uri, 'req', nil)
461
716
  end
462
717
 
463
- it "set open_timeout" do
718
+ it "sets open_timeout" do
464
719
  @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :open_timeout => 123)
465
- @http.stub(:request)
466
- @request.stub(:process_result)
467
- @request.stub(:response_log)
720
+ allow(@http).to receive(:request)
721
+ allow(@request).to receive(:process_result)
722
+ allow(@request).to receive(:response_log)
468
723
 
469
- @net.should_receive(:open_timeout=).with(123)
724
+ expect(@net).to receive(:open_timeout=).with(123)
470
725
 
471
- @request.transmit(@uri, 'req', nil)
726
+ @request.send(:transmit, @uri, 'req', nil)
472
727
  end
473
728
 
729
+ it 'sets both timeouts with :timeout' do
730
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123)
731
+ allow(@http).to receive(:request)
732
+ allow(@request).to receive(:process_result)
733
+ allow(@request).to receive(:response_log)
734
+
735
+ expect(@net).to receive(:open_timeout=).with(123)
736
+ expect(@net).to receive(:read_timeout=).with(123)
737
+
738
+ @request.send(:transmit, @uri, 'req', nil)
739
+ end
740
+
741
+ it 'supersedes :timeout with open/read_timeout' do
742
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123, :open_timeout => 34, :read_timeout => 56)
743
+ allow(@http).to receive(:request)
744
+ allow(@request).to receive(:process_result)
745
+ allow(@request).to receive(:response_log)
746
+
747
+ expect(@net).to receive(:open_timeout=).with(34)
748
+ expect(@net).to receive(:read_timeout=).with(56)
749
+
750
+ @request.send(:transmit, @uri, 'req', nil)
751
+ end
752
+
753
+
474
754
  it "disable timeout by setting it to nil" do
475
- @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => nil, :open_timeout => nil)
476
- @http.stub(:request)
477
- @request.stub(:process_result)
478
- @request.stub(:response_log)
755
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => nil, :open_timeout => nil)
756
+ allow(@http).to receive(:request)
757
+ allow(@request).to receive(:process_result)
758
+ allow(@request).to receive(:response_log)
479
759
 
480
- @net.should_receive(:read_timeout=).with(nil)
481
- @net.should_receive(:open_timeout=).with(nil)
760
+ expect(@net).to receive(:read_timeout=).with(nil)
761
+ expect(@net).to receive(:open_timeout=).with(nil)
482
762
 
483
- @request.transmit(@uri, 'req', nil)
763
+ @request.send(:transmit, @uri, 'req', nil)
764
+ end
765
+
766
+ it 'deprecated: warns when disabling timeout by setting it to -1' do
767
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => -1)
768
+ allow(@http).to receive(:request)
769
+ allow(@request).to receive(:process_result)
770
+ allow(@request).to receive(:response_log)
771
+
772
+ expect(@net).to receive(:read_timeout=).with(nil)
773
+
774
+ expect(fake_stderr {
775
+ @request.send(:transmit, @uri, 'req', nil)
776
+ }).to match(/^Deprecated: .*timeout.* nil instead of -1$/)
484
777
  end
485
778
 
486
779
  it "deprecated: disable timeout by setting it to -1" do
487
- @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => -1, :open_timeout => -1)
488
- @http.stub(:request)
489
- @request.stub(:process_result)
490
- @request.stub(:response_log)
780
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => -1, :open_timeout => -1)
781
+ allow(@http).to receive(:request)
782
+ allow(@request).to receive(:process_result)
783
+ allow(@request).to receive(:response_log)
491
784
 
492
- @request.should_receive(:warn)
493
- @net.should_receive(:read_timeout=).with(nil)
785
+ expect(@request).to receive(:warn)
786
+ expect(@net).to receive(:read_timeout=).with(nil)
494
787
 
495
- @request.should_receive(:warn)
496
- @net.should_receive(:open_timeout=).with(nil)
788
+ expect(@request).to receive(:warn)
789
+ expect(@net).to receive(:open_timeout=).with(nil)
497
790
 
498
- @request.transmit(@uri, 'req', nil)
791
+ @request.send(:transmit, @uri, 'req', nil)
499
792
  end
500
793
  end
501
794
 
502
795
  describe "ssl" do
503
796
  it "uses SSL when the URI refers to a https address" do
504
- @uri.stub(:is_a?).with(URI::HTTPS).and_return(true)
505
- @net.should_receive(:use_ssl=).with(true)
506
- @http.stub(:request)
507
- @request.stub(:process_result)
508
- @request.stub(:response_log)
509
- @request.transmit(@uri, 'req', 'payload')
797
+ allow(@uri).to receive(:is_a?).with(URI::HTTPS).and_return(true)
798
+ expect(@net).to receive(:use_ssl=).with(true)
799
+ allow(@http).to receive(:request)
800
+ allow(@request).to receive(:process_result)
801
+ allow(@request).to receive(:response_log)
802
+ @request.send(:transmit, @uri, 'req', 'payload')
510
803
  end
511
804
 
512
805
  it "should default to verifying ssl certificates" do
513
- @request.verify_ssl.should eq OpenSSL::SSL::VERIFY_PEER
806
+ expect(@request.verify_ssl).to eq OpenSSL::SSL::VERIFY_PEER
514
807
  end
515
808
 
516
809
  it "should have expected values for VERIFY_PEER and VERIFY_NONE" do
517
- OpenSSL::SSL::VERIFY_NONE.should eq(0)
518
- OpenSSL::SSL::VERIFY_PEER.should eq(1)
810
+ expect(OpenSSL::SSL::VERIFY_NONE).to eq(0)
811
+ expect(OpenSSL::SSL::VERIFY_PEER).to eq(1)
519
812
  end
520
813
 
521
814
  it "should set net.verify_mode to OpenSSL::SSL::VERIFY_NONE if verify_ssl is false" do
522
815
  @request = RestClient::Request.new(:method => :put, :verify_ssl => false, :url => 'http://some/resource', :payload => 'payload')
523
- @net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
524
- @http.stub(:request)
525
- @request.stub(:process_result)
526
- @request.stub(:response_log)
527
- @request.transmit(@uri, 'req', 'payload')
816
+ expect(@net).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
817
+ allow(@http).to receive(:request)
818
+ allow(@request).to receive(:process_result)
819
+ allow(@request).to receive(:response_log)
820
+ @request.send(:transmit, @uri, 'req', 'payload')
528
821
  end
529
822
 
530
823
  it "should not set net.verify_mode to OpenSSL::SSL::VERIFY_NONE if verify_ssl is true" do
531
824
  @request = RestClient::Request.new(:method => :put, :url => 'https://some/resource', :payload => 'payload', :verify_ssl => true)
532
- @net.should_not_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
533
- @http.stub(:request)
534
- @request.stub(:process_result)
535
- @request.stub(:response_log)
536
- @request.transmit(@uri, 'req', 'payload')
825
+ expect(@net).not_to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
826
+ allow(@http).to receive(:request)
827
+ allow(@request).to receive(:process_result)
828
+ allow(@request).to receive(:response_log)
829
+ @request.send(:transmit, @uri, 'req', 'payload')
537
830
  end
538
831
 
539
832
  it "should set net.verify_mode to OpenSSL::SSL::VERIFY_PEER if verify_ssl is true" do
540
833
  @request = RestClient::Request.new(:method => :put, :url => 'https://some/resource', :payload => 'payload', :verify_ssl => true)
541
- @net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
542
- @http.stub(:request)
543
- @request.stub(:process_result)
544
- @request.stub(:response_log)
545
- @request.transmit(@uri, 'req', 'payload')
834
+ expect(@net).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
835
+ allow(@http).to receive(:request)
836
+ allow(@request).to receive(:process_result)
837
+ allow(@request).to receive(:response_log)
838
+ @request.send(:transmit, @uri, 'req', 'payload')
546
839
  end
547
840
 
548
841
  it "should set net.verify_mode to OpenSSL::SSL::VERIFY_PEER if verify_ssl is not given" do
549
842
  @request = RestClient::Request.new(:method => :put, :url => 'https://some/resource', :payload => 'payload')
550
- @net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
551
- @http.stub(:request)
552
- @request.stub(:process_result)
553
- @request.stub(:response_log)
554
- @request.transmit(@uri, 'req', 'payload')
843
+ expect(@net).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
844
+ allow(@http).to receive(:request)
845
+ allow(@request).to receive(:process_result)
846
+ allow(@request).to receive(:response_log)
847
+ @request.send(:transmit, @uri, 'req', 'payload')
555
848
  end
556
849
 
557
850
  it "should set net.verify_mode to the passed value if verify_ssl is an OpenSSL constant" do
@@ -560,15 +853,15 @@ describe RestClient::Request do
560
853
  :url => 'https://some/resource',
561
854
  :payload => 'payload',
562
855
  :verify_ssl => mode )
563
- @net.should_receive(:verify_mode=).with(mode)
564
- @http.stub(:request)
565
- @request.stub(:process_result)
566
- @request.stub(:response_log)
567
- @request.transmit(@uri, 'req', 'payload')
856
+ expect(@net).to receive(:verify_mode=).with(mode)
857
+ allow(@http).to receive(:request)
858
+ allow(@request).to receive(:process_result)
859
+ allow(@request).to receive(:response_log)
860
+ @request.send(:transmit, @uri, 'req', 'payload')
568
861
  end
569
862
 
570
863
  it "should default to not having an ssl_client_cert" do
571
- @request.ssl_client_cert.should be(nil)
864
+ expect(@request.ssl_client_cert).to be(nil)
572
865
  end
573
866
 
574
867
  it "should set the ssl_version if provided" do
@@ -578,11 +871,11 @@ describe RestClient::Request do
578
871
  :payload => 'payload',
579
872
  :ssl_version => "TLSv1"
580
873
  )
581
- @net.should_receive(:ssl_version=).with("TLSv1")
582
- @http.stub(:request)
583
- @request.stub(:process_result)
584
- @request.stub(:response_log)
585
- @request.transmit(@uri, 'req', 'payload')
874
+ expect(@net).to receive(:ssl_version=).with("TLSv1")
875
+ allow(@http).to receive(:request)
876
+ allow(@request).to receive(:process_result)
877
+ allow(@request).to receive(:response_log)
878
+ @request.send(:transmit, @uri, 'req', 'payload')
586
879
  end
587
880
 
588
881
  it "should not set the ssl_version if not provided" do
@@ -591,11 +884,11 @@ describe RestClient::Request do
591
884
  :url => 'https://some/resource',
592
885
  :payload => 'payload'
593
886
  )
594
- @net.should_not_receive(:ssl_version=).with("TLSv1")
595
- @http.stub(:request)
596
- @request.stub(:process_result)
597
- @request.stub(:response_log)
598
- @request.transmit(@uri, 'req', 'payload')
887
+ expect(@net).not_to receive(:ssl_version=).with("TLSv1")
888
+ allow(@http).to receive(:request)
889
+ allow(@request).to receive(:process_result)
890
+ allow(@request).to receive(:response_log)
891
+ @request.send(:transmit, @uri, 'req', 'payload')
599
892
  end
600
893
 
601
894
  it "should set the ssl_ciphers if provided" do
@@ -606,11 +899,11 @@ describe RestClient::Request do
606
899
  :payload => 'payload',
607
900
  :ssl_ciphers => ciphers
608
901
  )
609
- @net.should_receive(:ciphers=).with(ciphers)
610
- @http.stub(:request)
611
- @request.stub(:process_result)
612
- @request.stub(:response_log)
613
- @request.transmit(@uri, 'req', 'payload')
902
+ expect(@net).to receive(:ciphers=).with(ciphers)
903
+ allow(@http).to receive(:request)
904
+ allow(@request).to receive(:process_result)
905
+ allow(@request).to receive(:response_log)
906
+ @request.send(:transmit, @uri, 'req', 'payload')
614
907
  end
615
908
 
616
909
  it "should not set the ssl_ciphers if set to nil" do
@@ -620,61 +913,11 @@ describe RestClient::Request do
620
913
  :payload => 'payload',
621
914
  :ssl_ciphers => nil,
622
915
  )
623
- @net.should_not_receive(:ciphers=)
624
- @http.stub(:request)
625
- @request.stub(:process_result)
626
- @request.stub(:response_log)
627
- @request.transmit(@uri, 'req', 'payload')
628
- end
629
-
630
- it "should override ssl_ciphers with better defaults with weak default ciphers" do
631
- stub_const(
632
- '::OpenSSL::SSL::SSLContext::DEFAULT_PARAMS',
633
- {
634
- :ssl_version=>"SSLv23",
635
- :verify_mode=>1,
636
- :ciphers=>"ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
637
- :options=>-2147480577,
638
- }
639
- )
640
-
641
- @request = RestClient::Request.new(
642
- :method => :put,
643
- :url => 'https://some/resource',
644
- :payload => 'payload',
645
- )
646
-
647
- @net.should_receive(:ciphers=).with(RestClient::Request::DefaultCiphers)
648
-
649
- @http.stub(:request)
650
- @request.stub(:process_result)
651
- @request.stub(:response_log)
652
- @request.transmit(@uri, 'req', 'payload')
653
- end
654
-
655
- it "should not override ssl_ciphers with better defaults with different default ciphers" do
656
- stub_const(
657
- '::OpenSSL::SSL::SSLContext::DEFAULT_PARAMS',
658
- {
659
- :ssl_version=>"SSLv23",
660
- :verify_mode=>1,
661
- :ciphers=>"HIGH:!aNULL:!eNULL:!EXPORT:!LOW:!MEDIUM:!SSLv2",
662
- :options=>-2147480577,
663
- }
664
- )
665
-
666
- @request = RestClient::Request.new(
667
- :method => :put,
668
- :url => 'https://some/resource',
669
- :payload => 'payload',
670
- )
671
-
672
- @net.should_not_receive(:ciphers=)
673
-
674
- @http.stub(:request)
675
- @request.stub(:process_result)
676
- @request.stub(:response_log)
677
- @request.transmit(@uri, 'req', 'payload')
916
+ expect(@net).not_to receive(:ciphers=)
917
+ allow(@http).to receive(:request)
918
+ allow(@request).to receive(:process_result)
919
+ allow(@request).to receive(:response_log)
920
+ @request.send(:transmit, @uri, 'req', 'payload')
678
921
  end
679
922
 
680
923
  it "should set the ssl_client_cert if provided" do
@@ -684,11 +927,11 @@ describe RestClient::Request do
684
927
  :payload => 'payload',
685
928
  :ssl_client_cert => "whatsupdoc!"
686
929
  )
687
- @net.should_receive(:cert=).with("whatsupdoc!")
688
- @http.stub(:request)
689
- @request.stub(:process_result)
690
- @request.stub(:response_log)
691
- @request.transmit(@uri, 'req', 'payload')
930
+ expect(@net).to receive(:cert=).with("whatsupdoc!")
931
+ allow(@http).to receive(:request)
932
+ allow(@request).to receive(:process_result)
933
+ allow(@request).to receive(:response_log)
934
+ @request.send(:transmit, @uri, 'req', 'payload')
692
935
  end
693
936
 
694
937
  it "should not set the ssl_client_cert if it is not provided" do
@@ -697,15 +940,15 @@ describe RestClient::Request do
697
940
  :url => 'https://some/resource',
698
941
  :payload => 'payload'
699
942
  )
700
- @net.should_not_receive(:cert=)
701
- @http.stub(:request)
702
- @request.stub(:process_result)
703
- @request.stub(:response_log)
704
- @request.transmit(@uri, 'req', 'payload')
943
+ expect(@net).not_to receive(:cert=)
944
+ allow(@http).to receive(:request)
945
+ allow(@request).to receive(:process_result)
946
+ allow(@request).to receive(:response_log)
947
+ @request.send(:transmit, @uri, 'req', 'payload')
705
948
  end
706
949
 
707
950
  it "should default to not having an ssl_client_key" do
708
- @request.ssl_client_key.should be(nil)
951
+ expect(@request.ssl_client_key).to be(nil)
709
952
  end
710
953
 
711
954
  it "should set the ssl_client_key if provided" do
@@ -715,11 +958,11 @@ describe RestClient::Request do
715
958
  :payload => 'payload',
716
959
  :ssl_client_key => "whatsupdoc!"
717
960
  )
718
- @net.should_receive(:key=).with("whatsupdoc!")
719
- @http.stub(:request)
720
- @request.stub(:process_result)
721
- @request.stub(:response_log)
722
- @request.transmit(@uri, 'req', 'payload')
961
+ expect(@net).to receive(:key=).with("whatsupdoc!")
962
+ allow(@http).to receive(:request)
963
+ allow(@request).to receive(:process_result)
964
+ allow(@request).to receive(:response_log)
965
+ @request.send(:transmit, @uri, 'req', 'payload')
723
966
  end
724
967
 
725
968
  it "should not set the ssl_client_key if it is not provided" do
@@ -728,15 +971,15 @@ describe RestClient::Request do
728
971
  :url => 'https://some/resource',
729
972
  :payload => 'payload'
730
973
  )
731
- @net.should_not_receive(:key=)
732
- @http.stub(:request)
733
- @request.stub(:process_result)
734
- @request.stub(:response_log)
735
- @request.transmit(@uri, 'req', 'payload')
974
+ expect(@net).not_to receive(:key=)
975
+ allow(@http).to receive(:request)
976
+ allow(@request).to receive(:process_result)
977
+ allow(@request).to receive(:response_log)
978
+ @request.send(:transmit, @uri, 'req', 'payload')
736
979
  end
737
980
 
738
981
  it "should default to not having an ssl_ca_file" do
739
- @request.ssl_ca_file.should be(nil)
982
+ expect(@request.ssl_ca_file).to be(nil)
740
983
  end
741
984
 
742
985
  it "should set the ssl_ca_file if provided" do
@@ -746,12 +989,12 @@ describe RestClient::Request do
746
989
  :payload => 'payload',
747
990
  :ssl_ca_file => "Certificate Authority File"
748
991
  )
749
- @net.should_receive(:ca_file=).with("Certificate Authority File")
750
- @net.should_not_receive(:cert_store=)
751
- @http.stub(:request)
752
- @request.stub(:process_result)
753
- @request.stub(:response_log)
754
- @request.transmit(@uri, 'req', 'payload')
992
+ expect(@net).to receive(:ca_file=).with("Certificate Authority File")
993
+ expect(@net).not_to receive(:cert_store=)
994
+ allow(@http).to receive(:request)
995
+ allow(@request).to receive(:process_result)
996
+ allow(@request).to receive(:response_log)
997
+ @request.send(:transmit, @uri, 'req', 'payload')
755
998
  end
756
999
 
757
1000
  it "should not set the ssl_ca_file if it is not provided" do
@@ -760,15 +1003,15 @@ describe RestClient::Request do
760
1003
  :url => 'https://some/resource',
761
1004
  :payload => 'payload'
762
1005
  )
763
- @net.should_not_receive(:ca_file=)
764
- @http.stub(:request)
765
- @request.stub(:process_result)
766
- @request.stub(:response_log)
767
- @request.transmit(@uri, 'req', 'payload')
1006
+ expect(@net).not_to receive(:ca_file=)
1007
+ allow(@http).to receive(:request)
1008
+ allow(@request).to receive(:process_result)
1009
+ allow(@request).to receive(:response_log)
1010
+ @request.send(:transmit, @uri, 'req', 'payload')
768
1011
  end
769
1012
 
770
1013
  it "should default to not having an ssl_ca_path" do
771
- @request.ssl_ca_path.should be(nil)
1014
+ expect(@request.ssl_ca_path).to be(nil)
772
1015
  end
773
1016
 
774
1017
  it "should set the ssl_ca_path if provided" do
@@ -778,12 +1021,12 @@ describe RestClient::Request do
778
1021
  :payload => 'payload',
779
1022
  :ssl_ca_path => "Certificate Authority Path"
780
1023
  )
781
- @net.should_receive(:ca_path=).with("Certificate Authority Path")
782
- @net.should_not_receive(:cert_store=)
783
- @http.stub(:request)
784
- @request.stub(:process_result)
785
- @request.stub(:response_log)
786
- @request.transmit(@uri, 'req', 'payload')
1024
+ expect(@net).to receive(:ca_path=).with("Certificate Authority Path")
1025
+ expect(@net).not_to receive(:cert_store=)
1026
+ allow(@http).to receive(:request)
1027
+ allow(@request).to receive(:process_result)
1028
+ allow(@request).to receive(:response_log)
1029
+ @request.send(:transmit, @uri, 'req', 'payload')
787
1030
  end
788
1031
 
789
1032
  it "should not set the ssl_ca_path if it is not provided" do
@@ -792,11 +1035,11 @@ describe RestClient::Request do
792
1035
  :url => 'https://some/resource',
793
1036
  :payload => 'payload'
794
1037
  )
795
- @net.should_not_receive(:ca_path=)
796
- @http.stub(:request)
797
- @request.stub(:process_result)
798
- @request.stub(:response_log)
799
- @request.transmit(@uri, 'req', 'payload')
1038
+ expect(@net).not_to receive(:ca_path=)
1039
+ allow(@http).to receive(:request)
1040
+ allow(@request).to receive(:process_result)
1041
+ allow(@request).to receive(:response_log)
1042
+ @request.send(:transmit, @uri, 'req', 'payload')
800
1043
  end
801
1044
 
802
1045
  it "should set the ssl_cert_store if provided" do
@@ -809,13 +1052,13 @@ describe RestClient::Request do
809
1052
  :payload => 'payload',
810
1053
  :ssl_cert_store => store
811
1054
  )
812
- @net.should_receive(:cert_store=).with(store)
813
- @net.should_not_receive(:ca_path=)
814
- @net.should_not_receive(:ca_file=)
815
- @http.stub(:request)
816
- @request.stub(:process_result)
817
- @request.stub(:response_log)
818
- @request.transmit(@uri, 'req', 'payload')
1055
+ expect(@net).to receive(:cert_store=).with(store)
1056
+ expect(@net).not_to receive(:ca_path=)
1057
+ expect(@net).not_to receive(:ca_file=)
1058
+ allow(@http).to receive(:request)
1059
+ allow(@request).to receive(:process_result)
1060
+ allow(@request).to receive(:response_log)
1061
+ @request.send(:transmit, @uri, 'req', 'payload')
819
1062
  end
820
1063
 
821
1064
  it "should by default set the ssl_cert_store if no CA info is provided" do
@@ -824,13 +1067,13 @@ describe RestClient::Request do
824
1067
  :url => 'https://some/resource',
825
1068
  :payload => 'payload'
826
1069
  )
827
- @net.should_receive(:cert_store=)
828
- @net.should_not_receive(:ca_path=)
829
- @net.should_not_receive(:ca_file=)
830
- @http.stub(:request)
831
- @request.stub(:process_result)
832
- @request.stub(:response_log)
833
- @request.transmit(@uri, 'req', 'payload')
1070
+ expect(@net).to receive(:cert_store=)
1071
+ expect(@net).not_to receive(:ca_path=)
1072
+ expect(@net).not_to receive(:ca_file=)
1073
+ allow(@http).to receive(:request)
1074
+ allow(@request).to receive(:process_result)
1075
+ allow(@request).to receive(:response_log)
1076
+ @request.send(:transmit, @uri, 'req', 'payload')
834
1077
  end
835
1078
 
836
1079
  it "should not set the ssl_cert_store if it is set falsy" do
@@ -840,11 +1083,11 @@ describe RestClient::Request do
840
1083
  :payload => 'payload',
841
1084
  :ssl_cert_store => nil,
842
1085
  )
843
- @net.should_not_receive(:cert_store=)
844
- @http.stub(:request)
845
- @request.stub(:process_result)
846
- @request.stub(:response_log)
847
- @request.transmit(@uri, 'req', 'payload')
1086
+ expect(@net).not_to receive(:cert_store=)
1087
+ allow(@http).to receive(:request)
1088
+ allow(@request).to receive(:process_result)
1089
+ allow(@request).to receive(:response_log)
1090
+ @request.send(:transmit, @uri, 'req', 'payload')
848
1091
  end
849
1092
 
850
1093
  it "should not set the ssl_verify_callback by default" do
@@ -853,11 +1096,11 @@ describe RestClient::Request do
853
1096
  :url => 'https://some/resource',
854
1097
  :payload => 'payload',
855
1098
  )
856
- @net.should_not_receive(:verify_callback=)
857
- @http.stub(:request)
858
- @request.stub(:process_result)
859
- @request.stub(:response_log)
860
- @request.transmit(@uri, 'req', 'payload')
1099
+ expect(@net).not_to receive(:verify_callback=)
1100
+ allow(@http).to receive(:request)
1101
+ allow(@request).to receive(:process_result)
1102
+ allow(@request).to receive(:response_log)
1103
+ @request.send(:transmit, @uri, 'req', 'payload')
861
1104
  end
862
1105
 
863
1106
  it "should set the ssl_verify_callback if passed" do
@@ -868,7 +1111,7 @@ describe RestClient::Request do
868
1111
  :payload => 'payload',
869
1112
  :ssl_verify_callback => callback,
870
1113
  )
871
- @net.should_receive(:verify_callback=).with(callback)
1114
+ expect(@net).to receive(:verify_callback=).with(callback)
872
1115
 
873
1116
  # we'll read cert_store on jruby
874
1117
  # https://github.com/jruby/jruby/issues/597
@@ -876,10 +1119,10 @@ describe RestClient::Request do
876
1119
  allow(@net).to receive(:cert_store)
877
1120
  end
878
1121
 
879
- @http.stub(:request)
880
- @request.stub(:process_result)
881
- @request.stub(:response_log)
882
- @request.transmit(@uri, 'req', 'payload')
1122
+ allow(@http).to receive(:request)
1123
+ allow(@request).to receive(:process_result)
1124
+ allow(@request).to receive(:response_log)
1125
+ @request.send(:transmit, @uri, 'req', 'payload')
883
1126
  end
884
1127
 
885
1128
  # </ssl>
@@ -892,11 +1135,11 @@ describe RestClient::Request do
892
1135
  :payload => 'payload'
893
1136
  )
894
1137
  net_http_res = Net::HTTPNoContent.new("", "204", "No Content")
895
- net_http_res.stub(:read_body).and_return(nil)
896
- @http.should_receive(:request).and_return(@request.fetch_body(net_http_res))
897
- response = @request.transmit(@uri, 'req', 'payload')
898
- response.should_not be_nil
899
- response.code.should eq 204
1138
+ allow(net_http_res).to receive(:read_body).and_return(nil)
1139
+ expect(@http).to receive(:request).and_return(net_http_res)
1140
+ response = @request.send(:transmit, @uri, 'req', 'payload')
1141
+ expect(response).not_to be_nil
1142
+ expect(response.code).to eq 204
900
1143
  end
901
1144
 
902
1145
  describe "raw response" do
@@ -904,14 +1147,92 @@ describe RestClient::Request do
904
1147
  @request = RestClient::Request.new(:method => "get", :url => "example.com", :raw_response => true)
905
1148
 
906
1149
  tempfile = double("tempfile")
907
- tempfile.should_receive(:binmode)
908
- tempfile.stub(:open)
909
- tempfile.stub(:close)
910
- Tempfile.should_receive(:new).with("rest-client").and_return(tempfile)
1150
+ expect(tempfile).to receive(:binmode)
1151
+ allow(tempfile).to receive(:open)
1152
+ allow(tempfile).to receive(:close)
1153
+ expect(Tempfile).to receive(:new).with("rest-client.").and_return(tempfile)
911
1154
 
912
1155
  net_http_res = Net::HTTPOK.new(nil, "200", "body")
913
- net_http_res.stub(:read_body).and_return("body")
914
- @request.fetch_body(net_http_res)
1156
+ allow(net_http_res).to receive(:read_body).and_return("body")
1157
+ received_tempfile = @request.send(:fetch_body_to_tempfile, net_http_res)
1158
+ expect(received_tempfile).to eq tempfile
1159
+ end
1160
+ end
1161
+
1162
+ describe 'payloads' do
1163
+ it 'should accept string payloads' do
1164
+ payload = 'Foo'
1165
+ @request = RestClient::Request.new(method: :get, url: 'example.com', :payload => payload)
1166
+ expect(@request).to receive(:process_result)
1167
+ expect(@http).to receive(:request).with('req', payload)
1168
+ @request.send(:transmit, @uri, 'req', payload)
1169
+ end
1170
+
1171
+ it 'should accept streaming IO payloads' do
1172
+ payload = StringIO.new('streamed')
1173
+
1174
+ @request = RestClient::Request.new(method: :get, url: 'example.com', :payload => payload)
1175
+ expect(@request).to receive(:process_result)
1176
+
1177
+ @get = double('net::http::get')
1178
+ expect(@get).to receive(:body_stream=).with(instance_of(RestClient::Payload::Streamed))
1179
+
1180
+ allow(@request.net_http_request_class(:GET)).to receive(:new).and_return(@get)
1181
+ expect(@http).to receive(:request).with(@get, nil)
1182
+ @request.execute
1183
+ end
1184
+ end
1185
+
1186
+ describe 'constructor' do
1187
+ it 'should reject valid URIs with no hostname' do
1188
+ expect(URI.parse('http:///').hostname).to be_nil
1189
+
1190
+ expect {
1191
+ RestClient::Request.new(method: :get, url: 'http:///')
1192
+ }.to raise_error(URI::InvalidURIError, /\Abad URI/)
1193
+ end
1194
+
1195
+ it 'should reject invalid URIs' do
1196
+ expect {
1197
+ RestClient::Request.new(method: :get, url: 'http://::')
1198
+ }.to raise_error(URI::InvalidURIError)
1199
+ end
1200
+ end
1201
+
1202
+ describe 'process_url_params' do
1203
+ it 'should handle basic URL params' do
1204
+ expect(@request.process_url_params('https://example.com/foo', params: {key1: 123, key2: 'abc'})).
1205
+ to eq 'https://example.com/foo?key1=123&key2=abc'
1206
+
1207
+ expect(@request.process_url_params('https://example.com/foo', params: {'key1' => 123})).
1208
+ to eq 'https://example.com/foo?key1=123'
1209
+
1210
+ expect(@request.process_url_params('https://example.com/path',
1211
+ params: {foo: 'one two', bar: 'three + four == seven'})).
1212
+ to eq 'https://example.com/path?foo=one+two&bar=three+%2B+four+%3D%3D+seven'
1213
+ end
1214
+
1215
+ it 'should combine with & when URL params already exist' do
1216
+ expect(@request.process_url_params('https://example.com/path?foo=1', params: {bar: 2})).
1217
+ to eq 'https://example.com/path?foo=1&bar=2'
1218
+ end
1219
+
1220
+ it 'should handle complex nested URL params per Rack / Rails conventions' do
1221
+ expect(@request.process_url_params('https://example.com/', params: {
1222
+ foo: [1,2,3],
1223
+ null: nil,
1224
+ falsy: false,
1225
+ math: '2+2=4',
1226
+ nested: {'key + escaped' => 'value + escaped', other: [], arr: [1,2]},
1227
+ })).to eq 'https://example.com/?foo[]=1&foo[]=2&foo[]=3&null&falsy=false&math=2%2B2%3D4' \
1228
+ '&nested[key+%2B+escaped]=value+%2B+escaped&nested[other]' \
1229
+ '&nested[arr][]=1&nested[arr][]=2'
1230
+ end
1231
+
1232
+ it 'should handle ParamsArray objects' do
1233
+ expect(@request.process_url_params('https://example.com/',
1234
+ params: RestClient::ParamsArray.new([[:foo, 1], [:foo, 2]])
1235
+ )).to eq 'https://example.com/?foo=1&foo=2'
915
1236
  end
916
1237
  end
917
1238
  end