如何在Rspec中为sinatra使用omniauth?

zlo*_*log 5 ruby testing rspec sinatra omniauth

缩短版本:

使用用于sinatra的omniauth gem,我无法使rspec登录正常工作并保持会话可用于后续请求。

根据http://benprew.posterous.com/testing-sessions-with-sinatra的建议并关闭会话,我将问题归结为:

  app.send(:set, :sessions, false)    # From http://benprew.posterous.com/testing-sessions-with-sinatra
  get '/auth/google_oauth2/callback', nil, {"omniauth.auth" => OmniAuth.config.mock_auth[:google_oauth2] }
  # last_request.session => {"uid"=>"222222222222222222222", :flash=>{:success=>"Welcome"}}
  # last_response.body => ""

  follow_redirect!
  # last_request.session => {:flash=>{}}
  # last_response.body => Html for the homepage, which is what I want
Run Code Online (Sandbox Code Playgroud)

如何使rspec遵循重定向并保留会话变量?锡那特拉有可能吗?

http://benprew.posterous.com/testing-sessions-with-sinatra看来,我不得不在我需要登录的每个get / post请求上发送会话变量,但这在重定向的情况。


细节:

我正在尝试通过以下设置在sinatra中使用omniauth gem:

spec_helper.rb

ENV['RACK_ENV'] = 'test'

# Include web.rb file
require_relative '../web'
# Include factories.rb file
require_relative '../test/factories.rb'

require 'rspec'
require 'rack/test'
require 'factory_girl'
require 'ruby-debug'

# Include Rack::Test in all rspec tests
RSpec.configure do |conf|
  conf.include Rack::Test::Methods
  conf.mock_with :rspec
end
Run Code Online (Sandbox Code Playgroud)

web_spec.rb

describe "Authentication:" do
  before do
    OmniAuth.config.test_mode = true
    OmniAuth.config.add_mock(:google_oauth2, {
      :uid => '222222222222222222222',
      :info => {
        :email => "someone@example.com",
        :name => 'Someone'
      }
    })
  end

  describe "Logging in as a new user" do
    it "should work" do
      get '/auth/google_oauth2/'

      last_response.body.should include("Welcome")
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

尝试进行身份验证时,我得到了<h1>Not Found</h1>答复。我想念什么?

在omn​​iauth docs 的Integration testing页面上,它提到添加两个环境变量:

before do 
  request.env["devise.mapping"] = Devise.mappings[:user] 
  request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter] 
end
Run Code Online (Sandbox Code Playgroud)

但是,正如我所补充的,似乎仅用于轨道

request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:google_oauth2] 
Run Code Online (Sandbox Code Playgroud)

before在我的规格块我得到这个错误:

Failure/Error: request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:google_oauth2]
 ArgumentError:
   wrong number of arguments (0 for 1)
Run Code Online (Sandbox Code Playgroud)

编辑:

打电话get

get '/auth/google_oauth2/', nil, {"omniauth.auth" => OmniAuth.config.mock_auth[:google_oauth2]}
Run Code Online (Sandbox Code Playgroud)

似乎给我last_request.env["omniauth.auth"]等于

 {"provider"=>"google_oauth2", "uid"=>"222222222222222222222", "info"=>{"email"=>"someone@example.com", "name"=>"Someone"}}
Run Code Online (Sandbox Code Playgroud)

看起来不错,但last_response.body仍然返回

<h1>Not Found</h1>
Run Code Online (Sandbox Code Playgroud)

zlo*_*log 3

部分答案...

添加请求环境变量后,回调 url 效果更好:

get '/auth/google_oauth2/callback', nil, {"omniauth.auth" => OmniAuth.config.mock_auth[:google_oauth2]}
follow_redirect!

last_response.body.should include("Welcome")
Run Code Online (Sandbox Code Playgroud)

但是,这不适用于重定向后的会话,这是我的应用程序知道某人已登录所必需的。更新了问题以反映这一点。