Railsチュートリアル12章 パスワード再設定

Railsチュートリアル12章で大事だと思ったことをメモします。

テストコードはRspecで書いています。

 

パスワード再設定

 

ログインする際、パスワードを忘れてしまった場合にパスワード再設定をする。

userのedit,updateでパスワードを変えるのは違う。それはパスワードが分かっていててログインできてる状態。

今回はパスワードが分からなくて、ログインできない状態

 

全体像

ログインページからpassword_fogetをクリックしてパスワード再設定ページへ。

emailを入力すれば(new),createアクションでreset_token,reset_digestを生成。

reset_digestをカラムに入れる。またこのcreate アクションでメールを送る。

メール内に書かれたedit_pathをクリック。edit_pathに含まれるreset_tokenとuserカラムにあるreset_digestがauthenticated?で合致すればeditにいける。

edit_pathでpassword とpassword_confirmationを入力(edit)するとupdateアクションへ。passwordとpassword_confirmationをupdateしてあげる。

変更されたpasswordでログインできるようになる。

---------------------------------------------------------------------------------------------------------------

 

テストコード(Rspec)

systemとrequest specで書きました。 ほとんどrequest になっちゃった。

spec/system/users_spec.rb

system

RSpec.describe "パスワードreset", type: :system do

before do
@user = FactoryBot.create(:user)
 
end

it 'password/new createでemailが正しくない時' do
visit password_resets_new_path
fill_in 'Email', with:"abc@111.com"
find('input[name="commit"]').click
expect(page).to have_content("Email address not found")
end

it 'password/new createでemailが正しい時' do
visit password_resets_new_path
fill_in 'Email', with: @user.email
find('input[name="commit"]').click
expect(current_path).to eq(root_path)
expect(page).to have_content("Email sent with password reset instructions")

end
end

同じくspec/system/users_spec.rb

request

RSpec.describe "パスワードreset", type: :request do

before do
@user = FactoryBot.create(:user)
@user.create_reset_digest
これによりreset_token生成、reset_digestとreset_sent_atをカラムに追加
system specではreset_tokenなどを生成できなかったため、request specにした
end

it 'password/edit ユーザーが無効の場合(not_activate)' do
@user.toggle!(:activated) ここ
# toggle!は真偽を反対にする この場合falseにしている
get edit_password_reset_path(@user.reset_token,email:@user.email)

expect(response.body).to redirect_to root_path
 
end

it 'password/editでemailが正しくない時' do
get edit_password_reset_path(@user.reset_token,email:"111@111.com")
expect(response).to redirect_to root_path
 
end

it 'password/editでreset_tokenが正しくない時' do
get edit_password_reset_path("invalid",email:@user.email)
expect(response).to redirect_to root_path
 
end

it 'password/editでreset_tokenが正しい時' do
get edit_password_reset_path(@user.reset_token,email:@user.email)

expect(response.body).to include "Reset password"

end

it 'password/updateでpasswordが空の時' do
patch password_reset_path(@user.reset_token),
params:{ email:@user.email,
user:{
password: "",
},
}
expect(response.body).to include "Reset password"

end

it 'password/updateでpasswordとpassword_confirmationが無効な時' do
patch password_reset_path(@user.reset_token),
params:{ email:@user.email,
user:{
password: "abcdef",
password_confirmation: "123456",
},
}
expect(response.body).to include "Reset password"
 

end

it 'password/updateで正しくpasswordとpassword_confirmationが入力されている場合' do
patch password_reset_path(@user.reset_token),
params:{ email:@user.email,
user:{
password: "abcdef",
password_confirmation: "abcdef",
},
}
expect(response).to redirect_to user_path(@user)
expect(is_login?).to be_truthy
expect(@user.reload.reset_digest).to eq nil
 

end

it 'Password resetが時間切れの場合' do
@user.update_attribute(:reset_sent_at, 5.hours.ago) ここで時間切れの要素を追加
patch password_reset_path(@user.reset_token),
params:{ email:@user.email,
user:{
password: "abcdef",
password_confirmation: "abcdef",
},
}
expect(response).to redirect_to new_password_reset_url
end


end