Reputation:
As you can see from the codes below, I already created a user in users.yml
, included the devise's helper for integration test in test_helper.rb
(that's why I was able to use the sign_in
method - based on Devise's README), and have a passing integration test in site_layout_test.rb
.
My question is, when I tried to comment-out the email
, encrypted_password
, and created_at
params of user john in users.yml
, I still have a passing test but my newbie mind tells me that I should have a failing test now since user john is now not a valid user.
What's happening here? Why am I still having a passing test?
By the way, this is the link that helped me how to create a user in users.yml
test/fixtures/users.yml
john:
name: John Rockefeller
email: [email protected]
encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %>
created_at: <%= Time.zone.now %>
test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require "minitest/reporters"
Minitest::Reporters.use!
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
# Add more helper methods to be used by all tests here...
include ApplicationHelper
include Devise::Test::IntegrationHelpers
end
test/integration/site_layout_test.rb
require 'test_helper'
class SiteLayoutTest < ActionDispatch::IntegrationTest
def setup
@user = users(:john)
end
test "layout links" do
# Not signed in
get root_path
assert_template 'static_pages/home'
assert_select "a[href=?]", root_path, count: 2
assert_select "a[href=?]", about_path
assert_select "a[href=?]", new_user_session_path, count: 2
assert_select "a[href=?]", new_user_registration_path
get new_user_registration_path
assert_template 'devise/registrations/new'
assert_select "title", full_title("Sign up")
get new_user_session_path
assert_template 'devise/sessions/new'
assert_select "title", full_title("Sign in")
# Signed in
sign_in @user
get root_path
assert_template 'static_pages/home'
assert_select "a[href=?]", new_user_session_path, count: 0
assert_select "a[href=?]", new_user_registration_path, count: 0
assert_select "a[href=?]", edit_user_registration_path
assert_select "a[href=?]", destroy_user_session_path
get edit_user_registration_path
assert_template 'devise/registrations/edit'
assert_select "title", full_title(@user.name)
end
end
EDIT: SOLVED! My new site_layout_test.rb
below:
require 'test_helper'
class SiteLayoutTest < ActionDispatch::IntegrationTest
def setup
@user = users(:john)
end
test "non-signed in user layout links" do
get root_path
assert_template 'static_pages/home'
assert_select "a[href=?]", root_path, count: 2
assert_select "a[href=?]", about_path
assert_select "a[href=?]", new_user_session_path, count: 2
assert_select "a[href=?]", new_user_registration_path
end
test "signed in user layout links" do
get new_user_session_path
assert_template 'devise/sessions/new'
post user_session_path, params: { user: { email: @user.email, password: 'password' } }
assert_not flash.empty?
assert_redirected_to root_path
follow_redirect!
assert_template 'static_pages/home'
assert_select "a[href=?]", new_user_session_path, count: 0
assert_select "a[href=?]", new_user_registration_path, count: 0
assert_select "a[href=?]", edit_user_registration_path
assert_select "a[href=?]", destroy_user_session_path
end
test "page title" do
get new_user_registration_path
assert_template 'devise/registrations/new'
assert_select "title", full_title("Sign up")
get new_user_session_path
assert_template 'devise/sessions/new'
assert_select "title", full_title("Sign in")
end
end
Upvotes: 2
Views: 1667
Reputation: 2934
There are two things you need to keep in mind.
First, fixtures are inserted directly into the database. The corresponding model is not instantiated. As a consequence, it's possible to insert values which would make model-level validations fail.
Second, sign_in
simply sets the user ID in the session (you can think of it as session[:user_id] = @user.id
). It performs no authentication. It should be used when testing a feature other than authentication (e.g. posting as a user on a forum). It skips the whole request-response cycle related to authentication and lets you go straight to the controller and action you want to test.
In order to test authentication you should fire a POST
request against new_sessions_path
(please substituted the route names you use in your app):
post new_sessions_path, params: { email: '...', password: '...' }
Last but not least, I recommend you split your test into many smaller tests. Especially that you named it layout links
but you test sign in which is confusing.
Upvotes: 2