cheap_ams 0.10.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.travis.yml +26 -0
  4. data/CHANGELOG.md +13 -0
  5. data/CONTRIBUTING.md +31 -0
  6. data/Gemfile +35 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +348 -0
  9. data/Rakefile +12 -0
  10. data/appveyor.yml +25 -0
  11. data/cheap_ams.gemspec +49 -0
  12. data/docs/README.md +27 -0
  13. data/docs/general/adapters.md +51 -0
  14. data/docs/general/getting_started.md +73 -0
  15. data/docs/howto/add_pagination_links.md +112 -0
  16. data/docs/howto/add_root_key.md +51 -0
  17. data/lib/action_controller/serialization.rb +62 -0
  18. data/lib/active_model/serializable_resource.rb +84 -0
  19. data/lib/active_model/serializer/adapter/flatten_json.rb +19 -0
  20. data/lib/active_model/serializer/adapter/fragment_cache.rb +82 -0
  21. data/lib/active_model/serializer/adapter/json/fragment_cache.rb +16 -0
  22. data/lib/active_model/serializer/adapter/json.rb +53 -0
  23. data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +24 -0
  24. data/lib/active_model/serializer/adapter/json_api/pagination_links.rb +58 -0
  25. data/lib/active_model/serializer/adapter/json_api.rb +183 -0
  26. data/lib/active_model/serializer/adapter/null.rb +11 -0
  27. data/lib/active_model/serializer/adapter.rb +98 -0
  28. data/lib/active_model/serializer/array_serializer.rb +35 -0
  29. data/lib/active_model/serializer/association.rb +21 -0
  30. data/lib/active_model/serializer/associations.rb +97 -0
  31. data/lib/active_model/serializer/belongs_to_reflection.rb +10 -0
  32. data/lib/active_model/serializer/collection_reflection.rb +7 -0
  33. data/lib/active_model/serializer/configuration.rb +14 -0
  34. data/lib/active_model/serializer/fieldset.rb +42 -0
  35. data/lib/active_model/serializer/has_many_reflection.rb +10 -0
  36. data/lib/active_model/serializer/has_one_reflection.rb +10 -0
  37. data/lib/active_model/serializer/lint.rb +131 -0
  38. data/lib/active_model/serializer/railtie.rb +9 -0
  39. data/lib/active_model/serializer/reflection.rb +74 -0
  40. data/lib/active_model/serializer/singular_reflection.rb +7 -0
  41. data/lib/active_model/serializer/version.rb +5 -0
  42. data/lib/active_model/serializer.rb +205 -0
  43. data/lib/active_model_serializers.rb +29 -0
  44. data/lib/generators/serializer/USAGE +6 -0
  45. data/lib/generators/serializer/resource_override.rb +12 -0
  46. data/lib/generators/serializer/serializer_generator.rb +37 -0
  47. data/lib/generators/serializer/templates/serializer.rb +8 -0
  48. data/test/action_controller/adapter_selector_test.rb +53 -0
  49. data/test/action_controller/explicit_serializer_test.rb +134 -0
  50. data/test/action_controller/json_api/linked_test.rb +180 -0
  51. data/test/action_controller/json_api/pagination_test.rb +116 -0
  52. data/test/action_controller/serialization_scope_name_test.rb +67 -0
  53. data/test/action_controller/serialization_test.rb +426 -0
  54. data/test/adapter/fragment_cache_test.rb +37 -0
  55. data/test/adapter/json/belongs_to_test.rb +47 -0
  56. data/test/adapter/json/collection_test.rb +82 -0
  57. data/test/adapter/json/has_many_test.rb +47 -0
  58. data/test/adapter/json_api/belongs_to_test.rb +157 -0
  59. data/test/adapter/json_api/collection_test.rb +96 -0
  60. data/test/adapter/json_api/has_many_embed_ids_test.rb +45 -0
  61. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
  62. data/test/adapter/json_api/has_many_test.rb +145 -0
  63. data/test/adapter/json_api/has_one_test.rb +81 -0
  64. data/test/adapter/json_api/json_api_test.rb +38 -0
  65. data/test/adapter/json_api/linked_test.rb +283 -0
  66. data/test/adapter/json_api/pagination_links_test.rb +115 -0
  67. data/test/adapter/json_api/resource_type_config_test.rb +59 -0
  68. data/test/adapter/json_test.rb +47 -0
  69. data/test/adapter/null_test.rb +25 -0
  70. data/test/adapter_test.rb +52 -0
  71. data/test/array_serializer_test.rb +97 -0
  72. data/test/capture_warnings.rb +57 -0
  73. data/test/fixtures/active_record.rb +57 -0
  74. data/test/fixtures/poro.rb +266 -0
  75. data/test/generators/scaffold_controller_generator_test.rb +24 -0
  76. data/test/generators/serializer_generator_test.rb +56 -0
  77. data/test/lint_test.rb +44 -0
  78. data/test/poro_test.rb +9 -0
  79. data/test/serializable_resource_test.rb +27 -0
  80. data/test/serializers/adapter_for_test.rb +50 -0
  81. data/test/serializers/association_macros_test.rb +36 -0
  82. data/test/serializers/associations_test.rb +150 -0
  83. data/test/serializers/attribute_test.rb +62 -0
  84. data/test/serializers/attributes_test.rb +63 -0
  85. data/test/serializers/cache_test.rb +164 -0
  86. data/test/serializers/configuration_test.rb +15 -0
  87. data/test/serializers/fieldset_test.rb +26 -0
  88. data/test/serializers/meta_test.rb +121 -0
  89. data/test/serializers/options_test.rb +21 -0
  90. data/test/serializers/root_test.rb +23 -0
  91. data/test/serializers/serializer_for_test.rb +65 -0
  92. data/test/serializers/urls_test.rb +26 -0
  93. data/test/support/rails_app.rb +21 -0
  94. data/test/support/stream_capture.rb +49 -0
  95. data/test/support/test_case.rb +5 -0
  96. data/test/test_helper.rb +41 -0
  97. metadata +287 -0
@@ -0,0 +1,426 @@
1
+
2
+ require 'test_helper'
3
+
4
+ module ActionController
5
+ module Serialization
6
+ class ImplicitSerializerTest < ActionController::TestCase
7
+ include ActiveSupport::Testing::Stream
8
+ class ImplicitSerializationTestController < ActionController::Base
9
+ def render_using_implicit_serializer
10
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
11
+ render json: @profile
12
+ end
13
+
14
+ def render_using_default_adapter_root
15
+ with_adapter ActiveModel::Serializer::Adapter::JsonApi do
16
+ # JSON-API adapter sets root by default
17
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
18
+ render json: @profile
19
+ end
20
+ end
21
+
22
+ def render_array_using_custom_root
23
+ with_adapter ActiveModel::Serializer::Adapter::Json do
24
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
25
+ render json: [@profile], root: "custom_root"
26
+ end
27
+ end
28
+
29
+ def render_array_that_is_empty_using_custom_root
30
+ with_adapter ActiveModel::Serializer::Adapter::Json do
31
+ render json: [], root: "custom_root"
32
+ end
33
+ end
34
+
35
+ def render_object_using_custom_root
36
+ with_adapter ActiveModel::Serializer::Adapter::Json do
37
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
38
+ render json: @profile, root: "custom_root"
39
+ end
40
+ end
41
+
42
+ def render_array_using_implicit_serializer
43
+ array = [
44
+ Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
45
+ Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })
46
+ ]
47
+ render json: array
48
+ end
49
+
50
+ def render_array_using_implicit_serializer_and_meta
51
+ with_adapter ActiveModel::Serializer::Adapter::JsonApi do
52
+
53
+ @profiles = [
54
+ Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
55
+ ]
56
+
57
+ render json: @profiles, meta: { total: 10 }
58
+ end
59
+ end
60
+
61
+ def render_object_with_cache_enabled
62
+ @comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
63
+ @author = Author.new(id: 1, name: 'Joao Moura.')
64
+ @post = Post.new({ id: 1, title: 'New Post', body: 'Body', comments: [@comment], author: @author })
65
+
66
+ generate_cached_serializer(@post)
67
+
68
+ @post.title = 'ZOMG a New Post'
69
+ render json: @post
70
+ end
71
+
72
+ def render_json_object_without_serializer
73
+ render json: {error: 'Result is Invalid'}
74
+ end
75
+
76
+ def render_json_array_object_without_serializer
77
+ render json: [{error: 'Result is Invalid'}]
78
+ end
79
+
80
+ def update_and_render_object_with_cache_enabled
81
+ @post.updated_at = Time.now
82
+
83
+ generate_cached_serializer(@post)
84
+ render json: @post
85
+ end
86
+
87
+ def render_object_expired_with_cache_enabled
88
+ comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
89
+ author = Author.new(id: 1, name: 'Joao Moura.')
90
+ post = Post.new({ id: 1, title: 'New Post', body: 'Body', comments: [comment], author: author })
91
+
92
+ generate_cached_serializer(post)
93
+
94
+ post.title = 'ZOMG a New Post'
95
+ sleep 0.1
96
+ render json: post
97
+ end
98
+
99
+ def render_changed_object_with_cache_enabled
100
+ comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
101
+ author = Author.new(id: 1, name: 'Joao Moura.')
102
+ post = Post.new({ id: 1, title: 'ZOMG a New Post', body: 'Body', comments: [comment], author: author })
103
+
104
+ render json: post
105
+ end
106
+
107
+ def render_fragment_changed_object_with_only_cache_enabled
108
+ author = Author.new(id: 1, name: 'Joao Moura.')
109
+ role = Role.new({ id: 42, name: 'ZOMG A ROLE', description: 'DESCRIPTION HERE', author: author })
110
+
111
+ generate_cached_serializer(role)
112
+ role.name = 'lol'
113
+ role.description = 'HUEHUEBRBR'
114
+
115
+ render json: role
116
+ end
117
+
118
+ def render_fragment_changed_object_with_except_cache_enabled
119
+ author = Author.new(id: 1, name: 'Joao Moura.')
120
+ bio = Bio.new({ id: 42, content: 'ZOMG A ROLE', rating: 5, author: author })
121
+
122
+ generate_cached_serializer(bio)
123
+ bio.content = 'lol'
124
+ bio.rating = 0
125
+
126
+ render json: bio
127
+ end
128
+
129
+ def render_fragment_changed_object_with_relationship
130
+ comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
131
+ comment2 = Comment.new({ id: 1, body: 'ZOMG AN UPDATED-BUT-NOT-CACHE-EXPIRED COMMENT' })
132
+ like = Like.new({ id: 1, likeable: comment, time: 3.days.ago })
133
+
134
+ generate_cached_serializer(like)
135
+ like.likable = comment2
136
+ like.time = Time.now.to_s
137
+
138
+ render json: like
139
+ end
140
+
141
+ private
142
+ def generate_cached_serializer(obj)
143
+ ActiveModel::SerializableResource.new(obj).to_json
144
+ end
145
+
146
+ def with_adapter(adapter)
147
+ old_adapter = ActiveModel::Serializer.config.adapter
148
+ # JSON-API adapter sets root by default
149
+ ActiveModel::Serializer.config.adapter = adapter
150
+ yield
151
+ ensure
152
+ ActiveModel::Serializer.config.adapter = old_adapter
153
+ end
154
+ end
155
+
156
+ tests ImplicitSerializationTestController
157
+
158
+ # We just have Null for now, this will change
159
+ def test_render_using_implicit_serializer
160
+ get :render_using_implicit_serializer
161
+
162
+ expected = {
163
+ name: "Name 1",
164
+ description: "Description 1"
165
+ }
166
+
167
+ assert_equal 'application/json', @response.content_type
168
+ assert_equal expected.to_json, @response.body
169
+ end
170
+
171
+ def test_render_using_default_root
172
+ get :render_using_default_adapter_root
173
+
174
+ expected = {
175
+ data: {
176
+ id: assigns(:profile).id.to_s,
177
+ type: "profiles",
178
+ attributes: {
179
+ name: "Name 1",
180
+ description: "Description 1"
181
+ }
182
+ }
183
+ }
184
+
185
+ assert_equal 'application/json', @response.content_type
186
+ assert_equal expected.to_json, @response.body
187
+ end
188
+
189
+ def test_render_array_using_custom_root
190
+ get :render_array_using_custom_root
191
+
192
+ expected = {custom_roots: [{name: "Name 1", description: "Description 1"}]}
193
+ assert_equal 'application/json', @response.content_type
194
+ assert_equal expected.to_json, @response.body
195
+ end
196
+
197
+ def test_render_array_that_is_empty_using_custom_root
198
+ get :render_array_that_is_empty_using_custom_root
199
+
200
+ expected = {custom_roots: []}
201
+ assert_equal 'application/json', @response.content_type
202
+ assert_equal expected.to_json, @response.body
203
+ end
204
+
205
+ def test_render_object_using_custom_root
206
+ get :render_object_using_custom_root
207
+
208
+ expected = {custom_root: {name: "Name 1", description: "Description 1"}}
209
+ assert_equal 'application/json', @response.content_type
210
+ assert_equal expected.to_json, @response.body
211
+ end
212
+
213
+ def test_render_json_object_without_serializer
214
+ get :render_json_object_without_serializer
215
+
216
+ assert_equal 'application/json', @response.content_type
217
+ expected_body = {error: 'Result is Invalid'}
218
+ assert_equal expected_body.to_json, @response.body
219
+ end
220
+
221
+ def test_render_json_array_object_without_serializer
222
+ get :render_json_array_object_without_serializer
223
+
224
+ assert_equal 'application/json', @response.content_type
225
+ expected_body = [{error: 'Result is Invalid'}]
226
+ assert_equal expected_body.to_json, @response.body
227
+ end
228
+
229
+ def test_render_array_using_implicit_serializer
230
+ get :render_array_using_implicit_serializer
231
+ assert_equal 'application/json', @response.content_type
232
+
233
+ expected = [
234
+ {
235
+ name: 'Name 1',
236
+ description: 'Description 1',
237
+ },
238
+ {
239
+ name: 'Name 2',
240
+ description: 'Description 2',
241
+ }
242
+ ]
243
+
244
+ assert_equal expected.to_json, @response.body
245
+ end
246
+
247
+ def test_render_array_using_implicit_serializer_and_meta
248
+ get :render_array_using_implicit_serializer_and_meta
249
+
250
+ expected = {
251
+ data: [
252
+ {
253
+ id: assigns(:profiles).first.id.to_s,
254
+ type: "profiles",
255
+ attributes: {
256
+ name: "Name 1",
257
+ description: "Description 1"
258
+ }
259
+ }
260
+ ],
261
+ meta: {
262
+ total: 10
263
+ }
264
+ }
265
+
266
+ assert_equal 'application/json', @response.content_type
267
+ assert_equal expected.to_json, @response.body
268
+ end
269
+
270
+ def test_render_with_cache_enable
271
+ expected = {
272
+ id: 1,
273
+ title: 'New Post',
274
+ body: 'Body',
275
+ comments: [
276
+ {
277
+ id: 1,
278
+ body: 'ZOMG A COMMENT' }
279
+ ],
280
+ blog: {
281
+ id: 999,
282
+ name: 'Custom blog'
283
+ },
284
+ author: {
285
+ id: 1,
286
+ name: 'Joao Moura.'
287
+ }
288
+ }
289
+
290
+ ActionController::Base.cache_store.clear
291
+ Timecop.freeze(Time.now) do
292
+ get :render_object_with_cache_enabled
293
+
294
+ assert_equal 'application/json', @response.content_type
295
+ assert_equal expected.to_json, @response.body
296
+
297
+ get :render_changed_object_with_cache_enabled
298
+ assert_equal expected.to_json, @response.body
299
+ end
300
+
301
+ ActionController::Base.cache_store.clear
302
+ get :render_changed_object_with_cache_enabled
303
+ assert_not_equal expected.to_json, @response.body
304
+ end
305
+
306
+ def test_render_with_cache_enable_and_expired
307
+ ActionController::Base.cache_store.clear
308
+ get :render_object_expired_with_cache_enabled
309
+
310
+ expected = {
311
+ id: 1,
312
+ title: 'ZOMG a New Post',
313
+ body: 'Body',
314
+ comments: [
315
+ {
316
+ id: 1,
317
+ body: 'ZOMG A COMMENT' }
318
+ ],
319
+ blog: {
320
+ id: 999,
321
+ name: 'Custom blog'
322
+ },
323
+ author: {
324
+ id: 1,
325
+ name: 'Joao Moura.'
326
+ }
327
+ }
328
+
329
+ assert_equal 'application/json', @response.content_type
330
+ assert_equal expected.to_json, @response.body
331
+ end
332
+
333
+ def test_render_with_fragment_only_cache_enable
334
+ ActionController::Base.cache_store.clear
335
+ get :render_fragment_changed_object_with_only_cache_enabled
336
+ response = JSON.parse(@response.body)
337
+
338
+ assert_equal 'application/json', @response.content_type
339
+ assert_equal 'ZOMG A ROLE', response["name"]
340
+ assert_equal 'HUEHUEBRBR', response["description"]
341
+ end
342
+
343
+ def test_render_with_fragment_except_cache_enable
344
+ ActionController::Base.cache_store.clear
345
+ get :render_fragment_changed_object_with_except_cache_enabled
346
+ response = JSON.parse(@response.body)
347
+
348
+ assert_equal 'application/json', @response.content_type
349
+ assert_equal 5, response["rating"]
350
+ assert_equal 'lol', response["content"]
351
+ end
352
+
353
+ def test_render_fragment_changed_object_with_relationship
354
+ ActionController::Base.cache_store.clear
355
+
356
+ Timecop.freeze(Time.now) do
357
+ get :render_fragment_changed_object_with_relationship
358
+ response = JSON.parse(@response.body)
359
+
360
+ expected_return = {
361
+ "id"=>1,
362
+ "time"=>Time.now.to_s,
363
+ "likeable" => {
364
+ "id"=>1,
365
+ "body"=>"ZOMG A COMMENT"
366
+ }
367
+ }
368
+
369
+ assert_equal 'application/json', @response.content_type
370
+ assert_equal expected_return, response
371
+ end
372
+ end
373
+
374
+ def test_cache_expiration_on_update
375
+ ActionController::Base.cache_store.clear
376
+ get :render_object_with_cache_enabled
377
+
378
+ expected = {
379
+ id: 1,
380
+ title: 'ZOMG a New Post',
381
+ body: 'Body',
382
+ comments: [
383
+ {
384
+ id: 1,
385
+ body: 'ZOMG A COMMENT' }
386
+ ],
387
+ blog: {
388
+ id:999,
389
+ name: "Custom blog"
390
+ },
391
+ author: {
392
+ id: 1,
393
+ name: 'Joao Moura.'
394
+ }
395
+ }
396
+
397
+ get :update_and_render_object_with_cache_enabled
398
+
399
+ assert_equal 'application/json', @response.content_type
400
+ assert_equal expected.to_json, @response.body
401
+ end
402
+
403
+ def test_warn_overridding_use_adapter_as_falsy_on_controller_instance
404
+ controller = Class.new(ImplicitSerializationTestController) {
405
+ def use_adapter?
406
+ false
407
+ end
408
+ }.new
409
+ assert_match(/adapter: false/, (capture(:stderr) {
410
+ controller.get_serializer(Profile.new)
411
+ }))
412
+ end
413
+
414
+ def test_dont_warn_overridding_use_adapter_as_truthy_on_controller_instance
415
+ controller = Class.new(ImplicitSerializationTestController) {
416
+ def use_adapter?
417
+ true
418
+ end
419
+ }.new
420
+ assert_equal "", (capture(:stderr) {
421
+ controller.get_serializer(Profile.new)
422
+ })
423
+ end
424
+ end
425
+ end
426
+ end
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+ module ActiveModel
3
+ class Serializer
4
+ class Adapter
5
+ class FragmentCacheTest < Minitest::Test
6
+ def setup
7
+ @spam = Spam::UnrelatedLink.new(id: "spam-id-1")
8
+ @author = Author.new(name: 'Joao M. D. Moura')
9
+ @role = Role.new(name: 'Great Author', description:nil)
10
+ @role.author = [@author]
11
+ @role_serializer = RoleSerializer.new(@role)
12
+ @spam_serializer = Spam::UnrelatedLinkSerializer.new(@spam)
13
+ @role_hash = FragmentCache.new(RoleSerializer.adapter.new(@role_serializer), @role_serializer, {})
14
+ @spam_hash = FragmentCache.new(Spam::UnrelatedLinkSerializer.adapter.new(@spam_serializer), @spam_serializer, {})
15
+ end
16
+
17
+ def test_fragment_fetch_with_virtual_attributes
18
+ expected_result = {
19
+ id: @role.id,
20
+ description: @role.description,
21
+ slug: "#{@role.name}-#{@role.id}",
22
+ name: @role.name
23
+ }
24
+ assert_equal(@role_hash.fetch, expected_result)
25
+ end
26
+
27
+ def test_fragment_fetch_with_namespaced_object
28
+ expected_result = {
29
+ id: @spam.id
30
+ }
31
+ assert_equal(@spam_hash.fetch, expected_result)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class Adapter
6
+ class Json
7
+ class BelongsToTest < Minitest::Test
8
+ def setup
9
+ @post = Post.new(id: 42, title: 'New Post', body: 'Body')
10
+ @anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
11
+ @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
12
+ @post.comments = [@comment]
13
+ @anonymous_post.comments = []
14
+ @comment.post = @post
15
+ @comment.author = nil
16
+ @anonymous_post.author = nil
17
+ @blog = Blog.new(id: 1, name: "My Blog!!")
18
+ @post.blog = @blog
19
+ @anonymous_post.blog = nil
20
+
21
+ @serializer = CommentSerializer.new(@comment)
22
+ @adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
23
+ ActionController::Base.cache_store.clear
24
+ end
25
+
26
+ def test_includes_post
27
+ assert_equal({id: 42, title: 'New Post', body: 'Body'}, @adapter.serializable_hash[:comment][:post])
28
+ end
29
+
30
+ def test_include_nil_author
31
+ serializer = PostSerializer.new(@anonymous_post)
32
+ adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
33
+
34
+ assert_equal({post: {title: "Hello!!", body: "Hello, world!!", id: 43, comments: [], blog: {id: 999, name: "Custom blog"}, author: nil}}, adapter.serializable_hash)
35
+ end
36
+
37
+ def test_include_nil_author_with_specified_serializer
38
+ serializer = PostPreviewSerializer.new(@anonymous_post)
39
+ adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
40
+
41
+ assert_equal({post: {title: "Hello!!", body: "Hello, world!!", id: 43, comments: [], author: nil}}, adapter.serializable_hash)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,82 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class Adapter
6
+ class Json
7
+ class Collection < Minitest::Test
8
+ def setup
9
+ @author = Author.new(id: 1, name: 'Steve K.')
10
+ @first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
11
+ @second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
12
+ @first_post.comments = []
13
+ @second_post.comments = []
14
+ @first_post.author = @author
15
+ @second_post.author = @author
16
+ @blog = Blog.new(id: 1, name: "My Blog!!")
17
+ @first_post.blog = @blog
18
+ @second_post.blog = nil
19
+
20
+ ActionController::Base.cache_store.clear
21
+ end
22
+
23
+ def test_with_serializer_option
24
+ @blog.special_attribute = "Special"
25
+ @blog.articles = [@first_post, @second_post]
26
+ serializer = ArraySerializer.new([@blog], serializer: CustomBlogSerializer)
27
+ adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
28
+
29
+ expected = {blogs:[{
30
+ id: 1,
31
+ special_attribute: "Special",
32
+ articles: [{id: 1,title: "Hello!!", body: "Hello, world!!"}, {id: 2, title: "New Post", body: "Body"}]
33
+ }]}
34
+ assert_equal expected, adapter.serializable_hash
35
+ end
36
+
37
+ def test_include_multiple_posts
38
+ serializer = ArraySerializer.new([@first_post, @second_post])
39
+ adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
40
+
41
+ expected = { posts: [{
42
+ title: "Hello!!",
43
+ body: "Hello, world!!",
44
+ id: 1,
45
+ comments: [],
46
+ author: {
47
+ id: 1,
48
+ name: "Steve K."
49
+ },
50
+ blog: {
51
+ id: 999,
52
+ name: "Custom blog"
53
+ }
54
+ }, {
55
+ title: "New Post",
56
+ body: "Body",
57
+ id: 2,
58
+ comments: [],
59
+ author: {
60
+ id: 1,
61
+ name: "Steve K."
62
+ },
63
+ blog: {
64
+ id: 999,
65
+ name: "Custom blog"
66
+ }
67
+ }]}
68
+ assert_equal expected, adapter.serializable_hash
69
+ end
70
+
71
+ def test_root_is_underscored
72
+ virtual_value = VirtualValue.new(id: 1)
73
+ serializer = ArraySerializer.new([virtual_value])
74
+ adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
75
+
76
+ assert_equal 1, adapter.serializable_hash[:virtual_values].length
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class Adapter
6
+ class Json
7
+ class HasManyTestTest < Minitest::Test
8
+ def setup
9
+ ActionController::Base.cache_store.clear
10
+ @author = Author.new(id: 1, name: 'Steve K.')
11
+ @post = Post.new(id: 42, title: 'New Post', body: 'Body')
12
+ @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
13
+ @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
14
+ @post.comments = [@first_comment, @second_comment]
15
+ @post.author = @author
16
+ @first_comment.post = @post
17
+ @second_comment.post = @post
18
+ @blog = Blog.new(id: 1, name: "My Blog!!")
19
+ @post.blog = @blog
20
+ @tag = Tag.new(id: 1, name: "#hash_tag")
21
+ @post.tags = [@tag]
22
+ end
23
+
24
+ def test_has_many
25
+ serializer = PostSerializer.new(@post)
26
+ adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
27
+ assert_equal([
28
+ {id: 1, body: 'ZOMG A COMMENT'},
29
+ {id: 2, body: 'ZOMG ANOTHER COMMENT'}
30
+ ], adapter.serializable_hash[:post][:comments])
31
+ end
32
+
33
+ def test_has_many_with_no_serializer
34
+ serializer = PostWithTagsSerializer.new(@post)
35
+ adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
36
+ assert_equal({
37
+ id: 42,
38
+ tags: [
39
+ {"attributes"=>{"id"=>1, "name"=>"#hash_tag"}}
40
+ ]
41
+ }.to_json, adapter.serializable_hash[:post].to_json)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end