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,512 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ class KeyCaseTest < ActiveSupport::TestCase
7
+ class Post < ::Model
8
+ attributes :title, :body, :publish_at
9
+ associations :author, :comments
10
+ end
11
+ class Author < ::Model
12
+ attributes :first_name, :last_name
13
+ end
14
+ class Comment < ::Model
15
+ attributes :body
16
+ associations :author, :post
17
+ end
18
+
19
+ class PostSerializer < ActiveModel::Serializer
20
+ type 'posts'
21
+ attributes :title, :body, :publish_at
22
+ belongs_to :author
23
+ has_many :comments
24
+
25
+ link(:self) { post_url(object.id) }
26
+ link(:post_authors) { post_authors_url(object.id) }
27
+ link(:subscriber_comments) { post_comments_url(object.id) }
28
+
29
+ meta do
30
+ {
31
+ rating: 5,
32
+ favorite_count: 10
33
+ }
34
+ end
35
+ end
36
+
37
+ class AuthorSerializer < ActiveModel::Serializer
38
+ type 'authors'
39
+ attributes :first_name, :last_name
40
+ end
41
+
42
+ class CommentSerializer < ActiveModel::Serializer
43
+ type 'comments'
44
+ attributes :body
45
+ belongs_to :author
46
+ end
47
+
48
+ def mock_request(transform = nil)
49
+ context = Minitest::Mock.new
50
+ context.expect(:request_url, URI)
51
+ context.expect(:query_parameters, {})
52
+ context.expect(:url_helpers, Rails.application.routes.url_helpers)
53
+ @options = {}
54
+ @options[:key_transform] = transform if transform
55
+ @options[:serialization_context] = context
56
+ end
57
+
58
+ def setup
59
+ Rails.application.routes.draw do
60
+ resources :posts do
61
+ resources :authors
62
+ resources :comments
63
+ end
64
+ end
65
+ @publish_at = 1.day.from_now
66
+ @author = Author.new(id: 1, first_name: 'Bob', last_name: 'Jones')
67
+ @comment1 = Comment.new(id: 7, body: 'cool', author: @author)
68
+ @comment2 = Comment.new(id: 12, body: 'awesome', author: @author)
69
+ @post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1',
70
+ author: @author, comments: [@comment1, @comment2],
71
+ publish_at: @publish_at)
72
+ @comment1.post = @post
73
+ @comment2.post = @post
74
+ end
75
+
76
+ def test_success_document_transform_default
77
+ mock_request
78
+ serializer = PostSerializer.new(@post)
79
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
80
+ result = adapter.serializable_hash
81
+ assert_equal({
82
+ data: {
83
+ id: '1337',
84
+ type: 'posts',
85
+ attributes: {
86
+ title: 'Title 1',
87
+ body: 'Body 1',
88
+ :"publish-at" => @publish_at
89
+ },
90
+ relationships: {
91
+ author: {
92
+ data: { id: '1', type: 'authors' }
93
+ },
94
+ comments: {
95
+ data: [
96
+ { id: '7', type: 'comments' },
97
+ { id: '12', type: 'comments' }
98
+ ]
99
+ }
100
+ },
101
+ links: {
102
+ self: 'http://example.com/posts/1337',
103
+ :"post-authors" => 'http://example.com/posts/1337/authors',
104
+ :"subscriber-comments" => 'http://example.com/posts/1337/comments'
105
+ },
106
+ meta: { rating: 5, :"favorite-count" => 10 }
107
+ }
108
+ }, result)
109
+ end
110
+
111
+ def test_success_document_transform_global_config
112
+ mock_request
113
+ result = with_config(key_transform: :camel_lower) do
114
+ serializer = PostSerializer.new(@post)
115
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
116
+ adapter.serializable_hash
117
+ end
118
+ assert_equal({
119
+ data: {
120
+ id: '1337',
121
+ type: 'posts',
122
+ attributes: {
123
+ title: 'Title 1',
124
+ body: 'Body 1',
125
+ publishAt: @publish_at
126
+ },
127
+ relationships: {
128
+ author: {
129
+ data: { id: '1', type: 'authors' }
130
+ },
131
+ comments: {
132
+ data: [
133
+ { id: '7', type: 'comments' },
134
+ { id: '12', type: 'comments' }
135
+ ]
136
+ }
137
+ },
138
+ links: {
139
+ self: 'http://example.com/posts/1337',
140
+ postAuthors: 'http://example.com/posts/1337/authors',
141
+ subscriberComments: 'http://example.com/posts/1337/comments'
142
+ },
143
+ meta: { rating: 5, favoriteCount: 10 }
144
+ }
145
+ }, result)
146
+ end
147
+
148
+ def test_success_doc_transform_serialization_ctx_overrides_global
149
+ mock_request(:camel)
150
+ result = with_config(key_transform: :camel_lower) do
151
+ serializer = PostSerializer.new(@post)
152
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
153
+ adapter.serializable_hash
154
+ end
155
+ assert_equal({
156
+ Data: {
157
+ Id: '1337',
158
+ Type: 'Posts',
159
+ Attributes: {
160
+ Title: 'Title 1',
161
+ Body: 'Body 1',
162
+ PublishAt: @publish_at
163
+ },
164
+ Relationships: {
165
+ Author: {
166
+ Data: { Id: '1', Type: 'Authors' }
167
+ },
168
+ Comments: {
169
+ Data: [
170
+ { Id: '7', Type: 'Comments' },
171
+ { Id: '12', Type: 'Comments' }
172
+ ]
173
+ }
174
+ },
175
+ Links: {
176
+ Self: 'http://example.com/posts/1337',
177
+ PostAuthors: 'http://example.com/posts/1337/authors',
178
+ SubscriberComments: 'http://example.com/posts/1337/comments'
179
+ },
180
+ Meta: { Rating: 5, FavoriteCount: 10 }
181
+ }
182
+ }, result)
183
+ end
184
+
185
+ def test_success_document_transform_dash
186
+ mock_request(:dash)
187
+ serializer = PostSerializer.new(@post)
188
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
189
+ result = adapter.serializable_hash
190
+ assert_equal({
191
+ data: {
192
+ id: '1337',
193
+ type: 'posts',
194
+ attributes: {
195
+ title: 'Title 1',
196
+ body: 'Body 1',
197
+ :"publish-at" => @publish_at
198
+ },
199
+ relationships: {
200
+ author: {
201
+ data: { id: '1', type: 'authors' }
202
+ },
203
+ comments: {
204
+ data: [
205
+ { id: '7', type: 'comments' },
206
+ { id: '12', type: 'comments' }
207
+ ]
208
+ }
209
+ },
210
+ links: {
211
+ self: 'http://example.com/posts/1337',
212
+ :"post-authors" => 'http://example.com/posts/1337/authors',
213
+ :"subscriber-comments" => 'http://example.com/posts/1337/comments'
214
+ },
215
+ meta: { rating: 5, :"favorite-count" => 10 }
216
+ }
217
+ }, result)
218
+ end
219
+
220
+ def test_success_document_transform_unaltered
221
+ mock_request(:unaltered)
222
+ serializer = PostSerializer.new(@post)
223
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
224
+ result = adapter.serializable_hash
225
+ assert_equal({
226
+ data: {
227
+ id: '1337',
228
+ type: 'posts',
229
+ attributes: {
230
+ title: 'Title 1',
231
+ body: 'Body 1',
232
+ publish_at: @publish_at
233
+ },
234
+ relationships: {
235
+ author: {
236
+ data: { id: '1', type: 'authors' }
237
+ },
238
+ comments: {
239
+ data: [
240
+ { id: '7', type: 'comments' },
241
+ { id: '12', type: 'comments' }
242
+ ]
243
+ }
244
+ },
245
+ links: {
246
+ self: 'http://example.com/posts/1337',
247
+ post_authors: 'http://example.com/posts/1337/authors',
248
+ subscriber_comments: 'http://example.com/posts/1337/comments'
249
+ },
250
+ meta: { rating: 5, favorite_count: 10 }
251
+ }
252
+ }, result)
253
+ end
254
+
255
+ def test_success_document_transform_undefined
256
+ mock_request(:zoot)
257
+ serializer = PostSerializer.new(@post)
258
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
259
+ exception = assert_raises NoMethodError do
260
+ adapter.serializable_hash
261
+ end
262
+ assert_match(/undefined method.*zoot/, exception.message)
263
+ end
264
+
265
+ def test_success_document_transform_camel
266
+ mock_request(:camel)
267
+ serializer = PostSerializer.new(@post)
268
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
269
+ result = adapter.serializable_hash
270
+ assert_equal({
271
+ Data: {
272
+ Id: '1337',
273
+ Type: 'Posts',
274
+ Attributes: {
275
+ Title: 'Title 1',
276
+ Body: 'Body 1',
277
+ PublishAt: @publish_at
278
+ },
279
+ Relationships: {
280
+ Author: {
281
+ Data: { Id: '1', Type: 'Authors' }
282
+ },
283
+ Comments: {
284
+ Data: [
285
+ { Id: '7', Type: 'Comments' },
286
+ { Id: '12', Type: 'Comments' }
287
+ ]
288
+ }
289
+ },
290
+ Links: {
291
+ Self: 'http://example.com/posts/1337',
292
+ PostAuthors: 'http://example.com/posts/1337/authors',
293
+ SubscriberComments: 'http://example.com/posts/1337/comments'
294
+ },
295
+ Meta: { Rating: 5, FavoriteCount: 10 }
296
+ }
297
+ }, result)
298
+ end
299
+
300
+ def test_success_document_transform_camel_lower
301
+ mock_request(:camel_lower)
302
+ serializer = PostSerializer.new(@post)
303
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
304
+ result = adapter.serializable_hash
305
+ assert_equal({
306
+ data: {
307
+ id: '1337',
308
+ type: 'posts',
309
+ attributes: {
310
+ title: 'Title 1',
311
+ body: 'Body 1',
312
+ publishAt: @publish_at
313
+ },
314
+ relationships: {
315
+ author: {
316
+ data: { id: '1', type: 'authors' }
317
+ },
318
+ comments: {
319
+ data: [
320
+ { id: '7', type: 'comments' },
321
+ { id: '12', type: 'comments' }
322
+ ]
323
+ }
324
+ },
325
+ links: {
326
+ self: 'http://example.com/posts/1337',
327
+ postAuthors: 'http://example.com/posts/1337/authors',
328
+ subscriberComments: 'http://example.com/posts/1337/comments'
329
+ },
330
+ meta: { rating: 5, favoriteCount: 10 }
331
+ }
332
+ }, result)
333
+ end
334
+
335
+ def test_error_document_transform_default
336
+ mock_request
337
+ resource = ModelWithErrors.new
338
+ resource.errors.add(:published_at, 'must be in the future')
339
+ resource.errors.add(:title, 'must be longer')
340
+ serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
341
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
342
+ result = adapter.serializable_hash
343
+ expected_errors_object = {
344
+ errors: [
345
+ {
346
+ source: { pointer: '/data/attributes/published-at' },
347
+ detail: 'must be in the future'
348
+ },
349
+ {
350
+ source: { pointer: '/data/attributes/title' },
351
+ detail: 'must be longer'
352
+ }
353
+ ]
354
+ }
355
+ assert_equal expected_errors_object, result
356
+ end
357
+
358
+ def test_error_document_transform_global_config
359
+ mock_request
360
+ result = with_config(key_transform: :camel) do
361
+ resource = ModelWithErrors.new
362
+ resource.errors.add(:published_at, 'must be in the future')
363
+ resource.errors.add(:title, 'must be longer')
364
+ serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
365
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
366
+ adapter.serializable_hash
367
+ end
368
+ expected_errors_object = {
369
+ Errors: [
370
+ {
371
+ Source: { Pointer: '/data/attributes/PublishedAt' },
372
+ Detail: 'must be in the future'
373
+ },
374
+ {
375
+ Source: { Pointer: '/data/attributes/Title' },
376
+ Detail: 'must be longer'
377
+ }
378
+ ]
379
+ }
380
+ assert_equal expected_errors_object, result
381
+ end
382
+
383
+ def test_error_document_transform_serialization_ctx_overrides_global
384
+ mock_request(:camel)
385
+ result = with_config(key_transform: :camel_lower) do
386
+ resource = ModelWithErrors.new
387
+ resource.errors.add(:published_at, 'must be in the future')
388
+ resource.errors.add(:title, 'must be longer')
389
+ serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
390
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
391
+ adapter.serializable_hash
392
+ end
393
+ expected_errors_object = {
394
+ Errors: [
395
+ {
396
+ Source: { Pointer: '/data/attributes/PublishedAt' },
397
+ Detail: 'must be in the future'
398
+ },
399
+ {
400
+ Source: { Pointer: '/data/attributes/Title' },
401
+ Detail: 'must be longer'
402
+ }
403
+ ]
404
+ }
405
+ assert_equal expected_errors_object, result
406
+ end
407
+
408
+ def test_error_document_transform_dash
409
+ mock_request(:dash)
410
+
411
+ resource = ModelWithErrors.new
412
+ resource.errors.add(:published_at, 'must be in the future')
413
+ resource.errors.add(:title, 'must be longer')
414
+
415
+ serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
416
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
417
+ result = adapter.serializable_hash
418
+
419
+ expected_errors_object = {
420
+ errors: [
421
+ {
422
+ source: { pointer: '/data/attributes/published-at' },
423
+ detail: 'must be in the future'
424
+ },
425
+ {
426
+ source: { pointer: '/data/attributes/title' },
427
+ detail: 'must be longer'
428
+ }
429
+ ]
430
+ }
431
+ assert_equal expected_errors_object, result
432
+ end
433
+
434
+ def test_error_document_transform_unaltered
435
+ mock_request(:unaltered)
436
+
437
+ resource = ModelWithErrors.new
438
+ resource.errors.add(:published_at, 'must be in the future')
439
+ resource.errors.add(:title, 'must be longer')
440
+
441
+ serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
442
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
443
+ result = adapter.serializable_hash
444
+
445
+ expected_errors_object = {
446
+ errors: [
447
+ { source: { pointer: '/data/attributes/published_at' }, detail: 'must be in the future' },
448
+ { source: { pointer: '/data/attributes/title' }, detail: 'must be longer' }
449
+ ]
450
+ }
451
+ assert_equal expected_errors_object, result
452
+ end
453
+
454
+ def test_error_document_transform_undefined
455
+ mock_request(:krazy)
456
+
457
+ resource = ModelWithErrors.new
458
+ resource.errors.add(:published_at, 'must be in the future')
459
+ resource.errors.add(:title, 'must be longer')
460
+
461
+ serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
462
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
463
+
464
+ exception = assert_raises NoMethodError do
465
+ adapter.serializable_hash
466
+ end
467
+ assert_match(/undefined method.*krazy/, exception.message)
468
+ end
469
+
470
+ def test_error_document_transform_camel
471
+ mock_request(:camel)
472
+
473
+ resource = ModelWithErrors.new
474
+ resource.errors.add(:published_at, 'must be in the future')
475
+ resource.errors.add(:title, 'must be longer')
476
+
477
+ serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
478
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
479
+ result = adapter.serializable_hash
480
+
481
+ expected_errors_object = {
482
+ Errors: [
483
+ { Source: { Pointer: '/data/attributes/PublishedAt' }, Detail: 'must be in the future' },
484
+ { Source: { Pointer: '/data/attributes/Title' }, Detail: 'must be longer' }
485
+ ]
486
+ }
487
+ assert_equal expected_errors_object, result
488
+ end
489
+
490
+ def test_error_document_transform_camel_lower
491
+ mock_request(:camel_lower)
492
+
493
+ resource = ModelWithErrors.new
494
+ resource.errors.add(:published_at, 'must be in the future')
495
+ resource.errors.add(:title, 'must be longer')
496
+
497
+ serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
498
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
499
+ result = adapter.serializable_hash
500
+
501
+ expected_errors_object = {
502
+ errors: [
503
+ { source: { pointer: '/data/attributes/publishedAt' }, detail: 'must be in the future' },
504
+ { source: { pointer: '/data/attributes/title' }, detail: 'must be longer' }
505
+ ]
506
+ }
507
+ assert_equal expected_errors_object, result
508
+ end
509
+ end
510
+ end
511
+ end
512
+ end