I am developing an app for Shopify and I want to do integration testing.
I need to be able to store some values in the session variable, so that authentication works.
How could I do that?
I use Capybara and Capybara-webkit.
I am developing an app for Shopify and I want to do integration testing.
I need to be able to store some values in the session variable, so that authentication works.
How could I do that?
I use Capybara and Capybara-webkit.
The accepted answer suggests rack_session_access. It works by inserting middleware controllers to edit and update the session state, then has capybara visit that page and submit a form with the session data. Very ingenious! But unnecessary if you are using Warden (directly or through Devise).
Warden has a hook on_next_request that gives access to the warden mechanism, which can be used to set session keys directly. I threw this together to bundle it up in rspec:
Create spec/support/inject_session.rb
:
module InjectSession
include Warden::Test::Helpers
def inject_session(hash)
Warden.on_next_request do |proxy|
hash.each do |key, value|
proxy.raw_session[key] = value
end
end
end
end
In spec/spec_helper.rb
include the module in feature specs:
RSpec.configure do |config|
config.include InjectSession, :type => :feature
end
Then sample use in a spec might be:
inject_session :magic => 'pixie dust', :color => 'pink'
visit shopping_cart_path
page.should be_all_sparkly_and_pink # or whatever
You can use something like VCR or webmock to stub out the call to the external http resource.
As the comment by apneadiving recommends, you should fill the form out "directly" using capybara. Testing using Cucumber might look like this for filling in a login form for authentication (from the Capybara github page):
When /I sign in/ do
within("#session") do
fill_in 'Login', :with => 'user@example.com'
fill_in 'Password', :with => 'password'
end
click_link 'Sign in'
...
end
If you trying to do something different or are having trouble with the normal login process, this SO question may help.
I fear I bring bad news, but from Capybara's documentation:
Access to session and request is not possible from the test, Access to response is limited.
So you won't be able to test as you expect.
Just thinking: it would be acceptable that you insert some conditional statement in your controller for test purpose.:
session[:foo] = User.first.id if Rails.env.test?
A better option would be to monkey patch your controller only for your integration tests.