I'm trying to run a rake test using devise (using a user that's been created by database seeds)
Running rake test produces the following error:
Failure:
CustomersControllerTest#test_should_get_index [/home/ubuntu/workspace/test/controllers/customers_controller_test.rb:7]:
Expected response to be a <2XX: success>, but was a <302: Found> redirect to <http://www.example.com/users/sign_in>
Response body: <html><body>You are being redirected.</body></html>
My test looks like this:
test "should get index" do
get customers_url
assert_response :success
end
It's a very simple test, but I don't know how to actually login to the site before performing the test.
To test actions that require an authenticated user you can use Devise's sign_in and sign_out helpers. These come from Devise::Test::ControllerHelpers on your test case or its parent class (or Devise::Test::IntegrationHelpers for Rails 5+):
class CustomersControllerTest < ActionController::TestCase
include Devise::Test::ControllerHelpers # <-- Include helpers
test "should get index" do
sign_in User.create(...) # <-- Create and authenticate a user
get customers_url
assert_response :success
end
end
See the controller tests section in the Devise README for details.
Related
my rspec file ->
describe 'GET /users' do
it 'test user list page' do
get '/users'
expect(response).to have_http_status(:success)
end
end
I maked login in my app, but I don't know how to define
'login' with 'before' in rspec file.
my login is using session, and I don't have to use specific user.
how can I check user logged in on rspec request test?
I want to test logged in user can access to /users url in rspec file
you can do it by mocking. The details depend on how your login status is determined, but suppose your application controller has a before_action like this:
# application_controller.rb
before_action :verify_login
# typically the checking is delegated
def verify_login
Authorize.logged_in?(current_user, session)
end
Where the checking is executed in the Authorize service model.
Now in Rspec you just have to mock the response:
before do
current_user = FactoryBot.create(:user)
session = Session.create
expect(Authorize).to receive(:logged_in?).with(current_user, session).and_return(true)
end
it "should respond to logged-in user" do
get '/users'
expect(response).to have_http_status(:success)(
end
I have the following test to ensure sign in is required. Most of the tests require a signed in user, so I have the user sign in on setup. However for this test, I need them signed out.
require 'test_helper'
class DealsControllerTest < ActionDispatch::IntegrationTest
include Warden::Test::Helpers
setup do
#deal = deals(:one)
#user = users(:one)
# https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara
#user.confirmed_at = Time.now
#user.save
login_as(#user, :scope => :user)
end
teardown do
Warden.test_reset!
end
test "require sign in for deal list" do
logout #user
get deals_url
assert_redirected_to new_user_session_path
end
I get the error
Failure:
DealsControllerTest#test_require_sign_in_for_deal_list [C:/Users/Chloe/workspace/fortuneempire/test/controllers/deals_controller_test.rb:35]:
Expected response to be a <3XX: redirect>, but was a <200: OK>
It says it will work, but it's just not working.
https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara
If for some reason you need to log out a logged in test user, you can use Warden's logout helper.
logout(:user)
Rails 5.0.2
Devise 4.2.1
logout by itself without any parameters worked. Maybe logout :user would work too. I wasn't using FactoryGirl so was confusing it for a FactoryGirl symbol.
I have a problem with unit testing in ruby on rails (rails v. 5.001). I use devise and cancancan for authorization. The user needs to login in a test unit, but how can I implement this without redirecting to http://www.example.com/users/sign_in? Here is the code:
appointments_controller_test.rb
require 'test_helper'
class AppointmentsControllerTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
def sign_in(user)
post user_session_path \
"heiko#me.com" => user.email,
"hhdk#s0" => user.password
end
setup do
#heikoAppointment = appointments(:appointment_heiko)
#heiko = users(:user_heiko)
sign_in(#heiko)
end
test "should get index" do
get appointments_url
assert_response :success
end
test "should get new" do
sign_in(#heiko)
get new_appointment_url
assert_response :success
end
And here is the Error I get when I run the test:
Error:
AppointmentsControllerTest#test_should_get_new [C:/Users/Clemens/meindorfladen/Server/test/controllers/appointments_controller_test.rb:33]:
Expected response to be a <2XX: success>, but was a <302: Found> redirect to <http://www.example.com/users/sign_in>
The issue is your user is not confirmed.
You need to pass in
confirmed_at = Time.now
to the user you create. That will then stop you getting redirected.
I was looking at the RailsGuides and I saw this example:
require 'test_helper'
class UserFlowsTest < ActionDispatch::IntegrationTest
test "login and browse site" do
# login via https
https!
get "/login"
assert_response :success
post_via_redirect "/login", username: users(:david).username, password: users(:david).password
assert_equal '/welcome', path
assert_equal 'Welcome david!', flash[:notice]
https!(false)
get "/articles/all"
assert_response :success
assert assigns(:articles)
end
end
I am confused about the variable "path" in the line assert_equal '/welcome', path. What is this exactly? Is this the url that would show up in your browser after we perform the post_via_redirect action right before it?
I looked into the helpers available in the integration tests, but the document didn't say anything about this "path" variable.
Additionally, I try it at my rails app and it works fine, but when I tried to call it at one of my controller tests, it gave me and undefined local variables or method error. So does it mean that the "path" variable is only available in the integration tests? What if I want to use it in the other types of tests?
path is the url of your current page.
path is request.url without the domain name.
In this test you've been redirected from '/login' to '/welcome'.
i want to to write a controler test to check that on a successful sign in, a user is redirected to a certain page. the current test I have at the moment is returning a 200.
require 'rails_helper'
RSpec.describe Admin::EntriesController, :type => :controller do
setup_factories
describe "after login" do
it "should redirect to pending after logged in" do
sign_in admin
expect(response).to redirect_to('admin/entries/pending')
end
end
end
which returns
Failure/Error: expect(response).to redirect_to('admin/entries/pending')
Expected response to be a <redirect>, but was <200>
the relevant controller
class AdminController < Devise::RegistrationsController
before_filter :authenticate_admin!
protected
def after_sign_in_path_for(admin)
pending_admin_entries_path
end
end
am I attempting this is in the right way, where am i going wrong?
thanks
sign_in user in RSpec doesn't make a request so you cannot test the redirection.
For after_sign_in_path, you can test like this:
it 'redirects user to pending admin entries path' do
expect(controller.after_sign_in_path(user)).to eq pending_admin_entries_path
end