active_model_serializers 0.10.0 → 0.10.7

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 (171) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +6 -5
  3. data/.travis.yml +30 -21
  4. data/CHANGELOG.md +172 -2
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +23 -4
  7. data/README.md +166 -28
  8. data/Rakefile +3 -32
  9. data/active_model_serializers.gemspec +22 -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 +125 -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 +13 -3
  34. data/lib/active_model/serializer/adapter/base.rb +2 -0
  35. data/lib/active_model/serializer/array_serializer.rb +8 -5
  36. data/lib/active_model/serializer/association.rb +62 -10
  37. data/lib/active_model/serializer/belongs_to_reflection.rb +4 -3
  38. data/lib/active_model/serializer/collection_serializer.rb +39 -13
  39. data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +82 -115
  40. data/lib/active_model/serializer/error_serializer.rb +11 -7
  41. data/lib/active_model/serializer/errors_serializer.rb +25 -20
  42. data/lib/active_model/serializer/has_many_reflection.rb +3 -3
  43. data/lib/active_model/serializer/has_one_reflection.rb +1 -4
  44. data/lib/active_model/serializer/lazy_association.rb +95 -0
  45. data/lib/active_model/serializer/lint.rb +134 -130
  46. data/lib/active_model/serializer/reflection.rb +127 -67
  47. data/lib/active_model/serializer/version.rb +1 -1
  48. data/lib/active_model/serializer.rb +297 -79
  49. data/lib/active_model_serializers/adapter/attributes.rb +3 -66
  50. data/lib/active_model_serializers/adapter/base.rb +39 -39
  51. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +2 -2
  52. data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
  53. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +47 -21
  54. data/lib/active_model_serializers/adapter/json_api/relationship.rb +75 -23
  55. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +39 -10
  56. data/lib/active_model_serializers/adapter/json_api.rb +71 -57
  57. data/lib/active_model_serializers/adapter.rb +6 -0
  58. data/lib/active_model_serializers/deprecate.rb +1 -2
  59. data/lib/active_model_serializers/deserialization.rb +2 -0
  60. data/lib/active_model_serializers/lookup_chain.rb +80 -0
  61. data/lib/active_model_serializers/model.rb +109 -28
  62. data/lib/active_model_serializers/railtie.rb +3 -1
  63. data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
  64. data/lib/active_model_serializers/serializable_resource.rb +6 -5
  65. data/lib/active_model_serializers/serialization_context.rb +10 -3
  66. data/lib/active_model_serializers/test/schema.rb +2 -2
  67. data/lib/active_model_serializers.rb +16 -1
  68. data/lib/generators/rails/resource_override.rb +1 -1
  69. data/lib/generators/rails/serializer_generator.rb +4 -4
  70. data/lib/grape/active_model_serializers.rb +7 -5
  71. data/lib/grape/formatters/active_model_serializers.rb +19 -2
  72. data/lib/grape/helpers/active_model_serializers.rb +1 -0
  73. data/lib/tasks/rubocop.rake +53 -0
  74. data/test/action_controller/adapter_selector_test.rb +14 -5
  75. data/test/action_controller/explicit_serializer_test.rb +5 -4
  76. data/test/action_controller/json/include_test.rb +106 -27
  77. data/test/action_controller/json_api/deserialization_test.rb +1 -1
  78. data/test/action_controller/json_api/errors_test.rb +8 -9
  79. data/test/action_controller/json_api/fields_test.rb +66 -0
  80. data/test/action_controller/json_api/linked_test.rb +29 -24
  81. data/test/action_controller/json_api/pagination_test.rb +31 -23
  82. data/test/action_controller/json_api/transform_test.rb +11 -3
  83. data/test/action_controller/lookup_proc_test.rb +49 -0
  84. data/test/action_controller/namespace_lookup_test.rb +232 -0
  85. data/test/action_controller/serialization_scope_name_test.rb +12 -6
  86. data/test/action_controller/serialization_test.rb +12 -9
  87. data/test/active_model_serializers/json_pointer_test.rb +15 -13
  88. data/test/active_model_serializers/model_test.rb +137 -4
  89. data/test/active_model_serializers/railtie_test_isolated.rb +12 -7
  90. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +161 -0
  91. data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
  92. data/test/active_model_serializers/test/schema_test.rb +3 -2
  93. data/test/adapter/attributes_test.rb +40 -0
  94. data/test/adapter/json/collection_test.rb +14 -0
  95. data/test/adapter/json/has_many_test.rb +10 -2
  96. data/test/adapter/json/transform_test.rb +15 -15
  97. data/test/adapter/json_api/collection_test.rb +4 -3
  98. data/test/adapter/json_api/errors_test.rb +17 -19
  99. data/test/adapter/json_api/fields_test.rb +12 -3
  100. data/test/adapter/json_api/has_many_test.rb +49 -20
  101. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +213 -0
  102. data/test/adapter/json_api/json_api_test.rb +5 -7
  103. data/test/adapter/json_api/linked_test.rb +33 -12
  104. data/test/adapter/json_api/links_test.rb +4 -2
  105. data/test/adapter/json_api/pagination_links_test.rb +53 -13
  106. data/test/adapter/json_api/parse_test.rb +1 -1
  107. data/test/adapter/json_api/relationship_test.rb +309 -73
  108. data/test/adapter/json_api/resource_meta_test.rb +3 -3
  109. data/test/adapter/json_api/transform_test.rb +263 -253
  110. data/test/adapter/json_api/type_test.rb +168 -36
  111. data/test/adapter/json_test.rb +8 -7
  112. data/test/adapter/null_test.rb +1 -2
  113. data/test/adapter/polymorphic_test.rb +52 -5
  114. data/test/adapter_test.rb +1 -1
  115. data/test/benchmark/app.rb +1 -1
  116. data/test/benchmark/benchmarking_support.rb +1 -1
  117. data/test/benchmark/bm_active_record.rb +81 -0
  118. data/test/benchmark/bm_adapter.rb +38 -0
  119. data/test/benchmark/bm_caching.rb +16 -16
  120. data/test/benchmark/bm_lookup_chain.rb +83 -0
  121. data/test/benchmark/bm_transform.rb +21 -10
  122. data/test/benchmark/controllers.rb +16 -17
  123. data/test/benchmark/fixtures.rb +72 -72
  124. data/test/cache_test.rb +235 -69
  125. data/test/collection_serializer_test.rb +31 -14
  126. data/test/fixtures/active_record.rb +45 -10
  127. data/test/fixtures/poro.rb +124 -181
  128. data/test/generators/serializer_generator_test.rb +23 -5
  129. data/test/grape_test.rb +170 -56
  130. data/test/lint_test.rb +1 -1
  131. data/test/logger_test.rb +13 -11
  132. data/test/serializable_resource_test.rb +18 -22
  133. data/test/serializers/association_macros_test.rb +3 -2
  134. data/test/serializers/associations_test.rb +222 -49
  135. data/test/serializers/attribute_test.rb +5 -3
  136. data/test/serializers/attributes_test.rb +1 -1
  137. data/test/serializers/caching_configuration_test_isolated.rb +6 -6
  138. data/test/serializers/fieldset_test.rb +1 -1
  139. data/test/serializers/meta_test.rb +12 -6
  140. data/test/serializers/options_test.rb +17 -6
  141. data/test/serializers/read_attribute_for_serialization_test.rb +3 -3
  142. data/test/serializers/reflection_test.rb +427 -0
  143. data/test/serializers/root_test.rb +1 -1
  144. data/test/serializers/serialization_test.rb +2 -2
  145. data/test/serializers/serializer_for_test.rb +12 -10
  146. data/test/serializers/serializer_for_with_namespace_test.rb +88 -0
  147. data/test/support/isolated_unit.rb +9 -4
  148. data/test/support/rails5_shims.rb +8 -2
  149. data/test/support/rails_app.rb +2 -9
  150. data/test/support/serialization_testing.rb +31 -5
  151. data/test/test_helper.rb +13 -0
  152. metadata +130 -71
  153. data/.rubocop_todo.yml +0 -167
  154. data/docs/ARCHITECTURE.md +0 -126
  155. data/lib/active_model/serializer/associations.rb +0 -100
  156. data/lib/active_model/serializer/attributes.rb +0 -82
  157. data/lib/active_model/serializer/collection_reflection.rb +0 -7
  158. data/lib/active_model/serializer/configuration.rb +0 -35
  159. data/lib/active_model/serializer/include_tree.rb +0 -111
  160. data/lib/active_model/serializer/links.rb +0 -35
  161. data/lib/active_model/serializer/meta.rb +0 -29
  162. data/lib/active_model/serializer/singular_reflection.rb +0 -7
  163. data/lib/active_model/serializer/type.rb +0 -25
  164. data/lib/active_model_serializers/key_transform.rb +0 -70
  165. data/test/active_model_serializers/key_transform_test.rb +0 -263
  166. data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
  167. data/test/adapter/json_api/relationships_test.rb +0 -199
  168. data/test/adapter/json_api/resource_identifier_test.rb +0 -85
  169. data/test/include_tree/from_include_args_test.rb +0 -26
  170. data/test/include_tree/from_string_test.rb +0 -94
  171. data/test/include_tree/include_args_to_hash_test.rb +0 -64
@@ -0,0 +1,161 @@
1
+ require 'support/isolated_unit'
2
+ require 'minitest/mock'
3
+ require 'action_dispatch'
4
+ require 'action_controller'
5
+
6
+ class JsonApiRendererTest < ActionDispatch::IntegrationTest
7
+ include ActiveSupport::Testing::Isolation
8
+
9
+ class TestController < ActionController::Base
10
+ class << self
11
+ attr_accessor :last_request_parameters
12
+ end
13
+
14
+ def render_with_jsonapi_renderer
15
+ permitted_params = params.permit(data: [:id, :type, attributes: [:name]])
16
+ permitted_params = permitted_params.to_h.with_indifferent_access
17
+ attributes =
18
+ if permitted_params[:data]
19
+ permitted_params[:data][:attributes].merge(id: permitted_params[:data][:id])
20
+ else
21
+ # Rails returns empty params when no mime type can be negotiated.
22
+ # (Until https://github.com/rails/rails/pull/26632 is reviewed.)
23
+ permitted_params
24
+ end
25
+ author = Author.new(attributes)
26
+ render jsonapi: author
27
+ end
28
+
29
+ def parse
30
+ self.class.last_request_parameters = request.request_parameters
31
+ head :ok
32
+ end
33
+ end
34
+
35
+ def teardown
36
+ TestController.last_request_parameters = nil
37
+ end
38
+
39
+ def assert_parses(expected, actual, headers = {})
40
+ post '/parse', params: actual, headers: headers
41
+ assert_response :ok
42
+ assert_equal(expected, TestController.last_request_parameters)
43
+ end
44
+
45
+ def define_author_model_and_serializer
46
+ TestController.const_set(:Author, Class.new(ActiveModelSerializers::Model) do
47
+ attributes :id, :name
48
+ end)
49
+ TestController.const_set(:AuthorSerializer, Class.new(ActiveModel::Serializer) do
50
+ type 'users'
51
+ attribute :id
52
+ attribute :name
53
+ end)
54
+ end
55
+
56
+ class WithoutRenderer < JsonApiRendererTest
57
+ setup do
58
+ require 'rails'
59
+ require 'active_record'
60
+ require 'support/rails5_shims'
61
+ require 'active_model_serializers'
62
+ require 'fixtures/poro'
63
+
64
+ make_basic_app
65
+
66
+ Rails.application.routes.draw do
67
+ ActiveSupport::Deprecation.silence do
68
+ match ':action', to: TestController, via: [:get, :post]
69
+ end
70
+ end
71
+ define_author_model_and_serializer
72
+ end
73
+
74
+ def test_jsonapi_parser_not_registered
75
+ parsers = if Rails::VERSION::MAJOR >= 5
76
+ ActionDispatch::Request.parameter_parsers
77
+ else
78
+ ActionDispatch::ParamsParser::DEFAULT_PARSERS
79
+ end
80
+ assert_nil parsers[Mime[:jsonapi]]
81
+ end
82
+
83
+ def test_jsonapi_renderer_not_registered
84
+ payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
85
+ headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
86
+ post '/render_with_jsonapi_renderer', params: payload, headers: headers
87
+ assert_equal '', response.body
88
+ assert_equal 500, response.status
89
+ assert_equal ActionView::MissingTemplate, request.env['action_dispatch.exception'].class
90
+ end
91
+
92
+ def test_jsonapi_parser
93
+ assert_parses(
94
+ {},
95
+ '',
96
+ 'CONTENT_TYPE' => 'application/vnd.api+json'
97
+ )
98
+ end
99
+ end
100
+
101
+ class WithRenderer < JsonApiRendererTest
102
+ setup do
103
+ require 'rails'
104
+ require 'active_record'
105
+ require 'support/rails5_shims'
106
+ require 'active_model_serializers'
107
+ require 'fixtures/poro'
108
+ require 'active_model_serializers/register_jsonapi_renderer'
109
+
110
+ make_basic_app
111
+
112
+ Rails.application.routes.draw do
113
+ ActiveSupport::Deprecation.silence do
114
+ match ':action', to: TestController, via: [:get, :post]
115
+ end
116
+ end
117
+ define_author_model_and_serializer
118
+ end
119
+
120
+ def test_jsonapi_parser_registered
121
+ if Rails::VERSION::MAJOR >= 5
122
+ parsers = ActionDispatch::Request.parameter_parsers
123
+ assert_equal Proc, parsers[:jsonapi].class
124
+ else
125
+ parsers = ActionDispatch::ParamsParser::DEFAULT_PARSERS
126
+ assert_equal Proc, parsers[Mime[:jsonapi]].class
127
+ end
128
+ end
129
+
130
+ def test_jsonapi_renderer_registered
131
+ expected = {
132
+ 'data' => {
133
+ 'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765',
134
+ 'type' => 'users',
135
+ 'attributes' => { 'name' => 'Johnny Rico' }
136
+ }
137
+ }
138
+
139
+ payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
140
+ headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
141
+ post '/render_with_jsonapi_renderer', params: payload, headers: headers
142
+ assert_equal expected.to_json, response.body
143
+ end
144
+
145
+ def test_jsonapi_parser
146
+ assert_parses(
147
+ {
148
+ 'data' => {
149
+ 'attributes' => {
150
+ 'name' => 'John Doe'
151
+ },
152
+ 'type' => 'users',
153
+ 'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765'
154
+ }
155
+ },
156
+ '{"data": {"attributes": {"name": "John Doe"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}',
157
+ 'CONTENT_TYPE' => 'application/vnd.api+json'
158
+ )
159
+ end
160
+ end
161
+ end
@@ -5,13 +5,19 @@ require 'minitest/mock'
5
5
  class SerializationContextTest < ActiveSupport::TestCase
6
6
  include ActiveSupport::Testing::Isolation
7
7
 
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
8
  class WithRails < SerializationContextTest
9
+ def create_request
10
+ request = ActionDispatch::Request.new({})
11
+ def request.original_url
12
+ 'http://example.com/articles?page=2'
13
+ end
14
+
15
+ def request.query_parameters
16
+ { 'page' => 2 }
17
+ end
18
+ request
19
+ end
20
+
15
21
  setup do
16
22
  require 'rails'
17
23
  require 'active_model_serializers'
@@ -20,8 +26,8 @@ class SerializationContextTest < ActiveSupport::TestCase
20
26
  end
21
27
 
22
28
  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'
29
+ assert_equal @context.request_url, 'http://example.com/articles'
30
+ assert_equal @context.query_parameters, 'page' => 2
25
31
  end
26
32
 
27
33
  test 'url_helpers is set up for Rails url_helpers' do
@@ -36,14 +42,21 @@ class SerializationContextTest < ActiveSupport::TestCase
36
42
  end
37
43
 
38
44
  class WithoutRails < SerializationContextTest
45
+ def create_request
46
+ {
47
+ request_url: 'http://example.com/articles',
48
+ query_parameters: { 'page' => 2 }
49
+ }
50
+ end
51
+
39
52
  setup do
40
53
  require 'active_model_serializers/serialization_context'
41
54
  @context = ActiveModelSerializers::SerializationContext.new(create_request)
42
55
  end
43
56
 
44
57
  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'
58
+ assert_equal @context.request_url, 'http://example.com/articles'
59
+ assert_equal @context.query_parameters, 'page' => 2
47
60
  end
48
61
 
49
62
  test 'url_helpers is a module when Rails is not present' do
@@ -115,7 +115,8 @@ module ActiveModelSerializers
115
115
  end
116
116
 
117
117
  def test_that_raises_with_a_invalid_json_body
118
- message = 'A JSON text must at least contain two octets!'
118
+ # message changes from JSON gem 2.0.2 to 2.2.0
119
+ message = /A JSON text must at least contain two octets!|unexpected token at ''/
119
120
 
120
121
  get :invalid_json_body
121
122
 
@@ -123,7 +124,7 @@ module ActiveModelSerializers
123
124
  assert_response_schema('custom/show.json')
124
125
  end
125
126
 
126
- assert_equal(message, error.message)
127
+ assert_match(message, error.message)
127
128
  end
128
129
  end
129
130
  end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModelSerializers
4
+ module Adapter
5
+ class AttributesTest < ActiveSupport::TestCase
6
+ class Person < ActiveModelSerializers::Model
7
+ attributes :first_name, :last_name
8
+ end
9
+
10
+ class PersonSerializer < ActiveModel::Serializer
11
+ attributes :first_name, :last_name
12
+ end
13
+
14
+ def setup
15
+ ActionController::Base.cache_store.clear
16
+ end
17
+
18
+ def test_serializable_hash
19
+ person = Person.new(first_name: 'Arthur', last_name: 'Dent')
20
+ serializer = PersonSerializer.new(person)
21
+ adapter = ActiveModelSerializers::Adapter::Attributes.new(serializer)
22
+
23
+ assert_equal({ first_name: 'Arthur', last_name: 'Dent' },
24
+ adapter.serializable_hash)
25
+ end
26
+
27
+ def test_serializable_hash_with_transform_key_casing
28
+ person = Person.new(first_name: 'Arthur', last_name: 'Dent')
29
+ serializer = PersonSerializer.new(person)
30
+ adapter = ActiveModelSerializers::Adapter::Attributes.new(
31
+ serializer,
32
+ key_transform: :camel_lower
33
+ )
34
+
35
+ assert_equal({ firstName: 'Arthur', lastName: 'Dent' },
36
+ adapter.serializable_hash)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -84,6 +84,20 @@ module ActiveModelSerializers
84
84
 
85
85
  assert_equal(expected, actual)
86
86
  end
87
+
88
+ def test_fields_with_no_associations_include_option
89
+ actual = ActiveModelSerializers::SerializableResource.new(
90
+ [@first_post, @second_post], adapter: :json, fields: [:id], include: []
91
+ ).as_json
92
+
93
+ expected = { posts: [{
94
+ id: 1
95
+ }, {
96
+ id: 2
97
+ }] }
98
+
99
+ assert_equal(expected, actual)
100
+ end
87
101
  end
88
102
  end
89
103
  end
@@ -4,6 +4,10 @@ module ActiveModelSerializers
4
4
  module Adapter
5
5
  class Json
6
6
  class HasManyTestTest < ActiveSupport::TestCase
7
+ class ModelWithoutSerializer < ::Model
8
+ attributes :id, :name
9
+ end
10
+
7
11
  def setup
8
12
  ActionController::Base.cache_store.clear
9
13
  @author = Author.new(id: 1, name: 'Steve K.')
@@ -16,7 +20,7 @@ module ActiveModelSerializers
16
20
  @second_comment.post = @post
17
21
  @blog = Blog.new(id: 1, name: 'My Blog!!')
18
22
  @post.blog = @blog
19
- @tag = Tag.new(id: 1, name: '#hash_tag')
23
+ @tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
20
24
  @post.tags = [@tag]
21
25
  end
22
26
 
@@ -30,7 +34,11 @@ module ActiveModelSerializers
30
34
  end
31
35
 
32
36
  def test_has_many_with_no_serializer
33
- serializer = PostWithTagsSerializer.new(@post)
37
+ post_serializer_class = Class.new(ActiveModel::Serializer) do
38
+ attributes :id
39
+ has_many :tags
40
+ end
41
+ serializer = post_serializer_class.new(@post)
34
42
  adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
35
43
  assert_equal({
36
44
  id: 42,
@@ -15,7 +15,7 @@ module ActiveModelSerializers
15
15
  @adapter = ActiveModelSerializers::Adapter::Json.new(serializer, options)
16
16
  end
17
17
 
18
- Post = Class.new(::Model)
18
+ class Post < ::Model; end
19
19
  class PostSerializer < ActiveModel::Serializer
20
20
  attributes :id, :title, :body, :publish_at
21
21
  end
@@ -28,8 +28,8 @@ module ActiveModelSerializers
28
28
  def test_transform_default
29
29
  mock_request
30
30
  assert_equal({
31
- blog: { id: 1, special_attribute: 'neat', articles: nil }
32
- }, @adapter.serializable_hash)
31
+ blog: { id: 1, special_attribute: 'neat', articles: nil }
32
+ }, @adapter.serializable_hash)
33
33
  end
34
34
 
35
35
  def test_transform_global_config
@@ -38,8 +38,8 @@ module ActiveModelSerializers
38
38
  @adapter.serializable_hash
39
39
  end
40
40
  assert_equal({
41
- blog: { id: 1, specialAttribute: 'neat', articles: nil }
42
- }, result)
41
+ blog: { id: 1, specialAttribute: 'neat', articles: nil }
42
+ }, result)
43
43
  end
44
44
 
45
45
  def test_transform_serialization_ctx_overrides_global_config
@@ -48,8 +48,8 @@ module ActiveModelSerializers
48
48
  @adapter.serializable_hash
49
49
  end
50
50
  assert_equal({
51
- Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
52
- }, result)
51
+ Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
52
+ }, result)
53
53
  end
54
54
 
55
55
  def test_transform_undefined
@@ -63,29 +63,29 @@ module ActiveModelSerializers
63
63
  def test_transform_dash
64
64
  mock_request(:dash)
65
65
  assert_equal({
66
- blog: { id: 1, :"special-attribute" => 'neat', articles: nil }
67
- }, @adapter.serializable_hash)
66
+ blog: { id: 1, :"special-attribute" => 'neat', articles: nil }
67
+ }, @adapter.serializable_hash)
68
68
  end
69
69
 
70
70
  def test_transform_unaltered
71
71
  mock_request(:unaltered)
72
72
  assert_equal({
73
- blog: { id: 1, special_attribute: 'neat', articles: nil }
74
- }, @adapter.serializable_hash)
73
+ blog: { id: 1, special_attribute: 'neat', articles: nil }
74
+ }, @adapter.serializable_hash)
75
75
  end
76
76
 
77
77
  def test_transform_camel
78
78
  mock_request(:camel)
79
79
  assert_equal({
80
- Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
81
- }, @adapter.serializable_hash)
80
+ Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
81
+ }, @adapter.serializable_hash)
82
82
  end
83
83
 
84
84
  def test_transform_camel_lower
85
85
  mock_request(:camel_lower)
86
86
  assert_equal({
87
- blog: { id: 1, specialAttribute: 'neat', articles: nil }
88
- }, @adapter.serializable_hash)
87
+ blog: { id: 1, specialAttribute: 'neat', articles: nil }
88
+ }, @adapter.serializable_hash)
89
89
  end
90
90
  end
91
91
  end
@@ -58,9 +58,10 @@ module ActiveModelSerializers
58
58
 
59
59
  def test_limiting_fields
60
60
  actual = ActiveModelSerializers::SerializableResource.new(
61
- [@first_post, @second_post], adapter: :json_api,
62
- fields: { posts: %w(title comments blog author) })
63
- .serializable_hash
61
+ [@first_post, @second_post],
62
+ adapter: :json_api,
63
+ fields: { posts: %w(title comments blog author) }
64
+ ).serializable_hash
64
65
  expected = [
65
66
  {
66
67
  id: '1',
@@ -12,8 +12,8 @@ module ActiveModelSerializers
12
12
 
13
13
  def test_active_model_with_error
14
14
  options = {
15
- serializer: ActiveModel::Serializer::ErrorSerializer,
16
- adapter: :json_api
15
+ serializer: ActiveModel::Serializer::ErrorSerializer,
16
+ adapter: :json_api
17
17
  }
18
18
 
19
19
  @resource.errors.add(:name, 'cannot be nil')
@@ -22,22 +22,21 @@ module ActiveModelSerializers
22
22
  assert_equal serializable_resource.serializer_instance.attributes, {}
23
23
  assert_equal serializable_resource.serializer_instance.object, @resource
24
24
 
25
- expected_errors_object =
26
- { :errors =>
27
- [
28
- {
29
- source: { pointer: '/data/attributes/name' },
30
- detail: 'cannot be nil'
31
- }
32
- ]
25
+ expected_errors_object = {
26
+ errors: [
27
+ {
28
+ source: { pointer: '/data/attributes/name' },
29
+ detail: 'cannot be nil'
30
+ }
31
+ ]
33
32
  }
34
33
  assert_equal serializable_resource.as_json, expected_errors_object
35
34
  end
36
35
 
37
36
  def test_active_model_with_multiple_errors
38
37
  options = {
39
- serializer: ActiveModel::Serializer::ErrorSerializer,
40
- adapter: :json_api
38
+ serializer: ActiveModel::Serializer::ErrorSerializer,
39
+ adapter: :json_api
41
40
  }
42
41
 
43
42
  @resource.errors.add(:name, 'cannot be nil')
@@ -48,13 +47,12 @@ module ActiveModelSerializers
48
47
  assert_equal serializable_resource.serializer_instance.attributes, {}
49
48
  assert_equal serializable_resource.serializer_instance.object, @resource
50
49
 
51
- expected_errors_object =
52
- { :errors =>
53
- [
54
- { :source => { :pointer => '/data/attributes/name' }, :detail => 'cannot be nil' },
55
- { :source => { :pointer => '/data/attributes/name' }, :detail => 'must be longer' },
56
- { :source => { :pointer => '/data/attributes/id' }, :detail => 'must be a uuid' }
57
- ]
50
+ expected_errors_object = {
51
+ errors: [
52
+ { source: { pointer: '/data/attributes/name' }, detail: 'cannot be nil' },
53
+ { source: { pointer: '/data/attributes/name' }, detail: 'must be longer' },
54
+ { source: { pointer: '/data/attributes/id' }, detail: 'must be a uuid' }
55
+ ]
58
56
  }
59
57
  assert_equal serializable_resource.as_json, expected_errors_object
60
58
  end
@@ -4,7 +4,18 @@ module ActiveModelSerializers
4
4
  module Adapter
5
5
  class JsonApi
6
6
  class FieldsTest < ActiveSupport::TestCase
7
- Post = Class.new(::Model)
7
+ class Post < ::Model
8
+ attributes :title, :body
9
+ associations :author, :comments
10
+ end
11
+ class Author < ::Model
12
+ attributes :name, :birthday
13
+ end
14
+ class Comment < ::Model
15
+ attributes :body
16
+ associations :author, :post
17
+ end
18
+
8
19
  class PostSerializer < ActiveModel::Serializer
9
20
  type 'posts'
10
21
  attributes :title, :body
@@ -12,13 +23,11 @@ module ActiveModelSerializers
12
23
  has_many :comments
13
24
  end
14
25
 
15
- Author = Class.new(::Model)
16
26
  class AuthorSerializer < ActiveModel::Serializer
17
27
  type 'authors'
18
28
  attributes :name, :birthday
19
29
  end
20
30
 
21
- Comment = Class.new(::Model)
22
31
  class CommentSerializer < ActiveModel::Serializer
23
32
  type 'comments'
24
33
  attributes :body
@@ -4,6 +4,10 @@ module ActiveModelSerializers
4
4
  module Adapter
5
5
  class JsonApi
6
6
  class HasManyTest < ActiveSupport::TestCase
7
+ class ModelWithoutSerializer < ::Model
8
+ attributes :id, :name
9
+ end
10
+
7
11
  def setup
8
12
  ActionController::Base.cache_store.clear
9
13
  @author = Author.new(id: 1, name: 'Steve K.')
@@ -26,7 +30,7 @@ module ActiveModelSerializers
26
30
  @blog.articles = [@post]
27
31
  @post.blog = @blog
28
32
  @post_without_comments.blog = nil
29
- @tag = Tag.new(id: 1, name: '#hash_tag')
33
+ @tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
30
34
  @post.tags = [@tag]
31
35
  @serializer = PostSerializer.new(@post)
32
36
  @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
@@ -40,6 +44,27 @@ module ActiveModelSerializers
40
44
  assert_equal(expected, @adapter.serializable_hash[:data][:relationships][:comments])
41
45
  end
42
46
 
47
+ test 'relationships can be whitelisted via fields' do
48
+ @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, fields: { posts: [:author] })
49
+ result = @adapter.serializable_hash
50
+ expected = {
51
+ data: {
52
+ id: '1',
53
+ type: 'posts',
54
+ relationships: {
55
+ author: {
56
+ data: {
57
+ id: '1',
58
+ type: 'authors'
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+
65
+ assert_equal expected, result
66
+ end
67
+
43
68
  def test_includes_linked_comments
44
69
  @adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer, include: [:comments])
45
70
  expected = [{
@@ -108,18 +133,22 @@ module ActiveModelSerializers
108
133
  end
109
134
 
110
135
  def test_has_many_with_no_serializer
111
- serializer = PostWithTagsSerializer.new(@post)
136
+ post_serializer_class = Class.new(ActiveModel::Serializer) do
137
+ attributes :id
138
+ has_many :tags
139
+ end
140
+ serializer = post_serializer_class.new(@post)
112
141
  adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
113
142
 
114
143
  assert_equal({
115
- data: {
116
- id: '1',
117
- type: 'posts',
118
- relationships: {
119
- tags: { data: [@tag.as_json] }
120
- }
121
- }
122
- }, adapter.serializable_hash)
144
+ data: {
145
+ id: '1',
146
+ type: 'posts',
147
+ relationships: {
148
+ tags: { data: [@tag.as_json] }
149
+ }
150
+ }
151
+ }, adapter.serializable_hash)
123
152
  end
124
153
 
125
154
  def test_has_many_with_virtual_value
@@ -127,16 +156,16 @@ module ActiveModelSerializers
127
156
  adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
128
157
 
129
158
  assert_equal({
130
- data: {
131
- id: '1',
132
- type: 'virtual-values',
133
- relationships: {
134
- maker: { data: { type: 'makers', id: '1' } },
135
- reviews: { data: [{ type: 'reviews', id: '1' },
136
- { type: 'reviews', id: '2' }] }
137
- }
138
- }
139
- }, adapter.serializable_hash)
159
+ data: {
160
+ id: '1',
161
+ type: 'virtual-values',
162
+ relationships: {
163
+ maker: { data: { type: 'makers', id: '1' } },
164
+ reviews: { data: [{ type: 'reviews', id: '1' },
165
+ { type: 'reviews', id: '2' }] }
166
+ }
167
+ }
168
+ }, adapter.serializable_hash)
140
169
  end
141
170
  end
142
171
  end