From ff4095525cc29f9e89e51f914dd635d85ca9f2d2 Mon Sep 17 00:00:00 2001 From: Jon Yurek Date: Fri, 4 Jun 2010 16:43:37 -0400 Subject: [PATCH] Fix for integration tests not serializing arrays in multipart forms correctly. --- actionpack/lib/action_controller/integration.rb | 17 ++++++++++-- actionpack/test/controller/integration_test.rb | 26 ++++++++++++++++++++ .../request/multipart_params_parsing_test.rb | 15 +++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb index 241b2c2..f376952 100644 --- a/actionpack/lib/action_controller/integration.rb +++ b/actionpack/lib/action_controller/integration.rb @@ -414,15 +414,25 @@ module ActionController end def multipart_requestify(params, first=true) - returning Hash.new do |p| + returning Array.new do |p| params.each do |key, value| k = first ? key.to_s : "[#{key.to_s}]" if Hash === value multipart_requestify(value, false).each do |subkey, subvalue| - p[k + subkey] = subvalue + p << [k + subkey, subvalue] + end + elsif Array === value + value.each do |element| + if Hash === element || Array === element + multipart_requestify(element, false).each do |subkey, subvalue| + p << ["#{k}[]#{subkey}", subvalue] + end + else + p << ["#{k}[]", element] + end end else - p[k] = value + p << [k, value] end end end @@ -453,6 +463,7 @@ EOF end end.join("")+"--#{boundary}--\r" end + end # A module used to extend ActionController::Base, so that integration tests diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 3096d47..609fbb5 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -266,6 +266,14 @@ class IntegrationProcessTest < ActionController::IntegrationTest render :text => "foo(1i): #{params[:"foo(1i)"]}, foo(2i): #{params[:"foo(2i)"]}, filesize: #{params[:file].size}", :status => 200 end + def multipart_post_with_nested_params + render :text => "foo: #{params[:foo][0]}, #{params[:foo][1]}; [filesize: #{params[:file_list][0][:content].size}, filesize: #{params[:file_list][1][:content].size}]", :status => 200 + end + + def multipart_post_with_multiparameter_complex_params + render :text => "foo(1i): #{params[:"foo(1i)"]}, foo(2i): #{params[:"foo(2i)"]}, [filesize: #{params[:file_list][0][:content].size}, filesize: #{params[:file_list][1][:content].size}]", :status => 200 + end + def post render :text => "Created", :status => 201 end @@ -405,6 +413,24 @@ class IntegrationProcessTest < ActionController::IntegrationTest end end + def test_multipart_post_with_nested_params + with_test_route_set do + post '/multipart_post_with_nested_params', :"foo" => ['a', 'b'], :file_list => [{:content => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")}, {:content => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")}] + + assert_equal 200, status + assert_equal "foo: a, b; [filesize: 159528, filesize: 159528]", response.body + end + end + + def test_multipart_post_with_multiparameter_complex_attribute_parameters + with_test_route_set do + post '/multipart_post_with_multiparameter_complex_params', :"foo(1i)" => "bar", :"foo(2i)" => "baz", :file_list => [{:content => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")}, {:content => fixture_file_upload(FILES_DIR + "/mona_lisa.jpg", "image/jpg")}] + + assert_equal 200, status + assert_equal "foo(1i): bar, foo(2i): baz, [filesize: 159528, filesize: 159528]", response.body + end + end + def test_head with_test_route_set do head '/get' diff --git a/actionpack/test/controller/request/multipart_params_parsing_test.rb b/actionpack/test/controller/request/multipart_params_parsing_test.rb index cc81a87..46aee37 100644 --- a/actionpack/test/controller/request/multipart_params_parsing_test.rb +++ b/actionpack/test/controller/request/multipart_params_parsing_test.rb @@ -14,6 +14,10 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest def read render :text => "File: #{params[:uploaded_data].read}" end + + def read_complex + render :text => "File: #{params[:level0][:level1][0][:file_data].read}" + end end FIXTURE_PATH = File.dirname(__FILE__) + '/../../fixtures/multipart' @@ -133,6 +137,17 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest end end + test "uploads and reads file in complex parameter" do + with_test_routing do + post '/read_complex', + :level0 => { + :level1 => [ { :file_data => fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain") } + ] + } + assert_equal "File: Hello", response.body + end + end + private def fixture(name) File.open(File.join(FIXTURE_PATH, name), 'rb') do |file| -- 1.7.0.2