我刚开始在当前的项目中使用Pundit进行授权以及权威匹配宝石。
到目前为止,它似乎通常对我有用,但我的测试中存在问题。
我一般都试图按照pundit-matchers readme和Thunderbolt实验室博客(http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/)中的示例进行操作。
这是我的政策文件;
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null &&
data.getExtras() != null) {
String accountName =
data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
Log.e("ghfyg",""+accountName);
if (accountName != null) {
mCredential.setSelectedAccountName(accountName);
SharedPreferences settings =
AccountSync.this.getSharedPreferences("deep",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString("PREF_ACCOUNT_NAME", accountName);
editor.apply();
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this,"Account unspecified.",Toast.LENGTH_SHORT).show();
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
这是我的policy_spec文件
#app/policies/procedure_policy.rb
class ProcedurePolicy
attr_reader :user, :procedure
def initialize(user, procedure)
@user = user
@procedure = procedure
end
def index?
user.admin?
end
end
我的3次测试中有2次通过; require 'rails_helper'
describe ProcedurePolicy do
subject {described_class.new(user, procedure)}
let(:procedure) {FactoryGirl.create(:procedure)}
context "for a guest" do
let(:user) {nil}
it {is_expected.not_to permit_action(:index)}
end
context "for a non-admin user" do
let(:user) {FactoryGirl.create(:user)}
it {is_expected.not_to permit_action(:index)}
end
context "for an admin user" do
let(:user) {FactoryGirl.create(:admin_user)}
it {is_expected.to permit_action(:index)}
end
end
和"for a non-admin user"
个。 "for an admin user"
测试失败,
"for a guest"
现在我明白了为什么。我将NoMethodError:
undefined method `admin?' for nil:NilClass
传递给了我的ProcedurePolicy类的nil
方法,该方法没有#index?
方法。但我在网上找到的所有示例规范都是这样做的。我没看到什么。
如果我错过了一些非常明显的东西,我会道歉。我已经远离编码几年了。
答案 0 :(得分:1)
"作为访客" context用于在系统中当前没有用户进行身份验证时测试授权尝试。由于没有用户登录,因此不存在用户记录/对象 - 用户对象的缺席为nil
。这就是Thunderbolt Labs和pundit-matchers示例使用nil来代表访问者的原因。 nil
对象没有admin?
方法,导致错误。
要在策略中正确处理nil / guest用户,请在检查用户是否为admin之前检查用户对象是否存在,方法是直接检查用户对象或使用Rails中的present?
方法,例如
def index?
user.present? && user.admin?
end
或只是:
def index?
user && user.admin?
end
当没有用户登录时,您会发现诸如Devise之类的身份验证系统从nil
方法返回current_user
。