2016-08-06 12:54:50 -04:00
|
|
|
require "abstract_unit"
|
2009-01-09 14:12:39 -05:00
|
|
|
|
2010-09-24 20:15:52 -04:00
|
|
|
class QueryStringParsingTest < ActionDispatch::IntegrationTest
|
2009-01-09 13:52:59 -05:00
|
|
|
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
|
2013-11-29 22:45:23 -05:00
|
|
|
class EarlyParse
|
|
|
|
def initialize(app)
|
|
|
|
@app = app
|
|
|
|
end
|
|
|
|
|
|
|
|
def call(env)
|
|
|
|
# Trigger a Rack parse so that env caches the query params
|
|
|
|
Rack::Request.new(env).params
|
|
|
|
@app.call(env)
|
|
|
|
end
|
|
|
|
end
|
2009-01-09 13:52:59 -05:00
|
|
|
|
|
|
|
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(
|
2016-08-06 12:54:50 -04:00
|
|
|
{"x" => {"y" => {"z" => "10"}}},
|
2009-01-09 13:52:59 -05:00
|
|
|
"x[y][z]=10"
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "deep query string with array" do
|
2016-08-06 12:54:50 -04:00
|
|
|
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")
|
2009-01-09 13:52:59 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
test "deep query string with array of hash" do
|
2016-08-06 12:54:50 -04:00
|
|
|
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")
|
2009-01-09 13:52:59 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
test "deep query string with array of hashes with one pair" do
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_parses({"x" => {"y" => [{"z" => "10"}, {"z" => "20"}]}}, "x[y][][z]=10&x[y][][z]=20")
|
2009-01-09 13:52:59 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
test "deep query string with array of hashes with multiple pairs" do
|
|
|
|
assert_parses(
|
2016-08-06 12:54:50 -04:00
|
|
|
{"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"
|
2009-01-09 13:52:59 -05:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "query string with nil" do
|
|
|
|
assert_parses(
|
2016-08-06 12:54:50 -04:00
|
|
|
{ "action" => "create_customer", "full_name" => ""},
|
2009-01-09 13:52:59 -05:00
|
|
|
"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
|
2012-05-30 18:13:03 -04:00
|
|
|
assert_parses({"action" => nil}, "action")
|
|
|
|
assert_parses({"action" => {"foo" => nil}}, "action[foo]")
|
|
|
|
assert_parses({"action" => {"foo" => { "bar" => nil }}}, "action[foo][bar]")
|
2014-09-14 06:22:29 -04:00
|
|
|
assert_parses({"action" => {"foo" => { "bar" => [] }}}, "action[foo][bar][]")
|
|
|
|
assert_parses({"action" => {"foo" => [] }}, "action[foo][]")
|
2012-05-30 18:13:03 -04:00
|
|
|
assert_parses({"action"=>{"foo"=>[{"bar"=>nil}]}}, "action[foo][][bar]")
|
2009-01-09 13:52:59 -05:00
|
|
|
end
|
|
|
|
|
2012-06-10 23:44:54 -04:00
|
|
|
def test_array_parses_without_nil
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_parses({"action" => ["1"]}, "action[]=1&action[]")
|
2012-06-10 23:44:54 -04:00
|
|
|
end
|
|
|
|
|
2013-12-05 06:08:34 -05:00
|
|
|
test "perform_deep_munge" do
|
2014-06-05 08:12:44 -04:00
|
|
|
old_perform_deep_munge = ActionDispatch::Request::Utils.perform_deep_munge
|
2013-12-05 06:08:34 -05:00
|
|
|
ActionDispatch::Request::Utils.perform_deep_munge = false
|
|
|
|
begin
|
|
|
|
assert_parses({"action" => nil}, "action")
|
|
|
|
assert_parses({"action" => {"foo" => nil}}, "action[foo]")
|
|
|
|
assert_parses({"action" => {"foo" => {"bar" => nil}}}, "action[foo][bar]")
|
|
|
|
assert_parses({"action" => {"foo" => {"bar" => [nil]}}}, "action[foo][bar][]")
|
|
|
|
assert_parses({"action" => {"foo" => [nil]}}, "action[foo][]")
|
|
|
|
assert_parses({"action" => {"foo" => [{"bar" => nil}]}}, "action[foo][][bar]")
|
2016-08-06 12:54:50 -04:00
|
|
|
assert_parses({"action" => ["1",nil]}, "action[]=1&action[]")
|
2013-12-05 06:08:34 -05:00
|
|
|
ensure
|
2014-06-05 08:12:44 -04:00
|
|
|
ActionDispatch::Request::Utils.perform_deep_munge = old_perform_deep_munge
|
2013-12-05 06:08:34 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-01-09 13:52:59 -05:00
|
|
|
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(
|
2016-08-06 12:54:50 -04:00
|
|
|
{"location" => ["1", "2"], "age_group" => ["2"]},
|
2009-01-09 13:52:59 -05:00
|
|
|
"location[]=1&location[]=2&age_group[]=2"
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2012-05-20 05:04:12 -04:00
|
|
|
test "ambiguous query string returns a bad request" do
|
|
|
|
with_routing do |set|
|
|
|
|
set.draw do
|
2016-03-01 03:48:53 -05:00
|
|
|
ActiveSupport::Deprecation.silence do
|
2016-08-06 12:54:50 -04:00
|
|
|
get ":action", :to => ::QueryStringParsingTest::TestController
|
2016-03-01 03:48:53 -05:00
|
|
|
end
|
2012-05-20 05:04:12 -04:00
|
|
|
end
|
|
|
|
|
2015-01-29 09:19:41 -05:00
|
|
|
get "/parse", headers: { "QUERY_STRING" => "foo[]=bar&foo[4]=bar" }
|
2012-05-20 05:04:12 -04:00
|
|
|
assert_response :bad_request
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-01-09 13:52:59 -05:00
|
|
|
private
|
|
|
|
def assert_parses(expected, actual)
|
|
|
|
with_routing do |set|
|
2010-08-05 09:44:23 -04:00
|
|
|
set.draw do
|
2016-03-01 03:48:53 -05:00
|
|
|
ActiveSupport::Deprecation.silence do
|
2016-08-06 12:54:50 -04:00
|
|
|
get ":action", :to => ::QueryStringParsingTest::TestController
|
2016-03-01 03:48:53 -05:00
|
|
|
end
|
2009-01-09 13:52:59 -05:00
|
|
|
end
|
2013-11-29 22:45:23 -05:00
|
|
|
@app = self.class.build_app(set) do |middleware|
|
|
|
|
middleware.use(EarlyParse)
|
|
|
|
end
|
|
|
|
|
2015-01-04 04:35:06 -05:00
|
|
|
get "/parse", params: actual
|
2009-01-09 13:52:59 -05:00
|
|
|
assert_response :ok
|
2009-11-04 18:25:15 -05:00
|
|
|
assert_equal(expected, ::QueryStringParsingTest::TestController.last_query_parameters)
|
2009-01-09 13:52:59 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|