faraday 1.10.4 → 2.14.1

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +198 -4
  3. data/LICENSE.md +1 -1
  4. data/README.md +34 -20
  5. data/Rakefile +6 -1
  6. data/examples/client_spec.rb +41 -19
  7. data/examples/client_test.rb +48 -22
  8. data/lib/faraday/adapter/test.rb +62 -13
  9. data/lib/faraday/adapter.rb +6 -10
  10. data/lib/faraday/connection.rb +73 -150
  11. data/lib/faraday/encoders/flat_params_encoder.rb +2 -2
  12. data/lib/faraday/encoders/nested_params_encoder.rb +14 -7
  13. data/lib/faraday/error.rb +66 -10
  14. data/lib/faraday/logging/formatter.rb +30 -17
  15. data/lib/faraday/middleware.rb +43 -2
  16. data/lib/faraday/middleware_registry.rb +17 -63
  17. data/lib/faraday/options/connection_options.rb +7 -6
  18. data/lib/faraday/options/env.rb +85 -62
  19. data/lib/faraday/options/proxy_options.rb +11 -5
  20. data/lib/faraday/options/request_options.rb +7 -6
  21. data/lib/faraday/options/ssl_options.rb +62 -45
  22. data/lib/faraday/options.rb +7 -6
  23. data/lib/faraday/rack_builder.rb +44 -45
  24. data/lib/faraday/request/authorization.rb +33 -41
  25. data/lib/faraday/request/instrumentation.rb +5 -1
  26. data/lib/faraday/request/json.rb +18 -3
  27. data/lib/faraday/request/url_encoded.rb +5 -1
  28. data/lib/faraday/request.rb +15 -30
  29. data/lib/faraday/response/json.rb +25 -5
  30. data/lib/faraday/response/logger.rb +11 -3
  31. data/lib/faraday/response/raise_error.rb +45 -18
  32. data/lib/faraday/response.rb +14 -22
  33. data/lib/faraday/utils/headers.rb +15 -4
  34. data/lib/faraday/utils.rb +11 -7
  35. data/lib/faraday/version.rb +1 -1
  36. data/lib/faraday.rb +10 -45
  37. data/spec/faraday/adapter/test_spec.rb +65 -0
  38. data/spec/faraday/connection_spec.rb +198 -93
  39. data/spec/faraday/error_spec.rb +122 -7
  40. data/spec/faraday/middleware_registry_spec.rb +31 -0
  41. data/spec/faraday/middleware_spec.rb +161 -0
  42. data/spec/faraday/options/env_spec.rb +8 -2
  43. data/spec/faraday/options/options_spec.rb +1 -1
  44. data/spec/faraday/options/proxy_options_spec.rb +35 -0
  45. data/spec/faraday/params_encoders/nested_spec.rb +10 -1
  46. data/spec/faraday/rack_builder_spec.rb +26 -54
  47. data/spec/faraday/request/authorization_spec.rb +50 -28
  48. data/spec/faraday/request/instrumentation_spec.rb +5 -7
  49. data/spec/faraday/request/json_spec.rb +88 -0
  50. data/spec/faraday/request/url_encoded_spec.rb +12 -2
  51. data/spec/faraday/request_spec.rb +5 -15
  52. data/spec/faraday/response/json_spec.rb +93 -6
  53. data/spec/faraday/response/logger_spec.rb +83 -4
  54. data/spec/faraday/response/raise_error_spec.rb +133 -16
  55. data/spec/faraday/response_spec.rb +10 -1
  56. data/spec/faraday/utils/headers_spec.rb +31 -4
  57. data/spec/faraday/utils_spec.rb +65 -1
  58. data/spec/faraday_spec.rb +10 -4
  59. data/spec/spec_helper.rb +5 -6
  60. data/spec/support/fake_safe_buffer.rb +1 -1
  61. data/spec/support/faraday_middleware_subclasses.rb +18 -0
  62. data/spec/support/helper_methods.rb +0 -37
  63. data/spec/support/shared_examples/adapter.rb +2 -2
  64. data/spec/support/shared_examples/request_method.rb +22 -21
  65. metadata +24 -149
  66. data/lib/faraday/adapter/typhoeus.rb +0 -15
  67. data/lib/faraday/autoload.rb +0 -89
  68. data/lib/faraday/dependency_loader.rb +0 -39
  69. data/lib/faraday/deprecate.rb +0 -110
  70. data/lib/faraday/request/basic_authentication.rb +0 -20
  71. data/lib/faraday/request/token_authentication.rb +0 -20
  72. data/spec/faraday/adapter/em_http_spec.rb +0 -49
  73. data/spec/faraday/adapter/em_synchrony_spec.rb +0 -18
  74. data/spec/faraday/adapter/excon_spec.rb +0 -49
  75. data/spec/faraday/adapter/httpclient_spec.rb +0 -73
  76. data/spec/faraday/adapter/net_http_spec.rb +0 -64
  77. data/spec/faraday/adapter/patron_spec.rb +0 -18
  78. data/spec/faraday/adapter/rack_spec.rb +0 -8
  79. data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
  80. data/spec/faraday/composite_read_io_spec.rb +0 -80
  81. data/spec/faraday/deprecate_spec.rb +0 -147
  82. data/spec/faraday/response/middleware_spec.rb +0 -68
  83. data/spec/support/webmock_rack_app.rb +0 -68
@@ -1,10 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ class CustomEncoder
4
+ def encode(params)
5
+ params.map { |k, v| "#{k.upcase}-#{v.to_s.upcase}" }.join(',')
6
+ end
7
+
8
+ def decode(params)
9
+ params.split(',').to_h { |pair| pair.split('-') }
10
+ end
11
+ end
12
+
3
13
  shared_examples 'initializer with url' do
4
14
  context 'with simple url' do
5
- let(:address) { 'http://sushi.com' }
15
+ let(:address) { 'http://httpbingo.org' }
6
16
 
7
- it { expect(subject.host).to eq('sushi.com') }
17
+ it { expect(subject.host).to eq('httpbingo.org') }
8
18
  it { expect(subject.port).to eq(80) }
9
19
  it { expect(subject.scheme).to eq('http') }
10
20
  it { expect(subject.path_prefix).to eq('/') }
@@ -12,7 +22,7 @@ shared_examples 'initializer with url' do
12
22
  end
13
23
 
14
24
  context 'with complex url' do
15
- let(:address) { 'http://sushi.com:815/fish?a=1' }
25
+ let(:address) { 'http://httpbingo.org:815/fish?a=1' }
16
26
 
17
27
  it { expect(subject.port).to eq(815) }
18
28
  it { expect(subject.path_prefix).to eq('/fish') }
@@ -31,17 +41,17 @@ shared_examples 'default connection options' do
31
41
  after { Faraday.default_connection_options = nil }
32
42
 
33
43
  it 'works with implicit url' do
34
- conn = Faraday.new 'http://sushi.com/foo'
44
+ conn = Faraday.new 'http://httpbingo.org/foo'
35
45
  expect(conn.options.timeout).to eq(10)
36
46
  end
37
47
 
38
48
  it 'works with option url' do
39
- conn = Faraday.new url: 'http://sushi.com/foo'
49
+ conn = Faraday.new url: 'http://httpbingo.org/foo'
40
50
  expect(conn.options.timeout).to eq(10)
41
51
  end
42
52
 
43
53
  it 'works with instance connection options' do
44
- conn = Faraday.new 'http://sushi.com/foo', request: { open_timeout: 1 }
54
+ conn = Faraday.new 'http://httpbingo.org/foo', request: { open_timeout: 1 }
45
55
  expect(conn.options.timeout).to eq(10)
46
56
  expect(conn.options.open_timeout).to eq(1)
47
57
  end
@@ -51,7 +61,7 @@ shared_examples 'default connection options' do
51
61
  conn.options.timeout = 1
52
62
  expect(Faraday.default_connection_options.request.timeout).to eq(10)
53
63
 
54
- other = Faraday.new url: 'https://sushi.com/foo'
64
+ other = Faraday.new url: 'https://httpbingo.org/foo'
55
65
  other.options.timeout = 1
56
66
 
57
67
  expect(Faraday.default_connection_options.request.timeout).to eq(10)
@@ -71,14 +81,14 @@ RSpec.describe Faraday::Connection do
71
81
  subject { conn }
72
82
 
73
83
  context 'with implicit url param' do
74
- # Faraday::Connection.new('http://sushi.com')
84
+ # Faraday::Connection.new('http://httpbingo.org')
75
85
  let(:url) { address }
76
86
 
77
87
  it_behaves_like 'initializer with url'
78
88
  end
79
89
 
80
90
  context 'with explicit url param' do
81
- # Faraday::Connection.new(url: 'http://sushi.com')
91
+ # Faraday::Connection.new(url: 'http://httpbingo.org')
82
92
  let(:url) { { url: address } }
83
93
 
84
94
  it_behaves_like 'initializer with url'
@@ -98,11 +108,17 @@ RSpec.describe Faraday::Connection do
98
108
  end
99
109
 
100
110
  context 'with custom params and params in url' do
101
- let(:url) { 'http://sushi.com/fish?a=1&b=2' }
111
+ let(:url) { 'http://httpbingo.org/fish?a=1&b=2' }
102
112
  let(:options) { { params: { a: 3 } } }
103
113
  it { expect(subject.params).to eq('a' => 3, 'b' => '2') }
104
114
  end
105
115
 
116
+ context 'with basic_auth in url' do
117
+ let(:url) { 'http://Aladdin:open%20sesame@httpbingo.org/fish' }
118
+
119
+ it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
120
+ end
121
+
106
122
  context 'with custom headers' do
107
123
  let(:options) { { headers: { user_agent: 'Faraday' } } }
108
124
 
@@ -115,6 +131,12 @@ RSpec.describe Faraday::Connection do
115
131
  it { expect(subject.ssl.verify?).to be_falsey }
116
132
  end
117
133
 
134
+ context 'with verify_hostname false' do
135
+ let(:options) { { ssl: { verify_hostname: false } } }
136
+
137
+ it { expect(subject.ssl.verify_hostname?).to be_falsey }
138
+ end
139
+
118
140
  context 'with empty block' do
119
141
  let(:conn) { Faraday::Connection.new {} }
120
142
 
@@ -124,8 +146,8 @@ RSpec.describe Faraday::Connection do
124
146
  context 'with block' do
125
147
  let(:conn) do
126
148
  Faraday::Connection.new(params: { 'a' => '1' }) do |faraday|
127
- faraday.adapter :net_http
128
- faraday.url_prefix = 'http://sushi.com/omnom'
149
+ faraday.adapter :test
150
+ faraday.url_prefix = 'http://httpbingo.org/omnom'
129
151
  end
130
152
  end
131
153
 
@@ -135,41 +157,22 @@ RSpec.describe Faraday::Connection do
135
157
  end
136
158
 
137
159
  describe '#close' do
160
+ before { Faraday.default_adapter = :test }
161
+ after { Faraday.default_adapter = nil }
162
+
138
163
  it 'can close underlying app' do
139
164
  expect(conn.app).to receive(:close)
140
165
  conn.close
141
166
  end
142
167
  end
143
168
 
144
- describe 'basic_auth' do
145
- subject { conn }
146
-
147
- context 'calling the #basic_auth method' do
148
- before { subject.basic_auth 'Aladdin', 'open sesame' }
149
-
150
- it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
151
- end
152
-
153
- context 'adding basic auth info to url' do
154
- let(:url) { 'http://Aladdin:open%20sesame@sushi.com/fish' }
155
-
156
- it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
157
- end
158
- end
159
-
160
- describe '#token_auth' do
161
- before { subject.token_auth('abcdef', nonce: 'abc') }
162
-
163
- it { expect(subject.headers['Authorization']).to eq('Token nonce="abc", token="abcdef"') }
164
- end
165
-
166
169
  describe '#build_exclusive_url' do
167
170
  context 'with relative path' do
168
171
  subject { conn.build_exclusive_url('sake.html') }
169
172
 
170
173
  it 'uses connection host as default host' do
171
- conn.host = 'sushi.com'
172
- expect(subject.host).to eq('sushi.com')
174
+ conn.host = 'httpbingo.org'
175
+ expect(subject.host).to eq('httpbingo.org')
173
176
  expect(subject.scheme).to eq('http')
174
177
  end
175
178
 
@@ -206,10 +209,10 @@ RSpec.describe Faraday::Connection do
206
209
  end
207
210
 
208
211
  context 'with complete url' do
209
- subject { conn.build_exclusive_url('http://sushi.com/sake.html?a=1') }
212
+ subject { conn.build_exclusive_url('http://httpbingo.org/sake.html?a=1') }
210
213
 
211
214
  it { expect(subject.scheme).to eq('http') }
212
- it { expect(subject.host).to eq('sushi.com') }
215
+ it { expect(subject.host).to eq('httpbingo.org') }
213
216
  it { expect(subject.port).to eq(80) }
214
217
  it { expect(subject.path).to eq('/sake.html') }
215
218
  it { expect(subject.query).to eq('a=1') }
@@ -217,35 +220,35 @@ RSpec.describe Faraday::Connection do
217
220
 
218
221
  it 'overrides connection port for absolute url' do
219
222
  conn.port = 23
220
- uri = conn.build_exclusive_url('http://sushi.com')
223
+ uri = conn.build_exclusive_url('http://httpbingo.org')
221
224
  expect(uri.port).to eq(80)
222
225
  end
223
226
 
224
227
  it 'does not add ending slash given nil url' do
225
- conn.url_prefix = 'http://sushi.com/nigiri'
228
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
226
229
  uri = conn.build_exclusive_url
227
230
  expect(uri.path).to eq('/nigiri')
228
231
  end
229
232
 
230
233
  it 'does not add ending slash given empty url' do
231
- conn.url_prefix = 'http://sushi.com/nigiri'
234
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
232
235
  uri = conn.build_exclusive_url('')
233
236
  expect(uri.path).to eq('/nigiri')
234
237
  end
235
238
 
236
239
  it 'does not use connection params' do
237
- conn.url_prefix = 'http://sushi.com/nigiri'
240
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
238
241
  conn.params = { a: 1 }
239
- expect(conn.build_exclusive_url.to_s).to eq('http://sushi.com/nigiri')
242
+ expect(conn.build_exclusive_url.to_s).to eq('http://httpbingo.org/nigiri')
240
243
  end
241
244
 
242
245
  it 'allows to provide params argument' do
243
- conn.url_prefix = 'http://sushi.com/nigiri'
246
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
244
247
  conn.params = { a: 1 }
245
248
  params = Faraday::Utils::ParamsHash.new
246
249
  params[:a] = 2
247
250
  uri = conn.build_exclusive_url(nil, params)
248
- expect(uri.to_s).to eq('http://sushi.com/nigiri?a=2')
251
+ expect(uri.to_s).to eq('http://httpbingo.org/nigiri?a=2')
249
252
  end
250
253
 
251
254
  it 'handles uri instances' do
@@ -254,34 +257,34 @@ RSpec.describe Faraday::Connection do
254
257
  end
255
258
 
256
259
  it 'always returns new URI instance' do
257
- conn.url_prefix = 'http://sushi.com'
260
+ conn.url_prefix = 'http://httpbingo.org'
258
261
  uri1 = conn.build_exclusive_url(nil)
259
262
  uri2 = conn.build_exclusive_url(nil)
260
263
  expect(uri1).not_to equal(uri2)
261
264
  end
262
265
 
263
266
  context 'with url_prefixed connection' do
264
- let(:url) { 'http://sushi.com/sushi/' }
267
+ let(:url) { 'http://httpbingo.org/get/' }
265
268
 
266
269
  it 'parses url and changes scheme' do
267
270
  conn.scheme = 'https'
268
271
  uri = conn.build_exclusive_url('sake.html')
269
- expect(uri.to_s).to eq('https://sushi.com/sushi/sake.html')
272
+ expect(uri.to_s).to eq('https://httpbingo.org/get/sake.html')
270
273
  end
271
274
 
272
275
  it 'joins url to base with ending slash' do
273
276
  uri = conn.build_exclusive_url('sake.html')
274
- expect(uri.to_s).to eq('http://sushi.com/sushi/sake.html')
277
+ expect(uri.to_s).to eq('http://httpbingo.org/get/sake.html')
275
278
  end
276
279
 
277
280
  it 'used default base with ending slash' do
278
281
  uri = conn.build_exclusive_url
279
- expect(uri.to_s).to eq('http://sushi.com/sushi/')
282
+ expect(uri.to_s).to eq('http://httpbingo.org/get/')
280
283
  end
281
284
 
282
285
  it 'overrides base' do
283
286
  uri = conn.build_exclusive_url('/sake/')
284
- expect(uri.to_s).to eq('http://sushi.com/sake/')
287
+ expect(uri.to_s).to eq('http://httpbingo.org/sake/')
285
288
  end
286
289
  end
287
290
 
@@ -297,35 +300,83 @@ RSpec.describe Faraday::Connection do
297
300
  it 'joins url to base when used relative path' do
298
301
  conn = Faraday.new(url: url)
299
302
  uri = conn.build_exclusive_url('service:search?limit=400')
300
- expect(uri.to_s).to eq('http://service.com/service%3Asearch?limit=400')
303
+ expect(uri.to_s).to eq('http://service.com/service:search?limit=400')
301
304
  end
302
305
 
303
306
  it 'joins url to base when used with path prefix' do
304
307
  conn = Faraday.new(url: url)
305
308
  conn.path_prefix = '/api'
306
309
  uri = conn.build_exclusive_url('service:search?limit=400')
307
- expect(uri.to_s).to eq('http://service.com/api/service%3Asearch?limit=400')
310
+ expect(uri.to_s).to eq('http://service.com/api/service:search?limit=400')
311
+ end
312
+ end
313
+
314
+ context 'with protocol-relative URL (GHSA-33mh-2634-fwr2)' do
315
+ it 'does not allow host override with //evil.com/path' do
316
+ conn.url_prefix = 'http://httpbingo.org/api'
317
+ uri = conn.build_exclusive_url('//evil.com/path')
318
+ expect(uri.host).to eq('httpbingo.org')
319
+ end
320
+
321
+ it 'does not allow host override with //evil.com:8080/path' do
322
+ conn.url_prefix = 'http://httpbingo.org/api'
323
+ uri = conn.build_exclusive_url('//evil.com:8080/path')
324
+ expect(uri.host).to eq('httpbingo.org')
325
+ end
326
+
327
+ it 'does not allow host override with //user:pass@evil.com/path' do
328
+ conn.url_prefix = 'http://httpbingo.org/api'
329
+ uri = conn.build_exclusive_url('//user:pass@evil.com/path')
330
+ expect(uri.host).to eq('httpbingo.org')
331
+ end
332
+
333
+ it 'does not allow host override with ///evil.com' do
334
+ conn.url_prefix = 'http://httpbingo.org/api'
335
+ uri = conn.build_exclusive_url('///evil.com')
336
+ expect(uri.host).to eq('httpbingo.org')
337
+ end
338
+
339
+ it 'still allows single-slash absolute paths' do
340
+ conn.url_prefix = 'http://httpbingo.org/api'
341
+ uri = conn.build_exclusive_url('/safe/path')
342
+ expect(uri.host).to eq('httpbingo.org')
343
+ expect(uri.path).to eq('/safe/path')
344
+ end
345
+ end
346
+
347
+ context 'with a custom `default_uri_parser`' do
348
+ let(:url) { 'http://httpbingo.org' }
349
+ let(:parser) { Addressable::URI }
350
+
351
+ around do |example|
352
+ with_default_uri_parser(parser) do
353
+ example.run
354
+ end
355
+ end
356
+
357
+ it 'does not raise error' do
358
+ expect { conn.build_exclusive_url('/nigiri') }.not_to raise_error
308
359
  end
309
360
  end
310
361
  end
311
362
 
312
363
  describe '#build_url' do
313
- let(:url) { 'http://sushi.com/nigiri' }
364
+ let(:url) { 'http://httpbingo.org/nigiri' }
314
365
 
315
366
  it 'uses params' do
316
367
  conn.params = { a: 1, b: 1 }
317
- expect(conn.build_url.to_s).to eq('http://sushi.com/nigiri?a=1&b=1')
368
+ expect(conn.build_url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=1')
318
369
  end
319
370
 
320
371
  it 'merges params' do
321
372
  conn.params = { a: 1, b: 1 }
322
373
  url = conn.build_url(nil, b: 2, c: 3)
323
- expect(url.to_s).to eq('http://sushi.com/nigiri?a=1&b=2&c=3')
374
+ expect(url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=2&c=3')
324
375
  end
325
376
  end
326
377
 
327
378
  describe '#build_request' do
328
- let(:url) { 'https://asushi.com/sake.html' }
379
+ let(:url) { 'https://ahttpbingo.org/sake.html' }
329
380
  let(:request) { conn.build_request(:get) }
330
381
 
331
382
  before do
@@ -342,7 +393,7 @@ RSpec.describe Faraday::Connection do
342
393
  describe '#to_env' do
343
394
  subject { conn.build_request(:get).to_env(conn).url }
344
395
 
345
- let(:url) { 'http://sushi.com/sake.html' }
396
+ let(:url) { 'http://httpbingo.org/sake.html' }
346
397
  let(:options) { { params: @params } }
347
398
 
348
399
  it 'parses url params into query' do
@@ -508,7 +559,7 @@ RSpec.describe Faraday::Connection do
508
559
  it 'uses env http_proxy' do
509
560
  with_env 'http_proxy' => 'http://proxy.com' do
510
561
  conn = Faraday.new
511
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
562
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
512
563
  expect(conn.proxy_for_request('http://google.co.uk').host).to eq('proxy.com')
513
564
  end
514
565
  end
@@ -516,7 +567,7 @@ RSpec.describe Faraday::Connection do
516
567
  it 'uses processes no_proxy before http_proxy' do
517
568
  with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'google.co.uk' do
518
569
  conn = Faraday.new
519
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
570
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
520
571
  expect(conn.proxy_for_request('http://google.co.uk')).to be_nil
521
572
  end
522
573
  end
@@ -524,7 +575,7 @@ RSpec.describe Faraday::Connection do
524
575
  it 'uses env https_proxy' do
525
576
  with_env 'https_proxy' => 'https://proxy.com' do
526
577
  conn = Faraday.new
527
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
578
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
528
579
  expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy.com')
529
580
  end
530
581
  end
@@ -532,7 +583,7 @@ RSpec.describe Faraday::Connection do
532
583
  it 'uses processes no_proxy before https_proxy' do
533
584
  with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do
534
585
  conn = Faraday.new
535
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
586
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
536
587
  expect(conn.proxy_for_request('https://google.co.uk')).to be_nil
537
588
  end
538
589
  end
@@ -542,7 +593,7 @@ RSpec.describe Faraday::Connection do
542
593
  conn = Faraday.new
543
594
  conn.proxy = 'http://proxy2.com'
544
595
 
545
- expect(conn.instance_variable_get('@manual_proxy')).to be_truthy
596
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_truthy
546
597
  expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy2.com')
547
598
  end
548
599
  end
@@ -556,26 +607,32 @@ RSpec.describe Faraday::Connection do
556
607
  end
557
608
 
558
609
  context 'performing a request' do
559
- before { stub_request(:get, 'http://example.com') }
610
+ let(:url) { 'http://example.com' }
611
+ let(:conn) do
612
+ Faraday.new do |f|
613
+ f.adapter :test do |stubs|
614
+ stubs.get(url) do
615
+ [200, {}, 'ok']
616
+ end
617
+ end
618
+ end
619
+ end
560
620
 
561
621
  it 'dynamically checks proxy' do
562
622
  with_env 'http_proxy' => 'http://proxy.com:80' do
563
- conn = Faraday.new
564
623
  expect(conn.proxy.uri.host).to eq('proxy.com')
565
624
 
566
- conn.get('http://example.com') do |req|
625
+ conn.get(url) do |req|
567
626
  expect(req.options.proxy.uri.host).to eq('proxy.com')
568
627
  end
569
628
  end
570
629
 
571
- conn.get('http://example.com')
572
- expect(conn.instance_variable_get('@temp_proxy')).to be_nil
630
+ conn.get(url)
631
+ expect(conn.instance_variable_get(:@temp_proxy)).to be_nil
573
632
  end
574
633
 
575
634
  it 'dynamically check no proxy' do
576
635
  with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
577
- conn = Faraday.new
578
-
579
636
  expect(conn.proxy.uri.host).to eq('proxy.com')
580
637
 
581
638
  conn.get('http://example.com') do |req|
@@ -589,7 +646,7 @@ RSpec.describe Faraday::Connection do
589
646
  describe '#dup' do
590
647
  subject { conn.dup }
591
648
 
592
- let(:url) { 'http://sushi.com/foo' }
649
+ let(:url) { 'http://httpbingo.org/foo' }
593
650
  let(:options) do
594
651
  {
595
652
  ssl: { verify: :none },
@@ -605,7 +662,6 @@ RSpec.describe Faraday::Connection do
605
662
 
606
663
  context 'after manual changes' do
607
664
  before do
608
- subject.basic_auth('', '')
609
665
  subject.headers['content-length'] = 12
610
666
  subject.params['b'] = '2'
611
667
  subject.options[:open_timeout] = 10
@@ -640,14 +696,42 @@ RSpec.describe Faraday::Connection do
640
696
 
641
697
  it_behaves_like 'default connection options'
642
698
  end
699
+
700
+ context 'preserving a user_agent assigned via default_conncetion_options' do
701
+ around do |example|
702
+ old = Faraday.default_connection_options
703
+ Faraday.default_connection_options = { headers: { user_agent: 'My Agent 1.2' } }
704
+ example.run
705
+ Faraday.default_connection_options = old
706
+ end
707
+
708
+ context 'when url is a Hash' do
709
+ let(:conn) { Faraday.new(url: 'http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) }
710
+
711
+ it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') }
712
+ end
713
+
714
+ context 'when url is a String' do
715
+ let(:conn) { Faraday.new('http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) }
716
+
717
+ it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') }
718
+ end
719
+ end
643
720
  end
644
721
 
645
722
  describe 'request params' do
646
723
  context 'with simple url' do
647
724
  let(:url) { 'http://example.com' }
648
- let!(:stubbed) { stub_request(:get, 'http://example.com?a=a&p=3') }
725
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
726
+
727
+ before do
728
+ conn.adapter(:test, stubs)
729
+ stubs.get('http://example.com?a=a&p=3') do
730
+ [200, {}, 'ok']
731
+ end
732
+ end
649
733
 
650
- after { expect(stubbed).to have_been_made.once }
734
+ after { stubs.verify_stubbed_calls }
651
735
 
652
736
  it 'test_overrides_request_params' do
653
737
  conn.get('?p=2&a=a', p: 3)
@@ -669,15 +753,22 @@ RSpec.describe Faraday::Connection do
669
753
  context 'with url and extra params' do
670
754
  let(:url) { 'http://example.com?a=1&b=2' }
671
755
  let(:options) { { params: { c: 3 } } }
756
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
757
+
758
+ before do
759
+ conn.adapter(:test, stubs)
760
+ end
672
761
 
673
762
  it 'merges connection and request params' do
674
- stubbed = stub_request(:get, 'http://example.com?a=1&b=2&c=3&limit=5&page=1')
763
+ expected = 'http://example.com?a=1&b=2&c=3&limit=5&page=1'
764
+ stubs.get(expected) { [200, {}, 'ok'] }
675
765
  conn.get('?page=1', limit: 5)
676
- expect(stubbed).to have_been_made.once
766
+ stubs.verify_stubbed_calls
677
767
  end
678
768
 
679
769
  it 'allows to override all params' do
680
- stubbed = stub_request(:get, 'http://example.com?b=b')
770
+ expected = 'http://example.com?b=b'
771
+ stubs.get(expected) { [200, {}, 'ok'] }
681
772
  conn.get('?p=1&a=a', p: 2) do |req|
682
773
  expect(req.params[:a]).to eq('a')
683
774
  expect(req.params['c']).to eq(3)
@@ -685,47 +776,61 @@ RSpec.describe Faraday::Connection do
685
776
  req.params = { b: 'b' }
686
777
  expect(req.params['b']).to eq('b')
687
778
  end
688
- expect(stubbed).to have_been_made.once
779
+ stubs.verify_stubbed_calls
689
780
  end
690
781
 
691
782
  it 'allows to set params_encoder for single request' do
692
- encoder = Object.new
693
- def encoder.encode(params)
694
- params.map { |k, v| "#{k.upcase}-#{v.to_s.upcase}" }.join(',')
695
- end
696
- stubbed = stub_request(:get, 'http://example.com/?A-1,B-2,C-3,FEELING-BLUE')
783
+ encoder = CustomEncoder.new
784
+ expected = 'http://example.com/?A-1,B-2,C-3,FEELING-BLUE'
785
+ stubs.get(expected) { [200, {}, 'ok'] }
697
786
 
698
- conn.get('/', feeling: 'blue') do |req|
787
+ conn.get('/', a: 1, b: 2, c: 3, feeling: 'blue') do |req|
699
788
  req.options.params_encoder = encoder
700
789
  end
701
- expect(stubbed).to have_been_made.once
790
+ stubs.verify_stubbed_calls
702
791
  end
703
792
  end
704
793
 
705
794
  context 'with default params encoder' do
706
- let!(:stubbed) { stub_request(:get, 'http://example.com?color%5B%5D=red&color%5B%5D=blue') }
707
- after { expect(stubbed).to have_been_made.once }
795
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
796
+
797
+ before do
798
+ conn.adapter(:test, stubs)
799
+ stubs.get('http://example.com?color%5B%5D=blue&color%5B%5D=red') do
800
+ [200, {}, 'ok']
801
+ end
802
+ end
803
+
804
+ after { stubs.verify_stubbed_calls }
708
805
 
709
806
  it 'supports array params in url' do
710
- conn.get('http://example.com?color[]=red&color[]=blue')
807
+ conn.get('http://example.com?color[]=blue&color[]=red')
711
808
  end
712
809
 
713
810
  it 'supports array params in params' do
714
- conn.get('http://example.com', color: %w[red blue])
811
+ conn.get('http://example.com', color: %w[blue red])
715
812
  end
716
813
  end
717
814
 
718
815
  context 'with flat params encoder' do
719
816
  let(:options) { { request: { params_encoder: Faraday::FlatParamsEncoder } } }
720
- let!(:stubbed) { stub_request(:get, 'http://example.com?color=blue') }
721
- after { expect(stubbed).to have_been_made.once }
817
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
818
+
819
+ before do
820
+ conn.adapter(:test, stubs)
821
+ stubs.get('http://example.com?color=blue&color=red') do
822
+ [200, {}, 'ok']
823
+ end
824
+ end
825
+
826
+ after { stubs.verify_stubbed_calls }
722
827
 
723
828
  it 'supports array params in params' do
724
- conn.get('http://example.com', color: %w[red blue])
829
+ conn.get('http://example.com', color: %w[blue red])
725
830
  end
726
831
 
727
832
  context 'with array param in url' do
728
- let(:url) { 'http://example.com?color[]=red&color[]=blue' }
833
+ let(:url) { 'http://example.com?color[]=blue&color[]=red' }
729
834
 
730
835
  it do
731
836
  conn.get('/')