attribute_assignment_test.rb 2.6 KB
Newer Older
S
Sean Griffin 已提交
1 2
require "cases/helper"
require "active_support/hash_with_indifferent_access"
3 4 5 6 7 8 9 10 11 12 13 14

class AttributeAssignmentTest < ActiveModel::TestCase
  class Model
    include ActiveModel::AttributeAssignment

    attr_accessor :name, :description

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

    def broken_attribute=(value)
S
Sean Griffin 已提交
15
      raise ErrorFromAttributeWriter
16 17
    end

S
Sean Griffin 已提交
18 19 20 21 22 23
    protected

    attr_writer :metadata
  end

  class ErrorFromAttributeWriter < StandardError
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
  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

S
Sean Griffin 已提交
45 46 47
    model.assign_attributes(name: "hello", description: "world")
    assert_equal "hello", model.name
    assert_equal "world", model.description
48 49 50 51
  end

  test "assign non-existing attribute" do
    model = Model.new
R
Robin Dupret 已提交
52
    error = assert_raises(ActiveModel::UnknownAttributeError) do
53 54 55 56 57 58 59 60 61
      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
R
Robin Dupret 已提交
62
    assert_raises(ActiveModel::UnknownAttributeError) do
63 64 65 66
      model.assign_attributes(metadata: { a: 1 })
    end
  end

S
Sean Griffin 已提交
67 68
  test "does not swallow errors raised in an attribute writer" do
    assert_raises(ErrorFromAttributeWriter) do
69 70 71 72
      Model.new(broken_attribute: 1)
    end
  end

S
Sean Griffin 已提交
73 74
  test "an ArgumentError is raised if a non-hash-like obejct is passed" do
    assert_raises(ArgumentError) do
75 76 77 78
      Model.new(1)
    end
  end

S
Sean Griffin 已提交
79 80 81
  test "forbidden attributes cannot be used for mass assignment" do
    params = ProtectedParams.new(name: "Guille", description: "m")

82 83 84 85 86
    assert_raises(ActiveModel::ForbiddenAttributesError) do
      Model.new(params)
    end
  end

S
Sean Griffin 已提交
87 88
  test "permitted attributes can be used for mass assignment" do
    params = ProtectedParams.new(name: "Guille", description: "desc")
89 90 91
    params.permit!
    model = Model.new(params)

S
Sean Griffin 已提交
92 93
    assert_equal "Guille", model.name
    assert_equal "desc", model.description
94 95
  end

S
Sean Griffin 已提交
96 97
  test "regular hash should still be used for mass assignment" do
    model = Model.new(name: "Guille", description: "m")
98

S
Sean Griffin 已提交
99 100
    assert_equal "Guille", model.name
    assert_equal "m", model.description
101 102
  end

S
Sean Griffin 已提交
103
  test "assigning no attributes should not raise, even if the hash is un-permitted" do
104 105 106 107
    model = Model.new
    assert_nil model.assign_attributes(ProtectedParams.new({}))
  end
end