33. キャンパス情報のセッション保持

キャンパス変更の受入テスト

キャンパス情報はセッションに記録する。ここでは、キャンパス変更に関する受入テストを追加した。当初はメニュー内の直接リンクをクリックしていたが、Javascript を有効にしたため、メニューバーのリンクをクリックして、メニューを表示しないといけなくなったので、以前書いていた記事内容を修正した。以下は現在書いてある受入テストである。

  シナリオ: 教務室のトップページからキャンパス変更ができる
    もし 品川リンクをクリックする
      かつ 荒川に変更リンクをクリックする
      かつ 荒川リンクをクリックする
    ならば "●荒川"と表示されていること

    もし 品川に変更リンクをクリックする
      かつ 品川リンクをクリックする
    ならば "●品川"と表示されていること

これらを実現するために ログイン時には welcome#index にてアクセス元の campus を取得し、now_campus_id としてsession に記録する。各ページでは now_campus の取得を privilege_check にて行う。以下の作業は app/controller/application_controller.rb に記述する。

  # @note ページの権限を確認して、権限がない場合にはリダイレクト
  # @return [Boolean] 権限がある場合には true を返す
  def privilege_check
    set_campus_id_to_session

set_campus_id_to_session は campus_id の所在を調べて、存在すればそれを session に代入。ただし、URL を直書きして間違った now_campus_id を指定されてしまうと問題なので、正しいかどうかも確認する。

  # @note campus_id が存在した場合 session[:now_campus_id] を設定
  def set_campus_id_to_session
    if cid = params[:now_campus_id]
      campus = Campus.find(cid)
      if campus && ! campus.is_both?
        @now_campus = campus
        each_session['now_campus_id'] = cid
      else
        now_campus
      end
    else
      now_campus
    end
  end

now_campus はセッションから campus を取得するメソッド。情報は @now_campus にキャッシュする。view からも使われるので、helper_method にする。

  # @return [Campus] セッションから取得したキャンパス
  def now_campus
    @now_campus ||= Campus.find(each_session('now_campus_id'))
  end
  helper_method: :now_campus

初めての接続では now_campus_id がセッションに登録されていないので、app/controllers/welcome_controller.rb にて初回登録する。ここでは、now_campus_id がセッションに登録されていない場合のみ、接続元の IP から Campus を推定する。

    unless each_session('now_campus_id')
      @now_campus = Campus.default(request.remote_ip)
      each_session['now_campus_id'] = @now_campus.id
    end

これで動作すると思ったが、Campus.default にて Campus.get_arakawa または Campus.get_shinagawa を実行し、キャンパスを取得していた。このため、これらに対する対処が必要だった。

受入テストに関しては、Campus データを使う必要が出てくるので、FactoryGirl で両キャンパスのデータを作成した。「ブラウザの準備をする」の中で spec/acceptance/steps/login_steps.rb に記述した。

step %(ブラウザの準備をする) do
  Capybara.current_driver = :poltergeist_debug
  campus_all_factories
end

これで、受入テストにおけるキャンパスの問題はなくなった。これと同時にコントローラのテストもエラーになっているので、修正する。こちらはデータベースを作りたくないので、now_year と同様に mock で対応した。

def login_user_as(fg_key, controller)
  allow(controller).to receive(:now_campus) { double(Campus, name: '品川', id: 1) }

また、spec/controllers/welcome_controller_spec.rb でも以下の記述をして、エラーを回避した。

  describe 'GET index' do
    before do
      allow(Campus).to receive(:default) { double(Campus, id: 1) }
    end

これでコードのエラーはなくなったので、受入テストを継続する。現在は、このようになっている。

     Failure/Error: ならば "●荒川"と表示されていること

変更処理は終わっており、表示だけの問題なので、app/views/shared/_top_link_bar.html.haml の該当部のリンクを修正する。

          %ul.dropdown-menu
            -Campus.campuses.each do |campus|
              -if campus == @now_campus
                %li.disabled= link_to "#{campus.name}", '#'
              -else
                %li= link_to "#{campus.name}に変更", recursive_path(now_campus_id: campus.id)

ここで、recursive_path は現在の URL の path を得るものである。app/helpers/applicatoin_helper.html.haml にメソッドを追記する。

  # @param [Hash] option 変更するオプション
  # @return [String] 再帰パス
  def recursive_path(option = {})
   request.params.merge(option)
  end

これで受入テストが無事に終了した。
今日はここまで。


written by iHatenaSync