Railsチュートリアル11章 アカウント有効化

Railsチュートリアル11章について大事だと思ったことメモっていきます。

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

 

アカウントの有効化とは・・・

ユーザーを新規登録する際にメールを送って、メール内に貼ってあるリンクをクリックすることで、初めてログインできるようになる。

 

全体の流れ

ユーザーがsave出来たら、before_createでactivation_tokenを作り、それをdigest化してハッシュにしたactivation_digestを作る(self.activation_digestとなっているのでuserのカラム内に入る)。そしてuserコントローラー内でメールを送る。この段階でuserはcreateされている。このメール内のedit_pathに行くとauthenticatedで、先ほどdigest化したやつとactivation_tokenが合っているか確かめる。合っていたらactivationコントローラー内のeditアクションでactivatedをtrueにする。セッションコントローラーでactivatedがtrueであればログインできる。falseであればログインできないように記述する。これによって初めてログインできるようになる。

 

テストコード(Rspec

 

まずはmailerのテスト

これはmailer作成時にある程度できていたので変更した点を修正するだけで助かる

spec/mailer/user_mailer_spec.rb

require "rails_helper"

RSpec.describe UserMailer, type: :mailer do
                 typeはmailerになっている。
describe "account_activation" do
let(:mail) { UserMailer.account_activation(@user) }
mailに関しては@userのようなfactorybotは全く関係ないのでletを使うことにした。
 
before do
@user = FactoryBot.create(:user)
# mail = UserMailer.account_activation(@user)
end

it "renders the headers" do
expect(mail.subject).to eq("Account activation")      " "の中身やemailを変えるくらいだ
expect(mail.to).to eq([@user.email])
expect(mail.from).to eq(["noreply@example.com"])
end

it "renders the body" do
expect(mail.body.encoded).to match("Welcome to the Sample App! Click on the link below to activate your account")
expect(mail.body.encoded).to match(@user.name)
end
end

end

 

続いてアカウント有効化についてのテスト

spec/factories/user.rb

FactoryBot.define do
factory :user do
name { Faker::Name.name }
email { Faker::Internet.free_email }
password { '1a' + Faker::Internet.password(min_length: 4)}
password_confirmation { password }
# 下の二つは後で改良
activated {true}
activated_at {Time.zone.now}
end

trait :admin do
admin { true }
end

trait :not_activation do ここ!!
activated {false}
activated_at {nil}
end

end

spec/system/users_spec.rb

RSpec.describe "アカウント有効化", type: :system do

before do
@user = FactoryBot.create(:user,:not_activation)
                       ここ!! factorybotでactivated:false
という特性を追加
end

it "activation_tokenが正しくない時" do
 
visit edit_account_activation_path("invalid",email:@user.email)
expect(current_path).to eq(root_path)
expect(page).to have_content("Invalid activation link")
 
expect(page).to have_link href: login_path
end

it "emailが正しくない時" do
 
visit edit_account_activation_path("invalid",email:"111@111.com")
expect(current_path).to eq(root_path)
expect(page).to have_content("Invalid activation link")
 
expect(page).to have_link href: login_path
end


it "valid signup information with account activation" do
 
 
visit edit_account_activation_path(@user.activation_token,email:@user.email)
expect(current_path).to eq(user_path(@user))
expect(page).to have_content("Account activated!")
find(".dropdown-toggle").click
 
expect(page).to have_link href: logout_path
 
system specに関してはログインしているかどうかをsesssion[user_id]を使ったりして判断できない
     そういうのはrequest specで。systemに関しては目に見えるとこで流れを追ってテストしていく感じだと思う。
     今回だとアカウント有効化されたらshowページに行って、Account activated!という文字(flash)
が表示されていてログアウトリンクがあるということで、ログインしていることを伝えている。

end
end