Help us understand the problem. What is going on with this article?

Railsチュートリアル 第10章 フレンドリーフォワーディングの追加演習 - フレンドリーフォワーディングのリダイレクト先のURLが渡されていないことのテスト(updateアクション編)

More than 1 year has passed since last update.

何についての記事か

「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/controllers/users_controller_test.rb(抜粋)
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/controllers/users_controller_test.rb(抜粋)
  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メソッドの記述を変更します。

app/helpers/sessions_helper.rb
  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行目でテストが失敗しました。当該行には、以下のコードが記述されています。

test/controllers/users_controller_test.rb(27行目)
assert_nil session[:forwarding_url]

たった今追加したコードですね。想定したテストが正しく行えていることがわかりました。

SessionsHelper#store_locationメソッドを元に戻す

テストが正しく実装できていることがわかったので、SessionsHelper#store_locationメソッドは元に戻しておきましょう。

app/helpers/sessions_helper.rb
  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

テストは無事成功しました。

rapidliner00
* 現在のところは、エンジニアに憧れる非エンジニア * エンジニア的な業務効率化・改善に興味あり
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away