faraday 1.1.0 → 1.10.3
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 +104 -0
- data/README.md +1 -2
- data/examples/client_spec.rb +34 -2
- data/examples/client_test.rb +41 -2
- data/lib/faraday/adapter/test.rb +59 -43
- data/lib/faraday/adapter.rb +1 -12
- data/lib/faraday/autoload.rb +1 -9
- data/lib/faraday/connection.rb +34 -6
- data/lib/faraday/deprecate.rb +110 -0
- data/lib/faraday/error.rb +12 -6
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +14 -4
- data/lib/faraday/options/proxy_options.rb +4 -0
- data/lib/faraday/request/authorization.rb +14 -7
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request.rb +10 -12
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +2 -4
- data/lib/faraday/response.rb +3 -7
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +67 -40
- data/spec/faraday/adapter/em_http_spec.rb +39 -37
- data/spec/faraday/adapter/em_synchrony_spec.rb +11 -9
- data/spec/faraday/adapter/test_spec.rb +117 -0
- data/spec/faraday/connection_spec.rb +45 -0
- data/spec/faraday/deprecate_spec.rb +147 -0
- data/spec/faraday/error_spec.rb +15 -0
- data/spec/faraday/middleware_spec.rb +32 -6
- data/spec/faraday/options/proxy_options_spec.rb +7 -0
- data/spec/faraday/request/authorization_spec.rb +8 -0
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request_spec.rb +1 -1
- data/spec/faraday/response/json_spec.rb +119 -0
- data/spec/faraday/response/raise_error_spec.rb +30 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/shared_examples/adapter.rb +2 -1
- data/spec/support/shared_examples/request_method.rb +36 -8
- metadata +143 -32
- data/lib/faraday/adapter/em_http.rb +0 -286
- 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 -152
- data/lib/faraday/adapter/net_http.rb +0 -219
- 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/file_part.rb +0 -128
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/request/multipart.rb +0 -106
- data/lib/faraday/request/retry.rb +0 -239
- data/spec/faraday/adapter/net_http_persistent_spec.rb +0 -57
- data/spec/faraday/request/multipart_spec.rb +0 -302
- data/spec/faraday/request/retry_spec.rb +0 -242
@@ -0,0 +1,111 @@
|
|
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 'object body with json type' do
|
77
|
+
let(:result) { process({ a: 1 }, 'application/json; charset=utf-8') }
|
78
|
+
|
79
|
+
it 'encodes body' do
|
80
|
+
expect(result_body).to eq('{"a":1}')
|
81
|
+
end
|
82
|
+
|
83
|
+
it "doesn't change content type" do
|
84
|
+
expect(result_type).to eq('application/json; charset=utf-8')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'object body with vendor json type' do
|
89
|
+
let(:result) { process({ a: 1 }, 'application/vnd.myapp.v1+json; charset=utf-8') }
|
90
|
+
|
91
|
+
it 'encodes body' do
|
92
|
+
expect(result_body).to eq('{"a":1}')
|
93
|
+
end
|
94
|
+
|
95
|
+
it "doesn't change content type" do
|
96
|
+
expect(result_type).to eq('application/vnd.myapp.v1+json; charset=utf-8')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'object body with incompatible type' do
|
101
|
+
let(:result) { process({ a: 1 }, 'application/xml; charset=utf-8') }
|
102
|
+
|
103
|
+
it "doesn't change 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/xml; charset=utf-8')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -25,7 +25,7 @@ RSpec.describe Faraday::Request do
|
|
25
25
|
describe 'deprecate method for HTTP method' do
|
26
26
|
let(:http_method) { :post }
|
27
27
|
let(:expected_warning) do
|
28
|
-
%r{
|
28
|
+
%r{NOTE: Faraday::Request#method is deprecated; use http_method instead\. It will be removed in or after version 2.0 \nFaraday::Request#method called from .+/spec/faraday/request_spec.rb:\d+.}
|
29
29
|
end
|
30
30
|
|
31
31
|
it { expect(subject.method).to eq(:post) }
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::Response::Json, type: :response do
|
4
|
+
let(:options) { {} }
|
5
|
+
let(:headers) { {} }
|
6
|
+
let(:middleware) do
|
7
|
+
described_class.new(lambda { |env|
|
8
|
+
Faraday::Response.new(env)
|
9
|
+
}, **options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def process(body, content_type = 'application/json', options = {})
|
13
|
+
env = {
|
14
|
+
body: body, request: options,
|
15
|
+
request_headers: Faraday::Utils::Headers.new,
|
16
|
+
response_headers: Faraday::Utils::Headers.new(headers)
|
17
|
+
}
|
18
|
+
env[:response_headers]['content-type'] = content_type if content_type
|
19
|
+
yield(env) if block_given?
|
20
|
+
middleware.call(Faraday::Env.from(env))
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'no type matching' do
|
24
|
+
it "doesn't change nil body" do
|
25
|
+
expect(process(nil).body).to be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'nullifies empty body' do
|
29
|
+
expect(process('').body).to be_nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'parses json body' do
|
33
|
+
response = process('{"a":1}')
|
34
|
+
expect(response.body).to eq('a' => 1)
|
35
|
+
expect(response.env[:raw_body]).to be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with preserving raw' do
|
40
|
+
let(:options) { { preserve_raw: true } }
|
41
|
+
|
42
|
+
it 'parses json body' do
|
43
|
+
response = process('{"a":1}')
|
44
|
+
expect(response.body).to eq('a' => 1)
|
45
|
+
expect(response.env[:raw_body]).to eq('{"a":1}')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with default regexp type matching' do
|
50
|
+
it 'parses json body of correct type' do
|
51
|
+
response = process('{"a":1}', 'application/x-json')
|
52
|
+
expect(response.body).to eq('a' => 1)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'ignores json body of incorrect type' do
|
56
|
+
response = process('{"a":1}', 'text/json-xml')
|
57
|
+
expect(response.body).to eq('{"a":1}')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with array type matching' do
|
62
|
+
let(:options) { { content_type: %w[a/b c/d] } }
|
63
|
+
|
64
|
+
it 'parses json body of correct type' do
|
65
|
+
expect(process('{"a":1}', 'a/b').body).to be_a(Hash)
|
66
|
+
expect(process('{"a":1}', 'c/d').body).to be_a(Hash)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'ignores json body of incorrect type' do
|
70
|
+
expect(process('{"a":1}', 'a/d').body).not_to be_a(Hash)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'chokes on invalid json' do
|
75
|
+
expect { process('{!') }.to raise_error(Faraday::ParsingError)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'includes the response on the ParsingError instance' do
|
79
|
+
begin
|
80
|
+
process('{') { |env| env[:response] = Faraday::Response.new }
|
81
|
+
raise 'Parsing should have failed.'
|
82
|
+
rescue Faraday::ParsingError => e
|
83
|
+
expect(e.response).to be_a(Faraday::Response)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'HEAD responses' do
|
88
|
+
it "nullifies the body if it's only one space" do
|
89
|
+
response = process(' ')
|
90
|
+
expect(response.body).to be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it "nullifies the body if it's two spaces" do
|
94
|
+
response = process(' ')
|
95
|
+
expect(response.body).to be_nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'JSON options' do
|
100
|
+
let(:body) { '{"a": 1}' }
|
101
|
+
let(:result) { { a: 1 } }
|
102
|
+
let(:options) do
|
103
|
+
{
|
104
|
+
parser_options: {
|
105
|
+
symbolize_names: true
|
106
|
+
}
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'passes relevant options to JSON parse' do
|
111
|
+
expect(::JSON).to receive(:parse)
|
112
|
+
.with(body, options[:parser_options])
|
113
|
+
.and_return(result)
|
114
|
+
|
115
|
+
response = process(body)
|
116
|
+
expect(response.body).to eq(result)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -29,6 +29,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
29
29
|
expect(ex.message).to eq('the server responded with status 400')
|
30
30
|
expect(ex.response[:headers]['X-Reason']).to eq('because')
|
31
31
|
expect(ex.response[:status]).to eq(400)
|
32
|
+
expect(ex.response_status).to eq(400)
|
33
|
+
expect(ex.response_body).to eq('keep looking')
|
34
|
+
expect(ex.response_headers['X-Reason']).to eq('because')
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
@@ -37,6 +40,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
37
40
|
expect(ex.message).to eq('the server responded with status 401')
|
38
41
|
expect(ex.response[:headers]['X-Reason']).to eq('because')
|
39
42
|
expect(ex.response[:status]).to eq(401)
|
43
|
+
expect(ex.response_status).to eq(401)
|
44
|
+
expect(ex.response_body).to eq('keep looking')
|
45
|
+
expect(ex.response_headers['X-Reason']).to eq('because')
|
40
46
|
end
|
41
47
|
end
|
42
48
|
|
@@ -45,6 +51,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
45
51
|
expect(ex.message).to eq('the server responded with status 403')
|
46
52
|
expect(ex.response[:headers]['X-Reason']).to eq('because')
|
47
53
|
expect(ex.response[:status]).to eq(403)
|
54
|
+
expect(ex.response_status).to eq(403)
|
55
|
+
expect(ex.response_body).to eq('keep looking')
|
56
|
+
expect(ex.response_headers['X-Reason']).to eq('because')
|
48
57
|
end
|
49
58
|
end
|
50
59
|
|
@@ -53,6 +62,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
53
62
|
expect(ex.message).to eq('the server responded with status 404')
|
54
63
|
expect(ex.response[:headers]['X-Reason']).to eq('because')
|
55
64
|
expect(ex.response[:status]).to eq(404)
|
65
|
+
expect(ex.response_status).to eq(404)
|
66
|
+
expect(ex.response_body).to eq('keep looking')
|
67
|
+
expect(ex.response_headers['X-Reason']).to eq('because')
|
56
68
|
end
|
57
69
|
end
|
58
70
|
|
@@ -61,6 +73,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
61
73
|
expect(ex.message).to eq('407 "Proxy Authentication Required"')
|
62
74
|
expect(ex.response[:headers]['X-Reason']).to eq('because')
|
63
75
|
expect(ex.response[:status]).to eq(407)
|
76
|
+
expect(ex.response_status).to eq(407)
|
77
|
+
expect(ex.response_body).to eq('keep looking')
|
78
|
+
expect(ex.response_headers['X-Reason']).to eq('because')
|
64
79
|
end
|
65
80
|
end
|
66
81
|
|
@@ -69,6 +84,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
69
84
|
expect(ex.message).to eq('the server responded with status 409')
|
70
85
|
expect(ex.response[:headers]['X-Reason']).to eq('because')
|
71
86
|
expect(ex.response[:status]).to eq(409)
|
87
|
+
expect(ex.response_status).to eq(409)
|
88
|
+
expect(ex.response_body).to eq('keep looking')
|
89
|
+
expect(ex.response_headers['X-Reason']).to eq('because')
|
72
90
|
end
|
73
91
|
end
|
74
92
|
|
@@ -77,6 +95,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
77
95
|
expect(ex.message).to eq('the server responded with status 422')
|
78
96
|
expect(ex.response[:headers]['X-Reason']).to eq('because')
|
79
97
|
expect(ex.response[:status]).to eq(422)
|
98
|
+
expect(ex.response_status).to eq(422)
|
99
|
+
expect(ex.response_body).to eq('keep looking')
|
100
|
+
expect(ex.response_headers['X-Reason']).to eq('because')
|
80
101
|
end
|
81
102
|
end
|
82
103
|
|
@@ -85,6 +106,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
85
106
|
expect(ex.message).to eq('http status could not be derived from the server response')
|
86
107
|
expect(ex.response[:headers]['X-Reason']).to eq('nil')
|
87
108
|
expect(ex.response[:status]).to be_nil
|
109
|
+
expect(ex.response_status).to be_nil
|
110
|
+
expect(ex.response_body).to eq('fail')
|
111
|
+
expect(ex.response_headers['X-Reason']).to eq('nil')
|
88
112
|
end
|
89
113
|
end
|
90
114
|
|
@@ -93,6 +117,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
93
117
|
expect(ex.message).to eq('the server responded with status 499')
|
94
118
|
expect(ex.response[:headers]['X-Reason']).to eq('because')
|
95
119
|
expect(ex.response[:status]).to eq(499)
|
120
|
+
expect(ex.response_status).to eq(499)
|
121
|
+
expect(ex.response_body).to eq('keep looking')
|
122
|
+
expect(ex.response_headers['X-Reason']).to eq('because')
|
96
123
|
end
|
97
124
|
end
|
98
125
|
|
@@ -101,6 +128,9 @@ RSpec.describe Faraday::Response::RaiseError do
|
|
101
128
|
expect(ex.message).to eq('the server responded with status 500')
|
102
129
|
expect(ex.response[:headers]['X-Error']).to eq('bailout')
|
103
130
|
expect(ex.response[:status]).to eq(500)
|
131
|
+
expect(ex.response_status).to eq(500)
|
132
|
+
expect(ex.response_body).to eq('fail')
|
133
|
+
expect(ex.response_headers['X-Error']).to eq('bailout')
|
104
134
|
end
|
105
135
|
end
|
106
136
|
|
data/spec/spec_helper.rb
CHANGED
@@ -38,6 +38,8 @@ require 'pry'
|
|
38
38
|
|
39
39
|
Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
|
40
40
|
|
41
|
+
Faraday::Deprecate.skip = false
|
42
|
+
|
41
43
|
RSpec.configure do |config|
|
42
44
|
# rspec-expectations config goes here. You can use an alternate
|
43
45
|
# assertion/expectation library such as wrong or the stdlib/minitest
|
@@ -33,6 +33,7 @@ shared_examples 'adapter examples' do |**options|
|
|
33
33
|
|
34
34
|
let(:protocol) { ssl_mode? ? 'https' : 'http' }
|
35
35
|
let(:remote) { "#{protocol}://example.com" }
|
36
|
+
let(:stub_remote) { remote }
|
36
37
|
|
37
38
|
let(:conn) do
|
38
39
|
conn_options[:ssl] ||= {}
|
@@ -46,7 +47,7 @@ shared_examples 'adapter examples' do |**options|
|
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
|
-
let!(:request_stub) { stub_request(http_method,
|
50
|
+
let!(:request_stub) { stub_request(http_method, stub_remote) }
|
50
51
|
|
51
52
|
after do
|
52
53
|
expect(request_stub).to have_been_requested unless request_stub.disabled?
|
@@ -1,5 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
shared_examples 'proxy examples' do
|
4
|
+
it 'handles requests with proxy' do
|
5
|
+
res = conn.public_send(http_method, '/')
|
6
|
+
|
7
|
+
expect(res.status).to eq(200)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'handles proxy failures' do
|
11
|
+
request_stub.to_return(status: 407)
|
12
|
+
|
13
|
+
expect { conn.public_send(http_method, '/') }.to raise_error(Faraday::ProxyAuthError)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
3
17
|
shared_examples 'a request method' do |http_method|
|
4
18
|
let(:query_or_body) { method_with_body?(http_method) ? :body : :query }
|
5
19
|
let(:response) { conn.public_send(http_method, '/') }
|
@@ -218,17 +232,31 @@ shared_examples 'a request method' do |http_method|
|
|
218
232
|
end
|
219
233
|
end
|
220
234
|
|
221
|
-
|
222
|
-
|
235
|
+
context 'when a proxy is provided as option' do
|
236
|
+
before do
|
237
|
+
conn_options[:proxy] = 'http://env-proxy.com:80'
|
238
|
+
end
|
223
239
|
|
224
|
-
|
225
|
-
expect(res.status).to eq(200)
|
240
|
+
include_examples 'proxy examples'
|
226
241
|
end
|
227
242
|
|
228
|
-
|
229
|
-
|
230
|
-
request_stub.to_return(status: 407)
|
243
|
+
context 'when http_proxy env variable is set' do
|
244
|
+
let(:proxy_url) { 'http://env-proxy.com:80' }
|
231
245
|
|
232
|
-
|
246
|
+
around do |example|
|
247
|
+
with_env 'http_proxy' => proxy_url do
|
248
|
+
example.run
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
include_examples 'proxy examples'
|
253
|
+
|
254
|
+
context 'when the env proxy is ignored' do
|
255
|
+
around do |example|
|
256
|
+
with_env_proxy_disabled(&example)
|
257
|
+
end
|
258
|
+
|
259
|
+
include_examples 'proxy examples'
|
260
|
+
end
|
233
261
|
end
|
234
262
|
end
|