SinatraでTwitterログインを下記みたいに実装しました。stubの使い方に少し悩んだ。
view
1 2 3 4 |
<form action="/login" method="post" id="login_form"> <input type="hidden" name="back_url" value="<%= request.path_info %>" /> <a href="javascript:void(0);" onclick="$('#login_form').submit();">Twitterでログイン</a> </form> |
hiddenパラメータのback_urlにログイン後に戻りたい画面のURLを保存してます。ログインをaタグにしているのはCSSの都合なので、submitボタンでもOK。
main.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
post "/login" do # 値を引き回すため、画面から受け取ったback_urlをcookieに保存。 response.set_cookie("back_url", params[:back_url]) # /auth/twitterへリダイレクト redirect "/auth/twitter" end # 認証後の処理 get "/auth/:provider/callback" do auth = request.env["omniauth.auth"] # 認証情報をsessionにセット session[:twitter] = { :uid => auth[:uid], :name => auth[:info][:name], :image => auth[:info][:image], } back_url = request.cookies['back_url'] || "/" redirect back_url end |
Requestの中身をstubにしたい
認証後にsessionに正しく情報がセットされたかどうかを検証したいので、Request.envに値が入っている必要があります。
これは実際にTwitterログインを行わないと値が入ってこないので、Request.envをstubにしちゃいます。
main_spec.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
describe "get /auth/:provider/callback" do before do # Twitterログイン認証情報のフェイク @auth = {"omniauth.auth" => { :uid => "testuid", :info => { :name => nil, :image => nil, } }} # Request.envをstubにする # requestの中身をstubにしたいので、Sinatra::Request.any_instance〜という構文で # 全てのSinatra::Requestのインスタンスに対してstubできる Sinatra::Request.any_instance.stub(:env).and_return(@auth) end it "sessionにTwitterアカウント情報がセットされること" do get "/auth/:provider/callback" session[:twitter][:uid].should == @auth["omniauth.auth"][:uid] end end end |
やっぱりRSpecは書きやすいなー。
contextで分岐を表現できたりするのでそれぞれのテストメソッドが担当する箇所が明確にしやすい感じ。
The following two tabs change content below.

原田 敦
日本CAWのエンジニア。もふもふ部の部長。得意分野はRuby on Railsを使った小規模WEBアプリケーションを高速で開発すること。週末の楽しみは一人お菓子パーティー。三度の飯より小動物をもふもふするのが好きです。

最新記事 by 原田 敦 (全て見る)
- Rails Engineでブログ機能追加するgemを作る - 2015年3月15日
- WEBエンジニア一人だけでサービスを作りきる方法-夫婦のための自動ごはん予定お知らせサービス「GoHaaan」制作でやったこと - 2015年3月7日
- CentOS6でMariaDBのDynamic Columnsを試してみた - 2015年2月28日