如何解决Rails 专家用户范围 Minitest 将无法运行
在我的应用程序中,只有 status == 'active'
的用户才能访问所有应用程序页面。我已经为该操作创建了一个范围策略和一个单独的中间控制器,我在其中设置了所有全局策略。如下:
class UserPolicy < ApplicationPolicy
class Scope < Scope
def resolve
return raise(Pundit::NotAuthorizedError) unless user.status == 'active'
scope.all
end
end
end
class BaseController < ApplicationController
before_action :authorized_user
rescue_from Pundit::NotAuthorizedError,with: :user_not_authorized
def authorized_user
policy_scope(current_user)
end
private
def user_not_authorized
flash[:alert] = 'You are not authorized to perform this action.'
redirect_to(request.referrer || root_path)
end
end
现在我想为这个范围策略做一个 MiniTest。这就是我所拥有的:
需要'test_helper'
class UserPolicyTest < ActiveSupport::TestCase
context 'when user is active' do
def setup
@user = user(:active)
@properties = properties(:one)
end
def scope_test
# user should have access to the show page in properties controller
refute_equal properties,user
assert permit(user,properties,:show)
end
end
end
我错过了什么?当我运行它时,它会告诉我:
Finished in 0.185689s,0.0000 runs/s,0.0000 assertions/s.
0 runs,0 assertions,0 failures,0 errors,0 skips
解决方法
你完全倒退了。控制整体访问权限不是范围的工作。
class ApplicationPolicy
class Scope
def resolve
@user.active?
scope.all
else
scope.none
end
end
end
# ...
def show?
@user.active?
end
def index?
@user.active?
end
private
def active?
user.active? # user.status == 'active' is iffy. Don't let the logic leak outside of the object
end
end
如果您想授权控制器的操作,您可以这样做:
def show
authorize(Thing.find(params[:id]))
end
def index
authorize(Thing) # controlls overall access - often skipped
@things = policy_scope(Thing)
end
如果你真的想给 show 方法添加一个作用域,你可以这样做:
def show
authorize(policy_scope(Thing).find(params[:id]))
end
您的范围不应该控制整体访问的原因是不知道上下文(调用哪个操作)。因此,虽然这现在可能“有效”,但当事情变得更复杂时,它会在你面前炸开。
如果你想测试一个特定的策略,你会这样做:
assert ThingPolicy.new(thing,user).show?
如果要测试范围,请解析范围并测试是否包含/不包含预期记录。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。