Reputation: 165
I have a restriction on my Rails DB to force unique usernames, and I create a user at the start of each of my model tests. I'm trying to create a second user with the same username as the first and I expect this to not be valid, but it is returning as valid.
I've tried tweaking the code to use the new, save, and create methods when generating new users but with no success.
Registration Model:
class Registration < ApplicationRecord
@username_length = (3..20)
@password_requirements = /\A
(?=.{8,}) # Password must be at least 8 characters
(?=.*\d) # Password must contain at least one number
(?=.*[a-z]) # Password must contain at least one lowercase letter
(?=.*[A-Z]) # Password must contain at least one capital letter
# Password must have special character
(?=.*[['!', '@', '#', '$', '%', '^', '&']])
/x
validates :username, length: @username_length, uniqueness: true
validates :password, format: @password_requirements
validates :email, uniqueness: true
has_secure_password
has_secure_token :auth_token
def invalidate_token
self.update_columns(auth_token: nil)
end
def self.validate_login(username, password)
user = Registration.find_by(username: username)
if user && user.authenticate(password)
user
end
end
end
Registration Tests:
require 'rails_helper'
RSpec.describe Registration, type: :model do
before do
@user = Registration.new(
username: '1234',
password: 'abcdeF7#',
email: '[email protected]',
name: 'One'
)
end
it 'should not be valid if the username is already taken' do
@user.save!(username: '1234')
expect(@user).not_to be_valid
end
end
I would expect this test to pass due to it being a duplicate username.
Upvotes: 1
Views: 1060
Reputation: 159
As fabio said, you dont have second Registration object to check uniquness. You just checked your saved @user is valid or not which is always valid and saved in DB. To check your uniqueness validation you can do something like this -
RSpec.describe Registration, type: :model do
before do
@user = Registration.create(
username: '1234',
password: 'abcdeF7#',
email: '[email protected]',
name: 'One'
)
@invalid_user = @user.dup
@invalid_user.email = "[email protected]"
end
it 'should not be valid if the username is already taken' do
expect(@invalid_user.valid?).should be_falsey
end
end
Upvotes: 3
Reputation: 1089
@user.save!
will raise an error even before reaching the expect as mentioned in comments by Fabio
Also, if it is important to you to test db level constraint you can do:
expect { @user.save validate: false }.to raise_error(ActiveRecord::RecordNotUnique)
Upvotes: 1