faraday 2.0.0 → 2.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +81 -3
- data/LICENSE.md +1 -1
- data/README.md +1 -6
- data/examples/client_spec.rb +40 -18
- data/examples/client_test.rb +47 -21
- data/lib/faraday/adapter/test.rb +41 -7
- data/lib/faraday/adapter.rb +2 -2
- data/lib/faraday/connection.rb +34 -34
- data/lib/faraday/encoders/nested_params_encoder.rb +11 -4
- data/lib/faraday/logging/formatter.rb +17 -3
- data/lib/faraday/middleware.rb +3 -0
- data/lib/faraday/middleware_registry.rb +19 -1
- data/lib/faraday/options/env.rb +18 -0
- data/lib/faraday/options/ssl_options.rb +11 -1
- data/lib/faraday/rack_builder.rb +2 -2
- data/lib/faraday/request/authorization.rb +8 -3
- data/lib/faraday/request/url_encoded.rb +3 -1
- data/lib/faraday/request.rb +1 -1
- data/lib/faraday/response/logger.rb +4 -0
- data/lib/faraday/utils/headers.rb +6 -1
- data/lib/faraday/version.rb +1 -1
- data/lib/faraday.rb +8 -2
- data/spec/faraday/adapter/test_spec.rb +36 -0
- data/spec/faraday/connection_spec.rb +48 -42
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +18 -0
- data/spec/faraday/options/env_spec.rb +6 -0
- data/spec/faraday/params_encoders/nested_spec.rb +8 -0
- data/spec/faraday/rack_builder_spec.rb +27 -12
- data/spec/faraday/request/authorization_spec.rb +35 -0
- data/spec/faraday/request/url_encoded_spec.rb +12 -1
- data/spec/faraday/request_spec.rb +5 -4
- data/spec/faraday/response/logger_spec.rb +28 -0
- data/spec/faraday/utils/headers_spec.rb +22 -4
- data/spec/faraday/utils_spec.rb +2 -1
- data/spec/support/shared_examples/adapter.rb +2 -1
- data/spec/support/shared_examples/request_method.rb +17 -3
- metadata +24 -3
|
@@ -6,15 +6,15 @@ class CustomEncoder
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def decode(params)
|
|
9
|
-
params.split(',').
|
|
9
|
+
params.split(',').to_h { |pair| pair.split('-') }
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
shared_examples 'initializer with url' do
|
|
14
14
|
context 'with simple url' do
|
|
15
|
-
let(:address) { 'http://
|
|
15
|
+
let(:address) { 'http://httpbingo.org' }
|
|
16
16
|
|
|
17
|
-
it { expect(subject.host).to eq('
|
|
17
|
+
it { expect(subject.host).to eq('httpbingo.org') }
|
|
18
18
|
it { expect(subject.port).to eq(80) }
|
|
19
19
|
it { expect(subject.scheme).to eq('http') }
|
|
20
20
|
it { expect(subject.path_prefix).to eq('/') }
|
|
@@ -22,7 +22,7 @@ shared_examples 'initializer with url' do
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
context 'with complex url' do
|
|
25
|
-
let(:address) { 'http://
|
|
25
|
+
let(:address) { 'http://httpbingo.org:815/fish?a=1' }
|
|
26
26
|
|
|
27
27
|
it { expect(subject.port).to eq(815) }
|
|
28
28
|
it { expect(subject.path_prefix).to eq('/fish') }
|
|
@@ -41,17 +41,17 @@ shared_examples 'default connection options' do
|
|
|
41
41
|
after { Faraday.default_connection_options = nil }
|
|
42
42
|
|
|
43
43
|
it 'works with implicit url' do
|
|
44
|
-
conn = Faraday.new 'http://
|
|
44
|
+
conn = Faraday.new 'http://httpbingo.org/foo'
|
|
45
45
|
expect(conn.options.timeout).to eq(10)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
it 'works with option url' do
|
|
49
|
-
conn = Faraday.new url: 'http://
|
|
49
|
+
conn = Faraday.new url: 'http://httpbingo.org/foo'
|
|
50
50
|
expect(conn.options.timeout).to eq(10)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it 'works with instance connection options' do
|
|
54
|
-
conn = Faraday.new 'http://
|
|
54
|
+
conn = Faraday.new 'http://httpbingo.org/foo', request: { open_timeout: 1 }
|
|
55
55
|
expect(conn.options.timeout).to eq(10)
|
|
56
56
|
expect(conn.options.open_timeout).to eq(1)
|
|
57
57
|
end
|
|
@@ -61,7 +61,7 @@ shared_examples 'default connection options' do
|
|
|
61
61
|
conn.options.timeout = 1
|
|
62
62
|
expect(Faraday.default_connection_options.request.timeout).to eq(10)
|
|
63
63
|
|
|
64
|
-
other = Faraday.new url: 'https://
|
|
64
|
+
other = Faraday.new url: 'https://httpbingo.org/foo'
|
|
65
65
|
other.options.timeout = 1
|
|
66
66
|
|
|
67
67
|
expect(Faraday.default_connection_options.request.timeout).to eq(10)
|
|
@@ -81,14 +81,14 @@ RSpec.describe Faraday::Connection do
|
|
|
81
81
|
subject { conn }
|
|
82
82
|
|
|
83
83
|
context 'with implicit url param' do
|
|
84
|
-
# Faraday::Connection.new('http://
|
|
84
|
+
# Faraday::Connection.new('http://httpbingo.org')
|
|
85
85
|
let(:url) { address }
|
|
86
86
|
|
|
87
87
|
it_behaves_like 'initializer with url'
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
context 'with explicit url param' do
|
|
91
|
-
# Faraday::Connection.new(url: 'http://
|
|
91
|
+
# Faraday::Connection.new(url: 'http://httpbingo.org')
|
|
92
92
|
let(:url) { { url: address } }
|
|
93
93
|
|
|
94
94
|
it_behaves_like 'initializer with url'
|
|
@@ -108,13 +108,13 @@ RSpec.describe Faraday::Connection do
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
context 'with custom params and params in url' do
|
|
111
|
-
let(:url) { 'http://
|
|
111
|
+
let(:url) { 'http://httpbingo.org/fish?a=1&b=2' }
|
|
112
112
|
let(:options) { { params: { a: 3 } } }
|
|
113
113
|
it { expect(subject.params).to eq('a' => 3, 'b' => '2') }
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
context 'with basic_auth in url' do
|
|
117
|
-
let(:url) { 'http://Aladdin:open%20sesame@
|
|
117
|
+
let(:url) { 'http://Aladdin:open%20sesame@httpbingo.org/fish' }
|
|
118
118
|
|
|
119
119
|
it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
|
|
120
120
|
end
|
|
@@ -131,6 +131,12 @@ RSpec.describe Faraday::Connection do
|
|
|
131
131
|
it { expect(subject.ssl.verify?).to be_falsey }
|
|
132
132
|
end
|
|
133
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
|
+
|
|
134
140
|
context 'with empty block' do
|
|
135
141
|
let(:conn) { Faraday::Connection.new {} }
|
|
136
142
|
|
|
@@ -141,7 +147,7 @@ RSpec.describe Faraday::Connection do
|
|
|
141
147
|
let(:conn) do
|
|
142
148
|
Faraday::Connection.new(params: { 'a' => '1' }) do |faraday|
|
|
143
149
|
faraday.adapter :test
|
|
144
|
-
faraday.url_prefix = 'http://
|
|
150
|
+
faraday.url_prefix = 'http://httpbingo.org/omnom'
|
|
145
151
|
end
|
|
146
152
|
end
|
|
147
153
|
|
|
@@ -165,8 +171,8 @@ RSpec.describe Faraday::Connection do
|
|
|
165
171
|
subject { conn.build_exclusive_url('sake.html') }
|
|
166
172
|
|
|
167
173
|
it 'uses connection host as default host' do
|
|
168
|
-
conn.host = '
|
|
169
|
-
expect(subject.host).to eq('
|
|
174
|
+
conn.host = 'httpbingo.org'
|
|
175
|
+
expect(subject.host).to eq('httpbingo.org')
|
|
170
176
|
expect(subject.scheme).to eq('http')
|
|
171
177
|
end
|
|
172
178
|
|
|
@@ -203,10 +209,10 @@ RSpec.describe Faraday::Connection do
|
|
|
203
209
|
end
|
|
204
210
|
|
|
205
211
|
context 'with complete url' do
|
|
206
|
-
subject { conn.build_exclusive_url('http://
|
|
212
|
+
subject { conn.build_exclusive_url('http://httpbingo.org/sake.html?a=1') }
|
|
207
213
|
|
|
208
214
|
it { expect(subject.scheme).to eq('http') }
|
|
209
|
-
it { expect(subject.host).to eq('
|
|
215
|
+
it { expect(subject.host).to eq('httpbingo.org') }
|
|
210
216
|
it { expect(subject.port).to eq(80) }
|
|
211
217
|
it { expect(subject.path).to eq('/sake.html') }
|
|
212
218
|
it { expect(subject.query).to eq('a=1') }
|
|
@@ -214,35 +220,35 @@ RSpec.describe Faraday::Connection do
|
|
|
214
220
|
|
|
215
221
|
it 'overrides connection port for absolute url' do
|
|
216
222
|
conn.port = 23
|
|
217
|
-
uri = conn.build_exclusive_url('http://
|
|
223
|
+
uri = conn.build_exclusive_url('http://httpbingo.org')
|
|
218
224
|
expect(uri.port).to eq(80)
|
|
219
225
|
end
|
|
220
226
|
|
|
221
227
|
it 'does not add ending slash given nil url' do
|
|
222
|
-
conn.url_prefix = 'http://
|
|
228
|
+
conn.url_prefix = 'http://httpbingo.org/nigiri'
|
|
223
229
|
uri = conn.build_exclusive_url
|
|
224
230
|
expect(uri.path).to eq('/nigiri')
|
|
225
231
|
end
|
|
226
232
|
|
|
227
233
|
it 'does not add ending slash given empty url' do
|
|
228
|
-
conn.url_prefix = 'http://
|
|
234
|
+
conn.url_prefix = 'http://httpbingo.org/nigiri'
|
|
229
235
|
uri = conn.build_exclusive_url('')
|
|
230
236
|
expect(uri.path).to eq('/nigiri')
|
|
231
237
|
end
|
|
232
238
|
|
|
233
239
|
it 'does not use connection params' do
|
|
234
|
-
conn.url_prefix = 'http://
|
|
240
|
+
conn.url_prefix = 'http://httpbingo.org/nigiri'
|
|
235
241
|
conn.params = { a: 1 }
|
|
236
|
-
expect(conn.build_exclusive_url.to_s).to eq('http://
|
|
242
|
+
expect(conn.build_exclusive_url.to_s).to eq('http://httpbingo.org/nigiri')
|
|
237
243
|
end
|
|
238
244
|
|
|
239
245
|
it 'allows to provide params argument' do
|
|
240
|
-
conn.url_prefix = 'http://
|
|
246
|
+
conn.url_prefix = 'http://httpbingo.org/nigiri'
|
|
241
247
|
conn.params = { a: 1 }
|
|
242
248
|
params = Faraday::Utils::ParamsHash.new
|
|
243
249
|
params[:a] = 2
|
|
244
250
|
uri = conn.build_exclusive_url(nil, params)
|
|
245
|
-
expect(uri.to_s).to eq('http://
|
|
251
|
+
expect(uri.to_s).to eq('http://httpbingo.org/nigiri?a=2')
|
|
246
252
|
end
|
|
247
253
|
|
|
248
254
|
it 'handles uri instances' do
|
|
@@ -251,34 +257,34 @@ RSpec.describe Faraday::Connection do
|
|
|
251
257
|
end
|
|
252
258
|
|
|
253
259
|
it 'always returns new URI instance' do
|
|
254
|
-
conn.url_prefix = 'http://
|
|
260
|
+
conn.url_prefix = 'http://httpbingo.org'
|
|
255
261
|
uri1 = conn.build_exclusive_url(nil)
|
|
256
262
|
uri2 = conn.build_exclusive_url(nil)
|
|
257
263
|
expect(uri1).not_to equal(uri2)
|
|
258
264
|
end
|
|
259
265
|
|
|
260
266
|
context 'with url_prefixed connection' do
|
|
261
|
-
let(:url) { 'http://
|
|
267
|
+
let(:url) { 'http://httpbingo.org/get/' }
|
|
262
268
|
|
|
263
269
|
it 'parses url and changes scheme' do
|
|
264
270
|
conn.scheme = 'https'
|
|
265
271
|
uri = conn.build_exclusive_url('sake.html')
|
|
266
|
-
expect(uri.to_s).to eq('https://
|
|
272
|
+
expect(uri.to_s).to eq('https://httpbingo.org/get/sake.html')
|
|
267
273
|
end
|
|
268
274
|
|
|
269
275
|
it 'joins url to base with ending slash' do
|
|
270
276
|
uri = conn.build_exclusive_url('sake.html')
|
|
271
|
-
expect(uri.to_s).to eq('http://
|
|
277
|
+
expect(uri.to_s).to eq('http://httpbingo.org/get/sake.html')
|
|
272
278
|
end
|
|
273
279
|
|
|
274
280
|
it 'used default base with ending slash' do
|
|
275
281
|
uri = conn.build_exclusive_url
|
|
276
|
-
expect(uri.to_s).to eq('http://
|
|
282
|
+
expect(uri.to_s).to eq('http://httpbingo.org/get/')
|
|
277
283
|
end
|
|
278
284
|
|
|
279
285
|
it 'overrides base' do
|
|
280
286
|
uri = conn.build_exclusive_url('/sake/')
|
|
281
|
-
expect(uri.to_s).to eq('http://
|
|
287
|
+
expect(uri.to_s).to eq('http://httpbingo.org/sake/')
|
|
282
288
|
end
|
|
283
289
|
end
|
|
284
290
|
|
|
@@ -307,22 +313,22 @@ RSpec.describe Faraday::Connection do
|
|
|
307
313
|
end
|
|
308
314
|
|
|
309
315
|
describe '#build_url' do
|
|
310
|
-
let(:url) { 'http://
|
|
316
|
+
let(:url) { 'http://httpbingo.org/nigiri' }
|
|
311
317
|
|
|
312
318
|
it 'uses params' do
|
|
313
319
|
conn.params = { a: 1, b: 1 }
|
|
314
|
-
expect(conn.build_url.to_s).to eq('http://
|
|
320
|
+
expect(conn.build_url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=1')
|
|
315
321
|
end
|
|
316
322
|
|
|
317
323
|
it 'merges params' do
|
|
318
324
|
conn.params = { a: 1, b: 1 }
|
|
319
325
|
url = conn.build_url(nil, b: 2, c: 3)
|
|
320
|
-
expect(url.to_s).to eq('http://
|
|
326
|
+
expect(url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=2&c=3')
|
|
321
327
|
end
|
|
322
328
|
end
|
|
323
329
|
|
|
324
330
|
describe '#build_request' do
|
|
325
|
-
let(:url) { 'https://
|
|
331
|
+
let(:url) { 'https://ahttpbingo.org/sake.html' }
|
|
326
332
|
let(:request) { conn.build_request(:get) }
|
|
327
333
|
|
|
328
334
|
before do
|
|
@@ -339,7 +345,7 @@ RSpec.describe Faraday::Connection do
|
|
|
339
345
|
describe '#to_env' do
|
|
340
346
|
subject { conn.build_request(:get).to_env(conn).url }
|
|
341
347
|
|
|
342
|
-
let(:url) { 'http://
|
|
348
|
+
let(:url) { 'http://httpbingo.org/sake.html' }
|
|
343
349
|
let(:options) { { params: @params } }
|
|
344
350
|
|
|
345
351
|
it 'parses url params into query' do
|
|
@@ -505,7 +511,7 @@ RSpec.describe Faraday::Connection do
|
|
|
505
511
|
it 'uses env http_proxy' do
|
|
506
512
|
with_env 'http_proxy' => 'http://proxy.com' do
|
|
507
513
|
conn = Faraday.new
|
|
508
|
-
expect(conn.instance_variable_get(
|
|
514
|
+
expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
|
|
509
515
|
expect(conn.proxy_for_request('http://google.co.uk').host).to eq('proxy.com')
|
|
510
516
|
end
|
|
511
517
|
end
|
|
@@ -513,7 +519,7 @@ RSpec.describe Faraday::Connection do
|
|
|
513
519
|
it 'uses processes no_proxy before http_proxy' do
|
|
514
520
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'google.co.uk' do
|
|
515
521
|
conn = Faraday.new
|
|
516
|
-
expect(conn.instance_variable_get(
|
|
522
|
+
expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
|
|
517
523
|
expect(conn.proxy_for_request('http://google.co.uk')).to be_nil
|
|
518
524
|
end
|
|
519
525
|
end
|
|
@@ -521,7 +527,7 @@ RSpec.describe Faraday::Connection do
|
|
|
521
527
|
it 'uses env https_proxy' do
|
|
522
528
|
with_env 'https_proxy' => 'https://proxy.com' do
|
|
523
529
|
conn = Faraday.new
|
|
524
|
-
expect(conn.instance_variable_get(
|
|
530
|
+
expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
|
|
525
531
|
expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy.com')
|
|
526
532
|
end
|
|
527
533
|
end
|
|
@@ -529,7 +535,7 @@ RSpec.describe Faraday::Connection do
|
|
|
529
535
|
it 'uses processes no_proxy before https_proxy' do
|
|
530
536
|
with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do
|
|
531
537
|
conn = Faraday.new
|
|
532
|
-
expect(conn.instance_variable_get(
|
|
538
|
+
expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
|
|
533
539
|
expect(conn.proxy_for_request('https://google.co.uk')).to be_nil
|
|
534
540
|
end
|
|
535
541
|
end
|
|
@@ -539,7 +545,7 @@ RSpec.describe Faraday::Connection do
|
|
|
539
545
|
conn = Faraday.new
|
|
540
546
|
conn.proxy = 'http://proxy2.com'
|
|
541
547
|
|
|
542
|
-
expect(conn.instance_variable_get(
|
|
548
|
+
expect(conn.instance_variable_get(:@manual_proxy)).to be_truthy
|
|
543
549
|
expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy2.com')
|
|
544
550
|
end
|
|
545
551
|
end
|
|
@@ -574,7 +580,7 @@ RSpec.describe Faraday::Connection do
|
|
|
574
580
|
end
|
|
575
581
|
|
|
576
582
|
conn.get(url)
|
|
577
|
-
expect(conn.instance_variable_get(
|
|
583
|
+
expect(conn.instance_variable_get(:@temp_proxy)).to be_nil
|
|
578
584
|
end
|
|
579
585
|
|
|
580
586
|
it 'dynamically check no proxy' do
|
|
@@ -592,7 +598,7 @@ RSpec.describe Faraday::Connection do
|
|
|
592
598
|
describe '#dup' do
|
|
593
599
|
subject { conn.dup }
|
|
594
600
|
|
|
595
|
-
let(:url) { 'http://
|
|
601
|
+
let(:url) { 'http://httpbingo.org/foo' }
|
|
596
602
|
let(:options) do
|
|
597
603
|
{
|
|
598
604
|
ssl: { verify: :none },
|
|
@@ -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
|
|
@@ -33,6 +33,24 @@ RSpec.describe Faraday::Middleware do
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
describe '#on_error' do
|
|
37
|
+
subject do
|
|
38
|
+
Class.new(described_class) do
|
|
39
|
+
def on_error(error)
|
|
40
|
+
# do nothing
|
|
41
|
+
end
|
|
42
|
+
end.new(app)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'is called by #call' do
|
|
46
|
+
expect(app).to receive(:call).and_raise(Faraday::ConnectionFailed)
|
|
47
|
+
is_expected.to receive(:call).and_call_original
|
|
48
|
+
is_expected.to receive(:on_error)
|
|
49
|
+
|
|
50
|
+
expect { subject.call(double) }.to raise_error(Faraday::ConnectionFailed)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
36
54
|
describe '#close' do
|
|
37
55
|
context "with app that doesn't support \#close" do
|
|
38
56
|
it 'should issue warning' do
|
|
@@ -27,6 +27,12 @@ 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
38
|
env[:bar] = :custom2
|
|
@@ -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|
|
|
@@ -110,18 +110,6 @@ RSpec.describe Faraday::RackBuilder do
|
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
context 'with custom registered middleware' do
|
|
114
|
-
let(:conn) { Faraday::Connection.new {} }
|
|
115
|
-
|
|
116
|
-
after { Faraday::Middleware.unregister_middleware(:apple) }
|
|
117
|
-
|
|
118
|
-
it 'allows to register with constant' do
|
|
119
|
-
Faraday::Middleware.register_middleware(apple: Apple)
|
|
120
|
-
subject.use(:apple)
|
|
121
|
-
expect(subject.handlers).to eq([Apple])
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
113
|
context 'when having two handlers' do
|
|
126
114
|
let(:conn) { Faraday::Connection.new {} }
|
|
127
115
|
|
|
@@ -151,6 +139,33 @@ RSpec.describe Faraday::RackBuilder do
|
|
|
151
139
|
end
|
|
152
140
|
end
|
|
153
141
|
|
|
142
|
+
context 'when adapter is added with named options' do
|
|
143
|
+
after { Faraday.default_adapter_options = {} }
|
|
144
|
+
let(:conn) { Faraday::Connection.new {} }
|
|
145
|
+
|
|
146
|
+
let(:cat_adapter) do
|
|
147
|
+
Class.new(Faraday::Adapter) do
|
|
148
|
+
attr_accessor :name
|
|
149
|
+
|
|
150
|
+
def initialize(app, name:)
|
|
151
|
+
super(app)
|
|
152
|
+
@name = name
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
let(:cat) { subject.adapter.build }
|
|
158
|
+
|
|
159
|
+
it 'adds a handler to construct adapter with named options' do
|
|
160
|
+
Faraday.default_adapter = cat_adapter
|
|
161
|
+
Faraday.default_adapter_options = { name: 'Chloe' }
|
|
162
|
+
expect { cat }.to_not output(
|
|
163
|
+
/warning: Using the last argument as keyword parameters is deprecated/
|
|
164
|
+
).to_stderr
|
|
165
|
+
expect(cat.name).to eq 'Chloe'
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
154
169
|
context 'when middleware is added with named arguments' do
|
|
155
170
|
let(:conn) { Faraday::Connection.new {} }
|
|
156
171
|
|
|
@@ -72,6 +72,41 @@ RSpec.describe Faraday::Request::Authorization do
|
|
|
72
72
|
include_examples 'does not interfere with existing authentication'
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
context 'with an argument' do
|
|
76
|
+
let(:response) { conn.get('/auth-echo', nil, 'middle' => 'crunchy surprise') }
|
|
77
|
+
|
|
78
|
+
context 'when passed a proc' do
|
|
79
|
+
let(:auth_config) { [proc { |env| "proc #{env.request_headers['middle']}" }] }
|
|
80
|
+
|
|
81
|
+
it { expect(response.body).to eq('Bearer proc crunchy surprise') }
|
|
82
|
+
|
|
83
|
+
include_examples 'does not interfere with existing authentication'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context 'when passed a lambda' do
|
|
87
|
+
let(:auth_config) { [->(env) { "lambda #{env.request_headers['middle']}" }] }
|
|
88
|
+
|
|
89
|
+
it { expect(response.body).to eq('Bearer lambda crunchy surprise') }
|
|
90
|
+
|
|
91
|
+
include_examples 'does not interfere with existing authentication'
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context 'when passed a callable with an argument' do
|
|
95
|
+
let(:callable) do
|
|
96
|
+
Class.new do
|
|
97
|
+
def call(env)
|
|
98
|
+
"callable #{env.request_headers['middle']}"
|
|
99
|
+
end
|
|
100
|
+
end.new
|
|
101
|
+
end
|
|
102
|
+
let(:auth_config) { [callable] }
|
|
103
|
+
|
|
104
|
+
it { expect(response.body).to eq('Bearer callable crunchy surprise') }
|
|
105
|
+
|
|
106
|
+
include_examples 'does not interfere with existing authentication'
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
75
110
|
context 'when passed too many arguments' do
|
|
76
111
|
let(:auth_config) { %w[baz foo] }
|
|
77
112
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'stringio'
|
|
4
|
+
|
|
3
5
|
RSpec.describe Faraday::Request::UrlEncoded do
|
|
4
6
|
let(:conn) do
|
|
5
7
|
Faraday.new do |b|
|
|
@@ -7,7 +9,11 @@ RSpec.describe Faraday::Request::UrlEncoded do
|
|
|
7
9
|
b.adapter :test do |stub|
|
|
8
10
|
stub.post('/echo') do |env|
|
|
9
11
|
posted_as = env[:request_headers]['Content-Type']
|
|
10
|
-
|
|
12
|
+
body = env[:body]
|
|
13
|
+
if body.respond_to?(:read)
|
|
14
|
+
body = body.read
|
|
15
|
+
end
|
|
16
|
+
[200, { 'Content-Type' => posted_as }, body]
|
|
11
17
|
end
|
|
12
18
|
end
|
|
13
19
|
end
|
|
@@ -67,6 +73,11 @@ RSpec.describe Faraday::Request::UrlEncoded do
|
|
|
67
73
|
expect(response.body).to eq('a%5Bb%5D%5Bc%5D%5B%5D=d')
|
|
68
74
|
end
|
|
69
75
|
|
|
76
|
+
it 'works with files' do
|
|
77
|
+
response = conn.post('/echo', StringIO.new('str=apple'))
|
|
78
|
+
expect(response.body).to eq('str=apple')
|
|
79
|
+
end
|
|
80
|
+
|
|
70
81
|
context 'customising default_space_encoding' do
|
|
71
82
|
around do |example|
|
|
72
83
|
Faraday::Utils.default_space_encoding = '%20'
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
RSpec.describe Faraday::Request do
|
|
4
4
|
let(:conn) do
|
|
5
|
-
Faraday.new(url: 'http://
|
|
5
|
+
Faraday.new(url: 'http://httpbingo.org/api',
|
|
6
6
|
headers: { 'Mime-Version' => '1.0' },
|
|
7
7
|
request: { oauth: { consumer_key: 'anonymous' } })
|
|
8
8
|
end
|
|
@@ -14,6 +14,7 @@ RSpec.describe Faraday::Request do
|
|
|
14
14
|
context 'when nothing particular is configured' do
|
|
15
15
|
it { expect(subject.http_method).to eq(:get) }
|
|
16
16
|
it { expect(subject.to_env(conn).ssl.verify).to be_falsey }
|
|
17
|
+
it { expect(subject.to_env(conn).ssl.verify_hostname).to be_falsey }
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
context 'when HTTP method is post' do
|
|
@@ -27,7 +28,7 @@ RSpec.describe Faraday::Request do
|
|
|
27
28
|
|
|
28
29
|
it { expect(subject.path).to eq(URI.parse('foo.json')) }
|
|
29
30
|
it { expect(subject.params).to eq('a' => '1') }
|
|
30
|
-
it { expect(subject.to_env(conn).url.to_s).to eq('http://
|
|
31
|
+
it { expect(subject.to_env(conn).url.to_s).to eq('http://httpbingo.org/api/foo.json?a=1') }
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
context 'when setting the url on setup with a string path and params' do
|
|
@@ -35,7 +36,7 @@ RSpec.describe Faraday::Request do
|
|
|
35
36
|
|
|
36
37
|
it { expect(subject.path).to eq('foo.json') }
|
|
37
38
|
it { expect(subject.params).to eq('a' => 1) }
|
|
38
|
-
it { expect(subject.to_env(conn).url.to_s).to eq('http://
|
|
39
|
+
it { expect(subject.to_env(conn).url.to_s).to eq('http://httpbingo.org/api/foo.json?a=1') }
|
|
39
40
|
end
|
|
40
41
|
|
|
41
42
|
context 'when setting the url on setup with a path including params' do
|
|
@@ -43,7 +44,7 @@ RSpec.describe Faraday::Request do
|
|
|
43
44
|
|
|
44
45
|
it { expect(subject.path).to eq('foo.json') }
|
|
45
46
|
it { expect(subject.params).to eq('a' => '1', 'b' => '2') }
|
|
46
|
-
it { expect(subject.to_env(conn).url.to_s).to eq('http://
|
|
47
|
+
it { expect(subject.to_env(conn).url.to_s).to eq('http://httpbingo.org/api/foo.json?a=1&b=2') }
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
context 'when setting a header on setup with []= syntax' do
|
|
@@ -64,6 +64,15 @@ RSpec.describe Faraday::Response::Logger do
|
|
|
64
64
|
expect(formatter).to receive(:response).with(an_instance_of(Faraday::Env))
|
|
65
65
|
conn.get '/hello'
|
|
66
66
|
end
|
|
67
|
+
|
|
68
|
+
context 'when no route' do
|
|
69
|
+
it 'delegates logging to the formatter' do
|
|
70
|
+
expect(formatter).to receive(:request).with(an_instance_of(Faraday::Env))
|
|
71
|
+
expect(formatter).to receive(:error).with(an_instance_of(Faraday::Adapter::Test::Stubs::NotFound))
|
|
72
|
+
|
|
73
|
+
expect { conn.get '/noroute' }.to raise_error(Faraday::Adapter::Test::Stubs::NotFound)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
67
76
|
end
|
|
68
77
|
|
|
69
78
|
context 'with custom formatter' do
|
|
@@ -94,6 +103,16 @@ RSpec.describe Faraday::Response::Logger do
|
|
|
94
103
|
expect(string_io.string).to match('GET http:/hello')
|
|
95
104
|
end
|
|
96
105
|
|
|
106
|
+
it 'logs status' do
|
|
107
|
+
conn.get '/hello', nil, accept: 'text/html'
|
|
108
|
+
expect(string_io.string).to match('Status 200')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'does not log error message by default' do
|
|
112
|
+
expect { conn.get '/noroute' }.to raise_error(Faraday::Adapter::Test::Stubs::NotFound)
|
|
113
|
+
expect(string_io.string).not_to match(%(no stubbed request for get http:/noroute))
|
|
114
|
+
end
|
|
115
|
+
|
|
97
116
|
it 'logs request headers by default' do
|
|
98
117
|
conn.get '/hello', nil, accept: 'text/html'
|
|
99
118
|
expect(string_io.string).to match(%(Accept: "text/html))
|
|
@@ -188,6 +207,15 @@ RSpec.describe Faraday::Response::Logger do
|
|
|
188
207
|
end
|
|
189
208
|
end
|
|
190
209
|
|
|
210
|
+
context 'when logging errors' do
|
|
211
|
+
let(:logger_options) { { errors: true } }
|
|
212
|
+
|
|
213
|
+
it 'logs error message' do
|
|
214
|
+
expect { conn.get '/noroute' }.to raise_error(Faraday::Adapter::Test::Stubs::NotFound)
|
|
215
|
+
expect(string_io.string).to match(%(no stubbed request for get http:/noroute))
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
191
219
|
context 'when using log_level' do
|
|
192
220
|
let(:logger_options) { { bodies: true, log_level: :debug } }
|
|
193
221
|
|
|
@@ -57,26 +57,44 @@ RSpec.describe Faraday::Utils::Headers do
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
describe '#parse' do
|
|
60
|
-
before { subject.parse(headers) }
|
|
61
|
-
|
|
62
60
|
context 'when response headers leave http status line out' do
|
|
63
61
|
let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n" }
|
|
64
62
|
|
|
63
|
+
before { subject.parse(headers) }
|
|
64
|
+
|
|
65
65
|
it { expect(subject.keys).to eq(%w[Content-Type]) }
|
|
66
66
|
it { expect(subject['Content-Type']).to eq('text/html') }
|
|
67
67
|
it { expect(subject['content-type']).to eq('text/html') }
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
context 'when response headers values include a colon' do
|
|
71
|
-
let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nLocation: http://
|
|
71
|
+
let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nLocation: http://httpbingo.org/\r\n\r\n" }
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
before { subject.parse(headers) }
|
|
74
|
+
|
|
75
|
+
it { expect(subject['location']).to eq('http://httpbingo.org/') }
|
|
74
76
|
end
|
|
75
77
|
|
|
76
78
|
context 'when response headers include a blank line' do
|
|
77
79
|
let(:headers) { "HTTP/1.1 200 OK\r\n\r\nContent-Type: text/html\r\n\r\n" }
|
|
78
80
|
|
|
81
|
+
before { subject.parse(headers) }
|
|
82
|
+
|
|
79
83
|
it { expect(subject['content-type']).to eq('text/html') }
|
|
80
84
|
end
|
|
85
|
+
|
|
86
|
+
context 'when response headers include already stored keys' do
|
|
87
|
+
let(:headers) { "HTTP/1.1 200 OK\r\nX-Numbers: 123\r\n\r\n" }
|
|
88
|
+
|
|
89
|
+
before do
|
|
90
|
+
h = subject
|
|
91
|
+
h[:x_numbers] = 8
|
|
92
|
+
h.parse(headers)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it do
|
|
96
|
+
expect(subject[:x_numbers]).to eq('8, 123')
|
|
97
|
+
end
|
|
98
|
+
end
|
|
81
99
|
end
|
|
82
100
|
end
|