aboutsummaryrefslogblamecommitdiffstats
path: root/activemodel/test/cases/serializer_test.rb
blob: 2b2e21540fa929442a880ad02a0bcb6e34ecf41a (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

    def initialize(hash={})
      @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
  end

  class Post < Model
    attr_accessor :comments
    def active_model_serializer; PostSerializer; end
  end

  class Comment < Model
    def active_model_serializer; CommentSerializer; end
  end

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

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

  class DefaultUserSerializer < ActiveModel::Serializer
    attributes :first_name, :last_name
  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 = 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, {})

    hash = user_serializer.as_json

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

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

    hash = user_serializer.as_json

    assert_equal({
      :user => {
        :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
    comments = Comment.new(:title => "Comment1", :id => 1)

    array = [model, user, comments]
    serializer = array.active_model_serializer.new(array, {:scope => true})
    assert_equal([
      { :model => "Model" },
      { :user => { :last_name=>"Valim", :ok=>true, :first_name=>"Jose", :scope => true } },
      { :comment => { :title => "Comment1" } }
    ], serializer.as_json)
  end
end