active_model_serializers 0.8.3 → 0.10.0

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 (232) hide show
  1. checksums.yaml +4 -4
  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 +104 -0
  6. data/.rubocop_todo.yml +167 -0
  7. data/.simplecov +110 -0
  8. data/.travis.yml +39 -24
  9. data/CHANGELOG.md +465 -6
  10. data/CONTRIBUTING.md +105 -0
  11. data/Gemfile +50 -1
  12. data/{MIT-LICENSE.txt → MIT-LICENSE} +3 -2
  13. data/README.md +102 -590
  14. data/Rakefile +93 -8
  15. data/active_model_serializers.gemspec +65 -23
  16. data/appveyor.yml +24 -0
  17. data/bin/bench +171 -0
  18. data/bin/bench_regression +316 -0
  19. data/bin/serve_benchmark +39 -0
  20. data/docs/ARCHITECTURE.md +126 -0
  21. data/docs/README.md +40 -0
  22. data/docs/STYLE.md +58 -0
  23. data/docs/general/adapters.md +245 -0
  24. data/docs/general/caching.md +52 -0
  25. data/docs/general/configuration_options.md +100 -0
  26. data/docs/general/deserialization.md +100 -0
  27. data/docs/general/getting_started.md +133 -0
  28. data/docs/general/instrumentation.md +40 -0
  29. data/docs/general/key_transforms.md +40 -0
  30. data/docs/general/logging.md +14 -0
  31. data/docs/general/rendering.md +255 -0
  32. data/docs/general/serializers.md +372 -0
  33. data/docs/how-open-source-maintained.jpg +0 -0
  34. data/docs/howto/add_pagination_links.md +139 -0
  35. data/docs/howto/add_root_key.md +51 -0
  36. data/docs/howto/outside_controller_use.md +58 -0
  37. data/docs/howto/passing_arbitrary_options.md +27 -0
  38. data/docs/howto/serialize_poro.md +32 -0
  39. data/docs/howto/test.md +152 -0
  40. data/docs/integrations/ember-and-json-api.md +112 -0
  41. data/docs/integrations/grape.md +19 -0
  42. data/docs/jsonapi/errors.md +56 -0
  43. data/docs/jsonapi/schema/schema.json +366 -0
  44. data/docs/jsonapi/schema.md +151 -0
  45. data/docs/rfcs/0000-namespace.md +106 -0
  46. data/docs/rfcs/template.md +15 -0
  47. data/lib/action_controller/serialization.rb +31 -36
  48. data/lib/active_model/serializable_resource.rb +11 -0
  49. data/lib/active_model/serializer/adapter/attributes.rb +15 -0
  50. data/lib/active_model/serializer/adapter/base.rb +16 -0
  51. data/lib/active_model/serializer/adapter/json.rb +15 -0
  52. data/lib/active_model/serializer/adapter/json_api.rb +15 -0
  53. data/lib/active_model/serializer/adapter/null.rb +15 -0
  54. data/lib/active_model/serializer/adapter.rb +24 -0
  55. data/lib/active_model/serializer/array_serializer.rb +9 -0
  56. data/lib/active_model/serializer/association.rb +19 -0
  57. data/lib/active_model/serializer/associations.rb +87 -220
  58. data/lib/active_model/serializer/attribute.rb +25 -0
  59. data/lib/active_model/serializer/attributes.rb +82 -0
  60. data/lib/active_model/serializer/belongs_to_reflection.rb +10 -0
  61. data/lib/active_model/serializer/caching.rb +333 -0
  62. data/lib/active_model/serializer/collection_reflection.rb +7 -0
  63. data/lib/active_model/serializer/collection_serializer.rb +64 -0
  64. data/lib/active_model/serializer/configuration.rb +35 -0
  65. data/lib/active_model/serializer/error_serializer.rb +10 -0
  66. data/lib/active_model/serializer/errors_serializer.rb +27 -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 +10 -0
  71. data/lib/active_model/serializer/include_tree.rb +111 -0
  72. data/lib/active_model/serializer/links.rb +35 -0
  73. data/lib/active_model/serializer/lint.rb +146 -0
  74. data/lib/active_model/serializer/meta.rb +29 -0
  75. data/lib/active_model/serializer/null.rb +17 -0
  76. data/lib/active_model/serializer/reflection.rb +147 -0
  77. data/lib/active_model/serializer/singular_reflection.rb +7 -0
  78. data/lib/active_model/serializer/type.rb +25 -0
  79. data/lib/active_model/{serializers → serializer}/version.rb +1 -1
  80. data/lib/active_model/serializer.rb +158 -481
  81. data/lib/active_model_serializers/adapter/attributes.rb +76 -0
  82. data/lib/active_model_serializers/adapter/base.rb +83 -0
  83. data/lib/active_model_serializers/adapter/json.rb +21 -0
  84. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +213 -0
  85. data/lib/active_model_serializers/adapter/json_api/error.rb +96 -0
  86. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +49 -0
  87. data/lib/active_model_serializers/adapter/json_api/link.rb +83 -0
  88. data/lib/active_model_serializers/adapter/json_api/meta.rb +37 -0
  89. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +62 -0
  90. data/lib/active_model_serializers/adapter/json_api/relationship.rb +52 -0
  91. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +37 -0
  92. data/lib/active_model_serializers/adapter/json_api.rb +516 -0
  93. data/lib/active_model_serializers/adapter/null.rb +9 -0
  94. data/lib/active_model_serializers/adapter.rb +92 -0
  95. data/lib/active_model_serializers/callbacks.rb +55 -0
  96. data/lib/active_model_serializers/deprecate.rb +55 -0
  97. data/lib/active_model_serializers/deserialization.rb +13 -0
  98. data/lib/active_model_serializers/json_pointer.rb +14 -0
  99. data/lib/active_model_serializers/key_transform.rb +70 -0
  100. data/lib/active_model_serializers/logging.rb +122 -0
  101. data/lib/active_model_serializers/model.rb +49 -0
  102. data/lib/active_model_serializers/railtie.rb +46 -0
  103. data/lib/active_model_serializers/register_jsonapi_renderer.rb +65 -0
  104. data/lib/active_model_serializers/serializable_resource.rb +81 -0
  105. data/lib/active_model_serializers/serialization_context.rb +32 -0
  106. data/lib/active_model_serializers/test/schema.rb +138 -0
  107. data/lib/active_model_serializers/test/serializer.rb +125 -0
  108. data/lib/active_model_serializers/test.rb +7 -0
  109. data/lib/active_model_serializers.rb +32 -89
  110. data/lib/generators/rails/USAGE +6 -0
  111. data/lib/generators/rails/resource_override.rb +10 -0
  112. data/lib/generators/rails/serializer_generator.rb +36 -0
  113. data/lib/generators/rails/templates/serializer.rb.erb +8 -0
  114. data/lib/grape/active_model_serializers.rb +14 -0
  115. data/lib/grape/formatters/active_model_serializers.rb +15 -0
  116. data/lib/grape/helpers/active_model_serializers.rb +16 -0
  117. data/test/action_controller/adapter_selector_test.rb +53 -0
  118. data/test/action_controller/explicit_serializer_test.rb +134 -0
  119. data/test/action_controller/json/include_test.rb +167 -0
  120. data/test/action_controller/json_api/deserialization_test.rb +112 -0
  121. data/test/action_controller/json_api/errors_test.rb +41 -0
  122. data/test/action_controller/json_api/linked_test.rb +197 -0
  123. data/test/action_controller/json_api/pagination_test.rb +116 -0
  124. data/test/action_controller/json_api/transform_test.rb +181 -0
  125. data/test/action_controller/serialization_scope_name_test.rb +229 -0
  126. data/test/action_controller/serialization_test.rb +469 -0
  127. data/test/active_model_serializers/adapter_for_test.rb +208 -0
  128. data/test/active_model_serializers/json_pointer_test.rb +20 -0
  129. data/test/active_model_serializers/key_transform_test.rb +263 -0
  130. data/test/active_model_serializers/logging_test.rb +77 -0
  131. data/test/active_model_serializers/model_test.rb +9 -0
  132. data/test/active_model_serializers/railtie_test_isolated.rb +63 -0
  133. data/test/active_model_serializers/serialization_context_test_isolated.rb +58 -0
  134. data/test/active_model_serializers/test/schema_test.rb +130 -0
  135. data/test/active_model_serializers/test/serializer_test.rb +62 -0
  136. data/test/active_record_test.rb +9 -0
  137. data/test/adapter/deprecation_test.rb +100 -0
  138. data/test/adapter/json/belongs_to_test.rb +45 -0
  139. data/test/adapter/json/collection_test.rb +90 -0
  140. data/test/adapter/json/has_many_test.rb +45 -0
  141. data/test/adapter/json/transform_test.rb +93 -0
  142. data/test/adapter/json_api/belongs_to_test.rb +155 -0
  143. data/test/adapter/json_api/collection_test.rb +95 -0
  144. data/test/adapter/json_api/errors_test.rb +78 -0
  145. data/test/adapter/json_api/fields_test.rb +87 -0
  146. data/test/adapter/json_api/has_many_embed_ids_test.rb +43 -0
  147. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +96 -0
  148. data/test/adapter/json_api/has_many_test.rb +144 -0
  149. data/test/adapter/json_api/has_one_test.rb +80 -0
  150. data/test/adapter/json_api/json_api_test.rb +35 -0
  151. data/test/adapter/json_api/linked_test.rb +392 -0
  152. data/test/adapter/json_api/links_test.rb +93 -0
  153. data/test/adapter/json_api/pagination_links_test.rb +166 -0
  154. data/test/adapter/json_api/parse_test.rb +137 -0
  155. data/test/adapter/json_api/relationship_test.rb +161 -0
  156. data/test/adapter/json_api/relationships_test.rb +199 -0
  157. data/test/adapter/json_api/resource_identifier_test.rb +85 -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 +502 -0
  161. data/test/adapter/json_api/type_test.rb +61 -0
  162. data/test/adapter/json_test.rb +45 -0
  163. data/test/adapter/null_test.rb +23 -0
  164. data/test/adapter/polymorphic_test.rb +171 -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_caching.rb +119 -0
  170. data/test/benchmark/bm_transform.rb +34 -0
  171. data/test/benchmark/config.ru +3 -0
  172. data/test/benchmark/controllers.rb +84 -0
  173. data/test/benchmark/fixtures.rb +219 -0
  174. data/test/cache_test.rb +485 -0
  175. data/test/collection_serializer_test.rb +110 -0
  176. data/test/fixtures/active_record.rb +78 -0
  177. data/test/fixtures/poro.rb +282 -0
  178. data/test/generators/scaffold_controller_generator_test.rb +24 -0
  179. data/test/generators/serializer_generator_test.rb +57 -0
  180. data/test/grape_test.rb +82 -0
  181. data/test/include_tree/from_include_args_test.rb +26 -0
  182. data/test/include_tree/from_string_test.rb +94 -0
  183. data/test/include_tree/include_args_to_hash_test.rb +64 -0
  184. data/test/lint_test.rb +49 -0
  185. data/test/logger_test.rb +18 -0
  186. data/test/poro_test.rb +9 -0
  187. data/test/serializable_resource_test.rb +83 -0
  188. data/test/serializers/association_macros_test.rb +36 -0
  189. data/test/serializers/associations_test.rb +295 -0
  190. data/test/serializers/attribute_test.rb +151 -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 +196 -0
  196. data/test/serializers/options_test.rb +21 -0
  197. data/test/serializers/read_attribute_for_serialization_test.rb +79 -0
  198. data/test/serializers/root_test.rb +21 -0
  199. data/test/serializers/serialization_test.rb +55 -0
  200. data/test/serializers/serializer_for_test.rb +134 -0
  201. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  202. data/test/support/isolated_unit.rb +79 -0
  203. data/test/support/rails5_shims.rb +47 -0
  204. data/test/support/rails_app.rb +45 -0
  205. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  206. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +6 -0
  207. data/test/support/schemas/custom/show.json +7 -0
  208. data/test/support/schemas/hyper_schema.json +93 -0
  209. data/test/support/schemas/render_using_json_api.json +43 -0
  210. data/test/support/schemas/simple_json_pointers.json +10 -0
  211. data/test/support/serialization_testing.rb +53 -0
  212. data/test/test_helper.rb +48 -23
  213. metadata +449 -43
  214. data/DESIGN.textile +0 -586
  215. data/Gemfile.edge +0 -9
  216. data/bench/perf.rb +0 -43
  217. data/cruft.md +0 -19
  218. data/lib/active_model/array_serializer.rb +0 -104
  219. data/lib/active_record/serializer_override.rb +0 -16
  220. data/lib/generators/resource_override.rb +0 -13
  221. data/lib/generators/serializer/USAGE +0 -9
  222. data/lib/generators/serializer/serializer_generator.rb +0 -42
  223. data/lib/generators/serializer/templates/serializer.rb +0 -19
  224. data/test/association_test.rb +0 -592
  225. data/test/caching_test.rb +0 -96
  226. data/test/generators_test.rb +0 -85
  227. data/test/no_serialization_scope_test.rb +0 -34
  228. data/test/serialization_scope_name_test.rb +0 -67
  229. data/test/serialization_test.rb +0 -392
  230. data/test/serializer_support_test.rb +0 -51
  231. data/test/serializer_test.rb +0 -1465
  232. data/test/test_fakes.rb +0 -217
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+ module ActiveModel
3
+ class Serializer
4
+ module Adapter
5
+ class DeprecationTest < ActiveSupport::TestCase
6
+ class PostSerializer < ActiveModel::Serializer
7
+ attribute :body
8
+ end
9
+ setup do
10
+ post = Post.new(id: 1, body: 'Hello')
11
+ @serializer = PostSerializer.new(post)
12
+ end
13
+
14
+ def test_null_adapter_serialization_deprecation
15
+ expected = {}
16
+ assert_deprecated do
17
+ assert_equal(expected, Null.new(@serializer).as_json)
18
+ end
19
+ end
20
+
21
+ def test_json_adapter_serialization_deprecation
22
+ expected = { post: { body: 'Hello' } }
23
+ assert_deprecated do
24
+ assert_equal(expected, Json.new(@serializer).as_json)
25
+ end
26
+ end
27
+
28
+ def test_jsonapi_adapter_serialization_deprecation
29
+ expected = {
30
+ data: {
31
+ id: '1',
32
+ type: 'posts',
33
+ attributes: {
34
+ body: 'Hello'
35
+ }
36
+ }
37
+ }
38
+ assert_deprecated do
39
+ assert_equal(expected, JsonApi.new(@serializer).as_json)
40
+ end
41
+ end
42
+
43
+ def test_attributes_adapter_serialization_deprecation
44
+ expected = { body: 'Hello' }
45
+ assert_deprecated do
46
+ assert_equal(expected, Attributes.new(@serializer).as_json)
47
+ end
48
+ end
49
+
50
+ def test_adapter_create_deprecation
51
+ assert_deprecated do
52
+ Adapter.create(@serializer)
53
+ end
54
+ end
55
+
56
+ def test_adapter_adapter_map_deprecation
57
+ assert_deprecated do
58
+ Adapter.adapter_map
59
+ end
60
+ end
61
+
62
+ def test_adapter_adapters_deprecation
63
+ assert_deprecated do
64
+ Adapter.adapters
65
+ end
66
+ end
67
+
68
+ def test_adapter_adapter_class_deprecation
69
+ assert_deprecated do
70
+ Adapter.adapter_class(:json_api)
71
+ end
72
+ end
73
+
74
+ def test_adapter_register_deprecation
75
+ assert_deprecated do
76
+ begin
77
+ Adapter.register(:test, Class.new)
78
+ ensure
79
+ Adapter.adapter_map.delete('test')
80
+ end
81
+ end
82
+ end
83
+
84
+ def test_adapter_lookup_deprecation
85
+ assert_deprecated do
86
+ Adapter.lookup(:json_api)
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def assert_deprecated
93
+ assert_output(nil, /deprecated/) do
94
+ yield
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class Json
6
+ class BelongsToTest < ActiveSupport::TestCase
7
+ def setup
8
+ @post = Post.new(id: 42, title: 'New Post', body: 'Body')
9
+ @anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
10
+ @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
11
+ @post.comments = [@comment]
12
+ @anonymous_post.comments = []
13
+ @comment.post = @post
14
+ @comment.author = nil
15
+ @anonymous_post.author = nil
16
+ @blog = Blog.new(id: 1, name: 'My Blog!!')
17
+ @post.blog = @blog
18
+ @anonymous_post.blog = nil
19
+
20
+ @serializer = CommentSerializer.new(@comment)
21
+ @adapter = ActiveModelSerializers::Adapter::Json.new(@serializer)
22
+ ActionController::Base.cache_store.clear
23
+ end
24
+
25
+ def test_includes_post
26
+ assert_equal({ id: 42, title: 'New Post', body: 'Body' }, @adapter.serializable_hash[:comment][:post])
27
+ end
28
+
29
+ def test_include_nil_author
30
+ serializer = PostSerializer.new(@anonymous_post)
31
+ adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
32
+
33
+ assert_equal({ post: { title: 'Hello!!', body: 'Hello, world!!', id: 43, comments: [], blog: { id: 999, name: 'Custom blog' }, author: nil } }, adapter.serializable_hash)
34
+ end
35
+
36
+ def test_include_nil_author_with_specified_serializer
37
+ serializer = PostPreviewSerializer.new(@anonymous_post)
38
+ adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
39
+
40
+ assert_equal({ post: { title: 'Hello!!', body: 'Hello, world!!', id: 43, comments: [], author: nil } }, adapter.serializable_hash)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,90 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class Json
6
+ class Collection < ActiveSupport::TestCase
7
+ def setup
8
+ @author = Author.new(id: 1, name: 'Steve K.')
9
+ @first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
10
+ @second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
11
+ @first_post.comments = []
12
+ @second_post.comments = []
13
+ @first_post.author = @author
14
+ @second_post.author = @author
15
+ @blog = Blog.new(id: 1, name: 'My Blog!!')
16
+ @first_post.blog = @blog
17
+ @second_post.blog = nil
18
+
19
+ ActionController::Base.cache_store.clear
20
+ end
21
+
22
+ def test_with_serializer_option
23
+ @blog.special_attribute = 'Special'
24
+ @blog.articles = [@first_post, @second_post]
25
+ serializer = ActiveModel::Serializer::CollectionSerializer.new([@blog], serializer: CustomBlogSerializer)
26
+ adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
27
+
28
+ expected = { blogs: [{
29
+ id: 1,
30
+ special_attribute: 'Special',
31
+ articles: [{ id: 1, title: 'Hello!!', body: 'Hello, world!!' }, { id: 2, title: 'New Post', body: 'Body' }]
32
+ }] }
33
+ assert_equal expected, adapter.serializable_hash
34
+ end
35
+
36
+ def test_include_multiple_posts
37
+ serializer = ActiveModel::Serializer::CollectionSerializer.new([@first_post, @second_post])
38
+ adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
39
+
40
+ expected = { posts: [{
41
+ title: 'Hello!!',
42
+ body: 'Hello, world!!',
43
+ id: 1,
44
+ comments: [],
45
+ author: {
46
+ id: 1,
47
+ name: 'Steve K.'
48
+ },
49
+ blog: {
50
+ id: 999,
51
+ name: 'Custom blog'
52
+ }
53
+ }, {
54
+ title: 'New Post',
55
+ body: 'Body',
56
+ id: 2,
57
+ comments: [],
58
+ author: {
59
+ id: 1,
60
+ name: 'Steve K.'
61
+ },
62
+ blog: {
63
+ id: 999,
64
+ name: 'Custom blog'
65
+ }
66
+ }] }
67
+ assert_equal expected, adapter.serializable_hash
68
+ end
69
+
70
+ def test_root_is_underscored
71
+ virtual_value = VirtualValue.new(id: 1)
72
+ serializer = ActiveModel::Serializer::CollectionSerializer.new([virtual_value])
73
+ adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
74
+
75
+ assert_equal 1, adapter.serializable_hash[:virtual_values].length
76
+ end
77
+
78
+ def test_include_option
79
+ serializer = ActiveModel::Serializer::CollectionSerializer.new([@first_post, @second_post])
80
+ adapter = ActiveModelSerializers::Adapter::Json.new(serializer, include: '')
81
+ actual = adapter.serializable_hash
82
+ expected = { posts: [{ id: 1, title: 'Hello!!', body: 'Hello, world!!' },
83
+ { id: 2, title: 'New Post', body: 'Body' }] }
84
+
85
+ assert_equal(expected, actual)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class Json
6
+ class HasManyTestTest < ActiveSupport::TestCase
7
+ def setup
8
+ ActionController::Base.cache_store.clear
9
+ @author = Author.new(id: 1, name: 'Steve K.')
10
+ @post = Post.new(id: 42, title: 'New Post', body: 'Body')
11
+ @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
12
+ @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
13
+ @post.comments = [@first_comment, @second_comment]
14
+ @post.author = @author
15
+ @first_comment.post = @post
16
+ @second_comment.post = @post
17
+ @blog = Blog.new(id: 1, name: 'My Blog!!')
18
+ @post.blog = @blog
19
+ @tag = Tag.new(id: 1, name: '#hash_tag')
20
+ @post.tags = [@tag]
21
+ end
22
+
23
+ def test_has_many
24
+ serializer = PostSerializer.new(@post)
25
+ adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
26
+ assert_equal([
27
+ { id: 1, body: 'ZOMG A COMMENT' },
28
+ { id: 2, body: 'ZOMG ANOTHER COMMENT' }
29
+ ], adapter.serializable_hash[:post][:comments])
30
+ end
31
+
32
+ def test_has_many_with_no_serializer
33
+ serializer = PostWithTagsSerializer.new(@post)
34
+ adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
35
+ assert_equal({
36
+ id: 42,
37
+ tags: [
38
+ { 'id' => 1, 'name' => '#hash_tag' }
39
+ ]
40
+ }.to_json, adapter.serializable_hash[:post].to_json)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,93 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class Json
6
+ class KeyCaseTest < ActiveSupport::TestCase
7
+ def mock_request(key_transform = nil)
8
+ context = Minitest::Mock.new
9
+ context.expect(:request_url, URI)
10
+ context.expect(:query_parameters, {})
11
+ options = {}
12
+ options[:key_transform] = key_transform if key_transform
13
+ options[:serialization_context] = context
14
+ serializer = CustomBlogSerializer.new(@blog)
15
+ @adapter = ActiveModelSerializers::Adapter::Json.new(serializer, options)
16
+ end
17
+
18
+ Post = Class.new(::Model)
19
+ class PostSerializer < ActiveModel::Serializer
20
+ attributes :id, :title, :body, :publish_at
21
+ end
22
+
23
+ setup do
24
+ ActionController::Base.cache_store.clear
25
+ @blog = Blog.new(id: 1, name: 'My Blog!!', special_attribute: 'neat')
26
+ end
27
+
28
+ def test_transform_default
29
+ mock_request
30
+ assert_equal({
31
+ blog: { id: 1, special_attribute: 'neat', articles: nil }
32
+ }, @adapter.serializable_hash)
33
+ end
34
+
35
+ def test_transform_global_config
36
+ mock_request
37
+ result = with_config(key_transform: :camel_lower) do
38
+ @adapter.serializable_hash
39
+ end
40
+ assert_equal({
41
+ blog: { id: 1, specialAttribute: 'neat', articles: nil }
42
+ }, result)
43
+ end
44
+
45
+ def test_transform_serialization_ctx_overrides_global_config
46
+ mock_request(:camel)
47
+ result = with_config(key_transform: :camel_lower) do
48
+ @adapter.serializable_hash
49
+ end
50
+ assert_equal({
51
+ Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
52
+ }, result)
53
+ end
54
+
55
+ def test_transform_undefined
56
+ mock_request(:blam)
57
+ result = nil
58
+ assert_raises NoMethodError do
59
+ result = @adapter.serializable_hash
60
+ end
61
+ end
62
+
63
+ def test_transform_dash
64
+ mock_request(:dash)
65
+ assert_equal({
66
+ blog: { id: 1, :"special-attribute" => 'neat', articles: nil }
67
+ }, @adapter.serializable_hash)
68
+ end
69
+
70
+ def test_transform_unaltered
71
+ mock_request(:unaltered)
72
+ assert_equal({
73
+ blog: { id: 1, special_attribute: 'neat', articles: nil }
74
+ }, @adapter.serializable_hash)
75
+ end
76
+
77
+ def test_transform_camel
78
+ mock_request(:camel)
79
+ assert_equal({
80
+ Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
81
+ }, @adapter.serializable_hash)
82
+ end
83
+
84
+ def test_transform_camel_lower
85
+ mock_request(:camel_lower)
86
+ assert_equal({
87
+ blog: { id: 1, specialAttribute: 'neat', articles: nil }
88
+ }, @adapter.serializable_hash)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,155 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ class BelongsToTest < 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
+
28
+ @serializer = CommentSerializer.new(@comment)
29
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
30
+ ActionController::Base.cache_store.clear
31
+ end
32
+
33
+ def test_includes_post_id
34
+ expected = { data: { type: 'posts', id: '42' } }
35
+
36
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:post])
37
+ end
38
+
39
+ def test_includes_linked_post
40
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:post])
41
+ expected = [{
42
+ id: '42',
43
+ type: 'posts',
44
+ attributes: {
45
+ title: 'New Post',
46
+ body: 'Body'
47
+ },
48
+ relationships: {
49
+ comments: { data: [{ type: 'comments', id: '1' }] },
50
+ blog: { data: { type: 'blogs', id: '999' } },
51
+ author: { data: { type: 'authors', id: '1' } }
52
+ }
53
+ }]
54
+ assert_equal expected, @adapter.serializable_hash[:included]
55
+ end
56
+
57
+ def test_limiting_linked_post_fields
58
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:post], fields: { post: [:title, :comments, :blog, :author] })
59
+ expected = [{
60
+ id: '42',
61
+ type: 'posts',
62
+ attributes: {
63
+ title: 'New Post'
64
+ },
65
+ relationships: {
66
+ comments: { data: [{ type: 'comments', id: '1' }] },
67
+ blog: { data: { type: 'blogs', id: '999' } },
68
+ author: { data: { type: 'authors', id: '1' } }
69
+ }
70
+ }]
71
+ assert_equal expected, @adapter.serializable_hash[:included]
72
+ end
73
+
74
+ def test_include_nil_author
75
+ serializer = PostSerializer.new(@anonymous_post)
76
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
77
+
78
+ assert_equal({ comments: { data: [] }, blog: { data: { type: 'blogs', id: '999' } }, author: { data: nil } }, adapter.serializable_hash[:data][:relationships])
79
+ end
80
+
81
+ def test_include_type_for_association_when_different_than_name
82
+ serializer = BlogSerializer.new(@blog)
83
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
84
+ relationships = adapter.serializable_hash[:data][:relationships]
85
+ expected = {
86
+ writer: {
87
+ data: {
88
+ type: 'authors',
89
+ id: '1'
90
+ }
91
+ },
92
+ articles: {
93
+ data: [
94
+ {
95
+ type: 'posts',
96
+ id: '42'
97
+ },
98
+ {
99
+ type: 'posts',
100
+ id: '43'
101
+ }
102
+ ]
103
+ }
104
+ }
105
+ assert_equal expected, relationships
106
+ end
107
+
108
+ def test_include_linked_resources_with_type_name
109
+ serializer = BlogSerializer.new(@blog)
110
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, include: [:writer, :articles])
111
+ linked = adapter.serializable_hash[:included]
112
+ expected = [
113
+ {
114
+ id: '1',
115
+ type: 'authors',
116
+ attributes: {
117
+ name: 'Steve K.'
118
+ },
119
+ relationships: {
120
+ posts: { data: [] },
121
+ roles: { data: [] },
122
+ bio: { data: nil }
123
+ }
124
+ }, {
125
+ id: '42',
126
+ type: 'posts',
127
+ attributes: {
128
+ title: 'New Post',
129
+ body: 'Body'
130
+ },
131
+ relationships: {
132
+ comments: { data: [{ type: 'comments', id: '1' }] },
133
+ blog: { data: { type: 'blogs', id: '999' } },
134
+ author: { data: { type: 'authors', id: '1' } }
135
+ }
136
+ }, {
137
+ id: '43',
138
+ type: 'posts',
139
+ attributes: {
140
+ title: 'Hello!!',
141
+ body: 'Hello, world!!'
142
+ },
143
+ relationships: {
144
+ comments: { data: [] },
145
+ blog: { data: { type: 'blogs', id: '999' } },
146
+ author: { data: nil }
147
+ }
148
+ }
149
+ ]
150
+ assert_equal expected, linked
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,95 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ class CollectionTest < ActiveSupport::TestCase
7
+ def setup
8
+ @author = Author.new(id: 1, name: 'Steve K.')
9
+ @author.bio = nil
10
+ @blog = Blog.new(id: 23, name: 'AMS Blog')
11
+ @first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
12
+ @second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
13
+ @first_post.comments = []
14
+ @second_post.comments = []
15
+ @first_post.blog = @blog
16
+ @second_post.blog = nil
17
+ @first_post.author = @author
18
+ @second_post.author = @author
19
+ @author.posts = [@first_post, @second_post]
20
+
21
+ @serializer = ActiveModel::Serializer::CollectionSerializer.new([@first_post, @second_post])
22
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
23
+ ActionController::Base.cache_store.clear
24
+ end
25
+
26
+ def test_include_multiple_posts
27
+ expected = [
28
+ {
29
+ id: '1',
30
+ type: 'posts',
31
+ attributes: {
32
+ title: 'Hello!!',
33
+ body: 'Hello, world!!'
34
+ },
35
+ relationships: {
36
+ comments: { data: [] },
37
+ blog: { data: { type: 'blogs', id: '999' } },
38
+ author: { data: { type: 'authors', id: '1' } }
39
+ }
40
+ },
41
+ {
42
+ id: '2',
43
+ type: 'posts',
44
+ attributes: {
45
+ title: 'New Post',
46
+ body: 'Body'
47
+ },
48
+ relationships: {
49
+ comments: { data: [] },
50
+ blog: { data: { type: 'blogs', id: '999' } },
51
+ author: { data: { type: 'authors', id: '1' } }
52
+ }
53
+ }
54
+ ]
55
+
56
+ assert_equal(expected, @adapter.serializable_hash[:data])
57
+ end
58
+
59
+ def test_limiting_fields
60
+ actual = ActiveModelSerializers::SerializableResource.new(
61
+ [@first_post, @second_post], adapter: :json_api,
62
+ fields: { posts: %w(title comments blog author) })
63
+ .serializable_hash
64
+ expected = [
65
+ {
66
+ id: '1',
67
+ type: 'posts',
68
+ attributes: {
69
+ title: 'Hello!!'
70
+ },
71
+ relationships: {
72
+ comments: { data: [] },
73
+ blog: { data: { type: 'blogs', id: '999' } },
74
+ author: { data: { type: 'authors', id: '1' } }
75
+ }
76
+ },
77
+ {
78
+ id: '2',
79
+ type: 'posts',
80
+ attributes: {
81
+ title: 'New Post'
82
+ },
83
+ relationships: {
84
+ comments: { data: [] },
85
+ blog: { data: { type: 'blogs', id: '999' } },
86
+ author: { data: { type: 'authors', id: '1' } }
87
+ }
88
+ }
89
+ ]
90
+ assert_equal(expected, actual[:data])
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end