Skip to content

Commit

Permalink
Add global config option for key transform
Browse files Browse the repository at this point in the history
  • Loading branch information
remear committed Mar 14, 2016
1 parent 8e699e1 commit 3d2b759
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 9 deletions.
1 change: 1 addition & 0 deletions lib/active_model/serializer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def config.array_serializer
# Make JSON API top-level jsonapi member opt-in
# ref: http://jsonapi.org/format/#document-top-level
config.jsonapi_include_toplevel_object = false
config.key_transform = nil

config.schema_path = 'test/support/schemas'
end
Expand Down
13 changes: 12 additions & 1 deletion lib/active_model_serializers/adapter/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,20 @@ 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 = serialization_context.key_transform || default_key_transform
transform = key_transform(serialization_context)
KeyTransform.send(transform, value)
end
end
Expand Down
20 changes: 20 additions & 0 deletions test/adapter/json/key_case_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,26 @@ def test_key_transform_default
}, @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
Expand Down
148 changes: 140 additions & 8 deletions test/adapter/json_api/key_case_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,78 @@ def test_success_document_key_transform_default
}, 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)
Expand Down Expand Up @@ -245,22 +317,76 @@ def test_success_document_key_transform_camel_lower

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' }
{
: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

Expand All @@ -278,8 +404,14 @@ def test_error_document_key_transform_dashed
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' }
{
: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
Expand Down

0 comments on commit 3d2b759

Please sign in to comment.