active_model_serializers_pg 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,579 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'ArraySerializer' do
4
+ # TODO: Run the tests with both adapters
5
+ let(:adapter) { :json_api_pg }
6
+ let(:options) { }
7
+ let(:full_options) { (options || {}).merge(adapter: adapter) }
8
+ let(:serializer) { controller.get_serializer(relation, full_options) }
9
+ # Take the string and cycle it through Ruby to remove whitespace inconsistencies:
10
+ let(:json_data) { JSON.parse(serializer.to_json).to_json }
11
+
12
+ context 'specify serializer' do
13
+ let(:relation) { Note.all }
14
+ let(:controller) { NotesController.new }
15
+ let(:options) { { each_serializer: OtherNoteSerializer } }
16
+
17
+ before do
18
+ @note = Note.create content: 'Test', name: 'Title'
19
+ @tag = Tag.create name: 'My tag', note: @note
20
+ end
21
+
22
+ it 'generates the proper json output' do
23
+ json_expected = {
24
+ data: [
25
+ {
26
+ id: @note.id.to_s,
27
+ type: 'notes',
28
+ attributes: {id: @note.id, name: 'Title'},
29
+ relationships: {tags: {data: [{id: @tag.id.to_s, type: 'tags'}]}},
30
+ }
31
+ ]
32
+ }.to_json
33
+ expect(json_data).to eq json_expected
34
+ end
35
+ end
36
+
37
+ # embed_key is no longer supported; I'm not sure about custom key:
38
+ =begin
39
+ context 'custom key and embed_key' do
40
+ let(:relation) { Note.all }
41
+ let(:controller) { NotesController.new }
42
+ let(:options) { { serializer: CustomKeysNoteSerializer } }
43
+
44
+ before do
45
+ @note = Note.create content: 'Test', name: 'Title'
46
+ @tag = Tag.create name: 'My tag', note: @note
47
+ end
48
+
49
+ it 'generates the proper json output' do
50
+ json_expected = %{{"notes":[{"id":#{@note.id},"name":"Title","tag_names":["#{@tag.name}"]}],"tags":[{"id":#{@tag.id},"name":"My tag","tagged_note_id":#{@note.id}}]}}
51
+ json_data.must_equal json_expected
52
+ end
53
+ end
54
+ =end
55
+
56
+ context 'computed value methods' do
57
+ let(:relation) { Person.all }
58
+ let(:controller) { PeopleController.new }
59
+ let(:person) { Person.create first_name: 'Test', last_name: 'User' }
60
+ let(:options) { }
61
+
62
+ it 'generates the proper json output for the serializer' do
63
+ json_expected = {
64
+ data: [
65
+ {
66
+ id: person.id.to_s,
67
+ type: 'people',
68
+ attributes: { id: person.id, full_name: 'Test User', attendance_name: 'User, Test' },
69
+ }
70
+ ]
71
+ }.to_json
72
+ expect(json_data).to eq json_expected
73
+ end
74
+
75
+ it 'passes scope to the serializer method' do
76
+ controller.stubs(:current_user).returns({ admin: true })
77
+
78
+ json_expected = {
79
+ data: [
80
+ {
81
+ id: person.id.to_s,
82
+ type: 'people',
83
+ attributes: {id: person.id, full_name: 'Test User', attendance_name: 'ADMIN User, Test'}
84
+ }
85
+ ]
86
+ }.to_json
87
+ expect(json_data).to eq json_expected
88
+ end
89
+ end
90
+
91
+ context 'merging bind values' do
92
+ let(:relation) { Note.joins(:popular_tags).where(name: 'Title') }
93
+ let(:controller) { NotesController.new }
94
+ let(:options) { }
95
+
96
+ before do
97
+ @note = Note.create content: 'Test', name: 'Title'
98
+ @tag = Tag.create name: 'My tag', note: @note, popular: true
99
+ end
100
+
101
+ it 'generates the proper json output' do
102
+ json_expected = {
103
+ data: [
104
+ {
105
+ id: @note.id.to_s,
106
+ type: 'notes',
107
+ attributes: { name: 'Title', content: 'Test' },
108
+ relationships: { tags: { data: [{id: @tag.id.to_s, type: 'tags'}] } }
109
+ }
110
+ ]
111
+ }.to_json
112
+ expect(json_data).to eq json_expected
113
+ end
114
+ end
115
+
116
+ context 'serialize singular record' do
117
+ let(:relation) { Note.where(name: 'Title').first }
118
+ let(:controller) { NotesController.new }
119
+ let(:options) { }
120
+
121
+ before do
122
+ @note = Note.create content: 'Test', name: 'Title'
123
+ @tag = Tag.create name: 'My tag', note: @note, popular: true
124
+ end
125
+
126
+ it 'generates the proper json output' do
127
+ json_expected = {
128
+ data: {
129
+ id: @note.id.to_s,
130
+ type: 'notes',
131
+ attributes: { name: 'Title', content: 'Test' },
132
+ relationships: { tags: { data: [{id: @tag.id.to_s, type: 'tags'}] } }
133
+ }
134
+ }.to_json
135
+ expect(json_data).to eq json_expected
136
+ end
137
+ end
138
+
139
+ context 'serialize single record with custom serializer' do
140
+ let(:relation) { Note.where(name: 'Title').first }
141
+ let(:controller) { NotesController.new }
142
+ let(:options) { { serializer: OtherNoteSerializer } }
143
+
144
+ before do
145
+ @note = Note.create content: 'Test', name: 'Title'
146
+ @tag = Tag.create name: 'My tag', note: @note
147
+ end
148
+
149
+ it 'generates the proper json output' do
150
+ json_expected = {
151
+ data: {
152
+ id: @note.id.to_s,
153
+ type: 'notes',
154
+ attributes: { id: @note.id, name: 'Title' },
155
+ relationships: { tags: { data: [{id: @tag.id.to_s, type: 'tags'}] } }
156
+ }
157
+ }.to_json
158
+ expect(json_data).to eq json_expected
159
+ end
160
+ end
161
+
162
+ context 'forcing single record mode' do
163
+ let(:relation) { Note.where(name: 'Title').limit(1) }
164
+ let(:controller) { NotesController.new }
165
+ let(:options) { { single_record: true } }
166
+
167
+ before do
168
+ @note = Note.create content: 'Test', name: 'Title'
169
+ @tag = Tag.create name: 'My tag', note: @note, popular: true
170
+ end
171
+
172
+ it 'generates the proper json output' do
173
+ pending 'is the single_record option part of AMS or just the postgres_ext-serializers gem?'
174
+ json_expected = {
175
+ data: {
176
+ id: @note.id.to_s,
177
+ type: 'notes',
178
+ attributes: { name: 'Title', content: 'Test' },
179
+ relationships: { tags: { data: [{id: @tag.id.to_s, type: 'tags'}] } }
180
+ }
181
+ }.to_json
182
+ expect(json_data).to eq json_expected
183
+ end
184
+ end
185
+
186
+ context 'forcing single record mode with custom root key' do
187
+ let(:relation) { Note.where(name: 'Title').limit(1) }
188
+ let(:controller) { NotesController.new }
189
+ let(:options) { { single_record: true, root: :foo } }
190
+
191
+ before do
192
+ @note = Note.create content: 'Test', name: 'Title'
193
+ @tag = Tag.create name: 'My tag', note: @note, popular: true
194
+ end
195
+
196
+ it 'generates the proper json output' do
197
+ json_expected = {
198
+ data: [
199
+ {
200
+ id: @note.id.to_s,
201
+ type: 'notes',
202
+ attributes: { name: 'Title', content: 'Test' },
203
+ relationships: { tags: { data: [{id: @tag.id.to_s, type: 'tags'}] } }
204
+ }
205
+ ]
206
+ }.to_json
207
+ expect(json_data).to eq json_expected
208
+ end
209
+ end
210
+
211
+ context 'no where clause on root relation' do
212
+ let(:relation) { Note.all }
213
+ let(:controller) { NotesController.new }
214
+
215
+ before do
216
+ note_1 = Note.create name: 'test', content: 'dummy content'
217
+ note_2 = Note.create name: 'test 2', content: 'dummy content'
218
+
219
+ tag = Tag.create name: 'tag 1', note_id: note_1.id
220
+ Tag.create name: 'tag 2'
221
+ @json_expected = {
222
+ data: [
223
+ {
224
+ id: note_1.id.to_s,
225
+ type: 'notes',
226
+ attributes: { name: 'test', content: 'dummy content' },
227
+ relationships: { tags: { data: [{id: tag.id.to_s, type: 'tags'}] } },
228
+ },
229
+ {
230
+ id: note_2.id.to_s,
231
+ type: 'notes',
232
+ attributes: { name: 'test 2', content: 'dummy content' },
233
+ relationships: { tags: { data: [] } }
234
+ },
235
+ ]
236
+ }.to_json
237
+ end
238
+
239
+ it 'generates the proper json output for the serializer' do
240
+ expect(json_data).to eq @json_expected
241
+ end
242
+
243
+ it 'does not instantiate ruby objects for relations' do
244
+ expect(relation).not_to receive(:to_a)
245
+ json_data
246
+ end
247
+ end
248
+
249
+ context 'where clause on root relation' do
250
+ let(:relation) { Note.where(name: 'test') }
251
+ let(:controller) { NotesController.new }
252
+
253
+ before do
254
+ note_1 = Note.create name: 'test', content: 'dummy content'
255
+ note_2 = Note.create name: 'test 2', content: 'dummy content'
256
+
257
+ tag = Tag.create name: 'tag 1', note_id: note_1.id
258
+ Tag.create name: 'tag 2', note_id: note_2.id
259
+ @json_expected = {
260
+ data: [
261
+ {
262
+ id: note_1.id.to_s,
263
+ type: 'notes',
264
+ attributes: { name: 'test', content: 'dummy content' },
265
+ relationships: { tags: { data: [{id: tag.id.to_s, type: 'tags'}] } },
266
+ }
267
+ ]
268
+ }.to_json
269
+ end
270
+
271
+ it 'generates the proper json output for the serializer' do
272
+ expect(json_data).to eq @json_expected
273
+ end
274
+
275
+ it 'does not instantiate ruby objects for relations' do
276
+ expect(relation).not_to receive(:to_a)
277
+ json_data
278
+ end
279
+ end
280
+
281
+ context 'root relation has belongs_to association' do
282
+ let(:relation) { Tag.all }
283
+ let(:controller) { TagsController.new }
284
+ let(:options) { { each_serializer: TagWithNoteSerializer, include: ['note'] } }
285
+
286
+ before do
287
+ note = Note.create content: 'Test', name: 'Title'
288
+ tag = Tag.create name: 'My tag', note: note
289
+ @json_expected = {
290
+ data: [
291
+ {
292
+ id: tag.id.to_s,
293
+ type: 'tags',
294
+ attributes: { id: tag.id, name: 'My tag' },
295
+ relationships: { note: { data: { id: note.id.to_s, type: 'notes' } } },
296
+ }
297
+ ],
298
+ included: [
299
+ {
300
+ id: note.id.to_s,
301
+ type: 'notes',
302
+ attributes: { name: 'Title', content: 'Test' },
303
+ relationships: { tags: { data: [{id: tag.id.to_s, type: 'tags' }] } }
304
+ }
305
+ ]
306
+ }.to_json
307
+ end
308
+
309
+ it 'generates the proper json output for the serializer' do
310
+ puts json_data
311
+ expect(json_data).to eq @json_expected
312
+ end
313
+
314
+ it 'does not instantiate ruby objects for relations' do
315
+ expect(relation).not_to receive(:to_a)
316
+ json_data
317
+ end
318
+ end
319
+
320
+ context 'relation has multiple associates to the same table' do
321
+ let(:relation) { User.order(:id) }
322
+ let(:controller) { UsersController.new }
323
+
324
+ before do
325
+ reviewer = User.create name: 'Peter'
326
+ user = User.create name: 'John'
327
+ offer = Offer.create created_by: user, reviewed_by: reviewer
328
+ @json_expected = {
329
+ data: [
330
+ {
331
+ id: reviewer.id.to_s,
332
+ type: 'users',
333
+ attributes: { id: reviewer.id, name: 'Peter' },
334
+ relationships: {
335
+ offers: { data: [] },
336
+ reviewed_offers: { data: [{id: offer.id.to_s, type: 'offers'}] },
337
+ },
338
+ },
339
+ {
340
+ id: user.id.to_s,
341
+ type: 'users',
342
+ attributes: { id: user.id, name: 'John' },
343
+ relationships: {
344
+ offers: { data: [{id: offer.id.to_s, type: 'offers'}] },
345
+ reviewed_offers: { data: [] },
346
+ },
347
+ }
348
+ ]
349
+ }.to_json
350
+ end
351
+
352
+ it 'generates the proper json output for the serializer' do
353
+ expect(json_data).to eq @json_expected
354
+ end
355
+
356
+ it 'does not instantiate ruby objects for relations' do
357
+ expect(relation).not_to receive(:to_a)
358
+ json_data
359
+ end
360
+ end
361
+
362
+ context 'empty data should return empty array not null' do
363
+ let(:relation) { Tag.all }
364
+ let(:controller) { TagsController.new }
365
+ let(:options) { { each_serializer: TagWithNoteSerializer } }
366
+
367
+ before do
368
+ @json_expected = {data: []}.to_json
369
+ end
370
+
371
+ it 'generates the proper json output for the serializer' do
372
+ expect(json_data).to eq @json_expected
373
+ end
374
+
375
+ it 'does not instantiate ruby objects for relations' do
376
+ expect(relation).not_to receive(:to_a)
377
+ json_data
378
+ end
379
+ end
380
+
381
+ context 'nested filtering support' do
382
+ let(:relation) { TagWithNote.where(notes: { name: 'Title' }) }
383
+ let(:controller) { TagsController.new }
384
+
385
+ before do
386
+ note = Note.create content: 'Test', name: 'Title'
387
+ tag = Tag.create name: 'My tag', note: note
388
+ @json_expected = {
389
+ data: [
390
+ {
391
+ id: tag.id.to_s,
392
+ type: 'tag_with_notes',
393
+ attributes: { id: tag.id, name: 'My tag' },
394
+ relationships: { note: { data: { id: note.id.to_s, type: 'notes' } } },
395
+ }
396
+ ]
397
+ }.to_json
398
+ end
399
+
400
+ it 'generates the proper json output for the serializer' do
401
+ expect(json_data).to eq @json_expected
402
+ end
403
+
404
+ it 'does not instantiate ruby objects for relations' do
405
+ expect(relation).not_to receive(:to_a)
406
+ json_data
407
+ end
408
+ end
409
+
410
+ context 'support for include_[attrbute]' do
411
+ let(:relation) { User.all }
412
+ let(:controller) { UsersController.new }
413
+ let(:options) { { each_serializer: UserSerializer } }
414
+ before { @user = User.create name: 'John', mobile: "51111111" }
415
+
416
+ it 'generates json for serializer when include_[attribute]? is true' do
417
+ address = Address.create district_name: "mumbai", user_id: @user.id
418
+ json_expected = {
419
+ data: [
420
+ {
421
+ id: @user.id.to_s,
422
+ type: 'users',
423
+ attributes: {id: @user.id, name: 'John', mobile: '51111111'},
424
+ relationships: {
425
+ offers: {data: []},
426
+ address: {data: {id: address.id.to_s, type: 'addresses'}},
427
+ reviewed_offers: {data: []},
428
+ }
429
+ }
430
+ ]
431
+ }.to_json
432
+
433
+ controller.stubs(:current_user).returns({ permission_id: 1 })
434
+ expect(json_data).to eq json_expected
435
+ end
436
+
437
+ it 'generates json for serializer when include_[attribute]? is false' do
438
+ json_expected = {
439
+ data: [
440
+ {
441
+ id: @user.id.to_s,
442
+ type: 'users',
443
+ attributes: {id: @user.id, name: 'John'},
444
+ relationships: {
445
+ offers: {data: []},
446
+ reviewed_offers: {data: []},
447
+ }
448
+ }
449
+ ]
450
+ }.to_json
451
+ expect(json_data).to eq json_expected
452
+ end
453
+ end
454
+
455
+ context 'respects order in default scope of has_many association' do
456
+ let(:relation) { Note.all }
457
+ let(:controller) { NotesController.new }
458
+ let(:options) { { each_serializer: SortedTagsNoteSerializer } }
459
+
460
+ before do
461
+ note = Note.create name: 'test', content: 'dummy content'
462
+
463
+ tag2 = Tag.create name: 'tag 2', note_id: note.id
464
+ tag1 = Tag.create name: 'tag 1', note_id: note.id
465
+ tag3 = Tag.create name: 'tag 3', note_id: note.id
466
+ @json_expected = {
467
+ data: [
468
+ {
469
+ id: note.id.to_s,
470
+ type: 'notes',
471
+ attributes: {id: note.id},
472
+ relationships: {
473
+ sorted_tags: {
474
+ data: [
475
+ {id: tag1.id.to_s, type: 'sorted_tags'},
476
+ {id: tag2.id.to_s, type: 'sorted_tags'},
477
+ {id: tag3.id.to_s, type: 'sorted_tags'},
478
+ ]
479
+ }
480
+ }
481
+ }
482
+ ]
483
+ }.to_json
484
+ end
485
+
486
+ it 'generates json output with correctly sorted tag ids and tags' do
487
+ expect(json_data).to eq @json_expected
488
+ end
489
+ end
490
+
491
+ context 'respects order in custom scope of has_many association' do
492
+ let(:relation) { Note.all }
493
+ let(:controller) { NotesController.new }
494
+ let(:options) { { each_serializer: CustomSortedTagsNoteSerializer } }
495
+
496
+ before do
497
+ note = Note.create name: 'test', content: 'dummy content'
498
+
499
+ tag2 = Tag.create name: 'tag 2', note_id: note.id
500
+ tag1 = Tag.create name: 'tag 1', note_id: note.id
501
+ tag3 = Tag.create name: 'tag 3', note_id: note.id
502
+ @json_expected = {
503
+ data: [
504
+ {
505
+ id: note.id.to_s,
506
+ type: 'notes',
507
+ attributes: {id: note.id},
508
+ relationships: {
509
+ custom_sorted_tags: {
510
+ data: [
511
+ {id: tag1.id.to_s, type: 'tags'},
512
+ {id: tag2.id.to_s, type: 'tags'},
513
+ {id: tag3.id.to_s, type: 'tags'},
514
+ ]
515
+ }
516
+ }
517
+ }
518
+ ]
519
+ }.to_json
520
+ end
521
+
522
+ it 'generates json output with correctly sorted tag ids and tags' do
523
+ expect(json_data).to eq @json_expected
524
+ end
525
+ end
526
+
527
+ context 'sideloads correct records with pagination on unordered relation' do
528
+ let(:relation) { Note.limit(1).offset(1) }
529
+ let(:controller) { NotesController.new }
530
+ let(:options) { }
531
+
532
+ before do
533
+ note1 = Note.new name: 'note 1', content: 'dummy content'
534
+ note2 = Note.new name: 'note 2', content: 'dummy content'
535
+ note3 = Note.new name: 'note 3', content: 'dummy content'
536
+ # Randomize physical table order of notes.
537
+ [note1, note2, note3].shuffle.map(&:save)
538
+ # Make predictable result by making sure note1 is the second physical record.
539
+ note1.destroy
540
+ note1 = Note.create id: note1.id, name: 'note 1', content: 'dummy content'
541
+ note3.destroy
542
+ note3 = Note.create id: note3.id, name: 'note 3', content: 'dummy content'
543
+
544
+ tag1 = Tag.new name: 'tag 1', note_id: note1.id
545
+ tag2 = Tag.new name: 'tag 2', note_id: note2.id
546
+ tag3 = Tag.new name: 'tag 3', note_id: note3.id
547
+ [tag1, tag2, tag3].shuffle.map(&:save)
548
+
549
+ @json_expected = {
550
+ data: [
551
+ {
552
+ id: note1.id.to_s,
553
+ type: 'notes',
554
+ attributes: {name: 'note 1', content: 'dummy content'},
555
+ relationships: {tags: {data: [{id: tag1.id.to_s, type: 'tags'}]}},
556
+ }
557
+ ]
558
+ }.to_json
559
+ end
560
+
561
+ it 'generates json output with matching tag ids and tags' do
562
+ expect(json_data).to eq @json_expected
563
+ end
564
+ end
565
+
566
+ pending 'obeys serializer option in has_many relationship' # Does AMS 0.10 still support this?
567
+
568
+ pending 'obeys overall :include option'
569
+
570
+ pending 'obeys :include option in serializer association' # Does AMS 0.10 still support this?
571
+
572
+ pending 'figures out aliased associations'
573
+
574
+ pending 'makes dasherized keys and types'
575
+
576
+ pending 'serializes enums'
577
+
578
+ pending 'uses __sql methods for relationships'
579
+ end