mirror of
https://github.com/lostisland/faraday.git
synced 2025-10-04 00:02:03 -04:00
Respect the params_encoder
in Faraday::Adapter::Test
(#1316)
This commit is contained in:
parent
dd1552f3ff
commit
0f9626c48d
@ -81,4 +81,17 @@ RSpec.describe Client do
|
||||
stubs.verify_stubbed_calls
|
||||
end
|
||||
end
|
||||
|
||||
context 'When the Faraday connection is configured with FlatParamsEncoder' do
|
||||
let(:conn) { Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) { |b| b.adapter(:test, stubs) } }
|
||||
|
||||
it 'handles the same multiple URL parameters' do
|
||||
stubs.get('/ebi?a=x&a=y&a=z') { [200, { 'Content-Type' => 'application/json' }, '{"name": "shrimp"}'] }
|
||||
|
||||
# uncomment to raise Stubs::NotFound
|
||||
# expect(client.sushi('ebi', params: { a: %w[x y] })).to eq('shrimp')
|
||||
expect(client.sushi('ebi', params: { a: %w[x y z] })).to eq('shrimp')
|
||||
stubs.verify_stubbed_calls
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -13,8 +13,8 @@ class Client
|
||||
@conn = conn
|
||||
end
|
||||
|
||||
def sushi(jname)
|
||||
res = @conn.get("/#{jname}")
|
||||
def sushi(jname, params: {})
|
||||
res = @conn.get("/#{jname}", params)
|
||||
data = JSON.parse(res.body)
|
||||
data['name']
|
||||
end
|
||||
@ -70,6 +70,45 @@ class ClientTest < Test::Unit::TestCase
|
||||
stubs.verify_stubbed_calls
|
||||
end
|
||||
|
||||
def test_strict_mode
|
||||
stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true)
|
||||
stubs.get('/ebi?abc=123') do
|
||||
[
|
||||
200,
|
||||
{ 'Content-Type': 'application/javascript' },
|
||||
'{"name": "shrimp"}'
|
||||
]
|
||||
end
|
||||
|
||||
cli = client(stubs)
|
||||
assert_equal 'shrimp', cli.sushi('ebi', params: { abc: 123 })
|
||||
|
||||
# uncomment to raise Stubs::NotFound
|
||||
# assert_equal 'shrimp', cli.sushi('ebi', params: { abc: 123, foo: 'Kappa' })
|
||||
stubs.verify_stubbed_calls
|
||||
end
|
||||
|
||||
def test_non_default_params_encoder
|
||||
stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true)
|
||||
stubs.get('/ebi?a=x&a=y&a=z') do
|
||||
[
|
||||
200,
|
||||
{ 'Content-Type': 'application/javascript' },
|
||||
'{"name": "shrimp"}'
|
||||
]
|
||||
end
|
||||
conn = Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) do |builder|
|
||||
builder.adapter :test, stubs
|
||||
end
|
||||
|
||||
cli = Client.new(conn)
|
||||
assert_equal 'shrimp', cli.sushi('ebi', params: { a: %w[x y z] })
|
||||
|
||||
# uncomment to raise Stubs::NotFound
|
||||
# assert_equal 'shrimp', cli.sushi('ebi', params: { a: %w[x y] })
|
||||
stubs.verify_stubbed_calls
|
||||
end
|
||||
|
||||
def client(stubs)
|
||||
conn = Faraday.new do |builder|
|
||||
builder.adapter :test, stubs
|
||||
|
@ -62,18 +62,20 @@ module Faraday
|
||||
@stack.empty?
|
||||
end
|
||||
|
||||
def match(request_method, host, path, headers, body)
|
||||
# @param env [Faraday::Env]
|
||||
def match(env)
|
||||
request_method = env[:method]
|
||||
return false unless @stack.key?(request_method)
|
||||
|
||||
stack = @stack[request_method]
|
||||
consumed = (@consumed[request_method] ||= [])
|
||||
|
||||
stub, meta = matches?(stack, host, path, headers, body)
|
||||
stub, meta = matches?(stack, env)
|
||||
if stub
|
||||
consumed << stack.delete(stub)
|
||||
return stub, meta
|
||||
end
|
||||
matches?(consumed, host, path, headers, body)
|
||||
matches?(consumed, env)
|
||||
end
|
||||
|
||||
def get(path, headers = {}, &block)
|
||||
@ -142,15 +144,18 @@ module Faraday
|
||||
Faraday::Utils.URI(path).host
|
||||
]
|
||||
end
|
||||
|
||||
path, query = normalized_path.respond_to?(:split) ? normalized_path.split('?') : normalized_path
|
||||
headers = Utils::Headers.new(headers)
|
||||
stub = Stub.new(host, normalized_path, headers, body, @strict_mode, block)
|
||||
|
||||
stub = Stub.new(host, path, query, headers, body, @strict_mode, block)
|
||||
(@stack[request_method] ||= []) << stub
|
||||
end
|
||||
|
||||
def matches?(stack, host, path, headers, body)
|
||||
# @param stack [Hash]
|
||||
# @param env [Faraday::Env]
|
||||
def matches?(stack, env)
|
||||
stack.each do |stub|
|
||||
match_result, meta = stub.matches?(host, path, headers, body)
|
||||
match_result, meta = stub.matches?(env)
|
||||
return stub, meta if match_result
|
||||
end
|
||||
nil
|
||||
@ -158,35 +163,20 @@ module Faraday
|
||||
end
|
||||
|
||||
# Stub request
|
||||
# rubocop:disable Style/StructInheritance
|
||||
class Stub < Struct.new(:host, :path, :params, :headers, :body, :strict_mode, :block)
|
||||
# rubocop:enable Style/StructInheritance
|
||||
def initialize(host, full, headers, body, strict_mode, block) # rubocop:disable Metrics/ParameterLists
|
||||
path, query = full.respond_to?(:split) ? full.split('?') : full
|
||||
params =
|
||||
if query
|
||||
Faraday::Utils.parse_nested_query(query)
|
||||
else
|
||||
{}
|
||||
end
|
||||
class Stub < Struct.new(:host, :path, :query, :headers, :body, :strict_mode, :block) # rubocop:disable Style/StructInheritance
|
||||
# @param env [Faraday::Env]
|
||||
def matches?(env)
|
||||
request_host = env[:url].host
|
||||
request_path = Faraday::Utils.normalize_path(env[:url].path)
|
||||
request_headers = env.request_headers
|
||||
request_body = env[:body]
|
||||
|
||||
super(host, path, params, headers, body, strict_mode, block)
|
||||
end
|
||||
|
||||
def matches?(request_host, request_uri, request_headers, request_body)
|
||||
request_path, request_query = request_uri.split('?')
|
||||
request_params =
|
||||
if request_query
|
||||
Faraday::Utils.parse_nested_query(request_query)
|
||||
else
|
||||
{}
|
||||
end
|
||||
# meta is a hash used as carrier
|
||||
# that will be yielded to consumer block
|
||||
meta = {}
|
||||
[(host.nil? || host == request_host) &&
|
||||
path_match?(request_path, meta) &&
|
||||
params_match?(request_params) &&
|
||||
params_match?(env) &&
|
||||
(body.to_s.size.zero? || request_body == body) &&
|
||||
headers_match?(request_headers), meta]
|
||||
end
|
||||
@ -199,7 +189,11 @@ module Faraday
|
||||
end
|
||||
end
|
||||
|
||||
def params_match?(request_params)
|
||||
# @param env [Faraday::Env]
|
||||
def params_match?(env)
|
||||
request_params = env[:params]
|
||||
params = env.params_encoder.decode(query) || {}
|
||||
|
||||
if strict_mode
|
||||
return Set.new(params) == Set.new(request_params)
|
||||
end
|
||||
@ -239,26 +233,19 @@ module Faraday
|
||||
yield(stubs)
|
||||
end
|
||||
|
||||
# @param env [Faraday::Env]
|
||||
def call(env)
|
||||
super
|
||||
host = env[:url].host
|
||||
normalized_path = Faraday::Utils.normalize_path(env[:url])
|
||||
params_encoder = env.request.params_encoder ||
|
||||
Faraday::Utils.default_params_encoder
|
||||
|
||||
stub, meta = stubs.match(env[:method], host, normalized_path,
|
||||
env.request_headers, env[:body])
|
||||
env.request.params_encoder ||= Faraday::Utils.default_params_encoder
|
||||
env[:params] = env.params_encoder.decode(env[:url].query) || {}
|
||||
stub, meta = stubs.match(env)
|
||||
|
||||
unless stub
|
||||
raise Stubs::NotFound, "no stubbed request for #{env[:method]} "\
|
||||
"#{normalized_path} #{env[:body]}"
|
||||
"#{env[:url]} #{env[:body]}"
|
||||
end
|
||||
|
||||
env[:params] = if (query = env[:url].query)
|
||||
params_encoder.decode(query)
|
||||
else
|
||||
{}
|
||||
end
|
||||
block_arity = stub.block.arity
|
||||
status, headers, body =
|
||||
if block_arity >= 0
|
||||
|
@ -258,6 +258,38 @@ RSpec.describe Faraday::Adapter::Test do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'for request with non default params encoder' do
|
||||
let(:connection) do
|
||||
Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) do |builder|
|
||||
builder.adapter :test, stubs
|
||||
end
|
||||
end
|
||||
let(:stubs) do
|
||||
described_class::Stubs.new do |stubs|
|
||||
stubs.get('/path?a=x&a=y&a=z') { [200, {}, 'a'] }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when all flat param values are correctly set' do
|
||||
subject(:request) { connection.get('/path?a=x&a=y&a=z') }
|
||||
|
||||
it { expect(request.status).to eq 200 }
|
||||
end
|
||||
|
||||
shared_examples 'raise NotFound when params do not satisfy the flat param values' do |params|
|
||||
subject(:request) { connection.get('/path', params) }
|
||||
|
||||
context "with #{params.inspect}" do
|
||||
it { expect { request }.to raise_error described_class::Stubs::NotFound }
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'raise NotFound when params do not satisfy the flat param values', { a: %w[x] }
|
||||
it_behaves_like 'raise NotFound when params do not satisfy the flat param values', { a: %w[x y] }
|
||||
it_behaves_like 'raise NotFound when params do not satisfy the flat param values', { a: %w[x z y] } # NOTE: The order of the value is also compared.
|
||||
it_behaves_like 'raise NotFound when params do not satisfy the flat param values', { b: %w[x y z] }
|
||||
end
|
||||
|
||||
describe 'strict_mode' do
|
||||
let(:stubs) do
|
||||
described_class::Stubs.new(strict_mode: true) do |stubs|
|
||||
|
Loading…
x
Reference in New Issue
Block a user