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,237 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test_helper'
|
|
4
|
+
|
|
5
|
+
module SerializationScopeTesting
|
|
6
|
+
class User < ActiveModelSerializers::Model
|
|
7
|
+
attributes :id, :name, :admin
|
|
8
|
+
def admin?
|
|
9
|
+
admin
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
class Comment < ActiveModelSerializers::Model
|
|
13
|
+
attributes :id, :body
|
|
14
|
+
end
|
|
15
|
+
class Post < ActiveModelSerializers::Model
|
|
16
|
+
attributes :id, :title, :body, :comments
|
|
17
|
+
end
|
|
18
|
+
class PostSerializer < ActiveModel::Serializer
|
|
19
|
+
attributes :id, :title, :body, :comments
|
|
20
|
+
|
|
21
|
+
def body
|
|
22
|
+
"The 'scope' is the 'current_user': #{scope == current_user}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def comments
|
|
26
|
+
if current_user.admin?
|
|
27
|
+
[Comment.new(id: 1, body: 'Admin')]
|
|
28
|
+
else
|
|
29
|
+
[Comment.new(id: 2, body: 'Scoped')]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def json_key
|
|
34
|
+
'post'
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
class PostTestController < ActionController::Base
|
|
38
|
+
attr_writer :current_user
|
|
39
|
+
|
|
40
|
+
def render_post_by_non_admin
|
|
41
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
|
42
|
+
render json: new_post, serializer: serializer, adapter: :json
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def render_post_by_admin
|
|
46
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: true)
|
|
47
|
+
render json: new_post, serializer: serializer, adapter: :json
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def current_user
|
|
51
|
+
defined?(@current_user) ? @current_user : :current_user_not_set
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def new_post
|
|
57
|
+
Post.new(id: 4, title: 'Title')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def serializer
|
|
61
|
+
PostSerializer
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
class PostViewContextSerializer < PostSerializer
|
|
65
|
+
def body
|
|
66
|
+
"The 'scope' is the 'view_context': #{scope == view_context}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def comments
|
|
70
|
+
if view_context.controller.current_user.admin?
|
|
71
|
+
[Comment.new(id: 1, body: 'Admin')]
|
|
72
|
+
else
|
|
73
|
+
[Comment.new(id: 2, body: 'Scoped')]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
class DefaultScopeTest < ActionController::TestCase
|
|
78
|
+
tests PostTestController
|
|
79
|
+
|
|
80
|
+
def test_default_serialization_scope
|
|
81
|
+
assert_equal :current_user, @controller._serialization_scope
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_default_serialization_scope_object
|
|
85
|
+
assert_equal :current_user_not_set, @controller.current_user
|
|
86
|
+
assert_equal :current_user_not_set, @controller.serialization_scope
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_default_scope_non_admin
|
|
90
|
+
get :render_post_by_non_admin
|
|
91
|
+
expected_json = {
|
|
92
|
+
post: {
|
|
93
|
+
id: 4,
|
|
94
|
+
title: 'Title',
|
|
95
|
+
body: "The 'scope' is the 'current_user': true",
|
|
96
|
+
comments: [
|
|
97
|
+
{ id: 2, body: 'Scoped' }
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
}.to_json
|
|
101
|
+
assert_equal expected_json, @response.body
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_default_scope_admin
|
|
105
|
+
get :render_post_by_admin
|
|
106
|
+
expected_json = {
|
|
107
|
+
post: {
|
|
108
|
+
id: 4,
|
|
109
|
+
title: 'Title',
|
|
110
|
+
body: "The 'scope' is the 'current_user': true",
|
|
111
|
+
comments: [
|
|
112
|
+
{ id: 1, body: 'Admin' }
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
}.to_json
|
|
116
|
+
assert_equal expected_json, @response.body
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
class SerializationScopeTest < ActionController::TestCase
|
|
120
|
+
class PostViewContextTestController < PostTestController
|
|
121
|
+
serialization_scope :view_context
|
|
122
|
+
|
|
123
|
+
private
|
|
124
|
+
|
|
125
|
+
def serializer
|
|
126
|
+
PostViewContextSerializer
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
tests PostViewContextTestController
|
|
130
|
+
|
|
131
|
+
def test_defined_serialization_scope
|
|
132
|
+
assert_equal :view_context, @controller._serialization_scope
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def test_defined_serialization_scope_object
|
|
136
|
+
assert_equal @controller.view_context.controller, @controller.serialization_scope.controller
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_serialization_scope_non_admin
|
|
140
|
+
get :render_post_by_non_admin
|
|
141
|
+
expected_json = {
|
|
142
|
+
post: {
|
|
143
|
+
id: 4,
|
|
144
|
+
title: 'Title',
|
|
145
|
+
body: "The 'scope' is the 'view_context': true",
|
|
146
|
+
comments: [
|
|
147
|
+
{ id: 2, body: 'Scoped' }
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
}.to_json
|
|
151
|
+
assert_equal expected_json, @response.body
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_serialization_scope_admin
|
|
155
|
+
get :render_post_by_admin
|
|
156
|
+
expected_json = {
|
|
157
|
+
post: {
|
|
158
|
+
id: 4,
|
|
159
|
+
title: 'Title',
|
|
160
|
+
body: "The 'scope' is the 'view_context': true",
|
|
161
|
+
comments: [
|
|
162
|
+
{ id: 1, body: 'Admin' }
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
}.to_json
|
|
166
|
+
assert_equal expected_json, @response.body
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
class NilSerializationScopeTest < ActionController::TestCase
|
|
170
|
+
class PostViewContextTestController < ActionController::Base
|
|
171
|
+
serialization_scope nil
|
|
172
|
+
|
|
173
|
+
attr_accessor :current_user
|
|
174
|
+
|
|
175
|
+
def render_post_with_no_scope
|
|
176
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
|
177
|
+
render json: new_post, serializer: PostSerializer, adapter: :json
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def render_post_with_passed_in_scope
|
|
181
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
|
182
|
+
render json: new_post, serializer: PostSerializer, adapter: :json, scope: current_user, scope_name: :current_user
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def render_post_with_passed_in_scope_without_scope_name
|
|
186
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
|
187
|
+
render json: new_post, serializer: PostSerializer, adapter: :json, scope: current_user
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
private
|
|
191
|
+
|
|
192
|
+
def new_post
|
|
193
|
+
Post.new(id: 4, title: 'Title')
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
tests PostViewContextTestController
|
|
197
|
+
|
|
198
|
+
def test_nil_serialization_scope
|
|
199
|
+
assert_nil @controller._serialization_scope
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def test_nil_serialization_scope_object
|
|
203
|
+
assert_nil @controller.serialization_scope
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def test_nil_scope
|
|
207
|
+
exception_matcher = /current_user/
|
|
208
|
+
exception = assert_raises(NameError) do
|
|
209
|
+
get :render_post_with_no_scope
|
|
210
|
+
end
|
|
211
|
+
assert_match exception_matcher, exception.message
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def test_serialization_scope_is_and_nil_scope_passed_in_current_user
|
|
215
|
+
get :render_post_with_passed_in_scope
|
|
216
|
+
expected_json = {
|
|
217
|
+
post: {
|
|
218
|
+
id: 4,
|
|
219
|
+
title: 'Title',
|
|
220
|
+
body: "The 'scope' is the 'current_user': true",
|
|
221
|
+
comments: [
|
|
222
|
+
{ id: 2, body: 'Scoped' }
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
}.to_json
|
|
226
|
+
assert_equal expected_json, @response.body
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def test_serialization_scope_is_nil_and_scope_passed_in_current_user_without_scope_name
|
|
230
|
+
exception_matcher = /current_user/
|
|
231
|
+
exception = assert_raises(NameError) do
|
|
232
|
+
get :render_post_with_passed_in_scope_without_scope_name
|
|
233
|
+
end
|
|
234
|
+
assert_match exception_matcher, exception.message
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test_helper'
|
|
4
|
+
|
|
5
|
+
module ActionController
|
|
6
|
+
module Serialization
|
|
7
|
+
class ImplicitSerializerTest < ActionController::TestCase
|
|
8
|
+
class ImplicitSerializationTestController < ActionController::Base
|
|
9
|
+
include SerializationTesting
|
|
10
|
+
def render_using_implicit_serializer
|
|
11
|
+
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
|
12
|
+
render json: @profile
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def render_using_default_adapter_root
|
|
16
|
+
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
|
17
|
+
render json: @profile
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def render_array_using_custom_root
|
|
21
|
+
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
|
22
|
+
render json: [@profile], root: 'custom_root'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def render_array_that_is_empty_using_custom_root
|
|
26
|
+
render json: [], root: 'custom_root'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def render_object_using_custom_root
|
|
30
|
+
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
|
31
|
+
render json: @profile, root: 'custom_root'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def render_array_using_implicit_serializer
|
|
35
|
+
array = [
|
|
36
|
+
Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
|
|
37
|
+
Profile.new(name: 'Name 2', description: 'Description 2', comments: 'Comments 2')
|
|
38
|
+
]
|
|
39
|
+
render json: array
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def render_array_using_implicit_serializer_and_meta
|
|
43
|
+
@profiles = [
|
|
44
|
+
Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
|
45
|
+
]
|
|
46
|
+
render json: @profiles, meta: { total: 10 }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def render_array_using_implicit_serializer_and_links
|
|
50
|
+
with_adapter ActiveModelSerializers::Adapter::JsonApi do
|
|
51
|
+
@profiles = [
|
|
52
|
+
Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
render json: @profiles, links: { self: 'http://example.com/api/profiles/1' }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def render_object_with_cache_enabled
|
|
60
|
+
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
|
61
|
+
@author = Author.new(id: 1, name: 'Joao Moura.')
|
|
62
|
+
@post = Post.new(id: 1, title: 'New Post', body: 'Body', comments: [@comment], author: @author)
|
|
63
|
+
|
|
64
|
+
generate_cached_serializer(@post)
|
|
65
|
+
|
|
66
|
+
@post.title = 'ZOMG a New Post'
|
|
67
|
+
render json: @post
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def render_json_object_without_serializer
|
|
71
|
+
render json: { error: 'Result is Invalid' }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def render_json_array_object_without_serializer
|
|
75
|
+
render json: [{ error: 'Result is Invalid' }]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def update_and_render_object_with_cache_enabled
|
|
79
|
+
@post.updated_at = Time.zone.now
|
|
80
|
+
|
|
81
|
+
generate_cached_serializer(@post)
|
|
82
|
+
render json: @post
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def render_object_expired_with_cache_enabled
|
|
86
|
+
comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
|
87
|
+
author = Author.new(id: 1, name: 'Joao Moura.')
|
|
88
|
+
post = Post.new(id: 1, title: 'New Post', body: 'Body', comments: [comment], author: author)
|
|
89
|
+
|
|
90
|
+
generate_cached_serializer(post)
|
|
91
|
+
|
|
92
|
+
post.title = 'ZOMG a New Post'
|
|
93
|
+
|
|
94
|
+
expires_in = [
|
|
95
|
+
PostSerializer._cache_options[:expires_in],
|
|
96
|
+
CommentSerializer._cache_options[:expires_in]
|
|
97
|
+
].max + 200
|
|
98
|
+
|
|
99
|
+
Timecop.travel(Time.zone.now + expires_in) do
|
|
100
|
+
render json: post
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def render_changed_object_with_cache_enabled
|
|
105
|
+
comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
|
106
|
+
author = Author.new(id: 1, name: 'Joao Moura.')
|
|
107
|
+
post = Post.new(id: 1, title: 'ZOMG a New Post', body: 'Body', comments: [comment], author: author)
|
|
108
|
+
|
|
109
|
+
render json: post
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def render_fragment_changed_object_with_only_cache_enabled
|
|
113
|
+
author = Author.new(id: 1, name: 'Joao Moura.')
|
|
114
|
+
role = Role.new(id: 42, name: 'ZOMG A ROLE', description: 'DESCRIPTION HERE', author: author)
|
|
115
|
+
|
|
116
|
+
generate_cached_serializer(role)
|
|
117
|
+
role.name = 'lol'
|
|
118
|
+
role.description = 'HUEHUEBRBR'
|
|
119
|
+
|
|
120
|
+
render json: role
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def render_fragment_changed_object_with_except_cache_enabled
|
|
124
|
+
author = Author.new(id: 1, name: 'Joao Moura.')
|
|
125
|
+
bio = Bio.new(id: 42, content: 'ZOMG A ROLE', rating: 5, author: author)
|
|
126
|
+
|
|
127
|
+
generate_cached_serializer(bio)
|
|
128
|
+
bio.content = 'lol'
|
|
129
|
+
bio.rating = 0
|
|
130
|
+
|
|
131
|
+
render json: bio
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def render_fragment_changed_object_with_relationship
|
|
135
|
+
comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
|
136
|
+
comment2 = Comment.new(id: 1, body: 'ZOMG AN UPDATED-BUT-NOT-CACHE-EXPIRED COMMENT')
|
|
137
|
+
like = Like.new(id: 1, likeable: comment, time: 3.days.ago)
|
|
138
|
+
|
|
139
|
+
generate_cached_serializer(like)
|
|
140
|
+
like.likeable = comment2
|
|
141
|
+
like.time = Time.zone.now.to_s
|
|
142
|
+
|
|
143
|
+
render json: like
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
tests ImplicitSerializationTestController
|
|
148
|
+
|
|
149
|
+
# We just have Null for now, this will change
|
|
150
|
+
def test_render_using_implicit_serializer
|
|
151
|
+
get :render_using_implicit_serializer
|
|
152
|
+
|
|
153
|
+
expected = {
|
|
154
|
+
name: 'Name 1',
|
|
155
|
+
description: 'Description 1'
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
assert_equal 'application/json', @response.content_type
|
|
159
|
+
assert_equal expected.to_json, @response.body
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def test_render_using_default_root
|
|
163
|
+
with_adapter :json_api do
|
|
164
|
+
get :render_using_default_adapter_root
|
|
165
|
+
end
|
|
166
|
+
expected = {
|
|
167
|
+
data: {
|
|
168
|
+
id: @controller.instance_variable_get(:@profile).id.to_s,
|
|
169
|
+
type: 'profiles',
|
|
170
|
+
attributes: {
|
|
171
|
+
name: 'Name 1',
|
|
172
|
+
description: 'Description 1'
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
assert_equal 'application/json', @response.content_type
|
|
178
|
+
assert_equal expected.to_json, @response.body
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def test_render_array_using_custom_root
|
|
182
|
+
with_adapter :json do
|
|
183
|
+
get :render_array_using_custom_root
|
|
184
|
+
end
|
|
185
|
+
expected = { custom_root: [{ name: 'Name 1', description: 'Description 1' }] }
|
|
186
|
+
assert_equal 'application/json', @response.content_type
|
|
187
|
+
assert_equal expected.to_json, @response.body
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def test_render_array_that_is_empty_using_custom_root
|
|
191
|
+
with_adapter :json do
|
|
192
|
+
get :render_array_that_is_empty_using_custom_root
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
expected = { custom_root: [] }
|
|
196
|
+
assert_equal 'application/json', @response.content_type
|
|
197
|
+
assert_equal expected.to_json, @response.body
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def test_render_object_using_custom_root
|
|
201
|
+
with_adapter :json do
|
|
202
|
+
get :render_object_using_custom_root
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
expected = { custom_root: { name: 'Name 1', description: 'Description 1' } }
|
|
206
|
+
assert_equal 'application/json', @response.content_type
|
|
207
|
+
assert_equal expected.to_json, @response.body
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def test_render_json_object_without_serializer
|
|
211
|
+
get :render_json_object_without_serializer
|
|
212
|
+
|
|
213
|
+
assert_equal 'application/json', @response.content_type
|
|
214
|
+
expected_body = { error: 'Result is Invalid' }
|
|
215
|
+
assert_equal expected_body.to_json, @response.body
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def test_render_json_array_object_without_serializer
|
|
219
|
+
get :render_json_array_object_without_serializer
|
|
220
|
+
|
|
221
|
+
assert_equal 'application/json', @response.content_type
|
|
222
|
+
expected_body = [{ error: 'Result is Invalid' }]
|
|
223
|
+
assert_equal expected_body.to_json, @response.body
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def test_render_array_using_implicit_serializer
|
|
227
|
+
get :render_array_using_implicit_serializer
|
|
228
|
+
assert_equal 'application/json', @response.content_type
|
|
229
|
+
|
|
230
|
+
expected = [
|
|
231
|
+
{
|
|
232
|
+
name: 'Name 1',
|
|
233
|
+
description: 'Description 1'
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: 'Name 2',
|
|
237
|
+
description: 'Description 2'
|
|
238
|
+
}
|
|
239
|
+
]
|
|
240
|
+
|
|
241
|
+
assert_equal expected.to_json, @response.body
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def test_render_array_using_implicit_serializer_and_meta
|
|
245
|
+
with_adapter :json_api do
|
|
246
|
+
get :render_array_using_implicit_serializer_and_meta
|
|
247
|
+
end
|
|
248
|
+
expected = {
|
|
249
|
+
data: [
|
|
250
|
+
{
|
|
251
|
+
id: @controller.instance_variable_get(:@profiles).first.id.to_s,
|
|
252
|
+
type: 'profiles',
|
|
253
|
+
attributes: {
|
|
254
|
+
name: 'Name 1',
|
|
255
|
+
description: 'Description 1'
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
],
|
|
259
|
+
meta: {
|
|
260
|
+
total: 10
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
assert_equal 'application/json', @response.content_type
|
|
265
|
+
assert_equal expected.to_json, @response.body
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def test_render_array_using_implicit_serializer_and_links
|
|
269
|
+
get :render_array_using_implicit_serializer_and_links
|
|
270
|
+
|
|
271
|
+
expected = {
|
|
272
|
+
data: [
|
|
273
|
+
{
|
|
274
|
+
id: @controller.instance_variable_get(:@profiles).first.id.to_s,
|
|
275
|
+
type: 'profiles',
|
|
276
|
+
attributes: {
|
|
277
|
+
name: 'Name 1',
|
|
278
|
+
description: 'Description 1'
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
],
|
|
282
|
+
links: {
|
|
283
|
+
self: 'http://example.com/api/profiles/1'
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
assert_equal 'application/json', @response.content_type
|
|
288
|
+
assert_equal expected.to_json, @response.body
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def test_render_with_cache_enable
|
|
292
|
+
expected = {
|
|
293
|
+
id: 1,
|
|
294
|
+
title: 'New Post',
|
|
295
|
+
body: 'Body',
|
|
296
|
+
comments: [
|
|
297
|
+
{
|
|
298
|
+
id: 1,
|
|
299
|
+
body: 'ZOMG A COMMENT'
|
|
300
|
+
}
|
|
301
|
+
],
|
|
302
|
+
blog: {
|
|
303
|
+
id: 999,
|
|
304
|
+
name: 'Custom blog'
|
|
305
|
+
},
|
|
306
|
+
author: {
|
|
307
|
+
id: 1,
|
|
308
|
+
name: 'Joao Moura.'
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
ActionController::Base.cache_store.clear
|
|
313
|
+
Timecop.freeze(Time.zone.now) do
|
|
314
|
+
get :render_object_with_cache_enabled
|
|
315
|
+
|
|
316
|
+
assert_equal 'application/json', @response.content_type
|
|
317
|
+
assert_equal expected.to_json, @response.body
|
|
318
|
+
|
|
319
|
+
get :render_changed_object_with_cache_enabled
|
|
320
|
+
assert_equal expected.to_json, @response.body
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
ActionController::Base.cache_store.clear
|
|
324
|
+
get :render_changed_object_with_cache_enabled
|
|
325
|
+
assert_not_equal expected.to_json, @response.body
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def test_render_with_cache_enable_and_expired
|
|
329
|
+
ActionController::Base.cache_store.clear
|
|
330
|
+
get :render_object_expired_with_cache_enabled
|
|
331
|
+
|
|
332
|
+
expected = {
|
|
333
|
+
id: 1,
|
|
334
|
+
title: 'ZOMG a New Post',
|
|
335
|
+
body: 'Body',
|
|
336
|
+
comments: [
|
|
337
|
+
{
|
|
338
|
+
id: 1,
|
|
339
|
+
body: 'ZOMG A COMMENT'
|
|
340
|
+
}
|
|
341
|
+
],
|
|
342
|
+
blog: {
|
|
343
|
+
id: 999,
|
|
344
|
+
name: 'Custom blog'
|
|
345
|
+
},
|
|
346
|
+
author: {
|
|
347
|
+
id: 1,
|
|
348
|
+
name: 'Joao Moura.'
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
assert_equal 'application/json', @response.content_type
|
|
353
|
+
actual = @response.body
|
|
354
|
+
expected = expected.to_json
|
|
355
|
+
if ENV['APPVEYOR'] && actual != expected
|
|
356
|
+
skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
|
|
357
|
+
else
|
|
358
|
+
assert_equal actual, expected
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def test_render_with_fragment_only_cache_enable
|
|
363
|
+
ActionController::Base.cache_store.clear
|
|
364
|
+
get :render_fragment_changed_object_with_only_cache_enabled
|
|
365
|
+
response = JSON.parse(@response.body)
|
|
366
|
+
|
|
367
|
+
assert_equal 'application/json', @response.content_type
|
|
368
|
+
assert_equal 'ZOMG A ROLE', response['name']
|
|
369
|
+
assert_equal 'HUEHUEBRBR', response['description']
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def test_render_with_fragment_except_cache_enable
|
|
373
|
+
ActionController::Base.cache_store.clear
|
|
374
|
+
get :render_fragment_changed_object_with_except_cache_enabled
|
|
375
|
+
response = JSON.parse(@response.body)
|
|
376
|
+
|
|
377
|
+
assert_equal 'application/json', @response.content_type
|
|
378
|
+
assert_equal 5, response['rating']
|
|
379
|
+
assert_equal 'lol', response['content']
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def test_render_fragment_changed_object_with_relationship
|
|
383
|
+
ActionController::Base.cache_store.clear
|
|
384
|
+
|
|
385
|
+
Timecop.freeze(Time.zone.now) do
|
|
386
|
+
get :render_fragment_changed_object_with_relationship
|
|
387
|
+
response = JSON.parse(@response.body)
|
|
388
|
+
|
|
389
|
+
expected_return = {
|
|
390
|
+
'id' => 1,
|
|
391
|
+
'time' => Time.zone.now.to_s,
|
|
392
|
+
'likeable' => {
|
|
393
|
+
'id' => 1,
|
|
394
|
+
'body' => 'ZOMG A COMMENT'
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
assert_equal 'application/json', @response.content_type
|
|
399
|
+
assert_equal expected_return, response
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
def test_cache_expiration_on_update
|
|
404
|
+
ActionController::Base.cache_store.clear
|
|
405
|
+
get :render_object_with_cache_enabled
|
|
406
|
+
|
|
407
|
+
expected = {
|
|
408
|
+
id: 1,
|
|
409
|
+
title: 'ZOMG a New Post',
|
|
410
|
+
body: 'Body',
|
|
411
|
+
comments: [
|
|
412
|
+
{
|
|
413
|
+
id: 1,
|
|
414
|
+
body: 'ZOMG A COMMENT'
|
|
415
|
+
}
|
|
416
|
+
],
|
|
417
|
+
blog: {
|
|
418
|
+
id: 999,
|
|
419
|
+
name: 'Custom blog'
|
|
420
|
+
},
|
|
421
|
+
author: {
|
|
422
|
+
id: 1,
|
|
423
|
+
name: 'Joao Moura.'
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
get :update_and_render_object_with_cache_enabled
|
|
428
|
+
|
|
429
|
+
assert_equal 'application/json', @response.content_type
|
|
430
|
+
actual = @response.body
|
|
431
|
+
expected = expected.to_json
|
|
432
|
+
if ENV['APPVEYOR'] && actual != expected
|
|
433
|
+
skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
|
|
434
|
+
else
|
|
435
|
+
assert_equal actual, expected
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def test_warn_overridding_use_adapter_as_falsy_on_controller_instance
|
|
440
|
+
controller = Class.new(ImplicitSerializationTestController) do
|
|
441
|
+
def use_adapter?
|
|
442
|
+
false
|
|
443
|
+
end
|
|
444
|
+
end.new
|
|
445
|
+
assert_output(nil, /adapter: false/) do
|
|
446
|
+
controller.get_serializer(Profile.new)
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def test_dont_warn_overridding_use_adapter_as_truthy_on_controller_instance
|
|
451
|
+
controller = Class.new(ImplicitSerializationTestController) do
|
|
452
|
+
def use_adapter?
|
|
453
|
+
true
|
|
454
|
+
end
|
|
455
|
+
end.new
|
|
456
|
+
assert_output(nil, '') do
|
|
457
|
+
controller.get_serializer(Profile.new)
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def test_render_event_is_emitted
|
|
462
|
+
subscriber = ::ActiveSupport::Notifications.subscribe('render.active_model_serializers') do |subscribed_event|
|
|
463
|
+
@subscribed_event = subscribed_event
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
get :render_using_implicit_serializer
|
|
467
|
+
|
|
468
|
+
subscribed_event_name =
|
|
469
|
+
if @subscribed_event.is_a?(String)
|
|
470
|
+
@subscribed_event
|
|
471
|
+
else
|
|
472
|
+
@subscribed_event.name # is a ActiveSupport::Notifications::Event
|
|
473
|
+
end
|
|
474
|
+
assert_equal 'render.active_model_serializers', subscribed_event_name
|
|
475
|
+
ensure
|
|
476
|
+
ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
end
|