我正在通过Hartl rails教程,在第9章中我试图复制测试以限制编辑操作给当前用户:
require 'spec_helper'
describe "Authentication" do
subject { page }
....
....
....
describe "as wrong user" do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
before { sign_in user, no_capybara: true }
describe "submitting a GET request to the Users#edit action" do
before { get edit_user_path(wrong_user) }
specify { expect(response.body).not_to match(full_title('Edit user')) }
specify { expect(response).to redirect_to(root_url) }
end
describe "submitting a PATCH request to the Users#update action" do
before { patch user_path(wrong_user) }
specify { expect(response).to redirect_to(root_url) }
end
end
end
然后我按照本书中的描述实现了代码,但测试仍然失败:
Failures:
1) Authentication as wrong user submitting a PATCH request to the Users#update action
Failure/Error: specify { expect(response).to 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>.
Expected "http://www.example.com/" to be === "http://www.example.com/signin".
# ./spec/requests/authentication_pages_spec.rb:100:in `block (4 levels) in <top (required)>'
我通过在测试中调用的sign_in方法中添加一些日志来进行调查:
def sign_in(user, options={})
Rails.logger.debug "sign_in "+"*"*15
if options[:no_capybara]
# Sign in when not using Capybara.
remember_token = User.new_remember_token
cookies[:remember_token] = remember_token
Rails.logger.debug "Created cookie rt: "+ cookies[:remember_token].to_s
user.update_attribute(:remember_token, User.encrypt(remember_token))
else
visit signin_path
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
end
在日志中,创建cookie remember_token报告为空白。如果我将登录更改为sign_in user
(没有没有capybara选项),我可以看到用户已登录并填充了cookie,但是当我访问编辑操作时,cookie不再填充。
如何进一步调查cookie被销毁的原因?
...谢谢
有关信息,我已在下面列出了应用程序代码:
users_controller.rb的内容
class UsersController < ApplicationController
before_action :signed_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
def new
@user = User.new
end
def show
@user = User.find(params[:id])
logger.debug "User show: "+ @user.to_yaml
logger.debug "cookie on user show: "+ cookies[:remember_token].to_yaml
end
def create
@user = User.new(user_params)
if @user.save
sign_in @user
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
render 'new'
end
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
flash[:success] = "Profile updated"
sign_in @user
redirect_to @user
else
render 'edit'
end
end
def edit
logger.debug "Edit user method"
@user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Before filters
def signed_in_user
si = signed_in?
logger.debug "*"*200
logger.debug "signed in user: signed in?: "+si.to_s
redirect_to signin_url, notice: "Please sign in." unless si
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
end
sessions_controller.rb的内容
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email].downcase)
if user && user.authenticate(params[:password])
sign_in user
redirect_to user
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
sign_out
redirect_to root_url
end
end
sessions_helper.rb的内容
module SessionsHelper
def sign_in(user)
logger.debug "Sessions Helper sign in Method"
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.encrypt(remember_token))
self.current_user = user
end
def signed_in?
s_in = !current_user.nil?
logger.debug "signed_in?: "+s_in.to_s
s_in
end
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
def current_user=(user)
@current_user = user
end
def current_user
logger.debug "getting current user"
logger.debug "cookie: "+ cookies[:remember_token].to_s
remember_token = User.encrypt(cookies[:remember_token])
logger.debug "rt: "+ remember_token.to_yaml
logger.debug "current_user before: "+ @current_user.to_yaml
@current_user ||= User.find_by(remember_token: remember_token)
logger.debug "current_user after: "+ @current_user.to_yaml
@current_user
end
def current_user?
remember_token = User.encrypt(cookies[:remember_token])
@current_user ||= User.find_by(remember_token: remember_token)
end
def current_user?(user)
user == current_user
end
end
答案 0 :(得分:0)
您的身份验证测试
没有任何问题users_controller.rb 文件
中的代码请从 users_controller.rb 文件中删除更新方法中指定的(&lt; --- )行。
从错误本身可以清楚地看出,它应该位于 root_ulr ,但是会降落在 sign_in_url 上。
这种情况正在发生,因为您已在update method.so中为users_controller.rb文件添加了一行“ sign_in @user ”。因此,根据您的代码,它会重定向到“ sign_in_url “这是不必要的,因为用户已经登录并更新了他的个人资料。我希望这将有所帮助并解决您的问题。
users_controller.rb文件中的更新方法
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
flash[:success] = "Profile updated"
sign_in @user `<----------- Remove this line
redirect_to @user
else
render 'edit'
end
end