何についての記事か
「Railsチュートリアル 第10章 演習 - フレンドリーフォワーディング」の発展学習となります。
同演習には、「渡されたURLに初回のみ転送されていることを確認する。具体的には、リダイレクトのURLはデフォルト (プロフィール画面) に戻っていることを確認する。」という内容の出題があります。それであれば、逆に「『ログインしていない状態でRDB上のユーザー情報を更新しようとした』という状況で、フレンドリーフォワーディングのリダイレクト先のURLが渡されていないこと」のテストも必要なはずです。
というわけで、発展学習としてQiita記事を書いてみました。
内容
フレンドリーフォワーディングのリダイレクト先のURLを保存する処理はどこにあるか
editアクションの場合と同じく、Usersコントローラーのlogged_in_user
メソッドとなります。
フレンドリーフォワーディングのリダイレクト先のURLを保存する処理に対応するテスト
上述コードに対応するテストコードは、test/controllers/users_controller_test.rb
内にあります。update
アクションに対応するテストは"hould redirect update when not logged in"です。
test "should redirect update when not logged in" do
patch user_path(@user), params: { user: { name: @user.name,
email: @user.email } }
assert_not flash.empty?
assert_redirected_to login_url
end
当該テストに記述を追加すれば、「『ログインしていない状態でRDB上のユーザー情報を更新しようとした』という状況で、フレンドリーフォワーディングのリダイレクト先のURLが渡されていないこと」がテストできるはずです。
実際に追加する記述は以下のようになります。
test "should redirect update when not logged in" do
patch user_path(@user), params: { user: { name: @user.name,
email: @user.email } }
assert_not flash.empty?
assert_redirected_to login_url
+ assert_nil session[:forwarding_url]
end
前提 - テストコードの特定行に対してテストを実行する
例えば、test/controllers/users_controller_test.rb
の22行目に対応するテストを実行するには、rails test
コマンドを以下のように呼び出せばOKです。
# rails test test/controllers/users_controller_test.rb:22
PATCH
リクエストに対して、一時cookiesにリダイレクト先のURLが保存される場合に対するテスト
「PATCH
リクエストに対して、一時cookiesにリダイレクト先のURLが保存される場合」を再現する
SessionsHelper#store_location
メソッドの記述を変更します。
module SessionsHelper
...略
# アクセスしようとしたURLを覚えておく
def store_location
- session[:forwarding_url] = request.original_url if request.get?
+ session[:forwarding_url] = request.original_url if request.patch?
end
end
request.get?
をrequest.patch?
にことにより、「リクエストの内容がPATCH
である場合、一時cookiesにリダイレクト先のURLを保存する」という動作にしています。
「PATCH
リクエストに対して、一時cookiesにリダイレクト先のURLが保存される場合」に、update
アクションに対するテストが失敗することを確認する
# rails test test/controllers/users_controller_test.rb:22
Running via Spring preloader in process 1311
Started with run options --seed 7566
FAIL["test_should_redirect_update_when_not_logged_in", UsersControllerTest, 0.6280409999890253]
test_should_redirect_update_when_not_logged_in#UsersControllerTest (0.63s)
Expected "http://www.example.com/users/959740715" to be nil.
test/controllers/users_controller_test.rb:27:in `block in <class:UsersControllerTest>'
5/5: [===================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.63188s
1 tests, 3 assertions, 1 failures, 0 errors, 0 skips
test/controllers/users_controller_test.rb
の27行目でテストが失敗しました。当該行には、以下のコードが記述されています。
assert_nil session[:forwarding_url]
たった今追加したコードですね。想定したテストが正しく行えていることがわかりました。
SessionsHelper#store_location
メソッドを元に戻す
テストが正しく実装できていることがわかったので、SessionsHelper#store_location
メソッドは元に戻しておきましょう。
module SessionsHelper
...略
# アクセスしようとしたURLを覚えておく
def store_location
- session[:forwarding_url] = request.original_url if request.patch?
+ session[:forwarding_url] = request.original_url if request.get?
end
end
実装が正しいことの確認
改めて、test/controllers/users_controller_test.rb
の22行目に対応するテストを実行します。
# rails test test/controllers/users_controller_test.rb:22
Running via Spring preloader in process 1324
Started with run options --seed 26169
5/5: [===================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.56564s
1 tests, 3 assertions, 0 failures, 0 errors, 0 skips
テストは無事成功しました。