mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
1522 lines
36 KiB
Ruby
1522 lines
36 KiB
Ruby
require "test_helper"
|
|
require "test_fakes"
|
|
|
|
class SerializerTest < ActiveModel::TestCase
|
|
def test_scope_works_correct
|
|
serializer = ActiveModel::Serializer.new :foo, scope: :bar
|
|
assert_equal serializer.scope, :bar
|
|
end
|
|
|
|
def test_attributes
|
|
user = User.new
|
|
user_serializer = DefaultUserSerializer.new(user, {})
|
|
|
|
hash = user_serializer.as_json
|
|
|
|
assert_equal({
|
|
default_user: { first_name: "Jose", last_name: "Valim" }
|
|
}, hash)
|
|
end
|
|
|
|
def test_attributes_method
|
|
user = User.new
|
|
user_serializer = UserSerializer.new(user, scope: {})
|
|
|
|
hash = user_serializer.as_json
|
|
|
|
assert_equal({
|
|
user: { first_name: "Jose", last_name: "Valim", ok: true }
|
|
}, hash)
|
|
end
|
|
|
|
def test_attributes_method_specifying_keys
|
|
user = User.new
|
|
user_serializer = UserAttributesWithKeySerializer.new(user, scope: {})
|
|
|
|
hash = user_serializer.as_json
|
|
|
|
assert_equal({
|
|
user_attributes_with_key: { f_name: "Jose", l_name: "Valim", ok: true }
|
|
}, hash)
|
|
end
|
|
|
|
def test_attributes_method_specifying_some_keys
|
|
user = User.new
|
|
user_serializer = UserAttributesWithSomeKeySerializer.new(user, scope: {})
|
|
|
|
hash = user_serializer.as_json
|
|
|
|
assert_equal({
|
|
user_attributes_with_some_key: { first_name: "Jose", l_name: "Valim", ok: true }
|
|
}, hash)
|
|
end
|
|
|
|
def test_attributes_method_with_unsymbolizable_key
|
|
user = User.new
|
|
user_serializer = UserAttributesWithUnsymbolizableKeySerializer.new(user, scope: {})
|
|
|
|
hash = user_serializer.as_json
|
|
|
|
assert_equal({
|
|
user_attributes_with_unsymbolizable_key: { first_name: "Jose", :"last-name" => "Valim", ok: true }
|
|
}, hash)
|
|
end
|
|
|
|
def test_attribute_method_with_name_as_serializer_prefix
|
|
object = SomeObject.new("something")
|
|
object_serializer = SomeSerializer.new(object, {})
|
|
|
|
hash = object_serializer.as_json
|
|
|
|
assert_equal({
|
|
some: { some: "something" }
|
|
}, hash)
|
|
end
|
|
|
|
def test_serializer_receives_scope
|
|
user = User.new
|
|
user_serializer = UserSerializer.new(user, scope: { scope: true })
|
|
|
|
hash = user_serializer.as_json
|
|
|
|
assert_equal({
|
|
user: {
|
|
first_name: "Jose",
|
|
last_name: "Valim",
|
|
ok: true,
|
|
scope: true
|
|
}
|
|
}, hash)
|
|
end
|
|
|
|
def test_serializer_receives_url_options
|
|
user = User.new
|
|
user_serializer = UserSerializer.new(user, url_options: { host: "test.local" })
|
|
assert_equal({ host: "test.local" }, user_serializer.url_options)
|
|
end
|
|
|
|
def test_serializer_returns_empty_hash_without_url_options
|
|
user = User.new
|
|
user_serializer = UserSerializer.new(user)
|
|
assert_equal({}, user_serializer.url_options)
|
|
end
|
|
|
|
def test_pretty_accessors
|
|
user = User.new
|
|
user.superuser = true
|
|
user_serializer = MyUserSerializer.new(user)
|
|
|
|
hash = user_serializer.as_json
|
|
|
|
assert_equal({
|
|
my_user: {
|
|
first_name: "Jose", last_name: "Valim", super_user: true
|
|
}
|
|
}, hash)
|
|
end
|
|
|
|
def test_has_many
|
|
user = User.new
|
|
|
|
post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
|
|
comments = [Comment.new(title: "Comment1"), Comment.new(title: "Comment2")]
|
|
post.comments = comments
|
|
|
|
post_serializer = PostSerializer.new(post, scope: user)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
comments: [
|
|
{ title: "Comment1" },
|
|
{ title: "Comment2" }
|
|
]
|
|
}
|
|
}, post_serializer.as_json)
|
|
end
|
|
|
|
def test_conditionally_included_associations
|
|
user = User.new
|
|
|
|
post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
|
|
comments = [Comment.new(title: "Comment1"), Comment.new(title: "Comment2")]
|
|
post.comments = comments
|
|
|
|
post_serializer = PostWithConditionalCommentsSerializer.new(post, scope: user)
|
|
|
|
# comments enabled
|
|
post.comments_disabled = false
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
comments: [
|
|
{ title: "Comment1" },
|
|
{ title: "Comment2" }
|
|
]
|
|
}
|
|
}, post_serializer.as_json)
|
|
|
|
# comments disabled
|
|
post.comments_disabled = true
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post"
|
|
}
|
|
}, post_serializer.as_json)
|
|
end
|
|
|
|
def test_conditionally_included_associations_and_attributes
|
|
user = User.new
|
|
|
|
post = Post.new(title: "New Post", body: "Body of new post", author: 'Sausage King', email: "tenderlove@tenderlove.com")
|
|
comments = [Comment.new(title: "Comment1"), Comment.new(title: "Comment2")]
|
|
post.comments = comments
|
|
|
|
post_serializer = PostWithMultipleConditionalsSerializer.new(post, scope: user)
|
|
|
|
# comments enabled
|
|
post.comments_disabled = false
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
comments: [
|
|
{ title: "Comment1" },
|
|
{ title: "Comment2" }
|
|
]
|
|
}
|
|
}, post_serializer.as_json)
|
|
|
|
# comments disabled
|
|
post.comments_disabled = true
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post"
|
|
}
|
|
}, post_serializer.as_json)
|
|
|
|
# superuser - should see author
|
|
user.superuser = true
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
author: "Sausage King"
|
|
}
|
|
}, post_serializer.as_json)
|
|
end
|
|
|
|
def test_has_one
|
|
user = User.new
|
|
blog = Blog.new
|
|
blog.author = user
|
|
|
|
json = BlogSerializer.new(blog, scope: user).as_json
|
|
assert_equal({
|
|
blog: {
|
|
author: {
|
|
first_name: "Jose",
|
|
last_name: "Valim"
|
|
}
|
|
}
|
|
}, json)
|
|
end
|
|
|
|
def test_overridden_associations
|
|
author_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :first_name
|
|
end
|
|
|
|
blog_serializer = Class.new(ActiveModel::Serializer) do
|
|
def person
|
|
object.author
|
|
end
|
|
|
|
has_one :person, serializer: author_serializer
|
|
end
|
|
|
|
user = User.new
|
|
blog = Blog.new
|
|
blog.author = user
|
|
|
|
json = blog_serializer.new(blog, scope: user).as_json
|
|
assert_equal({
|
|
person: {
|
|
first_name: "Jose"
|
|
}
|
|
}, json)
|
|
end
|
|
|
|
def post_serializer
|
|
Class.new(ActiveModel::Serializer) do
|
|
attributes :title, :body
|
|
has_many :comments, serializer: CommentSerializer
|
|
has_one :author, serializer: DefaultUserSerializer
|
|
end
|
|
end
|
|
|
|
def test_associations_with_nil_association
|
|
user = User.new
|
|
blog = Blog.new
|
|
|
|
json = BlogSerializer.new(blog, scope: user).as_json
|
|
assert_equal({
|
|
blog: { author: nil }
|
|
}, json)
|
|
|
|
serializer = Class.new(BlogSerializer) do
|
|
root :blog
|
|
end
|
|
|
|
json = serializer.new(blog, scope: user).as_json
|
|
assert_equal({ blog: { author: nil } }, json)
|
|
end
|
|
|
|
def test_custom_root
|
|
user = User.new
|
|
blog = Blog.new
|
|
|
|
serializer = Class.new(BlogSerializer) do
|
|
root :my_blog
|
|
end
|
|
|
|
assert_equal({ my_blog: { author: nil } }, serializer.new(blog, scope: user).as_json)
|
|
end
|
|
|
|
def test_nil_root_object
|
|
user = User.new
|
|
blog = nil
|
|
|
|
serializer = Class.new(BlogSerializer) do
|
|
root false
|
|
end
|
|
|
|
assert_equal(nil, serializer.new(blog, scope: user).as_json)
|
|
end
|
|
|
|
def test_custom_root_with_nil_root_object
|
|
user = User.new
|
|
blog = nil
|
|
|
|
serializer = Class.new(BlogSerializer) do
|
|
root :my_blog
|
|
end
|
|
|
|
assert_equal({ my_blog: nil }, serializer.new(blog, scope: user).as_json)
|
|
end
|
|
|
|
def test_false_root
|
|
user = User.new
|
|
blog = Blog.new
|
|
|
|
serializer = Class.new(BlogSerializer) do
|
|
root false
|
|
end
|
|
|
|
another_serializer = Class.new(BlogSerializer) do
|
|
self.root = false
|
|
end
|
|
|
|
assert_equal({ author: nil }, serializer.new(blog, scope: user).as_json)
|
|
assert_equal({ author: nil }, another_serializer.new(blog, scope: user).as_json)
|
|
|
|
# test inherited false root
|
|
serializer = Class.new(serializer)
|
|
assert_equal({ author: nil }, serializer.new(blog, scope: user).as_json)
|
|
end
|
|
|
|
def test_true_root
|
|
blog = Blog.new
|
|
|
|
assert_equal({
|
|
blog_with_root: {
|
|
author: nil,
|
|
}
|
|
}, BlogWithRootSerializer.new(blog).as_json)
|
|
end
|
|
|
|
def test_root_false_on_load_active_model_serializers
|
|
begin
|
|
ActiveSupport.on_load(:active_model_serializers) do
|
|
self.root = false
|
|
end
|
|
|
|
blog = Blog.new
|
|
serializer = BlogSerializer.new(blog)
|
|
|
|
assert_equal({ author: nil }, serializer.as_json)
|
|
ensure
|
|
ActiveSupport.on_load(:active_model_serializers) do
|
|
self.root = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_embed_ids
|
|
serializer = post_serializer
|
|
|
|
serializer.class_eval do
|
|
root :post
|
|
embed :ids
|
|
end
|
|
|
|
post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
|
|
comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
|
|
post.comments = comments
|
|
|
|
serializer = serializer.new(post)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
comment_ids: [1, 2],
|
|
author_id: nil
|
|
}
|
|
}, serializer.as_json)
|
|
end
|
|
|
|
def test_embed_ids_include_true
|
|
serializer_class = post_serializer
|
|
|
|
serializer_class.class_eval do
|
|
root :post
|
|
embed :ids, include: true
|
|
end
|
|
|
|
post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
|
|
comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
|
|
post.comments = comments
|
|
|
|
serializer = serializer_class.new(post)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
comment_ids: [1, 2],
|
|
author_id: nil
|
|
},
|
|
comments: [
|
|
{ title: "Comment1" },
|
|
{ title: "Comment2" }
|
|
],
|
|
authors: []
|
|
}, serializer.as_json)
|
|
|
|
post.author = User.new(id: 1)
|
|
|
|
serializer = serializer_class.new(post)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
comment_ids: [1, 2],
|
|
author_id: 1
|
|
},
|
|
comments: [
|
|
{ title: "Comment1" },
|
|
{ title: "Comment2" }
|
|
],
|
|
authors: [{ first_name: "Jose", last_name: "Valim" }]
|
|
}, serializer.as_json)
|
|
end
|
|
|
|
def test_methods_take_priority_over_associations
|
|
post_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :title
|
|
has_many :comments
|
|
embed :ids
|
|
|
|
def comments
|
|
object.comments[0,1]
|
|
end
|
|
end
|
|
|
|
post = Post.new(title: "My Post")
|
|
comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
|
|
post.comments = comments
|
|
|
|
post.class_eval do
|
|
define_method :comment_ids, lambda {
|
|
self.comments.map { |c| c.read_attribute_for_serialization(:id) }
|
|
}
|
|
end
|
|
json = post_serializer.new(post).as_json
|
|
assert_equal({
|
|
title: "My Post",
|
|
comment_ids: [1]
|
|
}, json)
|
|
end
|
|
|
|
def test_methods_take_priority_over_associations_and_call_the_appropriate_id_method
|
|
comment_serializer = Class.new(ActiveModel::Serializer) do
|
|
def id
|
|
"OMG"
|
|
end
|
|
end
|
|
|
|
post_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :title
|
|
has_many :comments, serializer: comment_serializer
|
|
embed :ids
|
|
|
|
def comments
|
|
object.comments[0,1]
|
|
end
|
|
end
|
|
|
|
post = Post.new(title: "My Post")
|
|
comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
|
|
post.comments = comments
|
|
|
|
post.class_eval do
|
|
define_method :comment_ids, lambda {
|
|
self.comments.map { |c| c.read_attribute_for_serialization(:id) }
|
|
}
|
|
end
|
|
json = post_serializer.new(post).as_json
|
|
assert_equal({
|
|
title: "My Post",
|
|
comment_ids: ["OMG"]
|
|
}, json)
|
|
end
|
|
|
|
def test_embed_objects
|
|
serializer = post_serializer
|
|
|
|
serializer.class_eval do
|
|
root :post
|
|
embed :objects
|
|
end
|
|
|
|
post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
|
|
comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
|
|
post.comments = comments
|
|
|
|
serializer = serializer.new(post)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
author: nil,
|
|
comments: [
|
|
{ title: "Comment1" },
|
|
{ title: "Comment2" }
|
|
]
|
|
}
|
|
}, serializer.as_json)
|
|
end
|
|
|
|
def test_sets_can_be_serialized
|
|
post1 = Post.new(title: "Post1", author: "Author1", id: 1)
|
|
post2 = Post.new(title: "Post2", author: "Author2", id: 2)
|
|
|
|
set = Set.new
|
|
set << post1
|
|
set << post2
|
|
|
|
serializer = set.active_model_serializer.new set, each_serializer: CustomPostSerializer
|
|
|
|
as_json = serializer.as_json
|
|
assert_equal 2, as_json.size
|
|
assert as_json.include?({ title: "Post1" })
|
|
assert as_json.include?({ title: "Post2" })
|
|
end
|
|
|
|
def test_associations_with_as
|
|
posts = [
|
|
Post.new(title: 'First Post', body: 'text'),
|
|
Post.new(title: 'Second Post', body: 'text')
|
|
]
|
|
user = User.new
|
|
|
|
custom_blog = CustomBlog.new
|
|
custom_blog.public_posts = posts
|
|
custom_blog.public_user = user
|
|
|
|
serializer = CustomBlogSerializer.new(custom_blog, scope: { scope: true })
|
|
|
|
assert_equal({
|
|
custom_blog: {
|
|
posts: [
|
|
{title: 'First Post', body: 'text', comments: []},
|
|
{title: 'Second Post', body: 'text', comments: []}
|
|
],
|
|
user: {
|
|
first_name: "Jose",
|
|
last_name: "Valim", ok: true,
|
|
scope: true
|
|
}
|
|
}
|
|
}, serializer.as_json)
|
|
end
|
|
|
|
def test_implicity_detection_for_association_serializers
|
|
implicit_serializer = Class.new(ActiveModel::Serializer) do
|
|
root :custom_blog
|
|
const_set(:UserSerializer, UserSerializer)
|
|
const_set(:PostSerializer, PostSerializer)
|
|
|
|
has_many :public_posts, key: :posts
|
|
has_one :public_user, key: :user
|
|
end
|
|
|
|
posts = [
|
|
Post.new(title: 'First Post', body: 'text', comments: []),
|
|
Post.new(title: 'Second Post', body: 'text', comments: [])
|
|
]
|
|
user = User.new
|
|
|
|
custom_blog = CustomBlog.new
|
|
custom_blog.public_posts = posts
|
|
custom_blog.public_user = user
|
|
|
|
serializer = implicit_serializer.new(custom_blog, scope: { scope: true })
|
|
|
|
assert_equal({
|
|
custom_blog: {
|
|
posts: [
|
|
{title: 'First Post', body: 'text', comments: []},
|
|
{title: 'Second Post', body: 'text', comments: []}
|
|
],
|
|
user: {
|
|
first_name: "Jose",
|
|
last_name: "Valim", ok: true,
|
|
scope: true
|
|
}
|
|
}
|
|
}, serializer.as_json)
|
|
end
|
|
|
|
def test_attribute_key
|
|
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
root :user
|
|
|
|
attribute :first_name, key: :firstName
|
|
attribute :last_name, key: :lastName
|
|
attribute :password
|
|
end
|
|
|
|
serializer = serializer_class.new(User.new)
|
|
|
|
assert_equal({
|
|
user: {
|
|
firstName: "Jose",
|
|
lastName: "Valim",
|
|
password: "oh noes yugive my password"
|
|
}
|
|
}, serializer.as_json)
|
|
end
|
|
|
|
def setup_model
|
|
Class.new do
|
|
class << self
|
|
def columns_hash
|
|
{ "name" => Struct.new(:type).new(:string), "age" => Struct.new(:type).new(:integer) }
|
|
end
|
|
|
|
def reflect_on_association(name)
|
|
case name
|
|
when :posts
|
|
Struct.new(:macro, :name).new(:has_many, :posts)
|
|
when :parent
|
|
Struct.new(:macro, :name).new(:belongs_to, :parent)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_schema
|
|
model = setup_model
|
|
|
|
serializer = Class.new(ActiveModel::Serializer) do
|
|
class << self; self; end.class_eval do
|
|
define_method(:model_class) do model end
|
|
end
|
|
|
|
# Computed attributes (not real columns or associations).
|
|
def can_edit; end
|
|
def can_view; end
|
|
def drafts; end
|
|
|
|
attributes :name, :age, { can_edit: :boolean }, :can_view
|
|
has_many :posts, serializer: Class.new
|
|
has_many :drafts, serializer: Class.new
|
|
has_one :parent, serializer: Class.new
|
|
end
|
|
|
|
assert_equal serializer.schema, {
|
|
attributes: { name: :string, age: :integer, can_edit: :boolean, can_view: nil },
|
|
associations: {
|
|
posts: { has_many: :posts },
|
|
drafts: nil,
|
|
parent: { belongs_to: :parent }
|
|
}
|
|
}
|
|
end
|
|
|
|
def test_schema_with_as
|
|
model = setup_model
|
|
|
|
serializer = Class.new(ActiveModel::Serializer) do
|
|
class << self; self; end.class_eval do
|
|
define_method(:model_class) do model end
|
|
end
|
|
|
|
attributes :name, :age
|
|
has_many :posts, key: :my_posts, serializer: Class.new
|
|
has_one :parent, key: :my_parent, serializer: Class.new
|
|
end
|
|
|
|
assert_equal serializer.schema, {
|
|
attributes: { name: :string, age: :integer },
|
|
associations: {
|
|
my_posts: { has_many: :posts },
|
|
my_parent: { belongs_to: :parent }
|
|
}
|
|
}
|
|
end
|
|
|
|
def test_embed_id_for_has_one
|
|
author_serializer = Class.new(ActiveModel::Serializer)
|
|
|
|
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
embed :ids
|
|
root :post
|
|
|
|
attributes :title, :body
|
|
has_one :author, serializer: author_serializer
|
|
end
|
|
|
|
post_class = Class.new(Model) do
|
|
attr_accessor :author
|
|
end
|
|
|
|
author_class = Class.new(Model)
|
|
|
|
post = post_class.new(title: "New Post", body: "It's a new post!")
|
|
author = author_class.new(id: 5)
|
|
post.author = author
|
|
|
|
hash = serializer_class.new(post)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "It's a new post!",
|
|
author_id: 5
|
|
}
|
|
}, hash.as_json)
|
|
end
|
|
|
|
def test_embed_id_for_has_one_overriding_associated_id
|
|
author_serializer = Class.new(ActiveModel::Serializer) do
|
|
def id
|
|
"OMG"
|
|
end
|
|
end
|
|
|
|
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
embed :ids
|
|
root :post
|
|
|
|
attributes :title, :body
|
|
has_one :author, serializer: author_serializer
|
|
end
|
|
|
|
post_class = Class.new(Model) do
|
|
attr_accessor :author
|
|
end
|
|
|
|
author_class = Class.new(Model)
|
|
|
|
post = post_class.new(title: "New Post", body: "It's a new post!")
|
|
author = author_class.new(id: 5)
|
|
post.author = author
|
|
|
|
hash = serializer_class.new(post)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "It's a new post!",
|
|
author_id: "OMG"
|
|
}
|
|
}, hash.as_json)
|
|
end
|
|
|
|
def test_embed_objects_for_has_one
|
|
author_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :id, :name
|
|
end
|
|
|
|
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
root :post
|
|
|
|
attributes :title, :body
|
|
has_one :author, serializer: author_serializer
|
|
end
|
|
|
|
post_class = Class.new(Model) do
|
|
attr_accessor :author
|
|
end
|
|
|
|
author_class = Class.new(Model)
|
|
|
|
post = post_class.new(title: "New Post", body: "It's a new post!")
|
|
author = author_class.new(id: 5, name: "Tom Dale")
|
|
post.author = author
|
|
|
|
hash = serializer_class.new(post)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "It's a new post!",
|
|
author: { id: 5, name: "Tom Dale" }
|
|
}
|
|
}, hash.as_json)
|
|
end
|
|
|
|
def test_root_provided_in_options
|
|
author_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :id, :name
|
|
end
|
|
|
|
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
root :post
|
|
|
|
attributes :title, :body
|
|
has_one :author, serializer: author_serializer
|
|
end
|
|
|
|
post_class = Class.new(Model) do
|
|
attr_accessor :author
|
|
end
|
|
|
|
author_class = Class.new(Model)
|
|
|
|
post = post_class.new(title: "New Post", body: "It's a new post!")
|
|
author = author_class.new(id: 5, name: "Tom Dale")
|
|
post.author = author
|
|
|
|
assert_equal({
|
|
blog_post: {
|
|
title: "New Post",
|
|
body: "It's a new post!",
|
|
author: { id: 5, name: "Tom Dale" }
|
|
}
|
|
}, serializer_class.new(post, root: :blog_post).as_json)
|
|
|
|
assert_equal({
|
|
title: "New Post",
|
|
body: "It's a new post!",
|
|
author: { id: 5, name: "Tom Dale" }
|
|
}, serializer_class.new(post, root: false).as_json)
|
|
|
|
assert_equal({
|
|
blog_post: {
|
|
title: "New Post",
|
|
body: "It's a new post!",
|
|
author: { id: 5, name: "Tom Dale" }
|
|
}
|
|
}, serializer_class.new(post).as_json(root: :blog_post))
|
|
|
|
assert_equal({
|
|
title: "New Post",
|
|
body: "It's a new post!",
|
|
author: { id: 5, name: "Tom Dale" }
|
|
}, serializer_class.new(post).as_json(root: false))
|
|
end
|
|
|
|
def test_serializer_has_access_to_root_object
|
|
hash_object = nil
|
|
|
|
author_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :id, :name
|
|
|
|
define_method :serializable_hash do
|
|
hash_object = @options[:hash]
|
|
super()
|
|
end
|
|
end
|
|
|
|
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
root :post
|
|
|
|
attributes :title, :body
|
|
has_one :author, serializer: author_serializer
|
|
end
|
|
|
|
post_class = Class.new(Model) do
|
|
attr_accessor :author
|
|
end
|
|
|
|
author_class = Class.new(Model)
|
|
|
|
post = post_class.new(title: "New Post", body: "It's a new post!")
|
|
author = author_class.new(id: 5, name: "Tom Dale")
|
|
post.author = author
|
|
|
|
expected = serializer_class.new(post).as_json
|
|
assert_equal expected, hash_object
|
|
end
|
|
|
|
def test_embed_ids_include_true_with_root
|
|
serializer_class = post_serializer
|
|
|
|
serializer_class.class_eval do
|
|
root :post
|
|
embed :ids, include: true
|
|
has_many :comments, key: :comment_ids, root: :comments
|
|
has_one :author, serializer: DefaultUserSerializer, key: :author_id, root: :author
|
|
end
|
|
|
|
post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
|
|
comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
|
|
post.comments = comments
|
|
|
|
serializer = serializer_class.new(post)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
comment_ids: [1, 2],
|
|
author_id: nil
|
|
},
|
|
comments: [
|
|
{ title: "Comment1" },
|
|
{ title: "Comment2" }
|
|
],
|
|
author: []
|
|
}, serializer.as_json)
|
|
|
|
post.author = User.new(id: 1)
|
|
|
|
serializer = serializer_class.new(post)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post",
|
|
body: "Body of new post",
|
|
comment_ids: [1, 2],
|
|
author_id: 1
|
|
},
|
|
comments: [
|
|
{ title: "Comment1" },
|
|
{ title: "Comment2" }
|
|
],
|
|
author: [{ first_name: "Jose", last_name: "Valim" }]
|
|
}, serializer.as_json)
|
|
end
|
|
|
|
# the point of this test is to illustrate that deeply nested serializers
|
|
# still side-load at the root.
|
|
def test_embed_with_include_inserts_at_root
|
|
tag_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :id, :name
|
|
end
|
|
|
|
comment_serializer = Class.new(ActiveModel::Serializer) do
|
|
embed :ids, include: true
|
|
attributes :id, :body
|
|
has_many :tags, serializer: tag_serializer
|
|
end
|
|
|
|
post_serializer = Class.new(ActiveModel::Serializer) do
|
|
embed :ids, include: true
|
|
attributes :id, :title, :body
|
|
has_many :comments, serializer: comment_serializer
|
|
end
|
|
|
|
post_class = Class.new(Model) do
|
|
attr_accessor :comments
|
|
|
|
define_method :active_model_serializer do
|
|
post_serializer
|
|
end
|
|
end
|
|
|
|
comment_class = Class.new(Model) do
|
|
attr_accessor :tags
|
|
end
|
|
|
|
tag_class = Class.new(Model)
|
|
|
|
post = post_class.new(title: "New Post", body: "NEW POST", id: 1)
|
|
comment1 = comment_class.new(body: "EWOT", id: 1)
|
|
comment2 = comment_class.new(body: "YARLY", id: 2)
|
|
tag1 = tag_class.new(name: "lolcat", id: 1)
|
|
tag2 = tag_class.new(name: "nyancat", id: 2)
|
|
tag3 = tag_class.new(name: "violetcat", id: 3)
|
|
|
|
post.comments = [comment1, comment2]
|
|
comment1.tags = [tag1, tag3]
|
|
comment2.tags = [tag1, tag2]
|
|
|
|
actual = ActiveModel::ArraySerializer.new([post], root: :posts).as_json
|
|
assert_equal({
|
|
posts: [
|
|
{ title: "New Post", body: "NEW POST", id: 1, comment_ids: [1,2] }
|
|
],
|
|
|
|
comments: [
|
|
{ body: "EWOT", id: 1, tag_ids: [1,3] },
|
|
{ body: "YARLY", id: 2, tag_ids: [1,2] }
|
|
],
|
|
|
|
tags: [
|
|
{ name: "lolcat", id: 1 },
|
|
{ name: "violetcat", id: 3 },
|
|
{ name: "nyancat", id: 2 }
|
|
]
|
|
}, actual)
|
|
end
|
|
|
|
def test_can_customize_attributes
|
|
serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :title, :body
|
|
|
|
def title
|
|
object.title.upcase
|
|
end
|
|
end
|
|
|
|
klass = Class.new do
|
|
def read_attribute_for_serialization(name)
|
|
{ title: "New post!", body: "First post body" }[name]
|
|
end
|
|
|
|
def title
|
|
read_attribute_for_serialization(:title)
|
|
end
|
|
|
|
def body
|
|
read_attribute_for_serialization(:body)
|
|
end
|
|
end
|
|
|
|
object = klass.new
|
|
|
|
actual = serializer.new(object, root: :post).as_json
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "NEW POST!",
|
|
body: "First post body"
|
|
}
|
|
}, actual)
|
|
end
|
|
|
|
def test_can_customize_attributes_with_read_attributes
|
|
serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :title, :body
|
|
|
|
def read_attribute_for_serialization(name)
|
|
{ title: "New post!", body: "First post body" }[name]
|
|
end
|
|
end
|
|
|
|
actual = serializer.new(Object.new, root: :post).as_json
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New post!",
|
|
body: "First post body"
|
|
}
|
|
}, actual)
|
|
end
|
|
|
|
def test_active_support_on_load_hooks_fired
|
|
loaded = nil
|
|
ActiveSupport.on_load(:active_model_serializers) do
|
|
loaded = self
|
|
end
|
|
assert_equal ActiveModel::Serializer, loaded
|
|
end
|
|
|
|
def tests_query_attributes_strip_question_mark
|
|
todo = Class.new do
|
|
def overdue?
|
|
true
|
|
end
|
|
|
|
def read_attribute_for_serialization(name)
|
|
send name
|
|
end
|
|
end
|
|
|
|
serializer = Class.new(ActiveModel::Serializer) do
|
|
attribute :overdue?
|
|
end
|
|
|
|
actual = serializer.new(todo.new).as_json
|
|
|
|
assert_equal({
|
|
overdue: true
|
|
}, actual)
|
|
end
|
|
|
|
def tests_query_attributes_allow_key_option
|
|
todo = Class.new do
|
|
def overdue?
|
|
true
|
|
end
|
|
|
|
def read_attribute_for_serialization(name)
|
|
send name
|
|
end
|
|
end
|
|
|
|
serializer = Class.new(ActiveModel::Serializer) do
|
|
attribute :overdue?, key: :foo
|
|
end
|
|
|
|
actual = serializer.new(todo.new).as_json
|
|
|
|
assert_equal({
|
|
foo: true
|
|
}, actual)
|
|
end
|
|
|
|
def tests_can_handle_polymorphism
|
|
email_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :subject, :body
|
|
end
|
|
|
|
email_class = Class.new(Model) do
|
|
def self.to_s
|
|
"Email"
|
|
end
|
|
|
|
define_method :active_model_serializer do
|
|
email_serializer
|
|
end
|
|
end
|
|
|
|
attachment_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :name, :url
|
|
has_one :attachable, polymorphic: true
|
|
end
|
|
|
|
email = email_class.new subject: 'foo', body: 'bar'
|
|
|
|
attachment = Attachment.new name: 'logo.png', url: 'http://example.com/logo.png', attachable: email
|
|
|
|
actual = attachment_serializer.new(attachment, {}).as_json
|
|
|
|
assert_equal({
|
|
name: 'logo.png',
|
|
url: 'http://example.com/logo.png',
|
|
attachable: {
|
|
type: :email,
|
|
email: { subject: 'foo', body: 'bar' }
|
|
}
|
|
}, actual)
|
|
end
|
|
|
|
def test_can_handle_polymoprhic_ids
|
|
email_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :subject, :body
|
|
end
|
|
|
|
email_class = Class.new(Model) do
|
|
def self.to_s
|
|
"Email"
|
|
end
|
|
|
|
define_method :active_model_serializer do
|
|
email_serializer
|
|
end
|
|
end
|
|
|
|
attachment_serializer = Class.new(ActiveModel::Serializer) do
|
|
embed :ids
|
|
attributes :name, :url
|
|
has_one :attachable, polymorphic: true
|
|
end
|
|
|
|
email = email_class.new id: 1
|
|
|
|
attachment = Attachment.new name: 'logo.png', url: 'http://example.com/logo.png', attachable: email
|
|
|
|
actual = attachment_serializer.new(attachment, {}).as_json
|
|
|
|
assert_equal({
|
|
name: 'logo.png',
|
|
url: 'http://example.com/logo.png',
|
|
attachable: {
|
|
type: :email,
|
|
id: 1
|
|
}
|
|
}, actual)
|
|
end
|
|
|
|
def test_polymorphic_associations_are_included_at_root
|
|
email_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :subject, :body, :id
|
|
end
|
|
|
|
email_class = Class.new(Model) do
|
|
def self.to_s
|
|
"Email"
|
|
end
|
|
|
|
define_method :active_model_serializer do
|
|
email_serializer
|
|
end
|
|
end
|
|
|
|
attachment_serializer = Class.new(ActiveModel::Serializer) do
|
|
root :attachment
|
|
embed :ids, include: true
|
|
attributes :name, :url
|
|
has_one :attachable, polymorphic: true
|
|
end
|
|
|
|
email = email_class.new id: 1, subject: "Hello", body: "World"
|
|
|
|
attachment = Attachment.new name: 'logo.png', url: 'http://example.com/logo.png', attachable: email
|
|
|
|
actual = attachment_serializer.new(attachment, {}).as_json
|
|
|
|
assert_equal({
|
|
attachment: {
|
|
name: 'logo.png',
|
|
url: 'http://example.com/logo.png',
|
|
attachable: {
|
|
type: :email,
|
|
id: 1
|
|
}},
|
|
emails: [{
|
|
id: 1,
|
|
subject: "Hello",
|
|
body: "World"
|
|
}]
|
|
}, actual)
|
|
end
|
|
|
|
def test_multiple_polymorphic_associations
|
|
email_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :subject, :body, :id
|
|
end
|
|
|
|
orange_serializer = Class.new(ActiveModel::Serializer) do
|
|
embed :ids, include: true
|
|
|
|
attributes :plu, :id
|
|
has_one :readable, polymorphic: true
|
|
end
|
|
|
|
email_class = Class.new(Model) do
|
|
def self.to_s
|
|
"Email"
|
|
end
|
|
|
|
define_method :active_model_serializer do
|
|
email_serializer
|
|
end
|
|
end
|
|
|
|
orange_class = Class.new(Model) do
|
|
def self.to_s
|
|
"Orange"
|
|
end
|
|
|
|
def readable
|
|
@attributes[:readable]
|
|
end
|
|
|
|
define_method :active_model_serializer do
|
|
orange_serializer
|
|
end
|
|
end
|
|
|
|
attachment_serializer = Class.new(ActiveModel::Serializer) do
|
|
root :attachment
|
|
embed :ids, include: true
|
|
|
|
attributes :name, :url
|
|
|
|
has_one :attachable, polymorphic: true
|
|
has_one :readable, polymorphic: true
|
|
has_one :edible, polymorphic: true
|
|
end
|
|
|
|
email = email_class.new id: 1, subject: "Hello", body: "World"
|
|
orange = orange_class.new id: 1, plu: "3027", readable: email
|
|
|
|
attachment = Attachment.new({
|
|
name: 'logo.png',
|
|
url: 'http://example.com/logo.png',
|
|
attachable: email,
|
|
readable: email,
|
|
edible: orange
|
|
})
|
|
|
|
actual = attachment_serializer.new(attachment, {}).as_json
|
|
|
|
assert_equal({
|
|
emails: [{
|
|
subject: "Hello",
|
|
body: "World",
|
|
id: 1
|
|
}],
|
|
|
|
oranges: [{
|
|
plu: "3027",
|
|
id: 1,
|
|
readable: { type: :email, id: 1 }
|
|
}],
|
|
|
|
attachment: {
|
|
name: 'logo.png',
|
|
url: 'http://example.com/logo.png',
|
|
attachable: { type: :email, id: 1 },
|
|
readable: { type: :email, id: 1 },
|
|
edible: { type: :orange, id: 1 }
|
|
}
|
|
}, actual)
|
|
end
|
|
|
|
def test_raises_an_error_when_a_child_serializer_includes_associations_when_the_source_doesnt
|
|
attachment_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :name
|
|
end
|
|
|
|
fruit_serializer = Class.new(ActiveModel::Serializer) do
|
|
embed :ids, include: true
|
|
has_one :attachment, serializer: attachment_serializer
|
|
attribute :color
|
|
end
|
|
|
|
banana_class = Class.new Model do
|
|
def self.to_s
|
|
'banana'
|
|
end
|
|
|
|
def attachment
|
|
@attributes[:attachment]
|
|
end
|
|
|
|
define_method :active_model_serializer do
|
|
fruit_serializer
|
|
end
|
|
end
|
|
|
|
strawberry_class = Class.new Model do
|
|
def self.to_s
|
|
'strawberry'
|
|
end
|
|
|
|
def attachment
|
|
@attributes[:attachment]
|
|
end
|
|
|
|
define_method :active_model_serializer do
|
|
fruit_serializer
|
|
end
|
|
end
|
|
|
|
smoothie = Class.new do
|
|
attr_reader :base, :flavor
|
|
|
|
def initialize(base, flavor)
|
|
@base, @flavor = base, flavor
|
|
end
|
|
end
|
|
|
|
smoothie_serializer = Class.new(ActiveModel::Serializer) do
|
|
root false
|
|
embed :ids, include: true
|
|
|
|
has_one :base, polymorphic: true
|
|
has_one :flavor, polymorphic: true
|
|
end
|
|
|
|
banana_attachment = Attachment.new({
|
|
name: 'banana_blending.md',
|
|
id: 3,
|
|
})
|
|
|
|
strawberry_attachment = Attachment.new({
|
|
name: 'strawberry_cleaning.doc',
|
|
id: 4
|
|
})
|
|
|
|
banana = banana_class.new color: "yellow", id: 1, attachment: banana_attachment
|
|
strawberry = strawberry_class.new color: "red", id: 2, attachment: strawberry_attachment
|
|
|
|
smoothie = smoothie_serializer.new(smoothie.new(banana, strawberry))
|
|
|
|
assert_raise ActiveModel::Serializer::IncludeError do
|
|
smoothie.as_json
|
|
end
|
|
end
|
|
|
|
def tests_includes_does_not_include_nil_polymoprhic_associations
|
|
post_serializer = Class.new(ActiveModel::Serializer) do
|
|
root :post
|
|
embed :ids, include: true
|
|
has_one :author, polymorphic: true
|
|
attributes :title
|
|
end
|
|
|
|
post = Post.new(title: 'Foo')
|
|
|
|
actual = post_serializer.new(post).as_json
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: 'Foo',
|
|
author: nil
|
|
}
|
|
}, actual)
|
|
end
|
|
|
|
def test_meta_key_serialization
|
|
tag_serializer = Class.new(ActiveModel::Serializer) do
|
|
attributes :name
|
|
end
|
|
|
|
tag_class = Class.new(Model) do
|
|
def name
|
|
@attributes[:name]
|
|
end
|
|
|
|
define_method :active_model_serializer do
|
|
tag_serializer
|
|
end
|
|
end
|
|
|
|
serializable_array = Class.new(Array)
|
|
|
|
array = serializable_array.new
|
|
array << tag_class.new(name: 'Rails')
|
|
array << tag_class.new(name: 'Sinatra')
|
|
|
|
actual = array.active_model_serializer.new(array, root: :tags, meta: {total: 10}).as_json
|
|
|
|
assert_equal({
|
|
meta: {
|
|
total: 10,
|
|
},
|
|
tags: [
|
|
{ name: "Rails" },
|
|
{ name: "Sinatra" },
|
|
]
|
|
}, actual)
|
|
|
|
actual = array.active_model_serializer.new(array, root: :tags, meta: {total: 10}, meta_key: 'meta_object').as_json
|
|
|
|
assert_equal({
|
|
meta_object: {
|
|
total: 10,
|
|
},
|
|
tags: [
|
|
{ name: "Rails" },
|
|
{ name: "Sinatra" },
|
|
]
|
|
}, actual)
|
|
end
|
|
|
|
def test_inheritance_does_not_used_cached_attributes
|
|
parent = Class.new(ActiveModel::Serializer) do
|
|
attributes :title
|
|
end
|
|
|
|
child = Class.new(parent) do
|
|
attributes :body
|
|
end
|
|
|
|
data_class = Class.new do
|
|
attr_accessor :title, :body
|
|
end
|
|
|
|
item = data_class.new
|
|
item.title = "title"
|
|
item.body = "body"
|
|
|
|
2.times do
|
|
assert_equal({title: "title"},
|
|
parent.new(item).attributes)
|
|
assert_equal({body: "body", title: "title"},
|
|
child.new(item).attributes)
|
|
end
|
|
|
|
end
|
|
|
|
def test_scope_name_method
|
|
serializer = Class.new(ActiveModel::Serializer) do
|
|
def has_permission?
|
|
current_user.super_user?
|
|
end
|
|
end
|
|
|
|
user = User.new
|
|
user.superuser = true
|
|
post = Post.new(title: 'Foo')
|
|
|
|
a_serializer = serializer.new(post, scope: user, scope_name: :current_user)
|
|
assert a_serializer.has_permission?
|
|
end
|
|
|
|
def test_only_option_filters_attributes_and_associations
|
|
post = Post.new(title: "New Post", body: "Body of new post")
|
|
comments = [Comment.new(title: "Comment1")]
|
|
post.comments = comments
|
|
|
|
post_serializer = PostSerializer.new(post, only: :title)
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post"
|
|
}
|
|
}, post_serializer.as_json)
|
|
end
|
|
|
|
def test_except_option_filters_attributes_and_associations
|
|
post = Post.new(title: "New Post", body: "Body of new post")
|
|
comments = [Comment.new(title: "Comment1")]
|
|
post.comments = comments
|
|
|
|
post_serializer = PostSerializer.new(post, except: [:body, :comments])
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post"
|
|
}
|
|
}, post_serializer.as_json)
|
|
end
|
|
|
|
def test_only_option_takes_precedence_over_custom_defined_include_methods
|
|
user = User.new
|
|
|
|
post = Post.new(title: "New Post", body: "Body of new post", author: "Sausage King")
|
|
comments = [Comment.new(title: "Comment")]
|
|
post.comments = comments
|
|
|
|
post_serializer = PostWithMultipleConditionalsSerializer.new(post, scope: user, only: :title)
|
|
|
|
# comments enabled
|
|
post.comments_disabled = false
|
|
# superuser - should see author
|
|
user.superuser = true
|
|
|
|
assert_equal({
|
|
post: {
|
|
title: "New Post"
|
|
}
|
|
}, post_serializer.as_json)
|
|
end
|
|
end
|