active_model_serializers 0.10.3 → 0.10.12

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 (224) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +154 -2
  3. data/README.md +153 -15
  4. data/lib/action_controller/serialization.rb +11 -1
  5. data/lib/active_model/serializable_resource.rb +2 -0
  6. data/lib/active_model/serializer.rb +275 -81
  7. data/lib/active_model/serializer/adapter.rb +2 -0
  8. data/lib/active_model/serializer/adapter/attributes.rb +2 -0
  9. data/lib/active_model/serializer/adapter/base.rb +2 -0
  10. data/lib/active_model/serializer/adapter/json.rb +2 -0
  11. data/lib/active_model/serializer/adapter/json_api.rb +2 -0
  12. data/lib/active_model/serializer/adapter/null.rb +2 -0
  13. data/lib/active_model/serializer/array_serializer.rb +2 -0
  14. data/lib/active_model/serializer/association.rb +53 -14
  15. data/lib/active_model/serializer/attribute.rb +2 -0
  16. data/lib/active_model/serializer/belongs_to_reflection.rb +7 -1
  17. data/lib/active_model/serializer/collection_serializer.rb +8 -5
  18. data/lib/active_model/serializer/concerns/caching.rb +36 -23
  19. data/lib/active_model/serializer/error_serializer.rb +2 -0
  20. data/lib/active_model/serializer/errors_serializer.rb +2 -0
  21. data/lib/active_model/serializer/field.rb +2 -0
  22. data/lib/active_model/serializer/fieldset.rb +3 -1
  23. data/lib/active_model/serializer/has_many_reflection.rb +6 -1
  24. data/lib/active_model/serializer/has_one_reflection.rb +3 -1
  25. data/lib/active_model/serializer/lazy_association.rb +99 -0
  26. data/lib/active_model/serializer/link.rb +23 -0
  27. data/lib/active_model/serializer/lint.rb +2 -0
  28. data/lib/active_model/serializer/null.rb +2 -0
  29. data/lib/active_model/serializer/reflection.rb +122 -73
  30. data/lib/active_model/serializer/version.rb +3 -1
  31. data/lib/active_model_serializers.rb +29 -11
  32. data/lib/active_model_serializers/adapter.rb +3 -1
  33. data/lib/active_model_serializers/adapter/attributes.rb +23 -0
  34. data/lib/active_model_serializers/adapter/base.rb +4 -2
  35. data/lib/active_model_serializers/adapter/json.rb +2 -0
  36. data/lib/active_model_serializers/adapter/json_api.rb +44 -26
  37. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +4 -2
  38. data/lib/active_model_serializers/adapter/json_api/error.rb +2 -0
  39. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +2 -0
  40. data/lib/active_model_serializers/adapter/json_api/link.rb +2 -0
  41. data/lib/active_model_serializers/adapter/json_api/meta.rb +2 -0
  42. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +42 -21
  43. data/lib/active_model_serializers/adapter/json_api/relationship.rb +52 -9
  44. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +35 -18
  45. data/lib/active_model_serializers/adapter/null.rb +2 -0
  46. data/lib/active_model_serializers/callbacks.rb +2 -0
  47. data/lib/active_model_serializers/deprecate.rb +2 -0
  48. data/lib/active_model_serializers/deserialization.rb +2 -0
  49. data/lib/active_model_serializers/json_pointer.rb +2 -0
  50. data/lib/active_model_serializers/logging.rb +2 -0
  51. data/lib/active_model_serializers/lookup_chain.rb +2 -0
  52. data/lib/active_model_serializers/model.rb +111 -30
  53. data/lib/active_model_serializers/model/caching.rb +25 -0
  54. data/lib/active_model_serializers/railtie.rb +4 -0
  55. data/lib/active_model_serializers/register_jsonapi_renderer.rb +2 -0
  56. data/lib/active_model_serializers/serializable_resource.rb +4 -2
  57. data/lib/active_model_serializers/serialization_context.rb +2 -0
  58. data/lib/active_model_serializers/test.rb +2 -0
  59. data/lib/active_model_serializers/test/schema.rb +4 -2
  60. data/lib/active_model_serializers/test/serializer.rb +2 -0
  61. data/lib/generators/rails/resource_override.rb +3 -1
  62. data/lib/generators/rails/serializer_generator.rb +2 -0
  63. data/lib/grape/active_model_serializers.rb +2 -0
  64. data/lib/grape/formatters/active_model_serializers.rb +2 -0
  65. data/lib/grape/helpers/active_model_serializers.rb +2 -0
  66. data/lib/tasks/rubocop.rake +55 -0
  67. metadata +74 -291
  68. data/.github/ISSUE_TEMPLATE.md +0 -29
  69. data/.github/PULL_REQUEST_TEMPLATE.md +0 -15
  70. data/.gitignore +0 -35
  71. data/.rubocop.yml +0 -102
  72. data/.simplecov +0 -110
  73. data/.travis.yml +0 -51
  74. data/CODE_OF_CONDUCT.md +0 -74
  75. data/CONTRIBUTING.md +0 -105
  76. data/Gemfile +0 -56
  77. data/Rakefile +0 -103
  78. data/active_model_serializers.gemspec +0 -62
  79. data/appveyor.yml +0 -24
  80. data/bin/bench +0 -171
  81. data/bin/bench_regression +0 -316
  82. data/bin/serve_benchmark +0 -39
  83. data/docs/ARCHITECTURE.md +0 -125
  84. data/docs/README.md +0 -42
  85. data/docs/STYLE.md +0 -58
  86. data/docs/general/adapters.md +0 -247
  87. data/docs/general/caching.md +0 -58
  88. data/docs/general/configuration_options.md +0 -169
  89. data/docs/general/deserialization.md +0 -100
  90. data/docs/general/fields.md +0 -31
  91. data/docs/general/getting_started.md +0 -133
  92. data/docs/general/instrumentation.md +0 -40
  93. data/docs/general/key_transforms.md +0 -40
  94. data/docs/general/logging.md +0 -14
  95. data/docs/general/rendering.md +0 -294
  96. data/docs/general/serializers.md +0 -461
  97. data/docs/how-open-source-maintained.jpg +0 -0
  98. data/docs/howto/add_pagination_links.md +0 -138
  99. data/docs/howto/add_relationship_links.md +0 -137
  100. data/docs/howto/add_root_key.md +0 -55
  101. data/docs/howto/grape_integration.md +0 -42
  102. data/docs/howto/outside_controller_use.md +0 -65
  103. data/docs/howto/passing_arbitrary_options.md +0 -27
  104. data/docs/howto/serialize_poro.md +0 -32
  105. data/docs/howto/test.md +0 -154
  106. data/docs/howto/upgrade_from_0_8_to_0_10.md +0 -265
  107. data/docs/integrations/ember-and-json-api.md +0 -144
  108. data/docs/integrations/grape.md +0 -19
  109. data/docs/jsonapi/errors.md +0 -56
  110. data/docs/jsonapi/schema.md +0 -151
  111. data/docs/jsonapi/schema/schema.json +0 -366
  112. data/docs/rfcs/0000-namespace.md +0 -106
  113. data/docs/rfcs/template.md +0 -15
  114. data/lib/active_model/serializer/collection_reflection.rb +0 -7
  115. data/lib/active_model/serializer/concerns/associations.rb +0 -102
  116. data/lib/active_model/serializer/concerns/attributes.rb +0 -82
  117. data/lib/active_model/serializer/concerns/configuration.rb +0 -59
  118. data/lib/active_model/serializer/concerns/links.rb +0 -35
  119. data/lib/active_model/serializer/concerns/meta.rb +0 -29
  120. data/lib/active_model/serializer/concerns/type.rb +0 -25
  121. data/lib/active_model/serializer/singular_reflection.rb +0 -7
  122. data/lib/active_model_serializers/key_transform.rb +0 -74
  123. data/test/action_controller/adapter_selector_test.rb +0 -53
  124. data/test/action_controller/explicit_serializer_test.rb +0 -135
  125. data/test/action_controller/json/include_test.rb +0 -246
  126. data/test/action_controller/json_api/deserialization_test.rb +0 -112
  127. data/test/action_controller/json_api/errors_test.rb +0 -40
  128. data/test/action_controller/json_api/fields_test.rb +0 -57
  129. data/test/action_controller/json_api/linked_test.rb +0 -202
  130. data/test/action_controller/json_api/pagination_test.rb +0 -116
  131. data/test/action_controller/json_api/transform_test.rb +0 -181
  132. data/test/action_controller/lookup_proc_test.rb +0 -49
  133. data/test/action_controller/namespace_lookup_test.rb +0 -226
  134. data/test/action_controller/serialization_scope_name_test.rb +0 -229
  135. data/test/action_controller/serialization_test.rb +0 -472
  136. data/test/active_model_serializers/adapter_for_test.rb +0 -208
  137. data/test/active_model_serializers/json_pointer_test.rb +0 -22
  138. data/test/active_model_serializers/key_transform_test.rb +0 -297
  139. data/test/active_model_serializers/logging_test.rb +0 -77
  140. data/test/active_model_serializers/model_test.rb +0 -22
  141. data/test/active_model_serializers/railtie_test_isolated.rb +0 -63
  142. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +0 -143
  143. data/test/active_model_serializers/serialization_context_test_isolated.rb +0 -71
  144. data/test/active_model_serializers/test/schema_test.rb +0 -130
  145. data/test/active_model_serializers/test/serializer_test.rb +0 -62
  146. data/test/active_record_test.rb +0 -9
  147. data/test/adapter/attributes_test.rb +0 -43
  148. data/test/adapter/deprecation_test.rb +0 -100
  149. data/test/adapter/json/belongs_to_test.rb +0 -45
  150. data/test/adapter/json/collection_test.rb +0 -104
  151. data/test/adapter/json/has_many_test.rb +0 -45
  152. data/test/adapter/json/transform_test.rb +0 -93
  153. data/test/adapter/json_api/belongs_to_test.rb +0 -155
  154. data/test/adapter/json_api/collection_test.rb +0 -96
  155. data/test/adapter/json_api/errors_test.rb +0 -76
  156. data/test/adapter/json_api/fields_test.rb +0 -88
  157. data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
  158. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +0 -96
  159. data/test/adapter/json_api/has_many_test.rb +0 -165
  160. data/test/adapter/json_api/has_one_test.rb +0 -80
  161. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +0 -166
  162. data/test/adapter/json_api/json_api_test.rb +0 -33
  163. data/test/adapter/json_api/linked_test.rb +0 -413
  164. data/test/adapter/json_api/links_test.rb +0 -95
  165. data/test/adapter/json_api/pagination_links_test.rb +0 -193
  166. data/test/adapter/json_api/parse_test.rb +0 -137
  167. data/test/adapter/json_api/relationship_test.rb +0 -397
  168. data/test/adapter/json_api/resource_identifier_test.rb +0 -110
  169. data/test/adapter/json_api/resource_meta_test.rb +0 -100
  170. data/test/adapter/json_api/toplevel_jsonapi_test.rb +0 -82
  171. data/test/adapter/json_api/transform_test.rb +0 -504
  172. data/test/adapter/json_api/type_test.rb +0 -61
  173. data/test/adapter/json_test.rb +0 -46
  174. data/test/adapter/null_test.rb +0 -22
  175. data/test/adapter/polymorphic_test.rb +0 -171
  176. data/test/adapter_test.rb +0 -67
  177. data/test/array_serializer_test.rb +0 -22
  178. data/test/benchmark/app.rb +0 -65
  179. data/test/benchmark/benchmarking_support.rb +0 -67
  180. data/test/benchmark/bm_active_record.rb +0 -81
  181. data/test/benchmark/bm_adapter.rb +0 -38
  182. data/test/benchmark/bm_caching.rb +0 -119
  183. data/test/benchmark/bm_lookup_chain.rb +0 -83
  184. data/test/benchmark/bm_transform.rb +0 -45
  185. data/test/benchmark/config.ru +0 -3
  186. data/test/benchmark/controllers.rb +0 -83
  187. data/test/benchmark/fixtures.rb +0 -219
  188. data/test/cache_test.rb +0 -579
  189. data/test/collection_serializer_test.rb +0 -110
  190. data/test/fixtures/active_record.rb +0 -78
  191. data/test/fixtures/poro.rb +0 -286
  192. data/test/generators/scaffold_controller_generator_test.rb +0 -24
  193. data/test/generators/serializer_generator_test.rb +0 -74
  194. data/test/grape_test.rb +0 -178
  195. data/test/lint_test.rb +0 -49
  196. data/test/logger_test.rb +0 -20
  197. data/test/poro_test.rb +0 -9
  198. data/test/serializable_resource_test.rb +0 -79
  199. data/test/serializers/association_macros_test.rb +0 -37
  200. data/test/serializers/associations_test.rb +0 -370
  201. data/test/serializers/attribute_test.rb +0 -151
  202. data/test/serializers/attributes_test.rb +0 -52
  203. data/test/serializers/caching_configuration_test_isolated.rb +0 -170
  204. data/test/serializers/configuration_test.rb +0 -32
  205. data/test/serializers/fieldset_test.rb +0 -14
  206. data/test/serializers/meta_test.rb +0 -202
  207. data/test/serializers/options_test.rb +0 -21
  208. data/test/serializers/read_attribute_for_serialization_test.rb +0 -79
  209. data/test/serializers/root_test.rb +0 -21
  210. data/test/serializers/serialization_test.rb +0 -55
  211. data/test/serializers/serializer_for_test.rb +0 -136
  212. data/test/serializers/serializer_for_with_namespace_test.rb +0 -87
  213. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
  214. data/test/support/isolated_unit.rb +0 -82
  215. data/test/support/rails5_shims.rb +0 -53
  216. data/test/support/rails_app.rb +0 -36
  217. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +0 -6
  218. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +0 -6
  219. data/test/support/schemas/custom/show.json +0 -7
  220. data/test/support/schemas/hyper_schema.json +0 -93
  221. data/test/support/schemas/render_using_json_api.json +0 -43
  222. data/test/support/schemas/simple_json_pointers.json +0 -10
  223. data/test/support/serialization_testing.rb +0 -71
  224. data/test/test_helper.rb +0 -58
@@ -1,110 +0,0 @@
1
- require 'test_helper'
2
-
3
- module ActiveModelSerializers
4
- module Adapter
5
- class JsonApi
6
- class ResourceIdentifierTest < ActiveSupport::TestCase
7
- class WithDefinedTypeSerializer < ActiveModel::Serializer
8
- type 'with_defined_type'
9
- end
10
-
11
- class WithDefinedIdSerializer < ActiveModel::Serializer
12
- def id
13
- 'special_id'
14
- end
15
- end
16
-
17
- class FragmentedSerializer < ActiveModel::Serializer
18
- cache only: :id
19
-
20
- def id
21
- 'special_id'
22
- end
23
- end
24
-
25
- setup do
26
- @model = Author.new(id: 1, name: 'Steve K.')
27
- ActionController::Base.cache_store.clear
28
- end
29
-
30
- def test_defined_type
31
- test_type(WithDefinedTypeSerializer, 'with-defined-type')
32
- end
33
-
34
- def test_singular_type
35
- test_type_inflection(AuthorSerializer, 'author', :singular)
36
- end
37
-
38
- def test_plural_type
39
- test_type_inflection(AuthorSerializer, 'authors', :plural)
40
- end
41
-
42
- def test_type_with_namespace
43
- Object.const_set(:Admin, Module.new)
44
- model = Class.new(::Model)
45
- Admin.const_set(:PowerUser, model)
46
- serializer = Class.new(ActiveModel::Serializer)
47
- Admin.const_set(:PowerUserSerializer, serializer)
48
- with_namespace_separator '--' do
49
- admin_user = Admin::PowerUser.new
50
- serializer = Admin::PowerUserSerializer.new(admin_user)
51
- expected = {
52
- id: admin_user.id,
53
- type: 'admin--power-users'
54
- }
55
-
56
- identifier = ResourceIdentifier.new(serializer, {})
57
- actual = identifier.as_json
58
- assert_equal(expected, actual)
59
- end
60
- end
61
-
62
- def test_id_defined_on_object
63
- test_id(AuthorSerializer, @model.id.to_s)
64
- end
65
-
66
- def test_id_defined_on_serializer
67
- test_id(WithDefinedIdSerializer, 'special_id')
68
- end
69
-
70
- def test_id_defined_on_fragmented
71
- test_id(FragmentedSerializer, 'special_id')
72
- end
73
-
74
- private
75
-
76
- def test_type_inflection(serializer_class, expected_type, inflection)
77
- original_inflection = ActiveModelSerializers.config.jsonapi_resource_type
78
- ActiveModelSerializers.config.jsonapi_resource_type = inflection
79
- test_type(serializer_class, expected_type)
80
- ensure
81
- ActiveModelSerializers.config.jsonapi_resource_type = original_inflection
82
- end
83
-
84
- def test_type(serializer_class, expected_type)
85
- serializer = serializer_class.new(@model)
86
- resource_identifier = ResourceIdentifier.new(serializer, nil)
87
- expected = {
88
- id: @model.id.to_s,
89
- type: expected_type
90
- }
91
-
92
- assert_equal(expected, resource_identifier.as_json)
93
- end
94
-
95
- def test_id(serializer_class, id)
96
- serializer = serializer_class.new(@model)
97
- resource_identifier = ResourceIdentifier.new(serializer, nil)
98
- inflection = ActiveModelSerializers.config.jsonapi_resource_type
99
- type = @model.class.model_name.send(inflection)
100
- expected = {
101
- id: id,
102
- type: type
103
- }
104
-
105
- assert_equal(expected, resource_identifier.as_json)
106
- end
107
- end
108
- end
109
- end
110
- end
@@ -1,100 +0,0 @@
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
@@ -1,82 +0,0 @@
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
@@ -1,504 +0,0 @@
1
- require 'test_helper'
2
-
3
- module ActiveModelSerializers
4
- module Adapter
5
- class JsonApi
6
- class KeyCaseTest < ActiveSupport::TestCase
7
- class Post < ::Model; end
8
- class Author < ::Model; end
9
- class Comment < ::Model; end
10
-
11
- class PostSerializer < ActiveModel::Serializer
12
- type 'posts'
13
- attributes :title, :body, :publish_at
14
- belongs_to :author
15
- has_many :comments
16
-
17
- link(:self) { post_url(object.id) }
18
- link(:post_authors) { post_authors_url(object.id) }
19
- link(:subscriber_comments) { post_comments_url(object.id) }
20
-
21
- meta do
22
- {
23
- rating: 5,
24
- favorite_count: 10
25
- }
26
- end
27
- end
28
-
29
- class AuthorSerializer < ActiveModel::Serializer
30
- type 'authors'
31
- attributes :first_name, :last_name
32
- end
33
-
34
- class CommentSerializer < ActiveModel::Serializer
35
- type 'comments'
36
- attributes :body
37
- belongs_to :author
38
- end
39
-
40
- def mock_request(transform = nil)
41
- context = Minitest::Mock.new
42
- context.expect(:request_url, URI)
43
- context.expect(:query_parameters, {})
44
- context.expect(:url_helpers, Rails.application.routes.url_helpers)
45
- @options = {}
46
- @options[:key_transform] = transform if transform
47
- @options[:serialization_context] = context
48
- end
49
-
50
- def setup
51
- Rails.application.routes.draw do
52
- resources :posts do
53
- resources :authors
54
- resources :comments
55
- end
56
- end
57
- @publish_at = 1.day.from_now
58
- @author = Author.new(id: 1, first_name: 'Bob', last_name: 'Jones')
59
- @comment1 = Comment.new(id: 7, body: 'cool', author: @author)
60
- @comment2 = Comment.new(id: 12, body: 'awesome', author: @author)
61
- @post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1',
62
- author: @author, comments: [@comment1, @comment2],
63
- publish_at: @publish_at)
64
- @comment1.post = @post
65
- @comment2.post = @post
66
- end
67
-
68
- def test_success_document_transform_default
69
- mock_request
70
- serializer = PostSerializer.new(@post)
71
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
72
- result = adapter.serializable_hash
73
- assert_equal({
74
- data: {
75
- id: '1337',
76
- type: 'posts',
77
- attributes: {
78
- title: 'Title 1',
79
- body: 'Body 1',
80
- :"publish-at" => @publish_at
81
- },
82
- relationships: {
83
- author: {
84
- data: { id: '1', type: 'authors' }
85
- },
86
- comments: {
87
- data: [
88
- { id: '7', type: 'comments' },
89
- { id: '12', type: 'comments' }
90
- ]
91
- }
92
- },
93
- links: {
94
- self: 'http://example.com/posts/1337',
95
- :"post-authors" => 'http://example.com/posts/1337/authors',
96
- :"subscriber-comments" => 'http://example.com/posts/1337/comments'
97
- },
98
- meta: { rating: 5, :"favorite-count" => 10 }
99
- }
100
- }, result)
101
- end
102
-
103
- def test_success_document_transform_global_config
104
- mock_request
105
- result = with_config(key_transform: :camel_lower) do
106
- serializer = PostSerializer.new(@post)
107
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
108
- adapter.serializable_hash
109
- end
110
- assert_equal({
111
- data: {
112
- id: '1337',
113
- type: 'posts',
114
- attributes: {
115
- title: 'Title 1',
116
- body: 'Body 1',
117
- publishAt: @publish_at
118
- },
119
- relationships: {
120
- author: {
121
- data: { id: '1', type: 'authors' }
122
- },
123
- comments: {
124
- data: [
125
- { id: '7', type: 'comments' },
126
- { id: '12', type: 'comments' }
127
- ]
128
- }
129
- },
130
- links: {
131
- self: 'http://example.com/posts/1337',
132
- postAuthors: 'http://example.com/posts/1337/authors',
133
- subscriberComments: 'http://example.com/posts/1337/comments'
134
- },
135
- meta: { rating: 5, favoriteCount: 10 }
136
- }
137
- }, result)
138
- end
139
-
140
- def test_success_doc_transform_serialization_ctx_overrides_global
141
- mock_request(:camel)
142
- result = with_config(key_transform: :camel_lower) do
143
- serializer = PostSerializer.new(@post)
144
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
145
- adapter.serializable_hash
146
- end
147
- assert_equal({
148
- Data: {
149
- Id: '1337',
150
- Type: 'Posts',
151
- Attributes: {
152
- Title: 'Title 1',
153
- Body: 'Body 1',
154
- PublishAt: @publish_at
155
- },
156
- Relationships: {
157
- Author: {
158
- Data: { Id: '1', Type: 'Authors' }
159
- },
160
- Comments: {
161
- Data: [
162
- { Id: '7', Type: 'Comments' },
163
- { Id: '12', Type: 'Comments' }
164
- ]
165
- }
166
- },
167
- Links: {
168
- Self: 'http://example.com/posts/1337',
169
- PostAuthors: 'http://example.com/posts/1337/authors',
170
- SubscriberComments: 'http://example.com/posts/1337/comments'
171
- },
172
- Meta: { Rating: 5, FavoriteCount: 10 }
173
- }
174
- }, result)
175
- end
176
-
177
- def test_success_document_transform_dash
178
- mock_request(:dash)
179
- serializer = PostSerializer.new(@post)
180
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
181
- result = adapter.serializable_hash
182
- assert_equal({
183
- data: {
184
- id: '1337',
185
- type: 'posts',
186
- attributes: {
187
- title: 'Title 1',
188
- body: 'Body 1',
189
- :"publish-at" => @publish_at
190
- },
191
- relationships: {
192
- author: {
193
- data: { id: '1', type: 'authors' }
194
- },
195
- comments: {
196
- data: [
197
- { id: '7', type: 'comments' },
198
- { id: '12', type: 'comments' }
199
- ]
200
- }
201
- },
202
- links: {
203
- self: 'http://example.com/posts/1337',
204
- :"post-authors" => 'http://example.com/posts/1337/authors',
205
- :"subscriber-comments" => 'http://example.com/posts/1337/comments'
206
- },
207
- meta: { rating: 5, :"favorite-count" => 10 }
208
- }
209
- }, result)
210
- end
211
-
212
- def test_success_document_transform_unaltered
213
- mock_request(:unaltered)
214
- serializer = PostSerializer.new(@post)
215
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
216
- result = adapter.serializable_hash
217
- assert_equal({
218
- data: {
219
- id: '1337',
220
- type: 'posts',
221
- attributes: {
222
- title: 'Title 1',
223
- body: 'Body 1',
224
- publish_at: @publish_at
225
- },
226
- relationships: {
227
- author: {
228
- data: { id: '1', type: 'authors' }
229
- },
230
- comments: {
231
- data: [
232
- { id: '7', type: 'comments' },
233
- { id: '12', type: 'comments' }
234
- ]
235
- }
236
- },
237
- links: {
238
- self: 'http://example.com/posts/1337',
239
- post_authors: 'http://example.com/posts/1337/authors',
240
- subscriber_comments: 'http://example.com/posts/1337/comments'
241
- },
242
- meta: { rating: 5, favorite_count: 10 }
243
- }
244
- }, result)
245
- end
246
-
247
- def test_success_document_transform_undefined
248
- mock_request(:zoot)
249
- serializer = PostSerializer.new(@post)
250
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
251
- exception = assert_raises NoMethodError do
252
- adapter.serializable_hash
253
- end
254
- assert_match(/undefined method.*zoot/, exception.message)
255
- end
256
-
257
- def test_success_document_transform_camel
258
- mock_request(:camel)
259
- serializer = PostSerializer.new(@post)
260
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
261
- result = adapter.serializable_hash
262
- assert_equal({
263
- Data: {
264
- Id: '1337',
265
- Type: 'Posts',
266
- Attributes: {
267
- Title: 'Title 1',
268
- Body: 'Body 1',
269
- PublishAt: @publish_at
270
- },
271
- Relationships: {
272
- Author: {
273
- Data: { Id: '1', Type: 'Authors' }
274
- },
275
- Comments: {
276
- Data: [
277
- { Id: '7', Type: 'Comments' },
278
- { Id: '12', Type: 'Comments' }
279
- ]
280
- }
281
- },
282
- Links: {
283
- Self: 'http://example.com/posts/1337',
284
- PostAuthors: 'http://example.com/posts/1337/authors',
285
- SubscriberComments: 'http://example.com/posts/1337/comments'
286
- },
287
- Meta: { Rating: 5, FavoriteCount: 10 }
288
- }
289
- }, result)
290
- end
291
-
292
- def test_success_document_transform_camel_lower
293
- mock_request(:camel_lower)
294
- serializer = PostSerializer.new(@post)
295
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
296
- result = adapter.serializable_hash
297
- assert_equal({
298
- data: {
299
- id: '1337',
300
- type: 'posts',
301
- attributes: {
302
- title: 'Title 1',
303
- body: 'Body 1',
304
- publishAt: @publish_at
305
- },
306
- relationships: {
307
- author: {
308
- data: { id: '1', type: 'authors' }
309
- },
310
- comments: {
311
- data: [
312
- { id: '7', type: 'comments' },
313
- { id: '12', type: 'comments' }
314
- ]
315
- }
316
- },
317
- links: {
318
- self: 'http://example.com/posts/1337',
319
- postAuthors: 'http://example.com/posts/1337/authors',
320
- subscriberComments: 'http://example.com/posts/1337/comments'
321
- },
322
- meta: { rating: 5, favoriteCount: 10 }
323
- }
324
- }, result)
325
- end
326
-
327
- def test_error_document_transform_default
328
- mock_request
329
- resource = ModelWithErrors.new
330
- resource.errors.add(:published_at, 'must be in the future')
331
- resource.errors.add(:title, 'must be longer')
332
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
333
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
334
- result = adapter.serializable_hash
335
- expected_errors_object = {
336
- errors: [
337
- {
338
- source: { pointer: '/data/attributes/published-at' },
339
- detail: 'must be in the future'
340
- },
341
- {
342
- source: { pointer: '/data/attributes/title' },
343
- detail: 'must be longer'
344
- }
345
- ]
346
- }
347
- assert_equal expected_errors_object, result
348
- end
349
-
350
- def test_error_document_transform_global_config
351
- mock_request
352
- result = with_config(key_transform: :camel) do
353
- resource = ModelWithErrors.new
354
- resource.errors.add(:published_at, 'must be in the future')
355
- resource.errors.add(:title, 'must be longer')
356
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
357
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
358
- adapter.serializable_hash
359
- end
360
- expected_errors_object = {
361
- Errors: [
362
- {
363
- Source: { Pointer: '/data/attributes/PublishedAt' },
364
- Detail: 'must be in the future'
365
- },
366
- {
367
- Source: { Pointer: '/data/attributes/Title' },
368
- Detail: 'must be longer'
369
- }
370
- ]
371
- }
372
- assert_equal expected_errors_object, result
373
- end
374
-
375
- def test_error_document_transform_serialization_ctx_overrides_global
376
- mock_request(:camel)
377
- result = with_config(key_transform: :camel_lower) do
378
- resource = ModelWithErrors.new
379
- resource.errors.add(:published_at, 'must be in the future')
380
- resource.errors.add(:title, 'must be longer')
381
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
382
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
383
- adapter.serializable_hash
384
- end
385
- expected_errors_object = {
386
- Errors: [
387
- {
388
- Source: { Pointer: '/data/attributes/PublishedAt' },
389
- Detail: 'must be in the future'
390
- },
391
- {
392
- Source: { Pointer: '/data/attributes/Title' },
393
- Detail: 'must be longer'
394
- }
395
- ]
396
- }
397
- assert_equal expected_errors_object, result
398
- end
399
-
400
- def test_error_document_transform_dash
401
- mock_request(:dash)
402
-
403
- resource = ModelWithErrors.new
404
- resource.errors.add(:published_at, 'must be in the future')
405
- resource.errors.add(:title, 'must be longer')
406
-
407
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
408
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
409
- result = adapter.serializable_hash
410
-
411
- expected_errors_object = {
412
- errors: [
413
- {
414
- source: { pointer: '/data/attributes/published-at' },
415
- detail: 'must be in the future'
416
- },
417
- {
418
- source: { pointer: '/data/attributes/title' },
419
- detail: 'must be longer'
420
- }
421
- ]
422
- }
423
- assert_equal expected_errors_object, result
424
- end
425
-
426
- def test_error_document_transform_unaltered
427
- mock_request(:unaltered)
428
-
429
- resource = ModelWithErrors.new
430
- resource.errors.add(:published_at, 'must be in the future')
431
- resource.errors.add(:title, 'must be longer')
432
-
433
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
434
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
435
- result = adapter.serializable_hash
436
-
437
- expected_errors_object = {
438
- errors: [
439
- { source: { pointer: '/data/attributes/published_at' }, detail: 'must be in the future' },
440
- { source: { pointer: '/data/attributes/title' }, detail: 'must be longer' }
441
- ]
442
- }
443
- assert_equal expected_errors_object, result
444
- end
445
-
446
- def test_error_document_transform_undefined
447
- mock_request(:krazy)
448
-
449
- resource = ModelWithErrors.new
450
- resource.errors.add(:published_at, 'must be in the future')
451
- resource.errors.add(:title, 'must be longer')
452
-
453
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
454
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
455
-
456
- exception = assert_raises NoMethodError do
457
- adapter.serializable_hash
458
- end
459
- assert_match(/undefined method.*krazy/, exception.message)
460
- end
461
-
462
- def test_error_document_transform_camel
463
- mock_request(:camel)
464
-
465
- resource = ModelWithErrors.new
466
- resource.errors.add(:published_at, 'must be in the future')
467
- resource.errors.add(:title, 'must be longer')
468
-
469
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
470
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
471
- result = adapter.serializable_hash
472
-
473
- expected_errors_object = {
474
- Errors: [
475
- { Source: { Pointer: '/data/attributes/PublishedAt' }, Detail: 'must be in the future' },
476
- { Source: { Pointer: '/data/attributes/Title' }, Detail: 'must be longer' }
477
- ]
478
- }
479
- assert_equal expected_errors_object, result
480
- end
481
-
482
- def test_error_document_transform_camel_lower
483
- mock_request(:camel_lower)
484
-
485
- resource = ModelWithErrors.new
486
- resource.errors.add(:published_at, 'must be in the future')
487
- resource.errors.add(:title, 'must be longer')
488
-
489
- serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
490
- adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, @options)
491
- result = adapter.serializable_hash
492
-
493
- expected_errors_object = {
494
- errors: [
495
- { source: { pointer: '/data/attributes/publishedAt' }, detail: 'must be in the future' },
496
- { source: { pointer: '/data/attributes/title' }, detail: 'must be longer' }
497
- ]
498
- }
499
- assert_equal expected_errors_object, result
500
- end
501
- end
502
- end
503
- end
504
- end