active_model_serializers 0.9.0 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +113 -0
  3. data/README.md +112 -19
  4. data/lib/action_controller/serialization.rb +35 -8
  5. data/lib/action_controller/serialization_test_case.rb +4 -4
  6. data/lib/active_model/array_serializer.rb +13 -10
  7. data/lib/active_model/default_serializer.rb +2 -6
  8. data/lib/active_model/serializable.rb +30 -11
  9. data/lib/active_model/serializable/utils.rb +16 -0
  10. data/lib/active_model/serializer.rb +90 -40
  11. data/lib/active_model/serializer/{associations.rb → association.rb} +8 -52
  12. data/lib/active_model/serializer/association/has_many.rb +39 -0
  13. data/lib/active_model/serializer/association/has_one.rb +25 -0
  14. data/lib/active_model/serializer/generators/serializer/scaffold_controller_generator.rb +1 -1
  15. data/lib/active_model/serializer/railtie.rb +12 -0
  16. data/lib/active_model/serializer/version.rb +1 -1
  17. data/lib/active_model_serializers.rb +1 -1
  18. data/lib/active_model_serializers/model/caching.rb +25 -0
  19. data/test/benchmark/app.rb +60 -0
  20. data/test/benchmark/benchmarking_support.rb +67 -0
  21. data/test/benchmark/bm_active_record.rb +41 -0
  22. data/test/benchmark/setup.rb +75 -0
  23. data/test/benchmark/tmp/miniprofiler/mp_timers_6eqewtfgrhitvq5gqm25 +0 -0
  24. data/test/benchmark/tmp/miniprofiler/mp_timers_8083sx03hu72pxz1a4d0 +0 -0
  25. data/test/benchmark/tmp/miniprofiler/mp_timers_fyz2gsml4z0ph9kpoy1c +0 -0
  26. data/test/benchmark/tmp/miniprofiler/mp_timers_hjry5rc32imd42oxoi48 +0 -0
  27. data/test/benchmark/tmp/miniprofiler/mp_timers_m8fpoz2cvt3g9agz0bs3 +0 -0
  28. data/test/benchmark/tmp/miniprofiler/mp_timers_p92m2drnj1i568u3sta0 +0 -0
  29. data/test/benchmark/tmp/miniprofiler/mp_timers_qg52tpca3uesdfguee9i +0 -0
  30. data/test/benchmark/tmp/miniprofiler/mp_timers_s15t1a6mvxe0z7vjv790 +0 -0
  31. data/test/benchmark/tmp/miniprofiler/mp_timers_x8kal3d17nfds6vp4kcj +0 -0
  32. data/test/benchmark/tmp/miniprofiler/mp_views_127.0.0.1 +0 -0
  33. data/test/fixtures/active_record.rb +4 -0
  34. data/test/fixtures/poro.rb +149 -1
  35. data/test/fixtures/template.html.erb +1 -0
  36. data/test/integration/action_controller/namespaced_serialization_test.rb +105 -0
  37. data/test/integration/action_controller/serialization_test.rb +5 -5
  38. data/test/integration/action_controller/serialization_test_case_test.rb +10 -0
  39. data/test/integration/active_record/active_record_test.rb +19 -2
  40. data/test/test_app.rb +3 -0
  41. data/test/tmp/app/assets/javascripts/accounts.js +2 -0
  42. data/test/tmp/app/assets/stylesheets/accounts.css +4 -0
  43. data/test/tmp/app/controllers/accounts_controller.rb +2 -0
  44. data/test/tmp/app/helpers/accounts_helper.rb +2 -0
  45. data/test/tmp/app/serializers/account_serializer.rb +3 -0
  46. data/test/tmp/config/routes.rb +1 -0
  47. data/test/unit/active_model/array_serializer/options_test.rb +16 -0
  48. data/test/unit/active_model/array_serializer/serialization_test.rb +18 -1
  49. data/test/unit/active_model/serializer/associations/build_serializer_test.rb +15 -0
  50. data/test/unit/active_model/serializer/associations_test.rb +30 -0
  51. data/test/unit/active_model/serializer/attributes_test.rb +16 -0
  52. data/test/unit/active_model/serializer/config_test.rb +3 -0
  53. data/test/unit/active_model/serializer/has_many_polymorphic_test.rb +189 -0
  54. data/test/unit/active_model/serializer/has_many_test.rb +52 -17
  55. data/test/unit/active_model/serializer/has_one_and_has_many_test.rb +27 -0
  56. data/test/unit/active_model/serializer/has_one_polymorphic_test.rb +196 -0
  57. data/test/unit/active_model/serializer/has_one_test.rb +46 -0
  58. data/test/unit/active_model/serializer/options_test.rb +27 -0
  59. data/test/unit/active_model/serializer/url_helpers_test.rb +35 -0
  60. data/test/unit/active_model/serilizable_test.rb +50 -0
  61. metadata +98 -25
@@ -0,0 +1 @@
1
+ <p>Hello.</p>
@@ -0,0 +1,105 @@
1
+ require 'test_helper'
2
+
3
+ module ActionController
4
+ module Serialization
5
+ class NamespacedSerializationTest < ActionController::TestCase
6
+ class TestNamespace::MyController < ActionController::Base
7
+ def render_profile_with_namespace
8
+ render json: Profile.new({ name: 'Name 1', description: 'Description 1'})
9
+ end
10
+
11
+ def render_profiles_with_namespace
12
+ render json: [Profile.new({ name: 'Name 1', description: 'Description 1'})]
13
+ end
14
+
15
+ def render_comment
16
+ render json: Comment.new(content: 'Comment 1')
17
+ end
18
+
19
+ def render_comments
20
+ render json: [Comment.new(content: 'Comment 1')]
21
+ end
22
+
23
+ def render_hash
24
+ render json: {message: 'not found'}, status: 404
25
+ end
26
+ end
27
+
28
+ tests TestNamespace::MyController
29
+
30
+ def test_render_profile_with_namespace
31
+ get :render_profile_with_namespace
32
+ assert_serializer TestNamespace::ProfileSerializer
33
+ end
34
+
35
+ def test_render_profiles_with_namespace
36
+ get :render_profiles_with_namespace
37
+ assert_serializer TestNamespace::ProfileSerializer
38
+ end
39
+
40
+ def test_fallback_to_a_version_without_namespace
41
+ get :render_comment
42
+ assert_serializer CommentSerializer
43
+ end
44
+
45
+ def test_array_fallback_to_a_version_without_namespace
46
+ get :render_comments
47
+ assert_serializer CommentSerializer
48
+ end
49
+
50
+ def test_render_hash_regression
51
+ get :render_hash
52
+ assert_equal JSON.parse(response.body), {'message' => 'not found'}
53
+ end
54
+ end
55
+
56
+ class OptionNamespacedSerializationTest < ActionController::TestCase
57
+ class MyController < ActionController::Base
58
+ def default_serializer_options
59
+ {
60
+ namespace: TestNamespace
61
+ }
62
+ end
63
+
64
+ def render_profile_with_namespace_option
65
+ render json: Profile.new({ name: 'Name 1', description: 'Description 1'})
66
+ end
67
+
68
+ def render_profiles_with_namespace_option
69
+ render json: [Profile.new({ name: 'Name 1', description: 'Description 1'})]
70
+ end
71
+
72
+ def render_comment
73
+ render json: Comment.new(content: 'Comment 1')
74
+ end
75
+
76
+ def render_comments
77
+ render json: [Comment.new(content: 'Comment 1')]
78
+ end
79
+ end
80
+
81
+ tests MyController
82
+
83
+ def test_render_profile_with_namespace_option
84
+ get :render_profile_with_namespace_option
85
+ assert_serializer TestNamespace::ProfileSerializer
86
+ end
87
+
88
+ def test_render_profiles_with_namespace_option
89
+ get :render_profiles_with_namespace_option
90
+ assert_serializer TestNamespace::ProfileSerializer
91
+ end
92
+
93
+ def test_fallback_to_a_version_without_namespace
94
+ get :render_comment
95
+ assert_serializer CommentSerializer
96
+ end
97
+
98
+ def test_array_fallback_to_a_version_without_namespace
99
+ get :render_comments
100
+ assert_serializer CommentSerializer
101
+ end
102
+ end
103
+
104
+ end
105
+ end
@@ -213,8 +213,8 @@ module ActionController
213
213
  class LowerCamelWoRootSerializerTest < ActionController::TestCase
214
214
  class WebLogController < ActionController::Base
215
215
  def render_without_root
216
- render json: WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
217
- root: false,
216
+ render json: WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
217
+ root: false,
218
218
  serializer: WebLogLowerCamelSerializer
219
219
  end
220
220
  end
@@ -231,9 +231,9 @@ module ActionController
231
231
  class LowerCamelArrayWoRootSerializerTest < ActionController::TestCase
232
232
  class WebLogController < ActionController::Base
233
233
  def render_array_without_root
234
- render json: [WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
235
- WebLog.new({name: 'Name 2', display_name: 'Display Name 2'})],
236
- root: false,
234
+ render json: [WebLog.new({name: 'Name 1', display_name: 'Display Name 1'}),
235
+ WebLog.new({name: 'Name 2', display_name: 'Display Name 2'})],
236
+ root: false,
237
237
  each_serializer: WebLogLowerCamelSerializer
238
238
  end
239
239
  end
@@ -11,6 +11,11 @@ module ActionController
11
11
  def render_text
12
12
  render text: 'ok'
13
13
  end
14
+
15
+ def render_template
16
+ prepend_view_path "./test/fixtures"
17
+ render template: "template"
18
+ end
14
19
  end
15
20
 
16
21
  tests MyController
@@ -56,6 +61,11 @@ module ActionController
56
61
  end
57
62
  assert_match 'assert_serializer only accepts a String, Symbol, Regexp, ActiveModel::Serializer, or nil', e.message
58
63
  end
64
+
65
+ def test_does_not_overwrite_notification_subscriptions
66
+ get :render_template
67
+ assert_template "template"
68
+ end
59
69
  end
60
70
  end
61
71
  end
@@ -49,15 +49,31 @@ module ActiveModel
49
49
  'ar_tag_ids' => [1, 2],
50
50
  'ar_section_id' => 1
51
51
  },
52
- ar_comments: [{ body: 'what a dumb post', 'ar_tag_ids' => [3, 2] },
52
+ 'ar_comments' => [{ body: 'what a dumb post', 'ar_tag_ids' => [3, 2] },
53
53
  { body: 'i liked it', 'ar_tag_ids' => [3, 1] }],
54
- ar_tags: [{ name: 'happy' }, { name: 'whiny' }, { name: 'short' }],
54
+ 'ar_tags' => [{ name: 'happy' }, { name: 'whiny' }, { name: 'short' }],
55
55
  'ar_sections' => [{ 'name' => 'ruby' }]
56
56
  }, post_serializer.as_json)
57
57
  end
58
58
  end
59
59
  end
60
60
 
61
+ def test_serialization_embedding_ids_in_common_root_key
62
+ post_serializer = AREmbeddedSerializer.new(@post)
63
+
64
+ embed(AREmbeddedSerializer, embed: :ids, embed_in_root: true, embed_in_root_key: :linked) do
65
+ embed(ARCommentSerializer, embed: :ids, embed_in_root: true, embed_in_root_key: :linked) do
66
+ assert_equal({
67
+ 'ar_tags' => [{ name: 'short' },
68
+ { name: 'whiny' },
69
+ { name: 'happy' }],
70
+ 'ar_comments' => [{ body: 'what a dumb post', 'ar_tag_ids' => [3, 2] },
71
+ { body: 'i liked it', 'ar_tag_ids' => [3, 1] }]
72
+ }, post_serializer.as_json[:linked])
73
+ end
74
+ end
75
+ end
76
+
61
77
  private
62
78
 
63
79
  def embed(serializer_class, options = {})
@@ -66,6 +82,7 @@ module ActiveModel
66
82
  serializer_class._associations.each_value do |association|
67
83
  association.embed = options[:embed]
68
84
  association.embed_in_root = options[:embed_in_root]
85
+ association.embed_in_root_key = options[:embed_in_root_key]
69
86
  end
70
87
 
71
88
  yield
data/test/test_app.rb CHANGED
@@ -3,6 +3,9 @@ class TestApp < Rails::Application
3
3
  config.eager_load = false
4
4
  config.secret_key_base = 'abc123'
5
5
  end
6
+ config.after_initialize do
7
+ Rails.application.routes.default_url_options = { host: 'http://example.com' }
8
+ end
6
9
 
7
10
  # Set up a logger to avoid creating a log directory on every run.
8
11
  config.logger = Logger.new(nil)
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,2 @@
1
+ class AccountsController < ApplicationController
2
+ end
@@ -0,0 +1,2 @@
1
+ module AccountsHelper
2
+ end
@@ -0,0 +1,3 @@
1
+ class AccountSerializer < ActiveModel::Serializer
2
+ attributes :id
3
+ end
@@ -0,0 +1 @@
1
+ Rails.application.routes.draw { }
@@ -0,0 +1,16 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class ArraySerializer
5
+ class OptionsTest < Minitest::Test
6
+ def test_custom_options_are_accessible_from_serializer
7
+
8
+ array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
9
+ Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })]
10
+ serializer = ArraySerializer.new(array, only: [:name], context: {foo: :bar})
11
+
12
+ assert_equal({foo: :bar}, serializer.context)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -35,6 +35,23 @@ module ActiveModel
35
35
  end
36
36
  end
37
37
 
38
+ class CustomSerializerClassTest < Minitest::Test
39
+ def setup
40
+ Object.const_set(:CustomSerializer, Class.new)
41
+ end
42
+
43
+ def teardown
44
+ Object.send(:remove_const, :CustomSerializer)
45
+ end
46
+
47
+ def test_serializer_for_array_returns_appropriate_type
48
+ object = {}
49
+ def object.serializer_class; CustomSerializer; end
50
+
51
+ assert_equal CustomSerializer, Serializer.serializer_for(object)
52
+ end
53
+ end
54
+
38
55
  class ModelSerializationTest < Minitest::Test
39
56
  def test_array_serializer_serializes_models
40
57
  array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
@@ -85,7 +102,7 @@ module ActiveModel
85
102
  {title: "Title 1", body: "Body 1", "comment_ids" => @post1.comments.map(&:object_id) },
86
103
  {title: "Title 2", body: "Body 2", "comment_ids" => @post2.comments.map(&:object_id) }
87
104
  ],
88
- comments: [
105
+ 'comments' => [
89
106
  {content: "C1"},
90
107
  {content: "C2"},
91
108
  {content: "C3"},
@@ -7,6 +7,7 @@ module ActiveModel
7
7
  def setup
8
8
  @association = Association::HasOne.new('post', serializer: PostSerializer)
9
9
  @post = Post.new({ title: 'Title 1', body: 'Body 1', date: '1/1/2000' })
10
+ @user = User.new
10
11
  end
11
12
 
12
13
  def test_build_serializer_for_array_called_twice
@@ -15,6 +16,20 @@ module ActiveModel
15
16
  assert_instance_of(PostSerializer, serializer)
16
17
  end
17
18
  end
19
+
20
+ def test_build_serializer_from_in_a_namespace
21
+ assoc = Association::HasOne.new('profile')
22
+ serializer = TestNamespace::UserSerializer.new(@user).build_serializer(assoc)
23
+
24
+ assert_instance_of(TestNamespace::ProfileSerializer, serializer)
25
+ end
26
+
27
+ def test_build_serializer_with_prefix
28
+ assoc = Association::HasOne.new('profile', prefix: :short)
29
+ serializer = UserSerializer.new(@user).build_serializer(assoc)
30
+
31
+ assert_instance_of(ShortProfileSerializer, serializer)
32
+ end
18
33
  end
19
34
  end
20
35
  end
@@ -14,6 +14,36 @@ module ActiveModel
14
14
  assert_equal([:comments],
15
15
  another_inherited_serializer_klass._associations.keys)
16
16
  end
17
+ def test_multiple_nested_associations
18
+ parent = SelfReferencingUserParent.new(name: "The Parent")
19
+ child = SelfReferencingUser.new(name: "The child", parent: parent)
20
+ self_referencing_user_serializer = SelfReferencingUserSerializer.new(child)
21
+ result = self_referencing_user_serializer.as_json
22
+ expected_result = {
23
+ "self_referencing_user"=>{
24
+ :name=>"The child",
25
+ "type_id"=>child.type.object_id,
26
+ "parent_id"=>child.parent.object_id
27
+
28
+ },
29
+ "types"=>[
30
+ {
31
+ :name=>"N1",
32
+ },
33
+ {
34
+ :name=>"N2",
35
+ }
36
+ ],
37
+ "parents"=>[
38
+ {
39
+ :name=>"N1",
40
+ "type_id"=>child.parent.type.object_id,
41
+ "parent_id"=>nil
42
+ }
43
+ ]
44
+ }
45
+ assert_equal(expected_result, result)
46
+ end
17
47
  end
18
48
  end
19
49
  end
@@ -36,6 +36,22 @@ module ActiveModel
36
36
  assert_equal([:name, :description],
37
37
  another_inherited_serializer_klass._attributes)
38
38
  end
39
+
40
+ def tests_query_attributes_strip_question_mark
41
+ model = Class.new(::Model) do
42
+ def strip?
43
+ true
44
+ end
45
+ end
46
+
47
+ serializer = Class.new(ActiveModel::Serializer) do
48
+ attributes :strip?
49
+ end
50
+
51
+ actual = serializer.new(model.new).as_json
52
+
53
+ assert_equal({ strip: true }, actual)
54
+ end
39
55
  end
40
56
  end
41
57
  end
@@ -78,6 +78,9 @@ module ActiveModel
78
78
  assert !association.embed_objects?
79
79
  assert association.embed_in_root
80
80
  assert_equal :lower_camel, association.key_format
81
+ assert_equal 'post', PostSerializer.root_name
82
+ CONFIG.plural_default_root = true
83
+ assert_equal 'posts', PostSerializer.root_name
81
84
  ensure
82
85
  PostSerializer._associations[:comments] = old_association
83
86
  CONFIG.clear
@@ -0,0 +1,189 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class HasManyPolymorphicTest < ActiveModel::TestCase
6
+ def setup
7
+ @association = MailSerializer._associations[:attachments]
8
+ @old_association = @association.dup
9
+
10
+ @mail = Mail.new({ body: 'Body 1' })
11
+ @mail_serializer = MailSerializer.new(@mail)
12
+ end
13
+
14
+ def teardown
15
+ MailSerializer._associations[:attachments] = @old_association
16
+ end
17
+
18
+ def model_name(object)
19
+ object.class.to_s.demodulize.underscore.to_sym
20
+ end
21
+
22
+ def test_associations_definition
23
+ assert_equal 1, MailSerializer._associations.length
24
+ assert_kind_of Association::HasMany, @association
25
+ assert_equal true, @association.polymorphic
26
+ assert_equal 'attachments', @association.name
27
+ end
28
+
29
+ def test_associations_embedding_ids_serialization_using_serializable_hash
30
+ @association.embed = :ids
31
+
32
+ assert_equal({
33
+ body: 'Body 1',
34
+ 'attachment_ids' => @mail.attachments.map do |c|
35
+ { id: c.object_id, type: model_name(c) }
36
+ end
37
+ }, @mail_serializer.serializable_hash)
38
+ end
39
+
40
+ def test_associations_embedding_ids_serialization_using_as_json
41
+ @association.embed = :ids
42
+
43
+ assert_equal({
44
+ 'mail' => {
45
+ :body => 'Body 1',
46
+ 'attachment_ids' => @mail.attachments.map do |c|
47
+ { id: c.object_id, type: model_name(c) }
48
+ end
49
+ }
50
+ }, @mail_serializer.as_json)
51
+ end
52
+
53
+ def test_associations_embedding_ids_serialization_using_serializable_hash_and_key_from_options
54
+ @association.embed = :ids
55
+ @association.key = 'key'
56
+
57
+ assert_equal({
58
+ body: 'Body 1',
59
+ 'key' => @mail.attachments.map do |c|
60
+ { id: c.object_id, type: model_name(c) }
61
+ end
62
+ }, @mail_serializer.serializable_hash)
63
+ end
64
+
65
+ def test_associations_embedding_objects_serialization_using_serializable_hash
66
+ @association.embed = :objects
67
+
68
+ assert_equal({
69
+ body: 'Body 1',
70
+ :attachments => [
71
+ { type: :image, image: { url: 'U1' }},
72
+ { type: :video, video: { html: 'H1' }}
73
+ ]
74
+ }, @mail_serializer.serializable_hash)
75
+ end
76
+
77
+ def test_associations_embedding_objects_serialization_using_as_json
78
+ @association.embed = :objects
79
+
80
+ assert_equal({
81
+ 'mail' => {
82
+ body: 'Body 1',
83
+ attachments: [
84
+ { type: :image, image: { url: 'U1' }},
85
+ { type: :video, video: { html: 'H1' }}
86
+ ]
87
+ }
88
+ }, @mail_serializer.as_json)
89
+ end
90
+
91
+ def test_associations_embedding_nil_objects_serialization_using_as_json
92
+ @association.embed = :objects
93
+ @mail.instance_eval do
94
+ def attachments
95
+ [nil]
96
+ end
97
+ end
98
+
99
+ assert_equal({
100
+ 'mail' => {
101
+ :body => 'Body 1',
102
+ :attachments => [nil]
103
+ }
104
+ }, @mail_serializer.as_json)
105
+ end
106
+
107
+ def test_associations_embedding_objects_serialization_using_serializable_hash_and_root_from_options
108
+ @association.embed = :objects
109
+ @association.embedded_key = 'root'
110
+
111
+ assert_equal({
112
+ body: 'Body 1',
113
+ 'root' => [
114
+ { type: :image, image: { url: 'U1' }},
115
+ { type: :video, video: { html: 'H1' }}
116
+ ]
117
+ }, @mail_serializer.serializable_hash)
118
+ end
119
+
120
+ def test_associations_embedding_ids_including_objects_serialization_using_serializable_hash
121
+ @association.embed = :ids
122
+ @association.embed_in_root = true
123
+
124
+ assert_equal({
125
+ body: 'Body 1',
126
+ 'attachment_ids' => @mail.attachments.map do |c|
127
+ { id: c.object_id, type: model_name(c) }
128
+ end
129
+ }, @mail_serializer.serializable_hash)
130
+ end
131
+
132
+ def test_associations_embedding_ids_including_objects_serialization_using_as_json
133
+ @association.embed = :ids
134
+ @association.embed_in_root = true
135
+
136
+ assert_equal({
137
+ 'mail' => {
138
+ body: 'Body 1',
139
+ 'attachment_ids' => @mail.attachments.map do |c|
140
+ { id: c.object_id, type: model_name(c) }
141
+ end,
142
+ },
143
+ 'attachments' => [
144
+ { type: :image, image: { url: 'U1' }},
145
+ { type: :video, video: { html: 'H1' }}
146
+ ]
147
+ }, @mail_serializer.as_json)
148
+ end
149
+
150
+ def test_associations_embedding_nothing_including_objects_serialization_using_as_json
151
+ @association.embed = nil
152
+ @association.embed_in_root = true
153
+
154
+ assert_equal({
155
+ 'mail' => { body: 'Body 1' },
156
+ 'attachments' => [
157
+ { type: :image, image: { url: 'U1' }},
158
+ { type: :video, video: { html: 'H1' }}
159
+ ]
160
+ }, @mail_serializer.as_json)
161
+ end
162
+
163
+ def test_associations_using_a_given_serializer
164
+ @association.embed = :ids
165
+ @association.embed_in_root = true
166
+ @association.serializer_from_options = Class.new(ActiveModel::Serializer) do
167
+ def fake
168
+ 'fake'
169
+ end
170
+
171
+ attributes :fake
172
+ end
173
+
174
+ assert_equal({
175
+ 'mail' => {
176
+ body: 'Body 1',
177
+ 'attachment_ids' => @mail.attachments.map do |c|
178
+ { id: c.object_id, type: model_name(c) }
179
+ end
180
+ },
181
+ 'attachments' => [
182
+ { type: :image, image: { fake: 'fake' }},
183
+ { type: :video, video: { fake: 'fake' }}
184
+ ]
185
+ }, @mail_serializer.as_json)
186
+ end
187
+ end
188
+ end
189
+ end