feat(email.validation): expand email validation to Avis, ContactInformation, Invite, DossierTransfert
This commit is contained in:
parent
05193e1d1e
commit
5f77c0cd06
18 changed files with 45 additions and 31 deletions
|
@ -22,7 +22,7 @@ class SimpleFormatComponent < ApplicationComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMPLE_URL_REGEX = %r{https?://[^\s<>]+}
|
SIMPLE_URL_REGEX = %r{https?://[^\s<>]+}
|
||||||
EMAIL_IN_TEXT_REGEX = Regexp.new(Devise.email_regexp.source.gsub(/\\A|\\z/, '\b'))
|
EMAIL_IN_TEXT_REGEX = Regexp.new(StrictEmailValidator::REGEXP.source.gsub(/\\A|\\z/, '\b'))
|
||||||
|
|
||||||
def initialize(text, allow_a: true, allow_autolink: true, class_names_map: {})
|
def initialize(text, allow_a: true, allow_autolink: true, class_names_map: {})
|
||||||
@allow_a = allow_a
|
@allow_a = allow_a
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Users::SessionsController < Devise::SessionsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_sent
|
def link_sent
|
||||||
if Devise.email_regexp.match?(params[:email])
|
if StrictEmailValidator::REGEXP.match?(params[:email])
|
||||||
@email = params[:email]
|
@email = params[:email]
|
||||||
else
|
else
|
||||||
redirect_to root_path
|
redirect_to root_path
|
||||||
|
|
|
@ -21,7 +21,7 @@ class Avis < ApplicationRecord
|
||||||
content_type: AUTHORIZED_CONTENT_TYPES,
|
content_type: AUTHORIZED_CONTENT_TYPES,
|
||||||
size: { less_than: FILE_MAX_SIZE }
|
size: { less_than: FILE_MAX_SIZE }
|
||||||
|
|
||||||
validates :email, format: { with: Devise.email_regexp, message: "n'est pas valide" }, allow_nil: true
|
validates :email, strict_email: true, allow_nil: true
|
||||||
validates :question_answer, inclusion: { in: [true, false] }, on: :update, if: -> { question_label.present? }
|
validates :question_answer, inclusion: { in: [true, false] }, on: :update, if: -> { question_label.present? }
|
||||||
validates :piece_justificative_file, size: { less_than: FILE_MAX_SIZE }
|
validates :piece_justificative_file, size: { less_than: FILE_MAX_SIZE }
|
||||||
validates :introduction_file, size: { less_than: FILE_MAX_SIZE }
|
validates :introduction_file, size: { less_than: FILE_MAX_SIZE }
|
||||||
|
|
|
@ -11,7 +11,7 @@ module UserFindByConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_all_by_identifier_with_emails(ids: [], emails: [])
|
def self.find_all_by_identifier_with_emails(ids: [], emails: [])
|
||||||
valid_emails, invalid_emails = emails.partition { Devise.email_regexp.match?(_1) }
|
valid_emails, invalid_emails = emails.partition { StrictEmailValidator::REGEXP.match?(_1) }
|
||||||
|
|
||||||
[
|
[
|
||||||
where(id: ids).or(where(users: { email: valid_emails })).distinct(:id),
|
where(id: ids).or(where(users: { email: valid_emails })).distinct(:id),
|
||||||
|
|
|
@ -3,7 +3,7 @@ class ContactInformation < ApplicationRecord
|
||||||
|
|
||||||
validates :nom, presence: { message: 'doit être renseigné' }, allow_nil: false
|
validates :nom, presence: { message: 'doit être renseigné' }, allow_nil: false
|
||||||
validates :nom, uniqueness: { scope: :groupe_instructeur, message: 'existe déjà' }
|
validates :nom, uniqueness: { scope: :groupe_instructeur, message: 'existe déjà' }
|
||||||
validates :email, format: { with: Devise.email_regexp, message: "n'est pas valide" }, presence: { message: 'doit être renseigné' }, allow_nil: false
|
validates :email, strict_email: true, presence: { message: 'doit être renseigné' }, allow_nil: false
|
||||||
validates :telephone, phone: { possible: true, allow_blank: false }
|
validates :telephone, phone: { possible: true, allow_blank: false }
|
||||||
validates :horaires, presence: { message: 'doivent être renseignés' }, allow_nil: false
|
validates :horaires, presence: { message: 'doivent être renseignés' }, allow_nil: false
|
||||||
validates :adresse, presence: { message: 'doit être renseignée' }, allow_nil: false
|
validates :adresse, presence: { message: 'doit être renseignée' }, allow_nil: false
|
||||||
|
|
|
@ -4,7 +4,7 @@ class DossierTransfer < ApplicationRecord
|
||||||
|
|
||||||
EXPIRATION_LIMIT = 2.weeks
|
EXPIRATION_LIMIT = 2.weeks
|
||||||
|
|
||||||
validates :email, format: { with: Devise.email_regexp }
|
validates :email, strict_email: true, presence: true
|
||||||
before_validation -> { sanitize_email(:email) }
|
before_validation -> { sanitize_email(:email) }
|
||||||
|
|
||||||
scope :pending, -> { where('created_at > ?', (Time.zone.now - EXPIRATION_LIMIT)) }
|
scope :pending, -> { where('created_at > ?', (Time.zone.now - EXPIRATION_LIMIT)) }
|
||||||
|
|
|
@ -11,8 +11,7 @@ class Invite < ApplicationRecord
|
||||||
|
|
||||||
validates :email, presence: true
|
validates :email, presence: true
|
||||||
validates :email, uniqueness: { scope: :dossier_id }
|
validates :email, uniqueness: { scope: :dossier_id }
|
||||||
|
validates :email, strict_email: true, allow_nil: true
|
||||||
validates :email, format: { with: Devise.email_regexp, message: "n'est pas valide" }, allow_nil: true
|
|
||||||
|
|
||||||
scope :with_dossiers, -> { joins(:dossier).merge(Dossier.visible_by_user) }
|
scope :with_dossiers, -> { joins(:dossier).merge(Dossier.visible_by_user) }
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,8 @@ class User < ApplicationRecord
|
||||||
before_validation -> { sanitize_email(:email) }
|
before_validation -> { sanitize_email(:email) }
|
||||||
validate :does_not_merge_on_self, if: :requested_merge_into_id_changed?
|
validate :does_not_merge_on_self, if: :requested_merge_into_id_changed?
|
||||||
|
|
||||||
with_options if: :elligible_to_new_validation? do
|
before_validation :remove_devise_email_validator
|
||||||
before_validation :remove_devise_email_validator
|
validates :email, strict_email: true
|
||||||
validates :email, strict_email: true
|
|
||||||
end
|
|
||||||
|
|
||||||
def validate_password_complexity?
|
def validate_password_complexity?
|
||||||
administrateur?
|
administrateur?
|
||||||
|
@ -274,10 +272,6 @@ class User < ApplicationRecord
|
||||||
Invite.where(email: email).update_all(user_id: id)
|
Invite.where(email: email).update_all(user_id: id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def elligible_to_new_validation?
|
|
||||||
StrictEmailValidator.elligible_to_new_validation?(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_devise_email_validator
|
def remove_devise_email_validator
|
||||||
_validators[:email]&.reject! { _1.is_a?(ActiveModel::Validations::FormatValidator) }
|
_validators[:email]&.reject! { _1.is_a?(ActiveModel::Validations::FormatValidator) }
|
||||||
_validate_callbacks.each do |callback|
|
_validate_callbacks.each do |callback|
|
||||||
|
|
|
@ -605,7 +605,7 @@ en:
|
||||||
not_a_phone: 'Invalid phone number'
|
not_a_phone: 'Invalid phone number'
|
||||||
not_a_rna: 'Invalid RNA number'
|
not_a_rna: 'Invalid RNA number'
|
||||||
url: 'is not a valid link'
|
url: 'is not a valid link'
|
||||||
invalid_email_format: "is not a valid email"
|
invalid_email_format: "is invalid. Please fill in a valid email ex: john.doe@exemple.fr"
|
||||||
models:
|
models:
|
||||||
attestation_template:
|
attestation_template:
|
||||||
attributes:
|
attributes:
|
||||||
|
|
|
@ -608,7 +608,7 @@ fr:
|
||||||
not_a_phone: 'Numéro de téléphone invalide'
|
not_a_phone: 'Numéro de téléphone invalide'
|
||||||
not_a_rna: 'Numéro RNA invalide'
|
not_a_rna: 'Numéro RNA invalide'
|
||||||
url: 'n’est pas un lien valide'
|
url: 'n’est pas un lien valide'
|
||||||
invalid_email_format: "n'est pas un email valide"
|
invalid_email_format: "est invalide. Saisir une adresse électronique valide, exemple : john.doe@exemple.fr"
|
||||||
models:
|
models:
|
||||||
attestation_template:
|
attestation_template:
|
||||||
attributes:
|
attributes:
|
||||||
|
|
|
@ -346,8 +346,9 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the admin wants to assign an instructor who is already assigned on this procedure' do
|
context 'when the admin wants to assign an instructor who is already assigned on this procedure' do
|
||||||
let(:emails) { ['instructeur_1@ministere_a.gouv.fr'].to_json }
|
let(:instructeur) { create(:instructeur) }
|
||||||
it { expect(subject.request.flash[:alert]).to be_present }
|
before { procedure_non_routee.groupe_instructeurs.first.add_instructeurs(emails: [instructeur.user.email]) }
|
||||||
|
let(:emails) { [instructeur.email].to_json }
|
||||||
it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure_non_routee) }
|
it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure_non_routee) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -414,7 +414,7 @@ describe Experts::AvisController, type: :controller do
|
||||||
|
|
||||||
it do
|
it do
|
||||||
expect(response).to render_template :instruction
|
expect(response).to render_template :instruction
|
||||||
expect(flash.alert).to eq(["toto.fr : Le champ « Email » n'est pas valide"])
|
expect(flash.alert).to eq(["toto.fr : Le champ « Email » est invalide. Saisir une adresse électronique valide, exemple : john.doe@exemple.fr"])
|
||||||
expect(Avis.last).to eq(previous_avis)
|
expect(Avis.last).to eq(previous_avis)
|
||||||
expect(dossier.last_avis_updated_at).to eq(nil)
|
expect(dossier.last_avis_updated_at).to eq(nil)
|
||||||
end
|
end
|
||||||
|
@ -445,7 +445,7 @@ describe Experts::AvisController, type: :controller do
|
||||||
|
|
||||||
it do
|
it do
|
||||||
expect(response).to render_template :instruction
|
expect(response).to render_template :instruction
|
||||||
expect(flash.alert).to eq(["toto.fr : Le champ « Email » n'est pas valide"])
|
expect(flash.alert).to eq(["toto.fr : Le champ « Email » est invalide. Saisir une adresse électronique valide, exemple : john.doe@exemple.fr"])
|
||||||
expect(flash.notice).to eq("Une demande d’avis a été envoyée à titi@titimail.com")
|
expect(flash.notice).to eq("Une demande d’avis a été envoyée à titi@titimail.com")
|
||||||
expect(Avis.count).to eq(old_avis_count + 1)
|
expect(Avis.count).to eq(old_avis_count + 1)
|
||||||
end
|
end
|
||||||
|
|
|
@ -798,7 +798,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
||||||
before { subject }
|
before { subject }
|
||||||
|
|
||||||
it { expect(response).to render_template :avis }
|
it { expect(response).to render_template :avis }
|
||||||
it { expect(flash.alert).to eq(["emaila.com : Le champ « Email » n'est pas valide"]) }
|
it { expect(flash.alert).to eq(["emaila.com : Le champ « Email » est invalide. Saisir une adresse électronique valide, exemple : john.doe@exemple.fr"]) }
|
||||||
it { expect { subject }.not_to change(Avis, :count) }
|
it { expect { subject }.not_to change(Avis, :count) }
|
||||||
it { expect(dossier.last_avis_updated_at).to eq(nil) }
|
it { expect(dossier.last_avis_updated_at).to eq(nil) }
|
||||||
end
|
end
|
||||||
|
@ -820,7 +820,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
||||||
before { subject }
|
before { subject }
|
||||||
|
|
||||||
it { expect(response).to render_template :avis }
|
it { expect(response).to render_template :avis }
|
||||||
it { expect(flash.alert).to eq(["toto.fr : Le champ « Email » n'est pas valide"]) }
|
it { expect(flash.alert).to eq(["toto.fr : Le champ « Email » est invalide. Saisir une adresse électronique valide, exemple : john.doe@exemple.fr"]) }
|
||||||
it { expect(flash.notice).to eq("Une demande d’avis a été envoyée à titi@titimail.com") }
|
it { expect(flash.notice).to eq("Une demande d’avis a été envoyée à titi@titimail.com") }
|
||||||
it { expect(Avis.count).to eq(old_avis_count + 1) }
|
it { expect(Avis.count).to eq(old_avis_count + 1) }
|
||||||
it { expect(saved_avis.expert.email).to eq("titi@titimail.com") }
|
it { expect(saved_avis.expert.email).to eq("titi@titimail.com") }
|
||||||
|
|
|
@ -54,7 +54,7 @@ describe Manager::DossiersController, type: :controller do
|
||||||
|
|
||||||
it do
|
it do
|
||||||
expect { subject }.not_to have_enqueued_mail
|
expect { subject }.not_to have_enqueued_mail
|
||||||
expect(flash[:alert]).to eq("L’adresse email est invalide")
|
expect(flash[:alert]).to eq("L’adresse email est invalide. Saisir une adresse électronique valide, exemple : john.doe@exemple.fr")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -134,7 +134,7 @@ describe Users::ProfilController, type: :controller do
|
||||||
|
|
||||||
it "should not transfer to an empty email" do
|
it "should not transfer to an empty email" do
|
||||||
expect { subject }.not_to change { DossierTransfer.count }
|
expect { subject }.not_to change { DossierTransfer.count }
|
||||||
expect(flash.alert).to eq(["L’adresse email est invalide"])
|
expect(flash.alert).to eq(["L’adresse email doit être rempli"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -84,18 +84,22 @@ describe Users::TransfersController, type: :controller do
|
||||||
|
|
||||||
shared_examples 'email error' do
|
shared_examples 'email error' do
|
||||||
it { expect { subject }.not_to change { DossierTransfer.count } }
|
it { expect { subject }.not_to change { DossierTransfer.count } }
|
||||||
it { expect(flash.alert).to match([/invalide/]) }
|
it { expect(flash.alert).to include(expected_error) }
|
||||||
it { is_expected.to redirect_to transferer_dossier_path(dossier.id) }
|
it { is_expected.to redirect_to transferer_dossier_path(dossier.id) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when email is empty" do
|
context "when email is empty" do
|
||||||
let(:email) { "" }
|
let(:email) { "" }
|
||||||
it_behaves_like 'email error'
|
it_behaves_like 'email error' do
|
||||||
|
let(:expected_error) { 'L’adresse email doit être rempli' }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when email is invalid" do
|
context "when email is invalid" do
|
||||||
let(:email) { "not-an-email" }
|
let(:email) { "not-an-email" }
|
||||||
it_behaves_like 'email error'
|
it_behaves_like 'email error' do
|
||||||
|
let(:expected_error) { "L’adresse email est invalide. Saisir une adresse électronique valide, exemple : john.doe@exemple.fr" }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,7 +39,7 @@ RSpec.describe Avis, type: :model do
|
||||||
before do
|
before do
|
||||||
avis.reload
|
avis.reload
|
||||||
end
|
end
|
||||||
|
it { expect(avis.valid?).to be_truthy }
|
||||||
it { expect(avis.email).to be_nil }
|
it { expect(avis.email).to be_nil }
|
||||||
it { expect(avis.experts_procedure).to eq(experts_procedure) }
|
it { expect(avis.experts_procedure).to eq(experts_procedure) }
|
||||||
end
|
end
|
||||||
|
@ -75,6 +75,22 @@ RSpec.describe Avis, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'email validation' do
|
||||||
|
let(:now_invalid_email) { "toto@tps" }
|
||||||
|
context 'new avis' do
|
||||||
|
before { allow(StrictEmailValidator).to receive(:elligible_to_new_validation?).and_return(true) }
|
||||||
|
|
||||||
|
it { expect(build(:avis, email: now_invalid_email).valid?).to be_falsey }
|
||||||
|
it { expect(build(:avis, email: nil).valid?).to be_truthy }
|
||||||
|
end
|
||||||
|
context 'old avis' do
|
||||||
|
before { allow(StrictEmailValidator).to receive(:elligible_to_new_validation?).and_return(false) }
|
||||||
|
|
||||||
|
it { expect(build(:avis, email: now_invalid_email).valid?).to be_truthy }
|
||||||
|
it { expect(build(:avis, email: nil).valid?).to be_truthy }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe ".revoke_by!" do
|
describe ".revoke_by!" do
|
||||||
let(:claimant) { create(:instructeur) }
|
let(:claimant) { create(:instructeur) }
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ describe Invite do
|
||||||
|
|
||||||
it do
|
it do
|
||||||
expect(invite.save).to be false
|
expect(invite.save).to be false
|
||||||
expect(invite.errors.full_messages).to eq(["Le champ « Email » n'est pas valide"])
|
expect(invite.errors.full_messages).to eq(["Le champ « Email » est invalide. Saisir une adresse électronique valide, exemple : john.doe@exemple.fr"])
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when an email is empty' do
|
context 'when an email is empty' do
|
||||||
|
|
Loading…
Reference in a new issue