Merge commit 'joshknowles/master'

Conflicts:
	lib/webrat/rails.rb
	spec/webrat/rails/rails_session_spec.rb
This commit is contained in:
Bryan Helmkamp 2008-12-28 19:35:42 -05:00
commit 29274f9b4b
7 changed files with 235 additions and 109 deletions

View File

@ -9,51 +9,53 @@ module Webrat
def doc_root def doc_root
File.expand_path(File.join(RAILS_ROOT, 'public')) File.expand_path(File.join(RAILS_ROOT, 'public'))
end end
def saved_page_dir def saved_page_dir
File.expand_path(File.join(RAILS_ROOT, "tmp")) File.expand_path(File.join(RAILS_ROOT, "tmp"))
end end
def get(url, data, headers = nil) def get(url, data, headers = nil)
do_request(:get, url, data, headers) do_request(:get, url, data, headers)
end end
def post(url, data, headers = nil) def post(url, data, headers = nil)
do_request(:post, url, data, headers) do_request(:post, url, data, headers)
end end
def put(url, data, headers = nil) def put(url, data, headers = nil)
do_request(:put, url, data, headers) do_request(:put, url, data, headers)
end end
def delete(url, data, headers = nil) def delete(url, data, headers = nil)
do_request(:delete, url, data, headers) do_request(:delete, url, data, headers)
end end
def response_body def response_body
response.body response.body
end end
def response_code def response_code
response.code.to_i response.code.to_i
end end
def xml_content_type? def xml_content_type?
response.headers["Content-Type"].to_s =~ /xml/ response.headers["Content-Type"].to_s =~ /xml/
end end
protected protected
def integration_session def integration_session
@context @context
end end
def do_request(http_method, url, data, headers) #:nodoc: def do_request(http_method, url, data, headers) #:nodoc:
update_protocol(url) update_protocol(url)
url = normalize_url(url)
integration_session.request_via_redirect(http_method, url, data, headers) integration_session.send(http_method, normalize_url(url), data, headers)
integration_session.follow_redirect_with_headers(headers) while integration_session.internal_redirect?
integration_session.status
end end
# remove protocol, host and anchor # remove protocol, host and anchor
def normalize_url(href) #:nodoc: def normalize_url(href) #:nodoc:
uri = URI.parse(href) uri = URI.parse(href)
@ -63,7 +65,7 @@ module Webrat
end end
normalized_url normalized_url
end end
def update_protocol(href) #:nodoc: def update_protocol(href) #:nodoc:
if href =~ /^https:/ if href =~ /^https:/
integration_session.https!(true) integration_session.https!(true)
@ -71,23 +73,31 @@ module Webrat
integration_session.https!(false) integration_session.https!(false)
end end
end end
def response #:nodoc: def response #:nodoc:
integration_session.response integration_session.response
end end
end end
end end
module ActionController #:nodoc: module ActionController #:nodoc:
module Integration #:nodoc: module Integration #:nodoc:
Session.class_eval do class Session #:nodoc:
unless instance_methods.include?("put_via_redirect") def internal_redirect?
require "webrat/rails/redirect_actions" redirect? && response.redirect_url_match?(host)
include Webrat::RedirectActions end
def follow_redirect_with_headers(h = {})
raise "Not a redirect! #{@status} #{@status_message}" unless redirect?
h['HTTP_REFERER'] = current_url if current_url
get(interpret_uri(headers["location"].first), {}, h)
status
end end
end end
end end
IntegrationTest.class_eval do IntegrationTest.class_eval do
include Webrat::Methods include Webrat::Methods
include Webrat::Matchers include Webrat::Matchers

View File

@ -1,18 +0,0 @@
# For Rails before http://dev.rubyonrails.org/ticket/10497 was committed
module Webrat
module RedirectActions #:nodoc:
def put_via_redirect(path, parameters = {}, headers = {})
put path, parameters, headers
follow_redirect! while redirect?
status
end
def delete_via_redirect(path, parameters = {}, headers = {})
delete path, parameters, headers
follow_redirect! while redirect?
status
end
end
end

View File

@ -11,9 +11,8 @@ module Webrat
path, data, headers = *args path, data, headers = *args
params = data.merge({:env => headers || {}}) params = data.merge({:env => headers || {}})
self.__send__("#{verb}_it", path, params) self.__send__("#{verb}_it", path, params)
follow! while @response.redirect? get_it(@response.location, params) while @response.redirect?
end end
end end
end end
end end

View File

@ -3,92 +3,189 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
require "webrat/rails" require "webrat/rails"
describe Webrat::RailsSession do describe Webrat::RailsSession do
before do before :each do
Webrat.configuration.mode = :rails Webrat.configuration.mode = :rails
@integration_session = mock("integration_session")
@integration_session.stub!(:internal_redirect?)
@integration_session.stub!(:status)
end end
it "should delegate response_body to the session response body" do it "should delegate response_body to the session response body" do
response = mock("response", :body => "<html>") @integration_session.stub!(:response => mock("response", :body => "<html>"))
integration_session = mock("integration session", :response => response) Webrat::RailsSession.new(@integration_session).response_body.should == "<html>"
Webrat::RailsSession.new(integration_session).response_body.should == "<html>"
end end
it "should delegate response_code to the session response code" do it "should delegate response_code to the session response code" do
response = mock("response", :code => "42") @integration_session.stub!(:response => mock("response", :code => "42"))
integration_session = mock("integration session", :response => response) Webrat::RailsSession.new(@integration_session).response_code.should == 42
Webrat::RailsSession.new(integration_session).response_code.should == 42
end end
it "should delegate get to request_via_redirect on the integration session" do it "should delegate get to the integration session" do
integration_session = mock("integration session") @integration_session.should_receive(:get).with("url", "data", "headers")
rails_session = Webrat::RailsSession.new(integration_session) rails_session = Webrat::RailsSession.new(@integration_session)
integration_session.should_receive(:request_via_redirect).with(:get, "url", "data", "headers")
rails_session.get("url", "data", "headers") rails_session.get("url", "data", "headers")
end end
it "should delegate post to request_via_redirect on the integration session" do it "should delegate post to the integration session" do
integration_session = mock("integration session") @integration_session.should_receive(:post).with("url", "data", "headers")
rails_session = Webrat::RailsSession.new(integration_session) rails_session = Webrat::RailsSession.new(@integration_session)
integration_session.should_receive(:request_via_redirect).with(:post, "url", "data", "headers")
rails_session.post("url", "data", "headers") rails_session.post("url", "data", "headers")
end end
it "should delegate put to request_via_redirect on the integration session" do it "should delegate put to the integration session" do
integration_session = mock("integration session") @integration_session.should_receive(:put).with("url", "data", "headers")
rails_session = Webrat::RailsSession.new(integration_session) rails_session = Webrat::RailsSession.new(@integration_session)
integration_session.should_receive(:request_via_redirect).with(:put, "url", "data", "headers")
rails_session.put("url", "data", "headers") rails_session.put("url", "data", "headers")
end end
it "should delegate delete to request_via_redirect on the integration session" do it "should delegate delete to the integration session" do
integration_session = mock("integration session") @integration_session.should_receive(:delete).with("url", "data", "headers")
rails_session = Webrat::RailsSession.new(integration_session) rails_session = Webrat::RailsSession.new(@integration_session)
integration_session.should_receive(:request_via_redirect).with(:delete, "url", "data", "headers")
rails_session.delete("url", "data", "headers") rails_session.delete("url", "data", "headers")
end end
context "the URL is a full path" do context "the URL is a full path" do
it "should just pass on the path" do it "should just pass on the path" do
integration_session = mock("integration session", :https! => nil) @integration_session.stub!(:https!)
rails_session = Webrat::RailsSession.new(integration_session) @integration_session.should_receive(:get).with("/url", "data", "headers")
integration_session.should_receive(:request_via_redirect).with(:get, "/url", "data", "headers") rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("http://www.example.com/url", "data", "headers") rails_session.get("http://www.example.com/url", "data", "headers")
end end
end end
context "the URL is https://" do context "the URL is https://" do
it "should call #https! with true before the request and just pass on the path" do it "should call #https! with true before the request and just pass on the path" do
integration_session = mock("integration session") @integration_session.should_receive(:https!).with(true)
rails_session = Webrat::RailsSession.new(integration_session) @integration_session.should_receive(:get).with("/url", "data", "headers")
integration_session.should_receive(:https!).with(true) rails_session = Webrat::RailsSession.new(@integration_session)
integration_session.should_receive(:request_via_redirect).with(:get, "/url", "data", "headers")
rails_session.get("https://www.example.com/url", "data", "headers") rails_session.get("https://www.example.com/url", "data", "headers")
end end
end end
context "the URL is http://" do context "the URL is http://" do
it "should call #https! with true before the request" do it "should call #https! with true before the request" do
integration_session = mock("integration session", :request_via_redirect => nil) @integration_session.stub!(:get)
rails_session = Webrat::RailsSession.new(integration_session) @integration_session.should_receive(:https!).with(false)
integration_session.should_receive(:https!).with(false) rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("http://www.example.com/url", "data", "headers") rails_session.get("http://www.example.com/url", "data", "headers")
end end
end end
context "the URL include an anchor" do context "the URL include an anchor" do
it "should strip out the anchor" do it "should strip out the anchor" do
integration_session = mock("integration session", :https! => false) @integration_session.should_receive(:https!).with(false)
rails_session = Webrat::RailsSession.new(integration_session) @integration_session.should_receive(:get).with("/url", "data", "headers")
integration_session.should_receive(:request_via_redirect).with(:get, "/url", "data", "headers") rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("http://www.example.com/url#foo", "data", "headers") rails_session.get("http://www.example.com/url#foo", "data", "headers")
end end
end end
context "following redirects" do
it "should use forward headers when following redirects" do
@integration_session.stub!(:post)
@integration_session.stub!(:host)
@integration_session.stub!(:status)
@integration_session.should_receive(:internal_redirect?).twice.and_return(true, false)
@integration_session.should_receive(:follow_redirect_with_headers).with("headers")
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.post("url", "data", "headers")
end
it "should follow internal redirects" do
@integration_session.stub!(:get)
@integration_session.stub!(:host)
@integration_session.stub!(:status)
@integration_session.should_receive(:internal_redirect?).twice.and_return(true, false)
@integration_session.should_receive(:follow_redirect_with_headers)
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("url", "data", "headers")
end
it "should not follow external redirects" do
@integration_session.stub!(:get)
@integration_session.stub!(:host)
@integration_session.stub!(:status)
@integration_session.should_receive(:internal_redirect?).and_return(false)
@integration_session.should_not_receive(:follow_redirect_with_headers)
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("url", "data", "headers")
end
end
it "should provide a saved_page_dir" do it "should provide a saved_page_dir" do
Webrat::RailsSession.new(mock("integration session")).should respond_to(:saved_page_dir) Webrat::RailsSession.new(mock("integration session")).should respond_to(:saved_page_dir)
end end
it "should provide a doc_root" do it "should provide a doc_root" do
Webrat::RailsSession.new(mock("integration session")).should respond_to(:doc_root) Webrat::RailsSession.new(mock("integration session")).should respond_to(:doc_root)
end end
end
describe ActionController::Integration::Session do
before :each do
Webrat.configuration.mode = :rails
@integration_session = ActionController::Integration::Session.new
@integration_session.stub!(:response => mock("response"))
end
describe "internal_redirect?" do
it "should return false if the response is not a redirect" do
@integration_session.should_receive(:redirect?).and_return(false)
@integration_session.internal_redirect?.should == false
end
it "should return false if the response was a redirect but the response location does not match the request host" do
@integration_session.should_receive(:redirect?).and_return(true)
@integration_session.response.should_receive(:redirect_url_match?).and_return(false)
@integration_session.internal_redirect?.should == false
end
it "should return true if the response is a redirect and the response location matches the request host" do
@integration_session.should_receive(:redirect?).and_return(true)
@integration_session.response.should_receive(:redirect_url_match?).and_return(true)
@integration_session.internal_redirect?.should == true
end
end
describe "follow_redirect_with_headers" do
before do
Webrat.configuration.mode = :rails
@integration_session.stub!(:headers).and_return({ 'location' => ["/"]})
@integration_session.stub!(:redirect?).and_return true
@integration_session.stub!(:get)
end
it "should raise an exception if response wasn't a redirect" do
@integration_session.stub!(:redirect?).and_return false
lambda { @integration_session.follow_redirect_with_headers }.should raise_error
end
it "should set the HTTP referer header" do
@integration_session.stub!(:current_url).and_return "http://source.url/"
headers = {}
@integration_session.follow_redirect_with_headers(headers)
headers["HTTP_REFERER"].should == "http://source.url/"
end
it "should GET the first location header" do
@integration_session.stub!("headers").and_return({ 'location' => ['/target'] })
@integration_session.should_receive(:get).with("/target", {}, hash_including("headers" => "foo"))
@integration_session.follow_redirect_with_headers({"headers" => "foo"})
end
it "should return the status" do
@integration_session.stub!(:status).and_return "202"
@integration_session.follow_redirect_with_headers.should == "202"
end
end
end end

View File

@ -1,20 +0,0 @@
# it "should default to current url" do
# # current_page.stub!(:url => "/page")
# response_body = <<-HTML
# <form method="get">
# <input type="submit" />
# </form>
# HTML
# @page.stub!(:url => "/current")
# webrat_session.should_receive(:get).with("/current", {})
# click_button
# end
#
# it "should follow fully qualified secure local links" do
# response_body = <<-HTML
# <a href="https://www.example.com/page/sub">Jump to sub page</a>
# HTML
# webrat_session.should_receive(:https!).with(true)
# webrat_session.should_receive(:get).with("/page/sub", {})
# click_link "Jump to sub page"
# end

View File

@ -0,0 +1,15 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
require "webrat/sinatra"
class Sinatra::Application
# Override this to prevent Sinatra from barfing on the options passed from RSpec
def self.load_default_options_from_command_line!
end
end
Sinatra::Application.default_options.merge!(
:env => :test,
:run => false,
:raise_errors => true,
:logging => false
)

View File

@ -0,0 +1,43 @@
require File.expand_path(File.dirname(__FILE__) + '/helper')
describe Webrat::SinatraSession do
before :each do
Webrat.configuration.mode = :sinatra
@sinatra_session = Webrat::SinatraSession.new
@response = mock(:response)
@response.stub!(:redirect?)
@sinatra_session.instance_variable_set("@response", @response)
end
it "should delegate get to get_it" do
@sinatra_session.should_receive(:get_it).with("url", { :env => "headers" })
@sinatra_session.get("url", {}, "headers")
end
it "should delegate post to post_it" do
@sinatra_session.should_receive(:post_it).with("url", { :env => "headers" })
@sinatra_session.post("url", {}, "headers")
end
it "should delegate put to put_it" do
@sinatra_session.should_receive(:put_it).with("url", { :env => "headers" })
@sinatra_session.put("url", {}, "headers")
end
it "should delegate delete to delete_it" do
@sinatra_session.should_receive(:delete_it).with("url", { :env => "headers" })
@sinatra_session.delete("url", {}, "headers")
end
it "should forward headers when following redirects" do
@response.should_receive(:redirect?).twice.and_return(true, false)
@response.should_receive(:location).and_return("redirect url")
@sinatra_session.should_receive(:get_it).with("original url", { :env => "headers" })
@sinatra_session.should_receive(:get_it).with("redirect url", { :env => "headers" })
@sinatra_session.get("original url", {}, "headers")
end
end