gpi-active_model_serializers 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,592 @@
1
+ require "test_helper"
2
+
3
+ class AssociationTest < ActiveModel::TestCase
4
+ def def_serializer(&block)
5
+ Class.new(ActiveModel::Serializer, &block)
6
+ end
7
+
8
+ class Model
9
+ def initialize(hash={})
10
+ @attributes = hash
11
+ end
12
+
13
+ def read_attribute_for_serialization(name)
14
+ @attributes[name]
15
+ end
16
+
17
+ def as_json(*)
18
+ { model: "Model" }
19
+ end
20
+
21
+ def method_missing(meth, *args)
22
+ if meth.to_s =~ /^(.*)=$/
23
+ @attributes[$1.to_sym] = args[0]
24
+ elsif @attributes.key?(meth)
25
+ @attributes[meth]
26
+ else
27
+ super
28
+ end
29
+ end
30
+ end
31
+
32
+ def setup
33
+ @hash = {}
34
+ @root_hash = {}
35
+
36
+ @post = Model.new(title: "New Post", body: "Body")
37
+ @comment = Model.new(id: 1, external_id: "COMM001", body: "ZOMG A COMMENT")
38
+ @post.comments = [ @comment ]
39
+ @post.comment = @comment
40
+
41
+ @comment_serializer_class = def_serializer do
42
+ attributes :id, :external_id, :body
43
+ end
44
+
45
+ @post_serializer_class = def_serializer do
46
+ attributes :title, :body
47
+ end
48
+
49
+ @post_serializer = @post_serializer_class.new(@post, hash: @root_hash)
50
+ end
51
+
52
+ def include!(key, options={})
53
+ @post_serializer.include! key, {
54
+ embed: :ids,
55
+ include: true,
56
+ node: @hash,
57
+ serializer: @comment_serializer_class
58
+ }.merge(options)
59
+ end
60
+
61
+ def include_bare!(key, options={})
62
+ @post_serializer.include! key, {
63
+ node: @hash,
64
+ serializer: @comment_serializer_class
65
+ }.merge(options)
66
+ end
67
+
68
+ class NoDefaults < AssociationTest
69
+ def test_include_bang_has_many_associations
70
+ include! :comments, value: @post.comments
71
+
72
+ assert_equal({
73
+ comment_ids: [ 1 ]
74
+ }, @hash)
75
+
76
+ assert_equal({
77
+ comments: [
78
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
79
+ ]
80
+ }, @root_hash)
81
+ end
82
+
83
+ def test_include_bang_with_embed_false
84
+ include! :comments, value: @post.comments, embed: false
85
+
86
+ assert_equal({}, @hash)
87
+ assert_equal({}, @root_hash)
88
+ end
89
+
90
+ def test_include_bang_with_embed_ids_include_false
91
+ include! :comments, value: @post.comments, embed: :ids, include: false
92
+
93
+ assert_equal({
94
+ comment_ids: [ 1 ]
95
+ }, @hash)
96
+
97
+ assert_equal({}, @root_hash)
98
+ end
99
+
100
+ def test_include_bang_has_one_associations
101
+ include! :comment, value: @post.comment
102
+
103
+ assert_equal({
104
+ comment_id: 1
105
+ }, @hash)
106
+
107
+ assert_equal({
108
+ comments: [{ id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }]
109
+ }, @root_hash)
110
+ end
111
+ end
112
+
113
+ class DefaultsTest < AssociationTest
114
+ def test_with_default_has_many
115
+ @post_serializer_class.class_eval do
116
+ has_many :comments
117
+ end
118
+
119
+ include! :comments
120
+
121
+ assert_equal({
122
+ comment_ids: [ 1 ]
123
+ }, @hash)
124
+
125
+ assert_equal({
126
+ comments: [
127
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
128
+ ]
129
+ }, @root_hash)
130
+ end
131
+
132
+ def test_with_default_has_one
133
+ @post_serializer_class.class_eval do
134
+ has_one :comment
135
+ end
136
+
137
+ include! :comment
138
+
139
+ assert_equal({
140
+ comment_id: 1
141
+ }, @hash)
142
+
143
+ assert_equal({
144
+ comments: [
145
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
146
+ ]
147
+ }, @root_hash)
148
+ end
149
+
150
+ def test_with_default_has_many_with_custom_key
151
+ @post_serializer_class.class_eval do
152
+ has_many :comments, key: :custom_comments
153
+ end
154
+
155
+ include! :comments
156
+
157
+ assert_equal({
158
+ custom_comments: [ 1 ]
159
+ }, @hash)
160
+
161
+ assert_equal({
162
+ comments: [
163
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
164
+ ]
165
+ }, @root_hash)
166
+ end
167
+
168
+ def test_with_default_has_one_with_custom_key
169
+ @post_serializer_class.class_eval do
170
+ has_one :comment, key: :custom_comment_id
171
+ end
172
+
173
+ include! :comment
174
+
175
+ assert_equal({
176
+ custom_comment_id: 1
177
+ }, @hash)
178
+
179
+ assert_equal({
180
+ comments: [
181
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
182
+ ]
183
+ }, @root_hash)
184
+ end
185
+
186
+ def test_with_default_has_many_with_custom_embed_key
187
+ @post_serializer_class.class_eval do
188
+ has_many :comments, embed_key: :external_id
189
+ end
190
+
191
+ include! :comments
192
+
193
+ assert_equal({
194
+ comment_ids: [ "COMM001" ]
195
+ }, @hash)
196
+
197
+ assert_equal({
198
+ comments: [
199
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
200
+ ]
201
+ }, @root_hash)
202
+ end
203
+
204
+ def test_with_default_has_one_with_custom_embed_key
205
+ @post_serializer_class.class_eval do
206
+ has_one :comment, embed_key: :external_id
207
+ end
208
+
209
+ include! :comment
210
+
211
+ assert_equal({
212
+ comment_id: "COMM001"
213
+ }, @hash)
214
+
215
+ assert_equal({
216
+ comments: [
217
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
218
+ ]
219
+ }, @root_hash)
220
+ end
221
+
222
+ def test_with_default_has_many_with_custom_key_and_custom_embed_key
223
+ @post_serializer_class.class_eval do
224
+ has_many :comments, key: :custom_comments, embed_key: :external_id
225
+ end
226
+
227
+ include! :comments
228
+
229
+ assert_equal({
230
+ custom_comments: [ "COMM001" ]
231
+ }, @hash)
232
+
233
+ assert_equal({
234
+ comments: [
235
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
236
+ ]
237
+ }, @root_hash)
238
+ end
239
+
240
+ def test_with_default_has_one_with_custom_key_and_custom_embed_key
241
+ @post_serializer_class.class_eval do
242
+ has_one :comment, key: :custom_comment, embed_key: :external_id
243
+ end
244
+
245
+ include! :comment
246
+
247
+ assert_equal({
248
+ custom_comment: "COMM001"
249
+ }, @hash)
250
+
251
+ assert_equal({
252
+ comments: [
253
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
254
+ ]
255
+ }, @root_hash)
256
+ end
257
+
258
+ def test_embed_objects_for_has_many_associations
259
+ @post_serializer_class.class_eval do
260
+ has_many :comments, embed: :objects
261
+ end
262
+
263
+ include_bare! :comments
264
+
265
+ assert_equal({
266
+ comments: [
267
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
268
+ ]
269
+ }, @hash)
270
+
271
+ assert_equal({}, @root_hash)
272
+ end
273
+
274
+ def test_embed_ids_for_has_many_associations
275
+ @post_serializer_class.class_eval do
276
+ has_many :comments, embed: :ids
277
+ end
278
+
279
+ include_bare! :comments
280
+
281
+ assert_equal({
282
+ comment_ids: [ 1 ]
283
+ }, @hash)
284
+
285
+ assert_equal({}, @root_hash)
286
+ end
287
+
288
+ def test_embed_false_for_has_many_associations
289
+ @post_serializer_class.class_eval do
290
+ has_many :comments, embed: false
291
+ end
292
+
293
+ include_bare! :comments
294
+
295
+ assert_equal({}, @hash)
296
+ assert_equal({}, @root_hash)
297
+ end
298
+
299
+ def test_embed_ids_include_true_for_has_many_associations
300
+ @post_serializer_class.class_eval do
301
+ has_many :comments, embed: :ids, include: true
302
+ end
303
+
304
+ include_bare! :comments
305
+
306
+ assert_equal({
307
+ comment_ids: [ 1 ]
308
+ }, @hash)
309
+
310
+ assert_equal({
311
+ comments: [
312
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
313
+ ]
314
+ }, @root_hash)
315
+ end
316
+
317
+ def test_embed_ids_for_has_one_associations
318
+ @post_serializer_class.class_eval do
319
+ has_one :comment, embed: :ids
320
+ end
321
+
322
+ include_bare! :comment
323
+
324
+ assert_equal({
325
+ comment_id: 1
326
+ }, @hash)
327
+
328
+ assert_equal({}, @root_hash)
329
+ end
330
+
331
+ def test_embed_false_for_has_one_associations
332
+ @post_serializer_class.class_eval do
333
+ has_one :comment, embed: false
334
+ end
335
+
336
+ include_bare! :comment
337
+
338
+ assert_equal({}, @hash)
339
+ assert_equal({}, @root_hash)
340
+ end
341
+
342
+ def test_embed_ids_include_true_for_has_one_associations
343
+ @post_serializer_class.class_eval do
344
+ has_one :comment, embed: :ids, include: true
345
+ end
346
+
347
+ include_bare! :comment
348
+
349
+ assert_equal({
350
+ comment_id: 1
351
+ }, @hash)
352
+
353
+ assert_equal({
354
+ comments: [
355
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
356
+ ]
357
+ }, @root_hash)
358
+ end
359
+
360
+ def test_embed_ids_include_true_does_not_serialize_multiple_times
361
+ @post.recent_comment = @comment
362
+
363
+ @post_serializer_class.class_eval do
364
+ has_one :comment, embed: :ids, include: true
365
+ has_one :recent_comment, embed: :ids, include: true, root: :comments
366
+ end
367
+
368
+ # Count how often the @comment record is serialized.
369
+ serialized_times = 0
370
+ @comment.class_eval do
371
+ define_method :read_attribute_for_serialization, lambda { |name|
372
+ serialized_times += 1 if name == :body
373
+ super(name)
374
+ }
375
+ end
376
+
377
+ include_bare! :comment
378
+ include_bare! :recent_comment
379
+
380
+ assert_equal 1, serialized_times
381
+ end
382
+
383
+ def test_include_with_read_association_id_for_serialization_hook
384
+ @post_serializer_class.class_eval do
385
+ has_one :comment, embed: :ids, include: true
386
+ end
387
+
388
+ association_name = nil
389
+ @post.class_eval do
390
+ define_method :read_attribute_for_serialization, lambda { |name|
391
+ association_name = name
392
+ send(name)
393
+ }
394
+ define_method :comment_id, lambda {
395
+ @attributes[:comment].id
396
+ }
397
+ end
398
+
399
+ include_bare! :comment
400
+
401
+ assert_equal({
402
+ comment_id: 1
403
+ }, @hash)
404
+ end
405
+
406
+ def test_include_with_read_association_ids_for_serialization_hook
407
+ @post_serializer_class.class_eval do
408
+ has_many :comments, embed: :ids, include: false
409
+ end
410
+
411
+ association_name = nil
412
+ @post.class_eval do
413
+ define_method :read_attribute_for_serialization, lambda { |name|
414
+ association_name = name
415
+ send(name)
416
+ }
417
+ define_method :comment_ids, lambda {
418
+ @attributes[:comments].map(&:id)
419
+ }
420
+ end
421
+
422
+ include_bare! :comments
423
+
424
+ assert_equal({
425
+ comment_ids: [1]
426
+ }, @hash)
427
+ end
428
+ end
429
+
430
+ class RecursiveTest < AssociationTest
431
+ class BarSerializer < ActiveModel::Serializer; end
432
+
433
+ class FooSerializer < ActiveModel::Serializer
434
+ root :foos
435
+ attributes :id
436
+ has_many :bars, serializer: BarSerializer, root: :bars, embed: :ids, include: true
437
+ end
438
+
439
+ class BarSerializer < ActiveModel::Serializer
440
+ root :bars
441
+ attributes :id
442
+ has_many :foos, serializer: FooSerializer, root: :foos, embed: :ids, include: true
443
+ end
444
+
445
+ class Foo < Model
446
+ def active_model_serializer; FooSerializer; end
447
+ end
448
+
449
+ class Bar < Model
450
+ def active_model_serializer; BarSerializer; end
451
+ end
452
+
453
+ def setup
454
+ super
455
+
456
+ foo = Foo.new(id: 1)
457
+ bar = Bar.new(id: 2)
458
+
459
+ foo.bars = [ bar ]
460
+ bar.foos = [ foo ]
461
+
462
+ collection = [ foo ]
463
+
464
+ @serializer = collection.active_model_serializer.new(collection, root: :foos)
465
+ end
466
+
467
+ def test_mutual_relation_result
468
+ assert_equal({
469
+ foos: [{
470
+ bar_ids: [ 2 ],
471
+ id: 1
472
+ }],
473
+ bars: [{
474
+ foo_ids: [ 1 ],
475
+ id: 2
476
+ }]
477
+ }, @serializer.as_json)
478
+ end
479
+
480
+ def test_mutual_relation_does_not_raise_error
481
+ assert_nothing_raised SystemStackError, 'stack level too deep' do
482
+ @serializer.as_json
483
+ end
484
+ end
485
+ end
486
+
487
+ class InclusionTest < AssociationTest
488
+ def setup
489
+ super
490
+
491
+ comment_serializer_class = @comment_serializer_class
492
+
493
+ @post_serializer_class.class_eval do
494
+ root :post
495
+ embed :ids, include: true
496
+ has_many :comments, serializer: comment_serializer_class
497
+ end
498
+ end
499
+
500
+ def test_when_it_is_included
501
+ post_serializer = @post_serializer_class.new(
502
+ @post, include: [:comments]
503
+ )
504
+
505
+ json = post_serializer.as_json
506
+
507
+ assert_equal({
508
+ post: {
509
+ title: "New Post",
510
+ body: "Body",
511
+ comment_ids: [ 1 ]
512
+ },
513
+ comments: [
514
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
515
+ ]
516
+ }, json)
517
+ end
518
+
519
+ def test_when_it_is_not_included
520
+ post_serializer = @post_serializer_class.new(
521
+ @post, include: []
522
+ )
523
+
524
+ json = post_serializer.as_json
525
+
526
+ assert_equal({
527
+ post: {
528
+ title: "New Post",
529
+ body: "Body",
530
+ comment_ids: [ 1 ]
531
+ }
532
+ }, json)
533
+ end
534
+
535
+ def test_when_it_is_excluded
536
+ post_serializer = @post_serializer_class.new(
537
+ @post, exclude: [:comments]
538
+ )
539
+
540
+ json = post_serializer.as_json
541
+
542
+ assert_equal({
543
+ post: {
544
+ title: "New Post",
545
+ body: "Body",
546
+ comment_ids: [ 1 ]
547
+ }
548
+ }, json)
549
+ end
550
+
551
+ def test_when_it_is_not_excluded
552
+ post_serializer = @post_serializer_class.new(
553
+ @post, exclude: []
554
+ )
555
+
556
+ json = post_serializer.as_json
557
+
558
+ assert_equal({
559
+ post: {
560
+ title: "New Post",
561
+ body: "Body",
562
+ comment_ids: [ 1 ]
563
+ },
564
+ comments: [
565
+ { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
566
+ ]
567
+ }, json)
568
+ end
569
+ end
570
+
571
+ class StringSerializerOption < AssociationTest
572
+ class StringSerializer < ActiveModel::Serializer
573
+ attributes :id, :body
574
+ end
575
+
576
+ def test_specifying_serializer_class_as_string
577
+ @post_serializer_class.class_eval do
578
+ has_many :comments, embed: :objects
579
+ end
580
+
581
+ include_bare! :comments, serializer: "AssociationTest::StringSerializerOption::StringSerializer"
582
+
583
+ assert_equal({
584
+ comments: [
585
+ { id: 1, body: "ZOMG A COMMENT" }
586
+ ]
587
+ }, @hash)
588
+
589
+ assert_equal({}, @root_hash)
590
+ end
591
+ end
592
+ end