diff options
Diffstat (limited to 'activerecord/test/cases/forbidden_attributes_protection_test.rb')
-rw-r--r-- | activerecord/test/cases/forbidden_attributes_protection_test.rb | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/activerecord/test/cases/forbidden_attributes_protection_test.rb b/activerecord/test/cases/forbidden_attributes_protection_test.rb new file mode 100644 index 0000000000..101fa118c8 --- /dev/null +++ b/activerecord/test/cases/forbidden_attributes_protection_test.rb @@ -0,0 +1,166 @@ +# frozen_string_literal: true + +require "cases/helper" +require "active_support/core_ext/hash/indifferent_access" + +require "models/company" +require "models/person" +require "models/ship" +require "models/ship_part" +require "models/treasure" + +class ProtectedParams + attr_accessor :permitted + alias :permitted? :permitted + + delegate :keys, :key?, :has_key?, :empty?, to: :@parameters + + def initialize(attributes) + @parameters = attributes.with_indifferent_access + @permitted = false + end + + def permit! + @permitted = true + self + end + + def [](key) + @parameters[key] + end + + def to_h + @parameters + end + + def stringify_keys + dup + end + + def dup + super.tap do |duplicate| + duplicate.instance_variable_set :@permitted, @permitted + end + end +end + +class ForbiddenAttributesProtectionTest < ActiveRecord::TestCase + def test_forbidden_attributes_cannot_be_used_for_mass_assignment + params = ProtectedParams.new(first_name: "Guille", gender: "m") + assert_raises(ActiveModel::ForbiddenAttributesError) do + Person.new(params) + end + end + + def test_permitted_attributes_can_be_used_for_mass_assignment + params = ProtectedParams.new(first_name: "Guille", gender: "m") + params.permit! + person = Person.new(params) + + assert_equal "Guille", person.first_name + assert_equal "m", person.gender + end + + def test_forbidden_attributes_cannot_be_used_for_sti_inheritance_column + params = ProtectedParams.new(type: "Client") + assert_raises(ActiveModel::ForbiddenAttributesError) do + Company.new(params) + end + end + + def test_permitted_attributes_can_be_used_for_sti_inheritance_column + params = ProtectedParams.new(type: "Client") + params.permit! + person = Company.new(params) + assert_equal person.class, Client + end + + def test_regular_hash_should_still_be_used_for_mass_assignment + person = Person.new(first_name: "Guille", gender: "m") + + assert_equal "Guille", person.first_name + assert_equal "m", person.gender + end + + def test_blank_attributes_should_not_raise + person = Person.new + assert_nil person.assign_attributes(ProtectedParams.new({})) + end + + def test_create_with_checks_permitted + params = ProtectedParams.new(first_name: "Guille", gender: "m") + + assert_raises(ActiveModel::ForbiddenAttributesError) do + Person.create_with(params).create! + end + end + + def test_create_with_works_with_permitted_params + params = ProtectedParams.new(first_name: "Guille").permit! + + person = Person.create_with(params).create! + assert_equal "Guille", person.first_name + end + + def test_create_with_works_with_params_values + params = ProtectedParams.new(first_name: "Guille") + + person = Person.create_with(first_name: params[:first_name]).create! + assert_equal "Guille", person.first_name + end + + def test_where_checks_permitted + params = ProtectedParams.new(first_name: "Guille", gender: "m") + + assert_raises(ActiveModel::ForbiddenAttributesError) do + Person.where(params).create! + end + end + + def test_where_works_with_permitted_params + params = ProtectedParams.new(first_name: "Guille").permit! + + person = Person.where(params).create! + assert_equal "Guille", person.first_name + end + + def test_where_works_with_params_values + params = ProtectedParams.new(first_name: "Guille") + + person = Person.where(first_name: params[:first_name]).create! + assert_equal "Guille", person.first_name + end + + def test_where_not_checks_permitted + params = ProtectedParams.new(first_name: "Guille", gender: "m") + + assert_raises(ActiveModel::ForbiddenAttributesError) do + Person.where().not(params) + end + end + + def test_where_not_works_with_permitted_params + params = ProtectedParams.new(first_name: "Guille").permit! + Person.create!(params) + assert_empty Person.where.not(params).select { |p| p.first_name == "Guille" } + end + + def test_strong_params_style_objects_work_with_singular_associations + params = ProtectedParams.new(name: "Stern", ship_attributes: ProtectedParams.new(name: "The Black Rock").permit!).permit! + part = ShipPart.new(params) + + assert_equal "Stern", part.name + assert_equal "The Black Rock", part.ship.name + end + + def test_strong_params_style_objects_work_with_collection_associations + params = ProtectedParams.new( + trinkets_attributes: ProtectedParams.new( + "0" => ProtectedParams.new(name: "Necklace").permit!, + "1" => ProtectedParams.new(name: "Spoon").permit!)).permit! + part = ShipPart.new(params) + + assert_equal "Necklace", part.trinkets[0].name + assert_equal "Spoon", part.trinkets[1].name + end +end |