ruby-on-rails - 在《Ruby on Rails 教程》第四版 12章重置密码中执行rails test有一个问题
高洛峰
高洛峰 2017-04-25 09:03:23
0
0
1297

就是密码验证那一块出了问题(即密码不匹配)
我重新写过这一块,以及Google找了相关的实例还是会报错,希望能解决,谢谢。
该项目来自我学习的网站:https://www.railstutorial.org...
PS:目前怀疑是<%= render 'shared/error_messages' %>(edit.html.erb)这条程序没起作用,不过“注册用户”也是用的同样的方法,能正常验证密码和邮箱的格式。但是“重置密码”就不起作用了。

实际操作中可以分辨空值、密码过短。但输入两个不同的密码就直接修改成功为第一次输入的密码了。

app/views/password_resets/edit.html.erb

 <% provide(:title, 'Reset password') %>
<h1>Reset password</h1>

<p class="row">
  <p class="col-md-6 col-md-offset-3">
    <%= form_for(@user, url: password_reset_path(params[:id])) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= hidden_field_tag :email, @user.email %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Update password", class: "btn btn-primary" %>
    <% end %>
  </p>
</p>

app/controllers/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]    # Case (1)

  def new
  end

  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 edit
  end

  def update
    if params[:user][:password].empty?                  # Case (3)
      @user.errors.add(:password, "can't be empty")
      render 'edit'
    elsif @user.update_attributes(user_params)          # Case (4)
      log_in @user
      flash[:success] = "Password has been reset."
      redirect_to @user
    else
      render 'edit'                                     # Case (2)
    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

test/integration/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'
      
      # 电子邮箱地址无效
      post password_resets_path, params: { password_reset: { email: "" } }
      assert_not flash.empty?
      assert_template 'password_resets/new'

      # 电子邮箱地址有效
      post password_resets_path,
               params: { 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

      # 密码重置表单
      user = assigns(:user)

      # 电子邮箱地址错误
      get edit_password_reset_path(user.reset_token, email: "")
      assert_redirected_to root_url

      # 用户未激活
      user.toggle!(:activated)
      get edit_password_reset_path(user.reset_token, email: user.email)
      assert_redirected_to root_url
      user.toggle!(:activated)

      # 电子邮箱地址正确,令牌不对
      get edit_password_reset_path('wrong token', email: user.email)
      assert_redirected_to root_url

      # 电子邮箱地址正确,令牌也对
      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

      # 密码和密码确认不匹配
      patch password_reset_path(user.reset_token),
          params: { email: user.email,
                    user: { password:              "foobaz",
                            password_confirmation: "barquux" } }
    assert_select 'p#error_explanation'    

      # 密码为空值
      patch password_reset_path(user.reset_token),
                  params: { email: user.email,
                                      user: { password:                             "",
                                                      password_confirmation:  "" } }
      assert_select 'p#error_explanation'

      # 密码和密码确认有效
      patch password_reset_path(user.reset_token),
                  params: { email: user.email,
                                      user: { password:                             "foobaz",
                                                      password_confirmation:  "foobaz" } }
      assert is_logged_in?
      assert_not flash.empty?
      assert_redirected_to user
  end

end

终端报错:

cmwap:sample_app terry$ rails test
Running via Spring preloader in process 23814
Started with run options --seed 63903

 FAIL["test_password_resets", PasswordResetsTest, 1.365597692999927]
 test_password_resets#PasswordResetsTest (1.37s)
        Expected at least 1 element matching "p#error_explanation", found 0..
        Expected 0 to be >= 1.
        test/integration/password_resets_test.rb:53:in `block in <class:PasswordResetsTest>'

  39/39: [=================================] 100% Time: 00:00:01, Time: 00:00:01

Finished in 1.88071s
39 tests, 186 assertions, 1 failures, 0 errors, 0 skips
高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全員に返信(0)
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート