gpt4 book ai didi

ruby-on-rails - M.Hartl 的 Ruby on Rails 教程(第 3 版)第 10 章 (10.54) 中的密码重置测试失败

转载 作者:数据小太阳 更新时间:2023-10-29 08:37:00 26 4
gpt4 key购买 nike

到目前为止,我所有的测试/断言都按预期通过了。我非常有信心应用程序本身运行良好,但我在此测试中没有通过一个断言。我是一名 Rails 新手,但我从其他编程经验中了解到,现在不解决这个问题可能会让 gremlin 恶化。

出于对 SO 成员时间的尊重(并认识到我的 Rails 新手状态),在问这个问题之前,我已经做了几乎所有可能的故障排除,包括:

  1. 重新启动我的本地 Rails 服务器(多次)。
  2. 在这里查看了有关 Rails 教程(及以后)中测试失败的所有其他问题。
  3. 深入研究 Minitest 文档以了解我遇到的错误。
  4. 用@Mhartl 的 Github 存储库中的代码替换了我的(密码重置)集成测试代码。
  5. 尝试在我的测试中使用“Rails.logger.debug”消息通过日志消息进行调试。

断言失败消息:

FAIL["test_password_resets", PasswordResetsTest, 2015-07-30 13:42:42 -0400] test_password_resets#PasswordResetsTest (1438278162.33s)
Failed assertion, no message given.
test/integration/password_resets_test.rb:57:in `block in <class:PasswordResetsTest>'

我的 password_resets_test.rb(完整):

require 'test_helper'

class PasswordResetsTest < ActionDispatch::IntegrationTest
def setup
ActionMailer::Base.deliveries.clear
@user = users(:michael)
end

test "password resets" do
get new_password_reset_path
assert_template 'password_resets/new'
# Invalid email
post password_resets_path, password_reset: { email: "" }
assert_not flash.empty?
assert_template 'password_resets/new'
# Valid email
post password_resets_path, password_reset: { email: @user.email }
assert_not_equal @user.reset_digest, @user.reload.reset_digest
assert_equal 1, ActionMailer::Base.deliveries.size
assert_not flash.empty?
assert_redirected_to root_url
# Password reset form
user = assigns(:user)
# Wrong email
get edit_password_reset_path(user.reset_token, email: "")
assert_redirected_to root_url
# Inactive user
user.toggle!(:activated)
get edit_password_reset_path(user.reset_token, email: user.email)
assert_redirected_to root_url
user.toggle!(:activated)
# Right email, wrong token
get edit_password_reset_path('wrong token', email: user.email)
assert_redirected_to root_url
# Right email, right token
get edit_password_reset_path(user.reset_token, email: user.email)
assert_template 'password_resets/edit'
assert_select "input[name=email][type=hidden][value=?]", user.email
# Invalid password & confirmation
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "foobaz",
password_confirmation: "barquux" }
assert_select 'div#error_explanation'
# Empty password
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "",
password_confirmation: "" }
assert_not flash.empty?
# Valid password & confirmation
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "foobaz",
password_confirmation: "foobaz" }
assert is_logged_in? #<=== FAILING ASSERTION
assert_not flash.empty?
assert_redirected_to user
end
end

第 57 行(失败的断言)是:

assert is_logged_in?

我的 test_helper.rb 的相关部分:

ENV['RAILS_ENV'] ||= 'test'

# Edited for brevity ...

# Returns true if a test user is logged in.
def is_logged_in?
!session[:user_id].nil?
end

# Logs in a test user.
def log_in_as(user, options = {})
password = options[:password] || 'password'
remember_me = options[:remember_me] || '1'
if integration_test?
post login_path, session: { email: user.email,
password: password,
remember_me: remember_me }
else
session[:user_id] = user.id
end
end

private
# Returns true inside an integration test.
def integration_test?
defined?(post_via_redirect)
end
end

这是我的 password_resets_controller.rb:

class PasswordResetsController < ApplicationController
before_action :get_user, only: [:edit, :update]
before_action :valid_user, only: [:edit, :update]
before_action :check_expiration, only: [:edit, :update] # Listing 10.52

def create
@user = User.find_by(email: params[:password_reset][:email].downcase)
if @user
@user.create_reset_digest
@user.send_password_reset_email
flash[:info] = "Email sent with password reset instructions"
redirect_to root_url
else
flash.now[:danger] = "Email address not found"
render 'new'
end
end

def update
if params[:user][:password].empty?
flash.now[:danger] = "Password can't be empty"
render 'edit'
elsif @user.update_attributes(user_params)
log_in @user
flash[:success] = "Password has been reset."
redirect_to @user
else
render 'edit'
end
end

private

def user_params
params.require(:user).permit(:password, :password_confirmation)
end

# Before filters:

def get_user
@user = User.find_by(email: params[:email])
end

# Confirms a valid user.
def valid_user
unless (@user && @user.activated? &&
@user.authenticated?(:reset, params[:id]))
redirect_to root_url
end
end

# Checks expiration of reset token.
def check_expiration
if @user.password_reset_expired?
flash[:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
end
end

这是我的 user.rb(已编辑):

class User < ActiveRecord::Base
# Add tokens to class accessor:
attr_accessor :remember_token, :activation_token, :reset_token

# Edited for brevity ...

# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil? # ... implied else here ...
BCrypt::Password.new(digest).is_password?(token)
end

# Edited for brevity ...

# Sets the password reset attributes.
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token))
update_attribute(:reset_sent_at, Time.zone.now)
end

# Sends password reset email.
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end

# Returns true if a password reset has expired.
def password_reset_expired?
reset_sent_at < 2.hours.ago
end

# Edited for brevity ...

end

我的 Gemfile(已编辑):

source 'https://rubygems.org'
ruby '2.2.2'
gem 'rails', '4.2.2'

# Edited for brevity ...

group :development, :test do
gem 'sqlite3', '1.3.9'
gem 'byebug', '3.4.0'
gem 'web-console', '2.0.0.beta3'
gem 'spring', '1.1.3'
end

group :test do
gem 'minitest-reporters', '1.0.5'
gem 'mini_backtrace', '0.1.3'
gem 'guard-minitest', '2.3.1'
end

# Edited for brevity ...

我从事软件开发已有很长时间了,这听起来像是一个经典案例,绕着车轴转,试图找到一个微妙的问题,而忽略了一些明显的问题。我绝对知道我在这上面花费的时间超出了合理范围,而且我预计在此过程中我在我的代码中注入(inject)了一些废话。

预先感谢您的帮助。

最佳答案

我认为这是一个非常简单的错误:

在您的测试中,在第 53 行,您正在提交密码重置表单以为用户选择一个新密码,但您选择的新密码(“foobaz”)只有 6 个字符长:

patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "foobaz",
password_confirmation: "foobaz" }

但是在 user.rb 中你规定密码必须至少有 8 个字符:

validates :password, presence: true, length: { minimum: 8 }, allow_nil: true

这就是密码重置失败的原因。使用更长的密码,您应该没问题!

要解决这个问题,您可以在失败的断言之前添加这一行:

puts html_document

这会将呈现的 HTML 转储到您的终端窗口,您会在其中找到...

<div class="alert alert-danger">
The form contains 1 error.
</div>
<ul>
<li>Password is too short (minimum is 8 characters)</li>
</ul>

关于ruby-on-rails - M.Hartl 的 Ruby on Rails 教程(第 3 版)第 10 章 (10.54) 中的密码重置测试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31799519/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com