active_model_serializers_custom 0.10.90

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 (215) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE.md +29 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +15 -0
  4. data/.gitignore +35 -0
  5. data/.rubocop.yml +109 -0
  6. data/.simplecov +110 -0
  7. data/.travis.yml +63 -0
  8. data/CHANGELOG.md +727 -0
  9. data/CODE_OF_CONDUCT.md +74 -0
  10. data/CONTRIBUTING.md +105 -0
  11. data/Gemfile +74 -0
  12. data/MIT-LICENSE +22 -0
  13. data/README.md +305 -0
  14. data/Rakefile +76 -0
  15. data/active_model_serializers.gemspec +64 -0
  16. data/appveyor.yml +28 -0
  17. data/bin/bench +171 -0
  18. data/bin/bench_regression +316 -0
  19. data/bin/rubocop +38 -0
  20. data/bin/serve_benchmark +39 -0
  21. data/docs/README.md +41 -0
  22. data/docs/STYLE.md +58 -0
  23. data/docs/general/adapters.md +269 -0
  24. data/docs/general/caching.md +58 -0
  25. data/docs/general/configuration_options.md +185 -0
  26. data/docs/general/deserialization.md +100 -0
  27. data/docs/general/fields.md +31 -0
  28. data/docs/general/getting_started.md +133 -0
  29. data/docs/general/instrumentation.md +40 -0
  30. data/docs/general/key_transforms.md +40 -0
  31. data/docs/general/logging.md +21 -0
  32. data/docs/general/rendering.md +293 -0
  33. data/docs/general/serializers.md +495 -0
  34. data/docs/how-open-source-maintained.jpg +0 -0
  35. data/docs/howto/add_pagination_links.md +138 -0
  36. data/docs/howto/add_relationship_links.md +140 -0
  37. data/docs/howto/add_root_key.md +62 -0
  38. data/docs/howto/grape_integration.md +42 -0
  39. data/docs/howto/outside_controller_use.md +66 -0
  40. data/docs/howto/passing_arbitrary_options.md +27 -0
  41. data/docs/howto/serialize_poro.md +73 -0
  42. data/docs/howto/test.md +154 -0
  43. data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
  44. data/docs/integrations/ember-and-json-api.md +147 -0
  45. data/docs/integrations/grape.md +19 -0
  46. data/docs/jsonapi/errors.md +56 -0
  47. data/docs/jsonapi/schema.md +151 -0
  48. data/docs/jsonapi/schema/schema.json +366 -0
  49. data/docs/rfcs/0000-namespace.md +106 -0
  50. data/docs/rfcs/template.md +15 -0
  51. data/lib/action_controller/serialization.rb +76 -0
  52. data/lib/active_model/serializable_resource.rb +13 -0
  53. data/lib/active_model/serializer.rb +418 -0
  54. data/lib/active_model/serializer/adapter.rb +26 -0
  55. data/lib/active_model/serializer/adapter/attributes.rb +17 -0
  56. data/lib/active_model/serializer/adapter/base.rb +20 -0
  57. data/lib/active_model/serializer/adapter/json.rb +17 -0
  58. data/lib/active_model/serializer/adapter/json_api.rb +17 -0
  59. data/lib/active_model/serializer/adapter/null.rb +17 -0
  60. data/lib/active_model/serializer/array_serializer.rb +14 -0
  61. data/lib/active_model/serializer/association.rb +91 -0
  62. data/lib/active_model/serializer/attribute.rb +27 -0
  63. data/lib/active_model/serializer/belongs_to_reflection.rb +13 -0
  64. data/lib/active_model/serializer/collection_serializer.rb +90 -0
  65. data/lib/active_model/serializer/concerns/caching.rb +304 -0
  66. data/lib/active_model/serializer/error_serializer.rb +16 -0
  67. data/lib/active_model/serializer/errors_serializer.rb +34 -0
  68. data/lib/active_model/serializer/field.rb +92 -0
  69. data/lib/active_model/serializer/fieldset.rb +33 -0
  70. data/lib/active_model/serializer/has_many_reflection.rb +12 -0
  71. data/lib/active_model/serializer/has_one_reflection.rb +9 -0
  72. data/lib/active_model/serializer/lazy_association.rb +99 -0
  73. data/lib/active_model/serializer/link.rb +23 -0
  74. data/lib/active_model/serializer/lint.rb +152 -0
  75. data/lib/active_model/serializer/null.rb +19 -0
  76. data/lib/active_model/serializer/reflection.rb +212 -0
  77. data/lib/active_model/serializer/version.rb +7 -0
  78. data/lib/active_model_serializers.rb +63 -0
  79. data/lib/active_model_serializers/adapter.rb +100 -0
  80. data/lib/active_model_serializers/adapter/attributes.rb +15 -0
  81. data/lib/active_model_serializers/adapter/base.rb +85 -0
  82. data/lib/active_model_serializers/adapter/json.rb +23 -0
  83. data/lib/active_model_serializers/adapter/json_api.rb +535 -0
  84. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +215 -0
  85. data/lib/active_model_serializers/adapter/json_api/error.rb +98 -0
  86. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +51 -0
  87. data/lib/active_model_serializers/adapter/json_api/link.rb +85 -0
  88. data/lib/active_model_serializers/adapter/json_api/meta.rb +39 -0
  89. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +90 -0
  90. data/lib/active_model_serializers/adapter/json_api/relationship.rb +106 -0
  91. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +68 -0
  92. data/lib/active_model_serializers/adapter/null.rb +11 -0
  93. data/lib/active_model_serializers/callbacks.rb +57 -0
  94. data/lib/active_model_serializers/deprecate.rb +56 -0
  95. data/lib/active_model_serializers/deserialization.rb +17 -0
  96. data/lib/active_model_serializers/json_pointer.rb +16 -0
  97. data/lib/active_model_serializers/logging.rb +124 -0
  98. data/lib/active_model_serializers/lookup_chain.rb +82 -0
  99. data/lib/active_model_serializers/model.rb +132 -0
  100. data/lib/active_model_serializers/railtie.rb +52 -0
  101. data/lib/active_model_serializers/register_jsonapi_renderer.rb +80 -0
  102. data/lib/active_model_serializers/serializable_resource.rb +84 -0
  103. data/lib/active_model_serializers/serialization_context.rb +41 -0
  104. data/lib/active_model_serializers/test.rb +9 -0
  105. data/lib/active_model_serializers/test/schema.rb +140 -0
  106. data/lib/active_model_serializers/test/serializer.rb +127 -0
  107. data/lib/generators/rails/USAGE +6 -0
  108. data/lib/generators/rails/resource_override.rb +12 -0
  109. data/lib/generators/rails/serializer_generator.rb +38 -0
  110. data/lib/generators/rails/templates/serializer.rb.erb +8 -0
  111. data/lib/grape/active_model_serializers.rb +18 -0
  112. data/lib/grape/formatters/active_model_serializers.rb +34 -0
  113. data/lib/grape/helpers/active_model_serializers.rb +19 -0
  114. data/lib/tasks/rubocop.rake +55 -0
  115. data/test/action_controller/adapter_selector_test.rb +64 -0
  116. data/test/action_controller/explicit_serializer_test.rb +137 -0
  117. data/test/action_controller/json/include_test.rb +248 -0
  118. data/test/action_controller/json_api/deserialization_test.rb +114 -0
  119. data/test/action_controller/json_api/errors_test.rb +42 -0
  120. data/test/action_controller/json_api/fields_test.rb +68 -0
  121. data/test/action_controller/json_api/linked_test.rb +204 -0
  122. data/test/action_controller/json_api/pagination_test.rb +126 -0
  123. data/test/action_controller/json_api/transform_test.rb +191 -0
  124. data/test/action_controller/lookup_proc_test.rb +51 -0
  125. data/test/action_controller/namespace_lookup_test.rb +239 -0
  126. data/test/action_controller/serialization_scope_name_test.rb +237 -0
  127. data/test/action_controller/serialization_test.rb +480 -0
  128. data/test/active_model_serializers/adapter_for_test.rb +210 -0
  129. data/test/active_model_serializers/json_pointer_test.rb +24 -0
  130. data/test/active_model_serializers/logging_test.rb +79 -0
  131. data/test/active_model_serializers/model_test.rb +144 -0
  132. data/test/active_model_serializers/railtie_test_isolated.rb +70 -0
  133. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +163 -0
  134. data/test/active_model_serializers/serialization_context_test_isolated.rb +73 -0
  135. data/test/active_model_serializers/test/schema_test.rb +133 -0
  136. data/test/active_model_serializers/test/serializer_test.rb +64 -0
  137. data/test/active_record_test.rb +11 -0
  138. data/test/adapter/attributes_test.rb +42 -0
  139. data/test/adapter/deprecation_test.rb +102 -0
  140. data/test/adapter/json/belongs_to_test.rb +47 -0
  141. data/test/adapter/json/collection_test.rb +106 -0
  142. data/test/adapter/json/has_many_test.rb +55 -0
  143. data/test/adapter/json/transform_test.rb +95 -0
  144. data/test/adapter/json_api/belongs_to_test.rb +157 -0
  145. data/test/adapter/json_api/collection_test.rb +98 -0
  146. data/test/adapter/json_api/errors_test.rb +78 -0
  147. data/test/adapter/json_api/fields_test.rb +98 -0
  148. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
  149. data/test/adapter/json_api/has_many_test.rb +175 -0
  150. data/test/adapter/json_api/has_one_test.rb +82 -0
  151. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +215 -0
  152. data/test/adapter/json_api/json_api_test.rb +35 -0
  153. data/test/adapter/json_api/linked_test.rb +415 -0
  154. data/test/adapter/json_api/links_test.rb +112 -0
  155. data/test/adapter/json_api/pagination_links_test.rb +208 -0
  156. data/test/adapter/json_api/parse_test.rb +139 -0
  157. data/test/adapter/json_api/relationship_test.rb +399 -0
  158. data/test/adapter/json_api/resource_meta_test.rb +102 -0
  159. data/test/adapter/json_api/toplevel_jsonapi_test.rb +84 -0
  160. data/test/adapter/json_api/transform_test.rb +514 -0
  161. data/test/adapter/json_api/type_test.rb +195 -0
  162. data/test/adapter/json_test.rb +48 -0
  163. data/test/adapter/null_test.rb +24 -0
  164. data/test/adapter/polymorphic_test.rb +220 -0
  165. data/test/adapter_test.rb +69 -0
  166. data/test/array_serializer_test.rb +24 -0
  167. data/test/benchmark/app.rb +67 -0
  168. data/test/benchmark/benchmarking_support.rb +69 -0
  169. data/test/benchmark/bm_active_record.rb +83 -0
  170. data/test/benchmark/bm_adapter.rb +40 -0
  171. data/test/benchmark/bm_caching.rb +121 -0
  172. data/test/benchmark/bm_lookup_chain.rb +85 -0
  173. data/test/benchmark/bm_transform.rb +47 -0
  174. data/test/benchmark/config.ru +3 -0
  175. data/test/benchmark/controllers.rb +85 -0
  176. data/test/benchmark/fixtures.rb +221 -0
  177. data/test/cache_test.rb +717 -0
  178. data/test/collection_serializer_test.rb +129 -0
  179. data/test/fixtures/active_record.rb +115 -0
  180. data/test/fixtures/poro.rb +227 -0
  181. data/test/generators/scaffold_controller_generator_test.rb +26 -0
  182. data/test/generators/serializer_generator_test.rb +77 -0
  183. data/test/grape_test.rb +198 -0
  184. data/test/lint_test.rb +51 -0
  185. data/test/logger_test.rb +22 -0
  186. data/test/poro_test.rb +11 -0
  187. data/test/serializable_resource_test.rb +81 -0
  188. data/test/serializers/association_macros_test.rb +39 -0
  189. data/test/serializers/associations_test.rb +520 -0
  190. data/test/serializers/attribute_test.rb +155 -0
  191. data/test/serializers/attributes_test.rb +54 -0
  192. data/test/serializers/caching_configuration_test_isolated.rb +172 -0
  193. data/test/serializers/configuration_test.rb +34 -0
  194. data/test/serializers/fieldset_test.rb +16 -0
  195. data/test/serializers/meta_test.rb +204 -0
  196. data/test/serializers/options_test.rb +34 -0
  197. data/test/serializers/read_attribute_for_serialization_test.rb +81 -0
  198. data/test/serializers/reflection_test.rb +481 -0
  199. data/test/serializers/root_test.rb +23 -0
  200. data/test/serializers/serialization_test.rb +57 -0
  201. data/test/serializers/serializer_for_test.rb +138 -0
  202. data/test/serializers/serializer_for_with_namespace_test.rb +90 -0
  203. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  204. data/test/support/isolated_unit.rb +86 -0
  205. data/test/support/rails5_shims.rb +55 -0
  206. data/test/support/rails_app.rb +40 -0
  207. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  208. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +6 -0
  209. data/test/support/schemas/custom/show.json +7 -0
  210. data/test/support/schemas/hyper_schema.json +93 -0
  211. data/test/support/schemas/render_using_json_api.json +43 -0
  212. data/test/support/schemas/simple_json_pointers.json +10 -0
  213. data/test/support/serialization_testing.rb +81 -0
  214. data/test/test_helper.rb +72 -0
  215. metadata +622 -0
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module ActiveModelSerializers
6
+ module Adapter
7
+ class JsonApi
8
+ class HasManyTest < ActiveSupport::TestCase
9
+ class ModelWithoutSerializer < ::Model
10
+ attributes :id, :name
11
+ end
12
+
13
+ def setup
14
+ ActionController::Base.cache_store.clear
15
+ @author = Author.new(id: 1, name: 'Steve K.')
16
+ @author.posts = []
17
+ @author.bio = nil
18
+ @post = Post.new(id: 1, title: 'New Post', body: 'Body')
19
+ @post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
20
+ @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
21
+ @first_comment.author = nil
22
+ @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
23
+ @second_comment.author = nil
24
+ @post.comments = [@first_comment, @second_comment]
25
+ @post_without_comments.comments = []
26
+ @first_comment.post = @post
27
+ @second_comment.post = @post
28
+ @post.author = @author
29
+ @post_without_comments.author = nil
30
+ @blog = Blog.new(id: 1, name: 'My Blog!!')
31
+ @blog.writer = @author
32
+ @blog.articles = [@post]
33
+ @post.blog = @blog
34
+ @post_without_comments.blog = nil
35
+ @tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
36
+ @post.tags = [@tag]
37
+ @serializer = PostSerializer.new(@post)
38
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
39
+
40
+ @virtual_value = VirtualValue.new(id: 1)
41
+ end
42
+
43
+ def test_includes_comment_ids
44
+ expected = { data: [{ type: 'comments', id: '1' }, { type: 'comments', id: '2' }] }
45
+
46
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments])
47
+ end
48
+
49
+ test 'relationships can be whitelisted via fields' do
50
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, fields: { posts: [:author] })
51
+ result = @adapter.serializable_hash
52
+ expected = {
53
+ data: {
54
+ id: '1',
55
+ type: 'posts',
56
+ relationships: {
57
+ author: {
58
+ data: {
59
+ id: '1',
60
+ type: 'authors'
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ assert_equal expected, result
68
+ end
69
+
70
+ def test_includes_linked_comments
71
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:comments])
72
+ expected = [{
73
+ id: '1',
74
+ type: 'comments',
75
+ attributes: {
76
+ body: 'ZOMG A COMMENT'
77
+ },
78
+ relationships: {
79
+ post: { data: { type: 'posts', id: '1' } },
80
+ author: { data: nil }
81
+ }
82
+ }, {
83
+ id: '2',
84
+ type: 'comments',
85
+ attributes: {
86
+ body: 'ZOMG ANOTHER COMMENT'
87
+ },
88
+ relationships: {
89
+ post: { data: { type: 'posts', id: '1' } },
90
+ author: { data: nil }
91
+ }
92
+ }]
93
+ assert_equal expected, @adapter.serializable_hash[:included]
94
+ end
95
+
96
+ def test_limit_fields_of_linked_comments
97
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:comments], fields: { comment: [:id, :post, :author] })
98
+ expected = [{
99
+ id: '1',
100
+ type: 'comments',
101
+ relationships: {
102
+ post: { data: { type: 'posts', id: '1' } },
103
+ author: { data: nil }
104
+ }
105
+ }, {
106
+ id: '2',
107
+ type: 'comments',
108
+ relationships: {
109
+ post: { data: { type: 'posts', id: '1' } },
110
+ author: { data: nil }
111
+ }
112
+ }]
113
+ assert_equal expected, @adapter.serializable_hash[:included]
114
+ end
115
+
116
+ def test_no_include_linked_if_comments_is_empty
117
+ serializer = PostSerializer.new(@post_without_comments)
118
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
119
+
120
+ assert_nil adapter.serializable_hash[:linked]
121
+ end
122
+
123
+ def test_include_type_for_association_when_different_than_name
124
+ serializer = BlogSerializer.new(@blog)
125
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
126
+ actual = adapter.serializable_hash[:data][:relationships][:articles]
127
+
128
+ expected = {
129
+ data: [{
130
+ type: 'posts',
131
+ id: '1'
132
+ }]
133
+ }
134
+ assert_equal expected, actual
135
+ end
136
+
137
+ def test_has_many_with_no_serializer
138
+ post_serializer_class = Class.new(ActiveModel::Serializer) do
139
+ attributes :id
140
+ has_many :tags
141
+ end
142
+ serializer = post_serializer_class.new(@post)
143
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
144
+
145
+ assert_equal({
146
+ data: {
147
+ id: '1',
148
+ type: 'posts',
149
+ relationships: {
150
+ tags: { data: [@tag.as_json] }
151
+ }
152
+ }
153
+ }, adapter.serializable_hash)
154
+ end
155
+
156
+ def test_has_many_with_virtual_value
157
+ serializer = VirtualValueSerializer.new(@virtual_value)
158
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
159
+
160
+ assert_equal({
161
+ data: {
162
+ id: '1',
163
+ type: 'virtual-values',
164
+ relationships: {
165
+ maker: { data: { type: 'makers', id: '1' } },
166
+ reviews: { data: [{ type: 'reviews', id: '1' },
167
+ { type: 'reviews', id: '2' }] }
168
+ }
169
+ }
170
+ }, adapter.serializable_hash)
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module ActiveModelSerializers
6
+ module Adapter
7
+ class JsonApi
8
+ class HasOneTest < ActiveSupport::TestCase
9
+ def setup
10
+ @author = Author.new(id: 1, name: 'Steve K.')
11
+ @bio = Bio.new(id: 43, content: 'AMS Contributor')
12
+ @author.bio = @bio
13
+ @bio.author = @author
14
+ @post = Post.new(id: 42, title: 'New Post', body: 'Body')
15
+ @anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
16
+ @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
17
+ @post.comments = [@comment]
18
+ @anonymous_post.comments = []
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
+ @author.roles = []
28
+
29
+ @virtual_value = VirtualValue.new(id: 1)
30
+
31
+ @serializer = AuthorSerializer.new(@author)
32
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:bio, :posts])
33
+ end
34
+
35
+ def test_includes_bio_id
36
+ expected = { data: { type: 'bios', id: '43' } }
37
+
38
+ assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:bio])
39
+ end
40
+
41
+ def test_includes_linked_bio
42
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:bio])
43
+
44
+ expected = [
45
+ {
46
+ id: '43',
47
+ type: 'bios',
48
+ attributes: {
49
+ content: 'AMS Contributor',
50
+ rating: nil
51
+ },
52
+ relationships: {
53
+ author: { data: { type: 'authors', id: '1' } }
54
+ }
55
+ }
56
+ ]
57
+
58
+ assert_equal(expected, @adapter.serializable_hash[:included])
59
+ end
60
+
61
+ def test_has_one_with_virtual_value
62
+ serializer = VirtualValueSerializer.new(@virtual_value)
63
+ adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
64
+
65
+ expected = {
66
+ data: {
67
+ id: '1',
68
+ type: 'virtual-values',
69
+ relationships: {
70
+ maker: { data: { type: 'makers', id: '1' } },
71
+ reviews: { data: [{ type: 'reviews', id: '1' },
72
+ { type: 'reviews', id: '2' }] }
73
+ }
74
+ }
75
+ }
76
+
77
+ assert_equal(expected, adapter.serializable_hash)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,215 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module ActiveModel
6
+ class Serializer
7
+ module Adapter
8
+ class JsonApi
9
+ class IncludeParamTest < ActiveSupport::TestCase
10
+ IncludeParamAuthor = Class.new(::Model) do
11
+ associations :tags, :posts, :roles
12
+ end
13
+
14
+ class CustomCommentLoader
15
+ def all
16
+ [{ foo: 'bar' }]
17
+ end
18
+ end
19
+ class Tag < ::Model
20
+ attributes :id, :name
21
+ end
22
+
23
+ class TagSerializer < ActiveModel::Serializer
24
+ type 'tags'
25
+ attributes :id, :name
26
+ end
27
+
28
+ class PostWithTagsSerializer < ActiveModel::Serializer
29
+ type 'posts'
30
+ attributes :id
31
+ has_many :tags
32
+ end
33
+
34
+ class IncludeParamAuthorSerializer < ActiveModel::Serializer
35
+ class_attribute :comment_loader
36
+
37
+ has_many :tags, serializer: TagSerializer do
38
+ link :self, '//example.com/link_author/relationships/tags'
39
+ include_data :if_sideloaded
40
+ end
41
+
42
+ has_many :unlinked_tags, serializer: TagSerializer do
43
+ include_data :if_sideloaded
44
+ end
45
+
46
+ has_many :posts, serializer: PostWithTagsSerializer do
47
+ include_data :if_sideloaded
48
+ end
49
+ has_many :locations do
50
+ include_data :if_sideloaded
51
+ end
52
+ has_many :comments do
53
+ include_data :if_sideloaded
54
+ IncludeParamAuthorSerializer.comment_loader.all
55
+ end
56
+ has_many :roles, key: :granted_roles do
57
+ include_data :if_sideloaded
58
+ end
59
+ end
60
+
61
+ def setup
62
+ IncludeParamAuthorSerializer.comment_loader = Class.new(CustomCommentLoader).new
63
+ @tag = Tag.new(id: 1337, name: 'mytag')
64
+ @role = Role.new(id: 1337, name: 'myrole')
65
+ @author = IncludeParamAuthor.new(
66
+ id: 1337,
67
+ tags: [@tag],
68
+ roles: [@role]
69
+ )
70
+ end
71
+
72
+ def test_relationship_not_loaded_when_not_included
73
+ expected = {
74
+ links: {
75
+ self: '//example.com/link_author/relationships/tags'
76
+ }
77
+ }
78
+
79
+ @author.define_singleton_method(:read_attribute_for_serialization) do |attr|
80
+ fail 'should not be called' if attr == :tags
81
+ super(attr)
82
+ end
83
+
84
+ assert_relationship(:tags, expected)
85
+ end
86
+
87
+ def test_relationship_included
88
+ expected = {
89
+ data: [
90
+ {
91
+ id: '1337',
92
+ type: 'tags'
93
+ }
94
+ ],
95
+ links: {
96
+ self: '//example.com/link_author/relationships/tags'
97
+ }
98
+ }
99
+
100
+ assert_relationship(:tags, expected, include: :tags)
101
+ end
102
+
103
+ def test_sideloads_included
104
+ expected = [
105
+ {
106
+ id: '1337',
107
+ type: 'tags',
108
+ attributes: { name: 'mytag' }
109
+ }
110
+ ]
111
+ hash = result(include: :tags)
112
+ assert_equal(expected, hash[:included])
113
+ end
114
+
115
+ def test_sideloads_included_when_using_key
116
+ expected = [
117
+ {
118
+ id: '1337',
119
+ type: 'roles',
120
+ attributes: {
121
+ name: 'myrole',
122
+ description: nil,
123
+ slug: 'myrole-1337'
124
+ },
125
+ relationships: {
126
+ author: { data: nil }
127
+ }
128
+ }
129
+ ]
130
+
131
+ hash = result(include: :granted_roles)
132
+ assert_equal(expected, hash[:included])
133
+ end
134
+
135
+ def test_sideloads_not_included_when_using_name_when_key_defined
136
+ hash = result(include: :roles)
137
+ assert_nil(hash[:included])
138
+ end
139
+
140
+ def test_nested_relationship
141
+ expected = {
142
+ data: [
143
+ {
144
+ id: '1337',
145
+ type: 'tags'
146
+ }
147
+ ],
148
+ links: {
149
+ self: '//example.com/link_author/relationships/tags'
150
+ }
151
+ }
152
+
153
+ expected_no_data = {
154
+ links: {
155
+ self: '//example.com/link_author/relationships/tags'
156
+ }
157
+ }
158
+
159
+ assert_relationship(:tags, expected, include: [:tags, { posts: :tags }])
160
+
161
+ @author.define_singleton_method(:read_attribute_for_serialization) do |attr|
162
+ fail 'should not be called' if attr == :tags
163
+ super(attr)
164
+ end
165
+
166
+ assert_relationship(:tags, expected_no_data, include: { posts: :tags })
167
+ end
168
+
169
+ def test_include_params_with_no_block
170
+ @author.define_singleton_method(:read_attribute_for_serialization) do |attr|
171
+ fail 'should not be called' if attr == :locations
172
+ super(attr)
173
+ end
174
+
175
+ expected = { meta: {} }
176
+
177
+ assert_relationship(:locations, expected)
178
+ end
179
+
180
+ def test_block_relationship
181
+ expected = {
182
+ data: [
183
+ { 'foo' => 'bar' }
184
+ ]
185
+ }
186
+
187
+ assert_relationship(:comments, expected, include: [:comments])
188
+ end
189
+
190
+ def test_node_not_included_when_no_link
191
+ expected = { meta: {} }
192
+ assert_relationship(:unlinked_tags, expected, key_transform: :unaltered)
193
+ end
194
+
195
+ private
196
+
197
+ def assert_relationship(relationship_name, expected, opts = {})
198
+ actual = relationship_data(relationship_name, opts)
199
+ assert_equal(expected, actual)
200
+ end
201
+
202
+ def result(opts)
203
+ opts = { adapter: :json_api }.merge(opts)
204
+ serializable(@author, opts).serializable_hash
205
+ end
206
+
207
+ def relationship_data(relationship_name, opts = {})
208
+ hash = result(opts)
209
+ hash[:data][:relationships][relationship_name]
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end