【发布时间】:2014-02-08 05:03:21
【问题描述】:
这开始是一个问题,我无法在 rails 教程中解决问题,但此时我只想了解发生了什么,如果可以的话,我应该能够解决教程中的问题。
我的问题归结为这个。我正在尝试在测试中设置一个 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? 方法应该查看用户是否存在,并且从 cookie 对象检索到的 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}"
返回 => 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)>'
【问题讨论】:
标签: ruby-on-rails cookies