diff --git a/lib/faraday/adapter/test.rb b/lib/faraday/adapter/test.rb index b62fdd37b..9d815823b 100644 --- a/lib/faraday/adapter/test.rb +++ b/lib/faraday/adapter/test.rb @@ -17,6 +17,9 @@ class Test < Faraday::Adapter def self.loaded?() false end class Stubs + class NotFound < StandardError + end + def initialize # {:get => [Stub, Stub]} @stack, @consumed = {}, {} @@ -84,9 +87,29 @@ def matches?(stack, path, body) end end - class Stub < Struct.new(:path, :body, :block) - def matches?(request_path, request_body) - request_path == path && (body.to_s.size.zero? || request_body == body) + class Stub < Struct.new(:path, :params, :body, :block) + def initialize(full, body, block) + path, query = full.split('?') + params = query ? + Rack::Utils.parse_nested_query(query) : + {} + super path, params, body, block + end + + def matches?(request_uri, request_body) + request_path, request_query = request_uri.split('?') + request_params = request_query ? + Rack::Utils.parse_nested_query(request_query) : + {} + request_path == path && + params_match?(request_params) && + (body.to_s.size.zero? || request_body == body) + end + + def params_match?(request_params) + params.keys.all? do |key| + request_params[key] == params[key] + end end def to_s @@ -109,10 +132,13 @@ def call(env) normalized_path = Faraday::Utils.normalize_path(env[:url]) if stub = stubs.match(env[:method], normalized_path, env[:body]) + env[:params] = (query = env[:url].query) ? + Rack::Utils.parse_nested_query(query) : + {} status, headers, body = stub.block.call(env) save_response(env, status, body, headers) else - raise "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}" + raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}" end @app.call(env) end diff --git a/test/adapters/test_middleware_test.rb b/test/adapters/test_middleware_test.rb index c85df24cb..8dae7f562 100644 --- a/test/adapters/test_middleware_test.rb +++ b/test/adapters/test_middleware_test.rb @@ -27,6 +27,20 @@ def test_middleware_can_be_called_several_times assert_equal 'hello', @conn.get("/hello").body end + def test_middleware_with_get_params + @stubs.get('/param?a=1') { [200, {}, 'a'] } + assert_equal 'a', @conn.get('/param?a=1').body + end + + def test_middleware_ignores_unspecified_get_params + @stubs.get('/optional?a=1') { [200, {}, 'a'] } + assert_equal 'a', @conn.get('/optional?a=1&b=1').body + assert_equal 'a', @conn.get('/optional?a=1').body + assert_raise Faraday::Adapter::Test::Stubs::NotFound do + @conn.get('/optional') + end + end + def test_middleware_allow_different_outcomes_for_the_same_request @stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'hello'] } @stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'world'] } @@ -34,8 +48,21 @@ def test_middleware_allow_different_outcomes_for_the_same_request assert_equal 'world', @conn.get("/hello").body end + def test_yields_env_to_stubs + @stubs.get '/hello' do |env| + assert_equal '/hello', env[:url].path + assert_equal 'foo.com', env[:url].host + assert_equal '1', env[:params]['a'] + assert_equal 'text/plain', env[:request_headers]['Accept'] + [200, {}, 'a'] + end + + @conn.headers['Accept'] = 'text/plain' + assert_equal 'a', @conn.get('http://foo.com/hello?a=1').body + end + def test_raises_an_error_if_no_stub_is_found_for_request - assert_raise RuntimeError do + assert_raise Faraday::Adapter::Test::Stubs::NotFound do @conn.get('/invalid'){ [200, {}, []] } end end