From 4cb4bf5ecfe9fc5be2321d5f2a50df74b1f39e38 Mon Sep 17 00:00:00 2001 From: Tad Thorley Date: Thu, 25 Jun 2026 09:49:49 -0600 Subject: [PATCH] only to_unsafe_h when there is a schema to check it --- lib/action_figure/core.rb | 2 ++ test/action_figure/core_test.rb | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/action_figure/core.rb b/lib/action_figure/core.rb index 75c1b46..44fb056 100644 --- a/lib/action_figure/core.rb +++ b/lib/action_figure/core.rb @@ -183,6 +183,8 @@ def notify private def normalize_params(kwargs) + return kwargs unless contract + raw = kwargs[:params] return kwargs unless raw.respond_to?(:to_unsafe_h) diff --git a/test/action_figure/core_test.rb b/test/action_figure/core_test.rb index 73e0d32..9574a2a 100644 --- a/test/action_figure/core_test.rb +++ b/test/action_figure/core_test.rb @@ -202,7 +202,10 @@ def call(params:) assert_equal({ name: "Tad" }, result[:json][:data]) end - def test_params_with_to_unsafe_h_are_unwrapped_without_schema + def test_params_with_to_unsafe_h_pass_through_without_schema + # Without a params_schema there is nothing to validate or whitelist, so + # to_unsafe_h must NOT be called — the raw params object passes through + # untouched and the action handles it (e.g. via strong params) itself. fake_params = Class.new do def initialize(hash) = @hash = hash def to_unsafe_h = @hash @@ -216,10 +219,11 @@ def call(params:) end end - result = action.call(params: fake_params.new({ name: "Tad" })) + raw = fake_params.new({ name: "Tad" }) + result = action.call(params: raw) assert_equal :ok, result[:status] - assert_equal({ name: "Tad" }, result[:json][:data]) + assert_same raw, result[:json][:data] end end