我有一个多租户SaaS应用。我对每个租户模型进行租户安全测试。
describe 'tenant security' do
it "has only the current company's data" do
set_tenant_company
other_companys_data = create :model
set_tenant_company
this_companys_data = create :model
expect(Model.all).to include this_companys_data
expect(Model.all).not_to include other_companys_data
end
end
有没有办法使用元编程在每个模型上运行它? [没有明确地将任何内容编码到单元测试中]如果是这样,是否有办法将非租户模型列入白名单?
租户安全至关重要,我不想忽视它。
答案 0 :(得分:0)
根据Pedro的评论,他的问题发布在RSpec核心团队:
使用您希望隐式包含在每个模型中的测试创建一个共享示例。 :除非条件适用于不应包含此测试的白名单模型。
RSpec.shared_examples 'a tenant model' do
it "has only the current company's data",unless: metadata[:not_a_tenant_model] == true do
set_tenant_company
other_companys_data = create subject.class.name.underscore.to_sym
set_tenant_company
this_companys_data = create subject.class.name.underscore.to_sym
expect(subject.class.all).to include this_companys_data
expect(subject.class.all).not_to include other_companys_data
end
end
将以下行放在RSpec.configuration
中RSpec.configure do |config|
config.include_context 'a tenant model', type: :model
end
这具有在每个模型中放置以下内容的效果。
Rspec.describe TenantModel do
it_behaves_like 'a tenant model'
end
要将非租户模型列入白名单,只需添加相应的标记:
RSpec.decribe NonTenantModel, :not_a_tenant_model do
# shared example will not be included
end
非常感谢你!佩德罗和RSpec核心团队。
答案 1 :(得分:0)
当前接受的解决方案需要特定地标记每个非租户模型。使用此解决方案,您可以在配置中执行此操作。
好吧,感谢您打开这个问题:https://github.com/rspec/rspec-core/issues/2480,这似乎是您案例的最佳解决方案:
non_tenant_models = %w(NonTenantModelOne NonTenantModelTwo).map(&:constantize)
RSpec.configure do |c|
c.define_derived_metadata(type: :model) do |meta|
meta[:tenant_model] = true unless meta[:described_class].presence_in non_tenant_models
end
c.include_context "shared", tenant_model: true
end
这为您提供了清晰的元数据,说明模型是否为租户,并将指定运行共享示例的每个非租户模型列入白名单,而无需在模型中编写任何代码。