Skip to content

Commit

Permalink
Fixed problem with matching requests with json body, when json string…
Browse files Browse the repository at this point in the history
…s had date format.
  • Loading branch information
bblimke committed Aug 8, 2011
1 parent af4c054 commit 772585e
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 1 deletion.
1 change: 1 addition & 0 deletions lib/webmock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
require 'webmock/util/headers'
require 'webmock/util/hash_counter'
require 'webmock/util/hash_keys_stringifier'
require 'webmock/util/json'

require 'webmock/request_pattern'
require 'webmock/request_signature'
Expand Down
2 changes: 1 addition & 1 deletion lib/webmock/request_pattern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def matches?(body, content_type = "")

case BODY_FORMATS[content_type]
when :json then
matching_hashes?(Crack::JSON.parse(body), @pattern)
matching_hashes?(WebMock::Util::JSON.parse(body), @pattern)
when :xml then
matching_hashes?(Crack::XML.parse(body), @pattern)
else
Expand Down
54 changes: 54 additions & 0 deletions lib/webmock/util/json.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# This is a copy of https://github.com/jnunemaker/crack/blob/master/lib/crack/json.rb
# with date parsing removed
module WebMock
module Util
class JSON
def self.parse(json)
YAML.load(unescape(convert_json_to_yaml(json)))
rescue ArgumentError => e
raise ParseError, "Invalid JSON string"
end

protected
def self.unescape(str)
str.gsub(/\\u([0-9a-f]{4})/) { [$1.hex].pack("U") }
end

# Ensure that ":" and "," are always followed by a space
def self.convert_json_to_yaml(json) #:nodoc:
scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, []
while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
case char = scanner[1]
when '"', "'"
if !quoting
quoting = char
pos = scanner.pos
elsif quoting == char
quoting = false
end
when ":",","
marks << scanner.pos - 1 unless quoting
when "\\"
scanner.skip(/\\/)
end
end

if marks.empty?
json.gsub(/\\\//, '/')
else
left_pos = [-1].push(*marks)
right_pos = marks << json.length
output = []
left_pos.each_with_index do |left, i|
output << json[left.succ..right_pos[i]]
end
output = output * " "

times.each { |i| output[i-1] = ' ' }
output.gsub!(/\\\//, '/')
output
end
end
end
end
end
7 changes: 7 additions & 0 deletions spec/util/json_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe WebMock::Util::JSON do
it "should parse json without parsing dates" do
WebMock::Util::JSON.parse("\"a\":\"2011-01-01\"").should == {"a" => "2011-01-01"}
end
end
32 changes: 32 additions & 0 deletions spec/webmock_shared.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,14 @@ class MyException < StandardError; end;
:body => "{\"a\":\"1\",\"b\":\"five\",\"c\":{\"d\":[\"e\",\"f\"]}}").status.should == "200"
end

it "should match if hash contains date string" do #Crack creates date object
WebMock.reset!
stub_http_request(:post, "www.example.com").
with(:body => {"foo" => "2010-01-01"})
http_request(
:post, "http://www.example.com/", :headers => {'Content-Type' => 'application/json'},
:body => "{\"foo\":\"2010-01-01\"}").status.should == "200"
end
end

describe "for request with xml body and content type is set to xml" do
Expand All @@ -321,6 +329,15 @@ class MyException < StandardError; end;
:body => "<opt b=\"five\" a=\"1\">\n <c>\n <d>e</d>\n <d>f</d>\n </c>\n</opt>\n").status.should == "200"
end

it "should match if hash contains date string" do #Crack creates date object
WebMock.reset!
stub_http_request(:post, "www.example.com").
with(:body => {"opt" => {"foo" => "2010-01-01"}})
http_request(
:post, "http://www.example.com/", :headers => {'Content-Type' => 'application/xml'},
:body => "<opt foo=\"2010-01-01\">\n</opt>\n").status.should == "200"
end

end

end
Expand Down Expand Up @@ -1141,6 +1158,13 @@ def call(request)
}.should_not raise_error
end

it "should succeed if json body contains date string" do
lambda {
http_request(:post, "http://www.example.com/", :headers => {'Content-Type' => 'application/json'},
:body => "{\"foo\":\"2010-01-01\"}")
a_request(:post, "www.example.com").with(:body => {"foo" => "2010-01-01"}).should have_been_made
}.should_not raise_error
end
end


Expand All @@ -1163,6 +1187,14 @@ def call(request)
}.should_not raise_error
end

it "should succeed if xml body contains date string" do
lambda {
http_request(:post, "http://www.example.com/", :headers => {'Content-Type' => 'application/xml'},
:body => "<opt foo=\"2010-01-01\">\n</opt>\n")
a_request(:post, "www.example.com").with(:body => {"opt" => {"foo" => "2010-01-01"}}).should have_been_made
}.should_not raise_error
end

end

end
Expand Down

0 comments on commit 772585e

Please sign in to comment.