timpone
timpone

Reputation: 19969

accessing session variables in an Rspec request spec

I am testing a login api for a mobile site using Rspec (2.13.0) request specs. I have a login_user method which correctly writes a user to test database and generates an auth_token in db.

I don't think that the auth_token is being set correctly as a session value in the example "just testing mobile-login-page". I can see though that the redirect occurs after login and that the correct auth_token is send on that redirect (see comment in login_user method).

Is my syntax incorrect (this is my first time using a request spec for something like this)? Would I be better off using a controller spec or using rack-test?

thx in advance

def login_user
  @user = FactoryGirl.create :user
  visit '/arc/signin'
  fill_in 'Email', with: '[email protected]'
  fill_in 'Password', with: 'foobar'
  click_button 'Log in'
  # from test.log showing that auth_token is actually called
  # Processing by UsersController#home as HTML
  # ESC[1mESC[35mUser Load (0.4ms)ESC[0m  SELECT `users`.* FROM `users` WHERE `users`.`auth_token` = 'pCnpG90vIw3qUAoXx3EBsA' LIMIT 1
  #
end

it "just testing the mobile-login-page" do
  login_user
  get '/arc/v1/api/signup-mobile-test'
  puts response.body
  JSON.parse(response.body)[:auth_token] == (@user.auth_token)
end

in controller:

def create_user_test                                           
  m={}                                                         
  m[:status]="success"                                         
  m[:auth_token]=session[:auth_token]
  render :json => m.to_json                                    
end                                                            

and here's the output:

Fri Apr 26$ rspec spec/requests/static_page_spec.rb 
{"status":"success","auth_token":null}
.....

Finished in 0.80587 seconds
5 examples, 0 failures

Upvotes: 0

Views: 2942

Answers (1)

Joe Ferris
Joe Ferris

Reputation: 2732

You're using two different testing harnesses, and they don't share session state.

The visit, fill_in, and click_button methods you're using go through capybara and rack-test: http://rubydoc.info/gems/capybara/Capybara/Session#visit-instance_method

The get method you're using to make the API request is from Rails' built-in integration tests: http://api.rubyonrails.org/classes/ActionDispatch/Integration/RequestHelpers.html#method-i-get

If you use visit instead of get in your second example, the session created from login_user will be visible.

Note that testing an API directly using capybara is generally not recommended, as capybara is designed to interact with the site through the user interface as an actual user would. I'm assuming that you're testing a rich UI with a JavaScript API behind it.

If that's the case, I'd use a combination of two testing approaches:

  • capybara specs which navigate through the user interface and never access the API directly. These specs can use the session generated when logging in.
  • controller specs which directly hit the API to quickly test edge cases and conditions. These specs can pass the session directly to the controller or use a mocking framework to stub out authentication.

Upvotes: 3

Related Questions