jat 0.0.1 → 0.0.3

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +21 -0
  4. data/jat.gemspec +37 -0
  5. data/lib/jat/attribute.rb +85 -0
  6. data/lib/jat/config.rb +38 -0
  7. data/lib/jat/plugins/_activerecord_preloads/_activerecord_preloads.rb +29 -0
  8. data/lib/jat/plugins/_activerecord_preloads/lib/preloader.rb +89 -0
  9. data/lib/jat/plugins/_json_api_activerecord/_json_api_activerecord.rb +22 -0
  10. data/lib/jat/plugins/_json_api_activerecord/lib/preloads.rb +84 -0
  11. data/lib/jat/plugins/_preloads/_preloads.rb +53 -0
  12. data/lib/jat/plugins/_preloads/lib/format_user_preloads.rb +52 -0
  13. data/lib/jat/plugins/_preloads/lib/preloads_with_path.rb +78 -0
  14. data/lib/jat/plugins/cache/cache.rb +39 -0
  15. data/lib/jat/plugins/camel_lower/camel_lower.rb +18 -0
  16. data/lib/jat/plugins/json_api/json_api.rb +207 -0
  17. data/lib/jat/plugins/json_api/lib/construct_traversal_map.rb +91 -0
  18. data/lib/jat/plugins/json_api/lib/map.rb +54 -0
  19. data/lib/jat/plugins/json_api/lib/params/fields/parse.rb +27 -0
  20. data/lib/jat/plugins/json_api/lib/params/fields/validate.rb +55 -0
  21. data/lib/jat/plugins/json_api/lib/params/fields.rb +23 -0
  22. data/lib/jat/plugins/json_api/lib/params/include/parse.rb +55 -0
  23. data/lib/jat/plugins/json_api/lib/params/include/validate.rb +29 -0
  24. data/lib/jat/plugins/json_api/lib/params/include.rb +49 -0
  25. data/lib/jat/plugins/json_api/lib/presenters/document_links_presenter.rb +48 -0
  26. data/lib/jat/plugins/json_api/lib/presenters/document_meta_presenter.rb +48 -0
  27. data/lib/jat/plugins/json_api/lib/presenters/jsonapi_presenter.rb +48 -0
  28. data/lib/jat/plugins/json_api/lib/presenters/links_presenter.rb +48 -0
  29. data/lib/jat/plugins/json_api/lib/presenters/meta_presenter.rb +48 -0
  30. data/lib/jat/plugins/json_api/lib/presenters/relationship_links_presenter.rb +53 -0
  31. data/lib/jat/plugins/json_api/lib/presenters/relationship_meta_presenter.rb +53 -0
  32. data/lib/jat/plugins/json_api/lib/response.rb +239 -0
  33. data/lib/jat/plugins/json_api/lib/traversal_map.rb +34 -0
  34. data/lib/jat/plugins/simple_api/lib/construct_traversal_map.rb +45 -0
  35. data/lib/jat/plugins/simple_api/lib/map.rb +29 -0
  36. data/lib/jat/plugins/simple_api/lib/params/parse.rb +68 -0
  37. data/lib/jat/plugins/simple_api/lib/response.rb +134 -0
  38. data/lib/jat/plugins/simple_api/simple_api.rb +65 -0
  39. data/lib/jat/plugins/to_str/to_str.rb +44 -0
  40. data/lib/jat/plugins.rb +39 -0
  41. data/lib/jat/presenter.rb +51 -0
  42. data/lib/jat/utils/enum_deep_dup.rb +29 -0
  43. data/lib/jat/utils/enum_deep_freeze.rb +19 -0
  44. data/lib/jat.rb +66 -144
  45. data/test/lib/jat/attribute_test.rb +142 -0
  46. data/test/lib/jat/config_test.rb +57 -0
  47. data/test/lib/jat/plugins/_activerecord_preloads/_activerecord_preloads_test.rb +40 -0
  48. data/test/lib/jat/plugins/_activerecord_preloads/lib/preloader_test.rb +98 -0
  49. data/test/lib/jat/plugins/_json_api_activerecord/_json_api_activerecord_test.rb +29 -0
  50. data/test/lib/jat/plugins/_json_api_activerecord/lib/preloads_test.rb +191 -0
  51. data/test/lib/jat/plugins/_preloads/_preloads_test.rb +68 -0
  52. data/test/lib/jat/plugins/_preloads/lib/format_user_preloads_test.rb +47 -0
  53. data/test/lib/jat/plugins/_preloads/lib/preloads_with_path_test.rb +33 -0
  54. data/test/lib/jat/plugins/cache/cache_test.rb +82 -0
  55. data/test/lib/jat/plugins/camel_lower/camel_lower_test.rb +78 -0
  56. data/test/lib/jat/plugins/json_api/json_api_test.rb +154 -0
  57. data/test/lib/jat/plugins/json_api/lib/construct_traversal_map_test.rb +119 -0
  58. data/test/lib/jat/plugins/json_api/lib/map_test.rb +117 -0
  59. data/test/lib/jat/plugins/json_api/lib/params/fields/parse_test.rb +24 -0
  60. data/test/lib/jat/plugins/json_api/lib/params/fields/validate_test.rb +47 -0
  61. data/test/lib/jat/plugins/json_api/lib/params/fields_test.rb +37 -0
  62. data/test/lib/jat/plugins/json_api/lib/params/include/parse_test.rb +46 -0
  63. data/test/lib/jat/plugins/json_api/lib/params/include/validate_test.rb +51 -0
  64. data/test/lib/jat/plugins/json_api/lib/params/include_test.rb +41 -0
  65. data/test/lib/jat/plugins/json_api/lib/presenters/document_links_presenter_test.rb +69 -0
  66. data/test/lib/jat/plugins/json_api/lib/presenters/document_meta_presenter_test.rb +69 -0
  67. data/test/lib/jat/plugins/json_api/lib/presenters/jsonapi_presenter_test.rb +69 -0
  68. data/test/lib/jat/plugins/json_api/lib/presenters/links_presenter_test.rb +69 -0
  69. data/test/lib/jat/plugins/json_api/lib/presenters/meta_presenter_test.rb +69 -0
  70. data/test/lib/jat/plugins/json_api/lib/presenters/relationship_links_presenter_test.rb +75 -0
  71. data/test/lib/jat/plugins/json_api/lib/presenters/relationship_meta_presenter_test.rb +75 -0
  72. data/test/lib/jat/plugins/json_api/lib/response_test.rb +489 -0
  73. data/test/lib/jat/plugins/json_api/lib/traversal_map_test.rb +58 -0
  74. data/test/lib/jat/plugins/simple_api/lib/construct_traversal_map_test.rb +100 -0
  75. data/test/lib/jat/plugins/simple_api/lib/map_test.rb +56 -0
  76. data/test/lib/jat/plugins/simple_api/lib/params/parse_test.rb +71 -0
  77. data/test/lib/jat/plugins/simple_api/lib/response_test.rb +342 -0
  78. data/test/lib/jat/plugins/simple_api/simple_api_test.rb +81 -0
  79. data/test/lib/jat/plugins/to_str/to_str_test.rb +52 -0
  80. data/test/lib/jat/presenter_test.rb +61 -0
  81. data/test/lib/jat/utils/enum_deep_dup_test.rb +31 -0
  82. data/test/lib/jat/utils/enum_deep_freeze_test.rb +28 -0
  83. data/test/lib/jat_test.rb +120 -0
  84. data/test/lib/plugin_test.rb +49 -0
  85. data/test/support/activerecord.rb +24 -0
  86. data/test/test_helper.rb +16 -0
  87. data/test/test_plugin.rb +59 -0
  88. metadata +240 -11
@@ -0,0 +1,489 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe "Jat::Plugins::JsonApi::Response" do
6
+ let(:base_class) { Class.new(Jat) { plugin :json_api } }
7
+
8
+ it "returns empty hash when nothing to serialize" do
9
+ empty_serializer = Class.new(base_class) { type :foo }
10
+
11
+ assert_equal({}, empty_serializer.to_h(nil))
12
+ end
13
+
14
+ it "returns correct structure with data" do
15
+ str_serializer = Class.new(base_class) do
16
+ type "str"
17
+ attribute(:id) { |_| "STRING" }
18
+ end
19
+
20
+ assert_equal({data: {type: :str, id: "STRING"}}, str_serializer.to_h("STRING"))
21
+ end
22
+
23
+ it "returns correct structure with array data" do
24
+ str_serializer = Class.new(base_class) do
25
+ type "str"
26
+ attribute(:id) { |obj| obj }
27
+ end
28
+
29
+ assert_equal(
30
+ {data: [{type: :str, id: "1"}, {type: :str, id: "2"}]},
31
+ str_serializer.to_h(%w[1 2], many: true)
32
+ )
33
+ end
34
+
35
+ it "returns correct structure with data with attributes" do
36
+ str_serializer = Class.new(base_class) do
37
+ type "str"
38
+ attribute(:id) { |obj| obj[0] }
39
+ attribute :length
40
+ end
41
+
42
+ assert_equal(
43
+ {data: {type: :str, id: "S", attributes: {length: 6}}},
44
+ str_serializer.to_h("STRING")
45
+ )
46
+ end
47
+
48
+ it "returns correct structure with has-one relationship" do
49
+ int_serializer = Class.new(base_class) do
50
+ type "int"
51
+ attribute(:id) { |obj| obj }
52
+ end
53
+
54
+ str_serializer = Class.new(base_class) do
55
+ type "str"
56
+ attribute(:id) { |obj| obj[0] }
57
+ relationship :length, serializer: int_serializer, exposed: true
58
+ end
59
+
60
+ assert_equal(
61
+ {
62
+ data: {
63
+ type: :str, id: "S",
64
+ relationships: {
65
+ length: {data: {type: :int, id: 6}}
66
+ }
67
+ },
68
+ included: [
69
+ {type: :int, id: 6}
70
+ ]
71
+ },
72
+ str_serializer.to_h("STRING")
73
+ )
74
+ end
75
+
76
+ it "does not return has-one relationship when not exposed" do
77
+ int_serializer = Class.new(base_class) do
78
+ type "int"
79
+ attribute(:id) { |obj| obj }
80
+ end
81
+
82
+ str_serializer = Class.new(base_class) do
83
+ type "str"
84
+ attribute(:id) { |obj| obj[0] }
85
+ relationship :length, serializer: int_serializer # relationships are not exposed by default
86
+ end
87
+
88
+ assert_equal({data: {type: :str, id: "S"}}, str_serializer.to_h("STRING"))
89
+ end
90
+
91
+ it "returns correct structure with empty has-one relationship" do
92
+ str_serializer = Class.new(base_class) do
93
+ type "str"
94
+ attribute(:id) { |obj| obj[0] }
95
+ relationship(:length, serializer: self, exposed: true) { |_obj| nil }
96
+ end
97
+
98
+ assert_equal(
99
+ {
100
+ data: {
101
+ type: :str, id: "S",
102
+ relationships: {length: {data: nil}}
103
+ }
104
+ },
105
+ str_serializer.to_h("STRING")
106
+ )
107
+ end
108
+
109
+ it "returns correct structure with has-one relationship with attributes" do
110
+ int_serializer = Class.new(base_class) do
111
+ type "int"
112
+ attribute(:id) { |obj| obj }
113
+ attribute(:next) { |obj| obj + 1 }
114
+ end
115
+
116
+ str_serializer = Class.new(base_class) do
117
+ type "str"
118
+ attribute(:id) { |obj| obj[0] }
119
+ relationship :length, serializer: int_serializer, exposed: true
120
+ end
121
+
122
+ assert_equal(
123
+ {
124
+ data: {
125
+ type: :str, id: "S",
126
+ relationships: {
127
+ length: {data: {type: :int, id: 6}}
128
+ }
129
+ },
130
+ included: [
131
+ {type: :int, id: 6, attributes: {next: 7}}
132
+ ]
133
+ },
134
+ str_serializer.to_h("STRING")
135
+ )
136
+ end
137
+
138
+ it "returns correct structure with empty has-many relationship" do
139
+ chr_serializer = Class.new(base_class) do
140
+ type "chr"
141
+ end
142
+
143
+ str_serializer = Class.new(base_class) do
144
+ type "str"
145
+ attribute(:id) { |_obj| "id" }
146
+ relationship :chars, serializer: chr_serializer, many: true, exposed: true
147
+ end
148
+
149
+ assert_equal(
150
+ {
151
+ data: {
152
+ type: :str, id: "id",
153
+ relationships: {chars: {data: []}}
154
+ }
155
+ },
156
+ str_serializer.to_h("")
157
+ )
158
+ end
159
+
160
+ it "returns correct structure with has-many relationship" do
161
+ chr_serializer = Class.new(base_class) do
162
+ type "chr"
163
+ attribute(:id) { |obj| obj }
164
+ end
165
+
166
+ str_serializer = Class.new(base_class) do
167
+ type "str"
168
+ attribute(:id) { |obj| obj[0] }
169
+ relationship :chars, serializer: chr_serializer, many: true, exposed: true
170
+ end
171
+
172
+ assert_equal(
173
+ {
174
+ data: {
175
+ type: :str, id: "a",
176
+ relationships: {
177
+ chars: {data: [{type: :chr, id: "a"}, {type: :chr, id: "b"}]}
178
+ }
179
+ },
180
+ included: [
181
+ {type: :chr, id: "a"}, {type: :chr, id: "b"}
182
+ ]
183
+ },
184
+ str_serializer.to_h("ab")
185
+ )
186
+ end
187
+
188
+ it "returns correct structure with has-many relationship with attributes" do
189
+ chr_serializer = Class.new(base_class) do
190
+ type "chr"
191
+ attribute(:id) { |obj| obj }
192
+ attribute :next
193
+ end
194
+
195
+ str_serializer = Class.new(base_class) do
196
+ type "str"
197
+ attribute(:id) { |obj| obj[0] }
198
+ relationship :chars, serializer: chr_serializer, many: true, exposed: true
199
+ end
200
+
201
+ assert_equal(
202
+ {
203
+ data: {
204
+ type: :str, id: "a",
205
+ relationships: {
206
+ chars: {data: [{type: :chr, id: "a"}, {type: :chr, id: "b"}]}
207
+ }
208
+ },
209
+ included: [
210
+ {type: :chr, id: "a", attributes: {next: "b"}},
211
+ {type: :chr, id: "b", attributes: {next: "c"}}
212
+ ]
213
+ },
214
+ str_serializer.to_h("ab")
215
+ )
216
+ end
217
+
218
+ it "accepts includes param" do
219
+ chr_serializer = Class.new(base_class) do
220
+ type "chr"
221
+ attribute(:id) { |obj| obj }
222
+ end
223
+
224
+ str_serializer = Class.new(base_class) do
225
+ type "str"
226
+ attribute(:id) { |obj| obj[0] }
227
+ relationship :chars, serializer: chr_serializer, many: true, exposed: false
228
+ end
229
+
230
+ assert_equal(
231
+ {
232
+ data: {
233
+ type: :str, id: "a",
234
+ relationships: {
235
+ chars: {data: [{type: :chr, id: "a"}, {type: :chr, id: "b"}]}
236
+ }
237
+ },
238
+ included: [
239
+ {type: :chr, id: "a"}, {type: :chr, id: "b"}
240
+ ]
241
+ },
242
+ str_serializer.to_h("ab", params: {include: "chars"})
243
+ )
244
+ end
245
+
246
+ it "accepts sparse_fieldset" do
247
+ chr_serializer = Class.new(base_class) do
248
+ type "chr"
249
+ attribute(:id) { |obj| obj }
250
+ end
251
+
252
+ str_serializer = Class.new(base_class) do
253
+ type "str"
254
+ attribute(:id) { |obj| obj[0] }
255
+ relationship :chars, serializer: chr_serializer, many: true, exposed: false
256
+ end
257
+
258
+ assert_equal(
259
+ {
260
+ data: {
261
+ type: :str, id: "a",
262
+ relationships: {
263
+ chars: {data: [{type: :chr, id: "a"}, {type: :chr, id: "b"}]}
264
+ }
265
+ },
266
+ included: [
267
+ {type: :chr, id: "a"}, {type: :chr, id: "b"}
268
+ ]
269
+ },
270
+ str_serializer.to_h("ab", params: {fields: {str: "chars"}})
271
+ )
272
+ end
273
+
274
+ describe "json_api" do
275
+ let(:serializer) do
276
+ Class.new(base_class) do
277
+ type :foo
278
+ attribute(:id) { |obj| obj }
279
+ end
280
+ end
281
+
282
+ it "adds `jsonapi` fields defined in serializer" do
283
+ serializer.jsonapi(:version) { "1.2.3" }
284
+ serializer.jsonapi(:uid) { |obj, context| [obj, context[:time]] }
285
+
286
+ response = serializer.to_h("bar", time: "12:00")
287
+ jsonapi = response.dig(:jsonapi)
288
+ assert_equal({version: "1.2.3", uid: ["bar", "12:00"]}, jsonapi)
289
+ end
290
+
291
+ it "does not overwrite manually added data" do
292
+ serializer.jsonapi(:version) { "1.2.3" }
293
+ serializer.jsonapi(:foo) { :bar }
294
+
295
+ response = serializer.to_h("bar", jsonapi: {version: "3.2.1"})
296
+ jsonapi = response.dig(:jsonapi)
297
+ assert_equal({version: "3.2.1", foo: :bar}, jsonapi)
298
+ end
299
+
300
+ it "does not add jsonapi attributes with nil values" do
301
+ serializer.jsonapi(:foo) {}
302
+ serializer.jsonapi(:bar) { false }
303
+
304
+ response = serializer.to_h("bar")
305
+ jsonapi = response.dig(:jsonapi)
306
+ assert_equal({bar: false}, jsonapi)
307
+ end
308
+ end
309
+
310
+ describe "document_meta" do
311
+ let(:serializer) do
312
+ Class.new(base_class) do
313
+ type :foo
314
+ attribute(:id) { |obj| obj }
315
+ end
316
+ end
317
+
318
+ it "adds document meta defined in serializer" do
319
+ serializer.document_meta(:version) { "1.2.3" }
320
+ serializer.document_meta(:uid) { |obj, context| [obj, context[:time]] }
321
+
322
+ response = serializer.to_h("bar", time: "12:00")
323
+ meta = response.dig(:meta)
324
+ assert_equal({version: "1.2.3", uid: ["bar", "12:00"]}, meta)
325
+ end
326
+
327
+ it "does not overwrite manually added meta" do
328
+ serializer.document_meta(:version) { "1.2.3" }
329
+ serializer.document_meta(:foo) { :bar }
330
+
331
+ response = serializer.to_h("bar", meta: {version: "3.2.1"})
332
+ meta = response.dig(:meta)
333
+ assert_equal({version: "3.2.1", foo: :bar}, meta)
334
+ end
335
+
336
+ it "does not add meta with nil values" do
337
+ serializer.document_meta(:foo) {}
338
+ serializer.document_meta(:bar) { false }
339
+
340
+ response = serializer.to_h("bar")
341
+ meta = response.dig(:meta)
342
+ assert_equal({bar: false}, meta)
343
+ end
344
+ end
345
+
346
+ describe "resource meta" do
347
+ let(:serializer) do
348
+ Class.new(base_class) do
349
+ type :foo
350
+ attribute(:id) { |obj| obj }
351
+ end
352
+ end
353
+
354
+ it "adds meta defined in serializer" do
355
+ serializer.object_meta(:version) { "1.2.3" }
356
+ serializer.object_meta(:uid) { |obj, context| [obj, context[:time]] }
357
+
358
+ response = serializer.to_h("bar", time: "12:00")
359
+ meta = response.dig(:data, :meta)
360
+ assert_equal({version: "1.2.3", uid: ["bar", "12:00"]}, meta)
361
+ end
362
+
363
+ it "does not add meta with nil values" do
364
+ serializer.object_meta(:foo) {}
365
+ serializer.object_meta(:bar) { false }
366
+
367
+ response = serializer.to_h("bar")
368
+ meta = response.dig(:data, :meta)
369
+ assert_equal({bar: false}, meta)
370
+ end
371
+ end
372
+
373
+ describe "relationship meta" do
374
+ let(:bar_serializer) do
375
+ Class.new(base_class) do
376
+ type :bar
377
+ attribute(:id) { |obj| obj }
378
+ end
379
+ end
380
+
381
+ let(:foo_serializer) do
382
+ Class.new(base_class) do
383
+ type :foo
384
+ attribute(:id) { |obj| obj }
385
+ end
386
+ end
387
+
388
+ it "adds relationship meta defined in serializer" do
389
+ foo_serializer.relationship(:bar, serializer: -> { bar_serializer }, exposed: true) { "bar" }
390
+ bar_serializer.relationship_meta(:version) { "1.2.3" }
391
+ bar_serializer.relationship_meta(:uid) { |parent, obj, context| [parent, obj, context[:time]] }
392
+ bar_serializer.relationship_meta(:null) {}
393
+
394
+ response = foo_serializer.to_h("foo", time: "12:00")
395
+ meta = response.dig(:data, :relationships, :bar, :meta)
396
+ assert_equal({version: "1.2.3", uid: ["foo", "bar", "12:00"]}, meta)
397
+ end
398
+ end
399
+
400
+ describe "document_link" do
401
+ let(:serializer) do
402
+ Class.new(base_class) do
403
+ type :foo
404
+ attribute(:id) { |obj| obj }
405
+ end
406
+ end
407
+
408
+ it "adds document links defined in serializer" do
409
+ serializer.document_link(:self) { "/self" }
410
+ serializer.document_link(:related) { |obj| "/#{obj}/self" }
411
+
412
+ response = serializer.to_h("bar")
413
+ links = response.dig(:links)
414
+ assert_equal({self: "/self", related: "/bar/self"}, links)
415
+ end
416
+
417
+ it "does not overwrite manually added links" do
418
+ serializer.document_link(:self) { "/self" }
419
+ serializer.document_link(:related) { |obj| "/#{obj}/self" }
420
+
421
+ response = serializer.to_h("bar", links: {self: "/foo"})
422
+ links = response.dig(:links)
423
+ assert_equal({self: "/foo", related: "/bar/self"}, links)
424
+ end
425
+
426
+ it "does not add links with nil values" do
427
+ serializer.document_link(:foo) {}
428
+ serializer.document_link(:bar) { false }
429
+
430
+ response = serializer.to_h("bar")
431
+ links = response.dig(:links)
432
+ assert_equal({bar: false}, links)
433
+ end
434
+ end
435
+
436
+ describe "resource links" do
437
+ let(:serializer) do
438
+ Class.new(base_class) do
439
+ type :foo
440
+ attribute(:id) { |obj| obj }
441
+ end
442
+ end
443
+
444
+ it "adds links defined in serializer" do
445
+ serializer.object_link(:self) { "/self" }
446
+ serializer.object_link(:related) { |obj| "/#{obj}/self" }
447
+
448
+ response = serializer.to_h("bar", time: "12:00")
449
+ links = response.dig(:data, :links)
450
+ assert_equal({self: "/self", related: "/bar/self"}, links)
451
+ end
452
+
453
+ it "does not add links with nil values" do
454
+ serializer.object_link(:foo) {}
455
+ serializer.object_link(:bar) { false }
456
+
457
+ response = serializer.to_h("bar")
458
+ links = response.dig(:data, :links)
459
+ assert_equal({bar: false}, links)
460
+ end
461
+ end
462
+
463
+ describe "relationship links" do
464
+ let(:bar_serializer) do
465
+ Class.new(base_class) do
466
+ type :bar
467
+ attribute(:id) { |obj| obj }
468
+ end
469
+ end
470
+
471
+ let(:foo_serializer) do
472
+ Class.new(base_class) do
473
+ type :foo
474
+ attribute(:id) { |obj| obj }
475
+ end
476
+ end
477
+
478
+ it "adds relationship link defined in serializer" do
479
+ foo_serializer.relationship(:bar, serializer: -> { bar_serializer }, exposed: true) { "bar" }
480
+ bar_serializer.relationship_link(:self) { "/self" }
481
+ bar_serializer.relationship_link(:related) { |parent_obj| "/#{parent_obj}/self" }
482
+ bar_serializer.relationship_link(:null) {}
483
+
484
+ response = foo_serializer.to_h("foo")
485
+ links = response.dig(:data, :relationships, :bar, :links)
486
+ assert_equal({self: "/self", related: "/foo/self"}, links)
487
+ end
488
+ end
489
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe "Jat::Plugins::JsonApi::TraversalMap" do
6
+ let(:jat_class) do
7
+ new_class = Class.new(Jat)
8
+ new_class.attribute :foo, exposed: true
9
+ new_class.attribute :bar, exposed: false
10
+ new_class
11
+ end
12
+
13
+ let(:jat) do
14
+ jat_class.new("JAT", params: {fields: {jat: "bar"}})
15
+ end
16
+
17
+ before do
18
+ jat_class.plugin :json_api
19
+ jat_class.type :jat
20
+ end
21
+
22
+ describe "#jat" do
23
+ it "returns initialization value" do
24
+ map = Jat::Plugins::JsonApi::TraversalMap.new(jat)
25
+ assert_same jat, map.jat
26
+ end
27
+ end
28
+
29
+ describe "#exposed" do
30
+ it "returns memorized exposed map" do
31
+ map = Jat::Plugins::JsonApi::TraversalMap.new(jat)
32
+ expected_map_hash = Jat::Plugins::JsonApi::ConstructTraversalMap.new(jat_class, :exposed).to_h
33
+
34
+ assert_equal expected_map_hash, map.exposed
35
+ assert_same map.exposed, map.exposed
36
+ end
37
+ end
38
+
39
+ describe "#full" do
40
+ it "returns memorized full map" do
41
+ map = Jat::Plugins::JsonApi::TraversalMap.new(jat)
42
+ expected_map_hash = Jat::Plugins::JsonApi::ConstructTraversalMap.new(jat_class, :all).to_h
43
+
44
+ assert_equal expected_map_hash, map.full
45
+ assert_same map.full, map.full
46
+ end
47
+ end
48
+
49
+ describe "#current" do
50
+ it "returns memorized current map" do
51
+ map = Jat::Plugins::JsonApi::TraversalMap.new(jat)
52
+ expected_map_hash = Jat::Plugins::JsonApi::Map.call(jat)
53
+
54
+ assert_equal expected_map_hash, map.current
55
+ assert_same map.current, map.current
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe "Jat::Plugins::JsonApi::SimpleApi::ConstructTraversalMap" do
6
+ before { Jat::Plugins.load_plugin(:simple_api) }
7
+
8
+ let(:described_class) { Jat::Plugins::SimpleApi::ConstructTraversalMap }
9
+ let(:base_class) { Class.new(Jat) { plugin :simple_api } }
10
+
11
+ let(:a) do
12
+ ser = Class.new(base_class)
13
+
14
+ ser.attribute :a1
15
+ ser.attribute :a2
16
+ ser.attribute :a3, exposed: false
17
+
18
+ ser.attribute :b, serializer: b
19
+ ser.attribute :c, serializer: c
20
+ ser.attribute :d, serializer: d, exposed: true
21
+ ser
22
+ end
23
+
24
+ let(:b) do
25
+ ser = Class.new(base_class)
26
+ ser.attribute :b1
27
+ ser.attribute :b2
28
+ ser.attribute :b3, exposed: false
29
+ ser
30
+ end
31
+
32
+ let(:c) do
33
+ ser = Class.new(base_class)
34
+ ser.attribute :c1
35
+ ser.attribute :c2
36
+ ser.attribute :c3, exposed: false
37
+ ser
38
+ end
39
+
40
+ let(:d) do
41
+ ser = Class.new(base_class)
42
+ ser.attribute :d1
43
+ ser.attribute :d2
44
+ ser.attribute :d3, exposed: false
45
+ ser
46
+ end
47
+
48
+ it "returns all attributes" do
49
+ result = described_class.new(a, :all).to_h
50
+ expected_result = {
51
+ a1: {},
52
+ a2: {},
53
+ a3: {},
54
+ b: {b1: {}, b2: {}, b3: {}},
55
+ c: {c1: {}, c2: {}, c3: {}},
56
+ d: {d1: {}, d2: {}, d3: {}}
57
+ }
58
+
59
+ assert_equal expected_result, result
60
+ end
61
+
62
+ it "returns exposed attributes" do
63
+ result = described_class.new(a, :exposed).to_h
64
+ expected_result = {
65
+ a1: {},
66
+ a2: {},
67
+ d: {d1: {}, d2: {}}
68
+ }
69
+
70
+ assert_equal expected_result, result
71
+ end
72
+
73
+ it "returns only manually exposed attributes when `none` type provided" do
74
+ manually_exposed = {
75
+ a2: {},
76
+ a3: {},
77
+ c: {c2: {}, c3: {}},
78
+ d: {d2: {}, d3: {}}
79
+ }
80
+ result = described_class.new(a, :none, manually_exposed: manually_exposed).to_h
81
+
82
+ assert_equal manually_exposed, result
83
+ end
84
+
85
+ it "returns combined auto-exposed and manualy exposed attributes when `default` type provided" do
86
+ manually_exposed = {
87
+ b: {b3: {}}, c: {}
88
+ }
89
+ result = described_class.new(a, :default, manually_exposed: manually_exposed).to_h
90
+ expected_result = {
91
+ a1: {},
92
+ a2: {},
93
+ b: {b1: {}, b2: {}, b3: {}},
94
+ c: {c1: {}, c2: {}},
95
+ d: {d1: {}, d2: {}}
96
+ }
97
+
98
+ assert_equal expected_result, result
99
+ end
100
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe "Jat::Plugins::SimpleApi::Map" do
6
+ before { Jat::Plugins.load_plugin(:simple_api) }
7
+
8
+ subject { Jat::Plugins::SimpleApi::Map.call(jat) }
9
+
10
+ let(:jat_class) do
11
+ Class.new(Jat) do
12
+ plugin :simple_api
13
+
14
+ attribute :a1
15
+ attribute :a2
16
+ attribute :a3, exposed: false
17
+ attribute :a4, exposed: false
18
+ attribute :a5, exposed: false
19
+ end
20
+ end
21
+
22
+ let(:jat) { jat_class.new(nil, {**params, **context}) }
23
+ let(:params) { {} }
24
+ let(:context) { {} }
25
+
26
+ describe "when no params given" do
27
+ it "returns map of exposed by default fields" do
28
+ assert_equal({a1: {}, a2: {}}, subject)
29
+ end
30
+ end
31
+
32
+ describe "when fields given" do
33
+ let(:params) { {params: {fields: "a2,a3,a4"}} }
34
+
35
+ it "constructs map with default and provided fields" do
36
+ assert_equal({a1: {}, a2: {}, a3: {}, a4: {}}, subject)
37
+ end
38
+ end
39
+
40
+ describe "with `exposed: all` context" do
41
+ let(:context) { {exposed: :all} }
42
+
43
+ it "constructs map with all fields" do
44
+ assert_equal({a1: {}, a2: {}, a3: {}, a4: {}, a5: {}}, subject)
45
+ end
46
+ end
47
+
48
+ describe "with `exposed: none` context" do
49
+ let(:params) { {params: {fields: "a2,a3,a4"}} }
50
+ let(:context) { {exposed: :none} }
51
+
52
+ it "constructs map with only requested fields" do
53
+ assert_equal({a2: {}, a3: {}, a4: {}}, subject)
54
+ end
55
+ end
56
+ end