active_model_serializers 0.8.3 → 0.10.8

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 (235) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE.md +29 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +15 -0
  4. data/.gitignore +17 -0
  5. data/.rubocop.yml +105 -0
  6. data/.simplecov +110 -0
  7. data/.travis.yml +50 -24
  8. data/CHANGELOG.md +650 -6
  9. data/CODE_OF_CONDUCT.md +74 -0
  10. data/CONTRIBUTING.md +105 -0
  11. data/Gemfile +69 -1
  12. data/{MIT-LICENSE.txt → MIT-LICENSE} +3 -2
  13. data/README.md +195 -545
  14. data/Rakefile +64 -8
  15. data/active_model_serializers.gemspec +62 -23
  16. data/appveyor.yml +28 -0
  17. data/bin/bench +171 -0
  18. data/bin/bench_regression +316 -0
  19. data/bin/rubocop +38 -0
  20. data/bin/serve_benchmark +39 -0
  21. data/docs/README.md +41 -0
  22. data/docs/STYLE.md +58 -0
  23. data/docs/general/adapters.md +269 -0
  24. data/docs/general/caching.md +58 -0
  25. data/docs/general/configuration_options.md +185 -0
  26. data/docs/general/deserialization.md +100 -0
  27. data/docs/general/fields.md +31 -0
  28. data/docs/general/getting_started.md +133 -0
  29. data/docs/general/instrumentation.md +40 -0
  30. data/docs/general/key_transforms.md +40 -0
  31. data/docs/general/logging.md +21 -0
  32. data/docs/general/rendering.md +293 -0
  33. data/docs/general/serializers.md +495 -0
  34. data/docs/how-open-source-maintained.jpg +0 -0
  35. data/docs/howto/add_pagination_links.md +138 -0
  36. data/docs/howto/add_relationship_links.md +140 -0
  37. data/docs/howto/add_root_key.md +62 -0
  38. data/docs/howto/grape_integration.md +42 -0
  39. data/docs/howto/outside_controller_use.md +66 -0
  40. data/docs/howto/passing_arbitrary_options.md +27 -0
  41. data/docs/howto/serialize_poro.md +73 -0
  42. data/docs/howto/test.md +154 -0
  43. data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
  44. data/docs/integrations/ember-and-json-api.md +147 -0
  45. data/docs/integrations/grape.md +19 -0
  46. data/docs/jsonapi/errors.md +56 -0
  47. data/docs/jsonapi/schema/schema.json +366 -0
  48. data/docs/jsonapi/schema.md +151 -0
  49. data/docs/rfcs/0000-namespace.md +106 -0
  50. data/docs/rfcs/template.md +15 -0
  51. data/lib/action_controller/serialization.rb +43 -38
  52. data/lib/active_model/serializable_resource.rb +11 -0
  53. data/lib/active_model/serializer/adapter/attributes.rb +15 -0
  54. data/lib/active_model/serializer/adapter/base.rb +18 -0
  55. data/lib/active_model/serializer/adapter/json.rb +15 -0
  56. data/lib/active_model/serializer/adapter/json_api.rb +15 -0
  57. data/lib/active_model/serializer/adapter/null.rb +15 -0
  58. data/lib/active_model/serializer/adapter.rb +24 -0
  59. data/lib/active_model/serializer/array_serializer.rb +12 -0
  60. data/lib/active_model/serializer/association.rb +71 -0
  61. data/lib/active_model/serializer/attribute.rb +25 -0
  62. data/lib/active_model/serializer/belongs_to_reflection.rb +11 -0
  63. data/lib/active_model/serializer/collection_serializer.rb +88 -0
  64. data/lib/active_model/serializer/concerns/caching.rb +300 -0
  65. data/lib/active_model/serializer/error_serializer.rb +14 -0
  66. data/lib/active_model/serializer/errors_serializer.rb +32 -0
  67. data/lib/active_model/serializer/field.rb +90 -0
  68. data/lib/active_model/serializer/fieldset.rb +31 -0
  69. data/lib/active_model/serializer/has_many_reflection.rb +10 -0
  70. data/lib/active_model/serializer/has_one_reflection.rb +7 -0
  71. data/lib/active_model/serializer/lazy_association.rb +96 -0
  72. data/lib/active_model/serializer/link.rb +21 -0
  73. data/lib/active_model/serializer/lint.rb +150 -0
  74. data/lib/active_model/serializer/null.rb +17 -0
  75. data/lib/active_model/serializer/reflection.rb +210 -0
  76. data/lib/active_model/{serializers → serializer}/version.rb +1 -1
  77. data/lib/active_model/serializer.rb +343 -442
  78. data/lib/active_model_serializers/adapter/attributes.rb +13 -0
  79. data/lib/active_model_serializers/adapter/base.rb +83 -0
  80. data/lib/active_model_serializers/adapter/json.rb +21 -0
  81. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +213 -0
  82. data/lib/active_model_serializers/adapter/json_api/error.rb +96 -0
  83. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +49 -0
  84. data/lib/active_model_serializers/adapter/json_api/link.rb +83 -0
  85. data/lib/active_model_serializers/adapter/json_api/meta.rb +37 -0
  86. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +88 -0
  87. data/lib/active_model_serializers/adapter/json_api/relationship.rb +104 -0
  88. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +66 -0
  89. data/lib/active_model_serializers/adapter/json_api.rb +533 -0
  90. data/lib/active_model_serializers/adapter/null.rb +9 -0
  91. data/lib/active_model_serializers/adapter.rb +98 -0
  92. data/lib/active_model_serializers/callbacks.rb +55 -0
  93. data/lib/active_model_serializers/deprecate.rb +54 -0
  94. data/lib/active_model_serializers/deserialization.rb +15 -0
  95. data/lib/active_model_serializers/json_pointer.rb +14 -0
  96. data/lib/active_model_serializers/logging.rb +122 -0
  97. data/lib/active_model_serializers/lookup_chain.rb +80 -0
  98. data/lib/active_model_serializers/model.rb +130 -0
  99. data/lib/active_model_serializers/railtie.rb +50 -0
  100. data/lib/active_model_serializers/register_jsonapi_renderer.rb +78 -0
  101. data/lib/active_model_serializers/serializable_resource.rb +82 -0
  102. data/lib/active_model_serializers/serialization_context.rb +39 -0
  103. data/lib/active_model_serializers/test/schema.rb +138 -0
  104. data/lib/active_model_serializers/test/serializer.rb +125 -0
  105. data/lib/active_model_serializers/test.rb +7 -0
  106. data/lib/active_model_serializers.rb +47 -81
  107. data/lib/generators/rails/USAGE +6 -0
  108. data/lib/generators/rails/resource_override.rb +10 -0
  109. data/lib/generators/rails/serializer_generator.rb +36 -0
  110. data/lib/generators/rails/templates/serializer.rb.erb +8 -0
  111. data/lib/grape/active_model_serializers.rb +16 -0
  112. data/lib/grape/formatters/active_model_serializers.rb +32 -0
  113. data/lib/grape/helpers/active_model_serializers.rb +17 -0
  114. data/lib/tasks/rubocop.rake +53 -0
  115. data/test/action_controller/adapter_selector_test.rb +62 -0
  116. data/test/action_controller/explicit_serializer_test.rb +135 -0
  117. data/test/action_controller/json/include_test.rb +246 -0
  118. data/test/action_controller/json_api/deserialization_test.rb +112 -0
  119. data/test/action_controller/json_api/errors_test.rb +40 -0
  120. data/test/action_controller/json_api/fields_test.rb +66 -0
  121. data/test/action_controller/json_api/linked_test.rb +202 -0
  122. data/test/action_controller/json_api/pagination_test.rb +124 -0
  123. data/test/action_controller/json_api/transform_test.rb +189 -0
  124. data/test/action_controller/lookup_proc_test.rb +49 -0
  125. data/test/action_controller/namespace_lookup_test.rb +232 -0
  126. data/test/action_controller/serialization_scope_name_test.rb +235 -0
  127. data/test/action_controller/serialization_test.rb +478 -0
  128. data/test/active_model_serializers/adapter_for_test.rb +208 -0
  129. data/test/active_model_serializers/json_pointer_test.rb +22 -0
  130. data/test/active_model_serializers/logging_test.rb +77 -0
  131. data/test/active_model_serializers/model_test.rb +142 -0
  132. data/test/active_model_serializers/railtie_test_isolated.rb +68 -0
  133. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +161 -0
  134. data/test/active_model_serializers/serialization_context_test_isolated.rb +71 -0
  135. data/test/active_model_serializers/test/schema_test.rb +131 -0
  136. data/test/active_model_serializers/test/serializer_test.rb +62 -0
  137. data/test/active_record_test.rb +9 -0
  138. data/test/adapter/attributes_test.rb +40 -0
  139. data/test/adapter/deprecation_test.rb +100 -0
  140. data/test/adapter/json/belongs_to_test.rb +45 -0
  141. data/test/adapter/json/collection_test.rb +104 -0
  142. data/test/adapter/json/has_many_test.rb +53 -0
  143. data/test/adapter/json/transform_test.rb +93 -0
  144. data/test/adapter/json_api/belongs_to_test.rb +155 -0
  145. data/test/adapter/json_api/collection_test.rb +96 -0
  146. data/test/adapter/json_api/errors_test.rb +76 -0
  147. data/test/adapter/json_api/fields_test.rb +96 -0
  148. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +96 -0
  149. data/test/adapter/json_api/has_many_test.rb +173 -0
  150. data/test/adapter/json_api/has_one_test.rb +80 -0
  151. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +213 -0
  152. data/test/adapter/json_api/json_api_test.rb +33 -0
  153. data/test/adapter/json_api/linked_test.rb +413 -0
  154. data/test/adapter/json_api/links_test.rb +110 -0
  155. data/test/adapter/json_api/pagination_links_test.rb +206 -0
  156. data/test/adapter/json_api/parse_test.rb +137 -0
  157. data/test/adapter/json_api/relationship_test.rb +397 -0
  158. data/test/adapter/json_api/resource_meta_test.rb +100 -0
  159. data/test/adapter/json_api/toplevel_jsonapi_test.rb +82 -0
  160. data/test/adapter/json_api/transform_test.rb +512 -0
  161. data/test/adapter/json_api/type_test.rb +193 -0
  162. data/test/adapter/json_test.rb +46 -0
  163. data/test/adapter/null_test.rb +22 -0
  164. data/test/adapter/polymorphic_test.rb +218 -0
  165. data/test/adapter_test.rb +67 -0
  166. data/test/array_serializer_test.rb +20 -73
  167. data/test/benchmark/app.rb +65 -0
  168. data/test/benchmark/benchmarking_support.rb +67 -0
  169. data/test/benchmark/bm_active_record.rb +81 -0
  170. data/test/benchmark/bm_adapter.rb +38 -0
  171. data/test/benchmark/bm_caching.rb +119 -0
  172. data/test/benchmark/bm_lookup_chain.rb +83 -0
  173. data/test/benchmark/bm_transform.rb +45 -0
  174. data/test/benchmark/config.ru +3 -0
  175. data/test/benchmark/controllers.rb +83 -0
  176. data/test/benchmark/fixtures.rb +219 -0
  177. data/test/cache_test.rb +651 -0
  178. data/test/collection_serializer_test.rb +127 -0
  179. data/test/fixtures/active_record.rb +113 -0
  180. data/test/fixtures/poro.rb +225 -0
  181. data/test/generators/scaffold_controller_generator_test.rb +24 -0
  182. data/test/generators/serializer_generator_test.rb +75 -0
  183. data/test/grape_test.rb +196 -0
  184. data/test/lint_test.rb +49 -0
  185. data/test/logger_test.rb +20 -0
  186. data/test/poro_test.rb +9 -0
  187. data/test/serializable_resource_test.rb +79 -0
  188. data/test/serializers/association_macros_test.rb +37 -0
  189. data/test/serializers/associations_test.rb +518 -0
  190. data/test/serializers/attribute_test.rb +153 -0
  191. data/test/serializers/attributes_test.rb +52 -0
  192. data/test/serializers/caching_configuration_test_isolated.rb +170 -0
  193. data/test/serializers/configuration_test.rb +32 -0
  194. data/test/serializers/fieldset_test.rb +14 -0
  195. data/test/serializers/meta_test.rb +202 -0
  196. data/test/serializers/options_test.rb +32 -0
  197. data/test/serializers/read_attribute_for_serialization_test.rb +79 -0
  198. data/test/serializers/reflection_test.rb +479 -0
  199. data/test/serializers/root_test.rb +21 -0
  200. data/test/serializers/serialization_test.rb +55 -0
  201. data/test/serializers/serializer_for_test.rb +136 -0
  202. data/test/serializers/serializer_for_with_namespace_test.rb +88 -0
  203. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  204. data/test/support/isolated_unit.rb +84 -0
  205. data/test/support/rails5_shims.rb +53 -0
  206. data/test/support/rails_app.rb +38 -0
  207. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  208. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +6 -0
  209. data/test/support/schemas/custom/show.json +7 -0
  210. data/test/support/schemas/hyper_schema.json +93 -0
  211. data/test/support/schemas/render_using_json_api.json +43 -0
  212. data/test/support/schemas/simple_json_pointers.json +10 -0
  213. data/test/support/serialization_testing.rb +79 -0
  214. data/test/test_helper.rb +59 -21
  215. metadata +529 -43
  216. data/DESIGN.textile +0 -586
  217. data/Gemfile.edge +0 -9
  218. data/bench/perf.rb +0 -43
  219. data/cruft.md +0 -19
  220. data/lib/active_model/array_serializer.rb +0 -104
  221. data/lib/active_model/serializer/associations.rb +0 -233
  222. data/lib/active_record/serializer_override.rb +0 -16
  223. data/lib/generators/resource_override.rb +0 -13
  224. data/lib/generators/serializer/USAGE +0 -9
  225. data/lib/generators/serializer/serializer_generator.rb +0 -42
  226. data/lib/generators/serializer/templates/serializer.rb +0 -19
  227. data/test/association_test.rb +0 -592
  228. data/test/caching_test.rb +0 -96
  229. data/test/generators_test.rb +0 -85
  230. data/test/no_serialization_scope_test.rb +0 -34
  231. data/test/serialization_scope_name_test.rb +0 -67
  232. data/test/serialization_test.rb +0 -392
  233. data/test/serializer_support_test.rb +0 -51
  234. data/test/serializer_test.rb +0 -1465
  235. data/test/test_fakes.rb +0 -217
@@ -0,0 +1,397 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ class RelationshipTest < ActiveSupport::TestCase
7
+ def test_relationship_with_data
8
+ expected = {
9
+ data: {
10
+ id: '1',
11
+ type: 'blogs'
12
+ }
13
+ }
14
+
15
+ model_attributes = { blog: Blog.new(id: 1) }
16
+ relationship_name = :blog
17
+ model = new_model(model_attributes)
18
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
19
+ has_one :blog
20
+ end
21
+ assert_equal(expected, actual)
22
+ end
23
+
24
+ def test_relationship_with_nil_model
25
+ expected = { data: nil }
26
+
27
+ model_attributes = { blog: nil }
28
+ relationship_name = :blog
29
+ model = new_model(model_attributes)
30
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
31
+ has_one :blog
32
+ end
33
+ assert_equal(expected, actual)
34
+ end
35
+
36
+ def test_relationship_with_data_array
37
+ expected = {
38
+ data: [
39
+ {
40
+ id: '1',
41
+ type: 'posts'
42
+ },
43
+ {
44
+ id: '2',
45
+ type: 'posts'
46
+ }
47
+ ]
48
+ }
49
+
50
+ model_attributes = { posts: [Post.new(id: 1), Post.new(id: 2)] }
51
+ relationship_name = :posts
52
+ model = new_model(model_attributes)
53
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
54
+ has_many :posts
55
+ end
56
+ assert_equal(expected, actual)
57
+ end
58
+
59
+ def test_relationship_data_not_included
60
+ expected = { meta: {} }
61
+
62
+ model_attributes = { blog: :does_not_matter }
63
+ relationship_name = :blog
64
+ model = new_model(model_attributes)
65
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
66
+ has_one :blog do
67
+ include_data false
68
+ end
69
+ end
70
+ assert_equal(expected, actual)
71
+ end
72
+
73
+ def test_relationship_many_links
74
+ expected = {
75
+ links: {
76
+ self: 'a link',
77
+ related: 'another link'
78
+ }
79
+ }
80
+
81
+ model_attributes = { blog: :does_not_matter }
82
+ relationship_name = :blog
83
+ model = new_model(model_attributes)
84
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
85
+ has_one :blog do
86
+ include_data false
87
+ link :self, 'a link'
88
+ link :related, 'another link'
89
+ end
90
+ end
91
+ assert_equal(expected, actual)
92
+ end
93
+
94
+ def test_relationship_block_link_with_meta
95
+ expected = {
96
+ links: {
97
+ self: {
98
+ href: '1',
99
+ meta: { id: 1 }
100
+ }
101
+ }
102
+ }
103
+
104
+ model_attributes = { blog: Blog.new(id: 1) }
105
+ relationship_name = :blog
106
+ model = new_model(model_attributes)
107
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
108
+ has_one :blog do
109
+ include_data false
110
+ link :self do
111
+ href object.blog.id.to_s
112
+ meta(id: object.blog.id)
113
+ end
114
+ end
115
+ end
116
+ assert_equal(expected, actual)
117
+ end
118
+
119
+ def test_relationship_simple_meta
120
+ expected = { meta: { id: '1' } }
121
+
122
+ model_attributes = { blog: Blog.new(id: 1) }
123
+ relationship_name = :blog
124
+ model = new_model(model_attributes)
125
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
126
+ has_one :blog do
127
+ include_data false
128
+ meta(id: object.blog.id.to_s)
129
+ end
130
+ end
131
+ assert_equal(expected, actual)
132
+ end
133
+
134
+ def test_relationship_block_meta
135
+ expected = {
136
+ meta: {
137
+ id: 1
138
+ }
139
+ }
140
+
141
+ model_attributes = { blog: Blog.new(id: 1) }
142
+ relationship_name = :blog
143
+ model = new_model(model_attributes)
144
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
145
+ has_one :blog do
146
+ include_data false
147
+ meta(id: object.blog.id)
148
+ end
149
+ end
150
+ assert_equal(expected, actual)
151
+ end
152
+
153
+ def test_relationship_simple_link
154
+ expected = {
155
+ data: {
156
+ id: '1337',
157
+ type: 'bios'
158
+ },
159
+ links: {
160
+ self: '//example.com/link_author/relationships/bio'
161
+ }
162
+ }
163
+
164
+ model_attributes = { bio: Bio.new(id: 1337) }
165
+ relationship_name = :bio
166
+ model = new_model(model_attributes)
167
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
168
+ has_one :bio do
169
+ link :self, '//example.com/link_author/relationships/bio'
170
+ end
171
+ end
172
+ assert_equal(expected, actual)
173
+ end
174
+
175
+ def test_relationship_block_link
176
+ expected = {
177
+ data: { id: '1337', type: 'profiles' },
178
+ links: { related: '//example.com/profiles/1337' }
179
+ }
180
+
181
+ model_attributes = { profile: Profile.new(id: 1337) }
182
+ relationship_name = :profile
183
+ model = new_model(model_attributes)
184
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
185
+ has_one :profile do
186
+ id = object.profile.id
187
+ link :related do
188
+ "//example.com/profiles/#{id}" if id != 123
189
+ end
190
+ end
191
+ end
192
+ assert_equal(expected, actual)
193
+ end
194
+
195
+ def test_relationship_with_everything
196
+ expected = {
197
+ data: [{ id: '1337', type: 'likes' }],
198
+ links: {
199
+ related: {
200
+ href: '//example.com/likes/1337',
201
+ meta: { ids: '1337' }
202
+ }
203
+ },
204
+ meta: { liked: true }
205
+ }
206
+
207
+ model_attributes = { likes: [Like.new(id: 1337)] }
208
+ relationship_name = :likes
209
+ model = new_model(model_attributes)
210
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
211
+ has_many :likes do
212
+ link :related do
213
+ ids = object.likes.map(&:id).join(',')
214
+ href "//example.com/likes/#{ids}"
215
+ meta ids: ids
216
+ end
217
+ meta liked: object.likes.any?
218
+ end
219
+ end
220
+ assert_equal(expected, actual)
221
+ end
222
+
223
+ def test_relationship_nil_link
224
+ expected = {
225
+ data: { id: '123', type: 'profiles' }
226
+ }
227
+
228
+ model_attributes = { profile: Profile.new(id: 123) }
229
+ relationship_name = :profile
230
+ model = new_model(model_attributes)
231
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
232
+ has_one :profile do
233
+ id = object.profile.id
234
+ link :related do
235
+ "//example.com/profiles/#{id}" if id != 123
236
+ end
237
+ end
238
+ end
239
+ assert_equal(expected, actual)
240
+ end
241
+
242
+ def test_relationship_block_link_href
243
+ expected = {
244
+ data: [{ id: '1337', type: 'locations' }],
245
+ links: {
246
+ related: { href: '//example.com/locations/1337' }
247
+ }
248
+ }
249
+
250
+ model_attributes = { locations: [Location.new(id: 1337)] }
251
+ relationship_name = :locations
252
+ model = new_model(model_attributes)
253
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
254
+ has_many :locations do
255
+ link :related do
256
+ ids = object.locations.map(&:id).join(',')
257
+ href "//example.com/locations/#{ids}"
258
+ end
259
+ end
260
+ end
261
+ assert_equal(expected, actual)
262
+ end
263
+
264
+ def test_relationship_block_link_href_and_meta
265
+ expected = {
266
+ data: [{ id: '1337', type: 'posts' }],
267
+ links: {
268
+ related: {
269
+ href: '//example.com/posts/1337',
270
+ meta: { ids: '1337' }
271
+ }
272
+ }
273
+ }
274
+
275
+ model_attributes = { posts: [Post.new(id: 1337, comments: [], author: nil)] }
276
+ relationship_name = :posts
277
+ model = new_model(model_attributes)
278
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
279
+ has_many :posts do
280
+ link :related do
281
+ ids = object.posts.map(&:id).join(',')
282
+ href "//example.com/posts/#{ids}"
283
+ meta ids: ids
284
+ end
285
+ end
286
+ end
287
+ assert_equal(expected, actual)
288
+ end
289
+
290
+ def test_relationship_block_link_meta
291
+ expected = {
292
+ data: [{ id: '1337', type: 'comments' }],
293
+ links: {
294
+ self: {
295
+ meta: { ids: [1] }
296
+ }
297
+ }
298
+ }
299
+
300
+ model_attributes = { comments: [Comment.new(id: 1337)] }
301
+ relationship_name = :comments
302
+ model = new_model(model_attributes)
303
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
304
+ has_many :comments do
305
+ link :self do
306
+ meta ids: [1]
307
+ end
308
+ end
309
+ end
310
+ assert_equal(expected, actual)
311
+ end
312
+
313
+ def test_relationship_meta
314
+ expected = {
315
+ data: [{ id: 'from-serializer-method', type: 'roles' }],
316
+ meta: { count: 1 }
317
+ }
318
+
319
+ model_attributes = { roles: [Role.new(id: 'from-record')] }
320
+ relationship_name = :roles
321
+ model = new_model(model_attributes)
322
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
323
+ has_many :roles do |serializer|
324
+ meta count: object.roles.count
325
+ serializer.cached_roles
326
+ end
327
+ def cached_roles
328
+ [
329
+ Role.new(id: 'from-serializer-method')
330
+ ]
331
+ end
332
+ end
333
+ assert_equal(expected, actual)
334
+ end
335
+
336
+ def test_relationship_not_including_data
337
+ expected = {
338
+ links: { self: '//example.com/link_author/relationships/blog' }
339
+ }
340
+
341
+ model_attributes = { blog: Object }
342
+ relationship_name = :blog
343
+ model = new_model(model_attributes)
344
+ model.define_singleton_method(:read_attribute_for_serialization) do |attr|
345
+ fail 'should not be called' if attr == :blog
346
+ super(attr)
347
+ end
348
+ assert_nothing_raised do
349
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
350
+ has_one :blog do
351
+ link :self, '//example.com/link_author/relationships/blog'
352
+ include_data false
353
+ end
354
+ end
355
+ assert_equal(expected, actual)
356
+ end
357
+ end
358
+
359
+ def test_relationship_including_data_explicit
360
+ expected = {
361
+ data: { id: '1337', type: 'authors' },
362
+ meta: { name: 'Dan Brown' }
363
+ }
364
+
365
+ model_attributes = { reviewer: Author.new(id: 1337) }
366
+ relationship_name = :reviewer
367
+ model = new_model(model_attributes)
368
+ actual = build_serializer_and_serialize_relationship(model, relationship_name) do
369
+ belongs_to :reviewer do
370
+ meta name: 'Dan Brown'
371
+ include_data true
372
+ end
373
+ end
374
+ assert_equal(expected, actual)
375
+ end
376
+
377
+ private
378
+
379
+ def build_serializer_and_serialize_relationship(model, relationship_name, &block)
380
+ serializer_class = Class.new(ActiveModel::Serializer, &block)
381
+ hash = serializable(model, serializer: serializer_class, adapter: :json_api).serializable_hash
382
+ hash[:data][:relationships][relationship_name]
383
+ end
384
+
385
+ def new_model(model_attributes)
386
+ Class.new(ActiveModelSerializers::Model) do
387
+ attributes(*model_attributes.keys)
388
+
389
+ def self.name
390
+ 'TestModel'
391
+ end
392
+ end.new(model_attributes)
393
+ end
394
+ end
395
+ end
396
+ end
397
+ end
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ module Adapter
6
+ class JsonApi
7
+ class ResourceMetaTest < Minitest::Test
8
+ class MetaHashPostSerializer < ActiveModel::Serializer
9
+ attributes :id
10
+ meta stuff: 'value'
11
+ end
12
+
13
+ class MetaBlockPostSerializer < ActiveModel::Serializer
14
+ attributes :id
15
+ meta do
16
+ { comments_count: object.comments.count }
17
+ end
18
+ end
19
+
20
+ class MetaBlockPostBlankMetaSerializer < ActiveModel::Serializer
21
+ attributes :id
22
+ meta do
23
+ {}
24
+ end
25
+ end
26
+
27
+ class MetaBlockPostEmptyStringSerializer < ActiveModel::Serializer
28
+ attributes :id
29
+ meta do
30
+ ''
31
+ end
32
+ end
33
+
34
+ def setup
35
+ @post = Post.new(id: 1337, comments: [], author: nil)
36
+ end
37
+
38
+ def test_meta_hash_object_resource
39
+ hash = ActiveModelSerializers::SerializableResource.new(
40
+ @post,
41
+ serializer: MetaHashPostSerializer,
42
+ adapter: :json_api
43
+ ).serializable_hash
44
+ expected = {
45
+ stuff: 'value'
46
+ }
47
+ assert_equal(expected, hash[:data][:meta])
48
+ end
49
+
50
+ def test_meta_block_object_resource
51
+ hash = ActiveModelSerializers::SerializableResource.new(
52
+ @post,
53
+ serializer: MetaBlockPostSerializer,
54
+ adapter: :json_api
55
+ ).serializable_hash
56
+ expected = {
57
+ :"comments-count" => @post.comments.count
58
+ }
59
+ assert_equal(expected, hash[:data][:meta])
60
+ end
61
+
62
+ def test_meta_object_resource_in_array
63
+ post2 = Post.new(id: 1339, comments: [Comment.new])
64
+ posts = [@post, post2]
65
+ hash = ActiveModelSerializers::SerializableResource.new(
66
+ posts,
67
+ each_serializer: MetaBlockPostSerializer,
68
+ adapter: :json_api
69
+ ).serializable_hash
70
+ expected = {
71
+ data: [
72
+ { id: '1337', type: 'posts', meta: { :"comments-count" => 0 } },
73
+ { id: '1339', type: 'posts', meta: { :"comments-count" => 1 } }
74
+ ]
75
+ }
76
+ assert_equal(expected, hash)
77
+ end
78
+
79
+ def test_meta_object_blank_omitted
80
+ hash = ActiveModelSerializers::SerializableResource.new(
81
+ @post,
82
+ serializer: MetaBlockPostBlankMetaSerializer,
83
+ adapter: :json_api
84
+ ).serializable_hash
85
+ refute hash[:data].key? :meta
86
+ end
87
+
88
+ def test_meta_object_empty_string_omitted
89
+ hash = ActiveModelSerializers::SerializableResource.new(
90
+ @post,
91
+ serializer: MetaBlockPostEmptyStringSerializer,
92
+ adapter: :json_api
93
+ ).serializable_hash
94
+ refute hash[:data].key? :meta
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,82 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ class TopLevelJsonApiTest < ActiveSupport::TestCase
7
+ def setup
8
+ @author = Author.new(id: 1, name: 'Steve K.')
9
+ @author.bio = nil
10
+ @author.roles = []
11
+ @blog = Blog.new(id: 23, name: 'AMS Blog')
12
+ @post = Post.new(id: 42, title: 'New Post', body: 'Body')
13
+ @anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
14
+ @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
15
+ @post.comments = [@comment]
16
+ @post.blog = @blog
17
+ @anonymous_post.comments = []
18
+ @anonymous_post.blog = nil
19
+ @comment.post = @post
20
+ @comment.author = nil
21
+ @post.author = @author
22
+ @anonymous_post.author = nil
23
+ @blog = Blog.new(id: 1, name: 'My Blog!!')
24
+ @blog.writer = @author
25
+ @blog.articles = [@post, @anonymous_post]
26
+ @author.posts = []
27
+ end
28
+
29
+ def test_toplevel_jsonapi_defaults_to_false
30
+ assert_equal config.fetch(:jsonapi_include_toplevel_object), false
31
+ end
32
+
33
+ def test_disable_toplevel_jsonapi
34
+ with_config(jsonapi_include_toplevel_object: false) do
35
+ hash = serialize(@post)
36
+ assert_nil(hash[:jsonapi])
37
+ end
38
+ end
39
+
40
+ def test_enable_toplevel_jsonapi
41
+ with_config(jsonapi_include_toplevel_object: true) do
42
+ hash = serialize(@post)
43
+ refute_nil(hash[:jsonapi])
44
+ end
45
+ end
46
+
47
+ def test_default_toplevel_jsonapi_version
48
+ with_config(jsonapi_include_toplevel_object: true) do
49
+ hash = serialize(@post)
50
+ assert_equal('1.0', hash[:jsonapi][:version])
51
+ end
52
+ end
53
+
54
+ def test_toplevel_jsonapi_no_meta
55
+ with_config(jsonapi_include_toplevel_object: true) do
56
+ hash = serialize(@post)
57
+ assert_nil(hash[:jsonapi][:meta])
58
+ end
59
+ end
60
+
61
+ def test_toplevel_jsonapi_meta
62
+ new_config = {
63
+ jsonapi_include_toplevel_object: true,
64
+ jsonapi_toplevel_meta: {
65
+ 'copyright' => 'Copyright 2015 Example Corp.'
66
+ }
67
+ }
68
+ with_config(new_config) do
69
+ hash = serialize(@post)
70
+ assert_equal(new_config[:jsonapi_toplevel_meta], hash.fetch(:jsonapi).fetch(:meta))
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def serialize(resource, options = {})
77
+ serializable(resource, { adapter: :json_api }.merge!(options)).serializable_hash
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end