From 41a14dcd1045f61278237f34f065b87212689376 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 13 Mar 2013 18:05:01 +0100 Subject: `Http::Headers` directly modifies the passed environment. The env hash passed to `Http::Headers#new` must be in env format. Also be aware that the passed hash is modified directly. docs and test-cases for setting headers/env in functional tests. Follow up to #9700. --- actionpack/CHANGELOG.md | 8 ++++++-- actionpack/lib/action_dispatch/http/headers.rb | 3 +-- .../lib/action_dispatch/testing/integration.rb | 5 +++-- actionpack/test/controller/test_case_test.rb | 22 ++++++++++++++++++++++ actionpack/test/dispatch/header_test.rb | 22 ++++++++++++++++------ 5 files changed, 48 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 3eb40a586e..b23d0668d3 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,13 +1,17 @@ ## Rails 4.0.0 (unreleased) ## -* `ActionDispatch::IntegrationTest` allows headers and rack env +* Integration and functional tests allow headers and rack env variables to be passed when performing requests. Fixes #6513. Example: + # integration test get "/success", {}, "HTTP_REFERER" => "http://test.com/", - "Host" => "http://test.com" + "Accepts" => "text/plain, text/html" + + # functional test + @request.headers["Accepts"] = "text/plain, text/html" *Yves Senn* diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb index 1574518a16..2666cd4b0a 100644 --- a/actionpack/lib/action_dispatch/http/headers.rb +++ b/actionpack/lib/action_dispatch/http/headers.rb @@ -15,8 +15,7 @@ module ActionDispatch attr_reader :env def initialize(env = {}) - @env = {} - merge!(env) + @env = env end def [](key) diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index ae1b0b5dea..56c31255f3 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -269,7 +269,6 @@ module ActionDispatch # Performs the actual request. def process(method, path, parameters = nil, headers_or_env = nil) - rack_env = Http::Headers.new(headers_or_env || {}).env if path =~ %r{://} location = URI.parse(path) https! URI::HTTPS === location if location.scheme @@ -300,10 +299,12 @@ module ActionDispatch "CONTENT_TYPE" => "application/x-www-form-urlencoded", "HTTP_ACCEPT" => accept } + # this modifies the passed env directly + Http::Headers.new(env).merge!(headers_or_env || {}) session = Rack::Test::Session.new(_mock_session) - env.merge!(rack_env) + env.merge!(env) # NOTE: rack-test v0.5 doesn't build a default uri correctly # Make sure requested path is always a full uri diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb index df31338f09..9c6d02a62d 100644 --- a/actionpack/test/controller/test_case_test.rb +++ b/actionpack/test/controller/test_case_test.rb @@ -57,6 +57,10 @@ class TestCaseTest < ActionController::TestCase render :text => request.protocol end + def test_headers + render text: JSON.dump(request.headers.env) + end + def test_html_output render :text => < @@ -626,6 +630,24 @@ XML assert_equal 2004, page[:year] end + test "set additional HTTP headers" do + @request.headers['Referer'] = "http://nohost.com/home" + @request.headers['Content-Type'] = "application/rss+xml" + get :test_headers + parsed_env = JSON.parse(@response.body) + assert_equal "http://nohost.com/home", parsed_env["HTTP_REFERER"] + assert_equal "application/rss+xml", parsed_env["CONTENT_TYPE"] + end + + test "set additional env variables" do + @request.headers['HTTP_REFERER'] = "http://example.com/about" + @request.headers['CONTENT_TYPE'] = "application/json" + get :test_headers + parsed_env = JSON.parse(@response.body) + assert_equal "http://example.com/about", parsed_env["HTTP_REFERER"] + assert_equal "application/json", parsed_env["CONTENT_TYPE"] + end + def test_id_converted_to_string get :test_params, :id => 20, :foo => Object.new assert_kind_of String, @request.path_parameters['id'] diff --git a/actionpack/test/dispatch/header_test.rb b/actionpack/test/dispatch/header_test.rb index 3bb3b3db23..9e37b96951 100644 --- a/actionpack/test/dispatch/header_test.rb +++ b/actionpack/test/dispatch/header_test.rb @@ -8,15 +8,15 @@ class HeaderTest < ActiveSupport::TestCase ) end - test "#new with mixed headers and env" do + test "#new does not normalize the data" do headers = ActionDispatch::Http::Headers.new( "Content-Type" => "application/json", "HTTP_REFERER" => "/some/page", "Host" => "http://test.com") - assert_equal({"CONTENT_TYPE" => "application/json", + assert_equal({"Content-Type" => "application/json", "HTTP_REFERER" => "/some/page", - "HTTP_HOST" => "http://test.com"}, headers.env) + "Host" => "http://test.com"}, headers.env) end test "#env returns the headers as env variables" do @@ -117,11 +117,21 @@ class HeaderTest < ActiveSupport::TestCase end test "symbols are treated as strings" do - headers = ActionDispatch::Http::Headers.new(:SERVER_NAME => "example.com", - "HTTP_REFERER" => "/", - :Host => "test.com") + headers = ActionDispatch::Http::Headers.new + headers.merge!(:SERVER_NAME => "example.com", + "HTTP_REFERER" => "/", + :Host => "test.com") assert_equal "example.com", headers["SERVER_NAME"] assert_equal "/", headers[:HTTP_REFERER] assert_equal "test.com", headers["HTTP_HOST"] end + + test "headers directly modifies the passed environment" do + env = {"HTTP_REFERER" => "/"} + headers = ActionDispatch::Http::Headers.new(env) + headers['Referer'] = "http://example.com/" + headers.merge! "CONTENT_TYPE" => "text/plain" + assert_equal({"HTTP_REFERER"=>"http://example.com/", + "CONTENT_TYPE"=>"text/plain"}, env) + end end -- cgit v1.2.3 From e8598a53a17da5fa909e6e5ec1d8284fca6a85f9 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Thu, 14 Mar 2013 11:48:33 +0100 Subject: document request simulation methods in functional tests. --- actionpack/lib/action_controller/test_case.rb | 34 +++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 9dae78d25d..b2ceedaa6c 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -451,37 +451,57 @@ module ActionController end - # Executes a request simulating GET HTTP method and set/volley the response + # Simulate a GET request with the given parameters. + # + # - +action+: The controller action to call + # - +parameters+: The HTTP parameters that you want to pass. This may + # be +nil+, + # a Hash, or a String that is appropriately encoded + # (application/x-www-form-urlencoded or + # multipart/form-data). + # - +session+: A Hash of parameters to store in the session. This my be +nil+. + # - +flash+: A Hash of parameters to store in the flash. This my be +nil+. + # + # You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with + # +#post+, +#patch+, +#put+, +#delete+, and +#head+. + # Note that the request method is not verified. The different methods are + # available to make the tests more expressive. def get(action, *args) process(action, "GET", *args) end - # Executes a request simulating POST HTTP method and set/volley the response + # Simulate a POST request with the given parameters and set/volley the response. + # See +#get+ for more details. def post(action, *args) process(action, "POST", *args) end - # Executes a request simulating PATCH HTTP method and set/volley the response + # Simulate a PATCH request with the given parameters and set/volley the response. + # See +#get+ for more details. def patch(action, *args) process(action, "PATCH", *args) end - # Executes a request simulating PUT HTTP method and set/volley the response + # Simulate a PUT request with the given parameters and set/volley the response. + # See +#get+ for more details. def put(action, *args) process(action, "PUT", *args) end - # Executes a request simulating DELETE HTTP method and set/volley the response + # Simulate a DELETE request with the given parameters and set/volley the response. + # See +#get+ for more details. def delete(action, *args) process(action, "DELETE", *args) end - # Executes a request simulating HEAD HTTP method and set/volley the response + # Simulate a HEAD request with the given parameters and set/volley the response. + # See +#get+ for more details. def head(action, *args) process(action, "HEAD", *args) end - # Executes a request simulating OPTIONS HTTP method and set/volley the response + # Simulate a OPTIONS request with the given parameters and set/volley the response. + # See +#get+ for more details. def options(action, *args) process(action, "OPTIONS", *args) end -- cgit v1.2.3