faraday 1.0.0 → 2.10.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 +299 -1
- data/LICENSE.md +1 -1
- data/README.md +35 -23
- data/Rakefile +6 -1
- data/examples/client_spec.rb +68 -14
- data/examples/client_test.rb +80 -15
- data/lib/faraday/adapter/test.rb +117 -52
- data/lib/faraday/adapter.rb +7 -21
- data/lib/faraday/adapter_registry.rb +3 -1
- data/lib/faraday/connection.rb +75 -133
- data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
- data/lib/faraday/encoders/nested_params_encoder.rb +20 -8
- data/lib/faraday/error.rb +39 -6
- data/lib/faraday/logging/formatter.rb +28 -15
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +59 -5
- data/lib/faraday/middleware_registry.rb +17 -63
- data/lib/faraday/options/connection_options.rb +7 -6
- data/lib/faraday/options/env.rb +85 -62
- data/lib/faraday/options/proxy_options.rb +11 -3
- data/lib/faraday/options/request_options.rb +7 -6
- data/lib/faraday/options/ssl_options.rb +56 -45
- data/lib/faraday/options.rb +11 -14
- data/lib/faraday/rack_builder.rb +35 -32
- data/lib/faraday/request/authorization.rb +37 -36
- data/lib/faraday/request/instrumentation.rb +5 -1
- data/lib/faraday/request/json.rb +70 -0
- data/lib/faraday/request/url_encoded.rb +8 -2
- data/lib/faraday/request.rb +22 -29
- data/lib/faraday/response/json.rb +74 -0
- data/lib/faraday/response/logger.rb +8 -4
- data/lib/faraday/response/raise_error.rb +43 -3
- data/lib/faraday/response.rb +10 -23
- data/lib/faraday/utils/headers.rb +17 -6
- data/lib/faraday/utils.rb +22 -10
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +49 -58
- data/spec/faraday/adapter/test_spec.rb +442 -0
- data/spec/faraday/connection_spec.rb +207 -90
- data/spec/faraday/error_spec.rb +45 -5
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +193 -6
- data/spec/faraday/options/env_spec.rb +8 -2
- data/spec/faraday/options/options_spec.rb +1 -1
- data/spec/faraday/options/proxy_options_spec.rb +15 -0
- data/spec/faraday/params_encoders/flat_spec.rb +8 -0
- data/spec/faraday/params_encoders/nested_spec.rb +18 -1
- data/spec/faraday/rack_builder_spec.rb +171 -50
- data/spec/faraday/request/authorization_spec.rb +54 -24
- data/spec/faraday/request/instrumentation_spec.rb +5 -7
- data/spec/faraday/request/json_spec.rb +199 -0
- data/spec/faraday/request/url_encoded_spec.rb +25 -2
- data/spec/faraday/request_spec.rb +11 -10
- data/spec/faraday/response/json_spec.rb +206 -0
- data/spec/faraday/response/logger_spec.rb +38 -0
- data/spec/faraday/response/raise_error_spec.rb +149 -0
- data/spec/faraday/response_spec.rb +3 -1
- data/spec/faraday/utils/headers_spec.rb +31 -4
- data/spec/faraday/utils_spec.rb +63 -1
- data/spec/faraday_spec.rb +10 -4
- data/spec/spec_helper.rb +6 -5
- data/spec/support/fake_safe_buffer.rb +1 -1
- data/spec/support/faraday_middleware_subclasses.rb +18 -0
- data/spec/support/helper_methods.rb +0 -37
- data/spec/support/shared_examples/adapter.rb +4 -3
- data/spec/support/shared_examples/request_method.rb +60 -31
- metadata +34 -44
- data/UPGRADING.md +0 -55
- data/lib/faraday/adapter/em_http.rb +0 -285
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
- data/lib/faraday/adapter/em_synchrony.rb +0 -150
- data/lib/faraday/adapter/excon.rb +0 -124
- data/lib/faraday/adapter/httpclient.rb +0 -151
- data/lib/faraday/adapter/net_http.rb +0 -209
- data/lib/faraday/adapter/net_http_persistent.rb +0 -91
- data/lib/faraday/adapter/patron.rb +0 -132
- data/lib/faraday/adapter/rack.rb +0 -75
- data/lib/faraday/adapter/typhoeus.rb +0 -15
- data/lib/faraday/autoload.rb +0 -95
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/request/basic_authentication.rb +0 -20
- data/lib/faraday/request/multipart.rb +0 -99
- data/lib/faraday/request/retry.rb +0 -239
- data/lib/faraday/request/token_authentication.rb +0 -20
- data/spec/faraday/adapter/em_http_spec.rb +0 -47
- data/spec/faraday/adapter/em_synchrony_spec.rb +0 -16
- data/spec/faraday/adapter/excon_spec.rb +0 -49
- data/spec/faraday/adapter/httpclient_spec.rb +0 -73
- data/spec/faraday/adapter/net_http_persistent_spec.rb +0 -57
- data/spec/faraday/adapter/net_http_spec.rb +0 -64
- data/spec/faraday/adapter/patron_spec.rb +0 -18
- data/spec/faraday/adapter/rack_spec.rb +0 -8
- data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
- data/spec/faraday/composite_read_io_spec.rb +0 -80
- data/spec/faraday/request/multipart_spec.rb +0 -274
- data/spec/faraday/request/retry_spec.rb +0 -242
- data/spec/faraday/response/middleware_spec.rb +0 -52
- data/spec/support/webmock_rack_app.rb +0 -68
|
@@ -12,16 +12,16 @@ RSpec.describe Faraday::RackBuilder do
|
|
|
12
12
|
|
|
13
13
|
class Apple < Handler
|
|
14
14
|
end
|
|
15
|
+
|
|
15
16
|
class Orange < Handler
|
|
16
17
|
end
|
|
17
|
-
class Banana < Handler
|
|
18
|
-
end
|
|
19
18
|
|
|
20
|
-
class
|
|
21
|
-
dependency 'zomg/i_dont/exist'
|
|
19
|
+
class Banana < Handler
|
|
22
20
|
end
|
|
23
21
|
|
|
24
22
|
subject { conn.builder }
|
|
23
|
+
before { Faraday.default_adapter = :test }
|
|
24
|
+
after { Faraday.default_adapter = nil }
|
|
25
25
|
|
|
26
26
|
context 'with default stack' do
|
|
27
27
|
let(:conn) { Faraday::Connection.new }
|
|
@@ -88,13 +88,6 @@ RSpec.describe Faraday::RackBuilder do
|
|
|
88
88
|
|
|
89
89
|
it { expect(subject.handlers).to eq([Apple]) }
|
|
90
90
|
|
|
91
|
-
it 'allows rebuilding' do
|
|
92
|
-
subject.build do |builder|
|
|
93
|
-
builder.use(Orange)
|
|
94
|
-
end
|
|
95
|
-
expect(subject.handlers).to eq([Orange])
|
|
96
|
-
end
|
|
97
|
-
|
|
98
91
|
it 'allows use' do
|
|
99
92
|
subject.use(Orange)
|
|
100
93
|
expect(subject.handlers).to eq([Apple, Orange])
|
|
@@ -117,36 +110,6 @@ RSpec.describe Faraday::RackBuilder do
|
|
|
117
110
|
end
|
|
118
111
|
end
|
|
119
112
|
|
|
120
|
-
context 'with custom registered middleware' do
|
|
121
|
-
let(:conn) { Faraday::Connection.new {} }
|
|
122
|
-
|
|
123
|
-
after { Faraday::Middleware.unregister_middleware(:apple) }
|
|
124
|
-
|
|
125
|
-
it 'allows to register with constant' do
|
|
126
|
-
Faraday::Middleware.register_middleware(apple: Apple)
|
|
127
|
-
subject.use(:apple)
|
|
128
|
-
expect(subject.handlers).to eq([Apple])
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
it 'allows to register with symbol' do
|
|
132
|
-
Faraday::Middleware.register_middleware(apple: :Apple)
|
|
133
|
-
subject.use(:apple)
|
|
134
|
-
expect(subject.handlers).to eq([Apple])
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it 'allows to register with string' do
|
|
138
|
-
Faraday::Middleware.register_middleware(apple: 'Apple')
|
|
139
|
-
subject.use(:apple)
|
|
140
|
-
expect(subject.handlers).to eq([Apple])
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
it 'allows to register with Proc' do
|
|
144
|
-
Faraday::Middleware.register_middleware(apple: -> { Apple })
|
|
145
|
-
subject.use(:apple)
|
|
146
|
-
expect(subject.handlers).to eq([Apple])
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
113
|
context 'when having two handlers' do
|
|
151
114
|
let(:conn) { Faraday::Connection.new {} }
|
|
152
115
|
|
|
@@ -176,21 +139,179 @@ RSpec.describe Faraday::RackBuilder do
|
|
|
176
139
|
end
|
|
177
140
|
end
|
|
178
141
|
|
|
179
|
-
context 'when
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
|
184
153
|
end
|
|
185
154
|
end
|
|
186
155
|
end
|
|
187
156
|
|
|
188
|
-
|
|
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
|
+
|
|
169
|
+
context 'when middleware is added with named arguments' do
|
|
170
|
+
let(:conn) { Faraday::Connection.new {} }
|
|
171
|
+
|
|
172
|
+
let(:dog_middleware) do
|
|
173
|
+
Class.new(Faraday::Middleware) do
|
|
174
|
+
attr_accessor :name
|
|
189
175
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
176
|
+
def initialize(app, name:)
|
|
177
|
+
super(app)
|
|
178
|
+
@name = name
|
|
179
|
+
end
|
|
193
180
|
end
|
|
194
181
|
end
|
|
182
|
+
let(:dog) do
|
|
183
|
+
subject.handlers.find { |handler| handler == dog_middleware }.build
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it 'adds a handler to construct middleware with options passed to use' do
|
|
187
|
+
subject.use dog_middleware, name: 'Rex'
|
|
188
|
+
expect { dog }.to_not output(
|
|
189
|
+
/warning: Using the last argument as keyword parameters is deprecated/
|
|
190
|
+
).to_stderr
|
|
191
|
+
expect(dog.name).to eq('Rex')
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
context 'when a middleware is added with named arguments' do
|
|
196
|
+
let(:conn) { Faraday::Connection.new {} }
|
|
197
|
+
|
|
198
|
+
let(:cat_request) do
|
|
199
|
+
Class.new(Faraday::Middleware) do
|
|
200
|
+
attr_accessor :name
|
|
201
|
+
|
|
202
|
+
def initialize(app, name:)
|
|
203
|
+
super(app)
|
|
204
|
+
@name = name
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
let(:cat) do
|
|
209
|
+
subject.handlers.find { |handler| handler == cat_request }.build
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it 'adds a handler to construct request adapter with options passed to request' do
|
|
213
|
+
Faraday::Request.register_middleware cat_request: cat_request
|
|
214
|
+
subject.request :cat_request, name: 'Felix'
|
|
215
|
+
expect { cat }.to_not output(
|
|
216
|
+
/warning: Using the last argument as keyword parameters is deprecated/
|
|
217
|
+
).to_stderr
|
|
218
|
+
expect(cat.name).to eq('Felix')
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
context 'when a middleware is added with named arguments' do
|
|
223
|
+
let(:conn) { Faraday::Connection.new {} }
|
|
224
|
+
|
|
225
|
+
let(:fish_response) do
|
|
226
|
+
Class.new(Faraday::Middleware) do
|
|
227
|
+
attr_accessor :name
|
|
228
|
+
|
|
229
|
+
def initialize(app, name:)
|
|
230
|
+
super(app)
|
|
231
|
+
@name = name
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
let(:fish) do
|
|
236
|
+
subject.handlers.find { |handler| handler == fish_response }.build
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it 'adds a handler to construct response adapter with options passed to response' do
|
|
240
|
+
Faraday::Response.register_middleware fish_response: fish_response
|
|
241
|
+
subject.response :fish_response, name: 'Bubbles'
|
|
242
|
+
expect { fish }.to_not output(
|
|
243
|
+
/warning: Using the last argument as keyword parameters is deprecated/
|
|
244
|
+
).to_stderr
|
|
245
|
+
expect(fish.name).to eq('Bubbles')
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
context 'when a plain adapter is added with named arguments' do
|
|
250
|
+
let(:conn) { Faraday::Connection.new {} }
|
|
251
|
+
|
|
252
|
+
let(:rabbit_adapter) do
|
|
253
|
+
Class.new(Faraday::Adapter) do
|
|
254
|
+
attr_accessor :name
|
|
255
|
+
|
|
256
|
+
def initialize(app, name:)
|
|
257
|
+
super(app)
|
|
258
|
+
@name = name
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
let(:rabbit) do
|
|
263
|
+
subject.adapter.build
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it 'adds a handler to construct adapter with options passed to adapter' do
|
|
267
|
+
Faraday::Adapter.register_middleware rabbit_adapter: rabbit_adapter
|
|
268
|
+
subject.adapter :rabbit_adapter, name: 'Thumper'
|
|
269
|
+
expect { rabbit }.to_not output(
|
|
270
|
+
/warning: Using the last argument as keyword parameters is deprecated/
|
|
271
|
+
).to_stderr
|
|
272
|
+
expect(rabbit.name).to eq('Thumper')
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
context 'when handlers are directly added or updated' do
|
|
277
|
+
let(:conn) { Faraday::Connection.new {} }
|
|
278
|
+
|
|
279
|
+
let(:rock_handler) do
|
|
280
|
+
Class.new do
|
|
281
|
+
attr_accessor :name
|
|
282
|
+
|
|
283
|
+
def initialize(_app, name:)
|
|
284
|
+
@name = name
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
let(:rock) do
|
|
289
|
+
subject.handlers.find { |handler| handler == rock_handler }.build
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
it 'adds a handler to construct adapter with options passed to insert' do
|
|
293
|
+
subject.insert 0, rock_handler, name: 'Stony'
|
|
294
|
+
expect { rock }.to_not output(
|
|
295
|
+
/warning: Using the last argument as keyword parameters is deprecated/
|
|
296
|
+
).to_stderr
|
|
297
|
+
expect(rock.name).to eq('Stony')
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
it 'adds a handler with options passed to insert_after' do
|
|
301
|
+
subject.insert_after 0, rock_handler, name: 'Rocky'
|
|
302
|
+
expect { rock }.to_not output(
|
|
303
|
+
/warning: Using the last argument as keyword parameters is deprecated/
|
|
304
|
+
).to_stderr
|
|
305
|
+
expect(rock.name).to eq('Rocky')
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it 'adds a handler with options passed to swap' do
|
|
309
|
+
subject.insert 0, rock_handler, name: 'Flint'
|
|
310
|
+
subject.swap 0, rock_handler, name: 'Chert'
|
|
311
|
+
expect { rock }.to_not output(
|
|
312
|
+
/warning: Using the last argument as keyword parameters is deprecated/
|
|
313
|
+
).to_stderr
|
|
314
|
+
expect(rock.name).to eq('Chert')
|
|
315
|
+
end
|
|
195
316
|
end
|
|
196
317
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
RSpec.describe Faraday::Request::Authorization do
|
|
4
4
|
let(:conn) do
|
|
5
5
|
Faraday.new do |b|
|
|
6
|
-
b.request auth_type, *auth_config
|
|
6
|
+
b.request :authorization, auth_type, *auth_config
|
|
7
7
|
b.adapter :test do |stub|
|
|
8
8
|
stub.get('/auth-echo') do |env|
|
|
9
9
|
[200, {}, env[:request_headers]['Authorization']]
|
|
@@ -14,10 +14,10 @@ RSpec.describe Faraday::Request::Authorization do
|
|
|
14
14
|
|
|
15
15
|
shared_examples 'does not interfere with existing authentication' do
|
|
16
16
|
context 'and request already has an authentication header' do
|
|
17
|
-
let(:response) { conn.get('/auth-echo', nil, authorization: '
|
|
17
|
+
let(:response) { conn.get('/auth-echo', nil, authorization: 'OAuth oauth_token') }
|
|
18
18
|
|
|
19
19
|
it 'does not interfere with existing authorization' do
|
|
20
|
-
expect(response.body).to eq('
|
|
20
|
+
expect(response.body).to eq('OAuth oauth_token')
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
@@ -25,7 +25,7 @@ RSpec.describe Faraday::Request::Authorization do
|
|
|
25
25
|
let(:response) { conn.get('/auth-echo') }
|
|
26
26
|
|
|
27
27
|
describe 'basic_auth' do
|
|
28
|
-
let(:auth_type) { :
|
|
28
|
+
let(:auth_type) { :basic }
|
|
29
29
|
|
|
30
30
|
context 'when passed correct params' do
|
|
31
31
|
let(:auth_config) { %w[aladdin opensesame] }
|
|
@@ -44,43 +44,73 @@ RSpec.describe Faraday::Request::Authorization do
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
describe '
|
|
48
|
-
let(:auth_type) { :
|
|
47
|
+
describe 'authorization' do
|
|
48
|
+
let(:auth_type) { :Bearer }
|
|
49
49
|
|
|
50
|
-
context 'when passed
|
|
51
|
-
let(:auth_config) { '
|
|
50
|
+
context 'when passed a string' do
|
|
51
|
+
let(:auth_config) { ['custom'] }
|
|
52
52
|
|
|
53
|
-
it { expect(response.body).to eq('
|
|
53
|
+
it { expect(response.body).to eq('Bearer custom') }
|
|
54
54
|
|
|
55
55
|
include_examples 'does not interfere with existing authentication'
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
context 'when
|
|
59
|
-
let(:auth_config) { ['
|
|
58
|
+
context 'when passed a proc' do
|
|
59
|
+
let(:auth_config) { [-> { 'custom_from_proc' }] }
|
|
60
60
|
|
|
61
|
-
it { expect(response.body).to
|
|
62
|
-
it { expect(response.body).to match(/token="baz"/) }
|
|
63
|
-
it { expect(response.body).to match(/foo="42"/) }
|
|
61
|
+
it { expect(response.body).to eq('Bearer custom_from_proc') }
|
|
64
62
|
|
|
65
63
|
include_examples 'does not interfere with existing authentication'
|
|
66
64
|
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
describe 'authorization' do
|
|
70
|
-
let(:auth_type) { :authorization }
|
|
71
65
|
|
|
72
|
-
context 'when passed
|
|
73
|
-
let(:
|
|
66
|
+
context 'when passed a callable' do
|
|
67
|
+
let(:callable) { double('Callable Authorizer', call: 'custom_from_callable') }
|
|
68
|
+
let(:auth_config) { [callable] }
|
|
74
69
|
|
|
75
|
-
it { expect(response.body).to eq('
|
|
70
|
+
it { expect(response.body).to eq('Bearer custom_from_callable') }
|
|
76
71
|
|
|
77
72
|
include_examples 'does not interfere with existing authentication'
|
|
78
73
|
end
|
|
79
74
|
|
|
80
|
-
context '
|
|
81
|
-
let(:
|
|
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
|
+
|
|
110
|
+
context 'when passed too many arguments' do
|
|
111
|
+
let(:auth_config) { %w[baz foo] }
|
|
82
112
|
|
|
83
|
-
it { expect
|
|
113
|
+
it { expect { response }.to raise_error(ArgumentError) }
|
|
84
114
|
|
|
85
115
|
include_examples 'does not interfere with existing authentication'
|
|
86
116
|
end
|
|
@@ -30,13 +30,11 @@ RSpec.describe Faraday::Request::Instrumentation do
|
|
|
30
30
|
|
|
31
31
|
it { expect(options.name).to eq('request.faraday') }
|
|
32
32
|
it 'defaults to ActiveSupport::Notifications' do
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
expect(res).to eq(ActiveSupport::Notifications)
|
|
39
|
-
end
|
|
33
|
+
res = options.instrumenter
|
|
34
|
+
rescue NameError => e
|
|
35
|
+
expect(e.to_s).to match('ActiveSupport')
|
|
36
|
+
else
|
|
37
|
+
expect(res).to eq(ActiveSupport::Notifications)
|
|
40
38
|
end
|
|
41
39
|
|
|
42
40
|
it 'instruments with default name' do
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Faraday::Request::Json do
|
|
4
|
+
let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }) }
|
|
5
|
+
|
|
6
|
+
def process(body, content_type = nil)
|
|
7
|
+
env = { body: body, request_headers: Faraday::Utils::Headers.new }
|
|
8
|
+
env[:request_headers]['content-type'] = content_type if content_type
|
|
9
|
+
middleware.call(Faraday::Env.from(env)).env
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def result_body
|
|
13
|
+
result[:body]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def result_type
|
|
17
|
+
result[:request_headers]['content-type']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'no body' do
|
|
21
|
+
let(:result) { process(nil) }
|
|
22
|
+
|
|
23
|
+
it "doesn't change body" do
|
|
24
|
+
expect(result_body).to be_nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "doesn't add content type" do
|
|
28
|
+
expect(result_type).to be_nil
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'empty body' do
|
|
33
|
+
let(:result) { process('') }
|
|
34
|
+
|
|
35
|
+
it "doesn't change body" do
|
|
36
|
+
expect(result_body).to be_empty
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "doesn't add content type" do
|
|
40
|
+
expect(result_type).to be_nil
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context 'string body' do
|
|
45
|
+
let(:result) { process('{"a":1}') }
|
|
46
|
+
|
|
47
|
+
it "doesn't change body" do
|
|
48
|
+
expect(result_body).to eq('{"a":1}')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'adds content type' do
|
|
52
|
+
expect(result_type).to eq('application/json')
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context 'object body' do
|
|
57
|
+
let(:result) { process(a: 1) }
|
|
58
|
+
|
|
59
|
+
it 'encodes body' do
|
|
60
|
+
expect(result_body).to eq('{"a":1}')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'adds content type' do
|
|
64
|
+
expect(result_type).to eq('application/json')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'empty object body' do
|
|
69
|
+
let(:result) { process({}) }
|
|
70
|
+
|
|
71
|
+
it 'encodes body' do
|
|
72
|
+
expect(result_body).to eq('{}')
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'true body' do
|
|
77
|
+
let(:result) { process(true) }
|
|
78
|
+
|
|
79
|
+
it 'encodes body' do
|
|
80
|
+
expect(result_body).to eq('true')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'adds content type' do
|
|
84
|
+
expect(result_type).to eq('application/json')
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context 'false body' do
|
|
89
|
+
let(:result) { process(false) }
|
|
90
|
+
|
|
91
|
+
it 'encodes body' do
|
|
92
|
+
expect(result_body).to eq('false')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'adds content type' do
|
|
96
|
+
expect(result_type).to eq('application/json')
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context 'object body with json type' do
|
|
101
|
+
let(:result) { process({ a: 1 }, 'application/json; charset=utf-8') }
|
|
102
|
+
|
|
103
|
+
it 'encodes body' do
|
|
104
|
+
expect(result_body).to eq('{"a":1}')
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "doesn't change content type" do
|
|
108
|
+
expect(result_type).to eq('application/json; charset=utf-8')
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context 'object body with vendor json type' do
|
|
113
|
+
let(:result) { process({ a: 1 }, 'application/vnd.myapp.v1+json; charset=utf-8') }
|
|
114
|
+
|
|
115
|
+
it 'encodes body' do
|
|
116
|
+
expect(result_body).to eq('{"a":1}')
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "doesn't change content type" do
|
|
120
|
+
expect(result_type).to eq('application/vnd.myapp.v1+json; charset=utf-8')
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context 'object body with incompatible type' do
|
|
125
|
+
let(:result) { process({ a: 1 }, 'application/xml; charset=utf-8') }
|
|
126
|
+
|
|
127
|
+
it "doesn't change body" do
|
|
128
|
+
expect(result_body).to eq(a: 1)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "doesn't change content type" do
|
|
132
|
+
expect(result_type).to eq('application/xml; charset=utf-8')
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context 'with encoder' do
|
|
137
|
+
let(:encoder) do
|
|
138
|
+
double('Encoder').tap do |e|
|
|
139
|
+
allow(e).to receive(:dump) { |s, opts| JSON.generate(s, opts) }
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
let(:result) { process(a: 1) }
|
|
144
|
+
|
|
145
|
+
context 'when encoder is passed as object' do
|
|
146
|
+
let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }, { encoder: encoder }) }
|
|
147
|
+
|
|
148
|
+
it 'calls specified JSON encoder\'s dump method' do
|
|
149
|
+
expect(encoder).to receive(:dump).with({ a: 1 })
|
|
150
|
+
|
|
151
|
+
result
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'encodes body' do
|
|
155
|
+
expect(result_body).to eq('{"a":1}')
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it 'adds content type' do
|
|
159
|
+
expect(result_type).to eq('application/json')
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
context 'when encoder is passed as an object-method pair' do
|
|
164
|
+
let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }, { encoder: [encoder, :dump] }) }
|
|
165
|
+
|
|
166
|
+
it 'calls specified JSON encoder' do
|
|
167
|
+
expect(encoder).to receive(:dump).with({ a: 1 })
|
|
168
|
+
|
|
169
|
+
result
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it 'encodes body' do
|
|
173
|
+
expect(result_body).to eq('{"a":1}')
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it 'adds content type' do
|
|
177
|
+
expect(result_type).to eq('application/json')
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
context 'when encoder is not passed' do
|
|
182
|
+
let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }) }
|
|
183
|
+
|
|
184
|
+
it 'calls JSON.generate' do
|
|
185
|
+
expect(JSON).to receive(:generate).with({ a: 1 })
|
|
186
|
+
|
|
187
|
+
result
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it 'encodes body' do
|
|
191
|
+
expect(result_body).to eq('{"a":1}')
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'adds content type' do
|
|
195
|
+
expect(result_type).to eq('application/json')
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
@@ -1,14 +1,19 @@
|
|
|
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|
|
|
6
|
-
b.request :multipart
|
|
7
8
|
b.request :url_encoded
|
|
8
9
|
b.adapter :test do |stub|
|
|
9
10
|
stub.post('/echo') do |env|
|
|
10
11
|
posted_as = env[:request_headers]['Content-Type']
|
|
11
|
-
|
|
12
|
+
body = env[:body]
|
|
13
|
+
if body.respond_to?(:read)
|
|
14
|
+
body = body.read
|
|
15
|
+
end
|
|
16
|
+
[200, { 'Content-Type' => posted_as }, body]
|
|
12
17
|
end
|
|
13
18
|
end
|
|
14
19
|
end
|
|
@@ -67,4 +72,22 @@ RSpec.describe Faraday::Request::UrlEncoded do
|
|
|
67
72
|
response = conn.post('/echo', 'a' => { 'b' => { 'c' => ['d'] } })
|
|
68
73
|
expect(response.body).to eq('a%5Bb%5D%5Bc%5D%5B%5D=d')
|
|
69
74
|
end
|
|
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
|
+
|
|
81
|
+
context 'customising default_space_encoding' do
|
|
82
|
+
around do |example|
|
|
83
|
+
Faraday::Utils.default_space_encoding = '%20'
|
|
84
|
+
example.run
|
|
85
|
+
Faraday::Utils.default_space_encoding = nil
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'uses the custom character to encode spaces' do
|
|
89
|
+
response = conn.post('/echo', str: 'apple banana')
|
|
90
|
+
expect(response.body).to eq('str=apple%20banana')
|
|
91
|
+
end
|
|
92
|
+
end
|
|
70
93
|
end
|