mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
Add better serialization_scope tests; uncover bug
This commit is contained in:
parent
26b089c881
commit
85658c0230
@ -96,6 +96,8 @@ module ActiveModel
|
||||
_serializer_instance_methods.include?(name)
|
||||
end
|
||||
|
||||
# TODO: Fix load-order failures when different serializer instances define different
|
||||
# scope methods
|
||||
def self._serializer_instance_methods
|
||||
@_serializer_instance_methods ||= (public_instance_methods - Object.public_instance_methods).to_set
|
||||
end
|
||||
|
||||
@ -1,63 +1,221 @@
|
||||
require 'test_helper'
|
||||
require 'pathname'
|
||||
|
||||
class DefaultScopeNameTest < ActionController::TestCase
|
||||
class UserSerializer < ActiveModel::Serializer
|
||||
module SerializationScopeTesting
|
||||
class User < ActiveModelSerializers::Model
|
||||
attr_accessor :id, :name, :admin
|
||||
def admin?
|
||||
current_user.admin
|
||||
end
|
||||
attributes :admin?
|
||||
end
|
||||
|
||||
class UserTestController < ActionController::Base
|
||||
protect_from_forgery
|
||||
|
||||
before_action { request.format = :json }
|
||||
|
||||
def current_user
|
||||
User.new(id: 1, name: 'Pete', admin: false)
|
||||
end
|
||||
|
||||
def render_new_user
|
||||
render json: User.new(id: 1, name: 'Pete', admin: false), serializer: UserSerializer, adapter: :json_api
|
||||
admin
|
||||
end
|
||||
end
|
||||
class Comment < ActiveModelSerializers::Model
|
||||
attr_accessor :id, :body
|
||||
end
|
||||
class Post < ActiveModelSerializers::Model
|
||||
attr_accessor :id, :title, :body, :comments
|
||||
end
|
||||
class PostSerializer < ActiveModel::Serializer
|
||||
attributes :id, :title, :body, :comments
|
||||
|
||||
tests UserTestController
|
||||
def body
|
||||
"The 'scope' is the 'current_user': #{scope == current_user}"
|
||||
end
|
||||
|
||||
def test_default_scope_name
|
||||
get :render_new_user
|
||||
assert_equal '{"data":{"id":"1","type":"users","attributes":{"admin?":false}}}', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
class SerializationScopeNameTest < ActionController::TestCase
|
||||
class AdminUserSerializer < ActiveModel::Serializer
|
||||
def admin?
|
||||
current_admin.admin
|
||||
end
|
||||
attributes :admin?
|
||||
end
|
||||
|
||||
class AdminUserTestController < ActionController::Base
|
||||
protect_from_forgery
|
||||
|
||||
serialization_scope :current_admin
|
||||
before_action { request.format = :json }
|
||||
|
||||
def current_admin
|
||||
User.new(id: 2, name: 'Bob', admin: true)
|
||||
end
|
||||
|
||||
def render_new_user
|
||||
render json: User.new(id: 1, name: 'Pete', admin: false), serializer: AdminUserSerializer, adapter: :json_api
|
||||
end
|
||||
end
|
||||
|
||||
tests AdminUserTestController
|
||||
|
||||
def test_override_scope_name_with_controller
|
||||
get :render_new_user
|
||||
assert_equal '{"data":{"id":"1","type":"users","attributes":{"admin?":true}}}', @response.body
|
||||
def comments
|
||||
if current_user.admin?
|
||||
[Comment.new(id: 1, body: 'Admin')]
|
||||
else
|
||||
[Comment.new(id: 2, body: 'Scoped')]
|
||||
end
|
||||
end
|
||||
|
||||
def json_key
|
||||
'post'
|
||||
end
|
||||
end
|
||||
class PostTestController < ActionController::Base
|
||||
attr_accessor :current_user
|
||||
def render_post_by_non_admin
|
||||
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
||||
render json: new_post, serializer: serializer, adapter: :json
|
||||
end
|
||||
|
||||
def render_post_by_admin
|
||||
self.current_user = User.new(id: 3, name: 'Pete', admin: true)
|
||||
render json: new_post, serializer: serializer, adapter: :json
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def new_post
|
||||
Post.new(id: 4, title: 'Title')
|
||||
end
|
||||
|
||||
def serializer
|
||||
PostSerializer
|
||||
end
|
||||
end
|
||||
class PostViewContextSerializer < PostSerializer
|
||||
def body
|
||||
"The 'scope' is the 'view_context': #{scope == view_context}"
|
||||
end
|
||||
|
||||
def comments
|
||||
if view_context.controller.current_user.admin?
|
||||
[Comment.new(id: 1, body: 'Admin')]
|
||||
else
|
||||
[Comment.new(id: 2, body: 'Scoped')]
|
||||
end
|
||||
end
|
||||
end
|
||||
class DefaultScopeTest < ActionController::TestCase
|
||||
tests PostTestController
|
||||
|
||||
def test_default_serialization_scope
|
||||
assert_equal :current_user, @controller._serialization_scope
|
||||
end
|
||||
|
||||
def test_default_serialization_scope_object
|
||||
assert_equal @controller.current_user, @controller.serialization_scope
|
||||
end
|
||||
|
||||
def test_default_scope_non_admin
|
||||
get :render_post_by_non_admin
|
||||
expected_json = {
|
||||
post: {
|
||||
id: 4,
|
||||
title: 'Title',
|
||||
body: "The 'scope' is the 'current_user': true",
|
||||
comments: [
|
||||
{ id: 2, body: 'Scoped' }
|
||||
]
|
||||
}
|
||||
}.to_json
|
||||
assert_equal expected_json, @response.body
|
||||
end
|
||||
|
||||
def test_default_scope_admin
|
||||
get :render_post_by_admin
|
||||
expected_json = {
|
||||
post: {
|
||||
id: 4,
|
||||
title: 'Title',
|
||||
body: "The 'scope' is the 'current_user': true",
|
||||
comments: [
|
||||
{ id: 1, body: 'Admin' }
|
||||
]
|
||||
}
|
||||
}.to_json
|
||||
assert_equal expected_json, @response.body
|
||||
end
|
||||
end
|
||||
class SerializationScopeTest < ActionController::TestCase
|
||||
class PostViewContextTestController < PostTestController
|
||||
serialization_scope :view_context
|
||||
|
||||
private
|
||||
|
||||
def serializer
|
||||
PostViewContextSerializer
|
||||
end
|
||||
end
|
||||
tests PostViewContextTestController
|
||||
|
||||
def test_defined_serialization_scope
|
||||
assert_equal :view_context, @controller._serialization_scope
|
||||
end
|
||||
|
||||
def test_defined_serialization_scope_object
|
||||
assert_equal @controller.view_context.class, @controller.serialization_scope.class
|
||||
end
|
||||
|
||||
def test_serialization_scope_non_admin
|
||||
get :render_post_by_non_admin
|
||||
expected_json = {
|
||||
post: {
|
||||
id: 4,
|
||||
title: 'Title',
|
||||
body: "The 'scope' is the 'view_context': true",
|
||||
comments: [
|
||||
{ id: 2, body: 'Scoped' }
|
||||
]
|
||||
}
|
||||
}.to_json
|
||||
assert_equal expected_json, @response.body
|
||||
end
|
||||
|
||||
def test_serialization_scope_admin
|
||||
get :render_post_by_admin
|
||||
expected_json = {
|
||||
post: {
|
||||
id: 4,
|
||||
title: 'Title',
|
||||
body: "The 'scope' is the 'view_context': true",
|
||||
comments: [
|
||||
{ id: 1, body: 'Admin' }
|
||||
]
|
||||
}
|
||||
}.to_json
|
||||
assert_equal expected_json, @response.body
|
||||
end
|
||||
end
|
||||
class NilSerializationScopeTest < ActionController::TestCase
|
||||
class PostViewContextTestController < ActionController::Base
|
||||
serialization_scope nil
|
||||
|
||||
attr_accessor :current_user
|
||||
|
||||
def render_post_with_no_scope
|
||||
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
||||
render json: new_post, serializer: PostSerializer, adapter: :json
|
||||
end
|
||||
|
||||
# TODO: run test when
|
||||
# global state in Serializer._serializer_instance_methods is fixed
|
||||
# def render_post_with_passed_in_scope
|
||||
# self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
||||
# render json: new_post, serializer: PostSerializer, adapter: :json, scope: current_user, scope_name: :current_user
|
||||
# end
|
||||
|
||||
private
|
||||
|
||||
def new_post
|
||||
Post.new(id: 4, title: 'Title')
|
||||
end
|
||||
end
|
||||
tests PostViewContextTestController
|
||||
|
||||
def test_nil_serialization_scope
|
||||
assert_nil @controller._serialization_scope
|
||||
end
|
||||
|
||||
def test_nil_serialization_scope_object
|
||||
assert_nil @controller.serialization_scope
|
||||
end
|
||||
|
||||
# TODO: change to NoMethodError and match 'admin?' when the
|
||||
# global state in Serializer._serializer_instance_methods is fixed
|
||||
def test_nil_scope
|
||||
exception = assert_raises(NameError) do
|
||||
get :render_post_with_no_scope
|
||||
end
|
||||
assert_match(/admin|current_user/, exception.message)
|
||||
end
|
||||
|
||||
# TODO: run test when
|
||||
# global state in Serializer._serializer_instance_methods is fixed
|
||||
# def test_nil_scope_passed_in_current_user
|
||||
# get :render_post_with_passed_in_scope
|
||||
# expected_json = {
|
||||
# post: {
|
||||
# id: 4,
|
||||
# title: 'Title',
|
||||
# body: "The 'scope' is the 'current_user': true",
|
||||
# comments: [
|
||||
# { id: 2, body: 'Scoped' }
|
||||
# ]
|
||||
# }
|
||||
# }.to_json
|
||||
# assert_equal expected_json, @response.body
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user