diff --git a/lib/webrat/mechanize.rb b/lib/webrat/mechanize.rb index e87ec30..d8e140b 100644 --- a/lib/webrat/mechanize.rb +++ b/lib/webrat/mechanize.rb @@ -6,6 +6,10 @@ module Webrat #:nodoc: attr_accessor :response alias :page :response + def request_page(url, http_method, data) #:nodoc: + super(absolute_url(url), http_method, data) + end + def get(url, data, headers_argument_not_used = nil) @response = mechanize.get(url, data) end @@ -36,7 +40,36 @@ module Webrat #:nodoc: end def_delegators :mechanize, :basic_auth + + def absolute_url(url) #:nodoc: + current_host, current_path = split_current_url + if url =~ Regexp.new('^https?://') + url + elsif url =~ Regexp.new('^/') + current_host + url + elsif url =~ Regexp.new('^\.') + current_host + absolute_path(current_path, url) + else + url + end + end + + private + def split_current_url + current_url =~ Regexp.new('^(https?://[^/]+)(/.*)?') + [Regexp.last_match(1), Regexp.last_match(2)] + end + def absolute_path(current_path, url) + levels_up = url.split('/').find_all { |x| x == '..' }.size + ancestor = if current_path.nil? + "" + else + current_path.split("/")[0..(-1 - levels_up)].join("/") + end + descendent = url.split("/")[levels_up..-1] + "#{ancestor}/#{descendent}" + end end end diff --git a/spec/webrat/mechanize/mechanize_session_spec.rb b/spec/webrat/mechanize/mechanize_session_spec.rb index 81d234e..4714140 100644 --- a/spec/webrat/mechanize/mechanize_session_spec.rb +++ b/spec/webrat/mechanize/mechanize_session_spec.rb @@ -33,4 +33,45 @@ describe Webrat::MechanizeSession do Webrat::MechanizeSession.new.post(url, data) end end + + describe "#absolute_url" do + before(:each) do + @session = Webrat::MechanizeSession.new + @session.stub!(:current_url).and_return(absolute_url) + end + + def absolute_url + 'http://test.host/users/fred/cabbages' + end + + def rooted_url + '/users/fred/cabbages' + end + + def relative_url + '../../wilma' + end + + it "should return unmodified url if prefixed with scheme" do + @session.absolute_url(absolute_url).should == absolute_url + end + + it "should prefix scheme and hostname if url begins with /" do + @session.absolute_url(rooted_url).should == absolute_url + end + + it "should resolve sibling URLs relative to current path" do + @session.absolute_url(relative_url).should == 'http://test.host/users/wilma' + end + + it "should cope with sibling URLs from root of site" do + @session.stub!(:current_url).and_return('http://test.host') + @session.absolute_url(relative_url).should == 'http://test.host/wilma' + end + + it "should cope with https" do + @session.stub!(:current_url).and_return('https://test.host') + @session.absolute_url(relative_url).should == 'https://test.host/wilma' + end + end end \ No newline at end of file