active_model_serializers/test/action_controller/serialization_test.rb
Ben Woosley 251e33a0a1 Don't pluralize the CollectionSerializer#root for #json_key
One of three constituents is used to provide the
CollectionSerializer's #json_key:

1) the :root option - controlled by the caller
2) the #name of the first resource serializer - the root or
   underscored model name
3) the underscored #name of the resources object - generally
   equivalent to the underscored model name of #2

Of the three, only the latter 2 are out of the callers control, and
only the latter two are expected to be singular by default. Not
pluralizing the root gives the caller additional flexibility in
defining the desired root, whether conventionally plural,
unconventionally plural (e.g. objects_received:) or singular.
2016-01-12 09:32:43 -08:00

436 lines
13 KiB
Ruby

require 'test_helper'
module ActionController
module Serialization
class ImplicitSerializerTest < ActionController::TestCase
include ActiveSupport::Testing::Stream
class ImplicitSerializationTestController < ActionController::Base
include SerializationTesting
def render_using_implicit_serializer
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
render json: @profile
end
def render_using_default_adapter_root
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
render json: @profile
end
def render_array_using_custom_root
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
render json: [@profile], root: 'custom_root'
end
def render_array_that_is_empty_using_custom_root
render json: [], root: 'custom_root'
end
def render_object_using_custom_root
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
render json: @profile, root: 'custom_root'
end
def render_array_using_implicit_serializer
array = [
Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
Profile.new(name: 'Name 2', description: 'Description 2', comments: 'Comments 2')
]
render json: array
end
def render_array_using_implicit_serializer_and_meta
@profiles = [
Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
]
render json: @profiles, meta: { total: 10 }
end
def render_object_with_cache_enabled
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
@author = Author.new(id: 1, name: 'Joao Moura.')
@post = Post.new(id: 1, title: 'New Post', body: 'Body', comments: [@comment], author: @author)
generate_cached_serializer(@post)
@post.title = 'ZOMG a New Post'
render json: @post
end
def render_json_object_without_serializer
render json: { error: 'Result is Invalid' }
end
def render_json_array_object_without_serializer
render json: [{ error: 'Result is Invalid' }]
end
def update_and_render_object_with_cache_enabled
@post.updated_at = Time.now
generate_cached_serializer(@post)
render json: @post
end
def render_object_expired_with_cache_enabled
comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
author = Author.new(id: 1, name: 'Joao Moura.')
post = Post.new(id: 1, title: 'New Post', body: 'Body', comments: [comment], author: author)
generate_cached_serializer(post)
post.title = 'ZOMG a New Post'
expires_in = [
PostSerializer._cache_options[:expires_in],
CommentSerializer._cache_options[:expires_in],
].max + 200
Timecop.travel(Time.zone.now + expires_in) do
render json: post
end
end
def render_changed_object_with_cache_enabled
comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
author = Author.new(id: 1, name: 'Joao Moura.')
post = Post.new(id: 1, title: 'ZOMG a New Post', body: 'Body', comments: [comment], author: author)
render json: post
end
def render_fragment_changed_object_with_only_cache_enabled
author = Author.new(id: 1, name: 'Joao Moura.')
role = Role.new(id: 42, name: 'ZOMG A ROLE', description: 'DESCRIPTION HERE', author: author)
generate_cached_serializer(role)
role.name = 'lol'
role.description = 'HUEHUEBRBR'
render json: role
end
def render_fragment_changed_object_with_except_cache_enabled
author = Author.new(id: 1, name: 'Joao Moura.')
bio = Bio.new(id: 42, content: 'ZOMG A ROLE', rating: 5, author: author)
generate_cached_serializer(bio)
bio.content = 'lol'
bio.rating = 0
render json: bio
end
def render_fragment_changed_object_with_relationship
comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
comment2 = Comment.new(id: 1, body: 'ZOMG AN UPDATED-BUT-NOT-CACHE-EXPIRED COMMENT')
like = Like.new(id: 1, likeable: comment, time: 3.days.ago)
generate_cached_serializer(like)
like.likable = comment2
like.time = Time.zone.now.to_s
render json: like
end
end
tests ImplicitSerializationTestController
# We just have Null for now, this will change
def test_render_using_implicit_serializer
get :render_using_implicit_serializer
expected = {
name: 'Name 1',
description: 'Description 1'
}
assert_equal 'application/json', @response.content_type
assert_equal expected.to_json, @response.body
end
def test_render_using_default_root
with_adapter :json_api do
get :render_using_default_adapter_root
end
expected = {
data: {
id: assigns(:profile).id.to_s,
type: 'profiles',
attributes: {
name: 'Name 1',
description: 'Description 1'
}
}
}
assert_equal 'application/json', @response.content_type
assert_equal expected.to_json, @response.body
end
def test_render_array_using_custom_root
with_adapter :json do
get :render_array_using_custom_root
end
expected = { custom_root: [{ name: 'Name 1', description: 'Description 1' }] }
assert_equal 'application/json', @response.content_type
assert_equal expected.to_json, @response.body
end
def test_render_array_that_is_empty_using_custom_root
with_adapter :json do
get :render_array_that_is_empty_using_custom_root
end
expected = { custom_root: [] }
assert_equal 'application/json', @response.content_type
assert_equal expected.to_json, @response.body
end
def test_render_object_using_custom_root
with_adapter :json do
get :render_object_using_custom_root
end
expected = { custom_root: { name: 'Name 1', description: 'Description 1' } }
assert_equal 'application/json', @response.content_type
assert_equal expected.to_json, @response.body
end
def test_render_json_object_without_serializer
get :render_json_object_without_serializer
assert_equal 'application/json', @response.content_type
expected_body = { error: 'Result is Invalid' }
assert_equal expected_body.to_json, @response.body
end
def test_render_json_array_object_without_serializer
get :render_json_array_object_without_serializer
assert_equal 'application/json', @response.content_type
expected_body = [{ error: 'Result is Invalid' }]
assert_equal expected_body.to_json, @response.body
end
def test_render_array_using_implicit_serializer
get :render_array_using_implicit_serializer
assert_equal 'application/json', @response.content_type
expected = [
{
name: 'Name 1',
description: 'Description 1'
},
{
name: 'Name 2',
description: 'Description 2'
}
]
assert_equal expected.to_json, @response.body
end
def test_render_array_using_implicit_serializer_and_meta
with_adapter :json_api do
get :render_array_using_implicit_serializer_and_meta
end
expected = {
data: [
{
id: assigns(:profiles).first.id.to_s,
type: 'profiles',
attributes: {
name: 'Name 1',
description: 'Description 1'
}
}
],
meta: {
total: 10
}
}
assert_equal 'application/json', @response.content_type
assert_equal expected.to_json, @response.body
end
def test_render_with_cache_enable
expected = {
id: 1,
title: 'New Post',
body: 'Body',
comments: [
{
id: 1,
body: 'ZOMG A COMMENT' }
],
blog: {
id: 999,
name: 'Custom blog'
},
author: {
id: 1,
name: 'Joao Moura.'
}
}
ActionController::Base.cache_store.clear
Timecop.freeze(Time.zone.now) do
get :render_object_with_cache_enabled
assert_equal 'application/json', @response.content_type
assert_equal expected.to_json, @response.body
get :render_changed_object_with_cache_enabled
assert_equal expected.to_json, @response.body
end
ActionController::Base.cache_store.clear
get :render_changed_object_with_cache_enabled
assert_not_equal expected.to_json, @response.body
end
def test_render_with_cache_enable_and_expired
ActionController::Base.cache_store.clear
get :render_object_expired_with_cache_enabled
expected = {
id: 1,
title: 'ZOMG a New Post',
body: 'Body',
comments: [
{
id: 1,
body: 'ZOMG A COMMENT' }
],
blog: {
id: 999,
name: 'Custom blog'
},
author: {
id: 1,
name: 'Joao Moura.'
}
}
assert_equal 'application/json', @response.content_type
actual = @response.body
expected = expected.to_json
if ENV['APPVEYOR'] && actual != expected
skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
else
assert_equal actual, expected
end
end
def test_render_with_fragment_only_cache_enable
ActionController::Base.cache_store.clear
get :render_fragment_changed_object_with_only_cache_enabled
response = JSON.parse(@response.body)
assert_equal 'application/json', @response.content_type
assert_equal 'ZOMG A ROLE', response['name']
assert_equal 'HUEHUEBRBR', response['description']
end
def test_render_with_fragment_except_cache_enable
ActionController::Base.cache_store.clear
get :render_fragment_changed_object_with_except_cache_enabled
response = JSON.parse(@response.body)
assert_equal 'application/json', @response.content_type
assert_equal 5, response['rating']
assert_equal 'lol', response['content']
end
def test_render_fragment_changed_object_with_relationship
ActionController::Base.cache_store.clear
Timecop.freeze(Time.zone.now) do
get :render_fragment_changed_object_with_relationship
response = JSON.parse(@response.body)
expected_return = {
'id' => 1,
'time' => Time.zone.now.to_s,
'likeable' => {
'id' => 1,
'body' => 'ZOMG A COMMENT'
}
}
assert_equal 'application/json', @response.content_type
assert_equal expected_return, response
end
end
def test_cache_expiration_on_update
ActionController::Base.cache_store.clear
get :render_object_with_cache_enabled
expected = {
id: 1,
title: 'ZOMG a New Post',
body: 'Body',
comments: [
{
id: 1,
body: 'ZOMG A COMMENT' }
],
blog: {
id: 999,
name: 'Custom blog'
},
author: {
id: 1,
name: 'Joao Moura.'
}
}
get :update_and_render_object_with_cache_enabled
assert_equal 'application/json', @response.content_type
actual = @response.body
expected = expected.to_json
if ENV['APPVEYOR'] && actual != expected
skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
else
assert_equal actual, expected
end
end
def test_warn_overridding_use_adapter_as_falsy_on_controller_instance
controller = Class.new(ImplicitSerializationTestController) do
def use_adapter?
false
end
end.new
assert_match(/adapter: false/, (capture(:stderr) do
controller.get_serializer(Profile.new)
end))
end
def test_dont_warn_overridding_use_adapter_as_truthy_on_controller_instance
controller = Class.new(ImplicitSerializationTestController) do
def use_adapter?
true
end
end.new
assert_equal '', (capture(:stderr) do
controller.get_serializer(Profile.new)
end)
end
def test_render_event_is_emmited
ActiveSupport::Notifications.subscribe('render.active_model_serializers') do |name|
@name = name
end
get :render_using_implicit_serializer
assert_equal 'render.active_model_serializers', @name
end
end
end
end