cm-active_model_serializers 0.10.0.rc1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +26 -0
  4. data/CHANGELOG.md +8 -0
  5. data/CONTRIBUTING.md +31 -0
  6. data/Gemfile +17 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +326 -0
  9. data/Rakefile +12 -0
  10. data/cm-active_model_serializers.gemspec +26 -0
  11. data/lib/action_controller/serialization.rb +62 -0
  12. data/lib/active_model/serializer.rb +261 -0
  13. data/lib/active_model/serializer/adapter.rb +87 -0
  14. data/lib/active_model/serializer/adapter/fragment_cache.rb +78 -0
  15. data/lib/active_model/serializer/adapter/json.rb +52 -0
  16. data/lib/active_model/serializer/adapter/json/fragment_cache.rb +15 -0
  17. data/lib/active_model/serializer/adapter/json_api.rb +152 -0
  18. data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +22 -0
  19. data/lib/active_model/serializer/adapter/null.rb +11 -0
  20. data/lib/active_model/serializer/array_serializer.rb +32 -0
  21. data/lib/active_model/serializer/configuration.rb +13 -0
  22. data/lib/active_model/serializer/fieldset.rb +40 -0
  23. data/lib/active_model/serializer/version.rb +5 -0
  24. data/lib/active_model_serializers.rb +18 -0
  25. data/lib/generators/serializer/USAGE +6 -0
  26. data/lib/generators/serializer/serializer_generator.rb +37 -0
  27. data/lib/generators/serializer/templates/serializer.rb +8 -0
  28. data/test/action_controller/adapter_selector_test.rb +51 -0
  29. data/test/action_controller/explicit_serializer_test.rb +110 -0
  30. data/test/action_controller/json_api_linked_test.rb +173 -0
  31. data/test/action_controller/serialization_scope_name_test.rb +63 -0
  32. data/test/action_controller/serialization_test.rb +365 -0
  33. data/test/adapter/fragment_cache_test.rb +27 -0
  34. data/test/adapter/json/belongs_to_test.rb +48 -0
  35. data/test/adapter/json/collection_test.rb +73 -0
  36. data/test/adapter/json/has_many_test.rb +36 -0
  37. data/test/adapter/json_api/belongs_to_test.rb +147 -0
  38. data/test/adapter/json_api/collection_test.rb +89 -0
  39. data/test/adapter/json_api/has_many_embed_ids_test.rb +45 -0
  40. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
  41. data/test/adapter/json_api/has_many_test.rb +106 -0
  42. data/test/adapter/json_api/has_one_test.rb +59 -0
  43. data/test/adapter/json_api/linked_test.rb +257 -0
  44. data/test/adapter/json_test.rb +34 -0
  45. data/test/adapter/null_test.rb +25 -0
  46. data/test/adapter_test.rb +43 -0
  47. data/test/array_serializer_test.rb +43 -0
  48. data/test/fixtures/poro.rb +213 -0
  49. data/test/serializers/adapter_for_test.rb +50 -0
  50. data/test/serializers/associations_test.rb +127 -0
  51. data/test/serializers/attribute_test.rb +38 -0
  52. data/test/serializers/attributes_test.rb +63 -0
  53. data/test/serializers/cache_test.rb +128 -0
  54. data/test/serializers/configuration_test.rb +15 -0
  55. data/test/serializers/fieldset_test.rb +26 -0
  56. data/test/serializers/generators_test.rb +59 -0
  57. data/test/serializers/meta_test.rb +78 -0
  58. data/test/serializers/options_test.rb +21 -0
  59. data/test/serializers/serializer_for_test.rb +65 -0
  60. data/test/serializers/urls_test.rb +26 -0
  61. data/test/test_helper.rb +38 -0
  62. metadata +195 -0
@@ -0,0 +1,365 @@
1
+ require 'test_helper'
2
+
3
+ module ActionController
4
+ module Serialization
5
+ class ImplicitSerializerTest < ActionController::TestCase
6
+ class MyController < ActionController::Base
7
+ def render_using_implicit_serializer
8
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
9
+ render json: @profile
10
+ end
11
+
12
+ def render_using_custom_root
13
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
14
+ render json: @profile, root: "custom_root"
15
+ end
16
+
17
+ def render_using_default_adapter_root
18
+ with_adapter ActiveModel::Serializer::Adapter::JsonApi do
19
+ # JSON-API adapter sets root by default
20
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
21
+ render json: @profile
22
+ end
23
+ end
24
+
25
+ def render_using_custom_root_in_adapter_with_a_default
26
+ # JSON-API adapter sets root by default
27
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
28
+ render json: @profile, root: "profile", adapter: :json_api
29
+ end
30
+
31
+ def render_array_using_implicit_serializer
32
+ array = [
33
+ Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
34
+ Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })
35
+ ]
36
+ render json: array
37
+ end
38
+
39
+ def render_array_using_implicit_serializer_and_meta
40
+ with_adapter ActiveModel::Serializer::Adapter::JsonApi do
41
+
42
+ @profiles = [
43
+ Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
44
+ ]
45
+
46
+ render json: @profiles, meta: { total: 10 }
47
+ end
48
+ end
49
+
50
+ def render_object_with_cache_enabled
51
+ @comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
52
+ @author = Author.new(id: 1, name: 'Joao Moura.')
53
+ @post = Post.new({ id: 1, title: 'New Post', body: 'Body', comments: [@comment], author: @author })
54
+
55
+ generate_cached_serializer(@post)
56
+
57
+ @post.title = 'ZOMG a New Post'
58
+ render json: @post
59
+ end
60
+
61
+ def update_and_render_object_with_cache_enabled
62
+ @post.updated_at = DateTime.now
63
+
64
+ generate_cached_serializer(@post)
65
+ render json: @post
66
+ end
67
+
68
+ def render_object_expired_with_cache_enabled
69
+ comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
70
+ author = Author.new(id: 1, name: 'Joao Moura.')
71
+ post = Post.new({ id: 1, title: 'New Post', body: 'Body', comments: [comment], author: author })
72
+
73
+ generate_cached_serializer(post)
74
+
75
+ post.title = 'ZOMG a New Post'
76
+ sleep 0.1
77
+ render json: post
78
+ end
79
+
80
+ def render_changed_object_with_cache_enabled
81
+ comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
82
+ author = Author.new(id: 1, name: 'Joao Moura.')
83
+ post = Post.new({ id: 1, title: 'ZOMG a New Post', body: 'Body', comments: [comment], author: author })
84
+
85
+ render json: post
86
+ end
87
+
88
+ def render_fragment_changed_object_with_only_cache_enabled
89
+ author = Author.new(id: 1, name: 'Joao Moura.')
90
+ role = Role.new({ id: 42, name: 'ZOMG A ROLE', description: 'DESCRIPTION HERE', author: author })
91
+
92
+ generate_cached_serializer(role)
93
+ role.name = 'lol'
94
+ role.description = 'HUEHUEBRBR'
95
+
96
+ render json: role
97
+ end
98
+
99
+ def render_fragment_changed_object_with_except_cache_enabled
100
+ author = Author.new(id: 1, name: 'Joao Moura.')
101
+ bio = Bio.new({ id: 42, content: 'ZOMG A ROLE', rating: 5, author: author })
102
+
103
+ generate_cached_serializer(bio)
104
+ bio.content = 'lol'
105
+ bio.rating = 0
106
+
107
+ render json: bio
108
+ end
109
+
110
+ def render_fragment_changed_object_with_relationship
111
+ comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
112
+ author = Author.new(id: 1, name: 'Joao Moura.')
113
+ post = Post.new({ id: 1, title: 'New Post', body: 'Body', comments: [comment], author: author })
114
+ post2 = Post.new({ id: 1, title: 'New Post2', body: 'Body2', comments: [comment], author: author })
115
+ like = Like.new({ id: 1, post: post, time: 3.days.ago })
116
+
117
+ generate_cached_serializer(like)
118
+ like.post = post2
119
+ like.time = DateTime.now.to_s
120
+
121
+ render json: like
122
+ end
123
+
124
+ private
125
+ def generate_cached_serializer(obj)
126
+ serializer_class = ActiveModel::Serializer.serializer_for(obj)
127
+ serializer = serializer_class.new(obj)
128
+ adapter = ActiveModel::Serializer.adapter.new(serializer)
129
+ adapter.to_json
130
+ end
131
+
132
+ def with_adapter(adapter)
133
+ old_adapter = ActiveModel::Serializer.config.adapter
134
+ # JSON-API adapter sets root by default
135
+ ActiveModel::Serializer.config.adapter = adapter
136
+ yield
137
+ ensure
138
+ ActiveModel::Serializer.config.adapter = old_adapter
139
+ end
140
+ end
141
+
142
+ tests MyController
143
+
144
+ # We just have Null for now, this will change
145
+ def test_render_using_implicit_serializer
146
+ get :render_using_implicit_serializer
147
+
148
+ expected = {
149
+ name: "Name 1",
150
+ description: "Description 1"
151
+ }
152
+
153
+ assert_equal 'application/json', @response.content_type
154
+ assert_equal expected.to_json, @response.body
155
+ end
156
+
157
+ def test_render_using_custom_root
158
+ get :render_using_custom_root
159
+
160
+ assert_equal 'application/json', @response.content_type
161
+ assert_equal '{"custom_root":{"name":"Name 1","description":"Description 1"}}', @response.body
162
+ end
163
+
164
+ def test_render_using_default_root
165
+ get :render_using_default_adapter_root
166
+
167
+ expected = {
168
+ data: {
169
+ name: "Name 1",
170
+ description: "Description 1",
171
+ id: assigns(:profile).id.to_s,
172
+ type: "profiles"
173
+ }
174
+ }
175
+
176
+ assert_equal 'application/json', @response.content_type
177
+ assert_equal expected.to_json, @response.body
178
+ end
179
+
180
+ def test_render_using_custom_root_in_adapter_with_a_default
181
+ get :render_using_custom_root_in_adapter_with_a_default
182
+
183
+ expected = {
184
+ data: {
185
+ name: "Name 1",
186
+ description: "Description 1",
187
+ id: assigns(:profile).id.to_s,
188
+ type: "profiles"
189
+ }
190
+ }
191
+
192
+ assert_equal 'application/json', @response.content_type
193
+ assert_equal expected.to_json, @response.body
194
+ end
195
+
196
+ def test_render_array_using_implicit_serializer
197
+ get :render_array_using_implicit_serializer
198
+ assert_equal 'application/json', @response.content_type
199
+
200
+ expected = [
201
+ {
202
+ name: 'Name 1',
203
+ description: 'Description 1',
204
+ },
205
+ {
206
+ name: 'Name 2',
207
+ description: 'Description 2',
208
+ }
209
+ ]
210
+
211
+ assert_equal expected.to_json, @response.body
212
+ end
213
+
214
+ def test_render_array_using_implicit_serializer_and_meta
215
+ get :render_array_using_implicit_serializer_and_meta
216
+
217
+ expected = {
218
+ data: [
219
+ {
220
+ name: "Name 1",
221
+ description: "Description 1",
222
+ id: assigns(:profiles).first.id.to_s,
223
+ type: "profiles"
224
+ }
225
+ ],
226
+ meta: {
227
+ total: 10
228
+ }
229
+ }
230
+
231
+ assert_equal 'application/json', @response.content_type
232
+ assert_equal expected.to_json, @response.body
233
+ end
234
+
235
+ def test_render_with_cache_enable
236
+ ActionController::Base.cache_store.clear
237
+ get :render_object_with_cache_enabled
238
+
239
+ expected = {
240
+ id: 1,
241
+ title: 'New Post',
242
+ body: 'Body',
243
+ comments: [
244
+ {
245
+ id: 1,
246
+ body: 'ZOMG A COMMENT' }
247
+ ],
248
+ blog: {
249
+ id: 999,
250
+ name: 'Custom blog'
251
+ },
252
+ author: {
253
+ id: 1,
254
+ name: 'Joao Moura.'
255
+ }
256
+ }
257
+
258
+ assert_equal 'application/json', @response.content_type
259
+ assert_equal expected.to_json, @response.body
260
+
261
+ get :render_changed_object_with_cache_enabled
262
+ assert_equal expected.to_json, @response.body
263
+
264
+ ActionController::Base.cache_store.clear
265
+ get :render_changed_object_with_cache_enabled
266
+ assert_not_equal expected.to_json, @response.body
267
+ end
268
+
269
+ def test_render_with_cache_enable_and_expired
270
+ ActionController::Base.cache_store.clear
271
+ get :render_object_expired_with_cache_enabled
272
+
273
+ expected = {
274
+ id: 1,
275
+ title: 'ZOMG a New Post',
276
+ body: 'Body',
277
+ comments: [
278
+ {
279
+ id: 1,
280
+ body: 'ZOMG A COMMENT' }
281
+ ],
282
+ blog: {
283
+ id: 999,
284
+ name: 'Custom blog'
285
+ },
286
+ author: {
287
+ id: 1,
288
+ name: 'Joao Moura.'
289
+ }
290
+ }
291
+
292
+ assert_equal 'application/json', @response.content_type
293
+ assert_equal expected.to_json, @response.body
294
+ end
295
+
296
+ def test_render_with_fragment_only_cache_enable
297
+ ActionController::Base.cache_store.clear
298
+ get :render_fragment_changed_object_with_only_cache_enabled
299
+ response = JSON.parse(@response.body)
300
+
301
+ assert_equal 'application/json', @response.content_type
302
+ assert_equal 'ZOMG A ROLE', response["name"]
303
+ assert_equal 'HUEHUEBRBR', response["description"]
304
+ end
305
+
306
+ def test_render_with_fragment_except_cache_enable
307
+ ActionController::Base.cache_store.clear
308
+ get :render_fragment_changed_object_with_except_cache_enabled
309
+ response = JSON.parse(@response.body)
310
+
311
+ assert_equal 'application/json', @response.content_type
312
+ assert_equal 5, response["rating"]
313
+ assert_equal 'lol', response["content"]
314
+ end
315
+
316
+ def test_render_fragment_changed_object_with_relationship
317
+ ActionController::Base.cache_store.clear
318
+ get :render_fragment_changed_object_with_relationship
319
+ response = JSON.parse(@response.body)
320
+
321
+ expected_return = {
322
+ "id"=>1,
323
+ "time"=>DateTime.now.to_s,
324
+ "post" => {
325
+ "id"=>1,
326
+ "title"=>"New Post",
327
+ "body"=>"Body"
328
+ }
329
+ }
330
+
331
+ assert_equal 'application/json', @response.content_type
332
+ assert_equal expected_return, response
333
+ end
334
+
335
+ def test_cache_expiration_on_update
336
+ ActionController::Base.cache_store.clear
337
+ get :render_object_with_cache_enabled
338
+
339
+ expected = {
340
+ id: 1,
341
+ title: 'ZOMG a New Post',
342
+ body: 'Body',
343
+ comments: [
344
+ {
345
+ id: 1,
346
+ body: 'ZOMG A COMMENT' }
347
+ ],
348
+ blog: {
349
+ id:999,
350
+ name: "Custom blog"
351
+ },
352
+ author: {
353
+ id: 1,
354
+ name: 'Joao Moura.'
355
+ }
356
+ }
357
+
358
+ get :update_and_render_object_with_cache_enabled
359
+
360
+ assert_equal 'application/json', @response.content_type
361
+ assert_equal expected.to_json, @response.body
362
+ end
363
+ end
364
+ end
365
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+ module ActiveModel
3
+ class Serializer
4
+ class Adapter
5
+ class FragmentCacheTest < Minitest::Test
6
+ def setup
7
+ @author = Author.new(name: 'Joao M. D. Moura')
8
+ @role = Role.new(name: 'Great Author', description:nil)
9
+ @role.author = [@author]
10
+ @role_serializer = RoleSerializer.new(@role)
11
+ @role_hash = FragmentCache.new(RoleSerializer.adapter.new(@role_serializer), @role_serializer, {}, nil)
12
+ end
13
+
14
+ def test_fragment_fetch_with_virtual_attributes
15
+ expected_result = {
16
+ id: @role.id,
17
+ description: @role.description,
18
+ slug: "#{@role.name}-#{@role.id}",
19
+ name: @role.name
20
+ }
21
+ assert_equal(@role_hash.fetch, expected_result)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,48 @@
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
+ @post.author = @author
15
+ @comment.post = @post
16
+ @comment.author = nil
17
+ @anonymous_post.author = nil
18
+ @blog = Blog.new(id: 1, name: "My Blog!!")
19
+ @post.blog = @blog
20
+ @anonymous_post.blog = nil
21
+
22
+ @serializer = CommentSerializer.new(@comment)
23
+ @adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
24
+ ActionController::Base.cache_store.clear
25
+ end
26
+
27
+ def test_includes_post
28
+ assert_equal({id: 42, title: 'New Post', body: 'Body'}, @adapter.serializable_hash[:post])
29
+ end
30
+
31
+ def test_include_nil_author
32
+ serializer = PostSerializer.new(@anonymous_post)
33
+ adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
34
+
35
+ assert_equal({title: "Hello!!", body: "Hello, world!!", id: 43, comments: [], blog: {id: 999, name: "Custom blog"}, author: nil}, adapter.serializable_hash)
36
+ end
37
+
38
+ def test_include_nil_author_with_specified_serializer
39
+ serializer = PostPreviewSerializer.new(@anonymous_post)
40
+ adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
41
+
42
+ assert_equal({title: "Hello!!", body: "Hello, world!!", id: 43, comments: [], author: nil}, adapter.serializable_hash)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,73 @@
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
+ @serializer = ArraySerializer.new([@first_post, @second_post])
21
+ @adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
22
+ ActionController::Base.cache_store.clear
23
+ end
24
+
25
+ def test_with_serializer_option
26
+ @blog.special_attribute = "Special"
27
+ @blog.articles = [@first_post, @second_post]
28
+ @serializer = ArraySerializer.new([@blog], serializer: CustomBlogSerializer)
29
+ @adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
30
+
31
+ expected = [{
32
+ id: 1,
33
+ special_attribute: "Special",
34
+ articles: [{id: 1,title: "Hello!!", body: "Hello, world!!"}, {id: 2, title: "New Post", body: "Body"}]
35
+ }]
36
+ assert_equal expected, @adapter.serializable_hash
37
+ end
38
+
39
+ def test_include_multiple_posts
40
+ expected = [{
41
+ title: "Hello!!",
42
+ body: "Hello, world!!",
43
+ id: 1,
44
+ comments: [],
45
+ author: {
46
+ id: 1,
47
+ name: "Steve K."
48
+ },
49
+ blog: {
50
+ id: 999,
51
+ name: "Custom blog"
52
+ }
53
+ }, {
54
+ title: "New Post",
55
+ body: "Body",
56
+ id: 2,
57
+ comments: [],
58
+ author: {
59
+ id: 1,
60
+ name: "Steve K."
61
+ },
62
+ blog: {
63
+ id: 999,
64
+ name: "Custom blog"
65
+ }
66
+ }]
67
+ assert_equal expected, @adapter.serializable_hash
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end