active_model_serializers 0.10.0 → 0.10.1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -2
  3. data/Gemfile +1 -1
  4. data/README.md +21 -24
  5. data/active_model_serializers.gemspec +4 -8
  6. data/docs/general/adapters.md +4 -2
  7. data/docs/general/configuration_options.md +6 -1
  8. data/docs/general/deserialization.md +1 -1
  9. data/docs/general/serializers.md +30 -3
  10. data/docs/jsonapi/schema.md +1 -1
  11. data/lib/active_model/serializer.rb +54 -11
  12. data/lib/active_model/serializer/adapter/base.rb +2 -0
  13. data/lib/active_model/serializer/associations.rb +4 -5
  14. data/lib/active_model/serializer/belongs_to_reflection.rb +0 -3
  15. data/lib/active_model/serializer/caching.rb +62 -110
  16. data/lib/active_model/serializer/collection_serializer.rb +30 -10
  17. data/lib/active_model/serializer/configuration.rb +1 -0
  18. data/lib/active_model/serializer/has_many_reflection.rb +0 -3
  19. data/lib/active_model/serializer/has_one_reflection.rb +0 -3
  20. data/lib/active_model/serializer/reflection.rb +3 -3
  21. data/lib/active_model/serializer/version.rb +1 -1
  22. data/lib/active_model_serializers.rb +6 -0
  23. data/lib/active_model_serializers/adapter.rb +6 -0
  24. data/lib/active_model_serializers/adapter/attributes.rb +2 -67
  25. data/lib/active_model_serializers/adapter/base.rb +38 -38
  26. data/lib/active_model_serializers/adapter/json_api.rb +36 -28
  27. data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
  28. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +8 -1
  29. data/lib/active_model_serializers/deprecate.rb +1 -2
  30. data/lib/active_model_serializers/deserialization.rb +2 -0
  31. data/lib/active_model_serializers/model.rb +2 -0
  32. data/lib/active_model_serializers/railtie.rb +2 -0
  33. data/lib/active_model_serializers/register_jsonapi_renderer.rb +34 -23
  34. data/lib/active_model_serializers/serialization_context.rb +10 -3
  35. data/lib/grape/formatters/active_model_serializers.rb +19 -2
  36. data/lib/grape/helpers/active_model_serializers.rb +1 -0
  37. data/test/action_controller/adapter_selector_test.rb +1 -1
  38. data/test/action_controller/explicit_serializer_test.rb +5 -4
  39. data/test/action_controller/json/include_test.rb +106 -27
  40. data/test/action_controller/json_api/errors_test.rb +2 -2
  41. data/test/action_controller/json_api/linked_test.rb +26 -21
  42. data/test/action_controller/serialization_test.rb +9 -6
  43. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +143 -0
  44. data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
  45. data/test/adapter/json/collection_test.rb +14 -0
  46. data/test/adapter/json_api/collection_test.rb +4 -3
  47. data/test/adapter/json_api/errors_test.rb +13 -15
  48. data/test/adapter/json_api/linked_test.rb +8 -5
  49. data/test/adapter/json_api/links_test.rb +3 -1
  50. data/test/adapter/json_api/pagination_links_test.rb +13 -1
  51. data/test/adapter/json_api/relationships_test.rb +9 -4
  52. data/test/adapter/json_api/resource_identifier_test.rb +7 -2
  53. data/test/adapter/json_api/transform_test.rb +76 -75
  54. data/test/adapter/json_test.rb +4 -3
  55. data/test/benchmark/app.rb +1 -1
  56. data/test/benchmark/bm_caching.rb +14 -14
  57. data/test/benchmark/bm_transform.rb +16 -5
  58. data/test/benchmark/controllers.rb +16 -17
  59. data/test/benchmark/fixtures.rb +72 -72
  60. data/test/cache_test.rb +73 -45
  61. data/test/fixtures/poro.rb +6 -5
  62. data/test/grape_test.rb +96 -2
  63. data/test/serializable_resource_test.rb +12 -12
  64. data/test/serializers/meta_test.rb +12 -6
  65. data/test/support/isolated_unit.rb +1 -0
  66. data/test/support/rails5_shims.rb +8 -2
  67. data/test/support/rails_app.rb +0 -9
  68. metadata +53 -23
  69. data/lib/active_model/serializer/include_tree.rb +0 -111
  70. data/test/include_tree/from_include_args_test.rb +0 -26
  71. data/test/include_tree/from_string_test.rb +0 -94
  72. data/test/include_tree/include_args_to_hash_test.rb +0 -64
@@ -1,4 +1,5 @@
1
1
  # Helpers can be included in your Grape endpoint as: helpers Grape::Helpers::ActiveModelSerializers
2
+
2
3
  module Grape
3
4
  module Helpers
4
5
  module ActiveModelSerializers
@@ -32,7 +32,7 @@ module ActionController
32
32
 
33
33
  expected = {
34
34
  data: {
35
- id: assigns(:profile).id.to_s,
35
+ id: @controller.instance_variable_get(:@profile).id.to_s,
36
36
  type: 'profiles',
37
37
  attributes: {
38
38
  name: 'Name 1',
@@ -100,11 +100,12 @@ module ActionController
100
100
  get :render_array_using_explicit_serializer_and_custom_serializers
101
101
 
102
102
  expected = [
103
- { 'title' => 'New Post',
103
+ {
104
+ 'title' => 'New Post',
104
105
  'body' => 'Body',
105
- 'id' => assigns(:post).id,
106
+ 'id' => @controller.instance_variable_get(:@post).id,
106
107
  'comments' => [{ 'id' => 1 }, { 'id' => 2 }],
107
- 'author' => { 'id' => assigns(:author).id }
108
+ 'author' => { 'id' => @controller.instance_variable_get(:@author).id }
108
109
  }
109
110
  ]
110
111
 
@@ -122,7 +123,7 @@ module ActionController
122
123
  id: 42,
123
124
  lat: '-23.550520',
124
125
  lng: '-46.633309',
125
- place: 'Nowhere' # is a virtual attribute on LocationSerializer
126
+ address: 'Nowhere' # is a virtual attribute on LocationSerializer
126
127
  }
127
128
  ]
128
129
  }
@@ -4,6 +4,10 @@ module ActionController
4
4
  module Serialization
5
5
  class Json
6
6
  class IncludeTest < ActionController::TestCase
7
+ INCLUDE_STRING = 'posts.comments'.freeze
8
+ INCLUDE_HASH = { posts: :comments }.freeze
9
+ DEEP_INCLUDE = 'posts.comments.author'.freeze
10
+
7
11
  class IncludeTestController < ActionController::Base
8
12
  def setup_data
9
13
  ActionController::Base.cache_store.clear
@@ -38,17 +42,28 @@ module ActionController
38
42
 
39
43
  def render_resource_with_include_hash
40
44
  setup_data
41
- render json: @author, include: { posts: :comments }, adapter: :json
45
+ render json: @author, include: INCLUDE_HASH, adapter: :json
42
46
  end
43
47
 
44
48
  def render_resource_with_include_string
45
49
  setup_data
46
- render json: @author, include: 'posts.comments', adapter: :json
50
+ render json: @author, include: INCLUDE_STRING, adapter: :json
47
51
  end
48
52
 
49
53
  def render_resource_with_deep_include
50
54
  setup_data
51
- render json: @author, include: 'posts.comments.author', adapter: :json
55
+ render json: @author, include: DEEP_INCLUDE, adapter: :json
56
+ end
57
+
58
+ def render_without_recursive_relationships
59
+ # testing recursive includes ('**') can't have any cycles in the
60
+ # relationships, or we enter an infinite loop.
61
+ author = Author.new(id: 11, name: 'Jane Doe')
62
+ post = Post.new(id: 12, title: 'Hello World', body: 'My first post')
63
+ comment = Comment.new(id: 13, body: 'Commentary')
64
+ author.posts = [post]
65
+ post.comments = [comment]
66
+ render json: author
52
67
  end
53
68
  end
54
69
 
@@ -77,34 +92,90 @@ module ActionController
77
92
  def test_render_resource_with_include_hash
78
93
  get :render_resource_with_include_hash
79
94
  response = JSON.parse(@response.body)
80
- expected = {
81
- 'author' => {
82
- 'id' => 1,
83
- 'name' => 'Steve K.',
95
+
96
+ assert_equal(expected_include_response, response)
97
+ end
98
+
99
+ def test_render_resource_with_include_string
100
+ get :render_resource_with_include_string
101
+
102
+ response = JSON.parse(@response.body)
103
+
104
+ assert_equal(expected_include_response, response)
105
+ end
106
+
107
+ def test_render_resource_with_deep_include
108
+ get :render_resource_with_deep_include
109
+
110
+ response = JSON.parse(@response.body)
111
+
112
+ assert_equal(expected_deep_include_response, response)
113
+ end
114
+
115
+ def test_render_with_empty_default_includes
116
+ with_default_includes '' do
117
+ get :render_without_include
118
+ response = JSON.parse(@response.body)
119
+ expected = {
120
+ 'author' => {
121
+ 'id' => 1,
122
+ 'name' => 'Steve K.'
123
+ }
124
+ }
125
+ assert_equal(expected, response)
126
+ end
127
+ end
128
+
129
+ def test_render_with_recursive_default_includes
130
+ with_default_includes '**' do
131
+ get :render_without_recursive_relationships
132
+ response = JSON.parse(@response.body)
133
+
134
+ expected = {
135
+ 'id' => 11,
136
+ 'name' => 'Jane Doe',
137
+ 'roles' => nil,
138
+ 'bio' => nil,
84
139
  'posts' => [
85
140
  {
86
- 'id' => 42, 'title' => 'New Post', 'body' => 'Body',
141
+ 'id' => 12,
142
+ 'title' => 'Hello World',
143
+ 'body' => 'My first post',
87
144
  'comments' => [
88
145
  {
89
- 'id' => 1, 'body' => 'ZOMG A COMMENT'
90
- },
91
- {
92
- 'id' => 2, 'body' => 'ZOMG ANOTHER COMMENT'
146
+ 'id' => 13,
147
+ 'body' => 'Commentary',
148
+ 'post' => nil, # not set to avoid infinite recursion
149
+ 'author' => nil, # not set to avoid infinite recursion
93
150
  }
94
- ]
151
+ ],
152
+ 'blog' => {
153
+ 'id' => 999,
154
+ 'name' => 'Custom blog',
155
+ 'writer' => nil,
156
+ 'articles' => nil
157
+ },
158
+ 'author' => nil # not set to avoid infinite recursion
95
159
  }
96
160
  ]
97
161
  }
98
- }
162
+ assert_equal(expected, response)
163
+ end
164
+ end
99
165
 
100
- assert_equal(expected, response)
166
+ def test_render_with_includes_overrides_default_includes
167
+ with_default_includes '' do
168
+ get :render_resource_with_include_hash
169
+ response = JSON.parse(@response.body)
170
+
171
+ assert_equal(expected_include_response, response)
172
+ end
101
173
  end
102
174
 
103
- def test_render_resource_with_include_string
104
- get :render_resource_with_include_string
175
+ private
105
176
 
106
- response = JSON.parse(@response.body)
107
- expected = {
177
+ def expected_include_response
178
+ {
108
179
  'author' => {
109
180
  'id' => 1,
110
181
  'name' => 'Steve K.',
@@ -123,15 +194,10 @@ module ActionController
123
194
  ]
124
195
  }
125
196
  }
126
-
127
- assert_equal(expected, response)
128
197
  end
129
198
 
130
- def test_render_resource_with_deep_include
131
- get :render_resource_with_deep_include
132
-
133
- response = JSON.parse(@response.body)
134
- expected = {
199
+ def expected_deep_include_response
200
+ {
135
201
  'author' => {
136
202
  'id' => 1,
137
203
  'name' => 'Steve K.',
@@ -158,8 +224,21 @@ module ActionController
158
224
  ]
159
225
  }
160
226
  }
227
+ end
161
228
 
162
- assert_equal(expected, response)
229
+ def with_default_includes(include_directive)
230
+ original = ActiveModelSerializers.config.default_includes
231
+ ActiveModelSerializers.config.default_includes = include_directive
232
+ clear_include_directive_cache
233
+ yield
234
+ ensure
235
+ ActiveModelSerializers.config.default_includes = original
236
+ clear_include_directive_cache
237
+ end
238
+
239
+ def clear_include_directive_cache
240
+ ActiveModelSerializers
241
+ .instance_variable_set(:@default_include_directive, nil)
163
242
  end
164
243
  end
165
244
  end
@@ -7,8 +7,8 @@ module ActionController
7
7
  def test_active_model_with_multiple_errors
8
8
  get :render_resource_with_errors
9
9
 
10
- expected_errors_object =
11
- { :errors =>
10
+ expected_errors_object = {
11
+ :errors =>
12
12
  [
13
13
  { :source => { :pointer => '/data/attributes/name' }, :detail => 'cannot be nil' },
14
14
  { :source => { :pointer => '/data/attributes/name' }, :detail => 'must be longer' },
@@ -3,9 +3,8 @@ require 'test_helper'
3
3
  module ActionController
4
4
  module Serialization
5
5
  class JsonApi
6
- class LinkedTest < ActionController::TestCase
6
+ class LinkedTest < ActionDispatch::IntegrationTest
7
7
  class LinkedTestController < ActionController::Base
8
- require 'active_model_serializers/register_jsonapi_renderer'
9
8
  def setup_post
10
9
  ActionController::Base.cache_store.clear
11
10
  @role1 = Role.new(id: 1, name: 'admin')
@@ -39,62 +38,68 @@ module ActionController
39
38
 
40
39
  def render_resource_without_include
41
40
  setup_post
42
- render jsonapi: @post
41
+ render json: @post
43
42
  end
44
43
 
45
44
  def render_resource_with_include
46
45
  setup_post
47
- render jsonapi: @post, include: [:author]
46
+ render json: @post, adapter: :json_api, include: [:author]
48
47
  end
49
48
 
50
49
  def render_resource_with_include_of_custom_key_by_original
51
50
  setup_post
52
- render jsonapi: @post, include: [:reviews], serializer: PostWithCustomKeysSerializer
51
+ render json: @post, adapter: :json_api, include: [:reviews], serializer: PostWithCustomKeysSerializer
53
52
  end
54
53
 
55
54
  def render_resource_with_nested_include
56
55
  setup_post
57
- render jsonapi: @post, include: [comments: [:author]]
56
+ render json: @post, adapter: :json_api, include: [comments: [:author]]
58
57
  end
59
58
 
60
59
  def render_resource_with_nested_has_many_include_wildcard
61
60
  setup_post
62
- render jsonapi: @post, include: 'author.*'
61
+ render json: @post, adapter: :json_api, include: 'author.*'
63
62
  end
64
63
 
65
64
  def render_resource_with_missing_nested_has_many_include
66
65
  setup_post
67
66
  @post.author = @author2 # author2 has no roles.
68
- render jsonapi: @post, include: [author: [:roles]]
67
+ render json: @post, adapter: :json_api, include: [author: [:roles]]
69
68
  end
70
69
 
71
70
  def render_collection_with_missing_nested_has_many_include
72
71
  setup_post
73
72
  @post.author = @author2
74
- render jsonapi: [@post, @post2], include: [author: [:roles]]
73
+ render json: [@post, @post2], adapter: :json_api, include: [author: [:roles]]
75
74
  end
76
75
 
77
76
  def render_collection_without_include
78
77
  setup_post
79
- render jsonapi: [@post]
78
+ render json: [@post], adapter: :json_api
80
79
  end
81
80
 
82
81
  def render_collection_with_include
83
82
  setup_post
84
- render jsonapi: [@post], include: 'author, comments'
83
+ render json: [@post], adapter: :json_api, include: 'author, comments'
85
84
  end
86
85
  end
87
86
 
88
- tests LinkedTestController
87
+ setup do
88
+ @routes = Rails.application.routes.draw do
89
+ ActiveSupport::Deprecation.silence do
90
+ match ':action', :to => LinkedTestController, via: [:get, :post]
91
+ end
92
+ end
93
+ end
89
94
 
90
95
  def test_render_resource_without_include
91
- get :render_resource_without_include
96
+ get '/render_resource_without_include'
92
97
  response = JSON.parse(@response.body)
93
98
  refute response.key? 'included'
94
99
  end
95
100
 
96
101
  def test_render_resource_with_include
97
- get :render_resource_with_include
102
+ get '/render_resource_with_include'
98
103
  response = JSON.parse(@response.body)
99
104
  assert response.key? 'included'
100
105
  assert_equal 1, response['included'].size
@@ -102,7 +107,7 @@ module ActionController
102
107
  end
103
108
 
104
109
  def test_render_resource_with_nested_has_many_include
105
- get :render_resource_with_nested_has_many_include_wildcard
110
+ get '/render_resource_with_nested_has_many_include_wildcard'
106
111
  response = JSON.parse(@response.body)
107
112
  expected_linked = [
108
113
  {
@@ -144,7 +149,7 @@ module ActionController
144
149
  end
145
150
 
146
151
  def test_render_resource_with_include_of_custom_key_by_original
147
- get :render_resource_with_include_of_custom_key_by_original
152
+ get '/render_resource_with_include_of_custom_key_by_original'
148
153
  response = JSON.parse(@response.body)
149
154
  assert response.key? 'included'
150
155
 
@@ -156,33 +161,33 @@ module ActionController
156
161
  end
157
162
 
158
163
  def test_render_resource_with_nested_include
159
- get :render_resource_with_nested_include
164
+ get '/render_resource_with_nested_include'
160
165
  response = JSON.parse(@response.body)
161
166
  assert response.key? 'included'
162
167
  assert_equal 3, response['included'].size
163
168
  end
164
169
 
165
170
  def test_render_collection_without_include
166
- get :render_collection_without_include
171
+ get '/render_collection_without_include'
167
172
  response = JSON.parse(@response.body)
168
173
  refute response.key? 'included'
169
174
  end
170
175
 
171
176
  def test_render_collection_with_include
172
- get :render_collection_with_include
177
+ get '/render_collection_with_include'
173
178
  response = JSON.parse(@response.body)
174
179
  assert response.key? 'included'
175
180
  end
176
181
 
177
182
  def test_render_resource_with_nested_attributes_even_when_missing_associations
178
- get :render_resource_with_missing_nested_has_many_include
183
+ get '/render_resource_with_missing_nested_has_many_include'
179
184
  response = JSON.parse(@response.body)
180
185
  assert response.key? 'included'
181
186
  refute has_type?(response['included'], 'roles')
182
187
  end
183
188
 
184
189
  def test_render_collection_with_missing_nested_has_many_include
185
- get :render_collection_with_missing_nested_has_many_include
190
+ get '/render_collection_with_missing_nested_has_many_include'
186
191
  response = JSON.parse(@response.body)
187
192
  assert response.key? 'included'
188
193
  assert has_type?(response['included'], 'roles')
@@ -163,7 +163,7 @@ module ActionController
163
163
  end
164
164
  expected = {
165
165
  data: {
166
- id: assigns(:profile).id.to_s,
166
+ id: @controller.instance_variable_get(:@profile).id.to_s,
167
167
  type: 'profiles',
168
168
  attributes: {
169
169
  name: 'Name 1',
@@ -246,7 +246,7 @@ module ActionController
246
246
  expected = {
247
247
  data: [
248
248
  {
249
- id: assigns(:profiles).first.id.to_s,
249
+ id: @controller.instance_variable_get(:@profiles).first.id.to_s,
250
250
  type: 'profiles',
251
251
  attributes: {
252
252
  name: 'Name 1',
@@ -269,7 +269,7 @@ module ActionController
269
269
  expected = {
270
270
  data: [
271
271
  {
272
- id: assigns(:profiles).first.id.to_s,
272
+ id: @controller.instance_variable_get(:@profiles).first.id.to_s,
273
273
  type: 'profiles',
274
274
  attributes: {
275
275
  name: 'Name 1',
@@ -294,7 +294,8 @@ module ActionController
294
294
  comments: [
295
295
  {
296
296
  id: 1,
297
- body: 'ZOMG A COMMENT' }
297
+ body: 'ZOMG A COMMENT'
298
+ }
298
299
  ],
299
300
  blog: {
300
301
  id: 999,
@@ -333,7 +334,8 @@ module ActionController
333
334
  comments: [
334
335
  {
335
336
  id: 1,
336
- body: 'ZOMG A COMMENT' }
337
+ body: 'ZOMG A COMMENT'
338
+ }
337
339
  ],
338
340
  blog: {
339
341
  id: 999,
@@ -407,7 +409,8 @@ module ActionController
407
409
  comments: [
408
410
  {
409
411
  id: 1,
410
- body: 'ZOMG A COMMENT' }
412
+ body: 'ZOMG A COMMENT'
413
+ }
411
414
  ],
412
415
  blog: {
413
416
  id: 999,
@@ -0,0 +1,143 @@
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
+ author = Author.new(params[:data][:attributes])
16
+ render jsonapi: author
17
+ end
18
+
19
+ def parse
20
+ self.class.last_request_parameters = request.request_parameters
21
+ head :ok
22
+ end
23
+ end
24
+
25
+ def teardown
26
+ TestController.last_request_parameters = nil
27
+ end
28
+
29
+ def assert_parses(expected, actual, headers = {})
30
+ post '/parse', params: actual, headers: headers
31
+ assert_response :ok
32
+ assert_equal(expected, TestController.last_request_parameters)
33
+ end
34
+
35
+ class WithoutRenderer < JsonApiRendererTest
36
+ setup do
37
+ require 'rails'
38
+ require 'active_record'
39
+ require 'support/rails5_shims'
40
+ require 'active_model_serializers'
41
+ require 'fixtures/poro'
42
+
43
+ make_basic_app
44
+
45
+ Rails.application.routes.draw do
46
+ ActiveSupport::Deprecation.silence do
47
+ match ':action', :to => TestController, via: [:get, :post]
48
+ end
49
+ end
50
+ end
51
+
52
+ def test_jsonapi_parser_not_registered
53
+ parsers = if Rails::VERSION::MAJOR >= 5
54
+ ActionDispatch::Request.parameter_parsers
55
+ else
56
+ ActionDispatch::ParamsParser::DEFAULT_PARSERS
57
+ end
58
+ assert_nil parsers[Mime[:jsonapi]]
59
+ end
60
+
61
+ def test_jsonapi_renderer_not_registered
62
+ expected = {
63
+ 'data' => {
64
+ 'attributes' => {
65
+ 'name' => 'Johnny Rico'
66
+ },
67
+ 'type' => 'users'
68
+ }
69
+ }
70
+ payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "authors"}}'
71
+ headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
72
+ post '/render_with_jsonapi_renderer', params: payload, headers: headers
73
+ assert expected, response.body
74
+ end
75
+
76
+ def test_jsonapi_parser
77
+ assert_parses(
78
+ {},
79
+ '',
80
+ 'CONTENT_TYPE' => 'application/vnd.api+json'
81
+ )
82
+ end
83
+ end
84
+
85
+ class WithRenderer < JsonApiRendererTest
86
+ setup do
87
+ require 'rails'
88
+ require 'active_record'
89
+ require 'support/rails5_shims'
90
+ require 'active_model_serializers'
91
+ require 'fixtures/poro'
92
+ require 'active_model_serializers/register_jsonapi_renderer'
93
+
94
+ make_basic_app
95
+
96
+ Rails.application.routes.draw do
97
+ ActiveSupport::Deprecation.silence do
98
+ match ':action', :to => TestController, via: [:get, :post]
99
+ end
100
+ end
101
+ end
102
+
103
+ def test_jsonapi_parser_registered
104
+ if Rails::VERSION::MAJOR >= 5
105
+ parsers = ActionDispatch::Request.parameter_parsers
106
+ assert_equal Proc, parsers[:jsonapi].class
107
+ else
108
+ parsers = ActionDispatch::ParamsParser::DEFAULT_PARSERS
109
+ assert_equal Proc, parsers[Mime[:jsonapi]].class
110
+ end
111
+ end
112
+
113
+ def test_jsonapi_renderer_registered
114
+ expected = {
115
+ 'data' => {
116
+ 'attributes' => {
117
+ 'name' => 'Johnny Rico'
118
+ },
119
+ 'type' => 'users'
120
+ }
121
+ }
122
+ payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "authors"}}'
123
+ headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
124
+ post '/render_with_jsonapi_renderer', params: payload, headers: headers
125
+ assert expected, response.body
126
+ end
127
+
128
+ def test_jsonapi_parser
129
+ assert_parses(
130
+ {
131
+ 'data' => {
132
+ 'attributes' => {
133
+ 'name' => 'John Doe'
134
+ },
135
+ 'type' => 'users'
136
+ }
137
+ },
138
+ '{"data": {"attributes": {"name": "John Doe"}, "type": "users"}}',
139
+ 'CONTENT_TYPE' => 'application/vnd.api+json'
140
+ )
141
+ end
142
+ end
143
+ end