Skip to content
This repository has been archived by the owner on Jul 10, 2018. It is now read-only.

Commit

Permalink
Fix that you'd have to sort the query params alphabetically in a regi…
Browse files Browse the repository at this point in the history
…stered regex in order for it to ever match a URI. Thanks to Ben Hall for discovering this.

Next up: registry implementation could use a little refactoring, after this change.
  • Loading branch information
chrisk committed Aug 18, 2009
1 parent 9d85cef commit 3d439fa
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 4 deletions.
23 changes: 19 additions & 4 deletions lib/fake_web/registry.rb
Expand Up @@ -19,7 +19,6 @@ def register_uri(method, uri, options)
end

def registered_uri?(method, uri)
normalized_uri = normalize_uri(uri)
!responses_for(method, uri).empty?
end

Expand Down Expand Up @@ -63,11 +62,11 @@ def uri_map_matches?(method, uri)
end

def uri_map_matches(method, uri)
uri = normalize_uri(uri.to_s).to_s
uri = Utility.strip_default_port_from_uri(uri)
uris_to_check = variations_of_uri(uri).map { |u| u.to_s }

matches = uri_map.select { |registered_uri, method_hash|
registered_uri.is_a?(Regexp) && uri.match(registered_uri) && method_hash.has_key?(method)
registered_uri.is_a?(Regexp) && method_hash.has_key?(method) &&
uris_to_check.any? { |uri_to_check| uri_to_check.match(registered_uri) }
}

if matches.size > 1
Expand All @@ -78,6 +77,22 @@ def uri_map_matches(method, uri)
matches.map { |_, method_hash| method_hash[method] }.first
end

def variations_of_uri(uri)
uris = []
normalized_uri = normalize_uri(uri)
query = normalized_uri.query
if query.nil? || query.empty?
uris << normalized_uri
else
FakeWeb::Utility.simple_array_permutation(query.split('&')) do |p|
current_permutation = normalized_uri.dup
current_permutation.query = p.join('&')
uris << current_permutation
end
end
uris
end

def normalize_uri(uri)
return uri if uri.is_a?(Regexp)
normalized_uri =
Expand Down
22 changes: 22 additions & 0 deletions lib/fake_web/utility.rb
Expand Up @@ -18,5 +18,27 @@ def self.strip_default_port_from_uri(uri)
end
end

# Array#permutation wrapper for 1.8.6-compatibility. It only supports the
# simple case that returns all permutations (so it doesn't take a numeric
# argument).
def self.simple_array_permutation(array, &block)
# use native implementation if it exists
return array.permutation(&block) if array.respond_to?(:permutation)

yield array if array.length <= 1

array.length.times do |i|
rest = array.dup
picked = rest.delete_at(i)
next if rest.empty?

simple_array_permutation(rest) do |part_of_rest|
yield [picked] + part_of_rest
end
end

array
end

end
end
19 changes: 19 additions & 0 deletions test/test_regexes.rb
Expand Up @@ -44,6 +44,17 @@ def test_requesting_a_uri_that_matches_two_registered_regexes_raises_an_error
end
end

def test_requesting_a_uri_that_matches_two_registered_regexes_with_differently_ordered_query_params_raises_an_error
FakeWeb.register_uri(:get, %r[example.com/list\?b=2&a=1], :body => "first")
FakeWeb.register_uri(:get, %r[example.com/list\?a=1&b=2], :body => "second")
assert_raise FakeWeb::MultipleMatchingRegexpsError do
Net::HTTP.start("example.com") { |query| query.get('/list?a=1&b=2') }
end
assert_raise FakeWeb::MultipleMatchingRegexpsError do
Net::HTTP.start("example.com") { |query| query.get('/list?b=2&a=1') }
end
end

def test_requesting_a_uri_that_matches_two_registered_regexes_raises_an_error_including_request_info
FakeWeb.register_uri(:get, %r|http://example\.com/|, :body => "first")
FakeWeb.register_uri(:get, %r|http://example\.com/a|, :body => "second")
Expand Down Expand Up @@ -100,4 +111,12 @@ def test_registry_matches_with_query_params
assert !FakeWeb.registered_uri?(:get, "http://example.com/list?hash=123&important=2&unimportant=1")
assert !FakeWeb.registered_uri?(:get, "http://example.com/list?notimportant=1&unimportant=1")
end

def test_registry_matches_with_unsorted_query_params
FakeWeb.register_uri(:get, %r[example\.com/list\?b=2&a=1], :body => "example")
assert FakeWeb.registered_uri?(:get, "http://example.com/list?b=2&a=1")
assert FakeWeb.registered_uri?(:get, "http://example.com/list?a=1&b=2")
assert FakeWeb.registered_uri?(:get, "https://example.com:443/list?b=2&a=1")
end

end
21 changes: 21 additions & 0 deletions test/test_utility.rb
Expand Up @@ -67,4 +67,25 @@ def test_strip_default_port_from_uri_does_not_modify_strings_that_do_not_start_w
assert_equal uri, FakeWeb::Utility.strip_default_port_from_uri(uri)
end

def test_simple_array_permutation_with_one_element
array, permutations = [1], [[1]]
FakeWeb::Utility.simple_array_permutation(array) do |permutation|
permutations.delete(permutation)
end
assert permutations.empty?
end

def test_simple_array_permutation_with_three_elements
array = [1, 2, 3]
permutations = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
FakeWeb::Utility.simple_array_permutation(array) do |permutation|
permutations.delete(permutation)
end
assert permutations.empty?
end

def test_simple_array_permutation_return_value
array = [1, 2, 3]
assert array, FakeWeb::Utility.simple_array_permutation(array) { }
end
end

0 comments on commit 3d439fa

Please sign in to comment.