はじめに
最近request.referer
という便利なものがあることを知り、使用する機会がありました。
ですが、minitestを書いている際にリファラを用いたアクションのテストがうまくいかず少し苦戦してしまったため、備忘録を兼ねてここに残しておこうと思います。
そもそもrequest.refererってなに?
リクエストヘッダーが持っている情報の一つであり、遷移前のURLを取得することができます。
そのため、request.referer
を活用することで、
- どのページからの流入なのかアクセス解析ができる
- 遷移元のURLに戻りたい時にリダイレクト先として使用できる
といったメリットがあります。
今回は後者のように、request.referer
をリダイレクト先として使用した時の、minitestの書き方について考えます。
minitestでのrequest.referer
ここではrequest.referer
を使用して、遷移元のURLに再度リダイレクトするようなアクションのテストを作成することを考えます。
# get new_pathを叩いた時のアクション
# original_pathからnew_pathに遷移してきたケースを考える
def hoge
redirect_to request.referer # 遷移元のoriginal_pathにリダイレクト
end
上記アクションによってoriginal_path
に遷移していることを確認したいとき、どのようにテストを記述すれば良いのでしょうか。
失敗するやり方
遷移元のURLを再現するためにoriginal_path
を叩いてからnew_path
を叩けばいいのでは?と思い下記の方法を試してみましたが、うまくいきませんでした。
test 'request.refererを使用したアクションのテスト' do
get original_path
get new_path
assert_redirected_to original_path
end
# 実行結果
# => Minitest::Assertion: Expected response to be a <3XX: redirect>, but was a <500: Internal Server Error>
エラーの発生箇所を調査してみると、コントローラー側で下記のようなメッセージが出ておりrequest.referer
がnilであることがわかります。
つまり、リクエストヘッダーにリファラをセットできていない状態です。
# Rendering with exception: Cannot redirect to nil!
ではminitestでリファラをセットするにはどうすればいいのでしょうか。
成功するやり方
test 'request.refererを使用したアクションのテスト' do
get new_path,
headers: {'HTTP_REFERER' => original_path}
assert_redirected_to original_path
end
上記のように、リクエストヘッダーにリファラを明示的にセットしてあげることで、リファラを用いたアクションのテストを記述することができるようになりました。
まとめ
-
request.referer
を用いることで、遷移元のURL情報を取得することができる。 - minitestで再現する場合、リクエストヘッダーにリファラを持たせることを明記する必要がある。
ちなみに
request.referer
と書くことが多いですが、正しい英単語はreferrerだそうです。
エイリアス設定されているおかげで、refererもreferrerも同じ動作をします。