mirror of
https://github.com/github/rails.git
synced 2026-01-24 13:58:12 -05:00
Merge branch 'master' of git@github.com:rails/rails
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
require 'abstract_unit'
|
||||
|
||||
class UrlEncodedParamsParsingTest < ActionController::IntegrationTest
|
||||
class TestController < ActionController::Base
|
||||
class << self
|
||||
attr_accessor :last_request_parameters, :last_request_type
|
||||
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 unbalanced query string with array" do
|
||||
assert_parses(
|
||||
{'location' => ["1", "2"], 'age_group' => ["2"]},
|
||||
"location[]=1&location[]=2&age_group[]=2"
|
||||
)
|
||||
end
|
||||
|
||||
test "parses nested hash" do
|
||||
query = [
|
||||
"note[viewers][viewer][][type]=User",
|
||||
"note[viewers][viewer][][id]=1",
|
||||
"note[viewers][viewer][][type]=Group",
|
||||
"note[viewers][viewer][][id]=2"
|
||||
].join("&")
|
||||
|
||||
expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
|
||||
assert_parses(expected, query)
|
||||
end
|
||||
|
||||
test "parses more complex nesting" do
|
||||
query = [
|
||||
"customers[boston][first][name]=David",
|
||||
"customers[boston][first][url]=http://David",
|
||||
"customers[boston][second][name]=Allan",
|
||||
"customers[boston][second][url]=http://Allan",
|
||||
"something_else=blah",
|
||||
"something_nil=",
|
||||
"something_empty=",
|
||||
"products[first]=Apple Computer",
|
||||
"products[second]=Pc",
|
||||
"=Save"
|
||||
].join("&")
|
||||
|
||||
expected = {
|
||||
"customers" => {
|
||||
"boston" => {
|
||||
"first" => {
|
||||
"name" => "David",
|
||||
"url" => "http://David"
|
||||
},
|
||||
"second" => {
|
||||
"name" => "Allan",
|
||||
"url" => "http://Allan"
|
||||
}
|
||||
}
|
||||
},
|
||||
"something_else" => "blah",
|
||||
"something_empty" => "",
|
||||
"something_nil" => "",
|
||||
"products" => {
|
||||
"first" => "Apple Computer",
|
||||
"second" => "Pc"
|
||||
}
|
||||
}
|
||||
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with array" do
|
||||
query = "selected[]=1&selected[]=2&selected[]=3"
|
||||
expected = { "selected" => [ "1", "2", "3" ] }
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with non alphanumeric name" do
|
||||
query = "a/b[c]=d"
|
||||
expected = { "a/b" => { "c" => "d" }}
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with single brackets in the middle" do
|
||||
query = "a/b[c]d=e"
|
||||
expected = { "a/b" => {} }
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with separated brackets" do
|
||||
query = "a/b@[c]d[e]=f"
|
||||
expected = { "a/b@" => { }}
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with separated brackets and array" do
|
||||
query = "a/b@[c]d[e][]=f"
|
||||
expected = { "a/b@" => { }}
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with unmatched brackets and array" do
|
||||
query = "a/b@[c][d[e][]=f"
|
||||
expected = { "a/b@" => { "c" => { }}}
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with nil key" do
|
||||
query = "=&test2=value1"
|
||||
expected = { "test2" => "value1" }
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with array prefix and hashes" do
|
||||
query = "a[][b][c]=d"
|
||||
expected = {"a" => [{"b" => {"c" => "d"}}]}
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with complex nesting" do
|
||||
query = "a[][b][c][][d][]=e"
|
||||
expected = {"a" => [{"b" => {"c" => [{"d" => ["e"]}]}}]}
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
test "parses params with file path" do
|
||||
query = [
|
||||
"customers[boston][first][name]=David",
|
||||
"something_else=blah",
|
||||
"logo=#{File.expand_path(__FILE__)}"
|
||||
].join("&")
|
||||
|
||||
expected = {
|
||||
"customers" => {
|
||||
"boston" => {
|
||||
"first" => {
|
||||
"name" => "David"
|
||||
}
|
||||
}
|
||||
},
|
||||
"something_else" => "blah",
|
||||
"logo" => File.expand_path(__FILE__),
|
||||
}
|
||||
|
||||
assert_parses expected, query
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
def with_test_routing
|
||||
with_routing do |set|
|
||||
set.draw do |map|
|
||||
map.connect ':action', :controller => "url_encoded_params_parsing_test/test"
|
||||
end
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
def assert_parses(expected, actual)
|
||||
with_test_routing do
|
||||
post "/parse", actual
|
||||
assert_response :ok
|
||||
assert_equal(expected, TestController.last_request_parameters)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -405,204 +405,3 @@ class RequestTest < ActiveSupport::TestCase
|
||||
@request.request_method(true)
|
||||
end
|
||||
end
|
||||
|
||||
class UrlEncodedRequestParameterParsingTest < ActiveSupport::TestCase
|
||||
def test_unbalanced_query_string_with_array
|
||||
assert_equal(
|
||||
{'location' => ["1", "2"], 'age_group' => ["2"]},
|
||||
ActionController::RequestParser.parse_request_parameters({'location[]' => ["1", "2"], 'age_group[]' => ["2"]})
|
||||
)
|
||||
end
|
||||
|
||||
def test_request_hash_parsing
|
||||
query = {
|
||||
"note[viewers][viewer][][type]" => ["User", "Group"],
|
||||
"note[viewers][viewer][][id]" => ["1", "2"]
|
||||
}
|
||||
|
||||
expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
|
||||
|
||||
assert_equal(expected, ActionController::RequestParser.parse_request_parameters(query))
|
||||
end
|
||||
|
||||
def test_parse_params
|
||||
input = {
|
||||
"customers[boston][first][name]" => [ "David" ],
|
||||
"customers[boston][first][url]" => [ "http://David" ],
|
||||
"customers[boston][second][name]" => [ "Allan" ],
|
||||
"customers[boston][second][url]" => [ "http://Allan" ],
|
||||
"something_else" => [ "blah" ],
|
||||
"something_nil" => [ nil ],
|
||||
"something_empty" => [ "" ],
|
||||
"products[first]" => [ "Apple Computer" ],
|
||||
"products[second]" => [ "Pc" ],
|
||||
"" => [ 'Save' ]
|
||||
}
|
||||
|
||||
expected_output = {
|
||||
"customers" => {
|
||||
"boston" => {
|
||||
"first" => {
|
||||
"name" => "David",
|
||||
"url" => "http://David"
|
||||
},
|
||||
"second" => {
|
||||
"name" => "Allan",
|
||||
"url" => "http://Allan"
|
||||
}
|
||||
}
|
||||
},
|
||||
"something_else" => "blah",
|
||||
"something_empty" => "",
|
||||
"something_nil" => "",
|
||||
"products" => {
|
||||
"first" => "Apple Computer",
|
||||
"second" => "Pc"
|
||||
}
|
||||
}
|
||||
|
||||
assert_equal expected_output, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
UploadedStringIO = ActionController::UploadedStringIO
|
||||
class MockUpload < UploadedStringIO
|
||||
def initialize(content_type, original_path, *args)
|
||||
self.content_type = content_type
|
||||
self.original_path = original_path
|
||||
super *args
|
||||
end
|
||||
end
|
||||
|
||||
def test_parse_params_from_multipart_upload
|
||||
file = MockUpload.new('img/jpeg', 'foo.jpg')
|
||||
ie_file = MockUpload.new('img/jpeg', 'c:\\Documents and Settings\\foo\\Desktop\\bar.jpg')
|
||||
non_file_text_part = MockUpload.new('text/plain', '', 'abc')
|
||||
|
||||
input = {
|
||||
"something" => [ UploadedStringIO.new("") ],
|
||||
"array_of_stringios" => [[ UploadedStringIO.new("One"), UploadedStringIO.new("Two") ]],
|
||||
"mixed_types_array" => [[ UploadedStringIO.new("Three"), "NotStringIO" ]],
|
||||
"mixed_types_as_checkboxes[strings][nested]" => [[ file, "String", UploadedStringIO.new("StringIO")]],
|
||||
"ie_mixed_types_as_checkboxes[strings][nested]" => [[ ie_file, "String", UploadedStringIO.new("StringIO")]],
|
||||
"products[string]" => [ UploadedStringIO.new("Apple Computer") ],
|
||||
"products[file]" => [ file ],
|
||||
"ie_products[string]" => [ UploadedStringIO.new("Microsoft") ],
|
||||
"ie_products[file]" => [ ie_file ],
|
||||
"text_part" => [non_file_text_part]
|
||||
}
|
||||
|
||||
expected_output = {
|
||||
"something" => "",
|
||||
"array_of_stringios" => ["One", "Two"],
|
||||
"mixed_types_array" => [ "Three", "NotStringIO" ],
|
||||
"mixed_types_as_checkboxes" => {
|
||||
"strings" => {
|
||||
"nested" => [ file, "String", "StringIO" ]
|
||||
},
|
||||
},
|
||||
"ie_mixed_types_as_checkboxes" => {
|
||||
"strings" => {
|
||||
"nested" => [ ie_file, "String", "StringIO" ]
|
||||
},
|
||||
},
|
||||
"products" => {
|
||||
"string" => "Apple Computer",
|
||||
"file" => file
|
||||
},
|
||||
"ie_products" => {
|
||||
"string" => "Microsoft",
|
||||
"file" => ie_file
|
||||
},
|
||||
"text_part" => "abc"
|
||||
}
|
||||
|
||||
params = ActionController::RequestParser.parse_request_parameters(input)
|
||||
assert_equal expected_output, params
|
||||
|
||||
# Lone filenames are preserved.
|
||||
assert_equal 'foo.jpg', params['mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
|
||||
assert_equal 'foo.jpg', params['products']['file'].original_filename
|
||||
|
||||
# But full Windows paths are reduced to their basename.
|
||||
assert_equal 'bar.jpg', params['ie_mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
|
||||
assert_equal 'bar.jpg', params['ie_products']['file'].original_filename
|
||||
end
|
||||
|
||||
def test_parse_params_with_file
|
||||
input = {
|
||||
"customers[boston][first][name]" => [ "David" ],
|
||||
"something_else" => [ "blah" ],
|
||||
"logo" => [ File.new(File.dirname(__FILE__) + "/rack_test.rb").path ]
|
||||
}
|
||||
|
||||
expected_output = {
|
||||
"customers" => {
|
||||
"boston" => {
|
||||
"first" => {
|
||||
"name" => "David"
|
||||
}
|
||||
}
|
||||
},
|
||||
"something_else" => "blah",
|
||||
"logo" => File.new(File.dirname(__FILE__) + "/rack_test.rb").path,
|
||||
}
|
||||
|
||||
assert_equal expected_output, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
def test_parse_params_with_array
|
||||
input = { "selected[]" => [ "1", "2", "3" ] }
|
||||
|
||||
expected_output = { "selected" => [ "1", "2", "3" ] }
|
||||
|
||||
assert_equal expected_output, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
def test_parse_params_with_non_alphanumeric_name
|
||||
input = { "a/b[c]" => %w(d) }
|
||||
expected = { "a/b" => { "c" => "d" }}
|
||||
assert_equal expected, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
def test_parse_params_with_single_brackets_in_middle
|
||||
input = { "a/b[c]d" => %w(e) }
|
||||
expected = { "a/b" => {} }
|
||||
assert_equal expected, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
def test_parse_params_with_separated_brackets
|
||||
input = { "a/b@[c]d[e]" => %w(f) }
|
||||
expected = { "a/b@" => { }}
|
||||
assert_equal expected, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
def test_parse_params_with_separated_brackets_and_array
|
||||
input = { "a/b@[c]d[e][]" => %w(f) }
|
||||
expected = { "a/b@" => { }}
|
||||
assert_equal expected , ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
def test_parse_params_with_unmatched_brackets_and_array
|
||||
input = { "a/b@[c][d[e][]" => %w(f) }
|
||||
expected = { "a/b@" => { "c" => { }}}
|
||||
assert_equal expected, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
def test_parse_params_with_nil_key
|
||||
input = { nil => nil, "test2" => %w(value1) }
|
||||
expected = { "test2" => "value1" }
|
||||
assert_equal expected, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
def test_parse_params_with_array_prefix_and_hashes
|
||||
input = { "a[][b][c]" => %w(d) }
|
||||
expected = {"a" => [{"b" => {"c" => "d"}}]}
|
||||
assert_equal expected, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
|
||||
def test_parse_params_with_complex_nesting
|
||||
input = { "a[][b][c][][d][]" => %w(e) }
|
||||
expected = {"a" => [{"b" => {"c" => [{"d" => ["e"]}]}}]}
|
||||
assert_equal expected, ActionController::RequestParser.parse_request_parameters(input)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user