faraday 1.9.3 → 2.6.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +197 -3
  3. data/LICENSE.md +1 -1
  4. data/README.md +11 -9
  5. data/examples/client_spec.rb +41 -19
  6. data/examples/client_test.rb +48 -22
  7. data/lib/faraday/adapter/test.rb +43 -7
  8. data/lib/faraday/adapter.rb +4 -7
  9. data/lib/faraday/connection.rb +39 -120
  10. data/lib/faraday/encoders/nested_params_encoder.rb +13 -6
  11. data/lib/faraday/error.rb +3 -2
  12. data/lib/faraday/logging/formatter.rb +1 -0
  13. data/lib/faraday/middleware.rb +0 -1
  14. data/lib/faraday/middleware_registry.rb +17 -63
  15. data/lib/faraday/options/env.rb +18 -0
  16. data/lib/faraday/options/ssl_options.rb +11 -1
  17. data/lib/faraday/options.rb +3 -3
  18. data/lib/faraday/rack_builder.rb +23 -20
  19. data/lib/faraday/request/authorization.rb +33 -41
  20. data/lib/faraday/request/instrumentation.rb +2 -0
  21. data/lib/faraday/request/json.rb +55 -0
  22. data/lib/faraday/request/url_encoded.rb +5 -1
  23. data/lib/faraday/request.rb +12 -30
  24. data/lib/faraday/response/json.rb +54 -0
  25. data/lib/faraday/response/logger.rb +4 -4
  26. data/lib/faraday/response/raise_error.rb +9 -1
  27. data/lib/faraday/response.rb +8 -19
  28. data/lib/faraday/utils/headers.rb +1 -1
  29. data/lib/faraday/utils.rb +10 -5
  30. data/lib/faraday/version.rb +1 -1
  31. data/lib/faraday.rb +10 -44
  32. data/spec/faraday/adapter/test_spec.rb +36 -0
  33. data/spec/faraday/connection_spec.rb +148 -91
  34. data/spec/faraday/middleware_registry_spec.rb +31 -0
  35. data/spec/faraday/options/env_spec.rb +8 -2
  36. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  37. data/spec/faraday/rack_builder_spec.rb +26 -54
  38. data/spec/faraday/request/authorization_spec.rb +50 -28
  39. data/spec/faraday/request/instrumentation_spec.rb +5 -7
  40. data/spec/faraday/request/json_spec.rb +111 -0
  41. data/spec/faraday/request/url_encoded_spec.rb +12 -2
  42. data/spec/faraday/request_spec.rb +5 -15
  43. data/spec/faraday/response/json_spec.rb +117 -0
  44. data/spec/faraday/response/raise_error_spec.rb +7 -4
  45. data/spec/faraday/utils/headers_spec.rb +2 -2
  46. data/spec/faraday/utils_spec.rb +63 -1
  47. data/spec/support/fake_safe_buffer.rb +1 -1
  48. data/spec/support/helper_methods.rb +0 -37
  49. data/spec/support/shared_examples/adapter.rb +2 -2
  50. data/spec/support/shared_examples/request_method.rb +22 -21
  51. metadata +18 -149
  52. data/lib/faraday/adapter/typhoeus.rb +0 -15
  53. data/lib/faraday/autoload.rb +0 -87
  54. data/lib/faraday/dependency_loader.rb +0 -37
  55. data/lib/faraday/request/basic_authentication.rb +0 -20
  56. data/lib/faraday/request/token_authentication.rb +0 -20
  57. data/spec/faraday/adapter/em_http_spec.rb +0 -49
  58. data/spec/faraday/adapter/em_synchrony_spec.rb +0 -18
  59. data/spec/faraday/adapter/excon_spec.rb +0 -49
  60. data/spec/faraday/adapter/httpclient_spec.rb +0 -73
  61. data/spec/faraday/adapter/net_http_spec.rb +0 -64
  62. data/spec/faraday/adapter/patron_spec.rb +0 -18
  63. data/spec/faraday/adapter/rack_spec.rb +0 -8
  64. data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
  65. data/spec/faraday/composite_read_io_spec.rb +0 -80
  66. data/spec/faraday/response/middleware_spec.rb +0 -68
  67. data/spec/support/webmock_rack_app.rb +0 -68
@@ -373,5 +373,41 @@ RSpec.describe Faraday::Adapter::Test do
373
373
  it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent' }
374
374
  it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent', x_special: 'special' }
375
375
  end
376
+
377
+ describe 'body_match?' do
378
+ let(:stubs) do
379
+ described_class::Stubs.new do |stubs|
380
+ stubs.post('/no_check') { [200, {}, 'ok'] }
381
+ stubs.post('/with_string', 'abc') { [200, {}, 'ok'] }
382
+ stubs.post(
383
+ '/with_proc',
384
+ ->(request_body) { JSON.parse(request_body, symbolize_names: true) == { x: '!', a: [{ m: [{ a: true }], n: 123 }] } },
385
+ { content_type: 'application/json' }
386
+ ) do
387
+ [200, {}, 'ok']
388
+ end
389
+ end
390
+ end
391
+
392
+ context 'when trying without any args for body' do
393
+ subject(:without_body) { connection.post('/no_check') }
394
+
395
+ it { expect(without_body.status).to eq 200 }
396
+ end
397
+
398
+ context 'when trying with string body stubs' do
399
+ subject(:with_string) { connection.post('/with_string', 'abc') }
400
+
401
+ it { expect(with_string.status).to eq 200 }
402
+ end
403
+
404
+ context 'when trying with proc body stubs' do
405
+ subject(:with_proc) do
406
+ connection.post('/with_proc', JSON.dump(a: [{ n: 123, m: [{ a: true }] }], x: '!'), { 'Content-Type' => 'application/json' })
407
+ end
408
+
409
+ it { expect(with_proc.status).to eq 200 }
410
+ end
411
+ end
376
412
  end
377
413
  end
@@ -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
 
@@ -310,22 +313,22 @@ RSpec.describe Faraday::Connection do
310
313
  end
311
314
 
312
315
  describe '#build_url' do
313
- let(:url) { 'http://sushi.com/nigiri' }
316
+ let(:url) { 'http://httpbingo.org/nigiri' }
314
317
 
315
318
  it 'uses params' do
316
319
  conn.params = { a: 1, b: 1 }
317
- expect(conn.build_url.to_s).to eq('http://sushi.com/nigiri?a=1&b=1')
320
+ expect(conn.build_url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=1')
318
321
  end
319
322
 
320
323
  it 'merges params' do
321
324
  conn.params = { a: 1, b: 1 }
322
325
  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')
326
+ expect(url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=2&c=3')
324
327
  end
325
328
  end
326
329
 
327
330
  describe '#build_request' do
328
- let(:url) { 'https://asushi.com/sake.html' }
331
+ let(:url) { 'https://ahttpbingo.org/sake.html' }
329
332
  let(:request) { conn.build_request(:get) }
330
333
 
331
334
  before do
@@ -342,7 +345,7 @@ RSpec.describe Faraday::Connection do
342
345
  describe '#to_env' do
343
346
  subject { conn.build_request(:get).to_env(conn).url }
344
347
 
345
- let(:url) { 'http://sushi.com/sake.html' }
348
+ let(:url) { 'http://httpbingo.org/sake.html' }
346
349
  let(:options) { { params: @params } }
347
350
 
348
351
  it 'parses url params into query' do
@@ -508,7 +511,7 @@ RSpec.describe Faraday::Connection do
508
511
  it 'uses env http_proxy' do
509
512
  with_env 'http_proxy' => 'http://proxy.com' do
510
513
  conn = Faraday.new
511
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
514
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
512
515
  expect(conn.proxy_for_request('http://google.co.uk').host).to eq('proxy.com')
513
516
  end
514
517
  end
@@ -516,7 +519,7 @@ RSpec.describe Faraday::Connection do
516
519
  it 'uses processes no_proxy before http_proxy' do
517
520
  with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'google.co.uk' do
518
521
  conn = Faraday.new
519
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
522
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
520
523
  expect(conn.proxy_for_request('http://google.co.uk')).to be_nil
521
524
  end
522
525
  end
@@ -524,7 +527,7 @@ RSpec.describe Faraday::Connection do
524
527
  it 'uses env https_proxy' do
525
528
  with_env 'https_proxy' => 'https://proxy.com' do
526
529
  conn = Faraday.new
527
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
530
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
528
531
  expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy.com')
529
532
  end
530
533
  end
@@ -532,7 +535,7 @@ RSpec.describe Faraday::Connection do
532
535
  it 'uses processes no_proxy before https_proxy' do
533
536
  with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do
534
537
  conn = Faraday.new
535
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
538
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
536
539
  expect(conn.proxy_for_request('https://google.co.uk')).to be_nil
537
540
  end
538
541
  end
@@ -542,7 +545,7 @@ RSpec.describe Faraday::Connection do
542
545
  conn = Faraday.new
543
546
  conn.proxy = 'http://proxy2.com'
544
547
 
545
- expect(conn.instance_variable_get('@manual_proxy')).to be_truthy
548
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_truthy
546
549
  expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy2.com')
547
550
  end
548
551
  end
@@ -556,26 +559,32 @@ RSpec.describe Faraday::Connection do
556
559
  end
557
560
 
558
561
  context 'performing a request' do
559
- before { stub_request(:get, 'http://example.com') }
562
+ let(:url) { 'http://example.com' }
563
+ let(:conn) do
564
+ Faraday.new do |f|
565
+ f.adapter :test do |stubs|
566
+ stubs.get(url) do
567
+ [200, {}, 'ok']
568
+ end
569
+ end
570
+ end
571
+ end
560
572
 
561
573
  it 'dynamically checks proxy' do
562
574
  with_env 'http_proxy' => 'http://proxy.com:80' do
563
- conn = Faraday.new
564
575
  expect(conn.proxy.uri.host).to eq('proxy.com')
565
576
 
566
- conn.get('http://example.com') do |req|
577
+ conn.get(url) do |req|
567
578
  expect(req.options.proxy.uri.host).to eq('proxy.com')
568
579
  end
569
580
  end
570
581
 
571
- conn.get('http://example.com')
572
- expect(conn.instance_variable_get('@temp_proxy')).to be_nil
582
+ conn.get(url)
583
+ expect(conn.instance_variable_get(:@temp_proxy)).to be_nil
573
584
  end
574
585
 
575
586
  it 'dynamically check no proxy' do
576
587
  with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
577
- conn = Faraday.new
578
-
579
588
  expect(conn.proxy.uri.host).to eq('proxy.com')
580
589
 
581
590
  conn.get('http://example.com') do |req|
@@ -589,7 +598,7 @@ RSpec.describe Faraday::Connection do
589
598
  describe '#dup' do
590
599
  subject { conn.dup }
591
600
 
592
- let(:url) { 'http://sushi.com/foo' }
601
+ let(:url) { 'http://httpbingo.org/foo' }
593
602
  let(:options) do
594
603
  {
595
604
  ssl: { verify: :none },
@@ -605,7 +614,6 @@ RSpec.describe Faraday::Connection do
605
614
 
606
615
  context 'after manual changes' do
607
616
  before do
608
- subject.basic_auth('', '')
609
617
  subject.headers['content-length'] = 12
610
618
  subject.params['b'] = '2'
611
619
  subject.options[:open_timeout] = 10
@@ -640,14 +648,42 @@ RSpec.describe Faraday::Connection do
640
648
 
641
649
  it_behaves_like 'default connection options'
642
650
  end
651
+
652
+ context 'preserving a user_agent assigned via default_conncetion_options' do
653
+ around do |example|
654
+ old = Faraday.default_connection_options
655
+ Faraday.default_connection_options = { headers: { user_agent: 'My Agent 1.2' } }
656
+ example.run
657
+ Faraday.default_connection_options = old
658
+ end
659
+
660
+ context 'when url is a Hash' do
661
+ let(:conn) { Faraday.new(url: 'http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) }
662
+
663
+ it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') }
664
+ end
665
+
666
+ context 'when url is a String' do
667
+ let(:conn) { Faraday.new('http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) }
668
+
669
+ it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') }
670
+ end
671
+ end
643
672
  end
644
673
 
645
674
  describe 'request params' do
646
675
  context 'with simple url' do
647
676
  let(:url) { 'http://example.com' }
648
- let!(:stubbed) { stub_request(:get, 'http://example.com?a=a&p=3') }
677
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
678
+
679
+ before do
680
+ conn.adapter(:test, stubs)
681
+ stubs.get('http://example.com?a=a&p=3') do
682
+ [200, {}, 'ok']
683
+ end
684
+ end
649
685
 
650
- after { expect(stubbed).to have_been_made.once }
686
+ after { stubs.verify_stubbed_calls }
651
687
 
652
688
  it 'test_overrides_request_params' do
653
689
  conn.get('?p=2&a=a', p: 3)
@@ -669,15 +705,22 @@ RSpec.describe Faraday::Connection do
669
705
  context 'with url and extra params' do
670
706
  let(:url) { 'http://example.com?a=1&b=2' }
671
707
  let(:options) { { params: { c: 3 } } }
708
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
709
+
710
+ before do
711
+ conn.adapter(:test, stubs)
712
+ end
672
713
 
673
714
  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')
715
+ expected = 'http://example.com?a=1&b=2&c=3&limit=5&page=1'
716
+ stubs.get(expected) { [200, {}, 'ok'] }
675
717
  conn.get('?page=1', limit: 5)
676
- expect(stubbed).to have_been_made.once
718
+ stubs.verify_stubbed_calls
677
719
  end
678
720
 
679
721
  it 'allows to override all params' do
680
- stubbed = stub_request(:get, 'http://example.com?b=b')
722
+ expected = 'http://example.com?b=b'
723
+ stubs.get(expected) { [200, {}, 'ok'] }
681
724
  conn.get('?p=1&a=a', p: 2) do |req|
682
725
  expect(req.params[:a]).to eq('a')
683
726
  expect(req.params['c']).to eq(3)
@@ -685,47 +728,61 @@ RSpec.describe Faraday::Connection do
685
728
  req.params = { b: 'b' }
686
729
  expect(req.params['b']).to eq('b')
687
730
  end
688
- expect(stubbed).to have_been_made.once
731
+ stubs.verify_stubbed_calls
689
732
  end
690
733
 
691
734
  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')
735
+ encoder = CustomEncoder.new
736
+ expected = 'http://example.com/?A-1,B-2,C-3,FEELING-BLUE'
737
+ stubs.get(expected) { [200, {}, 'ok'] }
697
738
 
698
- conn.get('/', feeling: 'blue') do |req|
739
+ conn.get('/', a: 1, b: 2, c: 3, feeling: 'blue') do |req|
699
740
  req.options.params_encoder = encoder
700
741
  end
701
- expect(stubbed).to have_been_made.once
742
+ stubs.verify_stubbed_calls
702
743
  end
703
744
  end
704
745
 
705
746
  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 }
747
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
748
+
749
+ before do
750
+ conn.adapter(:test, stubs)
751
+ stubs.get('http://example.com?color%5B%5D=blue&color%5B%5D=red') do
752
+ [200, {}, 'ok']
753
+ end
754
+ end
755
+
756
+ after { stubs.verify_stubbed_calls }
708
757
 
709
758
  it 'supports array params in url' do
710
- conn.get('http://example.com?color[]=red&color[]=blue')
759
+ conn.get('http://example.com?color[]=blue&color[]=red')
711
760
  end
712
761
 
713
762
  it 'supports array params in params' do
714
- conn.get('http://example.com', color: %w[red blue])
763
+ conn.get('http://example.com', color: %w[blue red])
715
764
  end
716
765
  end
717
766
 
718
767
  context 'with flat params encoder' do
719
768
  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 }
769
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
770
+
771
+ before do
772
+ conn.adapter(:test, stubs)
773
+ stubs.get('http://example.com?color=blue&color=red') do
774
+ [200, {}, 'ok']
775
+ end
776
+ end
777
+
778
+ after { stubs.verify_stubbed_calls }
722
779
 
723
780
  it 'supports array params in params' do
724
- conn.get('http://example.com', color: %w[red blue])
781
+ conn.get('http://example.com', color: %w[blue red])
725
782
  end
726
783
 
727
784
  context 'with array param in url' do
728
- let(:url) { 'http://example.com?color[]=red&color[]=blue' }
785
+ let(:url) { 'http://example.com?color[]=blue&color[]=red' }
729
786
 
730
787
  it do
731
788
  conn.get('/')
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::MiddlewareRegistry do
4
+ before do
5
+ stub_const('CustomMiddleware', custom_middleware_klass)
6
+ end
7
+ let(:custom_middleware_klass) { Class.new(Faraday::Middleware) }
8
+ let(:dummy) { Class.new { extend Faraday::MiddlewareRegistry } }
9
+
10
+ after { dummy.unregister_middleware(:custom) }
11
+
12
+ it 'allows to register with constant' do
13
+ dummy.register_middleware(custom: custom_middleware_klass)
14
+ expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass)
15
+ end
16
+
17
+ it 'allows to register with symbol' do
18
+ dummy.register_middleware(custom: :CustomMiddleware)
19
+ expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass)
20
+ end
21
+
22
+ it 'allows to register with string' do
23
+ dummy.register_middleware(custom: 'CustomMiddleware')
24
+ expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass)
25
+ end
26
+
27
+ it 'allows to register with Proc' do
28
+ dummy.register_middleware(custom: -> { custom_middleware_klass })
29
+ expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass)
30
+ end
31
+ end
@@ -27,14 +27,20 @@ RSpec.describe Faraday::Env do
27
27
  expect(ssl.fetch(:verify, true)).to be_falsey
28
28
  end
29
29
 
30
+ it 'handle verify_hostname when fetching' do
31
+ ssl = Faraday::SSLOptions.new
32
+ ssl.verify_hostname = true
33
+ expect(ssl.fetch(:verify_hostname, false)).to be_truthy
34
+ end
35
+
30
36
  it 'retains custom members' do
31
37
  env[:foo] = 'custom 1'
32
- env[:bar] = :custom_2
38
+ env[:bar] = :custom2
33
39
  env2 = Faraday::Env.from(env)
34
40
  env2[:baz] = 'custom 3'
35
41
 
36
42
  expect(env2[:foo]).to eq('custom 1')
37
- expect(env2[:bar]).to eq(:custom_2)
43
+ expect(env2[:bar]).to eq(:custom2)
38
44
  expect(env[:baz]).to be_nil
39
45
  end
40
46
 
@@ -102,6 +102,14 @@ RSpec.describe Faraday::NestedParamsEncoder do
102
102
  Faraday::NestedParamsEncoder.sort_params = true
103
103
  end
104
104
 
105
+ it 'encodes arrays indices when asked' do
106
+ params = { a: [0, 1, 2] }
107
+ expect(subject.encode(params)).to eq('a%5B%5D=0&a%5B%5D=1&a%5B%5D=2')
108
+ Faraday::NestedParamsEncoder.array_indices = true
109
+ expect(subject.encode(params)).to eq('a%5B0%5D=0&a%5B1%5D=1&a%5B2%5D=2')
110
+ Faraday::NestedParamsEncoder.array_indices = false
111
+ end
112
+
105
113
  shared_examples 'a wrong decoding' do
106
114
  it do
107
115
  expect { subject.decode(query) }.to raise_error(TypeError) do |e|