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,78 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi < Base
6
+ class ErrorsTest < Minitest::Test
7
+ include ActiveModel::Serializer::Lint::Tests
8
+
9
+ def setup
10
+ @resource = ModelWithErrors.new
11
+ end
12
+
13
+ def test_active_model_with_error
14
+ options = {
15
+ serializer: ActiveModel::Serializer::ErrorSerializer,
16
+ adapter: :json_api
17
+ }
18
+
19
+ @resource.errors.add(:name, 'cannot be nil')
20
+
21
+ serializable_resource = ActiveModelSerializers::SerializableResource.new(@resource, options)
22
+ assert_equal serializable_resource.serializer_instance.attributes, {}
23
+ assert_equal serializable_resource.serializer_instance.object, @resource
24
+
25
+ expected_errors_object =
26
+ { :errors =>
27
+ [
28
+ {
29
+ source: { pointer: '/data/attributes/name' },
30
+ detail: 'cannot be nil'
31
+ }
32
+ ]
33
+ }
34
+ assert_equal serializable_resource.as_json, expected_errors_object
35
+ end
36
+
37
+ def test_active_model_with_multiple_errors
38
+ options = {
39
+ serializer: ActiveModel::Serializer::ErrorSerializer,
40
+ adapter: :json_api
41
+ }
42
+
43
+ @resource.errors.add(:name, 'cannot be nil')
44
+ @resource.errors.add(:name, 'must be longer')
45
+ @resource.errors.add(:id, 'must be a uuid')
46
+
47
+ serializable_resource = ActiveModelSerializers::SerializableResource.new(@resource, options)
48
+ assert_equal serializable_resource.serializer_instance.attributes, {}
49
+ assert_equal serializable_resource.serializer_instance.object, @resource
50
+
51
+ expected_errors_object =
52
+ { :errors =>
53
+ [
54
+ { :source => { :pointer => '/data/attributes/name' }, :detail => 'cannot be nil' },
55
+ { :source => { :pointer => '/data/attributes/name' }, :detail => 'must be longer' },
56
+ { :source => { :pointer => '/data/attributes/id' }, :detail => 'must be a uuid' }
57
+ ]
58
+ }
59
+ assert_equal serializable_resource.as_json, expected_errors_object
60
+ end
61
+
62
+ # see http://jsonapi.org/examples/
63
+ def test_parameter_source_type_error
64
+ parameter = 'auther'
65
+ error_source = ActiveModelSerializers::Adapter::JsonApi::Error.error_source(:parameter, parameter)
66
+ assert_equal({ parameter: parameter }, error_source)
67
+ end
68
+
69
+ def test_unknown_source_type_error
70
+ value = 'auther'
71
+ assert_raises(ActiveModelSerializers::Adapter::JsonApi::Error::UnknownSourceTypeError) do
72
+ ActiveModelSerializers::Adapter::JsonApi::Error.error_source(:hyper, value)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,87 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ class FieldsTest < ActiveSupport::TestCase
7
+ Post = Class.new(::Model)
8
+ class PostSerializer < ActiveModel::Serializer
9
+ type 'posts'
10
+ attributes :title, :body
11
+ belongs_to :author
12
+ has_many :comments
13
+ end
14
+
15
+ Author = Class.new(::Model)
16
+ class AuthorSerializer < ActiveModel::Serializer
17
+ type 'authors'
18
+ attributes :name, :birthday
19
+ end
20
+
21
+ Comment = Class.new(::Model)
22
+ class CommentSerializer < ActiveModel::Serializer
23
+ type 'comments'
24
+ attributes :body
25
+ belongs_to :author
26
+ end
27
+
28
+ def setup
29
+ @author = Author.new(id: 1, name: 'Lucas', birthday: '10.01.1990')
30
+ @comment1 = Comment.new(id: 7, body: 'cool', author: @author)
31
+ @comment2 = Comment.new(id: 12, body: 'awesome', author: @author)
32
+ @post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1',
33
+ author: @author, comments: [@comment1, @comment2])
34
+ @comment1.post = @post
35
+ @comment2.post = @post
36
+ end
37
+
38
+ def test_fields_attributes
39
+ fields = { posts: [:title] }
40
+ hash = serializable(@post, adapter: :json_api, fields: fields).serializable_hash
41
+ expected = {
42
+ title: 'Title 1'
43
+ }
44
+
45
+ assert_equal(expected, hash[:data][:attributes])
46
+ end
47
+
48
+ def test_fields_relationships
49
+ fields = { posts: [:author] }
50
+ hash = serializable(@post, adapter: :json_api, fields: fields).serializable_hash
51
+ expected = {
52
+ author: {
53
+ data: {
54
+ type: 'authors',
55
+ id: '1'
56
+ }
57
+ }
58
+ }
59
+
60
+ assert_equal(expected, hash[:data][:relationships])
61
+ end
62
+
63
+ def test_fields_included
64
+ fields = { posts: [:author], comments: [:body] }
65
+ hash = serializable(@post, adapter: :json_api, fields: fields, include: 'comments').serializable_hash
66
+ expected = [
67
+ {
68
+ type: 'comments',
69
+ id: '7',
70
+ attributes: {
71
+ body: 'cool'
72
+ }
73
+ }, {
74
+ type: 'comments',
75
+ id: '12',
76
+ attributes: {
77
+ body: 'awesome'
78
+ }
79
+ }
80
+ ]
81
+
82
+ assert_equal(expected, hash[:included])
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,43 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ class HasManyEmbedIdsTest < ActiveSupport::TestCase
7
+ def setup
8
+ @author = Author.new(name: 'Steve K.')
9
+ @author.bio = nil
10
+ @author.roles = nil
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
+ @author.posts = [@first_post, @second_post]
14
+ @first_post.author = @author
15
+ @second_post.author = @author
16
+ @first_post.comments = []
17
+ @second_post.comments = []
18
+ @blog = Blog.new(id: 23, name: 'AMS Blog')
19
+ @first_post.blog = @blog
20
+ @second_post.blog = nil
21
+
22
+ @serializer = AuthorSerializer.new(@author)
23
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
24
+ end
25
+
26
+ def test_includes_comment_ids
27
+ expected = {
28
+ data: [
29
+ { type: 'posts', id: '1' },
30
+ { type: 'posts', id: '2' }
31
+ ]
32
+ }
33
+
34
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:posts])
35
+ end
36
+
37
+ def test_no_includes_linked_comments
38
+ assert_nil @adapter.serializable_hash[:linked]
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,96 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ # Test 'has_many :assocs, serializer: AssocXSerializer'
7
+ class HasManyExplicitSerializerTest < ActiveSupport::TestCase
8
+ def setup
9
+ @post = Post.new(title: 'New Post', body: 'Body')
10
+ @author = Author.new(name: 'Jane Blogger')
11
+ @author.posts = [@post]
12
+ @post.author = @author
13
+ @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
14
+ @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
15
+ @post.comments = [@first_comment, @second_comment]
16
+ @first_comment.post = @post
17
+ @first_comment.author = nil
18
+ @second_comment.post = @post
19
+ @second_comment.author = nil
20
+ @blog = Blog.new(id: 23, name: 'AMS Blog')
21
+ @post.blog = @blog
22
+
23
+ @serializer = PostPreviewSerializer.new(@post)
24
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(
25
+ @serializer,
26
+ include: [:comments, :author]
27
+ )
28
+ end
29
+
30
+ def test_includes_comment_ids
31
+ expected = {
32
+ data: [
33
+ { type: 'comments', id: '1' },
34
+ { type: 'comments', id: '2' }
35
+ ]
36
+ }
37
+
38
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments])
39
+ end
40
+
41
+ def test_includes_linked_data
42
+ # If CommentPreviewSerializer is applied correctly the body text will not be present in the output
43
+ expected = [
44
+ {
45
+ id: '1',
46
+ type: 'comments',
47
+ relationships: {
48
+ post: { data: { type: 'posts', id: @post.id.to_s } }
49
+ }
50
+ },
51
+ {
52
+ id: '2',
53
+ type: 'comments',
54
+ relationships: {
55
+ post: { data: { type: 'posts', id: @post.id.to_s } }
56
+ }
57
+ },
58
+ {
59
+ id: @author.id.to_s,
60
+ type: 'authors',
61
+ relationships: {
62
+ posts: { data: [{ type: 'posts', id: @post.id.to_s }] }
63
+ }
64
+ }
65
+ ]
66
+
67
+ assert_equal(expected, @adapter.serializable_hash[:included])
68
+ end
69
+
70
+ def test_includes_author_id
71
+ expected = {
72
+ data: { type: 'authors', id: @author.id.to_s }
73
+ }
74
+
75
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:author])
76
+ end
77
+
78
+ def test_explicit_serializer_with_null_resource
79
+ @post.author = nil
80
+
81
+ expected = { data: nil }
82
+
83
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:author])
84
+ end
85
+
86
+ def test_explicit_serializer_with_null_collection
87
+ @post.comments = []
88
+
89
+ expected = { data: [] }
90
+
91
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments])
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,144 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ class HasManyTest < ActiveSupport::TestCase
7
+ def setup
8
+ ActionController::Base.cache_store.clear
9
+ @author = Author.new(id: 1, name: 'Steve K.')
10
+ @author.posts = []
11
+ @author.bio = nil
12
+ @post = Post.new(id: 1, title: 'New Post', body: 'Body')
13
+ @post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
14
+ @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
15
+ @first_comment.author = nil
16
+ @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
17
+ @second_comment.author = nil
18
+ @post.comments = [@first_comment, @second_comment]
19
+ @post_without_comments.comments = []
20
+ @first_comment.post = @post
21
+ @second_comment.post = @post
22
+ @post.author = @author
23
+ @post_without_comments.author = nil
24
+ @blog = Blog.new(id: 1, name: 'My Blog!!')
25
+ @blog.writer = @author
26
+ @blog.articles = [@post]
27
+ @post.blog = @blog
28
+ @post_without_comments.blog = nil
29
+ @tag = Tag.new(id: 1, name: '#hash_tag')
30
+ @post.tags = [@tag]
31
+ @serializer = PostSerializer.new(@post)
32
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
33
+
34
+ @virtual_value = VirtualValue.new(id: 1)
35
+ end
36
+
37
+ def test_includes_comment_ids
38
+ expected = { data: [{ type: 'comments', id: '1' }, { type: 'comments', id: '2' }] }
39
+
40
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments])
41
+ end
42
+
43
+ def test_includes_linked_comments
44
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:comments])
45
+ expected = [{
46
+ id: '1',
47
+ type: 'comments',
48
+ attributes: {
49
+ body: 'ZOMG A COMMENT'
50
+ },
51
+ relationships: {
52
+ post: { data: { type: 'posts', id: '1' } },
53
+ author: { data: nil }
54
+ }
55
+ }, {
56
+ id: '2',
57
+ type: 'comments',
58
+ attributes: {
59
+ body: 'ZOMG ANOTHER COMMENT'
60
+ },
61
+ relationships: {
62
+ post: { data: { type: 'posts', id: '1' } },
63
+ author: { data: nil }
64
+ }
65
+ }]
66
+ assert_equal expected, @adapter.serializable_hash[:included]
67
+ end
68
+
69
+ def test_limit_fields_of_linked_comments
70
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:comments], fields: { comment: [:id, :post, :author] })
71
+ expected = [{
72
+ id: '1',
73
+ type: 'comments',
74
+ relationships: {
75
+ post: { data: { type: 'posts', id: '1' } },
76
+ author: { data: nil }
77
+ }
78
+ }, {
79
+ id: '2',
80
+ type: 'comments',
81
+ relationships: {
82
+ post: { data: { type: 'posts', id: '1' } },
83
+ author: { data: nil }
84
+ }
85
+ }]
86
+ assert_equal expected, @adapter.serializable_hash[:included]
87
+ end
88
+
89
+ def test_no_include_linked_if_comments_is_empty
90
+ serializer = PostSerializer.new(@post_without_comments)
91
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
92
+
93
+ assert_nil adapter.serializable_hash[:linked]
94
+ end
95
+
96
+ def test_include_type_for_association_when_different_than_name
97
+ serializer = BlogSerializer.new(@blog)
98
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
99
+ actual = adapter.serializable_hash[:data][:relationships][:articles]
100
+
101
+ expected = {
102
+ data: [{
103
+ type: 'posts',
104
+ id: '1'
105
+ }]
106
+ }
107
+ assert_equal expected, actual
108
+ end
109
+
110
+ def test_has_many_with_no_serializer
111
+ serializer = PostWithTagsSerializer.new(@post)
112
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
113
+
114
+ assert_equal({
115
+ data: {
116
+ id: '1',
117
+ type: 'posts',
118
+ relationships: {
119
+ tags: { data: [@tag.as_json] }
120
+ }
121
+ }
122
+ }, adapter.serializable_hash)
123
+ end
124
+
125
+ def test_has_many_with_virtual_value
126
+ serializer = VirtualValueSerializer.new(@virtual_value)
127
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
128
+
129
+ assert_equal({
130
+ data: {
131
+ id: '1',
132
+ type: 'virtual-values',
133
+ relationships: {
134
+ maker: { data: { type: 'makers', id: '1' } },
135
+ reviews: { data: [{ type: 'reviews', id: '1' },
136
+ { type: 'reviews', id: '2' }] }
137
+ }
138
+ }
139
+ }, adapter.serializable_hash)
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,80 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApi
6
+ class HasOneTest < ActiveSupport::TestCase
7
+ def setup
8
+ @author = Author.new(id: 1, name: 'Steve K.')
9
+ @bio = Bio.new(id: 43, content: 'AMS Contributor')
10
+ @author.bio = @bio
11
+ @bio.author = @author
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
+ @anonymous_post.comments = []
17
+ @comment.post = @post
18
+ @comment.author = nil
19
+ @post.author = @author
20
+ @anonymous_post.author = nil
21
+ @blog = Blog.new(id: 1, name: 'My Blog!!')
22
+ @blog.writer = @author
23
+ @blog.articles = [@post, @anonymous_post]
24
+ @author.posts = []
25
+ @author.roles = []
26
+
27
+ @virtual_value = VirtualValue.new(id: 1)
28
+
29
+ @serializer = AuthorSerializer.new(@author)
30
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:bio, :posts])
31
+ end
32
+
33
+ def test_includes_bio_id
34
+ expected = { data: { type: 'bios', id: '43' } }
35
+
36
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:bio])
37
+ end
38
+
39
+ def test_includes_linked_bio
40
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:bio])
41
+
42
+ expected = [
43
+ {
44
+ id: '43',
45
+ type: 'bios',
46
+ attributes: {
47
+ content: 'AMS Contributor',
48
+ rating: nil
49
+ },
50
+ relationships: {
51
+ author: { data: { type: 'authors', id: '1' } }
52
+ }
53
+ }
54
+ ]
55
+
56
+ assert_equal(expected, @adapter.serializable_hash[:included])
57
+ end
58
+
59
+ def test_has_one_with_virtual_value
60
+ serializer = VirtualValueSerializer.new(@virtual_value)
61
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
62
+
63
+ expected = {
64
+ data: {
65
+ id: '1',
66
+ type: 'virtual-values',
67
+ relationships: {
68
+ maker: { data: { type: 'makers', id: '1' } },
69
+ reviews: { data: [{ type: 'reviews', id: '1' },
70
+ { type: 'reviews', id: '2' }] }
71
+ }
72
+ }
73
+ }
74
+
75
+ assert_equal(expected, adapter.serializable_hash)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class JsonApiTest < ActiveSupport::TestCase
6
+ def setup
7
+ ActionController::Base.cache_store.clear
8
+ @author = Author.new(id: 1, name: 'Steve K.')
9
+ @post = Post.new(id: 1, title: 'New Post', body: 'Body')
10
+ @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
11
+ @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
12
+ @post.comments = [@first_comment, @second_comment]
13
+ @first_comment.post = @post
14
+ @second_comment.post = @post
15
+ @post.author = @author
16
+ @blog = Blog.new(id: 1, name: 'My Blog!!')
17
+ @post.blog = @blog
18
+ end
19
+
20
+ def test_custom_keys
21
+ serializer = PostWithCustomKeysSerializer.new(@post)
22
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
23
+
24
+ assert_equal({
25
+ reviews: { data: [
26
+ { type: 'comments', id: '1' },
27
+ { type: 'comments', id: '2' }
28
+ ] },
29
+ writer: { data: { type: 'authors', id: '1' } },
30
+ site: { data: { type: 'blogs', id: '1' } }
31
+ }, adapter.serializable_hash[:data][:relationships])
32
+ end
33
+ end
34
+ end
35
+ end