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,191 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module ActionController
6
+ module Serialization
7
+ class JsonApi
8
+ class KeyTransformTest < ActionController::TestCase
9
+ class KeyTransformTestController < ActionController::Base
10
+ class Post < ::Model
11
+ attributes :title, :body, :publish_at
12
+ associations :author, :top_comments
13
+ end
14
+ class Author < ::Model
15
+ attributes :first_name, :last_name
16
+ end
17
+ class TopComment < ::Model
18
+ attributes :body
19
+ associations :author, :post
20
+ end
21
+ class PostSerializer < ActiveModel::Serializer
22
+ type 'posts'
23
+ attributes :title, :body, :publish_at
24
+ belongs_to :author
25
+ has_many :top_comments
26
+
27
+ link(:post_authors) { 'https://example.com/post_authors' }
28
+
29
+ meta do
30
+ {
31
+ rating: 5,
32
+ favorite_count: 10
33
+ }
34
+ end
35
+ end
36
+
37
+ class AuthorSerializer < ActiveModel::Serializer
38
+ type 'authors'
39
+ attributes :first_name, :last_name
40
+ end
41
+
42
+ class TopCommentSerializer < ActiveModel::Serializer
43
+ type 'top_comments'
44
+ attributes :body
45
+ belongs_to :author
46
+ end
47
+
48
+ def setup_post
49
+ ActionController::Base.cache_store.clear
50
+ @author = Author.new(id: 1, first_name: 'Bob', last_name: 'Jones')
51
+ @comment1 = TopComment.new(id: 7, body: 'cool', author: @author)
52
+ @comment2 = TopComment.new(id: 12, body: 'awesome', author: @author)
53
+ @post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1',
54
+ author: @author, top_comments: [@comment1, @comment2],
55
+ publish_at: '2020-03-16T03:55:25.291Z')
56
+ @comment1.post = @post
57
+ @comment2.post = @post
58
+ end
59
+
60
+ def render_resource_with_transform
61
+ setup_post
62
+ render json: @post, serializer: PostSerializer, adapter: :json_api,
63
+ key_transform: :camel
64
+ end
65
+
66
+ def render_resource_with_transform_nil
67
+ setup_post
68
+ render json: @post, serializer: PostSerializer, adapter: :json_api,
69
+ key_transform: nil
70
+ end
71
+
72
+ def render_resource_with_transform_with_global_config
73
+ old_transform = ActiveModelSerializers.config.key_transform
74
+ setup_post
75
+ ActiveModelSerializers.config.key_transform = :camel_lower
76
+ render json: @post, serializer: PostSerializer, adapter: :json_api
77
+ ensure
78
+ ActiveModelSerializers.config.key_transform = old_transform
79
+ end
80
+ end
81
+
82
+ tests KeyTransformTestController
83
+
84
+ def test_render_resource_with_transform
85
+ get :render_resource_with_transform
86
+ response = JSON.parse(@response.body)
87
+ expected = {
88
+ 'Data' => {
89
+ 'Id' => '1337',
90
+ 'Type' => 'Posts',
91
+ 'Attributes' => {
92
+ 'Title' => 'Title 1',
93
+ 'Body' => 'Body 1',
94
+ 'PublishAt' => '2020-03-16T03:55:25.291Z'
95
+ },
96
+ 'Relationships' => {
97
+ 'Author' => {
98
+ 'Data' => {
99
+ 'Id' => '1',
100
+ 'Type' => 'Authors'
101
+ }
102
+ },
103
+ 'TopComments' => {
104
+ 'Data' => [
105
+ { 'Id' => '7', 'Type' => 'TopComments' },
106
+ { 'Id' => '12', 'Type' => 'TopComments' }
107
+ ]
108
+ }
109
+ },
110
+ 'Links' => {
111
+ 'PostAuthors' => 'https://example.com/post_authors'
112
+ },
113
+ 'Meta' => { 'Rating' => 5, 'FavoriteCount' => 10 }
114
+ }
115
+ }
116
+ assert_equal expected, response
117
+ end
118
+
119
+ def test_render_resource_with_transform_nil
120
+ get :render_resource_with_transform_nil
121
+ response = JSON.parse(@response.body)
122
+ expected = {
123
+ 'data' => {
124
+ 'id' => '1337',
125
+ 'type' => 'posts',
126
+ 'attributes' => {
127
+ 'title' => 'Title 1',
128
+ 'body' => 'Body 1',
129
+ 'publish-at' => '2020-03-16T03:55:25.291Z'
130
+ },
131
+ 'relationships' => {
132
+ 'author' => {
133
+ 'data' => {
134
+ 'id' => '1',
135
+ 'type' => 'authors'
136
+ }
137
+ },
138
+ 'top-comments' => {
139
+ 'data' => [
140
+ { 'id' => '7', 'type' => 'top-comments' },
141
+ { 'id' => '12', 'type' => 'top-comments' }
142
+ ]
143
+ }
144
+ },
145
+ 'links' => {
146
+ 'post-authors' => 'https://example.com/post_authors'
147
+ },
148
+ 'meta' => { 'rating' => 5, 'favorite-count' => 10 }
149
+ }
150
+ }
151
+ assert_equal expected, response
152
+ end
153
+
154
+ def test_render_resource_with_transform_with_global_config
155
+ get :render_resource_with_transform_with_global_config
156
+ response = JSON.parse(@response.body)
157
+ expected = {
158
+ 'data' => {
159
+ 'id' => '1337',
160
+ 'type' => 'posts',
161
+ 'attributes' => {
162
+ 'title' => 'Title 1',
163
+ 'body' => 'Body 1',
164
+ 'publishAt' => '2020-03-16T03:55:25.291Z'
165
+ },
166
+ 'relationships' => {
167
+ 'author' => {
168
+ 'data' => {
169
+ 'id' => '1',
170
+ 'type' => 'authors'
171
+ }
172
+ },
173
+ 'topComments' => {
174
+ 'data' => [
175
+ { 'id' => '7', 'type' => 'topComments' },
176
+ { 'id' => '12', 'type' => 'topComments' }
177
+ ]
178
+ }
179
+ },
180
+ 'links' => {
181
+ 'postAuthors' => 'https://example.com/post_authors'
182
+ },
183
+ 'meta' => { 'rating' => 5, 'favoriteCount' => 10 }
184
+ }
185
+ }
186
+ assert_equal expected, response
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module ActionController
6
+ module Serialization
7
+ class LookupProcTest < ActionController::TestCase
8
+ module Api
9
+ module V3
10
+ class PostCustomSerializer < ActiveModel::Serializer
11
+ attributes :title, :body
12
+
13
+ belongs_to :author
14
+ end
15
+
16
+ class AuthorCustomSerializer < ActiveModel::Serializer
17
+ attributes :name
18
+ end
19
+
20
+ class LookupProcTestController < ActionController::Base
21
+ def implicit_namespaced_serializer
22
+ author = Author.new(name: 'Bob')
23
+ post = Post.new(title: 'New Post', body: 'Body', author: author)
24
+
25
+ render json: post
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ tests Api::V3::LookupProcTestController
32
+
33
+ test 'implicitly uses namespaced serializer' do
34
+ controller_namespace = lambda do |resource_class, _parent_serializer_class, namespace|
35
+ "#{namespace}::#{resource_class}CustomSerializer" if namespace
36
+ end
37
+
38
+ with_prepended_lookup(controller_namespace) do
39
+ get :implicit_namespaced_serializer
40
+
41
+ assert_serializer Api::V3::PostCustomSerializer
42
+
43
+ expected = { 'title' => 'New Post', 'body' => 'Body', 'author' => { 'name' => 'Bob' } }
44
+ actual = JSON.parse(@response.body)
45
+
46
+ assert_equal expected, actual
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,239 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module ActionController
6
+ module Serialization
7
+ class NamespaceLookupTest < ActionController::TestCase
8
+ class Book < ::Model
9
+ attributes :id, :title, :body
10
+ associations :writer, :chapters
11
+ end
12
+ class Chapter < ::Model
13
+ attributes :title
14
+ end
15
+ class Writer < ::Model
16
+ attributes :name
17
+ end
18
+
19
+ module Api
20
+ module V2
21
+ class BookSerializer < ActiveModel::Serializer
22
+ attributes :title
23
+ end
24
+ end
25
+
26
+ module VHeader
27
+ class BookSerializer < ActiveModel::Serializer
28
+ attributes :title, :body
29
+
30
+ def body
31
+ 'header'
32
+ end
33
+ end
34
+ end
35
+
36
+ module V3
37
+ class BookSerializer < ActiveModel::Serializer
38
+ attributes :title, :body
39
+
40
+ belongs_to :writer
41
+ has_many :chapters
42
+ end
43
+
44
+ class ChapterSerializer < ActiveModel::Serializer
45
+ attribute :title do
46
+ "Chapter - #{object.title}"
47
+ end
48
+ end
49
+
50
+ class WriterSerializer < ActiveModel::Serializer
51
+ attributes :name
52
+ end
53
+
54
+ class LookupTestController < ActionController::Base
55
+ before_action only: [:namespace_set_in_before_filter] do
56
+ self.namespace_for_serializer = Api::V2
57
+ end
58
+
59
+ def implicit_namespaced_serializer
60
+ writer = Writer.new(name: 'Bob')
61
+ book = Book.new(title: 'New Post', body: 'Body', writer: writer, chapters: [])
62
+
63
+ render json: book
64
+ end
65
+
66
+ def implicit_namespaced_collection_serializer
67
+ chapter1 = Chapter.new(title: 'Oh')
68
+ chapter2 = Chapter.new(title: 'Oh my')
69
+
70
+ render json: [chapter1, chapter2]
71
+ end
72
+
73
+ def implicit_has_many_namespaced_serializer
74
+ chapter1 = Chapter.new(title: 'Odd World')
75
+ chapter2 = Chapter.new(title: 'New World')
76
+ book = Book.new(title: 'New Post', body: 'Body', chapters: [chapter1, chapter2])
77
+
78
+ render json: book
79
+ end
80
+
81
+ def explicit_namespace_as_module
82
+ book = Book.new(title: 'New Post', body: 'Body')
83
+
84
+ render json: book, namespace: Api::V2
85
+ end
86
+
87
+ def explicit_namespace_as_string
88
+ book = Book.new(title: 'New Post', body: 'Body')
89
+
90
+ # because this is a string, ruby can't auto-lookup the constant, so otherwise
91
+ # the lookup thinks we mean ::Api::V2
92
+ render json: book, namespace: 'ActionController::Serialization::NamespaceLookupTest::Api::V2'
93
+ end
94
+
95
+ def explicit_namespace_as_symbol
96
+ book = Book.new(title: 'New Post', body: 'Body')
97
+
98
+ # because this is a string, ruby can't auto-lookup the constant, so otherwise
99
+ # the lookup thinks we mean ::Api::V2
100
+ render json: book, namespace: :'ActionController::Serialization::NamespaceLookupTest::Api::V2'
101
+ end
102
+
103
+ def invalid_namespace
104
+ book = Book.new(id: 'invalid_namespace_book_id', title: 'New Post', body: 'Body')
105
+
106
+ render json: book, namespace: :api_v2
107
+ end
108
+
109
+ def namespace_set_in_before_filter
110
+ book = Book.new(title: 'New Post', body: 'Body')
111
+ render json: book
112
+ end
113
+
114
+ def namespace_set_by_request_headers
115
+ book = Book.new(title: 'New Post', body: 'Body')
116
+ version_from_header = request.headers['X-API_VERSION']
117
+ namespace = "ActionController::Serialization::NamespaceLookupTest::#{version_from_header}"
118
+
119
+ render json: book, namespace: namespace
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ tests Api::V3::LookupTestController
126
+
127
+ setup do
128
+ @test_namespace =
129
+ if Module.method_defined?(:module_parent)
130
+ self.class.module_parent
131
+ else
132
+ self.class.parent
133
+ end
134
+ end
135
+
136
+ test 'uses request headers to determine the namespace' do
137
+ request.env['X-API_VERSION'] = 'Api::VHeader'
138
+ get :namespace_set_by_request_headers
139
+
140
+ assert_serializer Api::VHeader::BookSerializer
141
+ end
142
+
143
+ test 'implicitly uses namespaced serializer' do
144
+ get :implicit_namespaced_serializer
145
+
146
+ assert_serializer Api::V3::BookSerializer
147
+
148
+ expected = { 'title' => 'New Post', 'body' => 'Body', 'writer' => { 'name' => 'Bob' }, 'chapters' => [] }
149
+ actual = JSON.parse(@response.body)
150
+
151
+ assert_equal expected, actual
152
+ end
153
+
154
+ test 'implicitly uses namespaced serializer for collection' do
155
+ get :implicit_namespaced_collection_serializer
156
+
157
+ assert_serializer 'ActiveModel::Serializer::CollectionSerializer'
158
+
159
+ expected = [{ 'title' => 'Chapter - Oh' }, { 'title' => 'Chapter - Oh my' }]
160
+ actual = JSON.parse(@response.body)
161
+
162
+ assert_equal expected, actual
163
+ end
164
+
165
+ test 'implicitly uses namespaced serializer for has_many' do
166
+ get :implicit_has_many_namespaced_serializer
167
+
168
+ assert_serializer Api::V3::BookSerializer
169
+
170
+ expected = {
171
+ 'title' => 'New Post',
172
+ 'body' => 'Body', 'writer' => nil,
173
+ 'chapters' => [
174
+ { 'title' => 'Chapter - Odd World' },
175
+ { 'title' => 'Chapter - New World' }
176
+ ]
177
+ }
178
+ actual = JSON.parse(@response.body)
179
+
180
+ assert_equal expected, actual
181
+ end
182
+
183
+ test 'explicit namespace as module' do
184
+ get :explicit_namespace_as_module
185
+
186
+ assert_serializer Api::V2::BookSerializer
187
+
188
+ expected = { 'title' => 'New Post' }
189
+ actual = JSON.parse(@response.body)
190
+
191
+ assert_equal expected, actual
192
+ end
193
+
194
+ test 'explicit namespace as string' do
195
+ get :explicit_namespace_as_string
196
+
197
+ assert_serializer Api::V2::BookSerializer
198
+
199
+ expected = { 'title' => 'New Post' }
200
+ actual = JSON.parse(@response.body)
201
+
202
+ assert_equal expected, actual
203
+ end
204
+
205
+ test 'explicit namespace as symbol' do
206
+ get :explicit_namespace_as_symbol
207
+
208
+ assert_serializer Api::V2::BookSerializer
209
+
210
+ expected = { 'title' => 'New Post' }
211
+ actual = JSON.parse(@response.body)
212
+
213
+ assert_equal expected, actual
214
+ end
215
+
216
+ test 'invalid namespace' do
217
+ get :invalid_namespace
218
+
219
+ assert_serializer ActiveModel::Serializer::Null
220
+
221
+ expected = { 'id' => 'invalid_namespace_book_id', 'title' => 'New Post', 'body' => 'Body' }
222
+ actual = JSON.parse(@response.body)
223
+
224
+ assert_equal expected, actual
225
+ end
226
+
227
+ test 'namespace set in before filter' do
228
+ get :namespace_set_in_before_filter
229
+
230
+ assert_serializer Api::V2::BookSerializer
231
+
232
+ expected = { 'title' => 'New Post' }
233
+ actual = JSON.parse(@response.body)
234
+
235
+ assert_equal expected, actual
236
+ end
237
+ end
238
+ end
239
+ end