active_model_serializers 0.10.0 → 0.10.9

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.
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