Validating User Authentication Requirements in Devise Framework
This test suite validates the Devise gem’s user authentication functionality, focusing on email and password validation rules. It ensures proper validation of user credentials and authentication requirements in Rails applications.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
heartcombo/devise
test/models/validatable_test.rb
# encoding: UTF-8
# frozen_string_literal: true
require 'test_helper'
class ValidatableTest < ActiveSupport::TestCase
test 'should require email to be set' do
user = new_user(email: nil)
assert user.invalid?
assert user.errors[:email]
assert user.errors.added?(:email, :blank)
end
test 'should require uniqueness of email if email has changed, allowing blank' do
existing_user = create_user
user = new_user(email: '')
assert user.invalid?
assert_no_match(/taken/, user.errors[:email].join)
user.email = existing_user.email
assert user.invalid?
assert_match(/taken/, user.errors[:email].join)
user.save(validate: false)
assert user.valid?
end
test 'should require correct email format if email has changed, allowing blank' do
user = new_user(email: '')
assert user.invalid?
assert_not_equal 'is invalid', user.errors[:email].join
%w{invalid_email_format 123 $$$ () ☃}.each do |email|
user.email = email
assert user.invalid?, "should be invalid with email #{email}"
assert_equal 'is invalid', user.errors[:email].join
end
user.save(validate: false)
assert user.valid?
end
test 'should accept valid emails' do
%w([email protected] [email protected] [email protected] [email protected] [email protected] 1☃[email protected]).each do |email|
user = new_user(email: email)
assert user.valid?, "should be valid with email #{email}"
assert_blank user.errors[:email]
end
end
test 'should require password to be set when creating a new record' do
user = new_user(password: '', password_confirmation: '')
assert user.invalid?
assert user.errors.added?(:password, :blank)
end
test 'should require confirmation to be set when creating a new record' do
user = new_user(password: 'new_password', password_confirmation: 'blabla')
assert user.invalid?
assert user.errors.added?(:password_confirmation, :confirmation, attribute: "Password")
end
test 'should require password when updating/resetting password' do
user = create_user
user.password = ''
user.password_confirmation = ''
assert user.invalid?
assert user.errors.added?(:password, :blank)
end
test 'should require confirmation when updating/resetting password' do
user = create_user
user.password_confirmation = 'another_password'
assert user.invalid?
assert user.errors.added?(:password_confirmation, :confirmation, attribute: "Password")
end
test 'should require a password with minimum of 7 characters' do
user = new_user(password: '12345', password_confirmation: '12345')
assert user.invalid?
assert_equal 'is too short (minimum is 7 characters)', user.errors[:password].join
end
test 'should require a password with maximum of 72 characters long' do
user = new_user(password: 'x'*73, password_confirmation: 'x'*73)
assert user.invalid?
assert_equal 'is too long (maximum is 72 characters)', user.errors[:password].join
end
test 'should not require password length when it\'s not changed' do
user = create_user.reload
user.password = user.password_confirmation = nil
assert user.valid?
user.password_confirmation = 'confirmation'
assert user.invalid?
assert_not (user.errors[:password].join =~ /is too long/)
end
test 'should complain about length even if password is not required' do
user = new_user(password: 'x'*73, password_confirmation: 'x'*73)
user.stubs(:password_required?).returns(false)
assert user.invalid?
assert_equal 'is too long (maximum is 72 characters)', user.errors[:password].join
end
test 'should not be included in objects with invalid API' do
exception = assert_raise RuntimeError do
Class.new.send :include, Devise::Models::Validatable
end
expected_message = /Could not use :validatable module since .* does not respond to the following methods: validates_presence_of.*/
assert_match expected_message, exception.message
end
test 'required_fields should be an empty array' do
assert_equal [], Devise::Models::Validatable.required_fields(User)
end
end