Rails: Cucumber + Capybara - How to add http method to visit ()
I have this step definition:
Given /^I am not logged in$/ do
visit '/users/sign_out'
end
And the rake routes give me this:
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
So ... How can I check this? Is there a way to add an HTTP method to Capybara?
I say this because I keep getting this error in my tests:
No route matches [GET] "/users/sign_out" (ActionController::RoutingError)
source to share
Edit:
config.sign_out_via = :delete
for
config.sign_out_via = Rails.env.test? ? :get : :delete
in config/initializers/devise.rb
As explained in the Rails-Devise-Rspec-Cucumber tutorial , by doing this you are going to force Devise to make GET requests for the sign. And this will only happen in test environments ...
source to share
Several things are happening here.
-
You have a step defining the state, but the implementation does the action. I would expect this step to assert that you are not logged in, something like:
current_path.should eq(home_url)
-
The method
visit
will only issue GET requests.RackTest
will simulate delete requests if you provide a link to perform the actionsign_out
you would like to simulate in the browser:within('nav') { click_on('Logout') }
Alternatively, you can navigate to
Rack::Test::Methods
and then directly usedelete
:World(Rack::Test::Methods) Given /^I am not logged in$/ do delete '/users/sign_out' end
You have a trade-off between being correct, like how the user actually logs out, and speed without loading the page at all. You will need to choose which path is right in the context of your scenario and how often you will use this step.
source to share
To expand on Nobita's answer , if you are overriding Devise's default routes, you also need to edit routes.rb
:
as :user do
# Sample custom routes
get '/register' => 'devise/registrations#new', as: :new_user_registration
post '/register' => 'devise/registrations#create', as: :user_registration
get '/login' => 'devise/sessions#new', as: :new_user_session
post '/login' => 'devise/sessions#create', as: :user_session
get '/my-account' => 'devise/registrations#edit', as: :edit_user_registration
# This tells the test environment that GETting the logout path is OK
if Rails.env.test?
get '/logout' => 'devise/sessions#destroy', as: :destroy_user_session
else
delete '/logout' => 'devise/sessions#destroy', as: :destroy_user_session
end
end
source to share