1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

allow headers and env to be passed in IntegrationTest.

Closes #6513.
This commit is contained in:
Yves Senn 2013-03-13 12:25:32 +01:00
parent e2a5de2bb2
commit 9af59b2468
5 changed files with 119 additions and 36 deletions

View file

@ -1,5 +1,16 @@
## Rails 4.0.0 (unreleased) ##
* `ActionDispatch::IntegrationTest` allows headers and rack env
variables to be passed when performing requests.
Fixes #6513.
Example:
get "/success", {}, "HTTP_REFERER" => "http://test.com/",
"Host" => "http://test.com"
*Yves Senn*
* Http::Headers respects headers that are not prefixed with HTTP_
*Yves Senn*

View file

@ -12,9 +12,11 @@ module ActionDispatch
HEADER_REGEXP = /\A[A-Za-z-]+\z/
include Enumerable
attr_reader :env
def initialize(env = {})
@env = env
@env = {}
merge!(env)
end
def [](key)
@ -36,6 +38,18 @@ module ActionDispatch
@env.each(&block)
end
def merge(headers_or_env)
headers = Http::Headers.new(env.dup)
headers.merge!(headers_or_env)
headers
end
def merge!(headers_or_env)
headers_or_env.each do |key, value|
self[env_name(key)] = value
end
end
private
def env_name(key)
if key =~ HEADER_REGEXP

View file

@ -17,7 +17,7 @@ module ActionDispatch
# a Hash, or a String that is appropriately encoded
# (<tt>application/x-www-form-urlencoded</tt> or
# <tt>multipart/form-data</tt>).
# - +headers+: Additional headers to pass, as a Hash. The headers will be
# - +headers_or_env+: Additional headers to pass, as a Hash. The headers will be
# merged into the Rack env hash.
#
# This method returns a Response object, which one can use to
@ -28,44 +28,44 @@ module ActionDispatch
#
# You can also perform POST, PATCH, PUT, DELETE, and HEAD requests with
# +#post+, +#patch+, +#put+, +#delete+, and +#head+.
def get(path, parameters = nil, headers = nil)
process :get, path, parameters, headers
def get(path, parameters = nil, headers_or_env = nil)
process :get, path, parameters, headers_or_env
end
# Performs a POST request with the given parameters. See +#get+ for more
# details.
def post(path, parameters = nil, headers = nil)
process :post, path, parameters, headers
def post(path, parameters = nil, headers_or_env = nil)
process :post, path, parameters, headers_or_env
end
# Performs a PATCH request with the given parameters. See +#get+ for more
# details.
def patch(path, parameters = nil, headers = nil)
process :patch, path, parameters, headers
def patch(path, parameters = nil, headers_or_env = nil)
process :patch, path, parameters, headers_or_env
end
# Performs a PUT request with the given parameters. See +#get+ for more
# details.
def put(path, parameters = nil, headers = nil)
process :put, path, parameters, headers
def put(path, parameters = nil, headers_or_env = nil)
process :put, path, parameters, headers_or_env
end
# Performs a DELETE request with the given parameters. See +#get+ for
# more details.
def delete(path, parameters = nil, headers = nil)
process :delete, path, parameters, headers
def delete(path, parameters = nil, headers_or_env = nil)
process :delete, path, parameters, headers_or_env
end
# Performs a HEAD request with the given parameters. See +#get+ for more
# details.
def head(path, parameters = nil, headers = nil)
process :head, path, parameters, headers
def head(path, parameters = nil, headers_or_env = nil)
process :head, path, parameters, headers_or_env
end
# Performs a OPTIONS request with the given parameters. See +#get+ for
# more details.
def options(path, parameters = nil, headers = nil)
process :options, path, parameters, headers
def options(path, parameters = nil, headers_or_env = nil)
process :options, path, parameters, headers_or_env
end
# Performs an XMLHttpRequest request with the given parameters, mirroring
@ -74,11 +74,11 @@ module ActionDispatch
# The request_method is +:get+, +:post+, +:patch+, +:put+, +:delete+ or
# +:head+; the parameters are +nil+, a hash, or a url-encoded or multipart
# string; the headers are a hash.
def xml_http_request(request_method, path, parameters = nil, headers = nil)
headers ||= {}
headers['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
headers['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
process(request_method, path, parameters, headers)
def xml_http_request(request_method, path, parameters = nil, headers_or_env = nil)
headers_or_env ||= {}
headers_or_env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
headers_or_env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
process(request_method, path, parameters, headers_or_env)
end
alias xhr :xml_http_request
@ -95,40 +95,40 @@ module ActionDispatch
# redirect. Note that the redirects are followed until the response is
# not a redirect--this means you may run into an infinite loop if your
# redirect loops back to itself.
def request_via_redirect(http_method, path, parameters = nil, headers = nil)
process(http_method, path, parameters, headers)
def request_via_redirect(http_method, path, parameters = nil, headers_or_env = nil)
process(http_method, path, parameters, headers_or_env)
follow_redirect! while redirect?
status
end
# Performs a GET request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def get_via_redirect(path, parameters = nil, headers = nil)
request_via_redirect(:get, path, parameters, headers)
def get_via_redirect(path, parameters = nil, headers_or_env = nil)
request_via_redirect(:get, path, parameters, headers_or_env)
end
# Performs a POST request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def post_via_redirect(path, parameters = nil, headers = nil)
request_via_redirect(:post, path, parameters, headers)
def post_via_redirect(path, parameters = nil, headers_or_env = nil)
request_via_redirect(:post, path, parameters, headers_or_env)
end
# Performs a PATCH request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def patch_via_redirect(path, parameters = nil, headers = nil)
request_via_redirect(:patch, path, parameters, headers)
def patch_via_redirect(path, parameters = nil, headers_or_env = nil)
request_via_redirect(:patch, path, parameters, headers_or_env)
end
# Performs a PUT request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def put_via_redirect(path, parameters = nil, headers = nil)
request_via_redirect(:put, path, parameters, headers)
def put_via_redirect(path, parameters = nil, headers_or_env = nil)
request_via_redirect(:put, path, parameters, headers_or_env)
end
# Performs a DELETE request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def delete_via_redirect(path, parameters = nil, headers = nil)
request_via_redirect(:delete, path, parameters, headers)
def delete_via_redirect(path, parameters = nil, headers_or_env = nil)
request_via_redirect(:delete, path, parameters, headers_or_env)
end
end
@ -268,8 +268,8 @@ module ActionDispatch
end
# Performs the actual request.
def process(method, path, parameters = nil, rack_env = nil)
rack_env ||= {}
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

View file

@ -573,6 +573,21 @@ class MetalIntegrationTest < ActionDispatch::IntegrationTest
def test_generate_url_without_controller
assert_equal 'http://www.example.com/foo', url_for(:controller => "foo")
end
def test_pass_headers
get "/success", {}, "Referer" => "http://www.example.com/foo", "Host" => "http://nohost.com"
assert_equal "http://nohost.com", @request.env["HTTP_HOST"]
assert_equal "http://www.example.com/foo", @request.env["HTTP_REFERER"]
end
def test_pass_env
get "/success", {}, "HTTP_REFERER" => "http://test.com/", "HTTP_HOST" => "http://test.com"
assert_equal "http://test.com", @request.env["HTTP_HOST"]
assert_equal "http://test.com/", @request.env["HTTP_REFERER"]
end
end
class ApplicationIntegrationTest < ActionDispatch::IntegrationTest

View file

@ -8,7 +8,23 @@ class HeaderTest < ActiveSupport::TestCase
)
end
test "each" do
test "#new with mixed headers and env" do
headers = ActionDispatch::Http::Headers.new(
"Content-Type" => "application/json",
"HTTP_REFERER" => "/some/page",
"Host" => "http://test.com")
assert_equal({"CONTENT_TYPE" => "application/json",
"HTTP_REFERER" => "/some/page",
"HTTP_HOST" => "http://test.com"}, headers.env)
end
test "#env returns the headers as env variables" do
assert_equal({"CONTENT_TYPE" => "text/plain",
"HTTP_REFERER" => "/some/page"}, @headers.env)
end
test "#each iterates through the env variables" do
headers = []
@headers.each { |pair| headers << pair }
assert_equal [["CONTENT_TYPE", "text/plain"],
@ -54,4 +70,31 @@ class HeaderTest < ActiveSupport::TestCase
assert_equal "text/plain", @headers.fetch("content-type", nil)
assert_equal "not found", @headers.fetch("not-found", "not found")
end
test "#merge! headers with mutation" do
@headers.merge!("Host" => "http://example.test",
"Content-Type" => "text/html")
assert_equal({"HTTP_HOST" => "http://example.test",
"CONTENT_TYPE" => "text/html",
"HTTP_REFERER" => "/some/page"}, @headers.env)
end
test "#merge! env with mutation" do
@headers.merge!("HTTP_HOST" => "http://first.com",
"CONTENT_TYPE" => "text/html")
assert_equal({"HTTP_HOST" => "http://first.com",
"CONTENT_TYPE" => "text/html",
"HTTP_REFERER" => "/some/page"}, @headers.env)
end
test "merge without mutation" do
combined = @headers.merge("HTTP_HOST" => "http://example.com",
"CONTENT_TYPE" => "text/html")
assert_equal({"HTTP_HOST" => "http://example.com",
"CONTENT_TYPE" => "text/html",
"HTTP_REFERER" => "/some/page"}, combined.env)
assert_equal({"CONTENT_TYPE" => "text/plain",
"HTTP_REFERER" => "/some/page"}, @headers.env)
end
end