2016-08-06 12:54:50 -04:00
|
|
|
require "abstract_unit"
|
2009-01-09 16:43:32 -05:00
|
|
|
|
2010-09-24 20:15:52 -04:00
|
|
|
class JsonParamsParsingTest < ActionDispatch::IntegrationTest
|
2009-01-09 16:43:32 -05:00
|
|
|
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"}},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"person\": {\"name\": \"David\"}}", { "CONTENT_TYPE" => "application/json" }
|
2009-01-09 16:43:32 -05:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2014-01-23 21:56:28 -05:00
|
|
|
test "parses boolean and number json params for application json" do
|
|
|
|
assert_parses(
|
|
|
|
{"item" => {"enabled" => false, "count" => 10}},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"item\": {\"enabled\": false, \"count\": 10}}", { "CONTENT_TYPE" => "application/json" }
|
2014-01-23 21:56:28 -05:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2009-01-09 16:43:32 -05:00
|
|
|
test "parses json params for application jsonrequest" do
|
|
|
|
assert_parses(
|
|
|
|
{"person" => {"name" => "David"}},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"person\": {\"name\": \"David\"}}", { "CONTENT_TYPE" => "application/jsonrequest" }
|
2009-01-09 16:43:32 -05:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2016-02-16 23:17:52 -05:00
|
|
|
test "does not parse unregistered media types such as application/vnd.api+json" do
|
2015-08-15 14:18:39 -04:00
|
|
|
assert_parses(
|
2016-02-16 11:17:33 -05:00
|
|
|
{},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"person\": {\"name\": \"David\"}}", { "CONTENT_TYPE" => "application/vnd.api+json" }
|
2015-08-15 14:18:39 -04:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2013-01-04 15:02:22 -05:00
|
|
|
test "nils are stripped from collections" do
|
|
|
|
assert_parses(
|
2014-09-14 06:22:29 -04:00
|
|
|
{"person" => []},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"person\":[null]}", { "CONTENT_TYPE" => "application/json" }
|
2013-01-04 15:02:22 -05:00
|
|
|
)
|
|
|
|
assert_parses(
|
2016-08-06 12:54:50 -04:00
|
|
|
{"person" => ["foo"]},
|
|
|
|
"{\"person\":[\"foo\",null]}", { "CONTENT_TYPE" => "application/json" }
|
2013-01-04 15:02:22 -05:00
|
|
|
)
|
|
|
|
assert_parses(
|
2014-09-14 06:22:29 -04:00
|
|
|
{"person" => []},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"person\":[null, null]}", { "CONTENT_TYPE" => "application/json" }
|
2013-01-04 15:02:22 -05:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2009-08-11 00:56:46 -04:00
|
|
|
test "logs error if parsing unsuccessful" do
|
|
|
|
with_test_routing do
|
2011-11-24 14:37:48 -05:00
|
|
|
output = StringIO.new
|
|
|
|
json = "[\"person]\": {\"name\": \"David\"}}"
|
2016-08-06 12:54:50 -04:00
|
|
|
post "/parse", params: json, headers: { "CONTENT_TYPE" => "application/json", "action_dispatch.show_exceptions" => true, "action_dispatch.logger" => ActiveSupport::Logger.new(output) }
|
2013-05-01 09:48:01 -04:00
|
|
|
assert_response :bad_request
|
2011-11-24 14:37:48 -05:00
|
|
|
output.rewind && err = output.read
|
|
|
|
assert err =~ /Error occurred while parsing request parameters/
|
2009-08-11 00:56:46 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-11-23 09:49:43 -05:00
|
|
|
test "occurring a parse error if parsing unsuccessful" do
|
|
|
|
with_test_routing do
|
|
|
|
begin
|
|
|
|
$stderr = StringIO.new # suppress the log
|
|
|
|
json = "[\"person]\": {\"name\": \"David\"}}"
|
2016-08-06 12:54:50 -04:00
|
|
|
exception = assert_raise(ActionDispatch::ParamsParser::ParseError) { post "/parse", json, {"CONTENT_TYPE" => "application/json", "action_dispatch.show_exceptions" => false} }
|
2015-11-03 09:54:34 -05:00
|
|
|
assert_equal JSON::ParserError, exception.cause.class
|
|
|
|
assert_equal exception.cause.message, exception.message
|
2011-11-23 09:49:43 -05:00
|
|
|
ensure
|
|
|
|
$stderr = STDERR
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-08-06 12:54:50 -04:00
|
|
|
test "raw_post is not empty for JSON request" do
|
2013-07-07 18:32:22 -04:00
|
|
|
with_test_routing do
|
2016-08-06 12:54:50 -04:00
|
|
|
post "/parse", params: '{"posts": [{"title": "Post Title"}]}', headers: { "CONTENT_TYPE" => "application/json" }
|
2013-07-07 18:32:22 -04:00
|
|
|
assert_equal '{"posts": [{"title": "Post Title"}]}', request.raw_post
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-01-09 16:43:32 -05:00
|
|
|
private
|
|
|
|
def assert_parses(expected, actual, headers = {})
|
2009-08-11 00:56:46 -04:00
|
|
|
with_test_routing do
|
2015-01-04 04:35:06 -05:00
|
|
|
post "/parse", params: actual, headers: headers
|
2009-08-11 00:56:46 -04:00
|
|
|
assert_response :ok
|
|
|
|
assert_equal(expected, TestController.last_request_parameters)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def with_test_routing
|
2009-01-09 16:43:32 -05:00
|
|
|
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
|
|
|
post ":action", :to => ::JsonParamsParsingTest::TestController
|
2016-03-01 03:48:53 -05:00
|
|
|
end
|
2009-01-09 16:43:32 -05:00
|
|
|
end
|
2009-08-11 00:56:46 -04:00
|
|
|
yield
|
2009-01-09 16:43:32 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2011-04-28 04:56:11 -04:00
|
|
|
|
|
|
|
class RootLessJSONParamsParsingTest < ActionDispatch::IntegrationTest
|
|
|
|
class UsersController < ActionController::Base
|
|
|
|
wrap_parameters :format => :json
|
|
|
|
|
|
|
|
class << self
|
|
|
|
attr_accessor :last_request_parameters, :last_parameters
|
|
|
|
end
|
|
|
|
|
|
|
|
def parse
|
|
|
|
self.class.last_request_parameters = request.request_parameters
|
2015-07-13 16:43:21 -04:00
|
|
|
self.class.last_parameters = params.to_unsafe_h
|
2011-04-28 04:56:11 -04:00
|
|
|
head :ok
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def teardown
|
|
|
|
UsersController.last_request_parameters = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
test "parses json params for application json" do
|
|
|
|
assert_parses(
|
|
|
|
{"user" => {"username" => "sikachu"}, "username" => "sikachu"},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"username\": \"sikachu\"}", { "CONTENT_TYPE" => "application/json" }
|
2011-04-28 04:56:11 -04:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "parses json params for application jsonrequest" do
|
|
|
|
assert_parses(
|
|
|
|
{"user" => {"username" => "sikachu"}, "username" => "sikachu"},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"username\": \"sikachu\"}", { "CONTENT_TYPE" => "application/jsonrequest" }
|
2011-04-28 04:56:11 -04:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2013-01-09 15:26:12 -05:00
|
|
|
test "parses json with non-object JSON content" do
|
|
|
|
assert_parses(
|
|
|
|
{"user" => {"_json" => "string content" }, "_json" => "string content" },
|
2016-08-06 12:54:50 -04:00
|
|
|
"\"string content\"", { "CONTENT_TYPE" => "application/json" }
|
2013-01-09 15:26:12 -05:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2016-02-20 04:33:05 -05:00
|
|
|
test "parses json params after custom json mime type registered" do
|
2016-02-22 15:37:53 -05:00
|
|
|
begin
|
|
|
|
Mime::Type.unregister :json
|
2016-05-23 17:18:27 -04:00
|
|
|
Mime::Type.register "application/json", :json, %w(application/vnd.rails+json)
|
2016-02-22 15:37:53 -05:00
|
|
|
assert_parses(
|
|
|
|
{"user" => {"username" => "meinac"}, "username" => "meinac"},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"username\": \"meinac\"}", { "CONTENT_TYPE" => "application/json" }
|
2016-02-22 15:37:53 -05:00
|
|
|
)
|
|
|
|
ensure
|
|
|
|
Mime::Type.unregister :json
|
|
|
|
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
|
|
|
|
end
|
2016-02-20 04:33:05 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
test "parses json params after custom json mime type registered with synonym" do
|
2016-02-22 15:37:53 -05:00
|
|
|
begin
|
|
|
|
Mime::Type.unregister :json
|
2016-05-23 17:18:27 -04:00
|
|
|
Mime::Type.register "application/json", :json, %w(application/vnd.rails+json)
|
2016-02-22 15:37:53 -05:00
|
|
|
assert_parses(
|
|
|
|
{"user" => {"username" => "meinac"}, "username" => "meinac"},
|
2016-08-06 12:54:50 -04:00
|
|
|
"{\"username\": \"meinac\"}", { "CONTENT_TYPE" => "application/vnd.rails+json" }
|
2016-02-22 15:37:53 -05:00
|
|
|
)
|
|
|
|
ensure
|
|
|
|
Mime::Type.unregister :json
|
|
|
|
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
|
|
|
|
end
|
2016-02-20 04:33:05 -05:00
|
|
|
end
|
|
|
|
|
2011-04-28 04:56:11 -04:00
|
|
|
private
|
|
|
|
def assert_parses(expected, actual, headers = {})
|
|
|
|
with_test_routing(UsersController) do
|
2015-01-04 04:35:06 -05:00
|
|
|
post "/parse", params: actual, headers: headers
|
2011-04-28 04:56:11 -04:00
|
|
|
assert_response :ok
|
|
|
|
assert_equal(expected, UsersController.last_request_parameters)
|
|
|
|
assert_equal(expected.merge({"action" => "parse"}), UsersController.last_parameters)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def with_test_routing(controller)
|
|
|
|
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
|
|
|
post ":action", :to => controller
|
2016-03-01 03:48:53 -05:00
|
|
|
end
|
2011-04-28 04:56:11 -04:00
|
|
|
end
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|