aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test/controller/request
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/test/controller/request')
-rw-r--r--actionpack/test/controller/request/json_params_parsing_test.rb45
-rw-r--r--actionpack/test/controller/request/multipart_params_parsing_test.rb167
-rw-r--r--actionpack/test/controller/request/query_string_parsing_test.rb120
-rw-r--r--actionpack/test/controller/request/xml_params_parsing_test.rb88
4 files changed, 420 insertions, 0 deletions
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/multipart_params_parsing_test.rb b/actionpack/test/controller/request/multipart_params_parsing_test.rb
new file mode 100644
index 0000000000..03ab164972
--- /dev/null
+++ b/actionpack/test/controller/request/multipart_params_parsing_test.rb
@@ -0,0 +1,167 @@
+require 'abstract_unit'
+
+class MultipartParamsParsingTest < ActionController::IntegrationTest
+ class TestController < ActionController::Base
+ class << self
+ attr_accessor :last_request_parameters, :last_request_type
+ end
+
+ def parse
+ self.class.last_request_type = ActionController::Base.param_parsers[request.content_type]
+ self.class.last_request_parameters = request.request_parameters
+ head :ok
+ end
+
+ def read
+ render :text => "File: #{params[:uploaded_data].read}"
+ end
+ end
+
+ FIXTURE_PATH = File.dirname(__FILE__) + '/../../fixtures/multipart'
+
+ def teardown
+ TestController.last_request_parameters = nil
+ TestController.last_request_type = nil
+ end
+
+ test "parses single parameter" do
+ assert_equal({ 'foo' => 'bar' }, parse_multipart('single_parameter'))
+ end
+
+ test "parses bracketed parameters" do
+ assert_equal({ 'foo' => { 'baz' => 'bar'}}, parse_multipart('bracketed_param'))
+ end
+
+ test "parses text file" do
+ params = parse_multipart('text_file')
+ assert_equal %w(file foo), params.keys.sort
+ assert_equal 'bar', params['foo']
+
+ file = params['file']
+ assert_kind_of StringIO, file
+ assert_equal 'file.txt', file.original_filename
+ assert_equal "text/plain", file.content_type
+ assert_equal 'contents', file.read
+ end
+
+ test "parses boundary problem file" do
+ params = parse_multipart('boundary_problem_file')
+ assert_equal %w(file foo), params.keys.sort
+
+ file = params['file']
+ foo = params['foo']
+
+ assert_kind_of Tempfile, file
+
+ assert_equal 'file.txt', file.original_filename
+ assert_equal "text/plain", file.content_type
+
+ assert_equal 'bar', foo
+ end
+
+ test "parses large text file" do
+ params = parse_multipart('large_text_file')
+ assert_equal %w(file foo), params.keys.sort
+ assert_equal 'bar', params['foo']
+
+ file = params['file']
+
+ assert_kind_of Tempfile, file
+
+ assert_equal 'file.txt', file.original_filename
+ assert_equal "text/plain", file.content_type
+ assert ('a' * 20480) == file.read
+ end
+
+ test "parses binary file" do
+ params = parse_multipart('binary_file')
+ assert_equal %w(file flowers foo), params.keys.sort
+ assert_equal 'bar', params['foo']
+
+ file = params['file']
+ assert_kind_of StringIO, file
+ assert_equal 'file.csv', file.original_filename
+ assert_nil file.content_type
+ assert_equal 'contents', file.read
+
+ file = params['flowers']
+ assert_kind_of StringIO, file
+ assert_equal 'flowers.jpg', file.original_filename
+ assert_equal "image/jpeg", file.content_type
+ assert_equal 19512, file.size
+ end
+
+ test "parses mixed files" do
+ params = parse_multipart('mixed_files')
+ assert_equal %w(files foo), params.keys.sort
+ assert_equal 'bar', params['foo']
+
+ # Ruby CGI doesn't handle multipart/mixed for us.
+ files = params['files']
+ assert_kind_of String, files
+ files.force_encoding('ASCII-8BIT') if files.respond_to?(:force_encoding)
+ assert_equal 19756, files.size
+ end
+
+ test "uploads and parses parameters" do
+ with_test_routing do
+ params = { :uploaded_data => fixture_file_upload(FIXTURE_PATH + "/mona_lisa.jpg", "image/jpg") }
+ post '/parse', params, :location => 'blah'
+ assert_equal(:multipart_form, TestController.last_request_type)
+ end
+ end
+
+ test "uploads and reads file" do
+ with_test_routing do
+ post '/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain")
+ assert_equal "File: Hello", response.body
+ end
+ end
+
+ # The lint wrapper is used in integration tests
+ # instead of a normal StringIO class
+ InputWrapper = Rack::Lint::InputWrapper
+
+ test "parses unwindable stream" do
+ InputWrapper.any_instance.expects(:rewind).raises(Errno::ESPIPE)
+ params = parse_multipart('large_text_file')
+ assert_equal %w(file foo), params.keys.sort
+ assert_equal 'bar', params['foo']
+ end
+
+ test "uploads and reads file with unwindable input" do
+ InputWrapper.any_instance.expects(:rewind).raises(Errno::ESPIPE)
+
+ with_test_routing do
+ post '/read', :uploaded_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|
+ { "rack.input" => file.read,
+ "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
+ "CONTENT_LENGTH" => file.stat.size.to_s }
+ end
+ end
+
+ def parse_multipart(name)
+ with_test_routing do
+ headers = fixture(name)
+ post "/parse", headers.delete("rack.input"), headers
+ assert_response :ok
+ TestController.last_request_parameters
+ end
+ end
+
+ def with_test_routing
+ with_routing do |set|
+ set.draw do |map|
+ map.connect ':action', :controller => "multipart_params_parsing_test/test"
+ end
+ yield
+ end
+ end
+end
diff --git a/actionpack/test/controller/request/query_string_parsing_test.rb b/actionpack/test/controller/request/query_string_parsing_test.rb
new file mode 100644
index 0000000000..a31e326ddf
--- /dev/null
+++ b/actionpack/test/controller/request/query_string_parsing_test.rb
@@ -0,0 +1,120 @@
+require 'abstract_unit'
+
+class QueryStringParsingTest < ActionController::IntegrationTest
+ class TestController < ActionController::Base
+ class << self
+ attr_accessor :last_query_parameters
+ end
+
+ def parse
+ self.class.last_query_parameters = request.query_parameters
+ head :ok
+ end
+ end
+
+ def teardown
+ TestController.last_query_parameters = nil
+ end
+
+ test "query string" do
+ assert_parses(
+ {"action" => "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/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 = "<person><name>David</name></person>"
+ 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 = "<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar></person>"
+ 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
+ <person>
+ <name>David</name>
+ <avatars>
+ <avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar>
+ <avatar type='file' name='you.gif' content_type='image/gif'>#{ActiveSupport::Base64.encode64('DEF')}</avatar>
+ </avatars>
+ </person>
+ 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