mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Provide key case translation
This commit is contained in:
parent
daabb89fe0
commit
c533d1a7fe
@ -3,6 +3,7 @@
|
|||||||
Breaking changes:
|
Breaking changes:
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
- [#1574](https://github.com/rails-api/active_model_serializers/pull/1574) Provide key translation. (@remear)
|
||||||
- [#1494](https://github.com/rails-api/active_model_serializers/pull/1494) Make serializers serializalbe
|
- [#1494](https://github.com/rails-api/active_model_serializers/pull/1494) Make serializers serializalbe
|
||||||
(using the Attributes adapter by default). (@bf4)
|
(using the Attributes adapter by default). (@bf4)
|
||||||
- [#1550](https://github.com/rails-api/active_model_serializers/pull/1550) Add
|
- [#1550](https://github.com/rails-api/active_model_serializers/pull/1550) Add
|
||||||
|
|||||||
@ -2,26 +2,95 @@
|
|||||||
|
|
||||||
# Configuration Options
|
# Configuration Options
|
||||||
|
|
||||||
The following configuration options can be set on `ActiveModelSerializers.config`,
|
The following configuration options can be set on
|
||||||
preferably inside an initializer.
|
`ActiveModelSerializers.config`, preferably inside an initializer.
|
||||||
|
|
||||||
## General
|
## General
|
||||||
|
|
||||||
- `adapter`: The [adapter](adapters.md) to use. Possible values: `:attributes, :json, :json_api`. Default: `:attributes`.
|
##### adapter
|
||||||
- `serializer_lookup_enabled`: When `false`, serializers must be explicitly specified. Default: `true`
|
|
||||||
|
The [adapter](adapters.md) to use.
|
||||||
|
|
||||||
|
Possible values:
|
||||||
|
|
||||||
|
- `:attributes` (default)
|
||||||
|
- `:json`
|
||||||
|
- `:json_api`
|
||||||
|
|
||||||
|
##### serializer_lookup_enabled
|
||||||
|
|
||||||
|
Enable automatic serializer lookup.
|
||||||
|
|
||||||
|
Possible values:
|
||||||
|
|
||||||
|
- `true` (default)
|
||||||
|
- `false`
|
||||||
|
|
||||||
|
When `false`, serializers must be explicitly specified.
|
||||||
|
|
||||||
|
##### key_transform
|
||||||
|
|
||||||
|
The [key transform](key_transform.md) to use.
|
||||||
|
|
||||||
|
Possible values:
|
||||||
|
|
||||||
|
- `:camel` - ExampleKey
|
||||||
|
- `:camel_lower` - exampleKey
|
||||||
|
- `:dashed` - example-key
|
||||||
|
- `:unaltered` - the original, unaltered key
|
||||||
|
- `nil` - use the adapter default
|
||||||
|
|
||||||
|
Each adapter has a default key transform configured:
|
||||||
|
|
||||||
|
- `Json` - `:unaltered`
|
||||||
|
- `JsonApi` - `:dashed`
|
||||||
|
|
||||||
|
`config.key_transform` is a global override of the adapter default. Adapters
|
||||||
|
still prefer the render option `:key_transform` over this setting.
|
||||||
|
|
||||||
|
|
||||||
## JSON API
|
## JSON API
|
||||||
|
|
||||||
- `jsonapi_resource_type`: Whether the `type` attributes of resources should be singular or plural. Possible values: `:singular, :plural`. Default: `:plural`.
|
|
||||||
- `jsonapi_include_toplevel_object`: Whether to include a [top level JSON API member](http://jsonapi.org/format/#document-jsonapi-object)
|
##### jsonapi_resource_type
|
||||||
in the response document.
|
|
||||||
Default: `false`.
|
Sets whether the [type](http://jsonapi.org/format/#document-resource-identifier-objects)
|
||||||
- Used when `jsonapi_include_toplevel_object` is `true`:
|
of the resource should be `singularized` or `pluralized` when it is not
|
||||||
- `jsonapi_version`: The latest version of the spec the API conforms to.
|
[explicitly specified by the serializer](https://github.com/rails-api/active_model_serializers/blob/master/docs/general/serializers.md#type)
|
||||||
Default: `'1.0'`.
|
|
||||||
- `jsonapi_toplevel_meta`: Optional metadata. Not included if empty.
|
Possible values:
|
||||||
Default: `{}`.
|
|
||||||
|
- `:singular`
|
||||||
|
- `:plural` (default)
|
||||||
|
|
||||||
|
##### jsonapi_include_toplevel_object
|
||||||
|
|
||||||
|
Include a [top level jsonapi member](http://jsonapi.org/format/#document-jsonapi-object)
|
||||||
|
in the response document.
|
||||||
|
|
||||||
|
Possible values:
|
||||||
|
|
||||||
|
- `true`
|
||||||
|
- `false` (default)
|
||||||
|
|
||||||
|
##### jsonapi_version
|
||||||
|
|
||||||
|
The latest version of the spec to which the API conforms.
|
||||||
|
|
||||||
|
Default: `'1.0'`.
|
||||||
|
|
||||||
|
*Used when `jsonapi_include_toplevel_object` is `true`*
|
||||||
|
|
||||||
|
##### jsonapi_toplevel_meta
|
||||||
|
|
||||||
|
Optional top-level metadata. Not included if empty.
|
||||||
|
|
||||||
|
Default: `{}`.
|
||||||
|
|
||||||
|
*Used when `jsonapi_include_toplevel_object` is `true`*
|
||||||
|
|
||||||
|
|
||||||
## Hooks
|
## Hooks
|
||||||
|
|
||||||
To run a hook when ActiveModelSerializers is loaded, use `ActiveSupport.on_load(:action_controller) do end`
|
To run a hook when ActiveModelSerializers is loaded, use
|
||||||
|
`ActiveSupport.on_load(:action_controller) do end`
|
||||||
|
|||||||
34
docs/general/key_transform.md
Normal file
34
docs/general/key_transform.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[Back to Guides](../README.md)
|
||||||
|
|
||||||
|
# Key Transforms
|
||||||
|
|
||||||
|
Key transforms modify the keys in serialized responses.
|
||||||
|
|
||||||
|
Provided key transforms:
|
||||||
|
|
||||||
|
- `:camel` - ExampleKey
|
||||||
|
- `:camel_lower` - exampleKey
|
||||||
|
- `:dashed` - example-key
|
||||||
|
- `:unaltered` - the original, unaltered key
|
||||||
|
- `nil` - use the adapter default
|
||||||
|
|
||||||
|
Key translation precedence is as follows:
|
||||||
|
|
||||||
|
##### SerializableResource option
|
||||||
|
|
||||||
|
`key_transform` is provided as an option via render.
|
||||||
|
|
||||||
|
```render json: posts, each_serializer: PostSerializer, key_transform: :camel_lower```
|
||||||
|
|
||||||
|
##### Configuration option
|
||||||
|
|
||||||
|
`key_transform` is set in `ActiveModelSerializers.config.key_transform`.
|
||||||
|
|
||||||
|
```ActiveModelSerializers.config.key_transform = :camel_lower```
|
||||||
|
|
||||||
|
##### Adapter default
|
||||||
|
|
||||||
|
Each adapter has a default key transform configured:
|
||||||
|
|
||||||
|
- `Json` - `:unaltered`
|
||||||
|
- `JsonApi` - `:dashed`
|
||||||
@ -79,6 +79,12 @@ PR please :)
|
|||||||
|
|
||||||
PR please :)
|
PR please :)
|
||||||
|
|
||||||
|
#### key_transform
|
||||||
|
|
||||||
|
```render json: posts, each_serializer: PostSerializer, key_transform: :camel_lower```
|
||||||
|
|
||||||
|
See [Key Transforms](key_transforms.md) for more informaiton.
|
||||||
|
|
||||||
#### meta
|
#### meta
|
||||||
|
|
||||||
A `meta` member can be used to include non-standard meta-information. `meta` can
|
A `meta` member can be used to include non-standard meta-information. `meta` can
|
||||||
|
|||||||
@ -56,7 +56,9 @@ module ActionController
|
|||||||
|
|
||||||
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method|
|
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method|
|
||||||
define_method renderer_method do |resource, options|
|
define_method renderer_method do |resource, options|
|
||||||
options.fetch(:serialization_context) { options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request) }
|
options.fetch(:serialization_context) do
|
||||||
|
options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, options)
|
||||||
|
end
|
||||||
serializable_resource = get_serializer(resource, options)
|
serializable_resource = get_serializer(resource, options)
|
||||||
super(serializable_resource, options)
|
super(serializable_resource, options)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -26,6 +26,7 @@ module ActiveModel
|
|||||||
# Make JSON API top-level jsonapi member opt-in
|
# Make JSON API top-level jsonapi member opt-in
|
||||||
# ref: http://jsonapi.org/format/#document-top-level
|
# ref: http://jsonapi.org/format/#document-top-level
|
||||||
config.jsonapi_include_toplevel_object = false
|
config.jsonapi_include_toplevel_object = false
|
||||||
|
config.key_transform = nil
|
||||||
|
|
||||||
config.schema_path = 'test/support/schemas'
|
config.schema_path = 'test/support/schemas'
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
require 'active_model_serializers/key_transform'
|
||||||
|
|
||||||
module ActiveModelSerializers
|
module ActiveModelSerializers
|
||||||
module Adapter
|
module Adapter
|
||||||
class Base
|
class Base
|
||||||
@ -51,6 +53,27 @@ module ActiveModelSerializers
|
|||||||
json[meta_key] = meta unless meta.blank?
|
json[meta_key] = meta unless meta.blank?
|
||||||
json
|
json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_key_transform
|
||||||
|
:unaltered
|
||||||
|
end
|
||||||
|
|
||||||
|
# Determines the transform to use in order of precedence:
|
||||||
|
# serialization context, global config, adapter default.
|
||||||
|
#
|
||||||
|
# @param serialization_context [Object] the SerializationContext
|
||||||
|
# @return [Symbol] the transform to use
|
||||||
|
def key_transform(serialization_context)
|
||||||
|
serialization_context.key_transform ||
|
||||||
|
ActiveModelSerializers.config.key_transform ||
|
||||||
|
default_key_transform
|
||||||
|
end
|
||||||
|
|
||||||
|
def transform_key_casing!(value, serialization_context)
|
||||||
|
return value unless serialization_context
|
||||||
|
transform = key_transform(serialization_context)
|
||||||
|
KeyTransform.send(transform, value)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,7 +3,8 @@ module ActiveModelSerializers
|
|||||||
class Json < Base
|
class Json < Base
|
||||||
def serializable_hash(options = nil)
|
def serializable_hash(options = nil)
|
||||||
options ||= {}
|
options ||= {}
|
||||||
{ root => Attributes.new(serializer, instance_options).serializable_hash(options) }
|
serialized_hash = { root => Attributes.new(serializer, instance_options).serializable_hash(options) }
|
||||||
|
transform_key_casing!(serialized_hash, options[:serialization_context])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -37,15 +37,20 @@ module ActiveModelSerializers
|
|||||||
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
|
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_key_transform
|
||||||
|
:dashed
|
||||||
|
end
|
||||||
|
|
||||||
# {http://jsonapi.org/format/#crud Requests are transactional, i.e. success or failure}
|
# {http://jsonapi.org/format/#crud Requests are transactional, i.e. success or failure}
|
||||||
# {http://jsonapi.org/format/#document-top-level data and errors MUST NOT coexist in the same document.}
|
# {http://jsonapi.org/format/#document-top-level data and errors MUST NOT coexist in the same document.}
|
||||||
def serializable_hash(options = nil)
|
def serializable_hash(options = nil)
|
||||||
options ||= {}
|
options ||= {}
|
||||||
if serializer.success?
|
document = if serializer.success?
|
||||||
success_document(options)
|
success_document(options)
|
||||||
else
|
else
|
||||||
failure_document
|
failure_document
|
||||||
end
|
end
|
||||||
|
transform_key_casing!(document, options[:serialization_context])
|
||||||
end
|
end
|
||||||
|
|
||||||
# {http://jsonapi.org/format/#document-top-level Primary data}
|
# {http://jsonapi.org/format/#document-top-level Primary data}
|
||||||
|
|||||||
40
lib/active_model_serializers/key_transform.rb
Normal file
40
lib/active_model_serializers/key_transform.rb
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
require 'active_support/core_ext/hash/keys'
|
||||||
|
|
||||||
|
module ActiveModelSerializers
|
||||||
|
module KeyTransform
|
||||||
|
module_function
|
||||||
|
|
||||||
|
# Transforms keys to UpperCamelCase or PascalCase.
|
||||||
|
#
|
||||||
|
# @example:
|
||||||
|
# "some_key" => "SomeKey",
|
||||||
|
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize}
|
||||||
|
def camel(hash)
|
||||||
|
hash.deep_transform_keys! { |key| key.to_s.camelize.to_sym }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Transforms keys to camelCase.
|
||||||
|
#
|
||||||
|
# @example:
|
||||||
|
# "some_key" => "someKey",
|
||||||
|
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize}
|
||||||
|
def camel_lower(hash)
|
||||||
|
hash.deep_transform_keys! { |key| key.to_s.camelize(:lower).to_sym }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Transforms keys to dashed-case.
|
||||||
|
# This is the default case for the JsonApi adapter.
|
||||||
|
#
|
||||||
|
# @example:
|
||||||
|
# "some_key" => "some-key",
|
||||||
|
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L185-L187 ActiveSupport::Inflector.dasherize}
|
||||||
|
def dashed(hash)
|
||||||
|
hash.deep_transform_keys! { |key| key.to_s.dasherize.to_sym }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the hash unaltered
|
||||||
|
def unaltered(hash)
|
||||||
|
hash
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -4,13 +4,14 @@ module ActiveModelSerializers
|
|||||||
attr_writer :url_helpers, :default_url_options
|
attr_writer :url_helpers, :default_url_options
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :request_url, :query_parameters
|
attr_reader :request_url, :query_parameters, :key_transform
|
||||||
|
|
||||||
def initialize(request, options = {})
|
def initialize(request, options = {})
|
||||||
@request_url = request.original_url[/\A[^?]+/]
|
@request_url = request.original_url[/\A[^?]+/]
|
||||||
@query_parameters = request.query_parameters
|
@query_parameters = request.query_parameters
|
||||||
@url_helpers = options.delete(:url_helpers) || self.class.url_helpers
|
@url_helpers = options.delete(:url_helpers) || self.class.url_helpers
|
||||||
@default_url_options = options.delete(:default_url_options) || self.class.default_url_options
|
@default_url_options = options.delete(:default_url_options) || self.class.default_url_options
|
||||||
|
@key_transform = options.delete(:key_transform)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.url_helpers
|
def self.url_helpers
|
||||||
|
|||||||
180
test/action_controller/json_api/key_transform_test.rb
Normal file
180
test/action_controller/json_api/key_transform_test.rb
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
module ActionController
|
||||||
|
module Serialization
|
||||||
|
class JsonApi
|
||||||
|
class KeyTransformTest < ActionController::TestCase
|
||||||
|
class KeyTransformTestController < ActionController::Base
|
||||||
|
Post = Class.new(::Model)
|
||||||
|
class PostSerializer < ActiveModel::Serializer
|
||||||
|
type 'posts'
|
||||||
|
attributes :title, :body, :publish_at
|
||||||
|
belongs_to :author
|
||||||
|
has_many :comments
|
||||||
|
|
||||||
|
link(:post_authors) { 'https://example.com/post_authors' }
|
||||||
|
|
||||||
|
meta do
|
||||||
|
{
|
||||||
|
rating: 5,
|
||||||
|
favorite_count: 10
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Author = Class.new(::Model)
|
||||||
|
class AuthorSerializer < ActiveModel::Serializer
|
||||||
|
type 'authors'
|
||||||
|
attributes :first_name, :last_name
|
||||||
|
end
|
||||||
|
|
||||||
|
Comment = Class.new(::Model)
|
||||||
|
class CommentSerializer < ActiveModel::Serializer
|
||||||
|
type 'comments'
|
||||||
|
attributes :body
|
||||||
|
belongs_to :author
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_post
|
||||||
|
ActionController::Base.cache_store.clear
|
||||||
|
@author = Author.new(id: 1, first_name: 'Bob', last_name: 'Jones')
|
||||||
|
@comment1 = Comment.new(id: 7, body: 'cool', author: @author)
|
||||||
|
@comment2 = Comment.new(id: 12, body: 'awesome', author: @author)
|
||||||
|
@post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1',
|
||||||
|
author: @author, comments: [@comment1, @comment2],
|
||||||
|
publish_at: '2020-03-16T03:55:25.291Z')
|
||||||
|
@comment1.post = @post
|
||||||
|
@comment2.post = @post
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_resource_with_key_transform
|
||||||
|
setup_post
|
||||||
|
render json: @post, serializer: PostSerializer, adapter: :json_api,
|
||||||
|
key_transform: :camel
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_resource_with_key_transform_nil
|
||||||
|
setup_post
|
||||||
|
render json: @post, serializer: PostSerializer, adapter: :json_api,
|
||||||
|
key_transform: nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_resource_with_key_transform_with_global_config
|
||||||
|
setup_post
|
||||||
|
old_transform = ActiveModelSerializers.config.key_transform
|
||||||
|
ActiveModelSerializers.config.key_transform = :camel_lower
|
||||||
|
render json: @post, serializer: PostSerializer, adapter: :json_api
|
||||||
|
ActiveModelSerializers.config.key_transform = old_transform
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tests KeyTransformTestController
|
||||||
|
|
||||||
|
def test_render_resource_with_key_transform
|
||||||
|
get :render_resource_with_key_transform
|
||||||
|
response = JSON.parse(@response.body)
|
||||||
|
expected = {
|
||||||
|
'Data' => {
|
||||||
|
'Id' => '1337',
|
||||||
|
'Type' => 'posts',
|
||||||
|
'Attributes' => {
|
||||||
|
'Title' => 'Title 1',
|
||||||
|
'Body' => 'Body 1',
|
||||||
|
'PublishAt' => '2020-03-16T03:55:25.291Z'
|
||||||
|
},
|
||||||
|
'Relationships' => {
|
||||||
|
'Author' => {
|
||||||
|
'Data' => {
|
||||||
|
'Id' => '1',
|
||||||
|
'Type' => 'authors'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Comments' => {
|
||||||
|
'Data' => [
|
||||||
|
{ 'Id' => '7', 'Type' => 'comments' },
|
||||||
|
{ 'Id' => '12', 'Type' => 'comments' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Links' => {
|
||||||
|
'PostAuthors' => 'https://example.com/post_authors'
|
||||||
|
},
|
||||||
|
'Meta' => { 'Rating' => 5, 'FavoriteCount' => 10 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_equal expected, response
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_render_resource_with_key_transform_nil
|
||||||
|
get :render_resource_with_key_transform_nil
|
||||||
|
response = JSON.parse(@response.body)
|
||||||
|
expected = {
|
||||||
|
'data' => {
|
||||||
|
'id' => '1337',
|
||||||
|
'type' => 'posts',
|
||||||
|
'attributes' => {
|
||||||
|
'title' => 'Title 1',
|
||||||
|
'body' => 'Body 1',
|
||||||
|
'publish-at' => '2020-03-16T03:55:25.291Z'
|
||||||
|
},
|
||||||
|
'relationships' => {
|
||||||
|
'author' => {
|
||||||
|
'data' => {
|
||||||
|
'id' => '1',
|
||||||
|
'type' => 'authors'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'comments' => {
|
||||||
|
'data' => [
|
||||||
|
{ 'id' => '7', 'type' => 'comments' },
|
||||||
|
{ 'id' => '12', 'type' => 'comments' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'links' => {
|
||||||
|
'post-authors' => 'https://example.com/post_authors'
|
||||||
|
},
|
||||||
|
'meta' => { 'rating' => 5, 'favorite-count' => 10 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_equal expected, response
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_render_resource_with_key_transform_with_global_config
|
||||||
|
get :render_resource_with_key_transform_with_global_config
|
||||||
|
response = JSON.parse(@response.body)
|
||||||
|
expected = {
|
||||||
|
'data' => {
|
||||||
|
'id' => '1337',
|
||||||
|
'type' => 'posts',
|
||||||
|
'attributes' => {
|
||||||
|
'title' => 'Title 1',
|
||||||
|
'body' => 'Body 1',
|
||||||
|
'publishAt' => '2020-03-16T03:55:25.291Z'
|
||||||
|
},
|
||||||
|
'relationships' => {
|
||||||
|
'author' => {
|
||||||
|
'data' => {
|
||||||
|
'id' => '1',
|
||||||
|
'type' => 'authors'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'comments' => {
|
||||||
|
'data' => [
|
||||||
|
{ 'id' => '7', 'type' => 'comments' },
|
||||||
|
{ 'id' => '12', 'type' => 'comments' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'links' => {
|
||||||
|
'postAuthors' => 'https://example.com/post_authors'
|
||||||
|
},
|
||||||
|
'meta' => { 'rating' => 5, 'favoriteCount' => 10 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_equal expected, response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
93
test/adapter/json/key_case_test.rb
Normal file
93
test/adapter/json/key_case_test.rb
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
module ActiveModelSerializers
|
||||||
|
module Adapter
|
||||||
|
class Json
|
||||||
|
class KeyCaseTest < ActiveSupport::TestCase
|
||||||
|
def mock_request(key_transform = nil)
|
||||||
|
context = Minitest::Mock.new
|
||||||
|
context.expect(:request_url, URI)
|
||||||
|
context.expect(:query_parameters, {})
|
||||||
|
context.expect(:key_transform, key_transform)
|
||||||
|
@options = {}
|
||||||
|
@options[:serialization_context] = context
|
||||||
|
end
|
||||||
|
|
||||||
|
Post = Class.new(::Model)
|
||||||
|
class PostSerializer < ActiveModel::Serializer
|
||||||
|
attributes :id, :title, :body, :publish_at
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup
|
||||||
|
ActionController::Base.cache_store.clear
|
||||||
|
@blog = Blog.new(id: 1, name: 'My Blog!!', special_attribute: 'neat')
|
||||||
|
serializer = CustomBlogSerializer.new(@blog)
|
||||||
|
@adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_key_transform_default
|
||||||
|
mock_request
|
||||||
|
assert_equal({
|
||||||
|
blog: { id: 1, special_attribute: 'neat', articles: nil }
|
||||||
|
}, @adapter.serializable_hash(@options))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_key_transform_global_config
|
||||||
|
mock_request
|
||||||
|
result = with_config(key_transform: :camel_lower) do
|
||||||
|
@adapter.serializable_hash(@options)
|
||||||
|
end
|
||||||
|
assert_equal({
|
||||||
|
blog: { id: 1, specialAttribute: 'neat', articles: nil }
|
||||||
|
}, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_key_transform_serialization_ctx_overrides_global_config
|
||||||
|
mock_request(:camel)
|
||||||
|
result = with_config(key_transform: :camel_lower) do
|
||||||
|
@adapter.serializable_hash(@options)
|
||||||
|
end
|
||||||
|
assert_equal({
|
||||||
|
Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
|
||||||
|
}, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_key_transform_undefined
|
||||||
|
mock_request(:blam)
|
||||||
|
result = nil
|
||||||
|
assert_raises NoMethodError do
|
||||||
|
result = @adapter.serializable_hash(@options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_key_transform_dashed
|
||||||
|
mock_request(:dashed)
|
||||||
|
assert_equal({
|
||||||
|
blog: { id: 1, :"special-attribute" => 'neat', articles: nil }
|
||||||
|
}, @adapter.serializable_hash(@options))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_key_transform_unaltered
|
||||||
|
mock_request(:unaltered)
|
||||||
|
assert_equal({
|
||||||
|
blog: { id: 1, special_attribute: 'neat', articles: nil }
|
||||||
|
}, @adapter.serializable_hash(@options))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_key_transform_camel
|
||||||
|
mock_request(:camel)
|
||||||
|
assert_equal({
|
||||||
|
Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
|
||||||
|
}, @adapter.serializable_hash(@options))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_key_transform_camel_lower
|
||||||
|
mock_request(:camel_lower)
|
||||||
|
assert_equal({
|
||||||
|
blog: { id: 1, specialAttribute: 'neat', articles: nil }
|
||||||
|
}, @adapter.serializable_hash(@options))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
500
test/adapter/json_api/key_case_test.rb
Normal file
500
test/adapter/json_api/key_case_test.rb
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
module ActiveModelSerializers
|
||||||
|
module Adapter
|
||||||
|
class JsonApi
|
||||||
|
class KeyCaseTest < ActiveSupport::TestCase
|
||||||
|
Post = Class.new(::Model)
|
||||||
|
class PostSerializer < ActiveModel::Serializer
|
||||||
|
type 'posts'
|
||||||
|
attributes :title, :body, :publish_at
|
||||||
|
belongs_to :author
|
||||||
|
has_many :comments
|
||||||
|
|
||||||
|
link(:self) { post_url(object.id) }
|
||||||
|
link(:post_authors) { post_authors_url(object.id) }
|
||||||
|
link(:subscriber_comments) { post_comments_url(object.id) }
|
||||||
|
|
||||||
|
meta do
|
||||||
|
{
|
||||||
|
rating: 5,
|
||||||
|
favorite_count: 10
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Author = Class.new(::Model)
|
||||||
|
class AuthorSerializer < ActiveModel::Serializer
|
||||||
|
type 'authors'
|
||||||
|
attributes :first_name, :last_name
|
||||||
|
end
|
||||||
|
|
||||||
|
Comment = Class.new(::Model)
|
||||||
|
class CommentSerializer < ActiveModel::Serializer
|
||||||
|
type 'comments'
|
||||||
|
attributes :body
|
||||||
|
belongs_to :author
|
||||||
|
end
|
||||||
|
|
||||||
|
def mock_request(key_transform = nil)
|
||||||
|
context = Minitest::Mock.new
|
||||||
|
context.expect(:request_url, URI)
|
||||||
|
context.expect(:query_parameters, {})
|
||||||
|
context.expect(:key_transform, key_transform)
|
||||||
|
context.expect(:url_helpers, Rails.application.routes.url_helpers)
|
||||||
|
@options = {}
|
||||||
|
@options[:serialization_context] = context
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup
|
||||||
|
Rails.application.routes.draw do
|
||||||
|
resources :posts do
|
||||||
|
resources :authors
|
||||||
|
resources :comments
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@publish_at = 1.day.from_now
|
||||||
|
@author = Author.new(id: 1, first_name: 'Bob', last_name: 'Jones')
|
||||||
|
@comment1 = Comment.new(id: 7, body: 'cool', author: @author)
|
||||||
|
@comment2 = Comment.new(id: 12, body: 'awesome', author: @author)
|
||||||
|
@post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1',
|
||||||
|
author: @author, comments: [@comment1, @comment2],
|
||||||
|
publish_at: @publish_at)
|
||||||
|
@comment1.post = @post
|
||||||
|
@comment2.post = @post
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_success_document_key_transform_default
|
||||||
|
mock_request
|
||||||
|
serializer = PostSerializer.new(@post)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
assert_equal({
|
||||||
|
data: {
|
||||||
|
id: '1337',
|
||||||
|
type: 'posts',
|
||||||
|
attributes: {
|
||||||
|
title: 'Title 1',
|
||||||
|
body: 'Body 1',
|
||||||
|
:"publish-at" => @publish_at
|
||||||
|
},
|
||||||
|
relationships: {
|
||||||
|
author: {
|
||||||
|
data: { id: '1', type: 'authors' }
|
||||||
|
},
|
||||||
|
comments: {
|
||||||
|
data: [
|
||||||
|
{ id: '7', type: 'comments' },
|
||||||
|
{ id: '12', type: 'comments' }
|
||||||
|
] }
|
||||||
|
},
|
||||||
|
links: {
|
||||||
|
self: 'http://example.com/posts/1337',
|
||||||
|
:"post-authors" => 'http://example.com/posts/1337/authors',
|
||||||
|
:"subscriber-comments" => 'http://example.com/posts/1337/comments'
|
||||||
|
},
|
||||||
|
meta: { rating: 5, :"favorite-count" => 10 }
|
||||||
|
}
|
||||||
|
}, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_success_document_key_transform_global_config
|
||||||
|
mock_request
|
||||||
|
result = with_config(key_transform: :camel_lower) do
|
||||||
|
serializer = PostSerializer.new(@post)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
adapter.serializable_hash(@options)
|
||||||
|
end
|
||||||
|
assert_equal({
|
||||||
|
data: {
|
||||||
|
id: '1337',
|
||||||
|
type: 'posts',
|
||||||
|
attributes: {
|
||||||
|
title: 'Title 1',
|
||||||
|
body: 'Body 1',
|
||||||
|
publishAt: @publish_at
|
||||||
|
},
|
||||||
|
relationships: {
|
||||||
|
author: {
|
||||||
|
data: { id: '1', type: 'authors' }
|
||||||
|
},
|
||||||
|
comments: {
|
||||||
|
data: [
|
||||||
|
{ id: '7', type: 'comments' },
|
||||||
|
{ id: '12', type: 'comments' }
|
||||||
|
] }
|
||||||
|
},
|
||||||
|
links: {
|
||||||
|
self: 'http://example.com/posts/1337',
|
||||||
|
postAuthors: 'http://example.com/posts/1337/authors',
|
||||||
|
subscriberComments: 'http://example.com/posts/1337/comments'
|
||||||
|
},
|
||||||
|
meta: { rating: 5, favoriteCount: 10 }
|
||||||
|
}
|
||||||
|
}, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_success_doc_key_transform_serialization_ctx_overrides_global
|
||||||
|
mock_request(:camel)
|
||||||
|
result = with_config(key_transform: :camel_lower) do
|
||||||
|
serializer = PostSerializer.new(@post)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
adapter.serializable_hash(@options)
|
||||||
|
end
|
||||||
|
assert_equal({
|
||||||
|
Data: {
|
||||||
|
Id: '1337',
|
||||||
|
Type: 'posts',
|
||||||
|
Attributes: {
|
||||||
|
Title: 'Title 1',
|
||||||
|
Body: 'Body 1',
|
||||||
|
PublishAt: @publish_at
|
||||||
|
},
|
||||||
|
Relationships: {
|
||||||
|
Author: {
|
||||||
|
Data: { Id: '1', Type: 'authors' }
|
||||||
|
},
|
||||||
|
Comments: {
|
||||||
|
Data: [
|
||||||
|
{ Id: '7', Type: 'comments' },
|
||||||
|
{ Id: '12', Type: 'comments' }
|
||||||
|
] }
|
||||||
|
},
|
||||||
|
Links: {
|
||||||
|
Self: 'http://example.com/posts/1337',
|
||||||
|
PostAuthors: 'http://example.com/posts/1337/authors',
|
||||||
|
SubscriberComments: 'http://example.com/posts/1337/comments'
|
||||||
|
},
|
||||||
|
Meta: { Rating: 5, FavoriteCount: 10 }
|
||||||
|
}
|
||||||
|
}, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_success_document_key_transform_dashed
|
||||||
|
mock_request(:dashed)
|
||||||
|
serializer = PostSerializer.new(@post)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
assert_equal({
|
||||||
|
data: {
|
||||||
|
id: '1337',
|
||||||
|
type: 'posts',
|
||||||
|
attributes: {
|
||||||
|
title: 'Title 1',
|
||||||
|
body: 'Body 1',
|
||||||
|
:"publish-at" => @publish_at
|
||||||
|
},
|
||||||
|
relationships: {
|
||||||
|
author: {
|
||||||
|
data: { id: '1', type: 'authors' }
|
||||||
|
},
|
||||||
|
comments: {
|
||||||
|
data: [
|
||||||
|
{ id: '7', type: 'comments' },
|
||||||
|
{ id: '12', type: 'comments' }
|
||||||
|
] }
|
||||||
|
},
|
||||||
|
links: {
|
||||||
|
self: 'http://example.com/posts/1337',
|
||||||
|
:"post-authors" => 'http://example.com/posts/1337/authors',
|
||||||
|
:"subscriber-comments" => 'http://example.com/posts/1337/comments'
|
||||||
|
},
|
||||||
|
meta: { rating: 5, :"favorite-count" => 10 }
|
||||||
|
}
|
||||||
|
}, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_success_document_key_transform_unaltered
|
||||||
|
mock_request(:unaltered)
|
||||||
|
serializer = PostSerializer.new(@post)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
assert_equal({
|
||||||
|
data: {
|
||||||
|
id: '1337',
|
||||||
|
type: 'posts',
|
||||||
|
attributes: {
|
||||||
|
title: 'Title 1',
|
||||||
|
body: 'Body 1',
|
||||||
|
publish_at: @publish_at
|
||||||
|
},
|
||||||
|
relationships: {
|
||||||
|
author: {
|
||||||
|
data: { id: '1', type: 'authors' }
|
||||||
|
},
|
||||||
|
comments: {
|
||||||
|
data: [
|
||||||
|
{ id: '7', type: 'comments' },
|
||||||
|
{ id: '12', type: 'comments' }
|
||||||
|
] }
|
||||||
|
},
|
||||||
|
links: {
|
||||||
|
self: 'http://example.com/posts/1337',
|
||||||
|
post_authors: 'http://example.com/posts/1337/authors',
|
||||||
|
subscriber_comments: 'http://example.com/posts/1337/comments'
|
||||||
|
},
|
||||||
|
meta: { rating: 5, favorite_count: 10 }
|
||||||
|
}
|
||||||
|
}, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_success_document_key_transform_undefined
|
||||||
|
mock_request(:zoot)
|
||||||
|
serializer = PostSerializer.new(@post)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
assert_raises NoMethodError do
|
||||||
|
adapter.serializable_hash(@options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_success_document_key_transform_camel
|
||||||
|
mock_request(:camel)
|
||||||
|
serializer = PostSerializer.new(@post)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
assert_equal({
|
||||||
|
Data: {
|
||||||
|
Id: '1337',
|
||||||
|
Type: 'posts',
|
||||||
|
Attributes: {
|
||||||
|
Title: 'Title 1',
|
||||||
|
Body: 'Body 1',
|
||||||
|
PublishAt: @publish_at
|
||||||
|
},
|
||||||
|
Relationships: {
|
||||||
|
Author: {
|
||||||
|
Data: { Id: '1', Type: 'authors' }
|
||||||
|
},
|
||||||
|
Comments: {
|
||||||
|
Data: [
|
||||||
|
{ Id: '7', Type: 'comments' },
|
||||||
|
{ Id: '12', Type: 'comments' }
|
||||||
|
] }
|
||||||
|
},
|
||||||
|
Links: {
|
||||||
|
Self: 'http://example.com/posts/1337',
|
||||||
|
PostAuthors: 'http://example.com/posts/1337/authors',
|
||||||
|
SubscriberComments: 'http://example.com/posts/1337/comments'
|
||||||
|
},
|
||||||
|
Meta: { Rating: 5, FavoriteCount: 10 }
|
||||||
|
}
|
||||||
|
}, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_success_document_key_transform_camel_lower
|
||||||
|
mock_request(:camel_lower)
|
||||||
|
serializer = PostSerializer.new(@post)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
assert_equal({
|
||||||
|
data: {
|
||||||
|
id: '1337',
|
||||||
|
type: 'posts',
|
||||||
|
attributes: {
|
||||||
|
title: 'Title 1',
|
||||||
|
body: 'Body 1',
|
||||||
|
publishAt: @publish_at
|
||||||
|
},
|
||||||
|
relationships: {
|
||||||
|
author: {
|
||||||
|
data: { id: '1', type: 'authors' }
|
||||||
|
},
|
||||||
|
comments: {
|
||||||
|
data: [
|
||||||
|
{ id: '7', type: 'comments' },
|
||||||
|
{ id: '12', type: 'comments' }
|
||||||
|
] }
|
||||||
|
},
|
||||||
|
links: {
|
||||||
|
self: 'http://example.com/posts/1337',
|
||||||
|
postAuthors: 'http://example.com/posts/1337/authors',
|
||||||
|
subscriberComments: 'http://example.com/posts/1337/comments'
|
||||||
|
},
|
||||||
|
meta: { rating: 5, favoriteCount: 10 }
|
||||||
|
}
|
||||||
|
}, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_error_document_key_transform_default
|
||||||
|
mock_request
|
||||||
|
resource = ModelWithErrors.new
|
||||||
|
resource.errors.add(:published_at, 'must be in the future')
|
||||||
|
resource.errors.add(:title, 'must be longer')
|
||||||
|
serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
expected_errors_object =
|
||||||
|
{ :errors =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
:source => { :pointer => '/data/attributes/published_at' },
|
||||||
|
:detail => 'must be in the future' },
|
||||||
|
{
|
||||||
|
:source => { :pointer => '/data/attributes/title' },
|
||||||
|
:detail => 'must be longer'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal expected_errors_object, result
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_error_document_key_transform_global_config
|
||||||
|
mock_request
|
||||||
|
result = with_config(key_transform: :camel) do
|
||||||
|
resource = ModelWithErrors.new
|
||||||
|
resource.errors.add(:published_at, 'must be in the future')
|
||||||
|
resource.errors.add(:title, 'must be longer')
|
||||||
|
serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
adapter.serializable_hash(@options)
|
||||||
|
end
|
||||||
|
expected_errors_object =
|
||||||
|
{ :Errors =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
:Source => { :Pointer => '/data/attributes/published_at' },
|
||||||
|
:Detail => 'must be in the future'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:Source => { :Pointer => '/data/attributes/title' },
|
||||||
|
:Detail => 'must be longer'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal expected_errors_object, result
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_error_document_key_transform_serialization_ctx_overrides_global
|
||||||
|
mock_request(:camel)
|
||||||
|
result = with_config(key_transform: :camel_lower) do
|
||||||
|
resource = ModelWithErrors.new
|
||||||
|
resource.errors.add(:published_at, 'must be in the future')
|
||||||
|
resource.errors.add(:title, 'must be longer')
|
||||||
|
serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
adapter.serializable_hash(@options)
|
||||||
|
end
|
||||||
|
expected_errors_object =
|
||||||
|
{ :Errors =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
:Source => { :Pointer => '/data/attributes/published_at' },
|
||||||
|
:Detail => 'must be in the future'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:Source => { :Pointer => '/data/attributes/title' },
|
||||||
|
:Detail => 'must be longer'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal expected_errors_object, result
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_error_document_key_transform_dashed
|
||||||
|
mock_request(:dashed)
|
||||||
|
|
||||||
|
resource = ModelWithErrors.new
|
||||||
|
resource.errors.add(:published_at, 'must be in the future')
|
||||||
|
resource.errors.add(:title, 'must be longer')
|
||||||
|
|
||||||
|
serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
|
||||||
|
expected_errors_object =
|
||||||
|
{ :errors =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
:source => { :pointer => '/data/attributes/published_at' },
|
||||||
|
:detail => 'must be in the future'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:source => { :pointer => '/data/attributes/title' },
|
||||||
|
:detail => 'must be longer'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal expected_errors_object, result
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_error_document_key_transform_unaltered
|
||||||
|
mock_request(:unaltered)
|
||||||
|
|
||||||
|
resource = ModelWithErrors.new
|
||||||
|
resource.errors.add(:published_at, 'must be in the future')
|
||||||
|
resource.errors.add(:title, 'must be longer')
|
||||||
|
|
||||||
|
serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
|
||||||
|
expected_errors_object =
|
||||||
|
{ :errors =>
|
||||||
|
[
|
||||||
|
{ :source => { :pointer => '/data/attributes/published_at' }, :detail => 'must be in the future' },
|
||||||
|
{ :source => { :pointer => '/data/attributes/title' }, :detail => 'must be longer' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal expected_errors_object, result
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_error_document_key_transform_undefined
|
||||||
|
mock_request(:krazy)
|
||||||
|
|
||||||
|
resource = ModelWithErrors.new
|
||||||
|
resource.errors.add(:published_at, 'must be in the future')
|
||||||
|
resource.errors.add(:title, 'must be longer')
|
||||||
|
|
||||||
|
serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
|
||||||
|
assert_raises NoMethodError do
|
||||||
|
adapter.serializable_hash(@options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_error_document_key_transform_camel
|
||||||
|
mock_request(:camel)
|
||||||
|
|
||||||
|
resource = ModelWithErrors.new
|
||||||
|
resource.errors.add(:published_at, 'must be in the future')
|
||||||
|
resource.errors.add(:title, 'must be longer')
|
||||||
|
|
||||||
|
serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
|
||||||
|
expected_errors_object =
|
||||||
|
{ :Errors =>
|
||||||
|
[
|
||||||
|
{ :Source => { :Pointer => '/data/attributes/published_at' }, :Detail => 'must be in the future' },
|
||||||
|
{ :Source => { :Pointer => '/data/attributes/title' }, :Detail => 'must be longer' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal expected_errors_object, result
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_error_document_key_transform_camel_lower
|
||||||
|
mock_request(:camel_lower)
|
||||||
|
|
||||||
|
resource = ModelWithErrors.new
|
||||||
|
resource.errors.add(:published_at, 'must be in the future')
|
||||||
|
resource.errors.add(:title, 'must be longer')
|
||||||
|
|
||||||
|
serializer = ActiveModel::Serializer::ErrorSerializer.new(resource)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
result = adapter.serializable_hash(@options)
|
||||||
|
|
||||||
|
expected_errors_object =
|
||||||
|
{ :errors =>
|
||||||
|
[
|
||||||
|
{ :source => { :pointer => '/data/attributes/published_at' }, :detail => 'must be in the future' },
|
||||||
|
{ :source => { :pointer => '/data/attributes/title' }, :detail => 'must be longer' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal expected_errors_object, result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -25,6 +25,7 @@ module ActiveModelSerializers
|
|||||||
context = Minitest::Mock.new
|
context = Minitest::Mock.new
|
||||||
context.expect(:request_url, original_url)
|
context.expect(:request_url, original_url)
|
||||||
context.expect(:query_parameters, query_parameters)
|
context.expect(:query_parameters, query_parameters)
|
||||||
|
context.expect(:key_transform, nil)
|
||||||
@options = {}
|
@options = {}
|
||||||
@options[:serialization_context] = context
|
@options[:serialization_context] = context
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user