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.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE.md +29 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- data/.gitignore +35 -0
- data/.rubocop.yml +109 -0
- data/.simplecov +110 -0
- data/.travis.yml +63 -0
- data/CHANGELOG.md +727 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +105 -0
- data/Gemfile +74 -0
- data/MIT-LICENSE +22 -0
- data/README.md +305 -0
- data/Rakefile +76 -0
- data/active_model_serializers.gemspec +64 -0
- data/appveyor.yml +28 -0
- data/bin/bench +171 -0
- data/bin/bench_regression +316 -0
- data/bin/rubocop +38 -0
- data/bin/serve_benchmark +39 -0
- data/docs/README.md +41 -0
- data/docs/STYLE.md +58 -0
- data/docs/general/adapters.md +269 -0
- data/docs/general/caching.md +58 -0
- data/docs/general/configuration_options.md +185 -0
- data/docs/general/deserialization.md +100 -0
- data/docs/general/fields.md +31 -0
- data/docs/general/getting_started.md +133 -0
- data/docs/general/instrumentation.md +40 -0
- data/docs/general/key_transforms.md +40 -0
- data/docs/general/logging.md +21 -0
- data/docs/general/rendering.md +293 -0
- data/docs/general/serializers.md +495 -0
- data/docs/how-open-source-maintained.jpg +0 -0
- data/docs/howto/add_pagination_links.md +138 -0
- data/docs/howto/add_relationship_links.md +140 -0
- data/docs/howto/add_root_key.md +62 -0
- data/docs/howto/grape_integration.md +42 -0
- data/docs/howto/outside_controller_use.md +66 -0
- data/docs/howto/passing_arbitrary_options.md +27 -0
- data/docs/howto/serialize_poro.md +73 -0
- data/docs/howto/test.md +154 -0
- data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
- data/docs/integrations/ember-and-json-api.md +147 -0
- data/docs/integrations/grape.md +19 -0
- data/docs/jsonapi/errors.md +56 -0
- data/docs/jsonapi/schema.md +151 -0
- data/docs/jsonapi/schema/schema.json +366 -0
- data/docs/rfcs/0000-namespace.md +106 -0
- data/docs/rfcs/template.md +15 -0
- data/lib/action_controller/serialization.rb +76 -0
- data/lib/active_model/serializable_resource.rb +13 -0
- data/lib/active_model/serializer.rb +418 -0
- data/lib/active_model/serializer/adapter.rb +26 -0
- data/lib/active_model/serializer/adapter/attributes.rb +17 -0
- data/lib/active_model/serializer/adapter/base.rb +20 -0
- data/lib/active_model/serializer/adapter/json.rb +17 -0
- data/lib/active_model/serializer/adapter/json_api.rb +17 -0
- data/lib/active_model/serializer/adapter/null.rb +17 -0
- data/lib/active_model/serializer/array_serializer.rb +14 -0
- data/lib/active_model/serializer/association.rb +91 -0
- data/lib/active_model/serializer/attribute.rb +27 -0
- data/lib/active_model/serializer/belongs_to_reflection.rb +13 -0
- data/lib/active_model/serializer/collection_serializer.rb +90 -0
- data/lib/active_model/serializer/concerns/caching.rb +304 -0
- data/lib/active_model/serializer/error_serializer.rb +16 -0
- data/lib/active_model/serializer/errors_serializer.rb +34 -0
- data/lib/active_model/serializer/field.rb +92 -0
- data/lib/active_model/serializer/fieldset.rb +33 -0
- data/lib/active_model/serializer/has_many_reflection.rb +12 -0
- data/lib/active_model/serializer/has_one_reflection.rb +9 -0
- data/lib/active_model/serializer/lazy_association.rb +99 -0
- data/lib/active_model/serializer/link.rb +23 -0
- data/lib/active_model/serializer/lint.rb +152 -0
- data/lib/active_model/serializer/null.rb +19 -0
- data/lib/active_model/serializer/reflection.rb +212 -0
- data/lib/active_model/serializer/version.rb +7 -0
- data/lib/active_model_serializers.rb +63 -0
- data/lib/active_model_serializers/adapter.rb +100 -0
- data/lib/active_model_serializers/adapter/attributes.rb +15 -0
- data/lib/active_model_serializers/adapter/base.rb +85 -0
- data/lib/active_model_serializers/adapter/json.rb +23 -0
- data/lib/active_model_serializers/adapter/json_api.rb +535 -0
- data/lib/active_model_serializers/adapter/json_api/deserialization.rb +215 -0
- data/lib/active_model_serializers/adapter/json_api/error.rb +98 -0
- data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +51 -0
- data/lib/active_model_serializers/adapter/json_api/link.rb +85 -0
- data/lib/active_model_serializers/adapter/json_api/meta.rb +39 -0
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +90 -0
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +106 -0
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +68 -0
- data/lib/active_model_serializers/adapter/null.rb +11 -0
- data/lib/active_model_serializers/callbacks.rb +57 -0
- data/lib/active_model_serializers/deprecate.rb +56 -0
- data/lib/active_model_serializers/deserialization.rb +17 -0
- data/lib/active_model_serializers/json_pointer.rb +16 -0
- data/lib/active_model_serializers/logging.rb +124 -0
- data/lib/active_model_serializers/lookup_chain.rb +82 -0
- data/lib/active_model_serializers/model.rb +132 -0
- data/lib/active_model_serializers/railtie.rb +52 -0
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +80 -0
- data/lib/active_model_serializers/serializable_resource.rb +84 -0
- data/lib/active_model_serializers/serialization_context.rb +41 -0
- data/lib/active_model_serializers/test.rb +9 -0
- data/lib/active_model_serializers/test/schema.rb +140 -0
- data/lib/active_model_serializers/test/serializer.rb +127 -0
- data/lib/generators/rails/USAGE +6 -0
- data/lib/generators/rails/resource_override.rb +12 -0
- data/lib/generators/rails/serializer_generator.rb +38 -0
- data/lib/generators/rails/templates/serializer.rb.erb +8 -0
- data/lib/grape/active_model_serializers.rb +18 -0
- data/lib/grape/formatters/active_model_serializers.rb +34 -0
- data/lib/grape/helpers/active_model_serializers.rb +19 -0
- data/lib/tasks/rubocop.rake +55 -0
- data/test/action_controller/adapter_selector_test.rb +64 -0
- data/test/action_controller/explicit_serializer_test.rb +137 -0
- data/test/action_controller/json/include_test.rb +248 -0
- data/test/action_controller/json_api/deserialization_test.rb +114 -0
- data/test/action_controller/json_api/errors_test.rb +42 -0
- data/test/action_controller/json_api/fields_test.rb +68 -0
- data/test/action_controller/json_api/linked_test.rb +204 -0
- data/test/action_controller/json_api/pagination_test.rb +126 -0
- data/test/action_controller/json_api/transform_test.rb +191 -0
- data/test/action_controller/lookup_proc_test.rb +51 -0
- data/test/action_controller/namespace_lookup_test.rb +239 -0
- data/test/action_controller/serialization_scope_name_test.rb +237 -0
- data/test/action_controller/serialization_test.rb +480 -0
- data/test/active_model_serializers/adapter_for_test.rb +210 -0
- data/test/active_model_serializers/json_pointer_test.rb +24 -0
- data/test/active_model_serializers/logging_test.rb +79 -0
- data/test/active_model_serializers/model_test.rb +144 -0
- data/test/active_model_serializers/railtie_test_isolated.rb +70 -0
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +163 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +73 -0
- data/test/active_model_serializers/test/schema_test.rb +133 -0
- data/test/active_model_serializers/test/serializer_test.rb +64 -0
- data/test/active_record_test.rb +11 -0
- data/test/adapter/attributes_test.rb +42 -0
- data/test/adapter/deprecation_test.rb +102 -0
- data/test/adapter/json/belongs_to_test.rb +47 -0
- data/test/adapter/json/collection_test.rb +106 -0
- data/test/adapter/json/has_many_test.rb +55 -0
- data/test/adapter/json/transform_test.rb +95 -0
- data/test/adapter/json_api/belongs_to_test.rb +157 -0
- data/test/adapter/json_api/collection_test.rb +98 -0
- data/test/adapter/json_api/errors_test.rb +78 -0
- data/test/adapter/json_api/fields_test.rb +98 -0
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
- data/test/adapter/json_api/has_many_test.rb +175 -0
- data/test/adapter/json_api/has_one_test.rb +82 -0
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +215 -0
- data/test/adapter/json_api/json_api_test.rb +35 -0
- data/test/adapter/json_api/linked_test.rb +415 -0
- data/test/adapter/json_api/links_test.rb +112 -0
- data/test/adapter/json_api/pagination_links_test.rb +208 -0
- data/test/adapter/json_api/parse_test.rb +139 -0
- data/test/adapter/json_api/relationship_test.rb +399 -0
- data/test/adapter/json_api/resource_meta_test.rb +102 -0
- data/test/adapter/json_api/toplevel_jsonapi_test.rb +84 -0
- data/test/adapter/json_api/transform_test.rb +514 -0
- data/test/adapter/json_api/type_test.rb +195 -0
- data/test/adapter/json_test.rb +48 -0
- data/test/adapter/null_test.rb +24 -0
- data/test/adapter/polymorphic_test.rb +220 -0
- data/test/adapter_test.rb +69 -0
- data/test/array_serializer_test.rb +24 -0
- data/test/benchmark/app.rb +67 -0
- data/test/benchmark/benchmarking_support.rb +69 -0
- data/test/benchmark/bm_active_record.rb +83 -0
- data/test/benchmark/bm_adapter.rb +40 -0
- data/test/benchmark/bm_caching.rb +121 -0
- data/test/benchmark/bm_lookup_chain.rb +85 -0
- data/test/benchmark/bm_transform.rb +47 -0
- data/test/benchmark/config.ru +3 -0
- data/test/benchmark/controllers.rb +85 -0
- data/test/benchmark/fixtures.rb +221 -0
- data/test/cache_test.rb +717 -0
- data/test/collection_serializer_test.rb +129 -0
- data/test/fixtures/active_record.rb +115 -0
- data/test/fixtures/poro.rb +227 -0
- data/test/generators/scaffold_controller_generator_test.rb +26 -0
- data/test/generators/serializer_generator_test.rb +77 -0
- data/test/grape_test.rb +198 -0
- data/test/lint_test.rb +51 -0
- data/test/logger_test.rb +22 -0
- data/test/poro_test.rb +11 -0
- data/test/serializable_resource_test.rb +81 -0
- data/test/serializers/association_macros_test.rb +39 -0
- data/test/serializers/associations_test.rb +520 -0
- data/test/serializers/attribute_test.rb +155 -0
- data/test/serializers/attributes_test.rb +54 -0
- data/test/serializers/caching_configuration_test_isolated.rb +172 -0
- data/test/serializers/configuration_test.rb +34 -0
- data/test/serializers/fieldset_test.rb +16 -0
- data/test/serializers/meta_test.rb +204 -0
- data/test/serializers/options_test.rb +34 -0
- data/test/serializers/read_attribute_for_serialization_test.rb +81 -0
- data/test/serializers/reflection_test.rb +481 -0
- data/test/serializers/root_test.rb +23 -0
- data/test/serializers/serialization_test.rb +57 -0
- data/test/serializers/serializer_for_test.rb +138 -0
- data/test/serializers/serializer_for_with_namespace_test.rb +90 -0
- data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
- data/test/support/isolated_unit.rb +86 -0
- data/test/support/rails5_shims.rb +55 -0
- data/test/support/rails_app.rb +40 -0
- data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
- data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +6 -0
- data/test/support/schemas/custom/show.json +7 -0
- data/test/support/schemas/hyper_schema.json +93 -0
- data/test/support/schemas/render_using_json_api.json +43 -0
- data/test/support/schemas/simple_json_pointers.json +10 -0
- data/test/support/serialization_testing.rb +81 -0
- data/test/test_helper.rb +72 -0
- 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
|