From bf6db28e463565d40d3d0d11d7c7cb36466dd874 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 14 Oct 2024 16:15:45 +0200 Subject: [PATCH] Improve `ActionController::TestCase` to expose a binary encoded `request.body`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rack spec clearly states: > The input stream is an IO-like object which contains the raw HTTP POST data. > When applicable, its external encoding must be “ASCII-8BIT” and it must be opened in binary mode. Until now its encoding was generally UTF-8, which doesn't accurately reflect production behavior. --- actionpack/CHANGELOG.md | 12 ++++++++++++ actionpack/lib/action_controller/test_case.rb | 2 +- actionpack/test/controller/test_case_test.rb | 13 +++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 2a7aaa600dab7..30f0f603c20f3 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,15 @@ +* Improve `ActionController::TestCase` to expose a binary encoded `request.body`. + + The rack spec clearly states: + + > The input stream is an IO-like object which contains the raw HTTP POST data. + > When applicable, its external encoding must be “ASCII-8BIT” and it must be opened in binary mode. + + Until now its encoding was generally UTF-8, which doesn't accurately reflect production + behavior. + + *Jean Boussier* + * Update `ActionController::AllowBrowser` to support passing method names to `:block` ```ruby diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 85a658ac9ef34..1b77029d9682b 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -123,7 +123,7 @@ def assign_parameters(routes, controller_path, action, parameters, generated_pat end end - data_stream = StringIO.new(data) + data_stream = StringIO.new(data.b) set_header "CONTENT_LENGTH", data_stream.length.to_s set_header "rack.input", data_stream end diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb index bdeb81b999364..6481a71cf4d4f 100644 --- a/actionpack/test/controller/test_case_test.rb +++ b/actionpack/test/controller/test_case_test.rb @@ -53,6 +53,11 @@ def render_body render plain: request.body.read end + def render_body_encoding + request.body.rewind + render plain: request.body.read.encoding.name + end + def test_params render plain: ::JSON.dump(params.to_unsafe_h) end @@ -270,6 +275,14 @@ def test_body_stream assert_equal params.to_query, @response.body end + def test_body_stream_is_binary + params = Hash[:page, { name: "page name" }, "some key", 123] + + post :render_body_encoding, params: params.dup + + assert_equal Encoding::BINARY.name, @response.body + end + def test_document_body_and_params_with_post post :test_params, params: { id: 1 } assert_equal({ "id" => "1", "controller" => "test_case_test/test", "action" => "test_params" }, ::JSON.parse(@response.body))