Test for supporting various conventions for array fields #157

Closed
wants to merge 2 commits into
from
View
25 lib/webmock/request_pattern.rb
@@ -106,11 +106,30 @@ def matches?(uri)
end
end
+ # Someone might want to look at URIRegexpPattern and see if this should
+ # be used there, too.
+ def convert_hash_to_array(query_params)
+ query_params.inject([]) do |memo, pair|
+ key, value = *pair
+ if value.kind_of?(Array)
+ value.each do |val|
+ memo << [key + '[]', val]
+ end
+ else
+ memo << [key + '[]', value]
+ end
+ memo
+ end
+ end
+
def add_query_params(query_params)
- if !query_params.is_a?(Hash)
- query_params = Addressable::URI.parse('?' + query_params).query_values
+ query_params = convert_hash_to_array(query_params) if query_params.is_a?(Hash)
+
+ if !query_params.is_a?(Array)
+ query_params = Addressable::URI.parse('?' + query_params).query_values(:notation => :flat_array)
end
- @pattern.query_values = (@pattern.query_values || {}).merge(query_params)
+ qv = (@pattern.query_values(:notation => :flat_array) || []) + query_params #(@pattern.query_values || {}).merge(query_params)
+ @pattern.query_values = qv.sort
end
def to_s
View
4 lib/webmock/util/uri.rb
@@ -17,7 +17,7 @@ class URI
NORMALIZED_URIS = Hash.new do |hash, uri|
normalized_uri = WebMock::Util::URI.heuristic_parse(uri)
- normalized_uri.query_values = sort_query_values(normalized_uri.query_values) if normalized_uri.query_values
+ normalized_uri.query_values = sort_query_values(normalized_uri.query_values(:notation => :flat_array)) if normalized_uri.query_values
normalized_uri = normalized_uri.normalize #normalize! is slower
normalized_uri.port = normalized_uri.inferred_port unless normalized_uri.port
hash[uri] = normalized_uri
@@ -74,7 +74,7 @@ def self.is_uri_localhost?(uri)
private
def self.sort_query_values(query_values)
- Hash[*query_values.sort.inject([]) { |values, pair| values + pair}]
+ query_values.sort
end
def self.uris_with_inferred_port_and_without(uris)
View
2 spec/acceptance/httpclient/httpclient_spec_helper.rb
@@ -9,7 +9,7 @@ def http_request(method, uri, options = {}, &block)
c.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
c.set_basic_auth(nil, uri.user, uri.password) if uri.user
params = [method, "#{uri.omit(:userinfo, :query).normalize.to_s}",
- uri.query_values, options[:body], options[:headers] || {}]
+ uri.query_values(:notation => :flat_array), options[:body], options[:headers] || {}]
if HTTPClientSpecHelper.async_mode
connection = c.request_async(*params)
connection.join
View
23 spec/unit/util/uri_spec.rb
@@ -172,6 +172,29 @@
lambda { WebMock::Util::URI.normalize_uri(uri) }.should_not raise_error(ArgumentError)
end
+ context "with array parameters" do
+
+ it "should successfully handle array parameters" do
+ uri = 'http://www.example.com:80/path?a[]=b&a[]=c'
+ lambda { WebMock::Util::URI.normalize_uri(uri) }.should_not raise_error(ArgumentError)
+ end
+
+ context "in various formats" do
+ it "should be able to turn array parameters into a query string of the format ?a[]=b&a[]=c" do
+ uri_string = 'http://www.example.com:80/path?a[]=b&a[]=c'
+ uri = WebMock::Util::URI.normalize_uri(uri_string)
+ Addressable::URI.unencode(uri.query).should == "a[]=b&a[]=c"
+ end
+
+ it "should be able to turn array parameters into a query string of the format ?a=b&a=c" do
+ uri_string = 'http://www.example.com:80/path?a=b&a=c'
+ uri = WebMock::Util::URI.normalize_uri(uri_string)
+ Addressable::URI.unencode(uri.query).should == "a=b&a=c"
+ end
+ end
+
+ end
+
end
describe "stripping default port" do