How to use omniauth in rspec for sinatra?

Abridged version:

Using the omniauth gem for sinatra, I cannot get rspec to get into work and save the session for future requests.

Based on the suggestions of http://benprew.posterous.com/testing-sessions-with-sinatra and disconnecting sessions, I highlighted a problem:

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 

How do I get rspec to monitor redirection and save session variables? Is this possible in Sinatra?

From http://benprew.posterous.com/testing-sessions-with-sinatra it seems that I will have to send session variables in each receive / send request, for which I need a login for, but this will not work in case of redirection.


Details:

I am trying to use omniauth gem in sinatra with the following setting:

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 

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 

When I try to authenticate, I get a response <h1>Not Found</h1> . What am I missing?

The omniauth docs page integration test page mentions adding two environment variables:

 before do request.env["devise.mapping"] = Devise.mappings[:user] request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter] end 

But it seems to be for rails only, as I added

 request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:google_oauth2] 

in my before block in my specification, and I get this error:

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

Edit:

Call get with

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

seems to me last_request.env["omniauth.auth"] to be equal

  {"provider"=>"google_oauth2", "uid"=>"222222222222222222222", "info"=>{"email"=>" someone@example.com ", "name"=>"Someone"}} 

which seems correct, but last_response.body still returns

 <h1>Not Found</h1> 
+4
source share
2 answers

Partial answer ...

The callback url works better with the query environment variables added:

 get '/auth/google_oauth2/callback', nil, {"omniauth.auth" => OmniAuth.config.mock_auth[:google_oauth2]} follow_redirect! last_response.body.should include("Welcome") 

However, this does not work with redirection sessions, which are necessary for my application to find out that someone is logged in. Updated question to reflect this.

+3
source

Using this meaning (based on fooobar.com/questions/1385165 / ... ) to store a data session, I got my tests for storing a session, which allowed me to transfer the session to further requests.

However, it might be easier.

Installation Code:

 # Omniauth settings OmniAuth.config.test_mode = true OmniAuth.config.add_mock(:google_oauth2, { :uid => '222222222222222222222', :info => { :email => " someone@example.com ", :name => 'Someone' } }) # Based on https://gist.github.com/375973 (from /questions/1385165/how-can-i-make-racksessionpool-work-in-a-test-using-sinatra-and-rspec/4331873#4331873) class SessionData def initialize(cookies) @cookies = cookies @data = cookies['rack.session'] if @data @data = @data.unpack("m*").first @data = Marshal.load(@data) else @data = {} end end def [](key) @data[key] end def []=(key, value) @data[key] = value session_data = Marshal.dump(@data) session_data = [session_data].pack("m*") @cookies.merge("rack.session=#{Rack::Utils.escape(session_data)}", URI.parse("//example.org//")) raise "session variable not set" unless @cookies['rack.session'] == session_data end end def login!(session) get '/auth/google_oauth2/callback', nil, { "omniauth.auth" => OmniAuth.config.mock_auth[:google_oauth2] } session['uid'] = last_request.session['uid'] # Logged in user should have the same uid as login credentials session['uid'].should == OmniAuth.config.mock_auth[:google_oauth2]['uid'] end # Based on Rack::Test::Session::follow_redirect! def follow_redirect_with_session_login!(session) unless last_response.redirect? raise Error.new("Last response was not a redirect. Cannot follow_redirect!") end get(last_response["Location"], {}, { "HTTP_REFERER" => last_request.url, "rack.session" => {"uid" => session['uid']} }) end def get_with_session_login(path) get path, nil, {"rack.session" => {"uid" => session['uid']}} end 

Sample rspec code:

 describe "Authentication:" do def session SessionData.new(rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar) end describe "Logging in as a new user" do it "should create a new account with the user name" do login!(session) last_request.session[:flash][:success].should include("Welcome") get_with_session_login "/" follow_redirect_with_session_login!(session) last_response.body.should include("Someone") end end end 
0
source

Source: https://habr.com/ru/post/1385164/


All Articles