我正在关注Ruby on Rails 教程,现在我需要为授权代码编写测试,例如确保用户只能编辑他们自己的配置文件。
有两个动作要测试。一是确保用户无法访问编辑其他用户个人资料的页面。这很简单,在水豚中进行了简单的“功能”测试。
但我当然也想测试 PUT 操作,这样用户就无法绕过编辑页面手动提交 PUT 请求。根据我的阅读,这应该作为 rspec“请求”测试来完成。
现在我的问题是,我必须在不同的目录中维护它们吗?(规格/功能与规格/请求)?这听起来不对,因为这两个场景密切相关。在 Rails 中通常如何进行此类测试?
例如,
describe "as wrong user" do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
before { sign_in user }
describe "visiting Users#edit page" do
before { visit edit_user_path(wrong_user) }
it { should_not have_selector('title', text: full_title('Edit user')) }
end
describe "submitting a PUT request to the Users#update action" do
before { put user_path(wrong_user) }
specify { response.should redirect_to(root_path) }
end
end
第二个测试在 capybara 2.x 中不起作用,因为不再支持“put”。它必须是请求测试。现在我必须编写第二个“sign_in”方法,因为当前使用的方法仅可用于功能测试。闻起来像很多代码重复。
========我的解决方案========
在弄清楚如何登录请求测试后,感谢 Paul Fioravanti 的回答,
before do
post sessions_path, email: user.email, password: user.password
cookies[:remember_token] = user.remember_token
end
我将所有测试更改为请求测试。所以我不必将它们分成不同的文件。尽管我认为这更清洁,但保罗的解决方案也可以使用。
describe 'authorization' do
describe 'as un-signed-in user' do
let(:user) { FactoryGirl.create(:user) }
describe 'getting user edit page' do
before { get edit_user_path(user) }
specify { response.should redirect_to(signin_path) }
end
describe 'putting to user update page' do
before { put user_path(user) }
specify { response.should redirect_to(signin_path) }
end
end
describe 'as wrong user' do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: 'wrong@example.com') }
before do
post sessions_path, email: user.email, password: user.password
cookies[:remember_token] = user.remember_token
end
describe 'getting user edit page' do
before { get edit_user_path(wrong_user) }
specify { response.should redirect_to(root_path) }
end
describe 'putting to user update page' do
before { put user_path(wrong_user) }
specify { response.should redirect_to(root_path) }
end
end
end