Validate keys in the `_fixture` field

Otherwise it can be very hard to figure out that we made a typo.

Fix: https://github.com/rails/rails/issues/42441
This commit is contained in:
Jean Boussier 2021-06-15 10:43:30 +02:00
parent e581678396
commit fccbcd6574
3 changed files with 31 additions and 1 deletions

View File

@ -1,3 +1,10 @@
* Fixture configurations (`_fixture`) are now strictly validated.
If an error will be raised if that entry contains unknown keys while previously it
would silently have no effects.
*Jean Boussier*
* Add `ActiveRecord::Base.update!` that works like `ActiveRecord::Base.update` but raises exceptions.
This allows for the same behavior as the instance method `#update!` at a class level.

View File

@ -41,7 +41,7 @@ module ActiveRecord
@config_row ||= begin
row = raw_rows.find { |fixture_name, _| fixture_name == "_fixture" }
if row
row.last
validate_config_row(row.last)
else
{ 'model_class': nil, 'ignore': nil }
end
@ -58,6 +58,20 @@ module ActiveRecord
end
end
def validate_config_row(data)
unless Hash === data
raise Fixture::FormatError, "Invalid `_fixture` section: `_fixture` must be a hash: #{@file}"
end
begin
data.assert_valid_keys("model_class", "ignore")
rescue ArgumentError => error
raise Fixture::FormatError, "Invalid `_fixture` section: #{error.message}: #{@file}"
end
data
end
# Validate our unmarshalled data.
def validate(data)
unless Hash === data || YAML::Omap === data

View File

@ -70,6 +70,15 @@ module ActiveRecord
end
end
def test_wrong_config_row
tmp_yaml ["empty", "yml"], { "_fixture" => { "class_name" => "Foo" } }.to_yaml do |t|
error = assert_raises(ActiveRecord::Fixture::FormatError) do
File.open(t.path) { |fh| fh.model_class }
end
assert_includes error.message, "Invalid `_fixture` section"
end
end
def test_render_context_helper
ActiveRecord::FixtureSet.context_class.class_eval do
def fixture_helper