メールについてのRspecを書くときに詰まったので備忘録代わりに記事にします!
やりたいこと
SystemSpeec内でAction Mailerを使って送信されたメール本文のリンクURLを取得して利用したい
ヘルパーを使ったxxx_pathをしようと思ったが、今回はパスワードリセットで、deviseの処理で生成されたパスワードリセットトークンを含んだURLがほしかった。
結論
**URI.extract(str)**を使って文字列からURLを抽出する
https://docs.ruby-lang.org/ja/latest/method/URI/s/extract.html
実際のコード(deviseを利用したパスワードリセットのテスト)
visit 'members/password/new'
expect(page).to have_content("パスワードを忘れましたか?")
find('#xxxxx').set('example@example.com')
click_button("パスワードの再設定方法を送信する")
# システム上クリックされた後にタイミングでメールが送信される
expect(page).to have_content('xxxxxxx')
本題部分
# これで配信したメールのインスタンスを取得できる
password_reset_mail = ActionMailer::Base.deliveries.last
# 本文をエンコードして取得
mail_body = password_reset_mail.body.encoded
# 文字列からURLの配列で取得。今回はURLは1つだけなので1番目を取得
password_reset_url = URI.extract(mail_body)[0]
visit password_reset_url
expect(page).to have_content('パスワードを変更')
この後実際にフォームを入力させたりする
もっといい方法があればぜひコメントいただければと思います!!
参考
Action Mailer の基礎 | Rails ガイド
Mailer specs - RSpec Rails - RSpec - Relish
ingleton method URI.extract