-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add better serialization_scope tests; uncover bug
- Loading branch information
Showing
2 changed files
with
195 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
228 changes: 193 additions & 35 deletions
228
test/action_controller/serialization_scope_name_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
admin | ||
end | ||
attributes :admin? | ||
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 | ||
|
||
class UserTestController < ActionController::Base | ||
protect_from_forgery | ||
|
||
before_action { request.format = :json } | ||
def body | ||
"The 'scope' is the 'current_user': #{scope == current_user}" | ||
end | ||
|
||
def current_user | ||
User.new(id: 1, name: 'Pete', admin: false) | ||
def comments | ||
if current_user.admin? | ||
[Comment.new(id: 1, body: 'Admin')] | ||
else | ||
[Comment.new(id: 2, body: 'Scoped')] | ||
end | ||
end | ||
|
||
def render_new_user | ||
render json: User.new(id: 1, name: 'Pete', admin: false), serializer: UserSerializer, adapter: :json_api | ||
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 | ||
|
||
tests UserTestController | ||
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 test_default_scope_name | ||
get :render_new_user | ||
assert_equal '{"data":{"id":"1","type":"users","attributes":{"admin?":false}}}', @response.body | ||
def new_post | ||
Post.new(id: 4, title: 'Title') | ||
end | ||
|
||
def serializer | ||
PostSerializer | ||
end | ||
end | ||
end | ||
class PostViewContextSerializer < PostSerializer | ||
def body | ||
"The 'scope' is the 'view_context': #{scope == view_context}" | ||
end | ||
|
||
class SerializationScopeNameTest < ActionController::TestCase | ||
class AdminUserSerializer < ActiveModel::Serializer | ||
def admin? | ||
current_admin.admin | ||
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 | ||
attributes :admin? | ||
end | ||
class SerializationScopeTest < ActionController::TestCase | ||
class PostViewContextTestController < PostTestController | ||
serialization_scope :view_context | ||
|
||
private | ||
|
||
def serializer | ||
PostViewContextSerializer | ||
end | ||
end | ||
tests PostViewContextTestController | ||
|
||
class AdminUserTestController < ActionController::Base | ||
protect_from_forgery | ||
def test_defined_serialization_scope | ||
assert_equal :view_context, @controller._serialization_scope | ||
end | ||
|
||
serialization_scope :current_admin | ||
before_action { request.format = :json } | ||
def test_defined_serialization_scope_object | ||
assert_equal @controller.view_context.class, @controller.serialization_scope.class | ||
end | ||
|
||
def current_admin | ||
User.new(id: 2, name: 'Bob', admin: true) | ||
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 render_new_user | ||
render json: User.new(id: 1, name: 'Pete', admin: false), serializer: AdminUserSerializer, adapter: :json_api | ||
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 | ||
|
||
tests AdminUserTestController | ||
# 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 | ||
|
||
def test_override_scope_name_with_controller | ||
get :render_new_user | ||
assert_equal '{"data":{"id":"1","type":"users","attributes":{"admin?":true}}}', @response.body | ||
# 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 |