faraday 1.0.0 → 2.9.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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +299 -1
  3. data/LICENSE.md +1 -1
  4. data/README.md +35 -23
  5. data/Rakefile +3 -1
  6. data/examples/client_spec.rb +68 -14
  7. data/examples/client_test.rb +80 -15
  8. data/lib/faraday/adapter/test.rb +117 -52
  9. data/lib/faraday/adapter.rb +6 -20
  10. data/lib/faraday/adapter_registry.rb +3 -1
  11. data/lib/faraday/connection.rb +73 -132
  12. data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
  13. data/lib/faraday/encoders/nested_params_encoder.rb +20 -8
  14. data/lib/faraday/error.rb +37 -8
  15. data/lib/faraday/logging/formatter.rb +28 -15
  16. data/lib/faraday/methods.rb +6 -0
  17. data/lib/faraday/middleware.rb +17 -5
  18. data/lib/faraday/middleware_registry.rb +17 -63
  19. data/lib/faraday/options/connection_options.rb +7 -6
  20. data/lib/faraday/options/env.rb +85 -62
  21. data/lib/faraday/options/proxy_options.rb +11 -3
  22. data/lib/faraday/options/request_options.rb +7 -6
  23. data/lib/faraday/options/ssl_options.rb +56 -45
  24. data/lib/faraday/options.rb +11 -14
  25. data/lib/faraday/rack_builder.rb +35 -32
  26. data/lib/faraday/request/authorization.rb +37 -36
  27. data/lib/faraday/request/instrumentation.rb +5 -1
  28. data/lib/faraday/request/json.rb +70 -0
  29. data/lib/faraday/request/url_encoded.rb +8 -2
  30. data/lib/faraday/request.rb +22 -29
  31. data/lib/faraday/response/json.rb +73 -0
  32. data/lib/faraday/response/logger.rb +8 -4
  33. data/lib/faraday/response/raise_error.rb +41 -3
  34. data/lib/faraday/response.rb +10 -23
  35. data/lib/faraday/utils/headers.rb +9 -4
  36. data/lib/faraday/utils.rb +22 -10
  37. data/lib/faraday/version.rb +5 -0
  38. data/lib/faraday.rb +49 -58
  39. data/spec/faraday/adapter/test_spec.rb +442 -0
  40. data/spec/faraday/connection_spec.rb +207 -90
  41. data/spec/faraday/error_spec.rb +45 -5
  42. data/spec/faraday/middleware_registry_spec.rb +31 -0
  43. data/spec/faraday/middleware_spec.rb +50 -6
  44. data/spec/faraday/options/env_spec.rb +8 -2
  45. data/spec/faraday/options/options_spec.rb +1 -1
  46. data/spec/faraday/options/proxy_options_spec.rb +15 -0
  47. data/spec/faraday/params_encoders/flat_spec.rb +8 -0
  48. data/spec/faraday/params_encoders/nested_spec.rb +16 -0
  49. data/spec/faraday/rack_builder_spec.rb +171 -50
  50. data/spec/faraday/request/authorization_spec.rb +54 -24
  51. data/spec/faraday/request/instrumentation_spec.rb +5 -7
  52. data/spec/faraday/request/json_spec.rb +199 -0
  53. data/spec/faraday/request/url_encoded_spec.rb +25 -2
  54. data/spec/faraday/request_spec.rb +11 -10
  55. data/spec/faraday/response/json_spec.rb +189 -0
  56. data/spec/faraday/response/logger_spec.rb +38 -0
  57. data/spec/faraday/response/raise_error_spec.rb +105 -0
  58. data/spec/faraday/response_spec.rb +3 -1
  59. data/spec/faraday/utils/headers_spec.rb +22 -4
  60. data/spec/faraday/utils_spec.rb +63 -1
  61. data/spec/faraday_spec.rb +8 -4
  62. data/spec/spec_helper.rb +6 -5
  63. data/spec/support/fake_safe_buffer.rb +1 -1
  64. data/spec/support/helper_methods.rb +0 -37
  65. data/spec/support/shared_examples/adapter.rb +4 -3
  66. data/spec/support/shared_examples/request_method.rb +60 -31
  67. metadata +19 -44
  68. data/UPGRADING.md +0 -55
  69. data/lib/faraday/adapter/em_http.rb +0 -285
  70. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
  71. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
  72. data/lib/faraday/adapter/em_synchrony.rb +0 -150
  73. data/lib/faraday/adapter/excon.rb +0 -124
  74. data/lib/faraday/adapter/httpclient.rb +0 -151
  75. data/lib/faraday/adapter/net_http.rb +0 -209
  76. data/lib/faraday/adapter/net_http_persistent.rb +0 -91
  77. data/lib/faraday/adapter/patron.rb +0 -132
  78. data/lib/faraday/adapter/rack.rb +0 -75
  79. data/lib/faraday/adapter/typhoeus.rb +0 -15
  80. data/lib/faraday/autoload.rb +0 -95
  81. data/lib/faraday/dependency_loader.rb +0 -37
  82. data/lib/faraday/file_part.rb +0 -128
  83. data/lib/faraday/param_part.rb +0 -53
  84. data/lib/faraday/request/basic_authentication.rb +0 -20
  85. data/lib/faraday/request/multipart.rb +0 -99
  86. data/lib/faraday/request/retry.rb +0 -239
  87. data/lib/faraday/request/token_authentication.rb +0 -20
  88. data/spec/faraday/adapter/em_http_spec.rb +0 -47
  89. data/spec/faraday/adapter/em_synchrony_spec.rb +0 -16
  90. data/spec/faraday/adapter/excon_spec.rb +0 -49
  91. data/spec/faraday/adapter/httpclient_spec.rb +0 -73
  92. data/spec/faraday/adapter/net_http_persistent_spec.rb +0 -57
  93. data/spec/faraday/adapter/net_http_spec.rb +0 -64
  94. data/spec/faraday/adapter/patron_spec.rb +0 -18
  95. data/spec/faraday/adapter/rack_spec.rb +0 -8
  96. data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
  97. data/spec/faraday/composite_read_io_spec.rb +0 -80
  98. data/spec/faraday/request/multipart_spec.rb +0 -274
  99. data/spec/faraday/request/retry_spec.rb +0 -242
  100. data/spec/faraday/response/middleware_spec.rb +0 -52
  101. 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,29 +22,36 @@ 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') }
19
29
  it { expect(subject.params).to eq('a' => '1') }
20
30
  end
31
+
32
+ context 'with IPv6 address' do
33
+ let(:address) { 'http://[::1]:85/' }
34
+
35
+ it { expect(subject.host).to eq('[::1]') }
36
+ it { expect(subject.port).to eq(85) }
37
+ end
21
38
  end
22
39
 
23
40
  shared_examples 'default connection options' do
24
41
  after { Faraday.default_connection_options = nil }
25
42
 
26
43
  it 'works with implicit url' do
27
- conn = Faraday.new 'http://sushi.com/foo'
44
+ conn = Faraday.new 'http://httpbingo.org/foo'
28
45
  expect(conn.options.timeout).to eq(10)
29
46
  end
30
47
 
31
48
  it 'works with option url' do
32
- conn = Faraday.new url: 'http://sushi.com/foo'
49
+ conn = Faraday.new url: 'http://httpbingo.org/foo'
33
50
  expect(conn.options.timeout).to eq(10)
34
51
  end
35
52
 
36
53
  it 'works with instance connection options' do
37
- conn = Faraday.new 'http://sushi.com/foo', request: { open_timeout: 1 }
54
+ conn = Faraday.new 'http://httpbingo.org/foo', request: { open_timeout: 1 }
38
55
  expect(conn.options.timeout).to eq(10)
39
56
  expect(conn.options.open_timeout).to eq(1)
40
57
  end
@@ -44,7 +61,7 @@ shared_examples 'default connection options' do
44
61
  conn.options.timeout = 1
45
62
  expect(Faraday.default_connection_options.request.timeout).to eq(10)
46
63
 
47
- other = Faraday.new url: 'https://sushi.com/foo'
64
+ other = Faraday.new url: 'https://httpbingo.org/foo'
48
65
  other.options.timeout = 1
49
66
 
50
67
  expect(Faraday.default_connection_options.request.timeout).to eq(10)
@@ -64,14 +81,14 @@ RSpec.describe Faraday::Connection do
64
81
  subject { conn }
65
82
 
66
83
  context 'with implicit url param' do
67
- # Faraday::Connection.new('http://sushi.com')
84
+ # Faraday::Connection.new('http://httpbingo.org')
68
85
  let(:url) { address }
69
86
 
70
87
  it_behaves_like 'initializer with url'
71
88
  end
72
89
 
73
90
  context 'with explicit url param' do
74
- # Faraday::Connection.new(url: 'http://sushi.com')
91
+ # Faraday::Connection.new(url: 'http://httpbingo.org')
75
92
  let(:url) { { url: address } }
76
93
 
77
94
  it_behaves_like 'initializer with url'
@@ -91,11 +108,17 @@ RSpec.describe Faraday::Connection do
91
108
  end
92
109
 
93
110
  context 'with custom params and params in url' do
94
- let(:url) { 'http://sushi.com/fish?a=1&b=2' }
111
+ let(:url) { 'http://httpbingo.org/fish?a=1&b=2' }
95
112
  let(:options) { { params: { a: 3 } } }
96
113
  it { expect(subject.params).to eq('a' => 3, 'b' => '2') }
97
114
  end
98
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
+
99
122
  context 'with custom headers' do
100
123
  let(:options) { { headers: { user_agent: 'Faraday' } } }
101
124
 
@@ -108,6 +131,12 @@ RSpec.describe Faraday::Connection do
108
131
  it { expect(subject.ssl.verify?).to be_falsey }
109
132
  end
110
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
+
111
140
  context 'with empty block' do
112
141
  let(:conn) { Faraday::Connection.new {} }
113
142
 
@@ -117,8 +146,8 @@ RSpec.describe Faraday::Connection do
117
146
  context 'with block' do
118
147
  let(:conn) do
119
148
  Faraday::Connection.new(params: { 'a' => '1' }) do |faraday|
120
- faraday.adapter :net_http
121
- faraday.url_prefix = 'http://sushi.com/omnom'
149
+ faraday.adapter :test
150
+ faraday.url_prefix = 'http://httpbingo.org/omnom'
122
151
  end
123
152
  end
124
153
 
@@ -128,41 +157,22 @@ RSpec.describe Faraday::Connection do
128
157
  end
129
158
 
130
159
  describe '#close' do
160
+ before { Faraday.default_adapter = :test }
161
+ after { Faraday.default_adapter = nil }
162
+
131
163
  it 'can close underlying app' do
132
164
  expect(conn.app).to receive(:close)
133
165
  conn.close
134
166
  end
135
167
  end
136
168
 
137
- describe 'basic_auth' do
138
- subject { conn }
139
-
140
- context 'calling the #basic_auth method' do
141
- before { subject.basic_auth 'Aladdin', 'open sesame' }
142
-
143
- it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
144
- end
145
-
146
- context 'adding basic auth info to url' do
147
- let(:url) { 'http://Aladdin:open%20sesame@sushi.com/fish' }
148
-
149
- it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
150
- end
151
- end
152
-
153
- describe '#token_auth' do
154
- before { subject.token_auth('abcdef', nonce: 'abc') }
155
-
156
- it { expect(subject.headers['Authorization']).to eq('Token nonce="abc", token="abcdef"') }
157
- end
158
-
159
169
  describe '#build_exclusive_url' do
160
170
  context 'with relative path' do
161
171
  subject { conn.build_exclusive_url('sake.html') }
162
172
 
163
173
  it 'uses connection host as default host' do
164
- conn.host = 'sushi.com'
165
- expect(subject.host).to eq('sushi.com')
174
+ conn.host = 'httpbingo.org'
175
+ expect(subject.host).to eq('httpbingo.org')
166
176
  expect(subject.scheme).to eq('http')
167
177
  end
168
178
 
@@ -199,10 +209,10 @@ RSpec.describe Faraday::Connection do
199
209
  end
200
210
 
201
211
  context 'with complete url' do
202
- 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') }
203
213
 
204
214
  it { expect(subject.scheme).to eq('http') }
205
- it { expect(subject.host).to eq('sushi.com') }
215
+ it { expect(subject.host).to eq('httpbingo.org') }
206
216
  it { expect(subject.port).to eq(80) }
207
217
  it { expect(subject.path).to eq('/sake.html') }
208
218
  it { expect(subject.query).to eq('a=1') }
@@ -210,35 +220,35 @@ RSpec.describe Faraday::Connection do
210
220
 
211
221
  it 'overrides connection port for absolute url' do
212
222
  conn.port = 23
213
- uri = conn.build_exclusive_url('http://sushi.com')
223
+ uri = conn.build_exclusive_url('http://httpbingo.org')
214
224
  expect(uri.port).to eq(80)
215
225
  end
216
226
 
217
227
  it 'does not add ending slash given nil url' do
218
- conn.url_prefix = 'http://sushi.com/nigiri'
228
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
219
229
  uri = conn.build_exclusive_url
220
230
  expect(uri.path).to eq('/nigiri')
221
231
  end
222
232
 
223
233
  it 'does not add ending slash given empty url' do
224
- conn.url_prefix = 'http://sushi.com/nigiri'
234
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
225
235
  uri = conn.build_exclusive_url('')
226
236
  expect(uri.path).to eq('/nigiri')
227
237
  end
228
238
 
229
239
  it 'does not use connection params' do
230
- conn.url_prefix = 'http://sushi.com/nigiri'
240
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
231
241
  conn.params = { a: 1 }
232
- 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')
233
243
  end
234
244
 
235
245
  it 'allows to provide params argument' do
236
- conn.url_prefix = 'http://sushi.com/nigiri'
246
+ conn.url_prefix = 'http://httpbingo.org/nigiri'
237
247
  conn.params = { a: 1 }
238
248
  params = Faraday::Utils::ParamsHash.new
239
249
  params[:a] = 2
240
250
  uri = conn.build_exclusive_url(nil, params)
241
- 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')
242
252
  end
243
253
 
244
254
  it 'handles uri instances' do
@@ -246,49 +256,94 @@ RSpec.describe Faraday::Connection do
246
256
  expect(uri.path).to eq('/sake.html')
247
257
  end
248
258
 
259
+ it 'always returns new URI instance' do
260
+ conn.url_prefix = 'http://httpbingo.org'
261
+ uri1 = conn.build_exclusive_url(nil)
262
+ uri2 = conn.build_exclusive_url(nil)
263
+ expect(uri1).not_to equal(uri2)
264
+ end
265
+
249
266
  context 'with url_prefixed connection' do
250
- let(:url) { 'http://sushi.com/sushi/' }
267
+ let(:url) { 'http://httpbingo.org/get/' }
251
268
 
252
269
  it 'parses url and changes scheme' do
253
270
  conn.scheme = 'https'
254
271
  uri = conn.build_exclusive_url('sake.html')
255
- 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')
256
273
  end
257
274
 
258
275
  it 'joins url to base with ending slash' do
259
276
  uri = conn.build_exclusive_url('sake.html')
260
- 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')
261
278
  end
262
279
 
263
280
  it 'used default base with ending slash' do
264
281
  uri = conn.build_exclusive_url
265
- expect(uri.to_s).to eq('http://sushi.com/sushi/')
282
+ expect(uri.to_s).to eq('http://httpbingo.org/get/')
266
283
  end
267
284
 
268
285
  it 'overrides base' do
269
286
  uri = conn.build_exclusive_url('/sake/')
270
- expect(uri.to_s).to eq('http://sushi.com/sake/')
287
+ expect(uri.to_s).to eq('http://httpbingo.org/sake/')
288
+ end
289
+ end
290
+
291
+ context 'with colon in path' do
292
+ let(:url) { 'http://service.com' }
293
+
294
+ it 'joins url to base when used absolute path' do
295
+ conn = Faraday.new(url: url)
296
+ uri = conn.build_exclusive_url('/service:search?limit=400')
297
+ expect(uri.to_s).to eq('http://service.com/service:search?limit=400')
298
+ end
299
+
300
+ it 'joins url to base when used relative path' do
301
+ conn = Faraday.new(url: url)
302
+ uri = conn.build_exclusive_url('service:search?limit=400')
303
+ expect(uri.to_s).to eq('http://service.com/service%3Asearch?limit=400')
304
+ end
305
+
306
+ it 'joins url to base when used with path prefix' do
307
+ conn = Faraday.new(url: url)
308
+ conn.path_prefix = '/api'
309
+ uri = conn.build_exclusive_url('service:search?limit=400')
310
+ expect(uri.to_s).to eq('http://service.com/api/service%3Asearch?limit=400')
311
+ end
312
+ end
313
+
314
+ context 'with a custom `default_uri_parser`' do
315
+ let(:url) { 'http://httpbingo.org' }
316
+ let(:parser) { Addressable::URI }
317
+
318
+ around do |example|
319
+ with_default_uri_parser(parser) do
320
+ example.run
321
+ end
322
+ end
323
+
324
+ it 'does not raise error' do
325
+ expect { conn.build_exclusive_url('/nigiri') }.not_to raise_error
271
326
  end
272
327
  end
273
328
  end
274
329
 
275
330
  describe '#build_url' do
276
- let(:url) { 'http://sushi.com/nigiri' }
331
+ let(:url) { 'http://httpbingo.org/nigiri' }
277
332
 
278
333
  it 'uses params' do
279
334
  conn.params = { a: 1, b: 1 }
280
- expect(conn.build_url.to_s).to eq('http://sushi.com/nigiri?a=1&b=1')
335
+ expect(conn.build_url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=1')
281
336
  end
282
337
 
283
338
  it 'merges params' do
284
339
  conn.params = { a: 1, b: 1 }
285
340
  url = conn.build_url(nil, b: 2, c: 3)
286
- expect(url.to_s).to eq('http://sushi.com/nigiri?a=1&b=2&c=3')
341
+ expect(url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=2&c=3')
287
342
  end
288
343
  end
289
344
 
290
345
  describe '#build_request' do
291
- let(:url) { 'https://asushi.com/sake.html' }
346
+ let(:url) { 'https://ahttpbingo.org/sake.html' }
292
347
  let(:request) { conn.build_request(:get) }
293
348
 
294
349
  before do
@@ -305,7 +360,7 @@ RSpec.describe Faraday::Connection do
305
360
  describe '#to_env' do
306
361
  subject { conn.build_request(:get).to_env(conn).url }
307
362
 
308
- let(:url) { 'http://sushi.com/sake.html' }
363
+ let(:url) { 'http://httpbingo.org/sake.html' }
309
364
  let(:options) { { params: @params } }
310
365
 
311
366
  it 'parses url params into query' do
@@ -412,6 +467,14 @@ RSpec.describe Faraday::Connection do
412
467
  end
413
468
  end
414
469
 
470
+ it 'allows when url in no proxy list with url_prefix' do
471
+ with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
472
+ conn = Faraday::Connection.new
473
+ conn.url_prefix = 'http://example.com'
474
+ expect(conn.proxy).to be_nil
475
+ end
476
+ end
477
+
415
478
  it 'allows when prefixed url is not in no proxy list' do
416
479
  with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
417
480
  conn = Faraday::Connection.new('http://prefixedexample.com')
@@ -463,7 +526,7 @@ RSpec.describe Faraday::Connection do
463
526
  it 'uses env http_proxy' do
464
527
  with_env 'http_proxy' => 'http://proxy.com' do
465
528
  conn = Faraday.new
466
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
529
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
467
530
  expect(conn.proxy_for_request('http://google.co.uk').host).to eq('proxy.com')
468
531
  end
469
532
  end
@@ -471,7 +534,7 @@ RSpec.describe Faraday::Connection do
471
534
  it 'uses processes no_proxy before http_proxy' do
472
535
  with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'google.co.uk' do
473
536
  conn = Faraday.new
474
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
537
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
475
538
  expect(conn.proxy_for_request('http://google.co.uk')).to be_nil
476
539
  end
477
540
  end
@@ -479,7 +542,7 @@ RSpec.describe Faraday::Connection do
479
542
  it 'uses env https_proxy' do
480
543
  with_env 'https_proxy' => 'https://proxy.com' do
481
544
  conn = Faraday.new
482
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
545
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
483
546
  expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy.com')
484
547
  end
485
548
  end
@@ -487,7 +550,7 @@ RSpec.describe Faraday::Connection do
487
550
  it 'uses processes no_proxy before https_proxy' do
488
551
  with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do
489
552
  conn = Faraday.new
490
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
553
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
491
554
  expect(conn.proxy_for_request('https://google.co.uk')).to be_nil
492
555
  end
493
556
  end
@@ -497,7 +560,7 @@ RSpec.describe Faraday::Connection do
497
560
  conn = Faraday.new
498
561
  conn.proxy = 'http://proxy2.com'
499
562
 
500
- expect(conn.instance_variable_get('@manual_proxy')).to be_truthy
563
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_truthy
501
564
  expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy2.com')
502
565
  end
503
566
  end
@@ -511,26 +574,32 @@ RSpec.describe Faraday::Connection do
511
574
  end
512
575
 
513
576
  context 'performing a request' do
514
- before { stub_request(:get, 'http://example.com') }
577
+ let(:url) { 'http://example.com' }
578
+ let(:conn) do
579
+ Faraday.new do |f|
580
+ f.adapter :test do |stubs|
581
+ stubs.get(url) do
582
+ [200, {}, 'ok']
583
+ end
584
+ end
585
+ end
586
+ end
515
587
 
516
588
  it 'dynamically checks proxy' do
517
589
  with_env 'http_proxy' => 'http://proxy.com:80' do
518
- conn = Faraday.new
519
590
  expect(conn.proxy.uri.host).to eq('proxy.com')
520
591
 
521
- conn.get('http://example.com') do |req|
592
+ conn.get(url) do |req|
522
593
  expect(req.options.proxy.uri.host).to eq('proxy.com')
523
594
  end
524
595
  end
525
596
 
526
- conn.get('http://example.com')
527
- expect(conn.instance_variable_get('@temp_proxy')).to be_nil
597
+ conn.get(url)
598
+ expect(conn.instance_variable_get(:@temp_proxy)).to be_nil
528
599
  end
529
600
 
530
601
  it 'dynamically check no proxy' do
531
602
  with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
532
- conn = Faraday.new
533
-
534
603
  expect(conn.proxy.uri.host).to eq('proxy.com')
535
604
 
536
605
  conn.get('http://example.com') do |req|
@@ -544,7 +613,7 @@ RSpec.describe Faraday::Connection do
544
613
  describe '#dup' do
545
614
  subject { conn.dup }
546
615
 
547
- let(:url) { 'http://sushi.com/foo' }
616
+ let(:url) { 'http://httpbingo.org/foo' }
548
617
  let(:options) do
549
618
  {
550
619
  ssl: { verify: :none },
@@ -560,7 +629,6 @@ RSpec.describe Faraday::Connection do
560
629
 
561
630
  context 'after manual changes' do
562
631
  before do
563
- subject.basic_auth('', '')
564
632
  subject.headers['content-length'] = 12
565
633
  subject.params['b'] = '2'
566
634
  subject.options[:open_timeout] = 10
@@ -595,14 +663,42 @@ RSpec.describe Faraday::Connection do
595
663
 
596
664
  it_behaves_like 'default connection options'
597
665
  end
666
+
667
+ context 'preserving a user_agent assigned via default_conncetion_options' do
668
+ around do |example|
669
+ old = Faraday.default_connection_options
670
+ Faraday.default_connection_options = { headers: { user_agent: 'My Agent 1.2' } }
671
+ example.run
672
+ Faraday.default_connection_options = old
673
+ end
674
+
675
+ context 'when url is a Hash' do
676
+ let(:conn) { Faraday.new(url: 'http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) }
677
+
678
+ it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') }
679
+ end
680
+
681
+ context 'when url is a String' do
682
+ let(:conn) { Faraday.new('http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) }
683
+
684
+ it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') }
685
+ end
686
+ end
598
687
  end
599
688
 
600
689
  describe 'request params' do
601
690
  context 'with simple url' do
602
691
  let(:url) { 'http://example.com' }
603
- let!(:stubbed) { stub_request(:get, 'http://example.com?a=a&p=3') }
692
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
604
693
 
605
- after { expect(stubbed).to have_been_made.once }
694
+ before do
695
+ conn.adapter(:test, stubs)
696
+ stubs.get('http://example.com?a=a&p=3') do
697
+ [200, {}, 'ok']
698
+ end
699
+ end
700
+
701
+ after { stubs.verify_stubbed_calls }
606
702
 
607
703
  it 'test_overrides_request_params' do
608
704
  conn.get('?p=2&a=a', p: 3)
@@ -624,15 +720,22 @@ RSpec.describe Faraday::Connection do
624
720
  context 'with url and extra params' do
625
721
  let(:url) { 'http://example.com?a=1&b=2' }
626
722
  let(:options) { { params: { c: 3 } } }
723
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
724
+
725
+ before do
726
+ conn.adapter(:test, stubs)
727
+ end
627
728
 
628
729
  it 'merges connection and request params' do
629
- stubbed = stub_request(:get, 'http://example.com?a=1&b=2&c=3&limit=5&page=1')
730
+ expected = 'http://example.com?a=1&b=2&c=3&limit=5&page=1'
731
+ stubs.get(expected) { [200, {}, 'ok'] }
630
732
  conn.get('?page=1', limit: 5)
631
- expect(stubbed).to have_been_made.once
733
+ stubs.verify_stubbed_calls
632
734
  end
633
735
 
634
736
  it 'allows to override all params' do
635
- stubbed = stub_request(:get, 'http://example.com?b=b')
737
+ expected = 'http://example.com?b=b'
738
+ stubs.get(expected) { [200, {}, 'ok'] }
636
739
  conn.get('?p=1&a=a', p: 2) do |req|
637
740
  expect(req.params[:a]).to eq('a')
638
741
  expect(req.params['c']).to eq(3)
@@ -640,47 +743,61 @@ RSpec.describe Faraday::Connection do
640
743
  req.params = { b: 'b' }
641
744
  expect(req.params['b']).to eq('b')
642
745
  end
643
- expect(stubbed).to have_been_made.once
746
+ stubs.verify_stubbed_calls
644
747
  end
645
748
 
646
749
  it 'allows to set params_encoder for single request' do
647
- encoder = Object.new
648
- def encoder.encode(params)
649
- params.map { |k, v| "#{k.upcase}-#{v.to_s.upcase}" }.join(',')
650
- end
651
- stubbed = stub_request(:get, 'http://example.com/?A-1,B-2,C-3,FEELING-BLUE')
750
+ encoder = CustomEncoder.new
751
+ expected = 'http://example.com/?A-1,B-2,C-3,FEELING-BLUE'
752
+ stubs.get(expected) { [200, {}, 'ok'] }
652
753
 
653
- conn.get('/', feeling: 'blue') do |req|
754
+ conn.get('/', a: 1, b: 2, c: 3, feeling: 'blue') do |req|
654
755
  req.options.params_encoder = encoder
655
756
  end
656
- expect(stubbed).to have_been_made.once
757
+ stubs.verify_stubbed_calls
657
758
  end
658
759
  end
659
760
 
660
761
  context 'with default params encoder' do
661
- let!(:stubbed) { stub_request(:get, 'http://example.com?color%5B%5D=red&color%5B%5D=blue') }
662
- after { expect(stubbed).to have_been_made.once }
762
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
763
+
764
+ before do
765
+ conn.adapter(:test, stubs)
766
+ stubs.get('http://example.com?color%5B%5D=blue&color%5B%5D=red') do
767
+ [200, {}, 'ok']
768
+ end
769
+ end
770
+
771
+ after { stubs.verify_stubbed_calls }
663
772
 
664
773
  it 'supports array params in url' do
665
- conn.get('http://example.com?color[]=red&color[]=blue')
774
+ conn.get('http://example.com?color[]=blue&color[]=red')
666
775
  end
667
776
 
668
777
  it 'supports array params in params' do
669
- conn.get('http://example.com', color: %w[red blue])
778
+ conn.get('http://example.com', color: %w[blue red])
670
779
  end
671
780
  end
672
781
 
673
782
  context 'with flat params encoder' do
674
783
  let(:options) { { request: { params_encoder: Faraday::FlatParamsEncoder } } }
675
- let!(:stubbed) { stub_request(:get, 'http://example.com?color=blue') }
676
- after { expect(stubbed).to have_been_made.once }
784
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
785
+
786
+ before do
787
+ conn.adapter(:test, stubs)
788
+ stubs.get('http://example.com?color=blue&color=red') do
789
+ [200, {}, 'ok']
790
+ end
791
+ end
792
+
793
+ after { stubs.verify_stubbed_calls }
677
794
 
678
795
  it 'supports array params in params' do
679
- conn.get('http://example.com', color: %w[red blue])
796
+ conn.get('http://example.com', color: %w[blue red])
680
797
  end
681
798
 
682
799
  context 'with array param in url' do
683
- let(:url) { 'http://example.com?color[]=red&color[]=blue' }
800
+ let(:url) { 'http://example.com?color[]=blue&color[]=red' }
684
801
 
685
802
  it do
686
803
  conn.get('/')