809 lines
24 KiB
Ruby
809 lines
24 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class CustomEncoder
|
|
def encode(params)
|
|
params.map { |k, v| "#{k.upcase}-#{v.to_s.upcase}" }.join(',')
|
|
end
|
|
|
|
def decode(params)
|
|
params.split(',').to_h { |pair| pair.split('-') }
|
|
end
|
|
end
|
|
|
|
shared_examples 'initializer with url' do
|
|
context 'with simple url' do
|
|
let(:address) { 'http://httpbingo.org' }
|
|
|
|
it { expect(subject.host).to eq('httpbingo.org') }
|
|
it { expect(subject.port).to eq(80) }
|
|
it { expect(subject.scheme).to eq('http') }
|
|
it { expect(subject.path_prefix).to eq('/') }
|
|
it { expect(subject.params).to eq({}) }
|
|
end
|
|
|
|
context 'with complex url' do
|
|
let(:address) { 'http://httpbingo.org:815/fish?a=1' }
|
|
|
|
it { expect(subject.port).to eq(815) }
|
|
it { expect(subject.path_prefix).to eq('/fish') }
|
|
it { expect(subject.params).to eq('a' => '1') }
|
|
end
|
|
|
|
context 'with IPv6 address' do
|
|
let(:address) { 'http://[::1]:85/' }
|
|
|
|
it { expect(subject.host).to eq('[::1]') }
|
|
it { expect(subject.port).to eq(85) }
|
|
end
|
|
end
|
|
|
|
shared_examples 'default connection options' do
|
|
after { Faraday.default_connection_options = nil }
|
|
|
|
it 'works with implicit url' do
|
|
conn = Faraday.new 'http://httpbingo.org/foo'
|
|
expect(conn.options.timeout).to eq(10)
|
|
end
|
|
|
|
it 'works with option url' do
|
|
conn = Faraday.new url: 'http://httpbingo.org/foo'
|
|
expect(conn.options.timeout).to eq(10)
|
|
end
|
|
|
|
it 'works with instance connection options' do
|
|
conn = Faraday.new 'http://httpbingo.org/foo', request: { open_timeout: 1 }
|
|
expect(conn.options.timeout).to eq(10)
|
|
expect(conn.options.open_timeout).to eq(1)
|
|
end
|
|
|
|
it 'default connection options persist with an instance overriding' do
|
|
conn = Faraday.new 'http://nigiri.com/bar'
|
|
conn.options.timeout = 1
|
|
expect(Faraday.default_connection_options.request.timeout).to eq(10)
|
|
|
|
other = Faraday.new url: 'https://httpbingo.org/foo'
|
|
other.options.timeout = 1
|
|
|
|
expect(Faraday.default_connection_options.request.timeout).to eq(10)
|
|
end
|
|
|
|
it 'default connection uses default connection options' do
|
|
expect(Faraday.default_connection.options.timeout).to eq(10)
|
|
end
|
|
end
|
|
|
|
RSpec.describe Faraday::Connection do
|
|
let(:conn) { Faraday::Connection.new(url, options) }
|
|
let(:url) { nil }
|
|
let(:options) { nil }
|
|
|
|
describe '.new' do
|
|
subject { conn }
|
|
|
|
context 'with implicit url param' do
|
|
# Faraday::Connection.new('http://httpbingo.org')
|
|
let(:url) { address }
|
|
|
|
it_behaves_like 'initializer with url'
|
|
end
|
|
|
|
context 'with explicit url param' do
|
|
# Faraday::Connection.new(url: 'http://httpbingo.org')
|
|
let(:url) { { url: address } }
|
|
|
|
it_behaves_like 'initializer with url'
|
|
end
|
|
|
|
context 'with custom builder' do
|
|
let(:custom_builder) { Faraday::RackBuilder.new }
|
|
let(:options) { { builder: custom_builder } }
|
|
|
|
it { expect(subject.builder).to eq(custom_builder) }
|
|
end
|
|
|
|
context 'with custom params' do
|
|
let(:options) { { params: { a: 1 } } }
|
|
|
|
it { expect(subject.params).to eq('a' => 1) }
|
|
end
|
|
|
|
context 'with custom params and params in url' do
|
|
let(:url) { 'http://httpbingo.org/fish?a=1&b=2' }
|
|
let(:options) { { params: { a: 3 } } }
|
|
it { expect(subject.params).to eq('a' => 3, 'b' => '2') }
|
|
end
|
|
|
|
context 'with basic_auth in url' do
|
|
let(:url) { 'http://Aladdin:open%20sesame@httpbingo.org/fish' }
|
|
|
|
it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') }
|
|
end
|
|
|
|
context 'with custom headers' do
|
|
let(:options) { { headers: { user_agent: 'Faraday' } } }
|
|
|
|
it { expect(subject.headers['User-agent']).to eq('Faraday') }
|
|
end
|
|
|
|
context 'with ssl false' do
|
|
let(:options) { { ssl: { verify: false } } }
|
|
|
|
it { expect(subject.ssl.verify?).to be_falsey }
|
|
end
|
|
|
|
context 'with verify_hostname false' do
|
|
let(:options) { { ssl: { verify_hostname: false } } }
|
|
|
|
it { expect(subject.ssl.verify_hostname?).to be_falsey }
|
|
end
|
|
|
|
context 'with empty block' do
|
|
let(:conn) { Faraday::Connection.new {} }
|
|
|
|
it { expect(conn.builder.handlers.size).to eq(0) }
|
|
end
|
|
|
|
context 'with block' do
|
|
let(:conn) do
|
|
Faraday::Connection.new(params: { 'a' => '1' }) do |faraday|
|
|
faraday.adapter :test
|
|
faraday.url_prefix = 'http://httpbingo.org/omnom'
|
|
end
|
|
end
|
|
|
|
it { expect(conn.builder.handlers.size).to eq(0) }
|
|
it { expect(conn.path_prefix).to eq('/omnom') }
|
|
end
|
|
end
|
|
|
|
describe '#close' do
|
|
before { Faraday.default_adapter = :test }
|
|
after { Faraday.default_adapter = nil }
|
|
|
|
it 'can close underlying app' do
|
|
expect(conn.app).to receive(:close)
|
|
conn.close
|
|
end
|
|
end
|
|
|
|
describe '#build_exclusive_url' do
|
|
context 'with relative path' do
|
|
subject { conn.build_exclusive_url('sake.html') }
|
|
|
|
it 'uses connection host as default host' do
|
|
conn.host = 'httpbingo.org'
|
|
expect(subject.host).to eq('httpbingo.org')
|
|
expect(subject.scheme).to eq('http')
|
|
end
|
|
|
|
it do
|
|
conn.path_prefix = '/fish'
|
|
expect(subject.path).to eq('/fish/sake.html')
|
|
end
|
|
|
|
it do
|
|
conn.path_prefix = '/'
|
|
expect(subject.path).to eq('/sake.html')
|
|
end
|
|
|
|
it do
|
|
conn.path_prefix = 'fish'
|
|
expect(subject.path).to eq('/fish/sake.html')
|
|
end
|
|
|
|
it do
|
|
conn.path_prefix = '/fish/'
|
|
expect(subject.path).to eq('/fish/sake.html')
|
|
end
|
|
end
|
|
|
|
context 'with absolute path' do
|
|
subject { conn.build_exclusive_url('/sake.html') }
|
|
|
|
after { expect(subject.path).to eq('/sake.html') }
|
|
|
|
it { conn.path_prefix = '/fish' }
|
|
it { conn.path_prefix = '/' }
|
|
it { conn.path_prefix = 'fish' }
|
|
it { conn.path_prefix = '/fish/' }
|
|
end
|
|
|
|
context 'with complete url' do
|
|
subject { conn.build_exclusive_url('http://httpbingo.org/sake.html?a=1') }
|
|
|
|
it { expect(subject.scheme).to eq('http') }
|
|
it { expect(subject.host).to eq('httpbingo.org') }
|
|
it { expect(subject.port).to eq(80) }
|
|
it { expect(subject.path).to eq('/sake.html') }
|
|
it { expect(subject.query).to eq('a=1') }
|
|
end
|
|
|
|
it 'overrides connection port for absolute url' do
|
|
conn.port = 23
|
|
uri = conn.build_exclusive_url('http://httpbingo.org')
|
|
expect(uri.port).to eq(80)
|
|
end
|
|
|
|
it 'does not add ending slash given nil url' do
|
|
conn.url_prefix = 'http://httpbingo.org/nigiri'
|
|
uri = conn.build_exclusive_url
|
|
expect(uri.path).to eq('/nigiri')
|
|
end
|
|
|
|
it 'does not add ending slash given empty url' do
|
|
conn.url_prefix = 'http://httpbingo.org/nigiri'
|
|
uri = conn.build_exclusive_url('')
|
|
expect(uri.path).to eq('/nigiri')
|
|
end
|
|
|
|
it 'does not use connection params' do
|
|
conn.url_prefix = 'http://httpbingo.org/nigiri'
|
|
conn.params = { a: 1 }
|
|
expect(conn.build_exclusive_url.to_s).to eq('http://httpbingo.org/nigiri')
|
|
end
|
|
|
|
it 'allows to provide params argument' do
|
|
conn.url_prefix = 'http://httpbingo.org/nigiri'
|
|
conn.params = { a: 1 }
|
|
params = Faraday::Utils::ParamsHash.new
|
|
params[:a] = 2
|
|
uri = conn.build_exclusive_url(nil, params)
|
|
expect(uri.to_s).to eq('http://httpbingo.org/nigiri?a=2')
|
|
end
|
|
|
|
it 'handles uri instances' do
|
|
uri = conn.build_exclusive_url(URI('/sake.html'))
|
|
expect(uri.path).to eq('/sake.html')
|
|
end
|
|
|
|
it 'always returns new URI instance' do
|
|
conn.url_prefix = 'http://httpbingo.org'
|
|
uri1 = conn.build_exclusive_url(nil)
|
|
uri2 = conn.build_exclusive_url(nil)
|
|
expect(uri1).not_to equal(uri2)
|
|
end
|
|
|
|
context 'with url_prefixed connection' do
|
|
let(:url) { 'http://httpbingo.org/get/' }
|
|
|
|
it 'parses url and changes scheme' do
|
|
conn.scheme = 'https'
|
|
uri = conn.build_exclusive_url('sake.html')
|
|
expect(uri.to_s).to eq('https://httpbingo.org/get/sake.html')
|
|
end
|
|
|
|
it 'joins url to base with ending slash' do
|
|
uri = conn.build_exclusive_url('sake.html')
|
|
expect(uri.to_s).to eq('http://httpbingo.org/get/sake.html')
|
|
end
|
|
|
|
it 'used default base with ending slash' do
|
|
uri = conn.build_exclusive_url
|
|
expect(uri.to_s).to eq('http://httpbingo.org/get/')
|
|
end
|
|
|
|
it 'overrides base' do
|
|
uri = conn.build_exclusive_url('/sake/')
|
|
expect(uri.to_s).to eq('http://httpbingo.org/sake/')
|
|
end
|
|
end
|
|
|
|
context 'with colon in path' do
|
|
let(:url) { 'http://service.com' }
|
|
|
|
it 'joins url to base when used absolute path' do
|
|
conn = Faraday.new(url: url)
|
|
uri = conn.build_exclusive_url('/service:search?limit=400')
|
|
expect(uri.to_s).to eq('http://service.com/service:search?limit=400')
|
|
end
|
|
|
|
it 'joins url to base when used relative path' do
|
|
conn = Faraday.new(url: url)
|
|
uri = conn.build_exclusive_url('service:search?limit=400')
|
|
expect(uri.to_s).to eq('http://service.com/service%3Asearch?limit=400')
|
|
end
|
|
|
|
it 'joins url to base when used with path prefix' do
|
|
conn = Faraday.new(url: url)
|
|
conn.path_prefix = '/api'
|
|
uri = conn.build_exclusive_url('service:search?limit=400')
|
|
expect(uri.to_s).to eq('http://service.com/api/service%3Asearch?limit=400')
|
|
end
|
|
end
|
|
|
|
context 'with a custom `default_uri_parser`' do
|
|
let(:url) { 'http://httpbingo.org' }
|
|
let(:parser) { Addressable::URI }
|
|
|
|
around do |example|
|
|
with_default_uri_parser(parser) do
|
|
example.run
|
|
end
|
|
end
|
|
|
|
it 'does not raise error' do
|
|
expect { conn.build_exclusive_url('/nigiri') }.not_to raise_error
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#build_url' do
|
|
let(:url) { 'http://httpbingo.org/nigiri' }
|
|
|
|
it 'uses params' do
|
|
conn.params = { a: 1, b: 1 }
|
|
expect(conn.build_url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=1')
|
|
end
|
|
|
|
it 'merges params' do
|
|
conn.params = { a: 1, b: 1 }
|
|
url = conn.build_url(nil, b: 2, c: 3)
|
|
expect(url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=2&c=3')
|
|
end
|
|
end
|
|
|
|
describe '#build_request' do
|
|
let(:url) { 'https://ahttpbingo.org/sake.html' }
|
|
let(:request) { conn.build_request(:get) }
|
|
|
|
before do
|
|
conn.headers = { 'Authorization' => 'token abc123' }
|
|
request.headers.delete('Authorization')
|
|
end
|
|
|
|
it { expect(conn.headers.keys).to eq(['Authorization']) }
|
|
it { expect(conn.headers.include?('Authorization')).to be_truthy }
|
|
it { expect(request.headers.keys).to be_empty }
|
|
it { expect(request.headers.include?('Authorization')).to be_falsey }
|
|
end
|
|
|
|
describe '#to_env' do
|
|
subject { conn.build_request(:get).to_env(conn).url }
|
|
|
|
let(:url) { 'http://httpbingo.org/sake.html' }
|
|
let(:options) { { params: @params } }
|
|
|
|
it 'parses url params into query' do
|
|
@params = { 'a[b]' => '1 + 2' }
|
|
expect(subject.query).to eq('a%5Bb%5D=1+%2B+2')
|
|
end
|
|
|
|
it 'escapes per spec' do
|
|
@params = { 'a' => '1+2 foo~bar.-baz' }
|
|
expect(subject.query).to eq('a=1%2B2+foo~bar.-baz')
|
|
end
|
|
|
|
it 'bracketizes nested params in query' do
|
|
@params = { 'a' => { 'b' => 'c' } }
|
|
expect(subject.query).to eq('a%5Bb%5D=c')
|
|
end
|
|
|
|
it 'bracketizes repeated params in query' do
|
|
@params = { 'a' => [1, 2] }
|
|
expect(subject.query).to eq('a%5B%5D=1&a%5B%5D=2')
|
|
end
|
|
|
|
it 'without braketizing repeated params in query' do
|
|
@params = { 'a' => [1, 2] }
|
|
conn.options.params_encoder = Faraday::FlatParamsEncoder
|
|
expect(subject.query).to eq('a=1&a=2')
|
|
end
|
|
end
|
|
|
|
describe 'proxy support' do
|
|
it 'accepts string' do
|
|
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
|
conn.proxy = 'http://proxy.com'
|
|
expect(conn.proxy.host).to eq('proxy.com')
|
|
end
|
|
end
|
|
|
|
it 'accepts uri' do
|
|
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
|
conn.proxy = URI.parse('http://proxy.com')
|
|
expect(conn.proxy.host).to eq('proxy.com')
|
|
end
|
|
end
|
|
|
|
it 'accepts hash with string uri' do
|
|
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
|
conn.proxy = { uri: 'http://proxy.com', user: 'rick' }
|
|
expect(conn.proxy.host).to eq('proxy.com')
|
|
expect(conn.proxy.user).to eq('rick')
|
|
end
|
|
end
|
|
|
|
it 'accepts hash' do
|
|
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
|
conn.proxy = { uri: URI.parse('http://proxy.com'), user: 'rick' }
|
|
expect(conn.proxy.host).to eq('proxy.com')
|
|
expect(conn.proxy.user).to eq('rick')
|
|
end
|
|
end
|
|
|
|
it 'accepts http env' do
|
|
with_env 'http_proxy' => 'http://env-proxy.com:80' do
|
|
expect(conn.proxy.host).to eq('env-proxy.com')
|
|
end
|
|
end
|
|
|
|
it 'accepts http env with auth' do
|
|
with_env 'http_proxy' => 'http://a%40b:my%20pass@proxy.com:80' do
|
|
expect(conn.proxy.user).to eq('a@b')
|
|
expect(conn.proxy.password).to eq('my pass')
|
|
end
|
|
end
|
|
|
|
it 'accepts env without scheme' do
|
|
with_env 'http_proxy' => 'localhost:8888' do
|
|
uri = conn.proxy[:uri]
|
|
expect(uri.host).to eq('localhost')
|
|
expect(uri.port).to eq(8888)
|
|
end
|
|
end
|
|
|
|
it 'fetches no proxy from nil env' do
|
|
with_env 'http_proxy' => nil do
|
|
expect(conn.proxy).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'fetches no proxy from blank env' do
|
|
with_env 'http_proxy' => '' do
|
|
expect(conn.proxy).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'does not accept uppercase env' do
|
|
with_env 'HTTP_PROXY' => 'http://localhost:8888/' do
|
|
expect(conn.proxy).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'allows when url in no proxy list' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
|
|
conn = Faraday::Connection.new('http://example.com')
|
|
expect(conn.proxy).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'allows when url in no proxy list with url_prefix' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
|
|
conn = Faraday::Connection.new
|
|
conn.url_prefix = 'http://example.com'
|
|
expect(conn.proxy).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'allows when prefixed url is not in no proxy list' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
|
|
conn = Faraday::Connection.new('http://prefixedexample.com')
|
|
expect(conn.proxy.host).to eq('proxy.com')
|
|
end
|
|
end
|
|
|
|
it 'allows when subdomain url is in no proxy list' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
|
|
conn = Faraday::Connection.new('http://subdomain.example.com')
|
|
expect(conn.proxy).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'allows when url not in no proxy list' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example2.com' do
|
|
conn = Faraday::Connection.new('http://example.com')
|
|
expect(conn.proxy.host).to eq('proxy.com')
|
|
end
|
|
end
|
|
|
|
it 'allows when ip address is not in no proxy list but url is' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'localhost' do
|
|
conn = Faraday::Connection.new('http://127.0.0.1')
|
|
expect(conn.proxy).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'allows when url is not in no proxy list but ip address is' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => '127.0.0.1' do
|
|
conn = Faraday::Connection.new('http://localhost')
|
|
expect(conn.proxy).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'allows in multi element no proxy list' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example0.com,example.com,example1.com' do
|
|
expect(Faraday::Connection.new('http://example0.com').proxy).to be_nil
|
|
expect(Faraday::Connection.new('http://example.com').proxy).to be_nil
|
|
expect(Faraday::Connection.new('http://example1.com').proxy).to be_nil
|
|
expect(Faraday::Connection.new('http://example2.com').proxy.host).to eq('proxy.com')
|
|
end
|
|
end
|
|
|
|
it 'test proxy requires uri' do
|
|
expect { conn.proxy = { uri: :bad_uri, user: 'rick' } }.to raise_error(ArgumentError)
|
|
end
|
|
|
|
it 'uses env http_proxy' do
|
|
with_env 'http_proxy' => 'http://proxy.com' do
|
|
conn = Faraday.new
|
|
expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
|
|
expect(conn.proxy_for_request('http://google.co.uk').host).to eq('proxy.com')
|
|
end
|
|
end
|
|
|
|
it 'uses processes no_proxy before http_proxy' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'google.co.uk' do
|
|
conn = Faraday.new
|
|
expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
|
|
expect(conn.proxy_for_request('http://google.co.uk')).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'uses env https_proxy' do
|
|
with_env 'https_proxy' => 'https://proxy.com' do
|
|
conn = Faraday.new
|
|
expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
|
|
expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy.com')
|
|
end
|
|
end
|
|
|
|
it 'uses processes no_proxy before https_proxy' do
|
|
with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do
|
|
conn = Faraday.new
|
|
expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey
|
|
expect(conn.proxy_for_request('https://google.co.uk')).to be_nil
|
|
end
|
|
end
|
|
|
|
it 'gives priority to manually set proxy' do
|
|
with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do
|
|
conn = Faraday.new
|
|
conn.proxy = 'http://proxy2.com'
|
|
|
|
expect(conn.instance_variable_get(:@manual_proxy)).to be_truthy
|
|
expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy2.com')
|
|
end
|
|
end
|
|
|
|
it 'ignores env proxy if set that way' do
|
|
with_env_proxy_disabled do
|
|
with_env 'http_proxy' => 'http://duncan.proxy.com:80' do
|
|
expect(conn.proxy).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'performing a request' do
|
|
let(:url) { 'http://example.com' }
|
|
let(:conn) do
|
|
Faraday.new do |f|
|
|
f.adapter :test do |stubs|
|
|
stubs.get(url) do
|
|
[200, {}, 'ok']
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
it 'dynamically checks proxy' do
|
|
with_env 'http_proxy' => 'http://proxy.com:80' do
|
|
expect(conn.proxy.uri.host).to eq('proxy.com')
|
|
|
|
conn.get(url) do |req|
|
|
expect(req.options.proxy.uri.host).to eq('proxy.com')
|
|
end
|
|
end
|
|
|
|
conn.get(url)
|
|
expect(conn.instance_variable_get(:@temp_proxy)).to be_nil
|
|
end
|
|
|
|
it 'dynamically check no proxy' do
|
|
with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do
|
|
expect(conn.proxy.uri.host).to eq('proxy.com')
|
|
|
|
conn.get('http://example.com') do |req|
|
|
expect(req.options.proxy).to be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#dup' do
|
|
subject { conn.dup }
|
|
|
|
let(:url) { 'http://httpbingo.org/foo' }
|
|
let(:options) do
|
|
{
|
|
ssl: { verify: :none },
|
|
headers: { 'content-type' => 'text/plain' },
|
|
params: { 'a' => '1' },
|
|
request: { timeout: 5 }
|
|
}
|
|
end
|
|
|
|
it { expect(subject.build_exclusive_url).to eq(conn.build_exclusive_url) }
|
|
it { expect(subject.headers['content-type']).to eq('text/plain') }
|
|
it { expect(subject.params['a']).to eq('1') }
|
|
|
|
context 'after manual changes' do
|
|
before do
|
|
subject.headers['content-length'] = 12
|
|
subject.params['b'] = '2'
|
|
subject.options[:open_timeout] = 10
|
|
end
|
|
|
|
it { expect(subject.builder.handlers.size).to eq(1) }
|
|
it { expect(conn.builder.handlers.size).to eq(1) }
|
|
it { expect(conn.headers.key?('content-length')).to be_falsey }
|
|
it { expect(conn.params.key?('b')).to be_falsey }
|
|
it { expect(subject.options[:timeout]).to eq(5) }
|
|
it { expect(conn.options[:open_timeout]).to be_nil }
|
|
end
|
|
end
|
|
|
|
describe '#respond_to?' do
|
|
it { expect(Faraday.respond_to?(:get)).to be_truthy }
|
|
it { expect(Faraday.respond_to?(:post)).to be_truthy }
|
|
end
|
|
|
|
describe 'default_connection_options' do
|
|
context 'assigning a default value' do
|
|
before do
|
|
Faraday.default_connection_options = nil
|
|
Faraday.default_connection_options.request.timeout = 10
|
|
end
|
|
|
|
it_behaves_like 'default connection options'
|
|
end
|
|
|
|
context 'assigning a hash' do
|
|
before { Faraday.default_connection_options = { request: { timeout: 10 } } }
|
|
|
|
it_behaves_like 'default connection options'
|
|
end
|
|
|
|
context 'preserving a user_agent assigned via default_conncetion_options' do
|
|
around do |example|
|
|
old = Faraday.default_connection_options
|
|
Faraday.default_connection_options = { headers: { user_agent: 'My Agent 1.2' } }
|
|
example.run
|
|
Faraday.default_connection_options = old
|
|
end
|
|
|
|
context 'when url is a Hash' do
|
|
let(:conn) { Faraday.new(url: 'http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) }
|
|
|
|
it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') }
|
|
end
|
|
|
|
context 'when url is a String' do
|
|
let(:conn) { Faraday.new('http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) }
|
|
|
|
it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') }
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'request params' do
|
|
context 'with simple url' do
|
|
let(:url) { 'http://example.com' }
|
|
let(:stubs) { Faraday::Adapter::Test::Stubs.new }
|
|
|
|
before do
|
|
conn.adapter(:test, stubs)
|
|
stubs.get('http://example.com?a=a&p=3') do
|
|
[200, {}, 'ok']
|
|
end
|
|
end
|
|
|
|
after { stubs.verify_stubbed_calls }
|
|
|
|
it 'test_overrides_request_params' do
|
|
conn.get('?p=2&a=a', p: 3)
|
|
end
|
|
|
|
it 'test_overrides_request_params_block' do
|
|
conn.get('?p=1&a=a', p: 2) do |req|
|
|
req.params[:p] = 3
|
|
end
|
|
end
|
|
|
|
it 'test_overrides_request_params_block_url' do
|
|
conn.get(nil, p: 2) do |req|
|
|
req.url('?p=1&a=a', 'p' => 3)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'with url and extra params' do
|
|
let(:url) { 'http://example.com?a=1&b=2' }
|
|
let(:options) { { params: { c: 3 } } }
|
|
let(:stubs) { Faraday::Adapter::Test::Stubs.new }
|
|
|
|
before do
|
|
conn.adapter(:test, stubs)
|
|
end
|
|
|
|
it 'merges connection and request params' do
|
|
expected = 'http://example.com?a=1&b=2&c=3&limit=5&page=1'
|
|
stubs.get(expected) { [200, {}, 'ok'] }
|
|
conn.get('?page=1', limit: 5)
|
|
stubs.verify_stubbed_calls
|
|
end
|
|
|
|
it 'allows to override all params' do
|
|
expected = 'http://example.com?b=b'
|
|
stubs.get(expected) { [200, {}, 'ok'] }
|
|
conn.get('?p=1&a=a', p: 2) do |req|
|
|
expect(req.params[:a]).to eq('a')
|
|
expect(req.params['c']).to eq(3)
|
|
expect(req.params['p']).to eq(2)
|
|
req.params = { b: 'b' }
|
|
expect(req.params['b']).to eq('b')
|
|
end
|
|
stubs.verify_stubbed_calls
|
|
end
|
|
|
|
it 'allows to set params_encoder for single request' do
|
|
encoder = CustomEncoder.new
|
|
expected = 'http://example.com/?A-1,B-2,C-3,FEELING-BLUE'
|
|
stubs.get(expected) { [200, {}, 'ok'] }
|
|
|
|
conn.get('/', a: 1, b: 2, c: 3, feeling: 'blue') do |req|
|
|
req.options.params_encoder = encoder
|
|
end
|
|
stubs.verify_stubbed_calls
|
|
end
|
|
end
|
|
|
|
context 'with default params encoder' do
|
|
let(:stubs) { Faraday::Adapter::Test::Stubs.new }
|
|
|
|
before do
|
|
conn.adapter(:test, stubs)
|
|
stubs.get('http://example.com?color%5B%5D=blue&color%5B%5D=red') do
|
|
[200, {}, 'ok']
|
|
end
|
|
end
|
|
|
|
after { stubs.verify_stubbed_calls }
|
|
|
|
it 'supports array params in url' do
|
|
conn.get('http://example.com?color[]=blue&color[]=red')
|
|
end
|
|
|
|
it 'supports array params in params' do
|
|
conn.get('http://example.com', color: %w[blue red])
|
|
end
|
|
end
|
|
|
|
context 'with flat params encoder' do
|
|
let(:options) { { request: { params_encoder: Faraday::FlatParamsEncoder } } }
|
|
let(:stubs) { Faraday::Adapter::Test::Stubs.new }
|
|
|
|
before do
|
|
conn.adapter(:test, stubs)
|
|
stubs.get('http://example.com?color=blue&color=red') do
|
|
[200, {}, 'ok']
|
|
end
|
|
end
|
|
|
|
after { stubs.verify_stubbed_calls }
|
|
|
|
it 'supports array params in params' do
|
|
conn.get('http://example.com', color: %w[blue red])
|
|
end
|
|
|
|
context 'with array param in url' do
|
|
let(:url) { 'http://example.com?color[]=blue&color[]=red' }
|
|
|
|
it do
|
|
conn.get('/')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|