active_model_serializers 0.10.0 → 0.10.3
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 +4 -4
- data/.rubocop.yml +2 -4
- data/.travis.yml +9 -1
- data/CHANGELOG.md +81 -2
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -2
- data/README.md +24 -24
- data/Rakefile +3 -3
- data/active_model_serializers.gemspec +20 -24
- data/docs/ARCHITECTURE.md +6 -7
- data/docs/README.md +2 -0
- data/docs/general/adapters.md +4 -2
- data/docs/general/caching.md +7 -1
- data/docs/general/configuration_options.md +70 -1
- data/docs/general/deserialization.md +1 -1
- data/docs/general/fields.md +31 -0
- data/docs/general/rendering.md +42 -3
- data/docs/general/serializers.md +97 -8
- data/docs/howto/add_pagination_links.md +4 -5
- data/docs/howto/add_relationship_links.md +137 -0
- data/docs/howto/add_root_key.md +4 -0
- data/docs/howto/grape_integration.md +42 -0
- data/docs/howto/outside_controller_use.md +9 -2
- data/docs/howto/passing_arbitrary_options.md +2 -2
- data/docs/howto/test.md +2 -0
- data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
- data/docs/integrations/ember-and-json-api.md +64 -32
- data/docs/jsonapi/schema.md +1 -1
- data/lib/action_controller/serialization.rb +13 -3
- data/lib/active_model/serializer/adapter/base.rb +2 -0
- data/lib/active_model/serializer/array_serializer.rb +8 -5
- data/lib/active_model/serializer/association.rb +19 -4
- data/lib/active_model/serializer/belongs_to_reflection.rb +0 -3
- data/lib/active_model/serializer/collection_serializer.rb +35 -12
- data/lib/active_model/serializer/{associations.rb → concerns/associations.rb} +13 -11
- data/lib/active_model/serializer/{attributes.rb → concerns/attributes.rb} +0 -0
- data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +72 -113
- data/lib/active_model/serializer/{configuration.rb → concerns/configuration.rb} +25 -1
- data/lib/active_model/serializer/{links.rb → concerns/links.rb} +0 -0
- data/lib/active_model/serializer/{meta.rb → concerns/meta.rb} +0 -0
- data/lib/active_model/serializer/{type.rb → concerns/type.rb} +0 -0
- data/lib/active_model/serializer/error_serializer.rb +11 -7
- data/lib/active_model/serializer/errors_serializer.rb +25 -20
- data/lib/active_model/serializer/has_many_reflection.rb +0 -3
- data/lib/active_model/serializer/has_one_reflection.rb +0 -3
- data/lib/active_model/serializer/lint.rb +134 -130
- data/lib/active_model/serializer/reflection.rb +37 -21
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model/serializer.rb +76 -37
- data/lib/active_model_serializers/adapter/attributes.rb +3 -66
- data/lib/active_model_serializers/adapter/base.rb +38 -38
- data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +8 -1
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +30 -19
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +23 -9
- data/lib/active_model_serializers/adapter/json_api.rb +44 -43
- data/lib/active_model_serializers/adapter.rb +6 -0
- data/lib/active_model_serializers/deprecate.rb +1 -2
- data/lib/active_model_serializers/deserialization.rb +2 -0
- data/lib/active_model_serializers/key_transform.rb +4 -0
- data/lib/active_model_serializers/lookup_chain.rb +80 -0
- data/lib/active_model_serializers/model.rb +4 -2
- data/lib/active_model_serializers/railtie.rb +3 -1
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
- data/lib/active_model_serializers/serializable_resource.rb +6 -5
- data/lib/active_model_serializers/serialization_context.rb +10 -3
- data/lib/active_model_serializers.rb +7 -0
- data/lib/generators/rails/serializer_generator.rb +4 -4
- data/lib/grape/active_model_serializers.rb +7 -5
- data/lib/grape/formatters/active_model_serializers.rb +19 -2
- data/lib/grape/helpers/active_model_serializers.rb +1 -0
- data/test/action_controller/adapter_selector_test.rb +4 -4
- data/test/action_controller/explicit_serializer_test.rb +5 -4
- data/test/action_controller/json/include_test.rb +106 -27
- data/test/action_controller/json_api/errors_test.rb +6 -7
- data/test/action_controller/json_api/fields_test.rb +57 -0
- data/test/action_controller/json_api/linked_test.rb +29 -24
- data/test/action_controller/json_api/pagination_test.rb +19 -19
- data/test/action_controller/json_api/transform_test.rb +3 -3
- data/test/action_controller/lookup_proc_test.rb +49 -0
- data/test/action_controller/namespace_lookup_test.rb +226 -0
- data/test/action_controller/serialization_test.rb +10 -7
- data/test/active_model_serializers/json_pointer_test.rb +15 -13
- data/test/active_model_serializers/key_transform_test.rb +286 -252
- data/test/active_model_serializers/model_test.rb +17 -4
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +143 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
- data/test/adapter/attributes_test.rb +43 -0
- data/test/adapter/json/collection_test.rb +14 -0
- data/test/adapter/json/transform_test.rb +15 -15
- data/test/adapter/json_api/collection_test.rb +4 -3
- data/test/adapter/json_api/errors_test.rb +17 -19
- data/test/adapter/json_api/fields_test.rb +4 -3
- data/test/adapter/json_api/has_many_test.rb +39 -18
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +166 -0
- data/test/adapter/json_api/json_api_test.rb +5 -7
- data/test/adapter/json_api/linked_test.rb +33 -12
- data/test/adapter/json_api/links_test.rb +4 -2
- data/test/adapter/json_api/pagination_links_test.rb +35 -8
- data/test/adapter/json_api/relationship_test.rb +309 -73
- data/test/adapter/json_api/resource_identifier_test.rb +27 -2
- data/test/adapter/json_api/resource_meta_test.rb +3 -3
- data/test/adapter/json_api/transform_test.rb +255 -253
- data/test/adapter/json_api/type_test.rb +1 -1
- data/test/adapter/json_test.rb +8 -7
- data/test/adapter/null_test.rb +1 -2
- data/test/adapter/polymorphic_test.rb +5 -5
- data/test/adapter_test.rb +1 -1
- data/test/benchmark/app.rb +1 -1
- data/test/benchmark/benchmarking_support.rb +1 -1
- data/test/benchmark/bm_active_record.rb +81 -0
- data/test/benchmark/bm_adapter.rb +38 -0
- data/test/benchmark/bm_caching.rb +16 -16
- data/test/benchmark/bm_lookup_chain.rb +83 -0
- data/test/benchmark/bm_transform.rb +16 -5
- data/test/benchmark/controllers.rb +16 -17
- data/test/benchmark/fixtures.rb +72 -72
- data/test/cache_test.rb +143 -49
- data/test/collection_serializer_test.rb +3 -3
- data/test/fixtures/poro.rb +52 -48
- data/test/generators/serializer_generator_test.rb +22 -5
- data/test/grape_test.rb +152 -56
- data/test/lint_test.rb +1 -1
- data/test/logger_test.rb +13 -11
- data/test/serializable_resource_test.rb +18 -22
- data/test/serializers/association_macros_test.rb +3 -2
- data/test/serializers/associations_test.rb +107 -32
- data/test/serializers/attribute_test.rb +2 -2
- data/test/serializers/attributes_test.rb +1 -1
- data/test/serializers/fieldset_test.rb +1 -1
- data/test/serializers/meta_test.rb +12 -6
- data/test/serializers/root_test.rb +1 -1
- data/test/serializers/serializer_for_test.rb +6 -4
- data/test/serializers/serializer_for_with_namespace_test.rb +87 -0
- data/test/support/isolated_unit.rb +5 -2
- data/test/support/rails5_shims.rb +8 -2
- data/test/support/rails_app.rb +0 -9
- data/test/support/serialization_testing.rb +23 -5
- data/test/test_helper.rb +1 -0
- metadata +85 -34
- data/.rubocop_todo.yml +0 -167
- data/lib/active_model/serializer/include_tree.rb +0 -111
- data/test/adapter/json_api/relationships_test.rb +0 -199
- data/test/include_tree/from_include_args_test.rb +0 -26
- data/test/include_tree/from_string_test.rb +0 -94
- data/test/include_tree/include_args_to_hash_test.rb +0 -64
@@ -3,9 +3,8 @@ require 'test_helper'
|
|
3
3
|
module ActionController
|
4
4
|
module Serialization
|
5
5
|
class JsonApi
|
6
|
-
class LinkedTest <
|
6
|
+
class LinkedTest < ActionDispatch::IntegrationTest
|
7
7
|
class LinkedTestController < ActionController::Base
|
8
|
-
require 'active_model_serializers/register_jsonapi_renderer'
|
9
8
|
def setup_post
|
10
9
|
ActionController::Base.cache_store.clear
|
11
10
|
@role1 = Role.new(id: 1, name: 'admin')
|
@@ -39,62 +38,68 @@ module ActionController
|
|
39
38
|
|
40
39
|
def render_resource_without_include
|
41
40
|
setup_post
|
42
|
-
render
|
41
|
+
render json: @post
|
43
42
|
end
|
44
43
|
|
45
44
|
def render_resource_with_include
|
46
45
|
setup_post
|
47
|
-
render
|
46
|
+
render json: @post, adapter: :json_api, include: [:author]
|
48
47
|
end
|
49
48
|
|
50
49
|
def render_resource_with_include_of_custom_key_by_original
|
51
50
|
setup_post
|
52
|
-
render
|
51
|
+
render json: @post, adapter: :json_api, include: [:reviews], serializer: PostWithCustomKeysSerializer
|
53
52
|
end
|
54
53
|
|
55
54
|
def render_resource_with_nested_include
|
56
55
|
setup_post
|
57
|
-
render
|
56
|
+
render json: @post, adapter: :json_api, include: [comments: [:author]]
|
58
57
|
end
|
59
58
|
|
60
59
|
def render_resource_with_nested_has_many_include_wildcard
|
61
60
|
setup_post
|
62
|
-
render
|
61
|
+
render json: @post, adapter: :json_api, include: 'author.*'
|
63
62
|
end
|
64
63
|
|
65
64
|
def render_resource_with_missing_nested_has_many_include
|
66
65
|
setup_post
|
67
66
|
@post.author = @author2 # author2 has no roles.
|
68
|
-
render
|
67
|
+
render json: @post, adapter: :json_api, include: [author: [:roles]]
|
69
68
|
end
|
70
69
|
|
71
70
|
def render_collection_with_missing_nested_has_many_include
|
72
71
|
setup_post
|
73
72
|
@post.author = @author2
|
74
|
-
render
|
73
|
+
render json: [@post, @post2], adapter: :json_api, include: [author: [:roles]]
|
75
74
|
end
|
76
75
|
|
77
76
|
def render_collection_without_include
|
78
77
|
setup_post
|
79
|
-
render
|
78
|
+
render json: [@post], adapter: :json_api
|
80
79
|
end
|
81
80
|
|
82
81
|
def render_collection_with_include
|
83
82
|
setup_post
|
84
|
-
render
|
83
|
+
render json: [@post], adapter: :json_api, include: 'author, comments'
|
85
84
|
end
|
86
85
|
end
|
87
86
|
|
88
|
-
|
87
|
+
setup do
|
88
|
+
@routes = Rails.application.routes.draw do
|
89
|
+
ActiveSupport::Deprecation.silence do
|
90
|
+
match ':action', to: LinkedTestController, via: [:get, :post]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
89
94
|
|
90
95
|
def test_render_resource_without_include
|
91
|
-
get
|
96
|
+
get '/render_resource_without_include'
|
92
97
|
response = JSON.parse(@response.body)
|
93
98
|
refute response.key? 'included'
|
94
99
|
end
|
95
100
|
|
96
101
|
def test_render_resource_with_include
|
97
|
-
get
|
102
|
+
get '/render_resource_with_include'
|
98
103
|
response = JSON.parse(@response.body)
|
99
104
|
assert response.key? 'included'
|
100
105
|
assert_equal 1, response['included'].size
|
@@ -102,7 +107,7 @@ module ActionController
|
|
102
107
|
end
|
103
108
|
|
104
109
|
def test_render_resource_with_nested_has_many_include
|
105
|
-
get
|
110
|
+
get '/render_resource_with_nested_has_many_include_wildcard'
|
106
111
|
response = JSON.parse(@response.body)
|
107
112
|
expected_linked = [
|
108
113
|
{
|
@@ -144,7 +149,7 @@ module ActionController
|
|
144
149
|
end
|
145
150
|
|
146
151
|
def test_render_resource_with_include_of_custom_key_by_original
|
147
|
-
get
|
152
|
+
get '/render_resource_with_include_of_custom_key_by_original'
|
148
153
|
response = JSON.parse(@response.body)
|
149
154
|
assert response.key? 'included'
|
150
155
|
|
@@ -156,39 +161,39 @@ module ActionController
|
|
156
161
|
end
|
157
162
|
|
158
163
|
def test_render_resource_with_nested_include
|
159
|
-
get
|
164
|
+
get '/render_resource_with_nested_include'
|
160
165
|
response = JSON.parse(@response.body)
|
161
166
|
assert response.key? 'included'
|
162
167
|
assert_equal 3, response['included'].size
|
163
168
|
end
|
164
169
|
|
165
170
|
def test_render_collection_without_include
|
166
|
-
get
|
171
|
+
get '/render_collection_without_include'
|
167
172
|
response = JSON.parse(@response.body)
|
168
173
|
refute response.key? 'included'
|
169
174
|
end
|
170
175
|
|
171
176
|
def test_render_collection_with_include
|
172
|
-
get
|
177
|
+
get '/render_collection_with_include'
|
173
178
|
response = JSON.parse(@response.body)
|
174
179
|
assert response.key? 'included'
|
175
180
|
end
|
176
181
|
|
177
182
|
def test_render_resource_with_nested_attributes_even_when_missing_associations
|
178
|
-
get
|
183
|
+
get '/render_resource_with_missing_nested_has_many_include'
|
179
184
|
response = JSON.parse(@response.body)
|
180
185
|
assert response.key? 'included'
|
181
|
-
refute
|
186
|
+
refute include_type?(response['included'], 'roles')
|
182
187
|
end
|
183
188
|
|
184
189
|
def test_render_collection_with_missing_nested_has_many_include
|
185
|
-
get
|
190
|
+
get '/render_collection_with_missing_nested_has_many_include'
|
186
191
|
response = JSON.parse(@response.body)
|
187
192
|
assert response.key? 'included'
|
188
|
-
assert
|
193
|
+
assert include_type?(response['included'], 'roles')
|
189
194
|
end
|
190
195
|
|
191
|
-
def
|
196
|
+
def include_type?(collection, value)
|
192
197
|
collection.detect { |i| i['type'] == value }
|
193
198
|
end
|
194
199
|
end
|
@@ -14,9 +14,9 @@ module ActionController
|
|
14
14
|
class PaginationTestController < ActionController::Base
|
15
15
|
def setup
|
16
16
|
@array = [
|
17
|
-
Profile.new(
|
18
|
-
Profile.new(
|
19
|
-
Profile.new(
|
17
|
+
Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
|
18
|
+
Profile.new(name: 'Name 2', description: 'Description 2', comments: 'Comments 2'),
|
19
|
+
Profile.new(name: 'Name 3', description: 'Description 3', comments: 'Comments 3')
|
20
20
|
]
|
21
21
|
end
|
22
22
|
|
@@ -48,10 +48,10 @@ module ActionController
|
|
48
48
|
|
49
49
|
def test_render_pagination_links_with_will_paginate
|
50
50
|
expected_links = { 'self' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1",
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
'first' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
|
52
|
+
'prev' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
|
53
|
+
'next' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1",
|
54
|
+
'last' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1" }
|
55
55
|
|
56
56
|
get :render_pagination_using_will_paginate, params: { page: { number: 2, size: 1 } }
|
57
57
|
response = JSON.parse(@response.body)
|
@@ -60,8 +60,8 @@ module ActionController
|
|
60
60
|
|
61
61
|
def test_render_only_last_and_next_pagination_links
|
62
62
|
expected_links = { 'self' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2",
|
63
|
-
|
64
|
-
|
63
|
+
'next' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2",
|
64
|
+
'last' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2" }
|
65
65
|
get :render_pagination_using_will_paginate, params: { page: { number: 1, size: 2 } }
|
66
66
|
response = JSON.parse(@response.body)
|
67
67
|
assert_equal expected_links, response['links']
|
@@ -69,10 +69,10 @@ module ActionController
|
|
69
69
|
|
70
70
|
def test_render_pagination_links_with_kaminari
|
71
71
|
expected_links = { 'self' => "#{KAMINARI_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1",
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
'first' => "#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
|
73
|
+
'prev' => "#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
|
74
|
+
'next' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1",
|
75
|
+
'last' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1" }
|
76
76
|
get :render_pagination_using_kaminari, params: { page: { number: 2, size: 1 } }
|
77
77
|
response = JSON.parse(@response.body)
|
78
78
|
assert_equal expected_links, response['links']
|
@@ -80,8 +80,8 @@ module ActionController
|
|
80
80
|
|
81
81
|
def test_render_only_prev_and_first_pagination_links
|
82
82
|
expected_links = { 'self' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1",
|
83
|
-
|
84
|
-
|
83
|
+
'first' => "#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1",
|
84
|
+
'prev' => "#{KAMINARI_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1" }
|
85
85
|
get :render_pagination_using_kaminari, params: { page: { number: 3, size: 1 } }
|
86
86
|
response = JSON.parse(@response.body)
|
87
87
|
assert_equal expected_links, response['links']
|
@@ -89,8 +89,8 @@ module ActionController
|
|
89
89
|
|
90
90
|
def test_render_only_last_and_next_pagination_links_with_additional_params
|
91
91
|
expected_links = { 'self' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2&teste=additional",
|
92
|
-
|
93
|
-
|
92
|
+
'next' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2&teste=additional",
|
93
|
+
'last' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=2&teste=additional" }
|
94
94
|
get :render_pagination_using_will_paginate, params: { page: { number: 1, size: 2 }, teste: 'additional' }
|
95
95
|
response = JSON.parse(@response.body)
|
96
96
|
assert_equal expected_links, response['links']
|
@@ -98,8 +98,8 @@ module ActionController
|
|
98
98
|
|
99
99
|
def test_render_only_prev_and_first_pagination_links_with_additional_params
|
100
100
|
expected_links = { 'self' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1&teste=additional",
|
101
|
-
|
102
|
-
|
101
|
+
'first' => "#{KAMINARI_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=1&teste=additional",
|
102
|
+
'prev' => "#{KAMINARI_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1&teste=additional" }
|
103
103
|
get :render_pagination_using_kaminari, params: { page: { number: 3, size: 1 }, teste: 'additional' }
|
104
104
|
response = JSON.parse(@response.body)
|
105
105
|
assert_equal expected_links, response['links']
|
@@ -5,7 +5,9 @@ module ActionController
|
|
5
5
|
class JsonApi
|
6
6
|
class KeyTransformTest < ActionController::TestCase
|
7
7
|
class KeyTransformTestController < ActionController::Base
|
8
|
-
Post
|
8
|
+
class Post < ::Model; end
|
9
|
+
class Author < ::Model; end
|
10
|
+
class TopComment < ::Model; end
|
9
11
|
class PostSerializer < ActiveModel::Serializer
|
10
12
|
type 'posts'
|
11
13
|
attributes :title, :body, :publish_at
|
@@ -22,13 +24,11 @@ module ActionController
|
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
|
-
Author = Class.new(::Model)
|
26
27
|
class AuthorSerializer < ActiveModel::Serializer
|
27
28
|
type 'authors'
|
28
29
|
attributes :first_name, :last_name
|
29
30
|
end
|
30
31
|
|
31
|
-
TopComment = Class.new(::Model)
|
32
32
|
class TopCommentSerializer < ActiveModel::Serializer
|
33
33
|
type 'top_comments'
|
34
34
|
attributes :body
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module Serialization
|
5
|
+
class LookupProcTest < ActionController::TestCase
|
6
|
+
module Api
|
7
|
+
module V3
|
8
|
+
class PostCustomSerializer < ActiveModel::Serializer
|
9
|
+
attributes :title, :body
|
10
|
+
|
11
|
+
belongs_to :author
|
12
|
+
end
|
13
|
+
|
14
|
+
class AuthorCustomSerializer < ActiveModel::Serializer
|
15
|
+
attributes :name
|
16
|
+
end
|
17
|
+
|
18
|
+
class LookupProcTestController < ActionController::Base
|
19
|
+
def implicit_namespaced_serializer
|
20
|
+
author = Author.new(name: 'Bob')
|
21
|
+
post = Post.new(title: 'New Post', body: 'Body', author: author)
|
22
|
+
|
23
|
+
render json: post
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
tests Api::V3::LookupProcTestController
|
30
|
+
|
31
|
+
test 'implicitly uses namespaced serializer' do
|
32
|
+
controller_namespace = lambda do |resource_class, _parent_serializer_class, namespace|
|
33
|
+
"#{namespace}::#{resource_class}CustomSerializer" if namespace
|
34
|
+
end
|
35
|
+
|
36
|
+
with_prepended_lookup(controller_namespace) do
|
37
|
+
get :implicit_namespaced_serializer
|
38
|
+
|
39
|
+
assert_serializer Api::V3::PostCustomSerializer
|
40
|
+
|
41
|
+
expected = { 'title' => 'New Post', 'body' => 'Body', 'author' => { 'name' => 'Bob' } }
|
42
|
+
actual = JSON.parse(@response.body)
|
43
|
+
|
44
|
+
assert_equal expected, actual
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module Serialization
|
5
|
+
class NamespaceLookupTest < ActionController::TestCase
|
6
|
+
class Book < ::Model; end
|
7
|
+
class Page < ::Model; end
|
8
|
+
class Chapter < ::Model; end
|
9
|
+
class Writer < ::Model; end
|
10
|
+
|
11
|
+
module Api
|
12
|
+
module V2
|
13
|
+
class BookSerializer < ActiveModel::Serializer
|
14
|
+
attributes :title
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module VHeader
|
19
|
+
class BookSerializer < ActiveModel::Serializer
|
20
|
+
attributes :title, :body
|
21
|
+
|
22
|
+
def body
|
23
|
+
'header'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module V3
|
29
|
+
class BookSerializer < ActiveModel::Serializer
|
30
|
+
attributes :title, :body
|
31
|
+
|
32
|
+
belongs_to :writer
|
33
|
+
has_many :chapters
|
34
|
+
end
|
35
|
+
|
36
|
+
class ChapterSerializer < ActiveModel::Serializer
|
37
|
+
attribute :title do
|
38
|
+
"Chapter - #{object.title}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class WriterSerializer < ActiveModel::Serializer
|
43
|
+
attributes :name
|
44
|
+
end
|
45
|
+
|
46
|
+
class LookupTestController < ActionController::Base
|
47
|
+
before_action only: [:namespace_set_in_before_filter] do
|
48
|
+
self.namespace_for_serializer = Api::V2
|
49
|
+
end
|
50
|
+
|
51
|
+
def implicit_namespaced_serializer
|
52
|
+
writer = Writer.new(name: 'Bob')
|
53
|
+
book = Book.new(title: 'New Post', body: 'Body', writer: writer, chapters: [])
|
54
|
+
|
55
|
+
render json: book
|
56
|
+
end
|
57
|
+
|
58
|
+
def implicit_namespaced_collection_serializer
|
59
|
+
chapter1 = Chapter.new(title: 'Oh')
|
60
|
+
chapter2 = Chapter.new(title: 'Oh my')
|
61
|
+
|
62
|
+
render json: [chapter1, chapter2]
|
63
|
+
end
|
64
|
+
|
65
|
+
def implicit_has_many_namespaced_serializer
|
66
|
+
chapter1 = Chapter.new(title: 'Odd World')
|
67
|
+
chapter2 = Chapter.new(title: 'New World')
|
68
|
+
book = Book.new(title: 'New Post', body: 'Body', chapters: [chapter1, chapter2])
|
69
|
+
|
70
|
+
render json: book
|
71
|
+
end
|
72
|
+
|
73
|
+
def explicit_namespace_as_module
|
74
|
+
book = Book.new(title: 'New Post', body: 'Body')
|
75
|
+
|
76
|
+
render json: book, namespace: Api::V2
|
77
|
+
end
|
78
|
+
|
79
|
+
def explicit_namespace_as_string
|
80
|
+
book = Book.new(title: 'New Post', body: 'Body')
|
81
|
+
|
82
|
+
# because this is a string, ruby can't auto-lookup the constant, so otherwise
|
83
|
+
# the looku things we mean ::Api::V2
|
84
|
+
render json: book, namespace: 'ActionController::Serialization::NamespaceLookupTest::Api::V2'
|
85
|
+
end
|
86
|
+
|
87
|
+
def explicit_namespace_as_symbol
|
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 looku things we mean ::Api::V2
|
92
|
+
render json: book, namespace: :'ActionController::Serialization::NamespaceLookupTest::Api::V2'
|
93
|
+
end
|
94
|
+
|
95
|
+
def invalid_namespace
|
96
|
+
book = Book.new(title: 'New Post', body: 'Body')
|
97
|
+
|
98
|
+
render json: book, namespace: :api_v2
|
99
|
+
end
|
100
|
+
|
101
|
+
def namespace_set_in_before_filter
|
102
|
+
book = Book.new(title: 'New Post', body: 'Body')
|
103
|
+
render json: book
|
104
|
+
end
|
105
|
+
|
106
|
+
def namespace_set_by_request_headers
|
107
|
+
book = Book.new(title: 'New Post', body: 'Body')
|
108
|
+
version_from_header = request.headers['X-API_VERSION']
|
109
|
+
namespace = "ActionController::Serialization::NamespaceLookupTest::#{version_from_header}"
|
110
|
+
|
111
|
+
render json: book, namespace: namespace
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
tests Api::V3::LookupTestController
|
118
|
+
|
119
|
+
setup do
|
120
|
+
@test_namespace = self.class.parent
|
121
|
+
end
|
122
|
+
|
123
|
+
test 'uses request headers to determine the namespace' do
|
124
|
+
request.env['X-API_VERSION'] = 'Api::VHeader'
|
125
|
+
get :namespace_set_by_request_headers
|
126
|
+
|
127
|
+
assert_serializer Api::VHeader::BookSerializer
|
128
|
+
end
|
129
|
+
|
130
|
+
test 'implicitly uses namespaced serializer' do
|
131
|
+
get :implicit_namespaced_serializer
|
132
|
+
|
133
|
+
assert_serializer Api::V3::BookSerializer
|
134
|
+
|
135
|
+
expected = { 'title' => 'New Post', 'body' => 'Body', 'writer' => { 'name' => 'Bob' }, 'chapters' => [] }
|
136
|
+
actual = JSON.parse(@response.body)
|
137
|
+
|
138
|
+
assert_equal expected, actual
|
139
|
+
end
|
140
|
+
|
141
|
+
test 'implicitly uses namespaced serializer for collection' do
|
142
|
+
get :implicit_namespaced_collection_serializer
|
143
|
+
|
144
|
+
assert_serializer 'ActiveModel::Serializer::CollectionSerializer'
|
145
|
+
|
146
|
+
expected = [{ 'title' => 'Chapter - Oh' }, { 'title' => 'Chapter - Oh my' }]
|
147
|
+
actual = JSON.parse(@response.body)
|
148
|
+
|
149
|
+
assert_equal expected, actual
|
150
|
+
end
|
151
|
+
|
152
|
+
test 'implicitly uses namespaced serializer for has_many' do
|
153
|
+
get :implicit_has_many_namespaced_serializer
|
154
|
+
|
155
|
+
assert_serializer Api::V3::BookSerializer
|
156
|
+
|
157
|
+
expected = {
|
158
|
+
'title' => 'New Post',
|
159
|
+
'body' => 'Body', 'writer' => nil,
|
160
|
+
'chapters' => [
|
161
|
+
{ 'title' => 'Chapter - Odd World' },
|
162
|
+
{ 'title' => 'Chapter - New World' }
|
163
|
+
]
|
164
|
+
}
|
165
|
+
actual = JSON.parse(@response.body)
|
166
|
+
|
167
|
+
assert_equal expected, actual
|
168
|
+
end
|
169
|
+
|
170
|
+
test 'explicit namespace as module' do
|
171
|
+
get :explicit_namespace_as_module
|
172
|
+
|
173
|
+
assert_serializer Api::V2::BookSerializer
|
174
|
+
|
175
|
+
expected = { 'title' => 'New Post' }
|
176
|
+
actual = JSON.parse(@response.body)
|
177
|
+
|
178
|
+
assert_equal expected, actual
|
179
|
+
end
|
180
|
+
|
181
|
+
test 'explicit namespace as string' do
|
182
|
+
get :explicit_namespace_as_string
|
183
|
+
|
184
|
+
assert_serializer Api::V2::BookSerializer
|
185
|
+
|
186
|
+
expected = { 'title' => 'New Post' }
|
187
|
+
actual = JSON.parse(@response.body)
|
188
|
+
|
189
|
+
assert_equal expected, actual
|
190
|
+
end
|
191
|
+
|
192
|
+
test 'explicit namespace as symbol' do
|
193
|
+
get :explicit_namespace_as_symbol
|
194
|
+
|
195
|
+
assert_serializer Api::V2::BookSerializer
|
196
|
+
|
197
|
+
expected = { 'title' => 'New Post' }
|
198
|
+
actual = JSON.parse(@response.body)
|
199
|
+
|
200
|
+
assert_equal expected, actual
|
201
|
+
end
|
202
|
+
|
203
|
+
test 'invalid namespace' do
|
204
|
+
get :invalid_namespace
|
205
|
+
|
206
|
+
assert_serializer ActiveModel::Serializer::Null
|
207
|
+
|
208
|
+
expected = { 'title' => 'New Post', 'body' => 'Body' }
|
209
|
+
actual = JSON.parse(@response.body)
|
210
|
+
|
211
|
+
assert_equal expected, actual
|
212
|
+
end
|
213
|
+
|
214
|
+
test 'namespace set in before filter' do
|
215
|
+
get :namespace_set_in_before_filter
|
216
|
+
|
217
|
+
assert_serializer Api::V2::BookSerializer
|
218
|
+
|
219
|
+
expected = { 'title' => 'New Post' }
|
220
|
+
actual = JSON.parse(@response.body)
|
221
|
+
|
222
|
+
assert_equal expected, actual
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -74,7 +74,7 @@ module ActionController
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def update_and_render_object_with_cache_enabled
|
77
|
-
@post.updated_at = Time.now
|
77
|
+
@post.updated_at = Time.zone.now
|
78
78
|
|
79
79
|
generate_cached_serializer(@post)
|
80
80
|
render json: @post
|
@@ -163,7 +163,7 @@ module ActionController
|
|
163
163
|
end
|
164
164
|
expected = {
|
165
165
|
data: {
|
166
|
-
id:
|
166
|
+
id: @controller.instance_variable_get(:@profile).id.to_s,
|
167
167
|
type: 'profiles',
|
168
168
|
attributes: {
|
169
169
|
name: 'Name 1',
|
@@ -246,7 +246,7 @@ module ActionController
|
|
246
246
|
expected = {
|
247
247
|
data: [
|
248
248
|
{
|
249
|
-
id:
|
249
|
+
id: @controller.instance_variable_get(:@profiles).first.id.to_s,
|
250
250
|
type: 'profiles',
|
251
251
|
attributes: {
|
252
252
|
name: 'Name 1',
|
@@ -269,7 +269,7 @@ module ActionController
|
|
269
269
|
expected = {
|
270
270
|
data: [
|
271
271
|
{
|
272
|
-
id:
|
272
|
+
id: @controller.instance_variable_get(:@profiles).first.id.to_s,
|
273
273
|
type: 'profiles',
|
274
274
|
attributes: {
|
275
275
|
name: 'Name 1',
|
@@ -294,7 +294,8 @@ module ActionController
|
|
294
294
|
comments: [
|
295
295
|
{
|
296
296
|
id: 1,
|
297
|
-
body: 'ZOMG A COMMENT'
|
297
|
+
body: 'ZOMG A COMMENT'
|
298
|
+
}
|
298
299
|
],
|
299
300
|
blog: {
|
300
301
|
id: 999,
|
@@ -333,7 +334,8 @@ module ActionController
|
|
333
334
|
comments: [
|
334
335
|
{
|
335
336
|
id: 1,
|
336
|
-
body: 'ZOMG A COMMENT'
|
337
|
+
body: 'ZOMG A COMMENT'
|
338
|
+
}
|
337
339
|
],
|
338
340
|
blog: {
|
339
341
|
id: 999,
|
@@ -407,7 +409,8 @@ module ActionController
|
|
407
409
|
comments: [
|
408
410
|
{
|
409
411
|
id: 1,
|
410
|
-
body: 'ZOMG A COMMENT'
|
412
|
+
body: 'ZOMG A COMMENT'
|
413
|
+
}
|
411
414
|
],
|
412
415
|
blog: {
|
413
416
|
id: 999,
|
@@ -1,20 +1,22 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module ActiveModelSerializers
|
4
|
+
class JsonPointerTest < ActiveSupport::TestCase
|
5
|
+
def test_attribute_pointer
|
6
|
+
attribute_name = 'title'
|
7
|
+
pointer = ActiveModelSerializers::JsonPointer.new(:attribute, attribute_name)
|
8
|
+
assert_equal '/data/attributes/title', pointer
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def test_primary_data_pointer
|
12
|
+
pointer = ActiveModelSerializers::JsonPointer.new(:primary_data)
|
13
|
+
assert_equal '/data', pointer
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def test_unkown_data_pointer
|
17
|
+
assert_raises(TypeError) do
|
18
|
+
ActiveModelSerializers::JsonPointer.new(:unknown)
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|