require 'test_helper' module ActiveModel class Serializer class AttributeTest < ActiveSupport::TestCase def setup @blog = Blog.new(id: 1, name: 'AMS Hints', type: 'stuff') @blog_serializer = AlternateBlogSerializer.new(@blog) end def test_attributes_definition assert_equal([:id, :title], @blog_serializer.class._attributes) end def test_json_serializable_hash adapter = ActiveModelSerializers::Adapter::Json.new(@blog_serializer) assert_equal({ blog: { id: 1, title: 'AMS Hints' } }, adapter.serializable_hash) end def test_attribute_inheritance_with_key inherited_klass = Class.new(AlternateBlogSerializer) blog_serializer = inherited_klass.new(@blog) adapter = ActiveModelSerializers::Adapter::Attributes.new(blog_serializer) assert_equal({ id: 1, title: 'AMS Hints' }, adapter.serializable_hash) end def test_multiple_calls_with_the_same_attribute serializer_class = Class.new(ActiveModel::Serializer) do attribute :title attribute :title end assert_equal([:title], serializer_class._attributes) end def test_id_attribute_override serializer = Class.new(ActiveModel::Serializer) do attribute :name, key: :id end adapter = ActiveModelSerializers::Adapter::Json.new(serializer.new(@blog)) assert_equal({ blog: { id: 'AMS Hints' } }, adapter.serializable_hash) end def test_object_attribute_override serializer = Class.new(ActiveModel::Serializer) do attribute :name, key: :object end adapter = ActiveModelSerializers::Adapter::Json.new(serializer.new(@blog)) assert_equal({ blog: { object: 'AMS Hints' } }, adapter.serializable_hash) end def test_type_attribute attribute_serializer = Class.new(ActiveModel::Serializer) do attribute :id, key: :type end attributes_serializer = Class.new(ActiveModel::Serializer) do attributes :type end adapter = ActiveModelSerializers::Adapter::Json.new(attribute_serializer.new(@blog)) assert_equal({ blog: { type: 1 } }, adapter.serializable_hash) adapter = ActiveModelSerializers::Adapter::Json.new(attributes_serializer.new(@blog)) assert_equal({ blog: { type: 'stuff' } }, adapter.serializable_hash) end def test_id_attribute_override_before serializer = Class.new(ActiveModel::Serializer) do def id 'custom' end attribute :id end hash = ActiveModelSerializers::SerializableResource.new(@blog, adapter: :json, serializer: serializer).serializable_hash assert_equal('custom', hash[:blog][:id]) end class PostWithVirtualAttribute < ::Model; end class PostWithVirtualAttributeSerializer < ActiveModel::Serializer attribute :name do "#{object.first_name} #{object.last_name}" end end def test_virtual_attribute_block post = PostWithVirtualAttribute.new(first_name: 'Lucas', last_name: 'Hosseini') hash = serializable(post).serializable_hash expected = { name: 'Lucas Hosseini' } assert_equal(expected, hash) end # rubocop:disable Metrics/AbcSize def test_conditional_associations model = ::Model.new(true: true, false: false) scenarios = [ { options: { if: :true }, included: true }, { options: { if: :false }, included: false }, { options: { unless: :false }, included: true }, { options: { unless: :true }, included: false }, { options: { if: 'object.true' }, included: true }, { options: { if: 'object.false' }, included: false }, { options: { unless: 'object.false' }, included: true }, { options: { unless: 'object.true' }, included: false }, { options: { if: -> { object.true } }, included: true }, { options: { if: -> { object.false } }, included: false }, { options: { unless: -> { object.false } }, included: true }, { options: { unless: -> { object.true } }, included: false }, { options: { if: -> (s) { s.object.true } }, included: true }, { options: { if: -> (s) { s.object.false } }, included: false }, { options: { unless: -> (s) { s.object.false } }, included: true }, { options: { unless: -> (s) { s.object.true } }, included: false } ] scenarios.each do |s| serializer = Class.new(ActiveModel::Serializer) do attribute :attribute, s[:options] def true true end def false false end end hash = serializable(model, serializer: serializer).serializable_hash assert_equal(s[:included], hash.key?(:attribute), "Error with #{s[:options]}") end end def test_illegal_conditional_attributes exception = assert_raises(TypeError) do Class.new(ActiveModel::Serializer) do attribute :x, if: nil end end assert_match(/:if should be a Symbol, String or Proc/, exception.message) end end end end