作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在我的 Rails 应用程序上使用 Pundit 进行授权,我正在对我的请求进行单元测试。
我已经成功测试了该策略,但现在我想验证我的请求是否使用了该策略。
我想以一种通用的方式来做,我可以在任何请求规范中使用它(无论 Controller 、操作和策略如何)。
老实说,在这一点上,我会同意一种说法,即“期望获得授权的任何策略”,适用于所有请求。
对于索引操作(使用策略范围)很容易:
在请求中描述我说
RSpec.describe 'GET /companies', type: :request do
include_context 'invokes policy scope'
end
RSpec.shared_context 'invokes policy scope', shared_context: :metadata do
before do
expect(Pundit).to receive(:policy_scope!) do |user_context, relation|
expect(user_context.user).to eq(user)
expect(user_context.current_group).to eq(group)
relation
end
end
end
authorize
的具体 Controller 是哪个。 .
最佳答案
所以,我有一些评论......
期望( expect
语句)应该在示例( it
)块内,而不是在 before
内堵塞。 before
中的那种东西块是允许语句(例如, allow(ClassX).to receive(:method) { object }
)、无法在测试变量声明中完成的数据修改或请求触发器。见 http://www.betterspecs.org/对于一些例子。 TL;DR,共享上下文不是一种适当的测试方式。
测试使用特定参数调用 policy_scope 的方法是:
# You can put something generic like this in a shared context and then
# define 'params' and 'scoped_result' as let vars in the specs that include
# the shared context
let(:request) { get '/companies' }
let(:params) { user_context or whatever }
let(:scoped_result) { relation }
# By using abstract variable names here, we make this reusable
it 'calls policy scope' do
expect(Pundit).to receive(:policy_scope!).with(params)
request
end
it 'scopes result' do
expect(Pundit.policy_scope!(params)).to eq(scoped_result)
end
before do
# This ensures Pundit.policy_scope!(context) always returns scoped_result
allow(Pundit).to receive(:policy_scope!).with(context) { scoped_result }
end
# Shared context stuff
let(:json) { JSON.parse(response.body) }
let(:headers) { ...define the headers to use across requests...}
before { request }
shared_examples_for 'success' do
it { expect(response).to have_http_status(:success) }
it { expect(json).to eq(expected) } # or something
end
# User spec that includes shared context
include_context 'above stuff'
let(:request) { get '/companies', params: params, headers: headers }
let(:params) { { user_id: user.id } } # or something
let!(:admin_thing) {
...something that should be excluded by the pundit policy used by endpoint...
}
context 'restricted' do
let!(:user) { create :user, :restricted }
let(:expected) { ...stuff scoped to restricted user... }
it_behaves_like 'success'
end
context 'manager' do
let!(:user) { create :user, :manager }
let(:expected) { ...stuff scoped to manager user... }
it_behaves_like 'success'
end
context 'superuser' do
let!(:user) { create :user, :superuser }
let(expected) { ...unscoped stuff visible to super user... }
it_behaves_like 'success'
end
关于ruby-on-rails - 有没有办法在请求规范中模拟 Pundit 政策授权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59758888/
我是一名优秀的程序员,十分优秀!