faraday 1.8.0 → 2.7.11

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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +197 -3
  3. data/LICENSE.md +1 -1
  4. data/README.md +34 -20
  5. data/Rakefile +3 -1
  6. data/examples/client_spec.rb +41 -19
  7. data/examples/client_test.rb +48 -22
  8. data/lib/faraday/adapter/test.rb +61 -12
  9. data/lib/faraday/adapter.rb +5 -9
  10. data/lib/faraday/connection.rb +58 -145
  11. data/lib/faraday/encoders/nested_params_encoder.rb +13 -6
  12. data/lib/faraday/error.rb +16 -11
  13. data/lib/faraday/logging/formatter.rb +27 -14
  14. data/lib/faraday/middleware.rb +3 -1
  15. data/lib/faraday/middleware_registry.rb +17 -63
  16. data/lib/faraday/options/connection_options.rb +7 -6
  17. data/lib/faraday/options/env.rb +85 -62
  18. data/lib/faraday/options/proxy_options.rb +7 -3
  19. data/lib/faraday/options/request_options.rb +7 -6
  20. data/lib/faraday/options/ssl_options.rb +56 -45
  21. data/lib/faraday/options.rb +4 -3
  22. data/lib/faraday/rack_builder.rb +23 -20
  23. data/lib/faraday/request/authorization.rb +33 -41
  24. data/lib/faraday/request/instrumentation.rb +5 -1
  25. data/lib/faraday/request/json.rb +64 -0
  26. data/lib/faraday/request/url_encoded.rb +5 -1
  27. data/lib/faraday/request.rb +20 -37
  28. data/lib/faraday/response/json.rb +54 -0
  29. data/lib/faraday/response/logger.rb +8 -4
  30. data/lib/faraday/response/raise_error.rb +29 -4
  31. data/lib/faraday/response.rb +10 -20
  32. data/lib/faraday/utils/headers.rb +7 -2
  33. data/lib/faraday/utils.rb +10 -5
  34. data/lib/faraday/version.rb +1 -1
  35. data/lib/faraday.rb +10 -38
  36. data/spec/faraday/adapter/test_spec.rb +65 -0
  37. data/spec/faraday/connection_spec.rb +163 -91
  38. data/spec/faraday/error_spec.rb +31 -6
  39. data/spec/faraday/middleware_registry_spec.rb +31 -0
  40. data/spec/faraday/middleware_spec.rb +18 -0
  41. data/spec/faraday/options/env_spec.rb +8 -2
  42. data/spec/faraday/options/options_spec.rb +1 -1
  43. data/spec/faraday/options/proxy_options_spec.rb +8 -0
  44. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  45. data/spec/faraday/rack_builder_spec.rb +26 -54
  46. data/spec/faraday/request/authorization_spec.rb +50 -28
  47. data/spec/faraday/request/instrumentation_spec.rb +5 -7
  48. data/spec/faraday/request/json_spec.rb +135 -0
  49. data/spec/faraday/request/url_encoded_spec.rb +12 -2
  50. data/spec/faraday/request_spec.rb +5 -15
  51. data/spec/faraday/response/json_spec.rb +117 -0
  52. data/spec/faraday/response/logger_spec.rb +38 -0
  53. data/spec/faraday/response/raise_error_spec.rb +35 -5
  54. data/spec/faraday/response_spec.rb +3 -1
  55. data/spec/faraday/utils/headers_spec.rb +22 -4
  56. data/spec/faraday/utils_spec.rb +63 -1
  57. data/spec/faraday_spec.rb +8 -4
  58. data/spec/support/fake_safe_buffer.rb +1 -1
  59. data/spec/support/helper_methods.rb +0 -37
  60. data/spec/support/shared_examples/adapter.rb +2 -2
  61. data/spec/support/shared_examples/request_method.rb +22 -21
  62. metadata +19 -134
  63. data/lib/faraday/adapter/typhoeus.rb +0 -15
  64. data/lib/faraday/autoload.rb +0 -87
  65. data/lib/faraday/dependency_loader.rb +0 -37
  66. data/lib/faraday/file_part.rb +0 -128
  67. data/lib/faraday/param_part.rb +0 -53
  68. data/lib/faraday/request/basic_authentication.rb +0 -20
  69. data/lib/faraday/request/multipart.rb +0 -106
  70. data/lib/faraday/request/retry.rb +0 -239
  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/request/multipart_spec.rb +0 -302
  82. data/spec/faraday/request/retry_spec.rb +0 -242
  83. data/spec/faraday/response/middleware_spec.rb +0 -68
  84. 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
 
@@ -307,25 +310,40 @@ RSpec.describe Faraday::Connection do
307
310
  expect(uri.to_s).to eq('http://service.com/api/service%3Asearch?limit=400')
308
311
  end
309
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
326
+ end
327
+ end
310
328
  end
311
329
 
312
330
  describe '#build_url' do
313
- let(:url) { 'http://sushi.com/nigiri' }
331
+ let(:url) { 'http://httpbingo.org/nigiri' }
314
332
 
315
333
  it 'uses params' do
316
334
  conn.params = { a: 1, b: 1 }
317
- 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')
318
336
  end
319
337
 
320
338
  it 'merges params' do
321
339
  conn.params = { a: 1, b: 1 }
322
340
  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')
341
+ expect(url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=2&c=3')
324
342
  end
325
343
  end
326
344
 
327
345
  describe '#build_request' do
328
- let(:url) { 'https://asushi.com/sake.html' }
346
+ let(:url) { 'https://ahttpbingo.org/sake.html' }
329
347
  let(:request) { conn.build_request(:get) }
330
348
 
331
349
  before do
@@ -342,7 +360,7 @@ RSpec.describe Faraday::Connection do
342
360
  describe '#to_env' do
343
361
  subject { conn.build_request(:get).to_env(conn).url }
344
362
 
345
- let(:url) { 'http://sushi.com/sake.html' }
363
+ let(:url) { 'http://httpbingo.org/sake.html' }
346
364
  let(:options) { { params: @params } }
347
365
 
348
366
  it 'parses url params into query' do
@@ -508,7 +526,7 @@ RSpec.describe Faraday::Connection do
508
526
  it 'uses env http_proxy' do
509
527
  with_env 'http_proxy' => 'http://proxy.com' do
510
528
  conn = Faraday.new
511
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
529
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
512
530
  expect(conn.proxy_for_request('http://google.co.uk').host).to eq('proxy.com')
513
531
  end
514
532
  end
@@ -516,7 +534,7 @@ RSpec.describe Faraday::Connection do
516
534
  it 'uses processes no_proxy before http_proxy' do
517
535
  with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'google.co.uk' do
518
536
  conn = Faraday.new
519
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
537
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
520
538
  expect(conn.proxy_for_request('http://google.co.uk')).to be_nil
521
539
  end
522
540
  end
@@ -524,7 +542,7 @@ RSpec.describe Faraday::Connection do
524
542
  it 'uses env https_proxy' do
525
543
  with_env 'https_proxy' => 'https://proxy.com' do
526
544
  conn = Faraday.new
527
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
545
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
528
546
  expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy.com')
529
547
  end
530
548
  end
@@ -532,7 +550,7 @@ RSpec.describe Faraday::Connection do
532
550
  it 'uses processes no_proxy before https_proxy' do
533
551
  with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do
534
552
  conn = Faraday.new
535
- expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
553
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
536
554
  expect(conn.proxy_for_request('https://google.co.uk')).to be_nil
537
555
  end
538
556
  end
@@ -542,7 +560,7 @@ RSpec.describe Faraday::Connection do
542
560
  conn = Faraday.new
543
561
  conn.proxy = 'http://proxy2.com'
544
562
 
545
- expect(conn.instance_variable_get('@manual_proxy')).to be_truthy
563
+ expect(conn.instance_variable_get(:@manual_proxy)).to be_truthy
546
564
  expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy2.com')
547
565
  end
548
566
  end
@@ -556,26 +574,32 @@ RSpec.describe Faraday::Connection do
556
574
  end
557
575
 
558
576
  context 'performing a request' do
559
- 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
560
587
 
561
588
  it 'dynamically checks proxy' do
562
589
  with_env 'http_proxy' => 'http://proxy.com:80' do
563
- conn = Faraday.new
564
590
  expect(conn.proxy.uri.host).to eq('proxy.com')
565
591
 
566
- conn.get('http://example.com') do |req|
592
+ conn.get(url) do |req|
567
593
  expect(req.options.proxy.uri.host).to eq('proxy.com')
568
594
  end
569
595
  end
570
596
 
571
- conn.get('http://example.com')
572
- 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
573
599
  end
574
600
 
575
601
  it 'dynamically check no proxy' do
576
602
  with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
577
- conn = Faraday.new
578
-
579
603
  expect(conn.proxy.uri.host).to eq('proxy.com')
580
604
 
581
605
  conn.get('http://example.com') do |req|
@@ -589,7 +613,7 @@ RSpec.describe Faraday::Connection do
589
613
  describe '#dup' do
590
614
  subject { conn.dup }
591
615
 
592
- let(:url) { 'http://sushi.com/foo' }
616
+ let(:url) { 'http://httpbingo.org/foo' }
593
617
  let(:options) do
594
618
  {
595
619
  ssl: { verify: :none },
@@ -605,7 +629,6 @@ RSpec.describe Faraday::Connection do
605
629
 
606
630
  context 'after manual changes' do
607
631
  before do
608
- subject.basic_auth('', '')
609
632
  subject.headers['content-length'] = 12
610
633
  subject.params['b'] = '2'
611
634
  subject.options[:open_timeout] = 10
@@ -640,14 +663,42 @@ RSpec.describe Faraday::Connection do
640
663
 
641
664
  it_behaves_like 'default connection options'
642
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
643
687
  end
644
688
 
645
689
  describe 'request params' do
646
690
  context 'with simple url' do
647
691
  let(:url) { 'http://example.com' }
648
- let!(:stubbed) { stub_request(:get, 'http://example.com?a=a&p=3') }
692
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
693
+
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
649
700
 
650
- after { expect(stubbed).to have_been_made.once }
701
+ after { stubs.verify_stubbed_calls }
651
702
 
652
703
  it 'test_overrides_request_params' do
653
704
  conn.get('?p=2&a=a', p: 3)
@@ -669,15 +720,22 @@ RSpec.describe Faraday::Connection do
669
720
  context 'with url and extra params' do
670
721
  let(:url) { 'http://example.com?a=1&b=2' }
671
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
672
728
 
673
729
  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')
730
+ expected = 'http://example.com?a=1&b=2&c=3&limit=5&page=1'
731
+ stubs.get(expected) { [200, {}, 'ok'] }
675
732
  conn.get('?page=1', limit: 5)
676
- expect(stubbed).to have_been_made.once
733
+ stubs.verify_stubbed_calls
677
734
  end
678
735
 
679
736
  it 'allows to override all params' do
680
- stubbed = stub_request(:get, 'http://example.com?b=b')
737
+ expected = 'http://example.com?b=b'
738
+ stubs.get(expected) { [200, {}, 'ok'] }
681
739
  conn.get('?p=1&a=a', p: 2) do |req|
682
740
  expect(req.params[:a]).to eq('a')
683
741
  expect(req.params['c']).to eq(3)
@@ -685,47 +743,61 @@ RSpec.describe Faraday::Connection do
685
743
  req.params = { b: 'b' }
686
744
  expect(req.params['b']).to eq('b')
687
745
  end
688
- expect(stubbed).to have_been_made.once
746
+ stubs.verify_stubbed_calls
689
747
  end
690
748
 
691
749
  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')
750
+ encoder = CustomEncoder.new
751
+ expected = 'http://example.com/?A-1,B-2,C-3,FEELING-BLUE'
752
+ stubs.get(expected) { [200, {}, 'ok'] }
697
753
 
698
- conn.get('/', feeling: 'blue') do |req|
754
+ conn.get('/', a: 1, b: 2, c: 3, feeling: 'blue') do |req|
699
755
  req.options.params_encoder = encoder
700
756
  end
701
- expect(stubbed).to have_been_made.once
757
+ stubs.verify_stubbed_calls
702
758
  end
703
759
  end
704
760
 
705
761
  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 }
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 }
708
772
 
709
773
  it 'supports array params in url' do
710
- conn.get('http://example.com?color[]=red&color[]=blue')
774
+ conn.get('http://example.com?color[]=blue&color[]=red')
711
775
  end
712
776
 
713
777
  it 'supports array params in params' do
714
- conn.get('http://example.com', color: %w[red blue])
778
+ conn.get('http://example.com', color: %w[blue red])
715
779
  end
716
780
  end
717
781
 
718
782
  context 'with flat params encoder' do
719
783
  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 }
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 }
722
794
 
723
795
  it 'supports array params in params' do
724
- conn.get('http://example.com', color: %w[red blue])
796
+ conn.get('http://example.com', color: %w[blue red])
725
797
  end
726
798
 
727
799
  context 'with array param in url' do
728
- let(:url) { 'http://example.com?color[]=red&color[]=blue' }
800
+ let(:url) { 'http://example.com?color[]=blue&color[]=red' }
729
801
 
730
802
  it do
731
803
  conn.get('/')
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe Faraday::ClientError do
3
+ RSpec.describe Faraday::Error do
4
4
  describe '.initialize' do
5
5
  subject { described_class.new(exception, response) }
6
6
  let(:response) { nil }
@@ -12,8 +12,10 @@ RSpec.describe Faraday::ClientError do
12
12
  it { expect(subject.response).to be_nil }
13
13
  it { expect(subject.message).to eq(exception.message) }
14
14
  it { expect(subject.backtrace).to eq(exception.backtrace) }
15
- it { expect(subject.inspect).to eq('#<Faraday::ClientError wrapped=#<RuntimeError: test>>') }
15
+ it { expect(subject.inspect).to eq('#<Faraday::Error wrapped=#<RuntimeError: test>>') }
16
16
  it { expect(subject.response_status).to be_nil }
17
+ it { expect(subject.response_headers).to be_nil }
18
+ it { expect(subject.response_body).to be_nil }
17
19
  end
18
20
 
19
21
  context 'with response hash' do
@@ -22,8 +24,10 @@ RSpec.describe Faraday::ClientError do
22
24
  it { expect(subject.wrapped_exception).to be_nil }
23
25
  it { expect(subject.response).to eq(exception) }
24
26
  it { expect(subject.message).to eq('the server responded with status 400') }
25
- it { expect(subject.inspect).to eq('#<Faraday::ClientError response={:status=>400}>') }
27
+ it { expect(subject.inspect).to eq('#<Faraday::Error response={:status=>400}>') }
26
28
  it { expect(subject.response_status).to eq(400) }
29
+ it { expect(subject.response_headers).to be_nil }
30
+ it { expect(subject.response_body).to be_nil }
27
31
  end
28
32
 
29
33
  context 'with string' do
@@ -32,8 +36,10 @@ RSpec.describe Faraday::ClientError do
32
36
  it { expect(subject.wrapped_exception).to be_nil }
33
37
  it { expect(subject.response).to be_nil }
34
38
  it { expect(subject.message).to eq('custom message') }
35
- it { expect(subject.inspect).to eq('#<Faraday::ClientError #<Faraday::ClientError: custom message>>') }
39
+ it { expect(subject.inspect).to eq('#<Faraday::Error #<Faraday::Error: custom message>>') }
36
40
  it { expect(subject.response_status).to be_nil }
41
+ it { expect(subject.response_headers).to be_nil }
42
+ it { expect(subject.response_body).to be_nil }
37
43
  end
38
44
 
39
45
  context 'with anything else #to_s' do
@@ -42,8 +48,10 @@ RSpec.describe Faraday::ClientError do
42
48
  it { expect(subject.wrapped_exception).to be_nil }
43
49
  it { expect(subject.response).to be_nil }
44
50
  it { expect(subject.message).to eq('["error1", "error2"]') }
45
- it { expect(subject.inspect).to eq('#<Faraday::ClientError #<Faraday::ClientError: ["error1", "error2"]>>') }
51
+ it { expect(subject.inspect).to eq('#<Faraday::Error #<Faraday::Error: ["error1", "error2"]>>') }
46
52
  it { expect(subject.response_status).to be_nil }
53
+ it { expect(subject.response_headers).to be_nil }
54
+ it { expect(subject.response_body).to be_nil }
47
55
  end
48
56
 
49
57
  context 'with exception string and response hash' do
@@ -53,8 +61,25 @@ RSpec.describe Faraday::ClientError do
53
61
  it { expect(subject.wrapped_exception).to be_nil }
54
62
  it { expect(subject.response).to eq(response) }
55
63
  it { expect(subject.message).to eq('custom message') }
56
- it { expect(subject.inspect).to eq('#<Faraday::ClientError response={:status=>400}>') }
64
+ it { expect(subject.inspect).to eq('#<Faraday::Error response={:status=>400}>') }
57
65
  it { expect(subject.response_status).to eq(400) }
66
+ it { expect(subject.response_headers).to be_nil }
67
+ it { expect(subject.response_body).to be_nil }
68
+ end
69
+
70
+ context 'with exception and response object' do
71
+ let(:exception) { RuntimeError.new('test') }
72
+ let(:body) { { test: 'test' } }
73
+ let(:headers) { { 'Content-Type' => 'application/json' } }
74
+ let(:response) { Faraday::Response.new(status: 400, response_headers: headers, response_body: body) }
75
+
76
+ it { expect(subject.wrapped_exception).to eq(exception) }
77
+ it { expect(subject.response).to eq(response) }
78
+ it { expect(subject.message).to eq(exception.message) }
79
+ it { expect(subject.backtrace).to eq(exception.backtrace) }
80
+ it { expect(subject.response_status).to eq(400) }
81
+ it { expect(subject.response_headers).to eq(headers) }
82
+ it { expect(subject.response_body).to eq(body) }
58
83
  end
59
84
  end
60
85
  end
@@ -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