I've been working through M.Hartl's Ruby on Rails tutorial for a while now, and I've been able to work out when I've made typos that caused my integration tests to fail and the like, but I've run into one that I can't figure out. My get edit_password_reset_path()
with correct arguments is redirecting to the home url, not password_resets/edit
like it should.
The failing test:
FAIL["test_password_resets", PasswordResetsTest, 2015-11-02 15:50:02 +0000]
test_password_resets#PasswordResetsTest (1446479402.08s)
expecting <"password_resets/edit"> but rendering with <[]>
test/integration/password_resets_test.rb:37:in `block in <class:PasswordResetsTest>'
Here is my 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' # This is the assertion that fails
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: "foobazzz",
password_confirmation: "barquuxz" }
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: "foobazzz",
password_confirmation: "foobazzz" }
assert is_logged_in?
assert_not flash.empty?
assert_redirected_to user
end
end
Here is my 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]
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?
@user.errors.add(: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
def get_user
@user = User.find_by(email: params[:email])
end
def valid_user
unless (@user && @user.activated? &&
@user.authenticated?(:reset, params[:id]))
redirect_to root_url
end
end
def check_expiration
if @user.password_reset_expired?
flash[:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
end
end
The authenticated?
method in user.rb
:
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
I'm not super sure what else is needed to figure out my problem. I've searched StackOverflow, worked through the code a second time, and I've even compared the source code at M.Hartl's github repo.
Link to the appropriate branch on my repo.
I'm trying to follow exactly this part of the tutorial.
Aucun commentaire:
Enregistrer un commentaire