Skip to content

Commit

Permalink
Merge commit 'joshknowles/master'
Browse files Browse the repository at this point in the history
Conflicts:
	lib/webrat/rails.rb
	spec/webrat/rails/rails_session_spec.rb
  • Loading branch information
brynary committed Dec 29, 2008
2 parents f409ec3 + 89e9ea9 commit 29274f9
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 110 deletions.
52 changes: 31 additions & 21 deletions lib/webrat/rails.rb
Expand Up @@ -9,51 +9,53 @@ class RailsSession < Session #:nodoc:
def doc_root
File.expand_path(File.join(RAILS_ROOT, 'public'))
end

def saved_page_dir
File.expand_path(File.join(RAILS_ROOT, "tmp"))
end

def get(url, data, headers = nil)
do_request(:get, url, data, headers)
end

def post(url, data, headers = nil)
do_request(:post, url, data, headers)
end

def put(url, data, headers = nil)
do_request(:put, url, data, headers)
end

def delete(url, data, headers = nil)
do_request(:delete, url, data, headers)
end

def response_body
response.body
end

def response_code
response.code.to_i
end

def xml_content_type?
response.headers["Content-Type"].to_s =~ /xml/
end

protected

def integration_session
@context
end

def do_request(http_method, url, data, headers) #:nodoc:
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

# remove protocol, host and anchor
def normalize_url(href) #:nodoc:
uri = URI.parse(href)
Expand All @@ -63,31 +65,39 @@ def normalize_url(href) #:nodoc:
end
normalized_url
end

def update_protocol(href) #:nodoc:
if href =~ /^https:/
integration_session.https!(true)
elsif href =~ /^http:/
integration_session.https!(false)
end
end

def response #:nodoc:
integration_session.response
end

end
end

module ActionController #:nodoc:
module Integration #:nodoc:
Session.class_eval do
unless instance_methods.include?("put_via_redirect")
require "webrat/rails/redirect_actions"
include Webrat::RedirectActions
class Session #:nodoc:
def internal_redirect?
redirect? && response.redirect_url_match?(host)
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

IntegrationTest.class_eval do
include Webrat::Methods
include Webrat::Matchers
Expand Down
18 changes: 0 additions & 18 deletions lib/webrat/rails/redirect_actions.rb

This file was deleted.

3 changes: 1 addition & 2 deletions lib/webrat/sinatra.rb
Expand Up @@ -11,9 +11,8 @@ class SinatraSession < RackSession #:nodoc:
path, data, headers = *args
params = data.merge({:env => headers || {}})
self.__send__("#{verb}_it", path, params)
follow! while @response.redirect?
get_it(@response.location, params) while @response.redirect?
end
end

end
end
195 changes: 146 additions & 49 deletions spec/webrat/rails/rails_session_spec.rb
Expand Up @@ -3,92 +3,189 @@
require "webrat/rails"

describe Webrat::RailsSession do
before do
before :each do
Webrat.configuration.mode = :rails
@integration_session = mock("integration_session")
@integration_session.stub!(:internal_redirect?)
@integration_session.stub!(:status)
end

it "should delegate response_body to the session response body" do
response = mock("response", :body => "<html>")
integration_session = mock("integration session", :response => response)
Webrat::RailsSession.new(integration_session).response_body.should == "<html>"
@integration_session.stub!(:response => mock("response", :body => "<html>"))
Webrat::RailsSession.new(@integration_session).response_body.should == "<html>"
end

it "should delegate response_code to the session response code" do
response = mock("response", :code => "42")
integration_session = mock("integration session", :response => response)
Webrat::RailsSession.new(integration_session).response_code.should == 42
end

it "should delegate get to request_via_redirect on the integration session" do
integration_session = mock("integration session")
rails_session = Webrat::RailsSession.new(integration_session)
integration_session.should_receive(:request_via_redirect).with(:get, "url", "data", "headers")
@integration_session.stub!(:response => mock("response", :code => "42"))
Webrat::RailsSession.new(@integration_session).response_code.should == 42
end

it "should delegate get to the integration session" do
@integration_session.should_receive(:get).with("url", "data", "headers")
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("url", "data", "headers")
end

it "should delegate post to request_via_redirect on the integration session" do
integration_session = mock("integration session")
rails_session = Webrat::RailsSession.new(integration_session)
integration_session.should_receive(:request_via_redirect).with(:post, "url", "data", "headers")

it "should delegate post to the integration session" do
@integration_session.should_receive(:post).with("url", "data", "headers")
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.post("url", "data", "headers")
end

it "should delegate put to request_via_redirect on the integration session" do
integration_session = mock("integration session")
rails_session = Webrat::RailsSession.new(integration_session)
integration_session.should_receive(:request_via_redirect).with(:put, "url", "data", "headers")

it "should delegate put to the integration session" do
@integration_session.should_receive(:put).with("url", "data", "headers")
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.put("url", "data", "headers")
end

it "should delegate delete to request_via_redirect on the integration session" do
integration_session = mock("integration session")
rails_session = Webrat::RailsSession.new(integration_session)
integration_session.should_receive(:request_via_redirect).with(:delete, "url", "data", "headers")

it "should delegate delete to the integration session" do
@integration_session.should_receive(:delete).with("url", "data", "headers")
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.delete("url", "data", "headers")
end

context "the URL is a full path" do
it "should just pass on the path" do
integration_session = mock("integration session", :https! => nil)
rails_session = Webrat::RailsSession.new(integration_session)
integration_session.should_receive(:request_via_redirect).with(:get, "/url", "data", "headers")
@integration_session.stub!(:https!)
@integration_session.should_receive(:get).with("/url", "data", "headers")
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("http://www.example.com/url", "data", "headers")
end
end

context "the URL is https://" do
it "should call #https! with true before the request and just pass on the path" do
integration_session = mock("integration session")
rails_session = Webrat::RailsSession.new(integration_session)
integration_session.should_receive(:https!).with(true)
integration_session.should_receive(:request_via_redirect).with(:get, "/url", "data", "headers")
@integration_session.should_receive(:https!).with(true)
@integration_session.should_receive(:get).with("/url", "data", "headers")
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("https://www.example.com/url", "data", "headers")
end
end

context "the URL is http://" do
it "should call #https! with true before the request" do
integration_session = mock("integration session", :request_via_redirect => nil)
rails_session = Webrat::RailsSession.new(integration_session)
integration_session.should_receive(:https!).with(false)
@integration_session.stub!(:get)
@integration_session.should_receive(:https!).with(false)
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("http://www.example.com/url", "data", "headers")
end
end

context "the URL include an anchor" do
it "should strip out the anchor" do
integration_session = mock("integration session", :https! => false)
rails_session = Webrat::RailsSession.new(integration_session)
integration_session.should_receive(:request_via_redirect).with(:get, "/url", "data", "headers")
@integration_session.should_receive(:https!).with(false)
@integration_session.should_receive(:get).with("/url", "data", "headers")
rails_session = Webrat::RailsSession.new(@integration_session)
rails_session.get("http://www.example.com/url#foo", "data", "headers")
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
Webrat::RailsSession.new(mock("integration session")).should respond_to(:saved_page_dir)
end

it "should provide a doc_root" do
Webrat::RailsSession.new(mock("integration session")).should respond_to(:doc_root)
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

0 comments on commit 29274f9

Please sign in to comment.