aboutsummaryrefslogblamecommitdiffstats
path: root/activemodel/test/cases/attribute_assignment_test.rb
blob: 5c1be6a4563e5165cffd71e5784a92e0e0cb9e22 (plain) (tree)









































































































                                                                                    
require 'cases/helper'
require 'active_support/hash_with_indifferent_access' 

class AttributeAssignmentTest < ActiveModel::TestCase

  class Model
    include ActiveModel::AttributeAssignment

    attr_accessor :name, :description

    def initialize(attributes = {})
      assign_attributes(attributes)
    end

    def broken_attribute=(value)
      non_existing_method(value)
    end

    private
    def metadata=(data)
      @metadata = data
    end
  end

  class ProtectedParams < ActiveSupport::HashWithIndifferentAccess
    def permit!
      @permitted = true
    end

    def permitted?
      @permitted ||= false
    end

    def dup
      super.tap do |duplicate|
        duplicate.instance_variable_set :@permitted, permitted?
      end
    end
  end

  test "simple assignment" do
    model = Model.new

    model.assign_attributes(name: 'hello', description: 'world')
    assert_equal 'hello', model.name
    assert_equal 'world', model.description
  end

  test "assign non-existing attribute" do
    model = Model.new
    error = assert_raises ActiveModel::AttributeAssignment::UnknownAttributeError do
      model.assign_attributes(hz: 1)
    end

    assert_equal model, error.record
    assert_equal "hz", error.attribute
  end

  test "assign private attribute" do
    model = Model.new
    assert_raises ActiveModel::AttributeAssignment::UnknownAttributeError do
      model.assign_attributes(metadata: { a: 1 })
    end
  end

  test "raises NoMethodError if raised in attribute writer" do
    assert_raises NoMethodError do
      Model.new(broken_attribute: 1)
    end
  end

  test "raises ArgumentError if non-hash object passed" do
    assert_raises ArgumentError do
      Model.new(1)
    end
  end

  test 'forbidden attributes cannot be used for mass assignment' do
    params = ProtectedParams.new(name: 'Guille', description: 'm')
    assert_raises(ActiveModel::ForbiddenAttributesError) do
      Model.new(params)
    end
  end

  test 'permitted attributes can be used for mass assignment' do
    params = ProtectedParams.new(name: 'Guille', description: 'desc')
    params.permit!
    model = Model.new(params)

    assert_equal 'Guille', model.name
    assert_equal 'desc', model.description
  end

  test 'regular hash should still be used for mass assignment' do
    model = Model.new(name: 'Guille', description: 'm')

    assert_equal 'Guille', model.name
    assert_equal 'm', model.description
  end

  test 'blank attributes should not raise' do
    model = Model.new
    assert_nil model.assign_attributes(ProtectedParams.new({}))
  end

end