faraday 0.17.3 → 1.0.1
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 +52 -8
- data/LICENSE.md +1 -1
- data/README.md +18 -358
- data/Rakefile +1 -7
- data/examples/client_spec.rb +65 -0
- data/examples/client_test.rb +79 -0
- data/lib/faraday.rb +94 -175
- data/lib/faraday/adapter.rb +82 -22
- data/lib/faraday/adapter/em_http.rb +142 -99
- data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
- data/lib/faraday/adapter/em_synchrony.rb +104 -60
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
- data/lib/faraday/adapter/excon.rb +98 -56
- data/lib/faraday/adapter/httpclient.rb +83 -59
- data/lib/faraday/adapter/net_http.rb +130 -63
- data/lib/faraday/adapter/net_http_persistent.rb +50 -27
- data/lib/faraday/adapter/patron.rb +80 -43
- data/lib/faraday/adapter/rack.rb +30 -13
- data/lib/faraday/adapter/test.rb +86 -53
- data/lib/faraday/adapter/typhoeus.rb +4 -1
- data/lib/faraday/adapter_registry.rb +30 -0
- data/lib/faraday/autoload.rb +47 -36
- data/lib/faraday/connection.rb +312 -182
- data/lib/faraday/dependency_loader.rb +37 -0
- data/lib/faraday/encoders/flat_params_encoder.rb +98 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
- data/lib/faraday/error.rb +9 -35
- data/lib/faraday/file_part.rb +128 -0
- data/lib/faraday/logging/formatter.rb +105 -0
- data/lib/faraday/middleware.rb +12 -28
- data/lib/faraday/middleware_registry.rb +129 -0
- data/lib/faraday/options.rb +32 -183
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +181 -0
- data/lib/faraday/options/proxy_options.rb +28 -0
- data/lib/faraday/options/request_options.rb +22 -0
- data/lib/faraday/options/ssl_options.rb +59 -0
- data/lib/faraday/param_part.rb +53 -0
- data/lib/faraday/parameters.rb +4 -197
- data/lib/faraday/rack_builder.rb +66 -55
- data/lib/faraday/request.rb +68 -36
- data/lib/faraday/request/authorization.rb +44 -30
- data/lib/faraday/request/basic_authentication.rb +14 -7
- data/lib/faraday/request/instrumentation.rb +45 -27
- data/lib/faraday/request/multipart.rb +79 -48
- data/lib/faraday/request/retry.rb +197 -171
- data/lib/faraday/request/token_authentication.rb +15 -10
- data/lib/faraday/request/url_encoded.rb +43 -23
- data/lib/faraday/response.rb +24 -14
- data/lib/faraday/response/logger.rb +22 -69
- data/lib/faraday/response/raise_error.rb +38 -18
- data/lib/faraday/utils.rb +36 -245
- data/lib/faraday/utils/headers.rb +139 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/spec/faraday/adapter/em_http_spec.rb +47 -0
- data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
- data/spec/faraday/adapter/excon_spec.rb +49 -0
- data/spec/faraday/adapter/httpclient_spec.rb +73 -0
- data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
- data/spec/faraday/adapter/net_http_spec.rb +64 -0
- data/spec/faraday/adapter/patron_spec.rb +18 -0
- data/spec/faraday/adapter/rack_spec.rb +8 -0
- data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/composite_read_io_spec.rb +80 -0
- data/spec/faraday/connection_spec.rb +691 -0
- data/spec/faraday/error_spec.rb +0 -57
- data/spec/faraday/middleware_spec.rb +26 -0
- data/spec/faraday/options/env_spec.rb +70 -0
- data/spec/faraday/options/options_spec.rb +297 -0
- data/spec/faraday/options/proxy_options_spec.rb +37 -0
- data/spec/faraday/options/request_options_spec.rb +19 -0
- data/spec/faraday/params_encoders/flat_spec.rb +34 -0
- data/spec/faraday/params_encoders/nested_spec.rb +134 -0
- data/spec/faraday/rack_builder_spec.rb +196 -0
- data/spec/faraday/request/authorization_spec.rb +88 -0
- data/spec/faraday/request/instrumentation_spec.rb +76 -0
- data/spec/faraday/request/multipart_spec.rb +274 -0
- data/spec/faraday/request/retry_spec.rb +242 -0
- data/spec/faraday/request/url_encoded_spec.rb +83 -0
- data/spec/faraday/request_spec.rb +109 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/middleware_spec.rb +68 -0
- data/spec/faraday/response/raise_error_spec.rb +15 -15
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +56 -0
- data/spec/faraday_spec.rb +37 -0
- data/spec/spec_helper.rb +63 -36
- data/spec/support/disabling_stub.rb +14 -0
- data/spec/support/fake_safe_buffer.rb +15 -0
- data/spec/support/helper_methods.rb +133 -0
- data/spec/support/shared_examples/adapter.rb +104 -0
- data/spec/support/shared_examples/params_encoder.rb +18 -0
- data/spec/support/shared_examples/request_method.rb +234 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- data/spec/support/webmock_rack_app.rb +68 -0
- metadata +66 -38
- data/lib/faraday/deprecate.rb +0 -107
- data/lib/faraday/upload_io.rb +0 -67
- data/spec/faraday/deprecate_spec.rb +0 -69
- data/test/adapters/default_test.rb +0 -14
- data/test/adapters/em_http_test.rb +0 -30
- data/test/adapters/em_synchrony_test.rb +0 -32
- data/test/adapters/excon_test.rb +0 -30
- data/test/adapters/httpclient_test.rb +0 -34
- data/test/adapters/integration.rb +0 -263
- data/test/adapters/logger_test.rb +0 -136
- data/test/adapters/net_http_persistent_test.rb +0 -114
- data/test/adapters/net_http_test.rb +0 -79
- data/test/adapters/patron_test.rb +0 -40
- data/test/adapters/rack_test.rb +0 -38
- data/test/adapters/test_middleware_test.rb +0 -157
- data/test/adapters/typhoeus_test.rb +0 -38
- data/test/authentication_middleware_test.rb +0 -65
- data/test/composite_read_io_test.rb +0 -109
- data/test/connection_test.rb +0 -738
- data/test/env_test.rb +0 -268
- data/test/helper.rb +0 -75
- data/test/live_server.rb +0 -67
- data/test/middleware/instrumentation_test.rb +0 -88
- data/test/middleware/retry_test.rb +0 -282
- data/test/middleware_stack_test.rb +0 -260
- data/test/multibyte.txt +0 -1
- data/test/options_test.rb +0 -333
- data/test/parameters_test.rb +0 -157
- data/test/request_middleware_test.rb +0 -126
- data/test/response_middleware_test.rb +0 -72
- data/test/strawberry.rb +0 -2
- data/test/utils_test.rb +0 -98
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::Adapter::NetHttp do
|
4
|
+
features :request_body_on_query_methods, :reason_phrase_parse, :compression, :streaming, :trace_method
|
5
|
+
|
6
|
+
it_behaves_like 'an adapter'
|
7
|
+
|
8
|
+
context 'checking http' do
|
9
|
+
let(:url) { URI('http://example.com') }
|
10
|
+
let(:adapter) { described_class.new }
|
11
|
+
let(:http) { adapter.send(:connection, url: url, request: {}) }
|
12
|
+
|
13
|
+
it { expect(http.port).to eq(80) }
|
14
|
+
|
15
|
+
it 'sets max_retries to 0' do
|
16
|
+
adapter.send(:configure_request, http, {})
|
17
|
+
|
18
|
+
expect(http.max_retries).to eq(0) if http.respond_to?(:max_retries=)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'supports write_timeout' do
|
22
|
+
adapter.send(:configure_request, http, write_timeout: 10)
|
23
|
+
|
24
|
+
expect(http.write_timeout).to eq(10) if http.respond_to?(:write_timeout=)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'supports open_timeout' do
|
28
|
+
adapter.send(:configure_request, http, open_timeout: 10)
|
29
|
+
|
30
|
+
expect(http.open_timeout).to eq(10)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'supports read_timeout' do
|
34
|
+
adapter.send(:configure_request, http, read_timeout: 10)
|
35
|
+
|
36
|
+
expect(http.read_timeout).to eq(10)
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with https url' do
|
40
|
+
let(:url) { URI('https://example.com') }
|
41
|
+
|
42
|
+
it { expect(http.port).to eq(443) }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with http url including port' do
|
46
|
+
let(:url) { URI('https://example.com:1234') }
|
47
|
+
|
48
|
+
it { expect(http.port).to eq(1234) }
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with custom adapter config' do
|
52
|
+
let(:adapter) do
|
53
|
+
described_class.new do |http|
|
54
|
+
http.continue_timeout = 123
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it do
|
59
|
+
adapter.send(:configure_request, http, {})
|
60
|
+
expect(http.continue_timeout).to eq(123)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::Adapter::Patron, unless: defined?(JRUBY_VERSION) do
|
4
|
+
features :reason_phrase_parse
|
5
|
+
|
6
|
+
it_behaves_like 'an adapter'
|
7
|
+
|
8
|
+
it 'allows to provide adapter specific configs' do
|
9
|
+
conn = Faraday.new do |f|
|
10
|
+
f.adapter :patron do |session|
|
11
|
+
session.max_redirects = 10
|
12
|
+
raise 'Configuration block called'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
expect { conn.get('/') }.to raise_error(RuntimeError, 'Configuration block called')
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::AdapterRegistry do
|
4
|
+
describe '#initialize' do
|
5
|
+
subject(:registry) { described_class.new }
|
6
|
+
|
7
|
+
it { expect { registry.get(:FinFangFoom) }.to raise_error(NameError) }
|
8
|
+
it { expect { registry.get('FinFangFoom') }.to raise_error(NameError) }
|
9
|
+
|
10
|
+
it 'looks up class by string name' do
|
11
|
+
expect(registry.get('Faraday::Connection')).to eq(Faraday::Connection)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'looks up class by symbol name' do
|
15
|
+
expect(registry.get(:Faraday)).to eq(Faraday)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'caches lookups with implicit name' do
|
19
|
+
registry.set :symbol
|
20
|
+
expect(registry.get('symbol')).to eq(:symbol)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'caches lookups with explicit name' do
|
24
|
+
registry.set 'string', :name
|
25
|
+
expect(registry.get(:name)).to eq('string')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Faraday::Adapter do
|
4
|
+
let(:adapter) { Faraday::Adapter.new }
|
5
|
+
let(:request) { {} }
|
6
|
+
|
7
|
+
context '#request_timeout' do
|
8
|
+
it 'gets :read timeout' do
|
9
|
+
expect(timeout(:read)).to eq(nil)
|
10
|
+
|
11
|
+
request[:timeout] = 5
|
12
|
+
request[:write_timeout] = 1
|
13
|
+
|
14
|
+
expect(timeout(:read)).to eq(5)
|
15
|
+
|
16
|
+
request[:read_timeout] = 2
|
17
|
+
|
18
|
+
expect(timeout(:read)).to eq(2)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'gets :open timeout' do
|
22
|
+
expect(timeout(:open)).to eq(nil)
|
23
|
+
|
24
|
+
request[:timeout] = 5
|
25
|
+
request[:write_timeout] = 1
|
26
|
+
|
27
|
+
expect(timeout(:open)).to eq(5)
|
28
|
+
|
29
|
+
request[:open_timeout] = 2
|
30
|
+
|
31
|
+
expect(timeout(:open)).to eq(2)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'gets :write timeout' do
|
35
|
+
expect(timeout(:write)).to eq(nil)
|
36
|
+
|
37
|
+
request[:timeout] = 5
|
38
|
+
request[:read_timeout] = 1
|
39
|
+
|
40
|
+
expect(timeout(:write)).to eq(5)
|
41
|
+
|
42
|
+
request[:write_timeout] = 2
|
43
|
+
|
44
|
+
expect(timeout(:write)).to eq(2)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'attempts unknown timeout type' do
|
48
|
+
expect { timeout(:unknown) }.to raise_error(ArgumentError)
|
49
|
+
end
|
50
|
+
|
51
|
+
def timeout(type)
|
52
|
+
adapter.send(:request_timeout, type, request)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
RSpec.describe Faraday::CompositeReadIO do
|
6
|
+
Part = Struct.new(:to_io) do
|
7
|
+
def length
|
8
|
+
to_io.string.length
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def part(str)
|
13
|
+
Part.new StringIO.new(str)
|
14
|
+
end
|
15
|
+
|
16
|
+
def composite_io(*parts)
|
17
|
+
Faraday::CompositeReadIO.new(*parts)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with empty composite_io' do
|
21
|
+
subject { composite_io }
|
22
|
+
|
23
|
+
it { expect(subject.length).to eq(0) }
|
24
|
+
it { expect(subject.read).to eq('') }
|
25
|
+
it { expect(subject.read(1)).to be_nil }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with empty parts' do
|
29
|
+
subject { composite_io(part(''), part('')) }
|
30
|
+
|
31
|
+
it { expect(subject.length).to eq(0) }
|
32
|
+
it { expect(subject.read).to eq('') }
|
33
|
+
it { expect(subject.read(1)).to be_nil }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with 2 parts' do
|
37
|
+
subject { composite_io(part('abcd'), part('1234')) }
|
38
|
+
|
39
|
+
it { expect(subject.length).to eq(8) }
|
40
|
+
it { expect(subject.read).to eq('abcd1234') }
|
41
|
+
it 'allows to read in chunks' do
|
42
|
+
expect(subject.read(3)).to eq('abc')
|
43
|
+
expect(subject.read(3)).to eq('d12')
|
44
|
+
expect(subject.read(3)).to eq('34')
|
45
|
+
expect(subject.read(3)).to be_nil
|
46
|
+
end
|
47
|
+
it 'allows to rewind while reading in chunks' do
|
48
|
+
expect(subject.read(3)).to eq('abc')
|
49
|
+
expect(subject.read(3)).to eq('d12')
|
50
|
+
subject.rewind
|
51
|
+
expect(subject.read(3)).to eq('abc')
|
52
|
+
expect(subject.read(5)).to eq('d1234')
|
53
|
+
expect(subject.read(3)).to be_nil
|
54
|
+
subject.rewind
|
55
|
+
expect(subject.read(2)).to eq('ab')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with mix of empty and non-empty parts' do
|
60
|
+
subject { composite_io(part(''), part('abcd'), part(''), part('1234'), part('')) }
|
61
|
+
|
62
|
+
it 'allows to read in chunks' do
|
63
|
+
expect(subject.read(6)).to eq('abcd12')
|
64
|
+
expect(subject.read(6)).to eq('34')
|
65
|
+
expect(subject.read(6)).to be_nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with utf8 multibyte part' do
|
70
|
+
subject { composite_io(part("\x86"), part('ファイル')) }
|
71
|
+
|
72
|
+
it { expect(subject.read).to eq(String.new("\x86\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB", encoding: 'BINARY')) }
|
73
|
+
it 'allows to read in chunks' do
|
74
|
+
expect(subject.read(3)).to eq(String.new("\x86\xE3\x83", encoding: 'BINARY'))
|
75
|
+
expect(subject.read(3)).to eq(String.new("\x95\xE3\x82", encoding: 'BINARY'))
|
76
|
+
expect(subject.read(8)).to eq(String.new("\xA1\xE3\x82\xA4\xE3\x83\xAB", encoding: 'BINARY'))
|
77
|
+
expect(subject.read(3)).to be_nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,691 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
shared_examples 'initializer with url' do
|
4
|
+
context 'with simple url' do
|
5
|
+
let(:address) { 'http://sushi.com' }
|
6
|
+
|
7
|
+
it { expect(subject.host).to eq('sushi.com') }
|
8
|
+
it { expect(subject.port).to eq(80) }
|
9
|
+
it { expect(subject.scheme).to eq('http') }
|
10
|
+
it { expect(subject.path_prefix).to eq('/') }
|
11
|
+
it { expect(subject.params).to eq({}) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with complex url' do
|
15
|
+
let(:address) { 'http://sushi.com:815/fish?a=1' }
|
16
|
+
|
17
|
+
it { expect(subject.port).to eq(815) }
|
18
|
+
it { expect(subject.path_prefix).to eq('/fish') }
|
19
|
+
it { expect(subject.params).to eq('a' => '1') }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
shared_examples 'default connection options' do
|
24
|
+
after { Faraday.default_connection_options = nil }
|
25
|
+
|
26
|
+
it 'works with implicit url' do
|
27
|
+
conn = Faraday.new 'http://sushi.com/foo'
|
28
|
+
expect(conn.options.timeout).to eq(10)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'works with option url' do
|
32
|
+
conn = Faraday.new url: 'http://sushi.com/foo'
|
33
|
+
expect(conn.options.timeout).to eq(10)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'works with instance connection options' do
|
37
|
+
conn = Faraday.new 'http://sushi.com/foo', request: { open_timeout: 1 }
|
38
|
+
expect(conn.options.timeout).to eq(10)
|
39
|
+
expect(conn.options.open_timeout).to eq(1)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'default connection options persist with an instance overriding' do
|
43
|
+
conn = Faraday.new 'http://nigiri.com/bar'
|
44
|
+
conn.options.timeout = 1
|
45
|
+
expect(Faraday.default_connection_options.request.timeout).to eq(10)
|
46
|
+
|
47
|
+
other = Faraday.new url: 'https://sushi.com/foo'
|
48
|
+
other.options.timeout = 1
|
49
|
+
|
50
|
+
expect(Faraday.default_connection_options.request.timeout).to eq(10)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'default connection uses default connection options' do
|
54
|
+
expect(Faraday.default_connection.options.timeout).to eq(10)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
RSpec.describe Faraday::Connection do
|
59
|
+
let(:conn) { Faraday::Connection.new(url, options) }
|
60
|
+
let(:url) { nil }
|
61
|
+
let(:options) { nil }
|
62
|
+
|
63
|
+
describe '.new' do
|
64
|
+
subject { conn }
|
65
|
+
|
66
|
+
context 'with implicit url param' do
|
67
|
+
# Faraday::Connection.new('http://sushi.com')
|
68
|
+
let(:url) { address }
|
69
|
+
|
70
|
+
it_behaves_like 'initializer with url'
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'with explicit url param' do
|
74
|
+
# Faraday::Connection.new(url: 'http://sushi.com')
|
75
|
+
let(:url) { { url: address } }
|
76
|
+
|
77
|
+
it_behaves_like 'initializer with url'
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with custom builder' do
|
81
|
+
let(:custom_builder) { Faraday::RackBuilder.new }
|
82
|
+
let(:options) { { builder: custom_builder } }
|
83
|
+
|
84
|
+
it { expect(subject.builder).to eq(custom_builder) }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'with custom params' do
|
88
|
+
let(:options) { { params: { a: 1 } } }
|
89
|
+
|
90
|
+
it { expect(subject.params).to eq('a' => 1) }
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'with custom params and params in url' do
|
94
|
+
let(:url) { 'http://sushi.com/fish?a=1&b=2' }
|
95
|
+
let(:options) { { params: { a: 3 } } }
|
96
|
+
it { expect(subject.params).to eq('a' => 3, 'b' => '2') }
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'with custom headers' do
|
100
|
+
let(:options) { { headers: { user_agent: 'Faraday' } } }
|
101
|
+
|
102
|
+
it { expect(subject.headers['User-agent']).to eq('Faraday') }
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'with ssl false' do
|
106
|
+
let(:options) { { ssl: { verify: false } } }
|
107
|
+
|
108
|
+
it { expect(subject.ssl.verify?).to be_falsey }
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'with empty block' do
|
112
|
+
let(:conn) { Faraday::Connection.new {} }
|
113
|
+
|
114
|
+
it { expect(conn.builder.handlers.size).to eq(0) }
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'with block' do
|
118
|
+
let(:conn) do
|
119
|
+
Faraday::Connection.new(params: { 'a' => '1' }) do |faraday|
|
120
|
+
faraday.adapter :net_http
|
121
|
+
faraday.url_prefix = 'http://sushi.com/omnom'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it { expect(conn.builder.handlers.size).to eq(0) }
|
126
|
+
it { expect(conn.path_prefix).to eq('/omnom') }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#close' do
|
131
|
+
it 'can close underlying app' do
|
132
|
+
expect(conn.app).to receive(:close)
|
133
|
+
conn.close
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe 'basic_auth' do
|
138
|
+
subject { conn }
|
139
|
+
|
140
|
+
context 'calling the #basic_auth method' do
|
141
|
+
before { subject.basic_auth 'Aladdin', 'open sesame' }
|
142
|
+
|
143
|
+
it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'adding basic auth info to url' do
|
147
|
+
let(:url) { 'http://Aladdin:open%20sesame@sushi.com/fish' }
|
148
|
+
|
149
|
+
it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#token_auth' do
|
154
|
+
before { subject.token_auth('abcdef', nonce: 'abc') }
|
155
|
+
|
156
|
+
it { expect(subject.headers['Authorization']).to eq('Token nonce="abc", token="abcdef"') }
|
157
|
+
end
|
158
|
+
|
159
|
+
describe '#build_exclusive_url' do
|
160
|
+
context 'with relative path' do
|
161
|
+
subject { conn.build_exclusive_url('sake.html') }
|
162
|
+
|
163
|
+
it 'uses connection host as default host' do
|
164
|
+
conn.host = 'sushi.com'
|
165
|
+
expect(subject.host).to eq('sushi.com')
|
166
|
+
expect(subject.scheme).to eq('http')
|
167
|
+
end
|
168
|
+
|
169
|
+
it do
|
170
|
+
conn.path_prefix = '/fish'
|
171
|
+
expect(subject.path).to eq('/fish/sake.html')
|
172
|
+
end
|
173
|
+
|
174
|
+
it do
|
175
|
+
conn.path_prefix = '/'
|
176
|
+
expect(subject.path).to eq('/sake.html')
|
177
|
+
end
|
178
|
+
|
179
|
+
it do
|
180
|
+
conn.path_prefix = 'fish'
|
181
|
+
expect(subject.path).to eq('/fish/sake.html')
|
182
|
+
end
|
183
|
+
|
184
|
+
it do
|
185
|
+
conn.path_prefix = '/fish/'
|
186
|
+
expect(subject.path).to eq('/fish/sake.html')
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'with absolute path' do
|
191
|
+
subject { conn.build_exclusive_url('/sake.html') }
|
192
|
+
|
193
|
+
after { expect(subject.path).to eq('/sake.html') }
|
194
|
+
|
195
|
+
it { conn.path_prefix = '/fish' }
|
196
|
+
it { conn.path_prefix = '/' }
|
197
|
+
it { conn.path_prefix = 'fish' }
|
198
|
+
it { conn.path_prefix = '/fish/' }
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'with complete url' do
|
202
|
+
subject { conn.build_exclusive_url('http://sushi.com/sake.html?a=1') }
|
203
|
+
|
204
|
+
it { expect(subject.scheme).to eq('http') }
|
205
|
+
it { expect(subject.host).to eq('sushi.com') }
|
206
|
+
it { expect(subject.port).to eq(80) }
|
207
|
+
it { expect(subject.path).to eq('/sake.html') }
|
208
|
+
it { expect(subject.query).to eq('a=1') }
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'overrides connection port for absolute url' do
|
212
|
+
conn.port = 23
|
213
|
+
uri = conn.build_exclusive_url('http://sushi.com')
|
214
|
+
expect(uri.port).to eq(80)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'does not add ending slash given nil url' do
|
218
|
+
conn.url_prefix = 'http://sushi.com/nigiri'
|
219
|
+
uri = conn.build_exclusive_url
|
220
|
+
expect(uri.path).to eq('/nigiri')
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'does not add ending slash given empty url' do
|
224
|
+
conn.url_prefix = 'http://sushi.com/nigiri'
|
225
|
+
uri = conn.build_exclusive_url('')
|
226
|
+
expect(uri.path).to eq('/nigiri')
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'does not use connection params' do
|
230
|
+
conn.url_prefix = 'http://sushi.com/nigiri'
|
231
|
+
conn.params = { a: 1 }
|
232
|
+
expect(conn.build_exclusive_url.to_s).to eq('http://sushi.com/nigiri')
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'allows to provide params argument' do
|
236
|
+
conn.url_prefix = 'http://sushi.com/nigiri'
|
237
|
+
conn.params = { a: 1 }
|
238
|
+
params = Faraday::Utils::ParamsHash.new
|
239
|
+
params[:a] = 2
|
240
|
+
uri = conn.build_exclusive_url(nil, params)
|
241
|
+
expect(uri.to_s).to eq('http://sushi.com/nigiri?a=2')
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'handles uri instances' do
|
245
|
+
uri = conn.build_exclusive_url(URI('/sake.html'))
|
246
|
+
expect(uri.path).to eq('/sake.html')
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'with url_prefixed connection' do
|
250
|
+
let(:url) { 'http://sushi.com/sushi/' }
|
251
|
+
|
252
|
+
it 'parses url and changes scheme' do
|
253
|
+
conn.scheme = 'https'
|
254
|
+
uri = conn.build_exclusive_url('sake.html')
|
255
|
+
expect(uri.to_s).to eq('https://sushi.com/sushi/sake.html')
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'joins url to base with ending slash' do
|
259
|
+
uri = conn.build_exclusive_url('sake.html')
|
260
|
+
expect(uri.to_s).to eq('http://sushi.com/sushi/sake.html')
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'used default base with ending slash' do
|
264
|
+
uri = conn.build_exclusive_url
|
265
|
+
expect(uri.to_s).to eq('http://sushi.com/sushi/')
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'overrides base' do
|
269
|
+
uri = conn.build_exclusive_url('/sake/')
|
270
|
+
expect(uri.to_s).to eq('http://sushi.com/sake/')
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe '#build_url' do
|
276
|
+
let(:url) { 'http://sushi.com/nigiri' }
|
277
|
+
|
278
|
+
it 'uses params' do
|
279
|
+
conn.params = { a: 1, b: 1 }
|
280
|
+
expect(conn.build_url.to_s).to eq('http://sushi.com/nigiri?a=1&b=1')
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'merges params' do
|
284
|
+
conn.params = { a: 1, b: 1 }
|
285
|
+
url = conn.build_url(nil, b: 2, c: 3)
|
286
|
+
expect(url.to_s).to eq('http://sushi.com/nigiri?a=1&b=2&c=3')
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe '#build_request' do
|
291
|
+
let(:url) { 'https://asushi.com/sake.html' }
|
292
|
+
let(:request) { conn.build_request(:get) }
|
293
|
+
|
294
|
+
before do
|
295
|
+
conn.headers = { 'Authorization' => 'token abc123' }
|
296
|
+
request.headers.delete('Authorization')
|
297
|
+
end
|
298
|
+
|
299
|
+
it { expect(conn.headers.keys).to eq(['Authorization']) }
|
300
|
+
it { expect(conn.headers.include?('Authorization')).to be_truthy }
|
301
|
+
it { expect(request.headers.keys).to be_empty }
|
302
|
+
it { expect(request.headers.include?('Authorization')).to be_falsey }
|
303
|
+
end
|
304
|
+
|
305
|
+
describe '#to_env' do
|
306
|
+
subject { conn.build_request(:get).to_env(conn).url }
|
307
|
+
|
308
|
+
let(:url) { 'http://sushi.com/sake.html' }
|
309
|
+
let(:options) { { params: @params } }
|
310
|
+
|
311
|
+
it 'parses url params into query' do
|
312
|
+
@params = { 'a[b]' => '1 + 2' }
|
313
|
+
expect(subject.query).to eq('a%5Bb%5D=1+%2B+2')
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'escapes per spec' do
|
317
|
+
@params = { 'a' => '1+2 foo~bar.-baz' }
|
318
|
+
expect(subject.query).to eq('a=1%2B2+foo~bar.-baz')
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'bracketizes nested params in query' do
|
322
|
+
@params = { 'a' => { 'b' => 'c' } }
|
323
|
+
expect(subject.query).to eq('a%5Bb%5D=c')
|
324
|
+
end
|
325
|
+
|
326
|
+
it 'bracketizes repeated params in query' do
|
327
|
+
@params = { 'a' => [1, 2] }
|
328
|
+
expect(subject.query).to eq('a%5B%5D=1&a%5B%5D=2')
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'without braketizing repeated params in query' do
|
332
|
+
@params = { 'a' => [1, 2] }
|
333
|
+
conn.options.params_encoder = Faraday::FlatParamsEncoder
|
334
|
+
expect(subject.query).to eq('a=1&a=2')
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
describe 'proxy support' do
|
339
|
+
it 'accepts string' do
|
340
|
+
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
341
|
+
conn.proxy = 'http://proxy.com'
|
342
|
+
expect(conn.proxy.host).to eq('proxy.com')
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'accepts uri' do
|
347
|
+
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
348
|
+
conn.proxy = URI.parse('http://proxy.com')
|
349
|
+
expect(conn.proxy.host).to eq('proxy.com')
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
it 'accepts hash with string uri' do
|
354
|
+
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
355
|
+
conn.proxy = { uri: 'http://proxy.com', user: 'rick' }
|
356
|
+
expect(conn.proxy.host).to eq('proxy.com')
|
357
|
+
expect(conn.proxy.user).to eq('rick')
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
it 'accepts hash' do
|
362
|
+
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
363
|
+
conn.proxy = { uri: URI.parse('http://proxy.com'), user: 'rick' }
|
364
|
+
expect(conn.proxy.host).to eq('proxy.com')
|
365
|
+
expect(conn.proxy.user).to eq('rick')
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
it 'accepts http env' do
|
370
|
+
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
371
|
+
expect(conn.proxy.host).to eq('env-proxy.com')
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
it 'accepts http env with auth' do
|
376
|
+
with_env 'http_proxy' => 'http://a%40b:my%20pass@proxy.com:80' do
|
377
|
+
expect(conn.proxy.user).to eq('a@b')
|
378
|
+
expect(conn.proxy.password).to eq('my pass')
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
it 'accepts env without scheme' do
|
383
|
+
with_env 'http_proxy' => 'localhost:8888' do
|
384
|
+
uri = conn.proxy[:uri]
|
385
|
+
expect(uri.host).to eq('localhost')
|
386
|
+
expect(uri.port).to eq(8888)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'fetches no proxy from nil env' do
|
391
|
+
with_env 'http_proxy' => nil do
|
392
|
+
expect(conn.proxy).to be_nil
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
it 'fetches no proxy from blank env' do
|
397
|
+
with_env 'http_proxy' => '' do
|
398
|
+
expect(conn.proxy).to be_nil
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
it 'does not accept uppercase env' do
|
403
|
+
with_env 'HTTP_PROXY' => 'http://localhost:8888/' do
|
404
|
+
expect(conn.proxy).to be_nil
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'allows when url in no proxy list' do
|
409
|
+
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
|
410
|
+
conn = Faraday::Connection.new('http://example.com')
|
411
|
+
expect(conn.proxy).to be_nil
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
it 'allows when prefixed url is not in no proxy list' do
|
416
|
+
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
|
417
|
+
conn = Faraday::Connection.new('http://prefixedexample.com')
|
418
|
+
expect(conn.proxy.host).to eq('proxy.com')
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
it 'allows when subdomain url is in no proxy list' do
|
423
|
+
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
|
424
|
+
conn = Faraday::Connection.new('http://subdomain.example.com')
|
425
|
+
expect(conn.proxy).to be_nil
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'allows when url not in no proxy list' do
|
430
|
+
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example2.com' do
|
431
|
+
conn = Faraday::Connection.new('http://example.com')
|
432
|
+
expect(conn.proxy.host).to eq('proxy.com')
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
it 'allows when ip address is not in no proxy list but url is' do
|
437
|
+
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'localhost' do
|
438
|
+
conn = Faraday::Connection.new('http://127.0.0.1')
|
439
|
+
expect(conn.proxy).to be_nil
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
it 'allows when url is not in no proxy list but ip address is' do
|
444
|
+
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => '127.0.0.1' do
|
445
|
+
conn = Faraday::Connection.new('http://localhost')
|
446
|
+
expect(conn.proxy).to be_nil
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
it 'allows in multi element no proxy list' do
|
451
|
+
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example0.com,example.com,example1.com' do
|
452
|
+
expect(Faraday::Connection.new('http://example0.com').proxy).to be_nil
|
453
|
+
expect(Faraday::Connection.new('http://example.com').proxy).to be_nil
|
454
|
+
expect(Faraday::Connection.new('http://example1.com').proxy).to be_nil
|
455
|
+
expect(Faraday::Connection.new('http://example2.com').proxy.host).to eq('proxy.com')
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
it 'test proxy requires uri' do
|
460
|
+
expect { conn.proxy = { uri: :bad_uri, user: 'rick' } }.to raise_error(ArgumentError)
|
461
|
+
end
|
462
|
+
|
463
|
+
it 'uses env http_proxy' do
|
464
|
+
with_env 'http_proxy' => 'http://proxy.com' do
|
465
|
+
conn = Faraday.new
|
466
|
+
expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
|
467
|
+
expect(conn.proxy_for_request('http://google.co.uk').host).to eq('proxy.com')
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
it 'uses processes no_proxy before http_proxy' do
|
472
|
+
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'google.co.uk' do
|
473
|
+
conn = Faraday.new
|
474
|
+
expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
|
475
|
+
expect(conn.proxy_for_request('http://google.co.uk')).to be_nil
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
it 'uses env https_proxy' do
|
480
|
+
with_env 'https_proxy' => 'https://proxy.com' do
|
481
|
+
conn = Faraday.new
|
482
|
+
expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
|
483
|
+
expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy.com')
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
it 'uses processes no_proxy before https_proxy' do
|
488
|
+
with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do
|
489
|
+
conn = Faraday.new
|
490
|
+
expect(conn.instance_variable_get('@manual_proxy')).to be_falsey
|
491
|
+
expect(conn.proxy_for_request('https://google.co.uk')).to be_nil
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
it 'gives priority to manually set proxy' do
|
496
|
+
with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do
|
497
|
+
conn = Faraday.new
|
498
|
+
conn.proxy = 'http://proxy2.com'
|
499
|
+
|
500
|
+
expect(conn.instance_variable_get('@manual_proxy')).to be_truthy
|
501
|
+
expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy2.com')
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
it 'ignores env proxy if set that way' do
|
506
|
+
with_env_proxy_disabled do
|
507
|
+
with_env 'http_proxy' => 'http://duncan.proxy.com:80' do
|
508
|
+
expect(conn.proxy).to be_nil
|
509
|
+
end
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
context 'performing a request' do
|
514
|
+
before { stub_request(:get, 'http://example.com') }
|
515
|
+
|
516
|
+
it 'dynamically checks proxy' do
|
517
|
+
with_env 'http_proxy' => 'http://proxy.com:80' do
|
518
|
+
conn = Faraday.new
|
519
|
+
expect(conn.proxy.uri.host).to eq('proxy.com')
|
520
|
+
|
521
|
+
conn.get('http://example.com') do |req|
|
522
|
+
expect(req.options.proxy.uri.host).to eq('proxy.com')
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
conn.get('http://example.com')
|
527
|
+
expect(conn.instance_variable_get('@temp_proxy')).to be_nil
|
528
|
+
end
|
529
|
+
|
530
|
+
it 'dynamically check no proxy' do
|
531
|
+
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
|
532
|
+
conn = Faraday.new
|
533
|
+
|
534
|
+
expect(conn.proxy.uri.host).to eq('proxy.com')
|
535
|
+
|
536
|
+
conn.get('http://example.com') do |req|
|
537
|
+
expect(req.options.proxy).to be_nil
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
describe '#dup' do
|
545
|
+
subject { conn.dup }
|
546
|
+
|
547
|
+
let(:url) { 'http://sushi.com/foo' }
|
548
|
+
let(:options) do
|
549
|
+
{
|
550
|
+
ssl: { verify: :none },
|
551
|
+
headers: { 'content-type' => 'text/plain' },
|
552
|
+
params: { 'a' => '1' },
|
553
|
+
request: { timeout: 5 }
|
554
|
+
}
|
555
|
+
end
|
556
|
+
|
557
|
+
it { expect(subject.build_exclusive_url).to eq(conn.build_exclusive_url) }
|
558
|
+
it { expect(subject.headers['content-type']).to eq('text/plain') }
|
559
|
+
it { expect(subject.params['a']).to eq('1') }
|
560
|
+
|
561
|
+
context 'after manual changes' do
|
562
|
+
before do
|
563
|
+
subject.basic_auth('', '')
|
564
|
+
subject.headers['content-length'] = 12
|
565
|
+
subject.params['b'] = '2'
|
566
|
+
subject.options[:open_timeout] = 10
|
567
|
+
end
|
568
|
+
|
569
|
+
it { expect(subject.builder.handlers.size).to eq(1) }
|
570
|
+
it { expect(conn.builder.handlers.size).to eq(1) }
|
571
|
+
it { expect(conn.headers.key?('content-length')).to be_falsey }
|
572
|
+
it { expect(conn.params.key?('b')).to be_falsey }
|
573
|
+
it { expect(subject.options[:timeout]).to eq(5) }
|
574
|
+
it { expect(conn.options[:open_timeout]).to be_nil }
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
describe '#respond_to?' do
|
579
|
+
it { expect(Faraday.respond_to?(:get)).to be_truthy }
|
580
|
+
it { expect(Faraday.respond_to?(:post)).to be_truthy }
|
581
|
+
end
|
582
|
+
|
583
|
+
describe 'default_connection_options' do
|
584
|
+
context 'assigning a default value' do
|
585
|
+
before do
|
586
|
+
Faraday.default_connection_options = nil
|
587
|
+
Faraday.default_connection_options.request.timeout = 10
|
588
|
+
end
|
589
|
+
|
590
|
+
it_behaves_like 'default connection options'
|
591
|
+
end
|
592
|
+
|
593
|
+
context 'assigning a hash' do
|
594
|
+
before { Faraday.default_connection_options = { request: { timeout: 10 } } }
|
595
|
+
|
596
|
+
it_behaves_like 'default connection options'
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
describe 'request params' do
|
601
|
+
context 'with simple url' do
|
602
|
+
let(:url) { 'http://example.com' }
|
603
|
+
let!(:stubbed) { stub_request(:get, 'http://example.com?a=a&p=3') }
|
604
|
+
|
605
|
+
after { expect(stubbed).to have_been_made.once }
|
606
|
+
|
607
|
+
it 'test_overrides_request_params' do
|
608
|
+
conn.get('?p=2&a=a', p: 3)
|
609
|
+
end
|
610
|
+
|
611
|
+
it 'test_overrides_request_params_block' do
|
612
|
+
conn.get('?p=1&a=a', p: 2) do |req|
|
613
|
+
req.params[:p] = 3
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
it 'test_overrides_request_params_block_url' do
|
618
|
+
conn.get(nil, p: 2) do |req|
|
619
|
+
req.url('?p=1&a=a', 'p' => 3)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
context 'with url and extra params' do
|
625
|
+
let(:url) { 'http://example.com?a=1&b=2' }
|
626
|
+
let(:options) { { params: { c: 3 } } }
|
627
|
+
|
628
|
+
it 'merges connection and request params' do
|
629
|
+
stubbed = stub_request(:get, 'http://example.com?a=1&b=2&c=3&limit=5&page=1')
|
630
|
+
conn.get('?page=1', limit: 5)
|
631
|
+
expect(stubbed).to have_been_made.once
|
632
|
+
end
|
633
|
+
|
634
|
+
it 'allows to override all params' do
|
635
|
+
stubbed = stub_request(:get, 'http://example.com?b=b')
|
636
|
+
conn.get('?p=1&a=a', p: 2) do |req|
|
637
|
+
expect(req.params[:a]).to eq('a')
|
638
|
+
expect(req.params['c']).to eq(3)
|
639
|
+
expect(req.params['p']).to eq(2)
|
640
|
+
req.params = { b: 'b' }
|
641
|
+
expect(req.params['b']).to eq('b')
|
642
|
+
end
|
643
|
+
expect(stubbed).to have_been_made.once
|
644
|
+
end
|
645
|
+
|
646
|
+
it 'allows to set params_encoder for single request' do
|
647
|
+
encoder = Object.new
|
648
|
+
def encoder.encode(params)
|
649
|
+
params.map { |k, v| "#{k.upcase}-#{v.to_s.upcase}" }.join(',')
|
650
|
+
end
|
651
|
+
stubbed = stub_request(:get, 'http://example.com/?A-1,B-2,C-3,FEELING-BLUE')
|
652
|
+
|
653
|
+
conn.get('/', feeling: 'blue') do |req|
|
654
|
+
req.options.params_encoder = encoder
|
655
|
+
end
|
656
|
+
expect(stubbed).to have_been_made.once
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
context 'with default params encoder' do
|
661
|
+
let!(:stubbed) { stub_request(:get, 'http://example.com?color%5B%5D=red&color%5B%5D=blue') }
|
662
|
+
after { expect(stubbed).to have_been_made.once }
|
663
|
+
|
664
|
+
it 'supports array params in url' do
|
665
|
+
conn.get('http://example.com?color[]=red&color[]=blue')
|
666
|
+
end
|
667
|
+
|
668
|
+
it 'supports array params in params' do
|
669
|
+
conn.get('http://example.com', color: %w[red blue])
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
context 'with flat params encoder' do
|
674
|
+
let(:options) { { request: { params_encoder: Faraday::FlatParamsEncoder } } }
|
675
|
+
let!(:stubbed) { stub_request(:get, 'http://example.com?color=blue') }
|
676
|
+
after { expect(stubbed).to have_been_made.once }
|
677
|
+
|
678
|
+
it 'supports array params in params' do
|
679
|
+
conn.get('http://example.com', color: %w[red blue])
|
680
|
+
end
|
681
|
+
|
682
|
+
context 'with array param in url' do
|
683
|
+
let(:url) { 'http://example.com?color[]=red&color[]=blue' }
|
684
|
+
|
685
|
+
it do
|
686
|
+
conn.get('/')
|
687
|
+
end
|
688
|
+
end
|
689
|
+
end
|
690
|
+
end
|
691
|
+
end
|