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
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])
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}
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