From 35fa00731329120fa1d0c2a9d66af6813203195a Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 7 Jan 2009 13:23:10 -0800 Subject: Include process methods in ActionController::TestCase only. No need to alias_method_chain :process either. --- actionpack/lib/action_controller/test_case.rb | 3 ++ actionpack/lib/action_controller/test_process.rb | 54 ++++++++-------------- actionpack/lib/action_view/test_case.rb | 1 + .../test/controller/addresses_render_test.rb | 9 ++-- actionpack/test/controller/base_test.rb | 22 ++++----- actionpack/test/controller/benchmark_test.rb | 6 +-- actionpack/test/controller/capture_test.rb | 9 ++-- actionpack/test/controller/content_type_test.rb | 9 ++-- actionpack/test/controller/cookie_test.rb | 8 ++-- actionpack/test/controller/filters_test.rb | 8 +++- actionpack/test/controller/flash_test.rb | 8 +--- actionpack/test/controller/send_file_test.rb | 3 +- 12 files changed, 59 insertions(+), 81 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 7ed1a3e160..93a0be4127 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -1,4 +1,5 @@ require 'active_support/test_case' +require 'action_controller/test_process' module ActionController # Superclass for ActionController functional tests. Functional tests allow you to @@ -102,6 +103,8 @@ module ActionController # # assert_redirected_to page_url(:title => 'foo') class TestCase < ActiveSupport::TestCase + include TestProcess + module Assertions %w(response selector tag dom routing model).each do |kind| include ActionController::Assertions.const_get("#{kind.camelize}Assertions") diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index 285a8b09e4..8180d4ee93 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -1,32 +1,4 @@ -require 'action_controller/test_case' - module ActionController #:nodoc: - class Base - attr_reader :assigns - - # Process a test request called with a TestRequest object. - def self.process_test(request) - new.process_test(request) - end - - def process_test(request) #:nodoc: - process(request, TestResponse.new) - end - - def process_with_test(*args) - returning process_without_test(*args) do - @assigns = {} - (instance_variable_names - @@protected_instance_variables).each do |var| - value = instance_variable_get(var) - @assigns[var[1..-1]] = value - response.template.assigns[var[1..-1]] = value if response - end - end - end - - alias_method_chain :process, :test - end - class TestRequest < Request #:nodoc: attr_accessor :cookies, :session_options attr_accessor :query_parameters, :path, :session @@ -433,7 +405,9 @@ module ActionController #:nodoc: @request.session = ActionController::TestSession.new(session) unless session.nil? @request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash build_request_uri(action, parameters) - @controller.process(@request, @response) + + Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest + @controller.process_with_test(@request, @response) end def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil) @@ -545,12 +519,24 @@ module ActionController #:nodoc: ActionController::Routing.const_set(:Routes, real_routes) if real_routes end end -end -module Test - module Unit - class TestCase #:nodoc: - include ActionController::TestProcess + module ProcessWithTest #:nodoc: + def self.included(base) + base.class_eval { attr_reader :assigns } + end + + def process_with_test(*args) + process(*args).tap { set_test_assigns } end + + private + def set_test_assigns + @assigns = {} + (instance_variable_names - self.class.protected_instance_variables).each do |var| + name, value = var[1..-1], instance_variable_get(var) + @assigns[name] = value + response.template.assigns[name] = value if response + end + end end end diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 65839256aa..ec337bb05b 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -23,6 +23,7 @@ module ActionView class TestCase < ActiveSupport::TestCase include ActionController::TestCase::Assertions + include ActionController::TestProcess class_inheritable_accessor :helper_class @@helper_class = nil diff --git a/actionpack/test/controller/addresses_render_test.rb b/actionpack/test/controller/addresses_render_test.rb index b26cae24fb..556b0593ea 100644 --- a/actionpack/test/controller/addresses_render_test.rb +++ b/actionpack/test/controller/addresses_render_test.rb @@ -19,17 +19,14 @@ class AddressesTestController < ActionController::Base def self.controller_path; "addresses"; end end -class AddressesTest < Test::Unit::TestCase - def setup - @controller = AddressesTestController.new +class AddressesTest < ActionController::TestCase + tests AddressesTestController + def setup # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get # a more accurate simulation of what happens in "real life". @controller.logger = Logger.new(nil) - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - @request.host = "www.nextangle.com" end diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 18d185b264..9523189f41 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -129,6 +129,8 @@ class PerformActionTest < ActionController::TestCase @response = ActionController::TestResponse.new @request.host = "www.nextangle.com" + + rescue_action_in_public! end def test_get_on_priv_should_show_selector @@ -164,14 +166,12 @@ class PerformActionTest < ActionController::TestCase end end -class DefaultUrlOptionsTest < Test::Unit::TestCase - def setup - @controller = DefaultUrlOptionsController.new - - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new +class DefaultUrlOptionsTest < ActionController::TestCase + tests DefaultUrlOptionsController + def setup @request.host = 'www.example.com' + rescue_action_in_public! end def test_default_url_options_are_used_if_set @@ -189,14 +189,12 @@ class DefaultUrlOptionsTest < Test::Unit::TestCase end end -class EmptyUrlOptionsTest < Test::Unit::TestCase - def setup - @controller = NonEmptyController.new - - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new +class EmptyUrlOptionsTest < ActionController::TestCase + tests NonEmptyController + def setup @request.host = 'www.example.com' + rescue_action_in_public! end def test_ensure_url_for_works_as_expected_when_called_with_no_options_if_default_url_options_is_not_set diff --git a/actionpack/test/controller/benchmark_test.rb b/actionpack/test/controller/benchmark_test.rb index 608ea5f5a9..f9100a2313 100644 --- a/actionpack/test/controller/benchmark_test.rb +++ b/actionpack/test/controller/benchmark_test.rb @@ -11,17 +11,17 @@ class BenchmarkedController < ActionController::Base end end -class BenchmarkTest < Test::Unit::TestCase +class BenchmarkTest < ActionController::TestCase + tests BenchmarkedController + class MockLogger def method_missing(*args) end end def setup - @controller = BenchmarkedController.new # benchmark doesn't do anything unless a logger is set @controller.logger = MockLogger.new - @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new @request.host = "test.actioncontroller.i" end diff --git a/actionpack/test/controller/capture_test.rb b/actionpack/test/controller/capture_test.rb index 5ded6a5d26..6dfa0995eb 100644 --- a/actionpack/test/controller/capture_test.rb +++ b/actionpack/test/controller/capture_test.rb @@ -23,17 +23,14 @@ class CaptureController < ActionController::Base def rescue_action(e) raise end end -class CaptureTest < Test::Unit::TestCase - def setup - @controller = CaptureController.new +class CaptureTest < ActionController::TestCase + tests CaptureController + def setup # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get # a more accurate simulation of what happens in "real life". @controller.logger = Logger.new(nil) - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - @request.host = "www.nextangle.com" end diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb index ae71d62e11..32c1757ef9 100644 --- a/actionpack/test/controller/content_type_test.rb +++ b/actionpack/test/controller/content_type_test.rb @@ -50,16 +50,13 @@ class ContentTypeController < ActionController::Base def rescue_action(e) raise end end -class ContentTypeTest < Test::Unit::TestCase - def setup - @controller = ContentTypeController.new +class ContentTypeTest < ActionController::TestCase + tests ContentTypeController + def setup # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get # a more accurate simulation of what happens in "real life". @controller.logger = Logger.new(nil) - - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new end def test_render_defaults diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb index 3ddc5768a9..9508348ca1 100644 --- a/actionpack/test/controller/cookie_test.rb +++ b/actionpack/test/controller/cookie_test.rb @@ -1,6 +1,6 @@ require 'abstract_unit' -class CookieTest < Test::Unit::TestCase +class CookieTest < ActionController::TestCase class TestController < ActionController::Base def authenticate cookies["user_name"] = "david" @@ -41,11 +41,9 @@ class CookieTest < Test::Unit::TestCase end end - def setup - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new + tests TestController - @controller = TestController.new + def setup @request.host = "www.nextangle.com" end diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index dafa344473..e83fde2349 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -634,9 +634,11 @@ class FilterTest < Test::Unit::TestCase private def test_process(controller, action = "show") + ActionController::Base.class_eval { include ActionController::ProcessWithTest } unless ActionController::Base < ActionController::ProcessWithTest request = ActionController::TestRequest.new request.action = action - controller.process(request, ActionController::TestResponse.new) + controller = controller.new if controller.is_a?(Class) + controller.process_with_test(request, ActionController::TestResponse.new) end end @@ -874,8 +876,10 @@ class YieldingAroundFiltersTest < Test::Unit::TestCase protected def test_process(controller, action = "show") + ActionController::Base.class_eval { include ActionController::ProcessWithTest } unless ActionController::Base < ActionController::ProcessWithTest request = ActionController::TestRequest.new request.action = action - controller.process(request, ActionController::TestResponse.new) + controller = controller.new if controller.is_a?(Class) + controller.process_with_test(request, ActionController::TestResponse.new) end end diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb index e562531bf3..d8a892811e 100644 --- a/actionpack/test/controller/flash_test.rb +++ b/actionpack/test/controller/flash_test.rb @@ -1,6 +1,6 @@ require 'abstract_unit' -class FlashTest < Test::Unit::TestCase +class FlashTest < ActionController::TestCase class TestController < ActionController::Base def set_flash flash["that"] = "hello" @@ -73,11 +73,7 @@ class FlashTest < Test::Unit::TestCase end end - def setup - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - @controller = TestController.new - end + tests TestController def test_flash get :set_flash diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index 1b7486ad34..5fc79baa44 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -19,7 +19,8 @@ class SendFileController < ActionController::Base def rescue_action(e) raise end end -class SendFileTest < Test::Unit::TestCase +class SendFileTest < ActionController::TestCase + tests SendFileController include TestFileUtils Mime::Type.register "image/png", :png unless defined? Mime::PNG -- cgit v1.2.3 From c90572e3ab65e02933d204747645d0de83b00481 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 7 Jan 2009 14:39:23 -0800 Subject: Use instance_eval instead of adding an accessor to the class --- actionpack/test/controller/layout_test.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index c2efe9d00b..2f5e830fba 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -146,8 +146,7 @@ class LayoutExceptionRaised < ActionController::TestCase def test_exception_raised_when_layout_file_not_found @controller = SetsNonExistentLayoutFile.new get :hello - @response.template.class.module_eval { attr_accessor :exception } - assert_equal ActionView::MissingTemplate, @response.template.exception.class + assert_kind_of ActionView::MissingTemplate, @response.template.instance_eval { @exception } end end -- cgit v1.2.3 From 347db97eddfc4c303a005b71fce9faf12e74e63a Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 7 Jan 2009 14:39:47 -0800 Subject: Take care not to mix in public methods --- actionpack/lib/action_controller/test_case.rb | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 93a0be4127..0b0d0c799b 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -127,17 +127,18 @@ module ActionController # # The exception is stored in the exception accessor for further inspection. module RaiseActionExceptions - attr_accessor :exception + protected + attr_accessor :exception - def rescue_action_without_handler(e) - self.exception = e - - if request.remote_addr == "0.0.0.0" - raise(e) - else - super(e) + def rescue_action_without_handler(e) + self.exception = e + + if request.remote_addr == "0.0.0.0" + raise(e) + else + super(e) + end end - end end setup :setup_controller_request_and_response -- cgit v1.2.3 From 48963a55c7b4cbd06a66a4f9717801a7417acba9 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 7 Jan 2009 15:52:19 -0800 Subject: Set assigns for integration tests also --- actionpack/lib/action_controller/integration.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb index d9899112c3..ded72a71fb 100644 --- a/actionpack/lib/action_controller/integration.rb +++ b/actionpack/lib/action_controller/integration.rb @@ -367,8 +367,10 @@ module ActionController env[key] = value end - unless ActionController::Base.respond_to?(:clear_last_instantiation!) - ActionController::Base.module_eval { include ControllerCapture } + [ControllerCapture, ActionController::ProcessWithTest].each do |mod| + unless ActionController::Base < mod + ActionController::Base.class_eval { include mod } + end end ActionController::Base.clear_last_instantiation! @@ -396,6 +398,7 @@ module ActionController if @controller = ActionController::Base.last_instantiation @request = @controller.request @response = @controller.response + @controller.send(:set_test_assigns) else # Decorate responses from Rack Middleware and Rails Metal # as an Response for the purposes of integration testing -- cgit v1.2.3 From 074414883cd39c24a6197f7450723c6fc60132d0 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 7 Jan 2009 15:55:28 -0800 Subject: Remove Content-Length header from :no_content responses --- actionpack/lib/action_controller/response.rb | 9 ++++++--- actionpack/test/controller/render_test.rb | 7 ++++++- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/response.rb b/actionpack/lib/action_controller/response.rb index 64319fe102..27860a6207 100644 --- a/actionpack/lib/action_controller/response.rb +++ b/actionpack/lib/action_controller/response.rb @@ -231,10 +231,13 @@ module ActionController # :nodoc: # Don't set the Content-Length for block-based bodies as that would mean # reading it all into memory. Not nice for, say, a 2GB streaming file. def set_content_length! - unless body.respond_to?(:call) || (status && status.to_s[0..2] == '304') - self.headers["Content-Length"] ||= body.size + if status && status.to_s[0..2] == '204' + headers.delete('Content-Length') + elsif length = headers['Content-Length'] + headers['Content-Length'] = length.to_s + elsif !body.respond_to?(:call) && (!status || status.to_s[0..2] != '304') + headers["Content-Length"] = body.size.to_s end - headers["Content-Length"] = headers["Content-Length"].to_s if headers["Content-Length"] end def convert_language! diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 5fd41d8eec..8809aa7c34 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -1218,6 +1218,11 @@ class RenderTest < ActionController::TestCase assert_equal "404 Not Found", @response.status assert_response :not_found + get :head_with_symbolic_status, :status => "no_content" + assert_equal "204 No Content", @response.status + assert !@response.headers.include?('Content-Length') + assert_response :no_content + ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE.each do |status, code| get :head_with_symbolic_status, :status => status.to_s assert_equal code, @response.response_code @@ -1470,7 +1475,7 @@ class EtagRenderTest < ActionController::TestCase def test_render_against_etag_request_should_have_no_content_length_when_match @request.if_none_match = etag_for("hello david") get :render_hello_world_from_variable - assert !@response.headers.has_key?("Content-Length") + assert !@response.headers.has_key?("Content-Length"), @response.headers['Content-Length'] end def test_render_against_etag_request_should_200_when_no_match -- cgit v1.2.3 From e1f73aab8ca679a68a32bec6c0d72eb8a58d8788 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Fri, 9 Jan 2009 11:15:38 -0600 Subject: Inherit ActionController::Request from Rack::Request --- actionpack/lib/action_controller/request.rb | 34 ++++------------------ actionpack/lib/action_controller/request_parser.rb | 2 +- 2 files changed, 7 insertions(+), 29 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 6ac8c6f4a0..29d06441e4 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -6,25 +6,17 @@ require 'active_support/memoizable' require 'action_controller/cgi_ext' module ActionController - # CgiRequest and TestRequest provide concrete implementations. - class Request + class Request < Rack::Request extend ActiveSupport::Memoizable - class SessionFixationAttempt < StandardError #:nodoc: - end - - # The hash of environment variables for this request, - # such as { 'RAILS_ENV' => 'production' }. - attr_reader :env - def initialize(env) - @env = env + super @parser = ActionController::RequestParser.new(env) end - %w[ AUTH_TYPE GATEWAY_INTERFACE PATH_INFO + %w[ AUTH_TYPE GATEWAY_INTERFACE PATH_TRANSLATED REMOTE_HOST - REMOTE_IDENT REMOTE_USER SCRIPT_NAME + REMOTE_IDENT REMOTE_USER REMOTE_ADDR SERVER_NAME SERVER_PROTOCOL HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING @@ -45,8 +37,7 @@ module ActionController # The true HTTP request \method as a lowercase symbol, such as :get. # UnknownHttpMethod is raised for invalid methods not listed in ACCEPTED_HTTP_METHODS. def request_method - method = @env['REQUEST_METHOD'] - HTTP_METHOD_LOOKUP[method] || raise(UnknownHttpMethod, "#{method}, accepted HTTP methods are #{HTTP_METHODS.to_sentence}") + HTTP_METHOD_LOOKUP[super] || raise(UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence}") end memoize :request_method @@ -93,7 +84,7 @@ module ActionController # Returns the content length of the request as an integer. def content_length - @env["action_controller.request.content_length"] ||= @env['CONTENT_LENGTH'].to_i + super.to_i end # The MIME type of the HTTP request, such as Mime::XML. @@ -421,15 +412,6 @@ EOM @parser.body end - def remote_addr - @env['REMOTE_ADDR'] - end - - def referrer - @env['HTTP_REFERER'] - end - alias referer referrer - def query_parameters @parser.query_parameters end @@ -442,10 +424,6 @@ EOM @env['rack.input'] end - def cookies - Rack::Request.new(@env).cookies - end - def session @env['rack.session'] ||= {} end diff --git a/actionpack/lib/action_controller/request_parser.rb b/actionpack/lib/action_controller/request_parser.rb index 20d53f5d92..d1739ef4d0 100644 --- a/actionpack/lib/action_controller/request_parser.rb +++ b/actionpack/lib/action_controller/request_parser.rb @@ -91,7 +91,7 @@ module ActionController end def content_length - @env["action_controller.request.content_length"] ||= @env['CONTENT_LENGTH'].to_i + @env['CONTENT_LENGTH'].to_i end # The raw content type string. Use when you need parameters such as -- cgit v1.2.3 From 282c1d6159a06dce4dd52c1849daad9e73480808 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Fri, 9 Jan 2009 12:52:59 -0600 Subject: Refactor request query string parsing tests --- actionpack/lib/action_controller/request.rb | 4 +- .../test/controller/query_string_parsing_test.rb | 118 +++++++++++++++++++++ actionpack/test/controller/request_test.rb | 106 +----------------- 3 files changed, 122 insertions(+), 106 deletions(-) create mode 100644 actionpack/test/controller/query_string_parsing_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 29d06441e4..8371f1bf5c 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -412,9 +412,11 @@ EOM @parser.body end - def query_parameters + # Override Rack's GET method to support nested query strings + def GET @parser.query_parameters end + alias_method :query_parameters, :GET def request_parameters @parser.request_parameters diff --git a/actionpack/test/controller/query_string_parsing_test.rb b/actionpack/test/controller/query_string_parsing_test.rb new file mode 100644 index 0000000000..91f5b2b27a --- /dev/null +++ b/actionpack/test/controller/query_string_parsing_test.rb @@ -0,0 +1,118 @@ +class QueryStringParsingTest "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"}, + "action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1" + ) + end + + test "deep query string" do + assert_parses( + {'x' => {'y' => {'z' => '10'}}}, + "x[y][z]=10" + ) + end + + test "deep query string with array" do + assert_parses({'x' => {'y' => {'z' => ['10']}}}, 'x[y][z][]=10') + assert_parses({'x' => {'y' => {'z' => ['10', '5']}}}, 'x[y][z][]=10&x[y][z][]=5') + end + + test "deep query string with array of hash" do + assert_parses({'x' => {'y' => [{'z' => '10'}]}}, 'x[y][][z]=10') + assert_parses({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, 'x[y][][z]=10&x[y][][w]=10') + assert_parses({'x' => {'y' => [{'z' => '10', 'v' => {'w' => '10'}}]}}, 'x[y][][z]=10&x[y][][v][w]=10') + end + + test "deep query string with array of hashes with one pair" do + assert_parses({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, 'x[y][][z]=10&x[y][][z]=20') + end + + test "deep query string with array of hashes with multiple pairs" do + assert_parses( + {'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}}, + 'x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b' + ) + end + + test "query string with nil" do + assert_parses( + { "action" => "create_customer", "full_name" => ''}, + "action=create_customer&full_name=" + ) + end + + test "query string with array" do + assert_parses( + { "action" => "create_customer", "selected" => ["1", "2", "3"]}, + "action=create_customer&selected[]=1&selected[]=2&selected[]=3" + ) + end + + test "query string with amps" do + assert_parses( + { "action" => "create_customer", "name" => "Don't & Does"}, + "action=create_customer&name=Don%27t+%26+Does" + ) + end + + test "query string with many equal" do + assert_parses( + { "action" => "create_customer", "full_name" => "abc=def=ghi"}, + "action=create_customer&full_name=abc=def=ghi" + ) + end + + test "query string without equal" do + assert_parses({ "action" => nil }, "action") + end + + test "query string with empty key" do + assert_parses( + { "action" => "create_customer", "full_name" => "David Heinemeier Hansson" }, + "action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save" + ) + end + + test "query string with many ampersands" do + assert_parses( + { "action" => "create_customer", "full_name" => "David Heinemeier Hansson"}, + "&action=create_customer&&&full_name=David%20Heinemeier%20Hansson" + ) + end + + test "unbalanced query string with array" do + assert_parses( + {'location' => ["1", "2"], 'age_group' => ["2"]}, + "location[]=1&location[]=2&age_group[]=2" + ) + end + + private + def assert_parses(expected, actual) + with_routing do |set| + set.draw do |map| + map.connect ':action', :controller => "query_string_parsing_test/test" + end + + get "/parse", actual + assert_response :ok + assert_equal(expected, TestController.last_query_parameters) + end + end +end diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index 02bb2ee890..64cc3f5291 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -407,114 +407,10 @@ class RequestTest < ActiveSupport::TestCase end class UrlEncodedRequestParameterParsingTest < ActiveSupport::TestCase - def setup - @query_string = "action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1" - @query_string_with_empty = "action=create_customer&full_name=" - @query_string_with_array = "action=create_customer&selected[]=1&selected[]=2&selected[]=3" - @query_string_with_amps = "action=create_customer&name=Don%27t+%26+Does" - @query_string_with_multiple_of_same_name = - "action=update_order&full_name=Lau%20Taarnskov&products=4&products=2&products=3" - @query_string_with_many_equal = "action=create_customer&full_name=abc=def=ghi" - @query_string_without_equal = "action" - @query_string_with_many_ampersands = - "&action=create_customer&&&full_name=David%20Heinemeier%20Hansson" - @query_string_with_empty_key = "action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save" - end - - def test_query_string - assert_equal( - { "action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"}, - ActionController::RequestParser.parse_query_parameters(@query_string) - ) - end - - def test_deep_query_string - expected = {'x' => {'y' => {'z' => '10'}}} - assert_equal(expected, ActionController::RequestParser.parse_query_parameters('x[y][z]=10')) - end - - def test_deep_query_string_with_array - assert_equal({'x' => {'y' => {'z' => ['10']}}}, ActionController::RequestParser.parse_query_parameters('x[y][z][]=10')) - assert_equal({'x' => {'y' => {'z' => ['10', '5']}}}, ActionController::RequestParser.parse_query_parameters('x[y][z][]=10&x[y][z][]=5')) - end - - def test_deep_query_string_with_array_of_hash - assert_equal({'x' => {'y' => [{'z' => '10'}]}}, ActionController::RequestParser.parse_query_parameters('x[y][][z]=10')) - assert_equal({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, ActionController::RequestParser.parse_query_parameters('x[y][][z]=10&x[y][][w]=10')) - assert_equal({'x' => {'y' => [{'z' => '10', 'v' => {'w' => '10'}}]}}, ActionController::RequestParser.parse_query_parameters('x[y][][z]=10&x[y][][v][w]=10')) - end - - def test_deep_query_string_with_array_of_hashes_with_one_pair - assert_equal({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, ActionController::RequestParser.parse_query_parameters('x[y][][z]=10&x[y][][z]=20')) - assert_equal("10", ActionController::RequestParser.parse_query_parameters('x[y][][z]=10&x[y][][z]=20')["x"]["y"].first["z"]) - assert_equal("10", ActionController::RequestParser.parse_query_parameters('x[y][][z]=10&x[y][][z]=20').with_indifferent_access[:x][:y].first[:z]) - end - - def test_deep_query_string_with_array_of_hashes_with_multiple_pairs - assert_equal( - {'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}}, - ActionController::RequestParser.parse_query_parameters('x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b') - ) - end - - def test_query_string_with_nil - assert_equal( - { "action" => "create_customer", "full_name" => ''}, - ActionController::RequestParser.parse_query_parameters(@query_string_with_empty) - ) - end - - def test_query_string_with_array - assert_equal( - { "action" => "create_customer", "selected" => ["1", "2", "3"]}, - ActionController::RequestParser.parse_query_parameters(@query_string_with_array) - ) - end - - def test_query_string_with_amps - assert_equal( - { "action" => "create_customer", "name" => "Don't & Does"}, - ActionController::RequestParser.parse_query_parameters(@query_string_with_amps) - ) - end - - def test_query_string_with_many_equal - assert_equal( - { "action" => "create_customer", "full_name" => "abc=def=ghi"}, - ActionController::RequestParser.parse_query_parameters(@query_string_with_many_equal) - ) - end - - def test_query_string_without_equal - assert_equal( - { "action" => nil }, - ActionController::RequestParser.parse_query_parameters(@query_string_without_equal) - ) - end - - def test_query_string_with_empty_key - assert_equal( - { "action" => "create_customer", "full_name" => "David Heinemeier Hansson" }, - ActionController::RequestParser.parse_query_parameters(@query_string_with_empty_key) - ) - end - - def test_query_string_with_many_ampersands - assert_equal( - { "action" => "create_customer", "full_name" => "David Heinemeier Hansson"}, - ActionController::RequestParser.parse_query_parameters(@query_string_with_many_ampersands) - ) - end - def test_unbalanced_query_string_with_array assert_equal( {'location' => ["1", "2"], 'age_group' => ["2"]}, - ActionController::RequestParser.parse_query_parameters("location[]=1&location[]=2&age_group[]=2") - ) - assert_equal( - {'location' => ["1", "2"], 'age_group' => ["2"]}, - ActionController::RequestParser.parse_request_parameters({'location[]' => ["1", "2"], - 'age_group[]' => ["2"]}) + ActionController::RequestParser.parse_request_parameters({'location[]' => ["1", "2"], 'age_group[]' => ["2"]}) ) end -- cgit v1.2.3 From ac4bf1180aa0f82616038522bddaf3ff3d5020c8 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Fri, 9 Jan 2009 13:12:39 -0600 Subject: Ensure we override Rack::Request's POST method too --- actionpack/lib/action_controller/request.rb | 5 ++++- actionpack/test/controller/query_string_parsing_test.rb | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 8371f1bf5c..b4ab1ccda1 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -387,6 +387,7 @@ EOM def parameters @parameters ||= request_parameters.merge(query_parameters).update(path_parameters).with_indifferent_access end + alias_method :params, :parameters def path_parameters=(parameters) #:nodoc: @env["rack.routing_args"] = parameters @@ -418,9 +419,11 @@ EOM end alias_method :query_parameters, :GET - def request_parameters + # Override Rack's POST method to support nested query strings + def POST @parser.request_parameters end + alias_method :request_parameters, :POST def body_stream #:nodoc: @env['rack.input'] diff --git a/actionpack/test/controller/query_string_parsing_test.rb b/actionpack/test/controller/query_string_parsing_test.rb index 91f5b2b27a..a31e326ddf 100644 --- a/actionpack/test/controller/query_string_parsing_test.rb +++ b/actionpack/test/controller/query_string_parsing_test.rb @@ -1,4 +1,6 @@ -class QueryStringParsingTest Date: Fri, 9 Jan 2009 15:43:32 -0600 Subject: Refactor request json params parsing tests --- .../controller/request/json_params_parsing_test.rb | 45 ++++++++++++++++++++++ actionpack/test/controller/request_test.rb | 22 ----------- 2 files changed, 45 insertions(+), 22 deletions(-) create mode 100644 actionpack/test/controller/request/json_params_parsing_test.rb (limited to 'actionpack') diff --git a/actionpack/test/controller/request/json_params_parsing_test.rb b/actionpack/test/controller/request/json_params_parsing_test.rb new file mode 100644 index 0000000000..a3dde72c4e --- /dev/null +++ b/actionpack/test/controller/request/json_params_parsing_test.rb @@ -0,0 +1,45 @@ +require 'abstract_unit' + +class JsonParamsParsingTest < ActionController::IntegrationTest + class TestController < ActionController::Base + class << self + attr_accessor :last_request_parameters + end + + def parse + self.class.last_request_parameters = request.request_parameters + head :ok + end + end + + def teardown + TestController.last_request_parameters = nil + end + + test "parses json params for application json" do + assert_parses( + {"person" => {"name" => "David"}}, + "{\"person\": {\"name\": \"David\"}}", { 'CONTENT_TYPE' => 'application/json' } + ) + end + + test "parses json params for application jsonrequest" do + assert_parses( + {"person" => {"name" => "David"}}, + "{\"person\": {\"name\": \"David\"}}", { 'CONTENT_TYPE' => 'application/jsonrequest' } + ) + end + + private + def assert_parses(expected, actual, headers = {}) + with_routing do |set| + set.draw do |map| + map.connect ':action', :controller => "json_params_parsing_test/test" + end + + post "/parse", actual, headers + assert_response :ok + assert_equal(expected, TestController.last_request_parameters) + end + end +end diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index 64cc3f5291..2eb2693644 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -764,25 +764,3 @@ class LegacyXmlParamsParsingTest < XmlParamsParsingTest ActionController::Request.new(env).request_parameters end end - -class JsonParamsParsingTest < ActiveSupport::TestCase - def test_hash_params_for_application_json - person = parse_body({:person => {:name => "David"}}.to_json,'application/json')[:person] - assert_kind_of Hash, person - assert_equal 'David', person['name'] - end - - def test_hash_params_for_application_jsonrequest - person = parse_body({:person => {:name => "David"}}.to_json,'application/jsonrequest')[:person] - assert_kind_of Hash, person - assert_equal 'David', person['name'] - end - - private - def parse_body(body,content_type) - env = { 'rack.input' => StringIO.new(body), - 'CONTENT_TYPE' => content_type, - 'CONTENT_LENGTH' => body.size.to_s } - ActionController::Request.new(env).request_parameters - end -end -- cgit v1.2.3 From 40a75a509187b6759099a3644b7ae8db9fc14045 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Fri, 9 Jan 2009 16:05:27 -0600 Subject: Refactor request xml params parsing tests --- .../controller/request/xml_params_parsing_test.rb | 88 ++++++++++++++++++++++ actionpack/test/controller/request_test.rb | 54 ------------- 2 files changed, 88 insertions(+), 54 deletions(-) create mode 100644 actionpack/test/controller/request/xml_params_parsing_test.rb (limited to 'actionpack') diff --git a/actionpack/test/controller/request/xml_params_parsing_test.rb b/actionpack/test/controller/request/xml_params_parsing_test.rb new file mode 100644 index 0000000000..ee764e726e --- /dev/null +++ b/actionpack/test/controller/request/xml_params_parsing_test.rb @@ -0,0 +1,88 @@ +require 'abstract_unit' + +class XmlParamsParsingTest < ActionController::IntegrationTest + class TestController < ActionController::Base + class << self + attr_accessor :last_request_parameters + end + + def parse + self.class.last_request_parameters = request.request_parameters + head :ok + end + end + + def teardown + TestController.last_request_parameters = nil + end + + test "parses hash params" do + with_test_routing do + xml = "David" + post "/parse", xml, default_headers + assert_response :ok + assert_equal({"person" => {"name" => "David"}}, TestController.last_request_parameters) + end + end + + test "parses single file" do + with_test_routing do + xml = "David#{ActiveSupport::Base64.encode64('ABC')}" + post "/parse", xml, default_headers + assert_response :ok + + person = TestController.last_request_parameters + assert_equal "image/jpg", person['person']['avatar'].content_type + assert_equal "me.jpg", person['person']['avatar'].original_filename + assert_equal "ABC", person['person']['avatar'].read + end + end + + test "parses multiple files" do + xml = <<-end_body + + David + + #{ActiveSupport::Base64.encode64('ABC')} + #{ActiveSupport::Base64.encode64('DEF')} + + + end_body + + with_test_routing do + post "/parse", xml, default_headers + assert_response :ok + end + + person = TestController.last_request_parameters + + assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type + assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename + assert_equal "ABC", person['person']['avatars']['avatar'].first.read + + assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type + assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename + assert_equal "DEF", person['person']['avatars']['avatar'].last.read + end + + private + def with_test_routing + with_routing do |set| + set.draw do |map| + map.connect ':action', :controller => "xml_params_parsing_test/test" + end + yield + end + end + + def default_headers + {'CONTENT_TYPE' => 'application/xml'} + end +end + +class LegacyXmlParamsParsingTest < XmlParamsParsingTest + private + def default_headers + {'HTTP_X_POST_DATA_FORMAT' => 'xml'} + end +end diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index 2eb2693644..c53f1bc2d9 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -710,57 +710,3 @@ class MultipartRequestParameterParsingTest < ActiveSupport::TestCase end end end - -class XmlParamsParsingTest < ActiveSupport::TestCase - def test_hash_params - person = parse_body("David")[:person] - assert_kind_of Hash, person - assert_equal 'David', person['name'] - end - - def test_single_file - person = parse_body("David#{ActiveSupport::Base64.encode64('ABC')}") - - assert_equal "image/jpg", person['person']['avatar'].content_type - assert_equal "me.jpg", person['person']['avatar'].original_filename - assert_equal "ABC", person['person']['avatar'].read - end - - def test_multiple_files - person = parse_body(<<-end_body) - - David - - #{ActiveSupport::Base64.encode64('ABC')} - #{ActiveSupport::Base64.encode64('DEF')} - - - end_body - - assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type - assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename - assert_equal "ABC", person['person']['avatars']['avatar'].first.read - - assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type - assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename - assert_equal "DEF", person['person']['avatars']['avatar'].last.read - end - - private - def parse_body(body) - env = { 'rack.input' => StringIO.new(body), - 'CONTENT_TYPE' => 'application/xml', - 'CONTENT_LENGTH' => body.size.to_s } - ActionController::Request.new(env).request_parameters - end -end - -class LegacyXmlParamsParsingTest < XmlParamsParsingTest - private - def parse_body(body) - env = { 'rack.input' => StringIO.new(body), - 'HTTP_X_POST_DATA_FORMAT' => 'xml', - 'CONTENT_LENGTH' => body.size.to_s } - ActionController::Request.new(env).request_parameters - end -end -- cgit v1.2.3