diff --git a/Gemfile b/Gemfile
index 8436ad730..b96c3669b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,9 +2,6 @@ source 'https://rubygems.org'
gem 'rails', '~> 5.2.0.rc1'
-# Temporary lock ffi version. Read more: https://github.com/ffi/ffi/commit/0fef6d44d09018d03c24af7fa4f9fcd38f36b642
-gem 'ffi', '1.9.18'
-
# Use SCSS for stylesheets
gem 'sass-rails'
# Use Uglifier as compressor for JavaScript assets
diff --git a/Gemfile.lock b/Gemfile.lock
index 8dd66b411..3d82d807f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -92,6 +92,7 @@ GEM
momentjs-rails (~> 2.8)
sass-rails (~> 5.0)
selectize-rails (~> 0.6)
+ aes_key_wrap (1.0.1)
apipie-rails (0.5.6)
rails (>= 4.1)
archive-zip (0.11.0)
@@ -106,7 +107,7 @@ GEM
nokogiri (>= 1.4.1)
rubyzip (~> 1.0.0)
bcrypt (3.1.11)
- bindata (2.4.2)
+ bindata (2.4.3)
bindex (0.5.0)
bootstrap-sass (3.3.7)
autoprefixer-rails (>= 5.2.1)
@@ -114,7 +115,7 @@ GEM
bootstrap-wysihtml5-rails (0.3.3.8)
railties (>= 3.0)
brakeman (4.2.0)
- browser (2.5.2)
+ browser (2.5.3)
builder (3.2.3)
byebug (10.0.0)
capybara (2.18.0)
@@ -136,7 +137,7 @@ GEM
carrierwave-i18n (0.2.0)
case_transform (0.2)
activesupport
- chartkick (2.2.5)
+ chartkick (2.3.2)
childprocess (0.8.0)
ffi (~> 1.0, >= 1.0.11)
chromedriver-helper (1.2.0)
@@ -202,7 +203,7 @@ GEM
activesupport (>= 3.0.0)
faraday (0.12.2)
multipart-post (>= 1.2, < 3)
- ffi (1.9.18)
+ ffi (1.9.23)
fission (0.5.0)
CFPropertyList (~> 2.2)
fog (1.42.0)
@@ -419,8 +420,9 @@ GEM
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (2.1.0)
- json-jwt (1.8.3)
+ json-jwt (1.9.2)
activesupport
+ aes_key_wrap
bindata
securecompare
url_safe_base64
@@ -506,10 +508,9 @@ GEM
oauth2 (~> 1.1)
omniauth (~> 1.2)
open4 (1.3.4)
- openid_connect (1.1.4)
+ openid_connect (1.1.5)
activemodel
attr_required (>= 1.0.0)
- json (>= 1.4.3)
json-jwt (>= 1.5.0)
rack-oauth2 (>= 1.6.1)
swd (>= 1.0.0)
@@ -517,7 +518,7 @@ GEM
validate_email
validate_url
webfinger (>= 1.0.1)
- openstack (3.3.15)
+ openstack (3.3.17)
json
orm_adapter (0.5.0)
parallel (1.12.1)
@@ -544,11 +545,11 @@ GEM
rack
rack-mini-profiler (0.10.7)
rack (>= 1.2.0)
- rack-oauth2 (1.8.2)
+ rack-oauth2 (1.9.0)
activesupport
attr_required
httpclient
- json-jwt
+ json-jwt (>= 1.9.0)
rack
rack-protection (2.0.1)
rack
@@ -731,7 +732,7 @@ GEM
turbolinks-source (5.1.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
- uglifier (4.1.6)
+ uglifier (4.1.7)
execjs (>= 0.3.0, < 3)
unf (0.1.4)
unf_ext
@@ -801,7 +802,6 @@ DEPENDENCIES
dotenv-rails
draper
factory_bot
- ffi (= 1.9.18)
fog
fog-openstack
font-awesome-rails
diff --git a/app/controllers/new_gestionnaire/avis_controller.rb b/app/controllers/new_gestionnaire/avis_controller.rb
index 07367a7fd..3fd9b2376 100644
--- a/app/controllers/new_gestionnaire/avis_controller.rb
+++ b/app/controllers/new_gestionnaire/avis_controller.rb
@@ -3,7 +3,7 @@ module NewGestionnaire
before_action :authenticate_gestionnaire!, except: [:sign_up, :create_gestionnaire]
before_action :redirect_if_no_sign_up_needed, only: [:sign_up]
before_action :check_avis_exists_and_email_belongs_to_avis, only: [:sign_up, :create_gestionnaire]
- before_action :set_avis_and_dossier, only: [:show, :instruction, :messagerie, :create_commentaire]
+ before_action :set_avis_and_dossier, only: [:show, :instruction, :messagerie, :create_commentaire, :update]
A_DONNER_STATUS = 'a-donner'
DONNES_STATUS = 'donnes'
@@ -29,12 +29,18 @@ module NewGestionnaire
end
def instruction
+ @new_avis = Avis.new
end
def update
- avis.update(avis_params)
- flash.notice = 'Votre réponse est enregistrée.'
- redirect_to instruction_gestionnaire_avis_path(avis)
+ if @avis.update(avis_params)
+ flash.notice = 'Votre réponse est enregistrée.'
+ redirect_to instruction_gestionnaire_avis_path(@avis)
+ else
+ flash.now.alert = @avis.errors.full_messages
+ @new_avis = Avis.new
+ render :instruction
+ end
end
def messagerie
@@ -55,8 +61,16 @@ module NewGestionnaire
def create_avis
confidentiel = avis.confidentiel || params[:avis][:confidentiel]
- Avis.create(create_avis_params.merge(claimant: current_gestionnaire, dossier: avis.dossier, confidentiel: confidentiel))
- redirect_to instruction_gestionnaire_avis_path(avis)
+ @new_avis = Avis.new(create_avis_params.merge(claimant: current_gestionnaire, dossier: avis.dossier, confidentiel: confidentiel))
+
+ if @new_avis.save
+ flash.notice = "Une demande d'avis a été envoyée à #{@new_avis.email_to_display}"
+ redirect_to instruction_gestionnaire_avis_path(avis)
+ else
+ flash.now.alert = @new_avis.errors.full_messages
+ set_avis_and_dossier
+ render :instruction
+ end
end
def sign_up
diff --git a/app/controllers/new_gestionnaire/dossiers_controller.rb b/app/controllers/new_gestionnaire/dossiers_controller.rb
index c91e0d2b5..e978a348c 100644
--- a/app/controllers/new_gestionnaire/dossiers_controller.rb
+++ b/app/controllers/new_gestionnaire/dossiers_controller.rb
@@ -27,6 +27,7 @@ module NewGestionnaire
def avis
@avis_seen_at = current_gestionnaire.follows.find_by(dossier: dossier)&.avis_seen_at
+ @avis = Avis.new
end
def personnes_impliquees
@@ -159,8 +160,15 @@ module NewGestionnaire
end
def create_avis
- Avis.create(avis_params.merge(claimant: current_gestionnaire, dossier: dossier))
- redirect_to avis_gestionnaire_dossier_path(procedure, dossier)
+ @avis = Avis.new(avis_params.merge(claimant: current_gestionnaire, dossier: dossier))
+ if @avis.save
+ flash.notice = "Une demande d'avis a été envoyée à #{@avis.email_to_display}"
+ redirect_to avis_gestionnaire_dossier_path(procedure, dossier)
+ else
+ flash.now.alert = @avis.errors.full_messages
+ @avis_seen_at = current_gestionnaire.follows.find_by(dossier: dossier)&.avis_seen_at
+ render :avis
+ end
end
def update_annotations
diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb
index 6888a1770..0df3859ce 100644
--- a/app/controllers/root_controller.rb
+++ b/app/controllers/root_controller.rb
@@ -13,7 +13,7 @@ class RootController < ApplicationController
end
if Date.today < Date.new(2018, 03, 31)
- flash.now.notice = ["Téléprocédures Simplifiées change de nom et devient demarches-simplifiees.fr, en savoir plus."]
+ flash.now.notice = ["Téléprocédures Simplifiées change de nom et devient demarches-simplifiees.fr, en savoir plus."]
end
render 'landing'
diff --git a/app/models/administrateur.rb b/app/models/administrateur.rb
index ffd21bd17..94c0498f0 100644
--- a/app/models/administrateur.rb
+++ b/app/models/administrateur.rb
@@ -1,14 +1,16 @@
class Administrateur < ApplicationRecord
+ include CredentialsSyncableConcern
+ include EmailSanitizableConcern
+
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_and_belongs_to_many :gestionnaires
has_many :procedures
+ before_validation -> { sanitize_email(:email) }
before_save :ensure_api_token
- include CredentialsSyncableConcern
-
scope :inactive, -> { where(active: false) }
def self.find_inactive_by_token(reset_password_token)
diff --git a/app/models/avis.rb b/app/models/avis.rb
index e6d78c580..108d24777 100644
--- a/app/models/avis.rb
+++ b/app/models/avis.rb
@@ -1,9 +1,13 @@
class Avis < ApplicationRecord
+ include EmailSanitizableConcern
+
belongs_to :dossier, touch: true
belongs_to :gestionnaire
belongs_to :claimant, class_name: 'Gestionnaire'
- before_save :clean_email
+ validates :email, format: { with: Devise.email_regexp, message: "n'est pas valide" }, allow_nil: true
+
+ before_validation -> { sanitize_email(:email) }
before_create :try_to_assign_gestionnaire
after_create :notify_gestionnaire
@@ -29,12 +33,6 @@ class Avis < ApplicationRecord
private
- def clean_email
- if email.present?
- self.email = email.downcase.strip
- end
- end
-
def notify_gestionnaire
AvisMailer.avis_invitation(self).deliver_now
end
diff --git a/app/models/concerns/email_sanitizable_concern.rb b/app/models/concerns/email_sanitizable_concern.rb
new file mode 100644
index 000000000..d6c715815
--- /dev/null
+++ b/app/models/concerns/email_sanitizable_concern.rb
@@ -0,0 +1,10 @@
+module EmailSanitizableConcern
+ extend ActiveSupport::Concern
+
+ def sanitize_email(attribute)
+ value_to_sanitize = self.send(attribute)
+ if value_to_sanitize.present?
+ self[attribute] = value_to_sanitize.gsub(/[[:space:]]/, ' ').strip.downcase
+ end
+ end
+end
diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb
index a01eddad9..6fc42851d 100644
--- a/app/models/gestionnaire.rb
+++ b/app/models/gestionnaire.rb
@@ -1,9 +1,14 @@
class Gestionnaire < ApplicationRecord
+ include CredentialsSyncableConcern
+ include EmailSanitizableConcern
+
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_and_belongs_to_many :administrateurs
+ before_validation -> { sanitize_email(:email) }
+
has_many :assign_to, dependent: :destroy
has_many :procedures, through: :assign_to
has_many :dossiers, -> { state_not_brouillon }, through: :procedures
@@ -12,8 +17,6 @@ class Gestionnaire < ApplicationRecord
has_many :avis
has_many :dossiers_from_avis, through: :avis, source: :dossier
- include CredentialsSyncableConcern
-
def visible_procedures
procedures.publiees_ou_archivees
end
diff --git a/app/models/invite.rb b/app/models/invite.rb
index 526026634..3abb44e39 100644
--- a/app/models/invite.rb
+++ b/app/models/invite.rb
@@ -1,9 +1,13 @@
class Invite < ApplicationRecord
+ include EmailSanitizableConcern
+
belongs_to :dossier
belongs_to :user
+ before_validation -> { sanitize_email(:email) }
+
validates :email, presence: true
validates :email, uniqueness: { scope: :dossier_id }
- validates :email, email_format: true
+ validates :email, format: { with: Devise.email_regexp, message: "n'est pas valide" }, allow_nil: true
end
diff --git a/app/models/user.rb b/app/models/user.rb
index a495d2f84..83c030beb 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,4 +1,7 @@
class User < ApplicationRecord
+ include CredentialsSyncableConcern
+ include EmailSanitizableConcern
+
enum loged_in_with_france_connect: {
particulier: 'particulier',
entreprise: 'entreprise'
@@ -18,7 +21,7 @@ class User < ApplicationRecord
delegate :given_name, :family_name, :email_france_connect, :gender, :birthdate, :birthplace, :france_connect_particulier_id, to: :france_connect_information
accepts_nested_attributes_for :france_connect_information
- include CredentialsSyncableConcern
+ before_validation -> { sanitize_email(:email) }
def self.find_for_france_connect email, siret
user = User.find_by(email: email)
diff --git a/app/validators/email_format_validator.rb b/app/validators/email_format_validator.rb
deleted file mode 100644
index f9bd0d76d..000000000
--- a/app/validators/email_format_validator.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class EmailFormatValidator < ActiveModel::Validator
- def email_regex
- /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
- end
-
- def validate(record)
- return if record.email.blank?
- record.errors[:base] << "Email invalide" if !email_regex.match(record.email)
- end
-end
diff --git a/app/views/layouts/_new_footer.html.haml b/app/views/layouts/_new_footer.html.haml
index da94e6f41..264c5c331 100644
--- a/app/views/layouts/_new_footer.html.haml
+++ b/app/views/layouts/_new_footer.html.haml
@@ -24,7 +24,7 @@
%li.footer-link
= link_to "CGU", CGU_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-link
- = link_to "Mentions légales", "https://demarches-simplifiees.gitbooks.io/demarches-simplifiees/content/conditions-generales-dutilisation.html#4-mentions-l%C3%A9gales", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
+ = link_to "Mentions légales", "https://demarches-simplifiees.gitbook.io/demarches-simplifiees/cgu#4.-mentions-legales", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-column
%ul.footer-links
@@ -33,7 +33,7 @@
"mailto:#{t('dynamics.contact_email')}",
:class => "footer-link"
%li.footer-link
- = link_to "Documentation", "https://demarches-simplifiees.gitbooks.io/demarches-simplifiees/content/", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
+ = link_to "Documentation", "https://demarches-simplifiees.gitbook.io/demarches-simplifiees/", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-link
= link_to "Documentation de l'API", "/docs", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-link
diff --git a/app/views/new_gestionnaire/avis/instruction.html.haml b/app/views/new_gestionnaire/avis/instruction.html.haml
index 943764c97..1ff164457 100644
--- a/app/views/new_gestionnaire/avis/instruction.html.haml
+++ b/app/views/new_gestionnaire/avis/instruction.html.haml
@@ -21,6 +21,6 @@
.send-wrapper
= f.submit 'Envoyer votre avis', class: 'button send'
- = render partial: "new_gestionnaire/shared/avis/form", locals: { url: avis_gestionnaire_avis_path(@avis), must_be_confidentiel: @avis.confidentiel? }
+ = render partial: "new_gestionnaire/shared/avis/form", locals: { url: avis_gestionnaire_avis_path(@avis), must_be_confidentiel: @avis.confidentiel?, avis: @new_avis }
= render partial: 'new_gestionnaire/shared/avis/list', locals: { avis: @dossier.avis_for(current_gestionnaire), avis_seen_at: nil }
diff --git a/app/views/new_gestionnaire/dossiers/avis.html.haml b/app/views/new_gestionnaire/dossiers/avis.html.haml
index 87ce6b25a..67881abbb 100644
--- a/app/views/new_gestionnaire/dossiers/avis.html.haml
+++ b/app/views/new_gestionnaire/dossiers/avis.html.haml
@@ -3,6 +3,6 @@
= render partial: "header", locals: { dossier: @dossier }
.container
- = render partial: "new_gestionnaire/shared/avis/form", locals: { url: avis_gestionnaire_dossier_path(@dossier.procedure, @dossier), must_be_confidentiel: false }
+ = render partial: "new_gestionnaire/shared/avis/form", locals: { url: avis_gestionnaire_dossier_path(@dossier.procedure, @dossier), must_be_confidentiel: false, avis: @avis }
= render partial: 'new_gestionnaire/shared/avis/list', locals: { avis: @dossier.avis, avis_seen_at: @avis_seen_at }
diff --git a/app/views/new_gestionnaire/shared/avis/_form.html.haml b/app/views/new_gestionnaire/shared/avis/_form.html.haml
index 66e2cfe55..2a660ce51 100644
--- a/app/views/new_gestionnaire/shared/avis/_form.html.haml
+++ b/app/views/new_gestionnaire/shared/avis/_form.html.haml
@@ -2,9 +2,9 @@
%h1.tab-title Inviter une personne à donner son avis
%p.avis-notice L'invité pourra consulter, donner un avis sur le dossier et contribuer au fil de messagerie, mais il ne pourra le modifier.
- = form_for Avis.new, url: url, html: { class: 'form' } do |f|
+ = form_for avis, url: url, html: { class: 'form' } do |f|
= f.email_field :email, placeholder: 'Adresse email', required: true
- = f.text_area :introduction, rows: 3, value: 'Bonjour, merci de me donner votre avis sur ce dossier.', required: true
+ = f.text_area :introduction, rows: 3, value: avis.introduction || 'Bonjour, merci de me donner votre avis sur ce dossier.', required: true
.flex.justify-between.align-baseline
- if must_be_confidentiel
%p.confidentiel.flex
diff --git a/app/views/root/landing.html.haml b/app/views/root/landing.html.haml
index f4a83c69b..a8f44bf2c 100644
--- a/app/views/root/landing.html.haml
+++ b/app/views/root/landing.html.haml
@@ -54,7 +54,7 @@
onclick: "javascript: ga('send', 'pageview', '/demander-une-demo')"
= link_to "Voir la documentation",
- "https://demarches-simplifiees.gitbooks.io/demarches-simplifiees/content/",
+ "https://demarches-simplifiees.gitbook.io/demarches-simplifiees/",
target: "_blank",
rel: "noopener noreferrer",
class: "role-panel-button-secondary"
diff --git a/config/initializers/constants.rb b/config/initializers/constants.rb
index 3644b50cb..95da3f7ed 100644
--- a/config/initializers/constants.rb
+++ b/config/initializers/constants.rb
@@ -1 +1 @@
-CGU_URL = "https://demarches-simplifiees.gitbooks.io/demarches-simplifiees/content/conditions-generales-dutilisation.html"
+CGU_URL = "https://demarches-simplifiees.gitbook.io/demarches-simplifiees/cgu"
diff --git a/config/locales/models/avis/fr.yml b/config/locales/models/avis/fr.yml
new file mode 100644
index 000000000..9d1c31792
--- /dev/null
+++ b/config/locales/models/avis/fr.yml
@@ -0,0 +1,7 @@
+fr:
+ activerecord:
+ models:
+ avis: 'Avis'
+ attributes:
+ avis:
+ answer: "Réponse"
diff --git a/spec/controllers/new_gestionnaire/avis_controller_spec.rb b/spec/controllers/new_gestionnaire/avis_controller_spec.rb
index c34f1ed79..e1bb89021 100644
--- a/spec/controllers/new_gestionnaire/avis_controller_spec.rb
+++ b/spec/controllers/new_gestionnaire/avis_controller_spec.rb
@@ -108,6 +108,16 @@ describe NewGestionnaire::AvisController, type: :controller do
post :create_avis, params: { id: previous_avis.id, avis: { email: email, introduction: intro, confidentiel: asked_confidentiel } }
end
+ context 'when an invalid email' do
+ let(:previous_avis_confidentiel) { false }
+ let(:asked_confidentiel) { false }
+ let(:email) { "toto.fr" }
+
+ it { expect(response).to render_template :instruction }
+ it { expect(flash.alert).to eq(["Email n'est pas valide"]) }
+ it { expect(Avis.last).to eq(previous_avis) }
+ end
+
context 'when the previous avis is public' do
let(:previous_avis_confidentiel) { false }
diff --git a/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb b/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb
index 6f8c67cb4..2c4622bfe 100644
--- a/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb
+++ b/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb
@@ -337,20 +337,34 @@ describe NewGestionnaire::DossiersController, type: :controller do
describe "#create_avis" do
let(:saved_avis) { dossier.avis.first }
- before do
+ subject do
post :create_avis, params: {
procedure_id: procedure.id,
dossier_id: dossier.id,
- avis: { email: 'email@a.com', introduction: 'intro', confidentiel: true }
+ avis: { email: email, introduction: 'intro', confidentiel: true }
}
end
+ before do
+ subject
+ end
+
+ let(:email) { 'email@a.com' }
+
it { expect(saved_avis.email).to eq('email@a.com') }
it { expect(saved_avis.introduction).to eq('intro') }
it { expect(saved_avis.confidentiel).to eq(true) }
it { expect(saved_avis.dossier).to eq(dossier) }
it { expect(saved_avis.claimant).to eq(gestionnaire) }
it { expect(response).to redirect_to(avis_gestionnaire_dossier_path(dossier.procedure, dossier)) }
+
+ context "with an invalid email" do
+ let(:email) { 'emaila.com' }
+
+ it { expect(response).to render_template :avis }
+ it { expect(flash.alert).to eq(["Email n'est pas valide"]) }
+ it { expect { subject }.not_to change(Avis, :count) }
+ end
end
describe "#update_annotations" do
diff --git a/spec/models/avis_spec.rb b/spec/models/avis_spec.rb
index 3ca680440..0cce41b9c 100644
--- a/spec/models/avis_spec.rb
+++ b/spec/models/avis_spec.rb
@@ -118,7 +118,7 @@ RSpec.describe Avis, type: :model do
end
end
- describe "#clean_email" do
+ describe "email sanitization" do
subject { Avis.create(claimant: claimant, email: email, dossier: create(:dossier), gestionnaire: create(:gestionnaire)) }
context "when there is no email" do
diff --git a/spec/models/concern/email_sanitizable_concern_spec.rb b/spec/models/concern/email_sanitizable_concern_spec.rb
new file mode 100644
index 000000000..7b98b7d82
--- /dev/null
+++ b/spec/models/concern/email_sanitizable_concern_spec.rb
@@ -0,0 +1,51 @@
+describe EmailSanitizableConcern, type: :model do
+ describe 'sanitize_email' do
+ let(:email_concern) do
+ (Class.new do
+ include EmailSanitizableConcern
+ attr_accessor :email
+
+ def initialize(email)
+ self.email = email
+ end
+
+ def [](key)
+ self.send(key)
+ end
+
+ def []=(key, value)
+ self.send("#{key}=", value)
+ end
+ end).new(email)
+ end
+
+ before do
+ email_concern.sanitize_email(:email)
+ end
+
+ context 'on an empty email' do
+ let(:email) { '' }
+ it { expect(email_concern.email).to eq('') }
+ end
+
+ context 'on a valid email' do
+ let(:email) { 'michel@toto.fr' }
+ it { expect(email_concern.email).to eq('michel@toto.fr') }
+ end
+
+ context 'on an email with trailing spaces' do
+ let(:email) { ' michel@toto.fr ' }
+ it { expect(email_concern.email).to eq('michel@toto.fr') }
+ end
+
+ context 'on an email with trailing nbsp' do
+ let(:email) { ' michel@toto.fr ' }
+ it { expect(email_concern.email).to eq('michel@toto.fr') }
+ end
+
+ context 'on an invalid email' do
+ let(:email) { 'mich el@toto.fr' }
+ it { expect(email_concern.email).to eq('mich el@toto.fr') }
+ end
+ end
+end
diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb
index 63978930d..e952df95d 100644
--- a/spec/models/invite_spec.rb
+++ b/spec/models/invite_spec.rb
@@ -24,5 +24,36 @@ describe Invite do
it { expect{ subject }.to raise_error ActiveRecord::RecordInvalid }
end
+
+ context "email validation" do
+ let(:invite) { build(:invite, email: email, dossier: dossier1) }
+
+ context 'when an email is invalid' do
+ let(:email) { 'toto.fr' }
+
+ it do
+ expect(invite.save).to be false
+ expect(invite.errors.full_messages).to eq(["Email n'est pas valide"])
+ end
+
+ context 'when an email is empty' do
+ let(:email) { nil }
+
+ it do
+ expect(invite.save).to be false
+ expect(invite.errors.full_messages).to eq(["Email est vide"])
+ end
+ end
+ end
+
+ context 'when an email is valid' do
+ let(:email) { 'toto@toto.fr' }
+
+ it do
+ expect(invite.save).to be true
+ expect(invite.errors.full_messages).to eq([])
+ end
+ end
+ end
end
end