这开始是我在rails教程中无法解决的问题,但此时我想了解最新情况,如果可以,我应该能够在教程中解决我的问题。< / p>
我的问题归结为此。我试图在测试中设置一个cookie,然后在执行put之后在控制器中检查它的值,但是我没有在控制器中看到cookie。
以下是测试中的代码:
describe "as wrong user" do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
before do
puts "setting up test - set remeber_token"
cookies['remember_token'] = user.remember_token
puts "cookies['remember_token'] = #{cookies['remember_token']}"
end
describe "submitting a PUT request to the Users#update action" do
before do
puts "in test "
puts "cookies['remember_token'] = #{cookies['remember_token']}"
put user_path(wrong_user)
end
specify { response.should redirect_to(root_url) }
end
end
这里是控制器中的代码(我认为这是相关的)
before_filter :signed_in_user, only: [:edit, :update]
before_filter :correct_user, only: [:edit, :update]
def signed_in_user
puts "in signed_in_user filter"
puts "cookies['remember_token'] = #{cookies['remember_token']}"
redirect_to signin_url, notice: "Please sign in." unless signed_in?
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
当我运行测试时,输出似乎表明cookie已在测试中设置但在之前的过滤器中消失了。测试最终失败,因为signed_in?
方法应该查看用户是否存在从cookies对象检索到的remember_token,即nil。有人可以解释这里发生了什么吗?
这是控制台输出:
>bundle exec rspec spec/requests/authentication_pages_spec.rb -e "submitting a PUT request to the Users#update action"
Run options: include {:full_description=>/submitting\ a\ PUT\ request\ to\ the\ Users\#update\ action/}
setting up test - set remeber_token
cookies['remember_token'] = qpcZCCuhaoBirjWR9s5YMw
in test
cookies['remember_token'] = qpcZCCuhaoBirjWR9s5YMw
in signed_in_user filter
cookies['remember_token'] =
F
Failures:
1) Authentication authorization as wrong user submitting a PUT request to the Users#update action
Failure/Error: specify { response.should redirect_to(root_url) }
Expected response to be a redirect to <"http://www.example.com/"> but was a redirect to <"http://www.example.com/signin">
# ./spec/requests/authentication_pages_spec.rb:84:in `block (5 levels) in <top (required)>'
Finished in 0.34502 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/requests/authentication_pages_spec.rb:84 # Authentication authorization as wrong user submitting a PUT request to the Users#update action
更新: 我尝试使用request.cookies ['remember_token']在测试中设置cookie并在之前的过滤器中检索,我遇到了同样的问题。
基本上我有这个:
describe "as wrong user" do
describe "in the Users controller" do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
before do
puts "setting up test - set remeber_token"
get root_url
request.cookies['remember_token'] = user.remember_token
puts "cookies['remember_token'] = #{request.cookies['remember_token']}"
end
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 do
puts "in test "
puts "cookies['remember_token'] = #{request.cookies['remember_token']}"
put user_path(wrong_user)
end
specify { response.should redirect_to(root_url) }
end
end
并在before_filter中:
def signed_in_user
puts "in signed_in_user filter"
puts "cookies[:remember_token] = #{request.cookies[:remember_token]}"
puts "request = #{request.cookies}"
p request
redirect_to signin_url, notice: "Please sign in." unless signed_in?
end
和puts“request =#{request.cookies}”
returns =&gt; request = {}
更新
我现在明白这里发生了什么。我也回顾了整个教程,看看我是否错过了什么,或者找到了正确的方法。 这是正在发生的事情。
在ApplicationController中我有这个(直接从教程中复制)
class ApplicationController < ActionController::Base
protect_from_forgery
include SessionsHelper
# Force signout to prevent CSRF attacks
def handle_unverified_request
sign_out
super
end
end
会话助手有这个sign_out方法:
def sign_out
puts "in sign out"
cookies.delete :remember_token
self.current_user = nil
end
所以当我进行测试时,用户会退出并因此被重定向到登录页面而不是root_url。 我必须仔细阅读教程,看看我可能错过了什么,或者这可能是一种疏忽?
解决!
事实证明这在我的环境中是一个非常简单的设置问题。 我设置了环境变量RAILS_ENV =“development”。 删除它允许spec_helper.rb中的第一行正确地将RAILS_ENV设置为'test',这会在测试环境中关闭protect_from_forgery,这会在我执行put时阻止sign_out,并允许测试通过。
我怀疑其他人会遇到同样的问题,但是如果您正在浏览rails教程并且未通过以下测试,请确保您的测试在测试环境中运行。
故障:
1) Authentication authorization as wrong user submitting a PUT request to the Users#update action
Failure/Error: specify { response.should redirect_to(root_url) }
Expected response to be a redirect to <"http://www.example.com/"> but was a redirect to <"http://www.example.com/signin">
# ./spec/requests/authentication_pages_spec.rb:84:in `block (5 levels) in <top (required)>'
答案 0 :(得分:2)
尝试更改cookies['remember_token'] = user.remember_token
到request.cookies['remember_token'] = user.remember_token
区块的before
。
顺便说一下,post对测试中使用cookie有很好的解释。
答案 1 :(得分:0)
最终问题是测试是在“开发”环境而不是“测试”环境中运行的。在开发环境中,protect_from_forgery处于打开状态,在这种情况下,触发了对sign_out的调用,最终删除了cookie。这就是它在控制器中不可用的原因。修复环境变量问题后,测试现在在“测试”环境中运行,并且cookie在控制器中按预期显示。有关详细信息,请参阅更新部分“已解决!”在问题中。