From 417d19365de2bc849d5b7cee5913b35431252bc5 Mon Sep 17 00:00:00 2001 From: baarkerlounger Date: Fri, 5 Aug 2022 14:39:23 +0100 Subject: [PATCH] User validation order --- app/models/user.rb | 9 ++++--- config/initializers/devise.rb | 2 +- spec/models/user_spec.rb | 46 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index ee1a2fb5f..bbe81c0ea 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,16 +1,17 @@ class User < ApplicationRecord # Include default devise modules. Others available are: # :omniauthable - include Helpers::Email - devise :database_authenticatable, :recoverable, :rememberable, :validatable, + devise :database_authenticatable, :recoverable, :rememberable, :trackable, :lockable, :two_factor_authenticatable, :confirmable, :timeoutable belongs_to :organisation has_many :owned_case_logs, through: :organisation, dependent: :delete_all has_many :managed_case_logs, through: :organisation - validate :validate_email - validates :name, :email, presence: true + validates :name, presence: true + validates :email, presence: true, uniqueness: true + validates_format_of :email, with: Devise.email_regexp + validates_length_of :password, within: Devise.password_length, allow_blank: true has_paper_trail ignore: %w[last_sign_in_at current_sign_in_at diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 83c73db72..cd1a30ee8 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -184,7 +184,7 @@ Devise.setup do |config| # Email regex used to validate email formats. It simply asserts that # one (and only one) @ exists in the given string. This is mainly # to give user feedback and not to assert the e-mail validity. - config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ + config.email_regexp = URI::MailTo::EMAIL_REGEXP # ==> Configuration for :timeoutable # The time you want to timeout the user session without activity. After this diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index caf8d03d3..e9fb14283 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -225,4 +225,50 @@ RSpec.describe User, type: :model do end end end + + describe "validate" do + let(:organisation) { FactoryBot.create(:organisation) } + + context "when a user does not have values for required fields" do + let(:user) { described_class.new(organisation:) } + + before do + user.validate + end + + it "validates name presence before email presence" do + expect(user.errors.map(&:attribute).uniq).to eq(%i[name email]) + end + end + + context "when a too short password is entered" do + let(:password) { "123" } + let(:error_message) { "Validation failed: Password #{I18n.t('errors.messages.too_short', count: 8)}" } + + it "validates password length" do + expect { FactoryBot.create(:user, password:) } + .to raise_error(ActiveRecord::RecordInvalid, error_message) + end + end + + context "when an invalid email is entered" do + let(:invalid_email) { "not_an_email" } + let(:error_message) { "Validation failed: Email #{I18n.t('activerecord.errors.models.user.attributes.email.invalid')}" } + + it "validates email format" do + expect { FactoryBot.create(:user, email: invalid_email) } + .to raise_error(ActiveRecord::RecordInvalid, error_message) + end + end + + context "when the email entered has already been used" do + let(:user) { FactoryBot.create(:user) } + let(:error_message) { "Validation failed: Email #{I18n.t('activerecord.errors.models.user.attributes.email.taken')}" } + + it "validates email uniqueness" do + expect { FactoryBot.create(:user, email: user.email) } + .to raise_error(ActiveRecord::RecordInvalid, error_message) + end + end + end end