aboutsummaryrefslogblamecommitdiffstats
path: root/activemodel/test/cases/serializer_test.rb
blob: e99b3692ecafddb8c15e26ad1e42b5306dee52b9 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11


                                            
             
                           





                                              



                           

     


                                     
                            
                                   
 
                           





                                                                                                                       

       


                   



                                
     
 




                           








                                                 
                         






                                                  
                         





                                                                   





                                       
                                                                     


               
                                       







                                                        





                                                   


                                                               







                                                   


                                                                             







                                                                 







                              








                                                     




                                                                         
     










                                                                                                             







                                    
















                                                    




                                                 




                                























                                                             
     







                                                             



                     

                     












                                                  





                                                          





                                           

























                                                                                                             
                                                          




















                                                                                                             






                                                 
                                 


                                             

                




                                         


























                                                                                        

                                                                        











































































                                                                                                             











































                                                                                                                 
require "cases/helper"

class SerializerTest < ActiveModel::TestCase
  class Model
    def initialize(hash={})
      @attributes = hash
    end

    def read_attribute_for_serialization(name)
      @attributes[name]
    end

    def as_json(*)
      { :model => "Model" }
    end
  end

  class User
    include ActiveModel::Serializable

    attr_accessor :superuser
    attr_writer   :model_serializer

    def initialize(hash={})
      @model_serializer = nil
      @attributes = hash.merge(:first_name => "Jose", :last_name => "Valim", :password => "oh noes yugive my password")
    end

    def read_attribute_for_serialization(name)
      @attributes[name]
    end

    def super_user?
      @superuser
    end

    def model_serializer
      @model_serializer || super
    end
  end

  class Post < Model
    attr_accessor :comments
  end

  class Comment < Model
  end

  class UserSerializer < ActiveModel::Serializer
    attributes :first_name, :last_name
  end

  class User2Serializer < ActiveModel::Serializer
    attributes :first_name, :last_name

    def serializable_hash
      attributes.merge(:ok => true).merge(scope)
    end
  end

  class MyUserSerializer < ActiveModel::Serializer
    attributes :first_name, :last_name

    def serializable_hash
      hash = attributes
      hash = hash.merge(:super_user => true) if my_user.super_user?
      hash
    end
  end

  class CommentSerializer
    def initialize(comment, scope)
      @comment, @scope = comment, scope
    end

    def serializable_hash
      { :title => @comment.read_attribute_for_serialization(:title) }
    end

    def as_json
      { :comment => serializable_hash }
    end
  end

  class PostSerializer < ActiveModel::Serializer
    attributes :title, :body
    has_many :comments, :serializer => CommentSerializer
  end

  def test_attributes
    user = User.new
    user_serializer = UserSerializer.new(user, nil)

    hash = user_serializer.as_json

    assert_equal({
      :user => { :first_name => "Jose", :last_name => "Valim" }
    }, hash)
  end

  def test_attributes_method
    user = User.new
    user_serializer = User2Serializer.new(user, {})

    hash = user_serializer.as_json

    assert_equal({
      :user2 => { :first_name => "Jose", :last_name => "Valim", :ok => true }
    }, hash)
  end

  def test_serializer_receives_scope
    user = User.new
    user_serializer = User2Serializer.new(user, {:scope => true})

    hash = user_serializer.as_json

    assert_equal({
      :user2 => {
        :first_name => "Jose",
        :last_name => "Valim",
        :ok => true,
        :scope => true
      }
    }, hash)
  end

  def test_pretty_accessors
    user = User.new
    user.superuser = true
    user_serializer = MyUserSerializer.new(user, nil)

    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, user)

    assert_equal({
      :post => {
        :title => "New Post",
        :body => "Body of new post",
        :comments => [
          { :title => "Comment1" },
          { :title => "Comment2" }
        ]
      }
    }, post_serializer.as_json)
  end

  class Blog < Model
    attr_accessor :author
  end

  class AuthorSerializer < ActiveModel::Serializer
    attributes :first_name, :last_name
  end

  class BlogSerializer < ActiveModel::Serializer
    has_one :author, :serializer => AuthorSerializer
  end

  def test_has_one
    user = User.new
    blog = Blog.new
    blog.author = user

    json = BlogSerializer.new(blog, user).as_json
    assert_equal({
      :blog => {
        :author => {
          :first_name => "Jose",
          :last_name => "Valim"
        }
      }
    }, json)
  end

  def test_implicit_serializer
    author_serializer = Class.new(ActiveModel::Serializer) do
      attributes :first_name
    end

    blog_serializer = Class.new(ActiveModel::Serializer) do
      const_set(:AuthorSerializer, author_serializer)
      has_one :author
    end

    user = User.new
    blog = Blog.new
    blog.author = user

    json = blog_serializer.new(blog, user).as_json
    assert_equal({
      :author => {
        :first_name => "Jose"
      }
    }, json)
  end

  def test_overridden_associations
    author_serializer = Class.new(ActiveModel::Serializer) do
      attributes :first_name
    end

    blog_serializer = Class.new(ActiveModel::Serializer) do
      const_set(:PersonSerializer, author_serializer)

      def person
        object.author
      end

      has_one :person
    end

    user = User.new
    blog = Blog.new
    blog.author = user

    json = blog_serializer.new(blog, user).as_json
    assert_equal({
      :person => {
        :first_name => "Jose"
      }
    }, json)
  end

  def post_serializer(type)
    Class.new(ActiveModel::Serializer) do
      attributes :title, :body
      has_many :comments, :serializer => CommentSerializer

      if type != :super
        define_method :serializable_hash do
          post_hash = attributes
          post_hash.merge!(send(type))
          post_hash
        end
      end
    end
  end

  def test_associations
    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

    serializer = post_serializer(:associations).new(post, nil)

    assert_equal({
      :title => "New Post",
      :body => "Body of new post",
      :comments => [
        { :title => "Comment1" },
        { :title => "Comment2" }
      ]
    }, serializer.as_json)
  end

  def test_association_ids
    serializer = post_serializer(:association_ids)

    serializer.class_eval do
      def as_json(*)
        { :post => serializable_hash }.merge(associations)
      end
    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, nil)

    assert_equal({
      :post => {
        :title => "New Post",
        :body => "Body of new post",
        :comments => [1, 2]
      },
      :comments => [
        { :title => "Comment1" },
        { :title => "Comment2" }
      ]
    }, serializer.as_json)
  end

  def test_associations_with_nil_association
    user = User.new
    blog = Blog.new

    json = BlogSerializer.new(blog, user).as_json
    assert_equal({
      :blog => { :author => nil }
    }, json)

    serializer = Class.new(BlogSerializer) do
      root :blog

      def serializable_hash
        attributes.merge(association_ids)
      end
    end

    json = serializer.new(blog, 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, user).as_json)
  end

  def test_false_root
    user = User.new
    blog = Blog.new

    serializer = Class.new(BlogSerializer) do
      root false
    end

    assert_equal({ :author => nil }, serializer.new(blog, user).as_json)

    # test inherited false root
    serializer = Class.new(serializer)
    assert_equal({ :author => nil }, serializer.new(blog, user).as_json)
  end

  def test_embed_ids
    serializer = post_serializer(:super)

    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, nil)

    assert_equal({
      :post => {
        :title => "New Post",
        :body => "Body of new post",
        :comments => [1, 2]
      }
    }, serializer.as_json)
  end

  def test_embed_ids_include_true
    serializer = post_serializer(:super)

    serializer.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.new(post, nil)

    assert_equal({
      :post => {
        :title => "New Post",
        :body => "Body of new post",
        :comments => [1, 2]
      },
      :comments => [
        { :title => "Comment1" },
        { :title => "Comment2" }
      ]
    }, serializer.as_json)
  end

  def test_embed_objects
    serializer = post_serializer(:super)

    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, nil)

    assert_equal({
      :post => {
        :title => "New Post",
        :body => "Body of new post",
        :comments => [
          { :title => "Comment1" },
          { :title => "Comment2" }
        ]
      }
    }, serializer.as_json)
  end

  def test_array_serializer
    model    = Model.new
    user     = User.new
    post     = Post.new(:title => "New Post", :body => "Body of new post", :email => "tenderlove@tenderlove.com")
    comments = Comment.new(:title => "Comment1", :id => 1)
    post.comments = []

    array = [model, post, comments]
    serializer = ActiveModel::Serializer::Finder.find(array, user).new(array, user)
    assert_equal([
      { :model => "Model" },
      { :post => { :body => "Body of new post", :comments => [], :title => "New Post" } },
      { :comment => { :title => "Comment1" } }
    ], serializer.as_json)
  end

  def test_array_serializer_respects_model_serializer
    user = User.new(:first_name => "Jose", :last_name => "Valim")
    user.model_serializer = User2Serializer

    array = [user]
    serializer = ActiveModel::Serializer::Finder.find(array, user).new(array, {})
    assert_equal([
      { :user2 => { :last_name => "Valim", :first_name => "Jose", :ok => true } },
    ], serializer.as_json)
  end

  def test_finder_respects_model_serializer
    user = User.new(:first_name => "Jose", :last_name => "Valim")
    assert_equal UserSerializer, user.model_serializer

    serializer = ActiveModel::Serializer::Finder.find(user, self).new(user, {})
    assert_equal({
      :user => { :last_name => "Valim", :first_name => "Jose"},
    }, serializer.as_json)

    user.model_serializer = User2Serializer
    serializer = ActiveModel::Serializer::Finder.find(user, self).new(user, {})
    assert_equal({
      :user2 => { :last_name => "Valim", :first_name => "Jose", :ok => true },
    }, serializer.as_json)
  end
end