File: attribute_test.rb

package info (click to toggle)
ruby-active-model-serializers 0.10.12-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,752 kB
  • sloc: ruby: 13,138; sh: 53; makefile: 6
file content (155 lines) | stat: -rw-r--r-- 5,538 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# frozen_string_literal: true

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; attributes :first_name, :last_name 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 = Class.new(::Model) do
          attributes :true, :false, :attribute
        end.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