active_model_serializers 0.10.0 → 0.10.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (206) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +10 -5
  3. data/.travis.yml +41 -21
  4. data/CHANGELOG.md +200 -2
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +25 -4
  7. data/README.md +166 -28
  8. data/Rakefile +5 -32
  9. data/active_model_serializers.gemspec +23 -25
  10. data/appveyor.yml +10 -6
  11. data/bin/rubocop +38 -0
  12. data/docs/README.md +2 -1
  13. data/docs/general/adapters.md +35 -11
  14. data/docs/general/caching.md +7 -1
  15. data/docs/general/configuration_options.md +86 -1
  16. data/docs/general/deserialization.md +1 -1
  17. data/docs/general/fields.md +31 -0
  18. data/docs/general/getting_started.md +1 -1
  19. data/docs/general/logging.md +7 -0
  20. data/docs/general/rendering.md +63 -25
  21. data/docs/general/serializers.md +137 -14
  22. data/docs/howto/add_pagination_links.md +16 -17
  23. data/docs/howto/add_relationship_links.md +140 -0
  24. data/docs/howto/add_root_key.md +11 -0
  25. data/docs/howto/grape_integration.md +42 -0
  26. data/docs/howto/outside_controller_use.md +12 -4
  27. data/docs/howto/passing_arbitrary_options.md +2 -2
  28. data/docs/howto/serialize_poro.md +46 -5
  29. data/docs/howto/test.md +2 -0
  30. data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
  31. data/docs/integrations/ember-and-json-api.md +67 -32
  32. data/docs/jsonapi/schema.md +1 -1
  33. data/lib/action_controller/serialization.rb +15 -3
  34. data/lib/active_model/serializable_resource.rb +2 -0
  35. data/lib/active_model/serializer/adapter/attributes.rb +2 -0
  36. data/lib/active_model/serializer/adapter/base.rb +4 -0
  37. data/lib/active_model/serializer/adapter/json.rb +2 -0
  38. data/lib/active_model/serializer/adapter/json_api.rb +2 -0
  39. data/lib/active_model/serializer/adapter/null.rb +2 -0
  40. data/lib/active_model/serializer/adapter.rb +2 -0
  41. data/lib/active_model/serializer/array_serializer.rb +10 -5
  42. data/lib/active_model/serializer/association.rb +64 -10
  43. data/lib/active_model/serializer/attribute.rb +2 -0
  44. data/lib/active_model/serializer/belongs_to_reflection.rb +6 -3
  45. data/lib/active_model/serializer/collection_serializer.rb +39 -13
  46. data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +87 -116
  47. data/lib/active_model/serializer/error_serializer.rb +13 -7
  48. data/lib/active_model/serializer/errors_serializer.rb +27 -20
  49. data/lib/active_model/serializer/field.rb +2 -0
  50. data/lib/active_model/serializer/fieldset.rb +2 -0
  51. data/lib/active_model/serializer/has_many_reflection.rb +5 -3
  52. data/lib/active_model/serializer/has_one_reflection.rb +3 -4
  53. data/lib/active_model/serializer/lazy_association.rb +99 -0
  54. data/lib/active_model/serializer/link.rb +23 -0
  55. data/lib/active_model/serializer/lint.rb +136 -130
  56. data/lib/active_model/serializer/null.rb +2 -0
  57. data/lib/active_model/serializer/reflection.rb +132 -67
  58. data/lib/active_model/serializer/version.rb +3 -1
  59. data/lib/active_model/serializer.rb +308 -82
  60. data/lib/active_model_serializers/adapter/attributes.rb +5 -66
  61. data/lib/active_model_serializers/adapter/base.rb +41 -39
  62. data/lib/active_model_serializers/adapter/json.rb +2 -0
  63. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +4 -2
  64. data/lib/active_model_serializers/adapter/json_api/error.rb +2 -0
  65. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +2 -0
  66. data/lib/active_model_serializers/adapter/json_api/link.rb +3 -1
  67. data/lib/active_model_serializers/adapter/json_api/meta.rb +2 -0
  68. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +49 -21
  69. data/lib/active_model_serializers/adapter/json_api/relationship.rb +77 -23
  70. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +41 -10
  71. data/lib/active_model_serializers/adapter/json_api.rb +84 -65
  72. data/lib/active_model_serializers/adapter/null.rb +2 -0
  73. data/lib/active_model_serializers/adapter.rb +9 -1
  74. data/lib/active_model_serializers/callbacks.rb +2 -0
  75. data/lib/active_model_serializers/deprecate.rb +3 -2
  76. data/lib/active_model_serializers/deserialization.rb +4 -0
  77. data/lib/active_model_serializers/json_pointer.rb +2 -0
  78. data/lib/active_model_serializers/logging.rb +2 -0
  79. data/lib/active_model_serializers/lookup_chain.rb +82 -0
  80. data/lib/active_model_serializers/model.rb +111 -28
  81. data/lib/active_model_serializers/railtie.rb +7 -1
  82. data/lib/active_model_serializers/register_jsonapi_renderer.rb +46 -31
  83. data/lib/active_model_serializers/serializable_resource.rb +10 -7
  84. data/lib/active_model_serializers/serialization_context.rb +12 -3
  85. data/lib/active_model_serializers/test/schema.rb +4 -2
  86. data/lib/active_model_serializers/test/serializer.rb +2 -0
  87. data/lib/active_model_serializers/test.rb +2 -0
  88. data/lib/active_model_serializers.rb +35 -10
  89. data/lib/generators/rails/resource_override.rb +3 -1
  90. data/lib/generators/rails/serializer_generator.rb +6 -4
  91. data/lib/grape/active_model_serializers.rb +9 -5
  92. data/lib/grape/formatters/active_model_serializers.rb +21 -2
  93. data/lib/grape/helpers/active_model_serializers.rb +3 -0
  94. data/lib/tasks/rubocop.rake +55 -0
  95. data/test/action_controller/adapter_selector_test.rb +16 -5
  96. data/test/action_controller/explicit_serializer_test.rb +7 -4
  97. data/test/action_controller/json/include_test.rb +108 -27
  98. data/test/action_controller/json_api/deserialization_test.rb +3 -1
  99. data/test/action_controller/json_api/errors_test.rb +10 -9
  100. data/test/action_controller/json_api/fields_test.rb +68 -0
  101. data/test/action_controller/json_api/linked_test.rb +31 -24
  102. data/test/action_controller/json_api/pagination_test.rb +33 -23
  103. data/test/action_controller/json_api/transform_test.rb +13 -3
  104. data/test/action_controller/lookup_proc_test.rb +51 -0
  105. data/test/action_controller/namespace_lookup_test.rb +234 -0
  106. data/test/action_controller/serialization_scope_name_test.rb +14 -6
  107. data/test/action_controller/serialization_test.rb +23 -12
  108. data/test/active_model_serializers/adapter_for_test.rb +2 -0
  109. data/test/active_model_serializers/json_pointer_test.rb +17 -13
  110. data/test/active_model_serializers/logging_test.rb +2 -0
  111. data/test/active_model_serializers/model_test.rb +139 -4
  112. data/test/active_model_serializers/railtie_test_isolated.rb +14 -7
  113. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +163 -0
  114. data/test/active_model_serializers/serialization_context_test_isolated.rb +25 -10
  115. data/test/active_model_serializers/test/schema_test.rb +5 -2
  116. data/test/active_model_serializers/test/serializer_test.rb +2 -0
  117. data/test/active_record_test.rb +2 -0
  118. data/test/adapter/attributes_test.rb +42 -0
  119. data/test/adapter/deprecation_test.rb +2 -0
  120. data/test/adapter/json/belongs_to_test.rb +2 -0
  121. data/test/adapter/json/collection_test.rb +16 -0
  122. data/test/adapter/json/has_many_test.rb +12 -2
  123. data/test/adapter/json/transform_test.rb +17 -15
  124. data/test/adapter/json_api/belongs_to_test.rb +2 -0
  125. data/test/adapter/json_api/collection_test.rb +6 -3
  126. data/test/adapter/json_api/errors_test.rb +19 -19
  127. data/test/adapter/json_api/fields_test.rb +14 -3
  128. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +2 -0
  129. data/test/adapter/json_api/has_many_test.rb +51 -20
  130. data/test/adapter/json_api/has_one_test.rb +2 -0
  131. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +215 -0
  132. data/test/adapter/json_api/json_api_test.rb +7 -7
  133. data/test/adapter/json_api/linked_test.rb +35 -12
  134. data/test/adapter/json_api/links_test.rb +22 -3
  135. data/test/adapter/json_api/pagination_links_test.rb +55 -13
  136. data/test/adapter/json_api/parse_test.rb +3 -1
  137. data/test/adapter/json_api/relationship_test.rb +311 -73
  138. data/test/adapter/json_api/resource_meta_test.rb +5 -3
  139. data/test/adapter/json_api/toplevel_jsonapi_test.rb +2 -0
  140. data/test/adapter/json_api/transform_test.rb +265 -253
  141. data/test/adapter/json_api/type_test.rb +170 -36
  142. data/test/adapter/json_test.rb +10 -7
  143. data/test/adapter/null_test.rb +3 -2
  144. data/test/adapter/polymorphic_test.rb +54 -5
  145. data/test/adapter_test.rb +3 -1
  146. data/test/array_serializer_test.rb +2 -0
  147. data/test/benchmark/app.rb +3 -1
  148. data/test/benchmark/benchmarking_support.rb +3 -1
  149. data/test/benchmark/bm_active_record.rb +83 -0
  150. data/test/benchmark/bm_adapter.rb +40 -0
  151. data/test/benchmark/bm_caching.rb +18 -16
  152. data/test/benchmark/bm_lookup_chain.rb +85 -0
  153. data/test/benchmark/bm_transform.rb +23 -10
  154. data/test/benchmark/controllers.rb +18 -17
  155. data/test/benchmark/fixtures.rb +74 -72
  156. data/test/cache_test.rb +301 -69
  157. data/test/collection_serializer_test.rb +33 -14
  158. data/test/fixtures/active_record.rb +47 -10
  159. data/test/fixtures/poro.rb +128 -183
  160. data/test/generators/scaffold_controller_generator_test.rb +2 -0
  161. data/test/generators/serializer_generator_test.rb +25 -5
  162. data/test/grape_test.rb +172 -56
  163. data/test/lint_test.rb +3 -1
  164. data/test/logger_test.rb +15 -11
  165. data/test/poro_test.rb +2 -0
  166. data/test/serializable_resource_test.rb +20 -22
  167. data/test/serializers/association_macros_test.rb +5 -2
  168. data/test/serializers/associations_test.rb +274 -49
  169. data/test/serializers/attribute_test.rb +7 -3
  170. data/test/serializers/attributes_test.rb +3 -1
  171. data/test/serializers/caching_configuration_test_isolated.rb +8 -6
  172. data/test/serializers/configuration_test.rb +2 -0
  173. data/test/serializers/fieldset_test.rb +3 -1
  174. data/test/serializers/meta_test.rb +14 -6
  175. data/test/serializers/options_test.rb +19 -6
  176. data/test/serializers/read_attribute_for_serialization_test.rb +5 -3
  177. data/test/serializers/reflection_test.rb +481 -0
  178. data/test/serializers/root_test.rb +3 -1
  179. data/test/serializers/serialization_test.rb +4 -2
  180. data/test/serializers/serializer_for_test.rb +14 -10
  181. data/test/serializers/serializer_for_with_namespace_test.rb +90 -0
  182. data/test/support/isolated_unit.rb +11 -4
  183. data/test/support/rails5_shims.rb +10 -2
  184. data/test/support/rails_app.rb +4 -9
  185. data/test/support/serialization_testing.rb +33 -5
  186. data/test/test_helper.rb +15 -0
  187. metadata +126 -46
  188. data/.rubocop_todo.yml +0 -167
  189. data/docs/ARCHITECTURE.md +0 -126
  190. data/lib/active_model/serializer/associations.rb +0 -100
  191. data/lib/active_model/serializer/attributes.rb +0 -82
  192. data/lib/active_model/serializer/collection_reflection.rb +0 -7
  193. data/lib/active_model/serializer/configuration.rb +0 -35
  194. data/lib/active_model/serializer/include_tree.rb +0 -111
  195. data/lib/active_model/serializer/links.rb +0 -35
  196. data/lib/active_model/serializer/meta.rb +0 -29
  197. data/lib/active_model/serializer/singular_reflection.rb +0 -7
  198. data/lib/active_model/serializer/type.rb +0 -25
  199. data/lib/active_model_serializers/key_transform.rb +0 -70
  200. data/test/active_model_serializers/key_transform_test.rb +0 -263
  201. data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
  202. data/test/adapter/json_api/relationships_test.rb +0 -199
  203. data/test/adapter/json_api/resource_identifier_test.rb +0 -85
  204. data/test/include_tree/from_include_args_test.rb +0 -26
  205. data/test/include_tree/from_string_test.rb +0 -94
  206. data/test/include_tree/include_args_to_hash_test.rb +0 -64
@@ -1,9 +1,144 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
- class ActiveModelSerializers::ModelTest < ActiveSupport::TestCase
4
- include ActiveModel::Serializer::Lint::Tests
5
+ module ActiveModelSerializers
6
+ class ModelTest < ActiveSupport::TestCase
7
+ include ActiveModel::Serializer::Lint::Tests
8
+
9
+ setup do
10
+ @resource = ActiveModelSerializers::Model.new
11
+ end
12
+
13
+ def test_initialization_with_string_keys
14
+ klass = Class.new(ActiveModelSerializers::Model) do
15
+ attributes :key
16
+ end
17
+ value = 'value'
18
+
19
+ model_instance = klass.new('key' => value)
20
+
21
+ assert_equal model_instance.read_attribute_for_serialization(:key), value
22
+ end
23
+
24
+ def test_attributes_can_be_read_for_serialization
25
+ klass = Class.new(ActiveModelSerializers::Model) do
26
+ attributes :one, :two, :three
27
+ end
28
+ original_attributes = { one: 1, two: 2, three: 3 }
29
+ original_instance = klass.new(original_attributes)
30
+
31
+ # Initial value
32
+ instance = original_instance
33
+ expected_attributes = { one: 1, two: 2, three: 3 }.with_indifferent_access
34
+ assert_equal expected_attributes, instance.attributes
35
+ assert_equal 1, instance.one
36
+ assert_equal 1, instance.read_attribute_for_serialization(:one)
37
+
38
+ # FIXME: Change via accessor has no effect on attributes.
39
+ instance = original_instance.dup
40
+ instance.one = :not_one
41
+ assert_equal expected_attributes, instance.attributes
42
+ assert_equal :not_one, instance.one
43
+ assert_equal :not_one, instance.read_attribute_for_serialization(:one)
44
+
45
+ # FIXME: Change via mutating attributes
46
+ instance = original_instance.dup
47
+ instance.attributes[:one] = :not_one
48
+ expected_attributes = { one: :not_one, two: 2, three: 3 }.with_indifferent_access
49
+ assert_equal expected_attributes, instance.attributes
50
+ assert_equal 1, instance.one
51
+ assert_equal 1, instance.read_attribute_for_serialization(:one)
52
+ end
53
+
54
+ def test_attributes_can_be_read_for_serialization_with_attributes_accessors_fix
55
+ klass = Class.new(ActiveModelSerializers::Model) do
56
+ derive_attributes_from_names_and_fix_accessors
57
+ attributes :one, :two, :three
58
+ end
59
+ original_attributes = { one: 1, two: 2, three: 3 }
60
+ original_instance = klass.new(original_attributes)
61
+
62
+ # Initial value
63
+ instance = original_instance
64
+ expected_attributes = { one: 1, two: 2, three: 3 }.with_indifferent_access
65
+ assert_equal expected_attributes, instance.attributes
66
+ assert_equal 1, instance.one
67
+ assert_equal 1, instance.read_attribute_for_serialization(:one)
68
+
69
+ expected_attributes = { one: :not_one, two: 2, three: 3 }.with_indifferent_access
70
+ # Change via accessor
71
+ instance = original_instance.dup
72
+ instance.one = :not_one
73
+ assert_equal expected_attributes, instance.attributes
74
+ assert_equal :not_one, instance.one
75
+ assert_equal :not_one, instance.read_attribute_for_serialization(:one)
76
+
77
+ # Attributes frozen
78
+ assert instance.attributes.frozen?
79
+ end
80
+
81
+ def test_id_attribute_can_be_read_for_serialization
82
+ klass = Class.new(ActiveModelSerializers::Model) do
83
+ attributes :id, :one, :two, :three
84
+ end
85
+ self.class.const_set(:SomeTestModel, klass)
86
+ original_attributes = { id: :ego, one: 1, two: 2, three: 3 }
87
+ original_instance = klass.new(original_attributes)
88
+
89
+ # Initial value
90
+ instance = original_instance.dup
91
+ expected_attributes = { id: :ego, one: 1, two: 2, three: 3 }.with_indifferent_access
92
+ assert_equal expected_attributes, instance.attributes
93
+ assert_equal :ego, instance.id
94
+ assert_equal :ego, instance.read_attribute_for_serialization(:id)
95
+
96
+ # FIXME: Change via accessor has no effect on attributes.
97
+ instance = original_instance.dup
98
+ instance.id = :superego
99
+ assert_equal expected_attributes, instance.attributes
100
+ assert_equal :superego, instance.id
101
+ assert_equal :superego, instance.read_attribute_for_serialization(:id)
102
+
103
+ # FIXME: Change via mutating attributes
104
+ instance = original_instance.dup
105
+ instance.attributes[:id] = :superego
106
+ expected_attributes = { id: :superego, one: 1, two: 2, three: 3 }.with_indifferent_access
107
+ assert_equal expected_attributes, instance.attributes
108
+ assert_equal :ego, instance.id
109
+ assert_equal :ego, instance.read_attribute_for_serialization(:id)
110
+ ensure
111
+ self.class.send(:remove_const, :SomeTestModel)
112
+ end
113
+
114
+ def test_id_attribute_can_be_read_for_serialization_with_attributes_accessors_fix
115
+ klass = Class.new(ActiveModelSerializers::Model) do
116
+ derive_attributes_from_names_and_fix_accessors
117
+ attributes :id, :one, :two, :three
118
+ end
119
+ self.class.const_set(:SomeTestModel, klass)
120
+ original_attributes = { id: :ego, one: 1, two: 2, three: 3 }
121
+ original_instance = klass.new(original_attributes)
122
+
123
+ # Initial value
124
+ instance = original_instance.dup
125
+ expected_attributes = { id: :ego, one: 1, two: 2, three: 3 }.with_indifferent_access
126
+ assert_equal expected_attributes, instance.attributes
127
+ assert_equal :ego, instance.id
128
+ assert_equal :ego, instance.read_attribute_for_serialization(:id)
129
+
130
+ expected_attributes = { id: :superego, one: 1, two: 2, three: 3 }.with_indifferent_access
131
+ # Change via accessor
132
+ instance = original_instance.dup
133
+ instance.id = :superego
134
+ assert_equal expected_attributes, instance.attributes
135
+ assert_equal :superego, instance.id
136
+ assert_equal :superego, instance.read_attribute_for_serialization(:id)
5
137
 
6
- def setup
7
- @resource = ActiveModelSerializers::Model.new
138
+ # Attributes frozen
139
+ assert instance.attributes.frozen?
140
+ ensure
141
+ self.class.send(:remove_const, :SomeTestModel)
142
+ end
8
143
  end
9
144
  end
@@ -1,14 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Execute this test in isolation
2
4
  require 'support/isolated_unit'
3
5
 
4
6
  class RailtieTest < ActiveSupport::TestCase
5
7
  include ActiveSupport::Testing::Isolation
6
8
 
7
- class WithRails < RailtieTest
9
+ class WithRailsRequiredFirst < RailtieTest
8
10
  setup do
9
11
  require 'rails'
10
12
  require 'active_model_serializers'
11
- make_basic_app
13
+ make_basic_app do |app|
14
+ app.config.action_controller.perform_caching = true
15
+ end
12
16
  end
13
17
 
14
18
  test 'mixes ActionController::Serialization into ActionController::Base' do
@@ -32,14 +36,17 @@ class RailtieTest < ActiveSupport::TestCase
32
36
 
33
37
  test 'it is configured for caching' do
34
38
  assert_equal ActionController::Base.cache_store, ActiveModelSerializers.config.cache_store
35
- assert_equal Rails.configuration.action_controller.perform_caching, ActiveModelSerializers.config.perform_caching
39
+ assert_equal true, Rails.configuration.action_controller.perform_caching
40
+ assert_equal true, ActiveModelSerializers.config.perform_caching
36
41
  end
37
42
  end
38
43
 
39
- class WithoutRails < RailtieTest
44
+ class WithoutRailsRequiredFirst < RailtieTest
40
45
  setup do
41
46
  require 'active_model_serializers'
42
- make_basic_app
47
+ make_basic_app do |app|
48
+ app.config.action_controller.perform_caching = true
49
+ end
43
50
  end
44
51
 
45
52
  test 'does not mix ActionController::Serialization into ActionController::Base' do
@@ -56,8 +63,8 @@ class RailtieTest < ActiveSupport::TestCase
56
63
  test 'it is not configured for caching' do
57
64
  refute_nil ActionController::Base.cache_store
58
65
  assert_nil ActiveModelSerializers.config.cache_store
59
- refute Rails.configuration.action_controller.perform_caching
60
- refute ActiveModelSerializers.config.perform_caching
66
+ assert_equal true, Rails.configuration.action_controller.perform_caching
67
+ assert_nil ActiveModelSerializers.config.perform_caching
61
68
  end
62
69
  end
63
70
  end
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'support/isolated_unit'
4
+ require 'minitest/mock'
5
+ require 'action_dispatch'
6
+ require 'action_controller'
7
+
8
+ class JsonApiRendererTest < ActionDispatch::IntegrationTest
9
+ include ActiveSupport::Testing::Isolation
10
+
11
+ class TestController < ActionController::Base
12
+ class << self
13
+ attr_accessor :last_request_parameters
14
+ end
15
+
16
+ def render_with_jsonapi_renderer
17
+ permitted_params = params.permit(data: [:id, :type, attributes: [:name]])
18
+ permitted_params = permitted_params.to_h.with_indifferent_access
19
+ attributes =
20
+ if permitted_params[:data]
21
+ permitted_params[:data][:attributes].merge(id: permitted_params[:data][:id])
22
+ else
23
+ # Rails returns empty params when no mime type can be negotiated.
24
+ # (Until https://github.com/rails/rails/pull/26632 is reviewed.)
25
+ permitted_params
26
+ end
27
+ author = Author.new(attributes)
28
+ render jsonapi: author
29
+ end
30
+
31
+ def parse
32
+ self.class.last_request_parameters = request.request_parameters
33
+ head :ok
34
+ end
35
+ end
36
+
37
+ def teardown
38
+ TestController.last_request_parameters = nil
39
+ end
40
+
41
+ def assert_parses(expected, actual, headers = {})
42
+ post '/parse', params: actual, headers: headers
43
+ assert_response :ok
44
+ assert_equal(expected, TestController.last_request_parameters)
45
+ end
46
+
47
+ def define_author_model_and_serializer
48
+ TestController.const_set(:Author, Class.new(ActiveModelSerializers::Model) do
49
+ attributes :id, :name
50
+ end)
51
+ TestController.const_set(:AuthorSerializer, Class.new(ActiveModel::Serializer) do
52
+ type 'users'
53
+ attribute :id
54
+ attribute :name
55
+ end)
56
+ end
57
+
58
+ class WithoutRenderer < JsonApiRendererTest
59
+ setup do
60
+ require 'rails'
61
+ require 'active_record'
62
+ require 'support/rails5_shims'
63
+ require 'active_model_serializers'
64
+ require 'fixtures/poro'
65
+
66
+ make_basic_app
67
+
68
+ Rails.application.routes.draw do
69
+ ActiveSupport::Deprecation.silence do
70
+ match ':action', to: TestController, via: [:get, :post]
71
+ end
72
+ end
73
+ define_author_model_and_serializer
74
+ end
75
+
76
+ def test_jsonapi_parser_not_registered
77
+ parsers = if Rails::VERSION::MAJOR >= 5
78
+ ActionDispatch::Request.parameter_parsers
79
+ else
80
+ ActionDispatch::ParamsParser::DEFAULT_PARSERS
81
+ end
82
+ assert_nil parsers[Mime[:jsonapi]]
83
+ end
84
+
85
+ def test_jsonapi_renderer_not_registered
86
+ payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
87
+ headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
88
+ post '/render_with_jsonapi_renderer', params: payload, headers: headers
89
+ assert_equal '', response.body
90
+ assert_equal 500, response.status
91
+ assert_equal ActionView::MissingTemplate, request.env['action_dispatch.exception'].class
92
+ end
93
+
94
+ def test_jsonapi_parser
95
+ assert_parses(
96
+ {},
97
+ '',
98
+ 'CONTENT_TYPE' => 'application/vnd.api+json'
99
+ )
100
+ end
101
+ end
102
+
103
+ class WithRenderer < JsonApiRendererTest
104
+ setup do
105
+ require 'rails'
106
+ require 'active_record'
107
+ require 'support/rails5_shims'
108
+ require 'active_model_serializers'
109
+ require 'fixtures/poro'
110
+ require 'active_model_serializers/register_jsonapi_renderer'
111
+
112
+ make_basic_app
113
+
114
+ Rails.application.routes.draw do
115
+ ActiveSupport::Deprecation.silence do
116
+ match ':action', to: TestController, via: [:get, :post]
117
+ end
118
+ end
119
+ define_author_model_and_serializer
120
+ end
121
+
122
+ def test_jsonapi_parser_registered
123
+ if Rails::VERSION::MAJOR >= 5
124
+ parsers = ActionDispatch::Request.parameter_parsers
125
+ assert_equal Proc, parsers[:jsonapi].class
126
+ else
127
+ parsers = ActionDispatch::ParamsParser::DEFAULT_PARSERS
128
+ assert_equal Proc, parsers[Mime[:jsonapi]].class
129
+ end
130
+ end
131
+
132
+ def test_jsonapi_renderer_registered
133
+ expected = {
134
+ 'data' => {
135
+ 'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765',
136
+ 'type' => 'users',
137
+ 'attributes' => { 'name' => 'Johnny Rico' }
138
+ }
139
+ }
140
+
141
+ payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
142
+ headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
143
+ post '/render_with_jsonapi_renderer', params: payload, headers: headers
144
+ assert_equal expected.to_json, response.body
145
+ end
146
+
147
+ def test_jsonapi_parser
148
+ assert_parses(
149
+ {
150
+ 'data' => {
151
+ 'attributes' => {
152
+ 'name' => 'John Doe'
153
+ },
154
+ 'type' => 'users',
155
+ 'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765'
156
+ }
157
+ },
158
+ '{"data": {"attributes": {"name": "John Doe"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}',
159
+ 'CONTENT_TYPE' => 'application/vnd.api+json'
160
+ )
161
+ end
162
+ end
163
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Execute this test in isolation
2
4
  require 'support/isolated_unit'
3
5
  require 'minitest/mock'
@@ -5,13 +7,19 @@ require 'minitest/mock'
5
7
  class SerializationContextTest < ActiveSupport::TestCase
6
8
  include ActiveSupport::Testing::Isolation
7
9
 
8
- def create_request
9
- request = Minitest::Mock.new
10
- request.expect(:original_url, 'original_url')
11
- request.expect(:query_parameters, 'query_parameters')
12
- end
13
-
14
10
  class WithRails < SerializationContextTest
11
+ def create_request
12
+ request = ActionDispatch::Request.new({})
13
+ def request.original_url
14
+ 'http://example.com/articles?page=2'
15
+ end
16
+
17
+ def request.query_parameters
18
+ { 'page' => 2 }
19
+ end
20
+ request
21
+ end
22
+
15
23
  setup do
16
24
  require 'rails'
17
25
  require 'active_model_serializers'
@@ -20,8 +28,8 @@ class SerializationContextTest < ActiveSupport::TestCase
20
28
  end
21
29
 
22
30
  test 'create context with request url and query parameters' do
23
- assert_equal @context.request_url, 'original_url'
24
- assert_equal @context.query_parameters, 'query_parameters'
31
+ assert_equal @context.request_url, 'http://example.com/articles'
32
+ assert_equal @context.query_parameters, 'page' => 2
25
33
  end
26
34
 
27
35
  test 'url_helpers is set up for Rails url_helpers' do
@@ -36,14 +44,21 @@ class SerializationContextTest < ActiveSupport::TestCase
36
44
  end
37
45
 
38
46
  class WithoutRails < SerializationContextTest
47
+ def create_request
48
+ {
49
+ request_url: 'http://example.com/articles',
50
+ query_parameters: { 'page' => 2 }
51
+ }
52
+ end
53
+
39
54
  setup do
40
55
  require 'active_model_serializers/serialization_context'
41
56
  @context = ActiveModelSerializers::SerializationContext.new(create_request)
42
57
  end
43
58
 
44
59
  test 'create context with request url and query parameters' do
45
- assert_equal @context.request_url, 'original_url'
46
- assert_equal @context.query_parameters, 'query_parameters'
60
+ assert_equal @context.request_url, 'http://example.com/articles'
61
+ assert_equal @context.query_parameters, 'page' => 2
47
62
  end
48
63
 
49
64
  test 'url_helpers is a module when Rails is not present' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module ActiveModelSerializers
@@ -115,7 +117,8 @@ module ActiveModelSerializers
115
117
  end
116
118
 
117
119
  def test_that_raises_with_a_invalid_json_body
118
- message = 'A JSON text must at least contain two octets!'
120
+ # message changes from JSON gem 2.0.2 to 2.2.0
121
+ message = /A JSON text must at least contain two octets!|unexpected token at ''/
119
122
 
120
123
  get :invalid_json_body
121
124
 
@@ -123,7 +126,7 @@ module ActiveModelSerializers
123
126
  assert_response_schema('custom/show.json')
124
127
  end
125
128
 
126
- assert_equal(message, error.message)
129
+ assert_match(message, error.message)
127
130
  end
128
131
  end
129
132
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module ActiveModelSerializers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class ActiveRecordTest < ActiveSupport::TestCase
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module ActiveModelSerializers
6
+ module Adapter
7
+ class AttributesTest < ActiveSupport::TestCase
8
+ class Person < ActiveModelSerializers::Model
9
+ attributes :first_name, :last_name
10
+ end
11
+
12
+ class PersonSerializer < ActiveModel::Serializer
13
+ attributes :first_name, :last_name
14
+ end
15
+
16
+ def setup
17
+ ActionController::Base.cache_store.clear
18
+ end
19
+
20
+ def test_serializable_hash
21
+ person = Person.new(first_name: 'Arthur', last_name: 'Dent')
22
+ serializer = PersonSerializer.new(person)
23
+ adapter = ActiveModelSerializers::Adapter::Attributes.new(serializer)
24
+
25
+ assert_equal({ first_name: 'Arthur', last_name: 'Dent' },
26
+ adapter.serializable_hash)
27
+ end
28
+
29
+ def test_serializable_hash_with_transform_key_casing
30
+ person = Person.new(first_name: 'Arthur', last_name: 'Dent')
31
+ serializer = PersonSerializer.new(person)
32
+ adapter = ActiveModelSerializers::Adapter::Attributes.new(
33
+ serializer,
34
+ key_transform: :camel_lower
35
+ )
36
+
37
+ assert_equal({ firstName: 'Arthur', lastName: 'Dent' },
38
+ adapter.serializable_hash)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  module ActiveModel
3
5
  class Serializer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module ActiveModelSerializers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module ActiveModelSerializers
@@ -84,6 +86,20 @@ module ActiveModelSerializers
84
86
 
85
87
  assert_equal(expected, actual)
86
88
  end
89
+
90
+ def test_fields_with_no_associations_include_option
91
+ actual = ActiveModelSerializers::SerializableResource.new(
92
+ [@first_post, @second_post], adapter: :json, fields: [:id], include: []
93
+ ).as_json
94
+
95
+ expected = { posts: [{
96
+ id: 1
97
+ }, {
98
+ id: 2
99
+ }] }
100
+
101
+ assert_equal(expected, actual)
102
+ end
87
103
  end
88
104
  end
89
105
  end
@@ -1,9 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module ActiveModelSerializers
4
6
  module Adapter
5
7
  class Json
6
8
  class HasManyTestTest < ActiveSupport::TestCase
9
+ class ModelWithoutSerializer < ::Model
10
+ attributes :id, :name
11
+ end
12
+
7
13
  def setup
8
14
  ActionController::Base.cache_store.clear
9
15
  @author = Author.new(id: 1, name: 'Steve K.')
@@ -16,7 +22,7 @@ module ActiveModelSerializers
16
22
  @second_comment.post = @post
17
23
  @blog = Blog.new(id: 1, name: 'My Blog!!')
18
24
  @post.blog = @blog
19
- @tag = Tag.new(id: 1, name: '#hash_tag')
25
+ @tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
20
26
  @post.tags = [@tag]
21
27
  end
22
28
 
@@ -30,7 +36,11 @@ module ActiveModelSerializers
30
36
  end
31
37
 
32
38
  def test_has_many_with_no_serializer
33
- serializer = PostWithTagsSerializer.new(@post)
39
+ post_serializer_class = Class.new(ActiveModel::Serializer) do
40
+ attributes :id
41
+ has_many :tags
42
+ end
43
+ serializer = post_serializer_class.new(@post)
34
44
  adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
35
45
  assert_equal({
36
46
  id: 42,
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module ActiveModelSerializers
@@ -15,7 +17,7 @@ module ActiveModelSerializers
15
17
  @adapter = ActiveModelSerializers::Adapter::Json.new(serializer, options)
16
18
  end
17
19
 
18
- Post = Class.new(::Model)
20
+ class Post < ::Model; end
19
21
  class PostSerializer < ActiveModel::Serializer
20
22
  attributes :id, :title, :body, :publish_at
21
23
  end
@@ -28,8 +30,8 @@ module ActiveModelSerializers
28
30
  def test_transform_default
29
31
  mock_request
30
32
  assert_equal({
31
- blog: { id: 1, special_attribute: 'neat', articles: nil }
32
- }, @adapter.serializable_hash)
33
+ blog: { id: 1, special_attribute: 'neat', articles: nil }
34
+ }, @adapter.serializable_hash)
33
35
  end
34
36
 
35
37
  def test_transform_global_config
@@ -38,8 +40,8 @@ module ActiveModelSerializers
38
40
  @adapter.serializable_hash
39
41
  end
40
42
  assert_equal({
41
- blog: { id: 1, specialAttribute: 'neat', articles: nil }
42
- }, result)
43
+ blog: { id: 1, specialAttribute: 'neat', articles: nil }
44
+ }, result)
43
45
  end
44
46
 
45
47
  def test_transform_serialization_ctx_overrides_global_config
@@ -48,8 +50,8 @@ module ActiveModelSerializers
48
50
  @adapter.serializable_hash
49
51
  end
50
52
  assert_equal({
51
- Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
52
- }, result)
53
+ Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
54
+ }, result)
53
55
  end
54
56
 
55
57
  def test_transform_undefined
@@ -63,29 +65,29 @@ module ActiveModelSerializers
63
65
  def test_transform_dash
64
66
  mock_request(:dash)
65
67
  assert_equal({
66
- blog: { id: 1, :"special-attribute" => 'neat', articles: nil }
67
- }, @adapter.serializable_hash)
68
+ blog: { id: 1, :"special-attribute" => 'neat', articles: nil }
69
+ }, @adapter.serializable_hash)
68
70
  end
69
71
 
70
72
  def test_transform_unaltered
71
73
  mock_request(:unaltered)
72
74
  assert_equal({
73
- blog: { id: 1, special_attribute: 'neat', articles: nil }
74
- }, @adapter.serializable_hash)
75
+ blog: { id: 1, special_attribute: 'neat', articles: nil }
76
+ }, @adapter.serializable_hash)
75
77
  end
76
78
 
77
79
  def test_transform_camel
78
80
  mock_request(:camel)
79
81
  assert_equal({
80
- Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
81
- }, @adapter.serializable_hash)
82
+ Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
83
+ }, @adapter.serializable_hash)
82
84
  end
83
85
 
84
86
  def test_transform_camel_lower
85
87
  mock_request(:camel_lower)
86
88
  assert_equal({
87
- blog: { id: 1, specialAttribute: 'neat', articles: nil }
88
- }, @adapter.serializable_hash)
89
+ blog: { id: 1, specialAttribute: 'neat', articles: nil }
90
+ }, @adapter.serializable_hash)
89
91
  end
90
92
  end
91
93
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module ActiveModelSerializers