Rails で devise ほど重厚ではなく、omniauth より機能が豊富なsorcery を使っているアプリケーションでいわゆるソーシャルログインを行う request spec や cucumber feature を書くのに困っている。
例えば omniauth だと Integration Testing に書いてあるように
OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new {
:provider => 'twitter',
:uid => '123545'
}
と書けば oauth の認証リクエストと認証後に callback に渡される user_hash も作ってくれる。こういう仕組みがあると、request spec だろうが、コントローラの spec だろうが自由にテストを書くことができる。便利。
一方、sorcery はどうかというと、omniauth のような仕組みは用意されていないらしく、どうすれば良いか探してみたらコントローラのテストの仕組みは https://github.com/NoamB/sorcery/blob/master/spec/rails3/spec/controller_oauth2_spec.rb にあるような
def stub_all_oauth2_requests!
auth_code = OAuth2::Strategy::AuthCode.any_instance
access_token = mock(OAuth2::AccessToken)
access_token.stub(:token_param=)
response = mock(OAuth2::Response)
response.stub(:body).and_return({
"id"=>"123",
"name"=>"Noam Ben Ari",
...snip...
"verified"=>true,
"updated_time"=>"2011-02-16T20:59:38+0000"}.to_json)
access_token.stub(:get).and_return(response)
auth_code.stub(:get_token).and_return(access_token)
end
を自分でも用意すれば何とか callback 後についてはコントローラの spec を書くことができるというのはわかった。
でも、request spec を書きたいんだよなあ。上のように callback 後の stub を作っても /auth/twitter に認証のためにリクエストを投げると sorcery は本当に api.twitter.com に繋いでしまうので、根本的にヘルパーを用意しないとダメそう。
omniauth みたいにちゃんとテストが書けるライブラリを知ってると、こういうテストを書くのに不自由なライブラリは選択を躊躇してしまうね。続く。