Fix read_attribute_for_serialization not seeing parent serializer methods

Fixes #1653, #1658, #1660

Define "scope_name" on instance singleton, not all instances
This commit is contained in:
Benjamin Fleischer
2016-04-04 11:01:01 -05:00
parent 0e82f6b5c0
commit 6370e5c72a
4 changed files with 84 additions and 41 deletions

View File

@@ -1,17 +1,6 @@
require 'test_helper'
module SerializationScopeTesting
def self.undef_serializer_dynamic_scope_methods
[PostSerializer, PostViewContextSerializer]. each do |serializer_class|
instance_method_cache = serializer_class.instance_variable_get(:@_serializer_instance_methods)
class_method_cache = serializer_class.class_variable_get(:@@_serializer_instance_methods)[serializer_class]
[:view_context, :current_user].each do |scope_method|
serializer_class.send(:undef_method, scope_method) if serializer_class.method_defined?(scope_method)
instance_method_cache && instance_method_cache.delete(scope_method)
class_method_cache && class_method_cache.delete(scope_method)
end
end
end
class User < ActiveModelSerializers::Model
attr_accessor :id, :name, :admin
def admin?
@@ -81,10 +70,6 @@ module SerializationScopeTesting
class DefaultScopeTest < ActionController::TestCase
tests PostTestController
teardown do
SerializationScopeTesting.undef_serializer_dynamic_scope_methods
end
def test_default_serialization_scope
assert_equal :current_user, @controller._serialization_scope
end
@@ -135,10 +120,6 @@ module SerializationScopeTesting
end
tests PostViewContextTestController
teardown do
SerializationScopeTesting.undef_serializer_dynamic_scope_methods
end
def test_defined_serialization_scope
assert_equal :view_context, @controller._serialization_scope
end
@@ -206,10 +187,6 @@ module SerializationScopeTesting
end
tests PostViewContextTestController
teardown do
SerializationScopeTesting.undef_serializer_dynamic_scope_methods
end
def test_nil_serialization_scope
assert_nil @controller._serialization_scope
end

View File

@@ -0,0 +1,79 @@
require 'test_helper'
module ActiveModel
class Serializer
class ReadAttributeForSerializationTest < ActiveSupport::TestCase
# https://github.com/rails-api/active_model_serializers/issues/1653
class Parent < ActiveModelSerializers::Model
attr_accessor :id
end
class Child < Parent
attr_accessor :name
end
class ParentSerializer < ActiveModel::Serializer
attributes :$id
define_method(:$id) do
object.id
end
end
class ChildSerializer < ParentSerializer
attributes :name
end
def test_child_serializer_calls_dynamic_method_in_parent_serializer
parent = ParentSerializer.new(Parent.new(id: 5))
child = ChildSerializer.new(Child.new(id: 6, name: 'Child'))
assert_equal 5, parent.read_attribute_for_serialization(:$id)
assert_equal 6, child.read_attribute_for_serialization(:$id)
end
# https://github.com/rails-api/active_model_serializers/issues/1658
class ErrorResponse < ActiveModelSerializers::Model
attr_accessor :error
end
class ApplicationSerializer < ActiveModel::Serializer
attributes :status
def status
object.try(:errors).blank? && object.try(:error).blank?
end
end
class ErrorResponseSerializer < ApplicationSerializer
attributes :error
end
class ErrorResponseWithSuperSerializer < ApplicationSerializer
attributes :error
def success
super
end
end
def test_child_serializer_with_error_attribute
error = ErrorResponse.new(error: 'i have an error')
serializer = ErrorResponseSerializer.new(error)
serializer_with_super = ErrorResponseWithSuperSerializer.new(error)
assert_equal false, serializer.read_attribute_for_serialization(:status)
assert_equal false, serializer_with_super.read_attribute_for_serialization(:status)
end
def test_child_serializer_with_errors
error = ErrorResponse.new
error.errors.add(:invalid, 'i am not valid')
serializer = ErrorResponseSerializer.new(error)
serializer_with_super = ErrorResponseWithSuperSerializer.new(error)
assert_equal false, serializer.read_attribute_for_serialization(:status)
assert_equal false, serializer_with_super.read_attribute_for_serialization(:status)
end
def test_child_serializer_no_error_attribute_or_errors
error = ErrorResponse.new
serializer = ErrorResponseSerializer.new(error)
serializer_with_super = ErrorResponseWithSuperSerializer.new(error)
assert_equal true, serializer.read_attribute_for_serialization(:status)
assert_equal true, serializer_with_super.read_attribute_for_serialization(:status)
end
end
end
end