test"当记住摘要错误时,current_user返回nil"

时间:2016-10-05 18:31:26

标签: ruby-on-rails railstutorial.org

我的问题不是测试失败;所有测试都通过,直到现在。 代码示例在Michael Hartl的书中(您可能已经猜到了)。 我看看这个测试:

test "current_user returns nil when remember digest is wrong" do
  @user.update_attribute(:remember_digest, User.digest(User.new_token))
  assert_nil current_user
end

我的问题很简单:请解释一下,为什么remember_digest错在这里?什么可以让它错?

有关详细信息,该文件为test/helpers/sessions_helper_test.rb,并以此方法开头:

  def setup
    @user = users(:michael)
    remember(@user)
  end

users(:michael)在文件test/fixtures/users.yml

中定义

2 个答案:

答案 0 :(得分:1)

你做对了 - 当current_user错误时,此测试确保nilremember_digest,这意味着如果Cookie与预期不同,则用户未登录

  

请注意,我们添加了第二个测试,用于检查当前测试   如果用户的记忆摘要不正确对应,则user为nil   记住令牌,从而测试经过验证的?表达   在嵌套的if语句中:

if user && user.authenticated?(cookies[:remember_token])

Chapter 9

setup在测试之前运行:

def setup
  @user = users(:michael)
  remember(@user)
end

并且remember功能通过在Cookie中设置remember_digest来设置用户remember_token

# Remembers a user in a persistent session.
def remember(user)
  user.remember
  cookies.permanent.signed[:user_id] = user.id
  cookies.permanent[:remember_token] = user.remember_token
end

然后,测试会将用户的remember_digest替换为随机值的摘要,从而使Cookie无效:

@user.update_attribute(:remember_digest, User.digest(User.new_token))

所以current_usernil,这意味着没有用户登录。

答案 1 :(得分:0)

看看:

  def current_user
      if (user_id = session[:user_id]) # i.e., if the user is logged in (has a session w/ user's id)
          @current_user ||= User.find_by(id: user_id)
      elsif (user_id = cookies.signed[:user_id]) 
          user = User.find_by(id: user_id)
          if user && user.authenticated?(cookies[:remember_token])
              log_in user
              @current_user = user
          end
      end
  end

(来自sessions_helper.rb) - 具体来说,请看语句:

if user && user.authenticated?(cookies[:remember_token])

请注意,如果user.authenticated?(cookies[:remember_token])失败,则不会分配实例变量@current_user。在这种情况下,@current_user的值将为零。

要获得更好的主意,请在rails控制台中尝试:

>> user = User.create(name: "Michael", email: "example@michael.com", password: "foobar", password_confirmation: "foobar")
>> user.remember_token 
=> nil
>> user.remember
>> user.remember_token
=> "68ObMQCCdjURdwH0QVEL7w"
>> token = user.remember_token
>> user.authenticated?(token)
=> true
>> user.update_attribute(:remember_digest, User.digest(User.new_token))
>> user.authenticated?(token)
=> false

制作最后一行=> true

>> user.remember
>> new_token = user.remember_token
>> user.authenticated?(new_token)
=> true

现在回顾一下session_helper_test.rb,因为在设置中调用remember方法,而不是在测试块中调用@user.update_attribute(:remember_digest, User.digest(User.new_token))之后,我们可以预期user.authenticated?(user.remember_token)会失败。因此,语句if user && user.authenticated?(cookies[:remember_token])将为false。因此,@current_user永远不会给出值,因此会nil