NissyBlog

Life goes on.

Ruby on Railsでcookie情報の変更を考慮したテストを書いてみた

この記事はVOYAGE GROUP エンジニアブログ : Advent Calendar 2014の15日目の記事になります。

こんにちは。@nissy0409240です。
VOYAGE GROUPで新卒一年目のエンジニアとして、毎日楽しくお仕事しています!!

寒くてやる気が出ない日々が続きますが、毎日のタスクや、音ゲー部の活動を疎かにすることなく、
同期の無茶ぶりに応えていこうと思いました。

しかし、本エントリーではRuby on Railscookie情報の変更を考慮したテストを書く時に使った
gemをご紹介したいと思います。


準備

まず、新しいRailsプロジェクトを下記コマンドで生成します。

$ ./bin/rails new show_me_the_cookie_test -T

今回はRSpecを使ったテストを書きたいので、-Tオプションを付けて実行します。

続いて、scaffoldでさくっとCRUD機能がついた雛形を作成します。

$ ./bin/rails g scaffold task content:text

最後に、DBの作成と生成されたマイグレーションの適用を行います。

$ ./bin/rake db:create
$ ./bin/rake db:migrate

以上のコマンドを行うことで、簡単なアプリケーションが作成されます。
f:id:Nissy0409:20141214230728p:plain

なお、上記コマンドはこちらの書籍を参考とさせて頂きました。パーフェクトRuby on Rails:書籍案内|技術評論社

show_me_the_cookies

ここで、今回使うgemをご紹介します。nruth/show_me_the_cookies · GitHub

こちらのgemはe2eテストを書く時に用いられることが多いcapybaraというgemが無いと使えません。
そのため、capybaraのインストールも必要です。

jnicklas/capybara · GitHub

show_me_the_cookiesのインストール方法はGemfileに下記一文を追加した後にbundle installを実行すればOKです。

gem 'show_me_the_cookies'

また、spec/rails_helper.rbに

config.include ShowMeTheCookies, :type => :feature

の一文を追記することも忘れずに行いましょう。

作成

ここからは実際に作って行こうと思います。
まず、ログイン機能の仮実装を行います。
仮実装が完了したらcookie情報の変更を考慮したテストを書いて行きます。
しかし、README.mdにcookieの作り方が書いてなかったので、ソースコードを見てみます。
すると

def create_cookie(name, value, options = {})
  current_driver_adapter.create_cookie(name, value, options)
end

というメソッドを見つけました。
こちらを参考に

require 'rails_helper'

feature "Tasks", :type => :feature do
  it '非ログイン状態でアクセスすると、ログインページへリダイレクトしていること' do
    visit tasks_path
    expect(current_url).to eq login_url
  end
  it 'cookieが存在する場合タスク一覧画面を表示すること' do
    create_cookie('sso', 'hogehogehoge')
    puts show_me_the_cookie('sso')
    visit tasks_path
    expect(current_url).to eq tasks_url
  end
end

というテストを書いてみます。

puts文は実際に'sso'というキーcookieが返って来るのかを確認するために、
show_me_the_cookieメソッドの結果を出力するようにしています。

このテストを実行してみると
f:id:Nissy0409:20141215021502p:plain
二行目にssoというキーのcookieが生成されていることが確認出来ました。
これでcookie情報の変更を考慮したテストすることが出来そうです。
それでは、ここまでの内容を踏まえて下記の様にソースコード

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  private

  def login_required
    sso_key = cookies[:sso]
    unless sso_key
      redirect_to login_path and return
    end 
    unless valid_sso_key?(sso_key)
      redirect_to login_path and return
    end
  end

  def valid_sso_key?(sso_key)
    true
  end

  def current_user
    nil
  end
end

また、下記の様にテストコードを実装します。

require 'rails_helper'

feature "Tasks", :type => :feature do
  it '非ログイン状態でアクセスすると、ログインページへリダイレクトしていること' do
    visit tasks_path
    expect(current_url).to eq login_url
  end
  it 'cookieが存在する場合タスク一覧画面を表示すること' do
    create_cookie('sso', 'hogehogehoge')
    visit tasks_path
    expect(current_url).to eq tasks_url
  end
end

最後に、仮実装のコードから

def login_required
    if current_user.nil?
      redirect_to login_path and return
    end
  end

こちらのコードを削除します。
以上を踏まえ、テストを実行すると
f:id:Nissy0409:20141215023949p:plain
こちらのようにテストが通り、無事、cookie生成時とそうでない場合のテストを書くことが出来ました。

まとめ

今回、Ruby on Railscookie情報の変更を考慮したテストを書くにあたり学んだ知見をまとめさせて頂きました。

つたない実装ではございますが、このエントリーの内容を実装したものがこちらになります。Nissy0409/show_me_the_cookie_test · GitHub


最後までお付き合い頂き、ありがとうございました。
明日はジバニャン方程式で有名な@Akiyahさんです。
お楽しみに!!