active_model_serializers 0.8.3 → 0.10.0
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/.github/ISSUE_TEMPLATE.md +29 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- data/.gitignore +17 -0
- data/.rubocop.yml +104 -0
- data/.rubocop_todo.yml +167 -0
- data/.simplecov +110 -0
- data/.travis.yml +39 -24
- data/CHANGELOG.md +465 -6
- data/CONTRIBUTING.md +105 -0
- data/Gemfile +50 -1
- data/{MIT-LICENSE.txt → MIT-LICENSE} +3 -2
- data/README.md +102 -590
- data/Rakefile +93 -8
- data/active_model_serializers.gemspec +65 -23
- data/appveyor.yml +24 -0
- data/bin/bench +171 -0
- data/bin/bench_regression +316 -0
- data/bin/serve_benchmark +39 -0
- data/docs/ARCHITECTURE.md +126 -0
- data/docs/README.md +40 -0
- data/docs/STYLE.md +58 -0
- data/docs/general/adapters.md +245 -0
- data/docs/general/caching.md +52 -0
- data/docs/general/configuration_options.md +100 -0
- data/docs/general/deserialization.md +100 -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 +14 -0
- data/docs/general/rendering.md +255 -0
- data/docs/general/serializers.md +372 -0
- data/docs/how-open-source-maintained.jpg +0 -0
- data/docs/howto/add_pagination_links.md +139 -0
- data/docs/howto/add_root_key.md +51 -0
- data/docs/howto/outside_controller_use.md +58 -0
- data/docs/howto/passing_arbitrary_options.md +27 -0
- data/docs/howto/serialize_poro.md +32 -0
- data/docs/howto/test.md +152 -0
- data/docs/integrations/ember-and-json-api.md +112 -0
- data/docs/integrations/grape.md +19 -0
- data/docs/jsonapi/errors.md +56 -0
- data/docs/jsonapi/schema/schema.json +366 -0
- data/docs/jsonapi/schema.md +151 -0
- data/docs/rfcs/0000-namespace.md +106 -0
- data/docs/rfcs/template.md +15 -0
- data/lib/action_controller/serialization.rb +31 -36
- data/lib/active_model/serializable_resource.rb +11 -0
- data/lib/active_model/serializer/adapter/attributes.rb +15 -0
- data/lib/active_model/serializer/adapter/base.rb +16 -0
- data/lib/active_model/serializer/adapter/json.rb +15 -0
- data/lib/active_model/serializer/adapter/json_api.rb +15 -0
- data/lib/active_model/serializer/adapter/null.rb +15 -0
- data/lib/active_model/serializer/adapter.rb +24 -0
- data/lib/active_model/serializer/array_serializer.rb +9 -0
- data/lib/active_model/serializer/association.rb +19 -0
- data/lib/active_model/serializer/associations.rb +87 -220
- data/lib/active_model/serializer/attribute.rb +25 -0
- data/lib/active_model/serializer/attributes.rb +82 -0
- data/lib/active_model/serializer/belongs_to_reflection.rb +10 -0
- data/lib/active_model/serializer/caching.rb +333 -0
- data/lib/active_model/serializer/collection_reflection.rb +7 -0
- data/lib/active_model/serializer/collection_serializer.rb +64 -0
- data/lib/active_model/serializer/configuration.rb +35 -0
- data/lib/active_model/serializer/error_serializer.rb +10 -0
- data/lib/active_model/serializer/errors_serializer.rb +27 -0
- data/lib/active_model/serializer/field.rb +90 -0
- data/lib/active_model/serializer/fieldset.rb +31 -0
- data/lib/active_model/serializer/has_many_reflection.rb +10 -0
- data/lib/active_model/serializer/has_one_reflection.rb +10 -0
- data/lib/active_model/serializer/include_tree.rb +111 -0
- data/lib/active_model/serializer/links.rb +35 -0
- data/lib/active_model/serializer/lint.rb +146 -0
- data/lib/active_model/serializer/meta.rb +29 -0
- data/lib/active_model/serializer/null.rb +17 -0
- data/lib/active_model/serializer/reflection.rb +147 -0
- data/lib/active_model/serializer/singular_reflection.rb +7 -0
- data/lib/active_model/serializer/type.rb +25 -0
- data/lib/active_model/{serializers → serializer}/version.rb +1 -1
- data/lib/active_model/serializer.rb +158 -481
- data/lib/active_model_serializers/adapter/attributes.rb +76 -0
- data/lib/active_model_serializers/adapter/base.rb +83 -0
- data/lib/active_model_serializers/adapter/json.rb +21 -0
- data/lib/active_model_serializers/adapter/json_api/deserialization.rb +213 -0
- data/lib/active_model_serializers/adapter/json_api/error.rb +96 -0
- data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +49 -0
- data/lib/active_model_serializers/adapter/json_api/link.rb +83 -0
- data/lib/active_model_serializers/adapter/json_api/meta.rb +37 -0
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +62 -0
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +52 -0
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +37 -0
- data/lib/active_model_serializers/adapter/json_api.rb +516 -0
- data/lib/active_model_serializers/adapter/null.rb +9 -0
- data/lib/active_model_serializers/adapter.rb +92 -0
- data/lib/active_model_serializers/callbacks.rb +55 -0
- data/lib/active_model_serializers/deprecate.rb +55 -0
- data/lib/active_model_serializers/deserialization.rb +13 -0
- data/lib/active_model_serializers/json_pointer.rb +14 -0
- data/lib/active_model_serializers/key_transform.rb +70 -0
- data/lib/active_model_serializers/logging.rb +122 -0
- data/lib/active_model_serializers/model.rb +49 -0
- data/lib/active_model_serializers/railtie.rb +46 -0
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +65 -0
- data/lib/active_model_serializers/serializable_resource.rb +81 -0
- data/lib/active_model_serializers/serialization_context.rb +32 -0
- data/lib/active_model_serializers/test/schema.rb +138 -0
- data/lib/active_model_serializers/test/serializer.rb +125 -0
- data/lib/active_model_serializers/test.rb +7 -0
- data/lib/active_model_serializers.rb +32 -89
- data/lib/generators/rails/USAGE +6 -0
- data/lib/generators/rails/resource_override.rb +10 -0
- data/lib/generators/rails/serializer_generator.rb +36 -0
- data/lib/generators/rails/templates/serializer.rb.erb +8 -0
- data/lib/grape/active_model_serializers.rb +14 -0
- data/lib/grape/formatters/active_model_serializers.rb +15 -0
- data/lib/grape/helpers/active_model_serializers.rb +16 -0
- data/test/action_controller/adapter_selector_test.rb +53 -0
- data/test/action_controller/explicit_serializer_test.rb +134 -0
- data/test/action_controller/json/include_test.rb +167 -0
- data/test/action_controller/json_api/deserialization_test.rb +112 -0
- data/test/action_controller/json_api/errors_test.rb +41 -0
- data/test/action_controller/json_api/linked_test.rb +197 -0
- data/test/action_controller/json_api/pagination_test.rb +116 -0
- data/test/action_controller/json_api/transform_test.rb +181 -0
- data/test/action_controller/serialization_scope_name_test.rb +229 -0
- data/test/action_controller/serialization_test.rb +469 -0
- data/test/active_model_serializers/adapter_for_test.rb +208 -0
- data/test/active_model_serializers/json_pointer_test.rb +20 -0
- data/test/active_model_serializers/key_transform_test.rb +263 -0
- data/test/active_model_serializers/logging_test.rb +77 -0
- data/test/active_model_serializers/model_test.rb +9 -0
- data/test/active_model_serializers/railtie_test_isolated.rb +63 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +58 -0
- data/test/active_model_serializers/test/schema_test.rb +130 -0
- data/test/active_model_serializers/test/serializer_test.rb +62 -0
- data/test/active_record_test.rb +9 -0
- data/test/adapter/deprecation_test.rb +100 -0
- data/test/adapter/json/belongs_to_test.rb +45 -0
- data/test/adapter/json/collection_test.rb +90 -0
- data/test/adapter/json/has_many_test.rb +45 -0
- data/test/adapter/json/transform_test.rb +93 -0
- data/test/adapter/json_api/belongs_to_test.rb +155 -0
- data/test/adapter/json_api/collection_test.rb +95 -0
- data/test/adapter/json_api/errors_test.rb +78 -0
- data/test/adapter/json_api/fields_test.rb +87 -0
- data/test/adapter/json_api/has_many_embed_ids_test.rb +43 -0
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +96 -0
- data/test/adapter/json_api/has_many_test.rb +144 -0
- data/test/adapter/json_api/has_one_test.rb +80 -0
- data/test/adapter/json_api/json_api_test.rb +35 -0
- data/test/adapter/json_api/linked_test.rb +392 -0
- data/test/adapter/json_api/links_test.rb +93 -0
- data/test/adapter/json_api/pagination_links_test.rb +166 -0
- data/test/adapter/json_api/parse_test.rb +137 -0
- data/test/adapter/json_api/relationship_test.rb +161 -0
- data/test/adapter/json_api/relationships_test.rb +199 -0
- data/test/adapter/json_api/resource_identifier_test.rb +85 -0
- data/test/adapter/json_api/resource_meta_test.rb +100 -0
- data/test/adapter/json_api/toplevel_jsonapi_test.rb +82 -0
- data/test/adapter/json_api/transform_test.rb +502 -0
- data/test/adapter/json_api/type_test.rb +61 -0
- data/test/adapter/json_test.rb +45 -0
- data/test/adapter/null_test.rb +23 -0
- data/test/adapter/polymorphic_test.rb +171 -0
- data/test/adapter_test.rb +67 -0
- data/test/array_serializer_test.rb +20 -73
- data/test/benchmark/app.rb +65 -0
- data/test/benchmark/benchmarking_support.rb +67 -0
- data/test/benchmark/bm_caching.rb +119 -0
- data/test/benchmark/bm_transform.rb +34 -0
- data/test/benchmark/config.ru +3 -0
- data/test/benchmark/controllers.rb +84 -0
- data/test/benchmark/fixtures.rb +219 -0
- data/test/cache_test.rb +485 -0
- data/test/collection_serializer_test.rb +110 -0
- data/test/fixtures/active_record.rb +78 -0
- data/test/fixtures/poro.rb +282 -0
- data/test/generators/scaffold_controller_generator_test.rb +24 -0
- data/test/generators/serializer_generator_test.rb +57 -0
- data/test/grape_test.rb +82 -0
- data/test/include_tree/from_include_args_test.rb +26 -0
- data/test/include_tree/from_string_test.rb +94 -0
- data/test/include_tree/include_args_to_hash_test.rb +64 -0
- data/test/lint_test.rb +49 -0
- data/test/logger_test.rb +18 -0
- data/test/poro_test.rb +9 -0
- data/test/serializable_resource_test.rb +83 -0
- data/test/serializers/association_macros_test.rb +36 -0
- data/test/serializers/associations_test.rb +295 -0
- data/test/serializers/attribute_test.rb +151 -0
- data/test/serializers/attributes_test.rb +52 -0
- data/test/serializers/caching_configuration_test_isolated.rb +170 -0
- data/test/serializers/configuration_test.rb +32 -0
- data/test/serializers/fieldset_test.rb +14 -0
- data/test/serializers/meta_test.rb +196 -0
- data/test/serializers/options_test.rb +21 -0
- data/test/serializers/read_attribute_for_serialization_test.rb +79 -0
- data/test/serializers/root_test.rb +21 -0
- data/test/serializers/serialization_test.rb +55 -0
- data/test/serializers/serializer_for_test.rb +134 -0
- data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
- data/test/support/isolated_unit.rb +79 -0
- data/test/support/rails5_shims.rb +47 -0
- data/test/support/rails_app.rb +45 -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 +53 -0
- data/test/test_helper.rb +48 -23
- metadata +449 -43
- data/DESIGN.textile +0 -586
- data/Gemfile.edge +0 -9
- data/bench/perf.rb +0 -43
- data/cruft.md +0 -19
- data/lib/active_model/array_serializer.rb +0 -104
- data/lib/active_record/serializer_override.rb +0 -16
- data/lib/generators/resource_override.rb +0 -13
- data/lib/generators/serializer/USAGE +0 -9
- data/lib/generators/serializer/serializer_generator.rb +0 -42
- data/lib/generators/serializer/templates/serializer.rb +0 -19
- data/test/association_test.rb +0 -592
- data/test/caching_test.rb +0 -96
- data/test/generators_test.rb +0 -85
- data/test/no_serialization_scope_test.rb +0 -34
- data/test/serialization_scope_name_test.rb +0 -67
- data/test/serialization_test.rb +0 -392
- data/test/serializer_support_test.rb +0 -51
- data/test/serializer_test.rb +0 -1465
- data/test/test_fakes.rb +0 -217
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'will_paginate/array'
|
|
3
|
+
require 'kaminari'
|
|
4
|
+
require 'kaminari/hooks'
|
|
5
|
+
::Kaminari::Hooks.init
|
|
6
|
+
|
|
7
|
+
module ActionController
|
|
8
|
+
module Serialization
|
|
9
|
+
class JsonApi
|
|
10
|
+
class PaginationTest < ActionController::TestCase
|
|
11
|
+
KAMINARI_URI = 'http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_kaminari'.freeze
|
|
12
|
+
WILL_PAGINATE_URI = 'http://test.host/action_controller/serialization/json_api/pagination_test/pagination_test/render_pagination_using_will_paginate'.freeze
|
|
13
|
+
|
|
14
|
+
class PaginationTestController < ActionController::Base
|
|
15
|
+
def setup
|
|
16
|
+
@array = [
|
|
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
|
+
]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def using_kaminari
|
|
24
|
+
setup
|
|
25
|
+
Kaminari.paginate_array(@array).page(params[:page][:number]).per(params[:page][:size])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def using_will_paginate
|
|
29
|
+
setup
|
|
30
|
+
@array.paginate(page: params[:page][:number], per_page: params[:page][:size])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def render_pagination_using_kaminari
|
|
34
|
+
render json: using_kaminari, adapter: :json_api
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def render_pagination_using_will_paginate
|
|
38
|
+
render json: using_will_paginate, adapter: :json_api
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def render_array_without_pagination_links
|
|
42
|
+
setup
|
|
43
|
+
render json: @array, adapter: :json_api
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
tests PaginationTestController
|
|
48
|
+
|
|
49
|
+
def test_render_pagination_links_with_will_paginate
|
|
50
|
+
expected_links = { 'self' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1",
|
|
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
|
+
|
|
56
|
+
get :render_pagination_using_will_paginate, params: { page: { number: 2, size: 1 } }
|
|
57
|
+
response = JSON.parse(@response.body)
|
|
58
|
+
assert_equal expected_links, response['links']
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_render_only_last_and_next_pagination_links
|
|
62
|
+
expected_links = { 'self' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2",
|
|
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
|
+
get :render_pagination_using_will_paginate, params: { page: { number: 1, size: 2 } }
|
|
66
|
+
response = JSON.parse(@response.body)
|
|
67
|
+
assert_equal expected_links, response['links']
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_render_pagination_links_with_kaminari
|
|
71
|
+
expected_links = { 'self' => "#{KAMINARI_URI}?page%5Bnumber%5D=2&page%5Bsize%5D=1",
|
|
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
|
+
get :render_pagination_using_kaminari, params: { page: { number: 2, size: 1 } }
|
|
77
|
+
response = JSON.parse(@response.body)
|
|
78
|
+
assert_equal expected_links, response['links']
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_render_only_prev_and_first_pagination_links
|
|
82
|
+
expected_links = { 'self' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1",
|
|
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
|
+
get :render_pagination_using_kaminari, params: { page: { number: 3, size: 1 } }
|
|
86
|
+
response = JSON.parse(@response.body)
|
|
87
|
+
assert_equal expected_links, response['links']
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_render_only_last_and_next_pagination_links_with_additional_params
|
|
91
|
+
expected_links = { 'self' => "#{WILL_PAGINATE_URI}?page%5Bnumber%5D=1&page%5Bsize%5D=2&teste=additional",
|
|
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
|
+
get :render_pagination_using_will_paginate, params: { page: { number: 1, size: 2 }, teste: 'additional' }
|
|
95
|
+
response = JSON.parse(@response.body)
|
|
96
|
+
assert_equal expected_links, response['links']
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def test_render_only_prev_and_first_pagination_links_with_additional_params
|
|
100
|
+
expected_links = { 'self' => "#{KAMINARI_URI}?page%5Bnumber%5D=3&page%5Bsize%5D=1&teste=additional",
|
|
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
|
+
get :render_pagination_using_kaminari, params: { page: { number: 3, size: 1 }, teste: 'additional' }
|
|
104
|
+
response = JSON.parse(@response.body)
|
|
105
|
+
assert_equal expected_links, response['links']
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_array_without_pagination_links
|
|
109
|
+
get :render_array_without_pagination_links, params: { page: { number: 2, size: 1 } }
|
|
110
|
+
response = JSON.parse(@response.body)
|
|
111
|
+
refute response.key? 'links'
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module ActionController
|
|
4
|
+
module Serialization
|
|
5
|
+
class JsonApi
|
|
6
|
+
class KeyTransformTest < ActionController::TestCase
|
|
7
|
+
class KeyTransformTestController < ActionController::Base
|
|
8
|
+
Post = Class.new(::Model)
|
|
9
|
+
class PostSerializer < ActiveModel::Serializer
|
|
10
|
+
type 'posts'
|
|
11
|
+
attributes :title, :body, :publish_at
|
|
12
|
+
belongs_to :author
|
|
13
|
+
has_many :top_comments
|
|
14
|
+
|
|
15
|
+
link(:post_authors) { 'https://example.com/post_authors' }
|
|
16
|
+
|
|
17
|
+
meta do
|
|
18
|
+
{
|
|
19
|
+
rating: 5,
|
|
20
|
+
favorite_count: 10
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Author = Class.new(::Model)
|
|
26
|
+
class AuthorSerializer < ActiveModel::Serializer
|
|
27
|
+
type 'authors'
|
|
28
|
+
attributes :first_name, :last_name
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
TopComment = Class.new(::Model)
|
|
32
|
+
class TopCommentSerializer < ActiveModel::Serializer
|
|
33
|
+
type 'top_comments'
|
|
34
|
+
attributes :body
|
|
35
|
+
belongs_to :author
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def setup_post
|
|
39
|
+
ActionController::Base.cache_store.clear
|
|
40
|
+
@author = Author.new(id: 1, first_name: 'Bob', last_name: 'Jones')
|
|
41
|
+
@comment1 = TopComment.new(id: 7, body: 'cool', author: @author)
|
|
42
|
+
@comment2 = TopComment.new(id: 12, body: 'awesome', author: @author)
|
|
43
|
+
@post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1',
|
|
44
|
+
author: @author, top_comments: [@comment1, @comment2],
|
|
45
|
+
publish_at: '2020-03-16T03:55:25.291Z')
|
|
46
|
+
@comment1.post = @post
|
|
47
|
+
@comment2.post = @post
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def render_resource_with_transform
|
|
51
|
+
setup_post
|
|
52
|
+
render json: @post, serializer: PostSerializer, adapter: :json_api,
|
|
53
|
+
key_transform: :camel
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def render_resource_with_transform_nil
|
|
57
|
+
setup_post
|
|
58
|
+
render json: @post, serializer: PostSerializer, adapter: :json_api,
|
|
59
|
+
key_transform: nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def render_resource_with_transform_with_global_config
|
|
63
|
+
old_transform = ActiveModelSerializers.config.key_transform
|
|
64
|
+
setup_post
|
|
65
|
+
ActiveModelSerializers.config.key_transform = :camel_lower
|
|
66
|
+
render json: @post, serializer: PostSerializer, adapter: :json_api
|
|
67
|
+
ensure
|
|
68
|
+
ActiveModelSerializers.config.key_transform = old_transform
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
tests KeyTransformTestController
|
|
73
|
+
|
|
74
|
+
def test_render_resource_with_transform
|
|
75
|
+
get :render_resource_with_transform
|
|
76
|
+
response = JSON.parse(@response.body)
|
|
77
|
+
expected = {
|
|
78
|
+
'Data' => {
|
|
79
|
+
'Id' => '1337',
|
|
80
|
+
'Type' => 'Posts',
|
|
81
|
+
'Attributes' => {
|
|
82
|
+
'Title' => 'Title 1',
|
|
83
|
+
'Body' => 'Body 1',
|
|
84
|
+
'PublishAt' => '2020-03-16T03:55:25.291Z'
|
|
85
|
+
},
|
|
86
|
+
'Relationships' => {
|
|
87
|
+
'Author' => {
|
|
88
|
+
'Data' => {
|
|
89
|
+
'Id' => '1',
|
|
90
|
+
'Type' => 'Authors'
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
'TopComments' => {
|
|
94
|
+
'Data' => [
|
|
95
|
+
{ 'Id' => '7', 'Type' => 'TopComments' },
|
|
96
|
+
{ 'Id' => '12', 'Type' => 'TopComments' }
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
'Links' => {
|
|
101
|
+
'PostAuthors' => 'https://example.com/post_authors'
|
|
102
|
+
},
|
|
103
|
+
'Meta' => { 'Rating' => 5, 'FavoriteCount' => 10 }
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
assert_equal expected, response
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_render_resource_with_transform_nil
|
|
110
|
+
get :render_resource_with_transform_nil
|
|
111
|
+
response = JSON.parse(@response.body)
|
|
112
|
+
expected = {
|
|
113
|
+
'data' => {
|
|
114
|
+
'id' => '1337',
|
|
115
|
+
'type' => 'posts',
|
|
116
|
+
'attributes' => {
|
|
117
|
+
'title' => 'Title 1',
|
|
118
|
+
'body' => 'Body 1',
|
|
119
|
+
'publish-at' => '2020-03-16T03:55:25.291Z'
|
|
120
|
+
},
|
|
121
|
+
'relationships' => {
|
|
122
|
+
'author' => {
|
|
123
|
+
'data' => {
|
|
124
|
+
'id' => '1',
|
|
125
|
+
'type' => 'authors'
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
'top-comments' => {
|
|
129
|
+
'data' => [
|
|
130
|
+
{ 'id' => '7', 'type' => 'top-comments' },
|
|
131
|
+
{ 'id' => '12', 'type' => 'top-comments' }
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
'links' => {
|
|
136
|
+
'post-authors' => 'https://example.com/post_authors'
|
|
137
|
+
},
|
|
138
|
+
'meta' => { 'rating' => 5, 'favorite-count' => 10 }
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
assert_equal expected, response
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def test_render_resource_with_transform_with_global_config
|
|
145
|
+
get :render_resource_with_transform_with_global_config
|
|
146
|
+
response = JSON.parse(@response.body)
|
|
147
|
+
expected = {
|
|
148
|
+
'data' => {
|
|
149
|
+
'id' => '1337',
|
|
150
|
+
'type' => 'posts',
|
|
151
|
+
'attributes' => {
|
|
152
|
+
'title' => 'Title 1',
|
|
153
|
+
'body' => 'Body 1',
|
|
154
|
+
'publishAt' => '2020-03-16T03:55:25.291Z'
|
|
155
|
+
},
|
|
156
|
+
'relationships' => {
|
|
157
|
+
'author' => {
|
|
158
|
+
'data' => {
|
|
159
|
+
'id' => '1',
|
|
160
|
+
'type' => 'authors'
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
'topComments' => {
|
|
164
|
+
'data' => [
|
|
165
|
+
{ 'id' => '7', 'type' => 'topComments' },
|
|
166
|
+
{ 'id' => '12', 'type' => 'topComments' }
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
'links' => {
|
|
171
|
+
'postAuthors' => 'https://example.com/post_authors'
|
|
172
|
+
},
|
|
173
|
+
'meta' => { 'rating' => 5, 'favoriteCount' => 10 }
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
assert_equal expected, response
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module SerializationScopeTesting
|
|
4
|
+
class User < ActiveModelSerializers::Model
|
|
5
|
+
attr_accessor :id, :name, :admin
|
|
6
|
+
def admin?
|
|
7
|
+
admin
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
class Comment < ActiveModelSerializers::Model
|
|
11
|
+
attr_accessor :id, :body
|
|
12
|
+
end
|
|
13
|
+
class Post < ActiveModelSerializers::Model
|
|
14
|
+
attr_accessor :id, :title, :body, :comments
|
|
15
|
+
end
|
|
16
|
+
class PostSerializer < ActiveModel::Serializer
|
|
17
|
+
attributes :id, :title, :body, :comments
|
|
18
|
+
|
|
19
|
+
def body
|
|
20
|
+
"The 'scope' is the 'current_user': #{scope == current_user}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def comments
|
|
24
|
+
if current_user.admin?
|
|
25
|
+
[Comment.new(id: 1, body: 'Admin')]
|
|
26
|
+
else
|
|
27
|
+
[Comment.new(id: 2, body: 'Scoped')]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def json_key
|
|
32
|
+
'post'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
class PostTestController < ActionController::Base
|
|
36
|
+
attr_accessor :current_user
|
|
37
|
+
def render_post_by_non_admin
|
|
38
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
|
39
|
+
render json: new_post, serializer: serializer, adapter: :json
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def render_post_by_admin
|
|
43
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: true)
|
|
44
|
+
render json: new_post, serializer: serializer, adapter: :json
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def new_post
|
|
50
|
+
Post.new(id: 4, title: 'Title')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def serializer
|
|
54
|
+
PostSerializer
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
class PostViewContextSerializer < PostSerializer
|
|
58
|
+
def body
|
|
59
|
+
"The 'scope' is the 'view_context': #{scope == view_context}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def comments
|
|
63
|
+
if view_context.controller.current_user.admin?
|
|
64
|
+
[Comment.new(id: 1, body: 'Admin')]
|
|
65
|
+
else
|
|
66
|
+
[Comment.new(id: 2, body: 'Scoped')]
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
class DefaultScopeTest < ActionController::TestCase
|
|
71
|
+
tests PostTestController
|
|
72
|
+
|
|
73
|
+
def test_default_serialization_scope
|
|
74
|
+
assert_equal :current_user, @controller._serialization_scope
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_default_serialization_scope_object
|
|
78
|
+
assert_equal @controller.current_user, @controller.serialization_scope
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_default_scope_non_admin
|
|
82
|
+
get :render_post_by_non_admin
|
|
83
|
+
expected_json = {
|
|
84
|
+
post: {
|
|
85
|
+
id: 4,
|
|
86
|
+
title: 'Title',
|
|
87
|
+
body: "The 'scope' is the 'current_user': true",
|
|
88
|
+
comments: [
|
|
89
|
+
{ id: 2, body: 'Scoped' }
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
}.to_json
|
|
93
|
+
assert_equal expected_json, @response.body
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_default_scope_admin
|
|
97
|
+
get :render_post_by_admin
|
|
98
|
+
expected_json = {
|
|
99
|
+
post: {
|
|
100
|
+
id: 4,
|
|
101
|
+
title: 'Title',
|
|
102
|
+
body: "The 'scope' is the 'current_user': true",
|
|
103
|
+
comments: [
|
|
104
|
+
{ id: 1, body: 'Admin' }
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
}.to_json
|
|
108
|
+
assert_equal expected_json, @response.body
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
class SerializationScopeTest < ActionController::TestCase
|
|
112
|
+
class PostViewContextTestController < PostTestController
|
|
113
|
+
serialization_scope :view_context
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
def serializer
|
|
118
|
+
PostViewContextSerializer
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
tests PostViewContextTestController
|
|
122
|
+
|
|
123
|
+
def test_defined_serialization_scope
|
|
124
|
+
assert_equal :view_context, @controller._serialization_scope
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_defined_serialization_scope_object
|
|
128
|
+
assert_equal @controller.view_context.class, @controller.serialization_scope.class
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_serialization_scope_non_admin
|
|
132
|
+
get :render_post_by_non_admin
|
|
133
|
+
expected_json = {
|
|
134
|
+
post: {
|
|
135
|
+
id: 4,
|
|
136
|
+
title: 'Title',
|
|
137
|
+
body: "The 'scope' is the 'view_context': true",
|
|
138
|
+
comments: [
|
|
139
|
+
{ id: 2, body: 'Scoped' }
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
}.to_json
|
|
143
|
+
assert_equal expected_json, @response.body
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_serialization_scope_admin
|
|
147
|
+
get :render_post_by_admin
|
|
148
|
+
expected_json = {
|
|
149
|
+
post: {
|
|
150
|
+
id: 4,
|
|
151
|
+
title: 'Title',
|
|
152
|
+
body: "The 'scope' is the 'view_context': true",
|
|
153
|
+
comments: [
|
|
154
|
+
{ id: 1, body: 'Admin' }
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
}.to_json
|
|
158
|
+
assert_equal expected_json, @response.body
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
class NilSerializationScopeTest < ActionController::TestCase
|
|
162
|
+
class PostViewContextTestController < ActionController::Base
|
|
163
|
+
serialization_scope nil
|
|
164
|
+
|
|
165
|
+
attr_accessor :current_user
|
|
166
|
+
|
|
167
|
+
def render_post_with_no_scope
|
|
168
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
|
169
|
+
render json: new_post, serializer: PostSerializer, adapter: :json
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def render_post_with_passed_in_scope
|
|
173
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
|
174
|
+
render json: new_post, serializer: PostSerializer, adapter: :json, scope: current_user, scope_name: :current_user
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def render_post_with_passed_in_scope_without_scope_name
|
|
178
|
+
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
|
179
|
+
render json: new_post, serializer: PostSerializer, adapter: :json, scope: current_user
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
private
|
|
183
|
+
|
|
184
|
+
def new_post
|
|
185
|
+
Post.new(id: 4, title: 'Title')
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
tests PostViewContextTestController
|
|
189
|
+
|
|
190
|
+
def test_nil_serialization_scope
|
|
191
|
+
assert_nil @controller._serialization_scope
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def test_nil_serialization_scope_object
|
|
195
|
+
assert_nil @controller.serialization_scope
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_nil_scope
|
|
199
|
+
exception_matcher = /current_user/
|
|
200
|
+
exception = assert_raises(NameError) do
|
|
201
|
+
get :render_post_with_no_scope
|
|
202
|
+
end
|
|
203
|
+
assert_match exception_matcher, exception.message
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def test_serialization_scope_is_and_nil_scope_passed_in_current_user
|
|
207
|
+
get :render_post_with_passed_in_scope
|
|
208
|
+
expected_json = {
|
|
209
|
+
post: {
|
|
210
|
+
id: 4,
|
|
211
|
+
title: 'Title',
|
|
212
|
+
body: "The 'scope' is the 'current_user': true",
|
|
213
|
+
comments: [
|
|
214
|
+
{ id: 2, body: 'Scoped' }
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
}.to_json
|
|
218
|
+
assert_equal expected_json, @response.body
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def test_serialization_scope_is_nil_and_scope_passed_in_current_user_without_scope_name
|
|
222
|
+
exception_matcher = /current_user/
|
|
223
|
+
exception = assert_raises(NameError) do
|
|
224
|
+
get :render_post_with_passed_in_scope_without_scope_name
|
|
225
|
+
end
|
|
226
|
+
assert_match exception_matcher, exception.message
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|