diff --git a/app/assets/stylesheets/new_design/avis_sign_up.scss b/app/assets/stylesheets/new_design/avis_sign_up.scss new file mode 100644 index 000000000..10d6d64ee --- /dev/null +++ b/app/assets/stylesheets/new_design/avis_sign_up.scss @@ -0,0 +1,92 @@ +@import "typography"; +@import "colors"; + +.avis-sign-up { + display: flex; + + .left, + .right { + width: 50%; + padding: 60px 86px; + } + + .left { + p { + margin: auto; + max-width: 410px; + text-align: center; + } + + .description { + font-size: 30px; + line-height: 1.3; + } + + .dossier { + font-size: 18px; + font-weight: bold; + margin-top: 15px; + } + } + + .right { + background-color: $light-grey; + + h1 { + font-size: 36px; + font-weight: bold; + margin-bottom: 60px; + } + + form { + max-width: 420px; + } + + label, + input { + display: block; + width: 100%; + } + + label { + font-size: 14px; + line-height: 1.57; + margin: 24px 0 8px; + } + + input { + border: solid 1px $border-grey; + border-radius: 4px; + height: 56px; + padding: 0 15px; + font-family: Muli; + font-size: 14px; + + &:disabled { + background-color: $border-grey; + } + } + + button { + display: inline-block; + height: 60px; + line-height: 60px; + border: none; + border-radius: 60px; + background-color: $blue; + color: #FFFFFF; + font-size: 16px; + font-weight: bold; + text-align: center; + width: 100%; + margin: 55px 0; + + &:hover { + color: #FFFFFF; + text-decoration: none; + background-color: $light-blue; + cursor: pointer; + } + } + } +} diff --git a/app/controllers/backoffice/avis_controller.rb b/app/controllers/backoffice/avis_controller.rb new file mode 100644 index 000000000..4d77496d2 --- /dev/null +++ b/app/controllers/backoffice/avis_controller.rb @@ -0,0 +1,95 @@ +class Backoffice::AvisController < ApplicationController + + 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] + + def create + avis = Avis.new(create_params.merge(claimant: current_gestionnaire)) + avis.dossier = dossier + + email = create_params[:email] + gestionnaire = Gestionnaire.find_by(email: email) + if gestionnaire + avis.gestionnaire = gestionnaire + avis.email = nil + end + + if avis.save + flash[:notice] = "Votre demande d'avis a bien été envoyée à #{email}" + end + + redirect_to backoffice_dossier_path(dossier) + end + + def update + if avis.update(update_params) + NotificationService.new('avis', params[:dossier_id]).notify + flash[:notice] = 'Merci, votre avis a été enregistré.' + end + + redirect_to backoffice_dossier_path(avis.dossier_id) + end + + def sign_up + @email = params[:email] + @dossier = Avis.includes(:dossier).find(params[:id]).dossier + + render layout: 'new_application' + end + + def create_gestionnaire + email = params[:email] + password = params['gestionnaire']['password'] + + gestionnaire = Gestionnaire.new(email: email, password: password) + + if gestionnaire.save + sign_in(gestionnaire, scope: :gestionnaire) + Avis.link_avis_to_gestionnaire(gestionnaire) + avis = Avis.find(params[:id]) + redirect_to url_for(backoffice_dossier_path(avis.dossier_id)) + else + flash[:alert] = gestionnaire.errors.full_messages.join('
') + redirect_to url_for(avis_sign_up_path(params[:id], email)) + end + end + + private + + def dossier + current_gestionnaire.dossiers.find(params[:dossier_id]) + end + + def avis + current_gestionnaire.avis.find(params[:id]) + end + + def create_params + params.require(:avis).permit(:email, :introduction) + end + + def update_params + params.require(:avis).permit(:answer) + end + + def redirect_if_no_sign_up_needed + avis = Avis.find(params[:id]) + + if current_gestionnaire.present? + # a gestionnaire is authenticated ... lets see if it can view the dossier + + redirect_to backoffice_dossier_url(avis.dossier) + elsif avis.gestionnaire.present? && avis.gestionnaire.email == params[:email] + # the avis gestionnaire has already signed up and it sould sign in + + redirect_to new_gestionnaire_session_url + end + end + + def check_avis_exists_and_email_belongs_to_avis + if !Avis.avis_exists_and_email_belongs_to_avis?(params[:id], params[:email]) + redirect_to url_for(root_path) + end + end +end diff --git a/app/controllers/backoffice/dossiers/procedure_controller.rb b/app/controllers/backoffice/dossiers/procedure_controller.rb index 76b96bf66..88bcf6536 100644 --- a/app/controllers/backoffice/dossiers/procedure_controller.rb +++ b/app/controllers/backoffice/dossiers/procedure_controller.rb @@ -22,4 +22,5 @@ class Backoffice::Dossiers::ProcedureController < Backoffice::DossiersListContro def retrieve_procedure current_gestionnaire.procedures.find params[:id] end + end diff --git a/app/controllers/backoffice/dossiers_controller.rb b/app/controllers/backoffice/dossiers_controller.rb index c2dc2b89c..8cc2260ae 100644 --- a/app/controllers/backoffice/dossiers_controller.rb +++ b/app/controllers/backoffice/dossiers_controller.rb @@ -4,10 +4,13 @@ class Backoffice::DossiersController < Backoffice::DossiersListController before_action :ensure_gestionnaire_is_authorized, only: :show def index + return redirect_to backoffice_invitations_path if current_gestionnaire.avis.any? + procedure = current_gestionnaire.procedure_filter if procedure.nil? procedure_list = dossiers_list_facade.gestionnaire_procedures_name_and_id_list + if procedure_list.count == 0 flash.alert = "Vous n'avez aucune procédure d'affectée." return redirect_to root_path @@ -20,7 +23,8 @@ class Backoffice::DossiersController < Backoffice::DossiersListController end def show - create_dossier_facade params[:id] + dossier_id = params[:id] + create_dossier_facade dossier_id unless @facade.nil? @champs_private = @facade.champs_private @@ -28,7 +32,13 @@ class Backoffice::DossiersController < Backoffice::DossiersListController @headers_private = @champs_private.select { |champ| champ.type_champ == 'header_section' } end - Notification.where(dossier_id: params[:id].to_i).update_all already_read: true + # if the current_gestionnaire does not own the dossier, it is here to give an advice + # and it should not remove the notifications + if current_gestionnaire.dossiers.find_by(id: dossier_id).present? + Notification.where(dossier_id: dossier_id).update_all(already_read: true) + end + + @new_avis = Avis.new(introduction: "Bonjour, merci de me donner votre avis sur ce dossier.") end def filter @@ -185,11 +195,10 @@ class Backoffice::DossiersController < Backoffice::DossiersListController private def ensure_gestionnaire_is_authorized - current_gestionnaire.dossiers.find(params[:id]) - - rescue ActiveRecord::RecordNotFound - flash.alert = t('errors.messages.dossier_not_found') - redirect_to url_for(controller: '/backoffice') + unless current_gestionnaire.can_view_dossier?(params[:id]) + flash.alert = t('errors.messages.dossier_not_found') + redirect_to url_for(controller: '/backoffice') + end end def create_dossier_facade dossier_id diff --git a/app/controllers/backoffice_controller.rb b/app/controllers/backoffice_controller.rb index 7cad9b2a4..fa77609d3 100644 --- a/app/controllers/backoffice_controller.rb +++ b/app/controllers/backoffice_controller.rb @@ -1,4 +1,8 @@ class BackofficeController < ApplicationController + include SmartListing::Helper::ControllerExtensions + helper SmartListing::Helper + + before_action :authenticate_gestionnaire!, only: [:invitations] def index if !gestionnaire_signed_in? @@ -7,4 +11,19 @@ class BackofficeController < ApplicationController redirect_to(:backoffice_dossiers) end end + + def invitations + pending_avis = current_gestionnaire.avis.without_answer.includes(dossier: [:procedure]).by_latest + @pending_avis = smart_listing_create :pending_avis, + pending_avis, + partial: 'backoffice/dossiers/list_invitations', + array: true + + avis_with_answer = current_gestionnaire.avis.with_answer.includes(dossier: [:procedure]).by_latest + @avis_with_answer = smart_listing_create :avis_with_answer, + avis_with_answer, + partial: 'backoffice/dossiers/list_invitations', + array: true + end + end diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb index ec123d601..fec3780b4 100644 --- a/app/controllers/root_controller.rb +++ b/app/controllers/root_controller.rb @@ -14,6 +14,8 @@ class RootController < ApplicationController return redirect_to admin_procedures_path elsif gestionnaire_signed_in? + return redirect_to backoffice_invitations_path if current_gestionnaire.avis.any? + procedure_id = current_gestionnaire.procedure_filter if procedure_id.nil? procedure_list = current_gestionnaire.procedures diff --git a/app/mailers/avis_mailer.rb b/app/mailers/avis_mailer.rb new file mode 100644 index 000000000..601ee464d --- /dev/null +++ b/app/mailers/avis_mailer.rb @@ -0,0 +1,9 @@ +class AvisMailer < ApplicationMailer + + def you_are_invited_on_dossier(avis) + @avis = avis + email = @avis.gestionnaire.try(:email) || @avis.email + mail(to: email, subject: "Donnez votre avis sur le dossier nº #{@avis.dossier.id} (#{@avis.dossier.procedure.libelle})") + end + +end diff --git a/app/models/avis.rb b/app/models/avis.rb new file mode 100644 index 000000000..59eff74fc --- /dev/null +++ b/app/models/avis.rb @@ -0,0 +1,29 @@ +class Avis < ApplicationRecord + belongs_to :dossier + belongs_to :gestionnaire + belongs_to :claimant, class_name: 'Gestionnaire' + + after_create :notify_gestionnaire + + scope :with_answer, -> { where.not(answer: nil) } + scope :without_answer, -> { where(answer: nil) } + scope :for_dossier, ->(dossier_id) { where(dossier_id: dossier_id) } + scope :by_latest, -> { order(updated_at: :desc) } + + def email_to_display + gestionnaire.try(:email) || email + end + + def notify_gestionnaire + AvisMailer.you_are_invited_on_dossier(self).deliver_now + end + + def self.link_avis_to_gestionnaire(gestionnaire) + Avis.where(email: gestionnaire.email).update_all(email: nil, gestionnaire_id: gestionnaire.id) + end + + def self.avis_exists_and_email_belongs_to_avis?(avis_id, email) + avis = Avis.find_by(id: avis_id) + avis.present? && avis.email == email + end +end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index c6eee566f..71506ee9c 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -25,6 +25,7 @@ class Dossier < ActiveRecord::Base has_many :invites_gestionnaires, class_name: 'InviteGestionnaire', dependent: :destroy has_many :follows has_many :notifications, dependent: :destroy + has_many :avis, dependent: :destroy belongs_to :procedure belongs_to :user diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index f4cb1578b..6492cca64 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -12,6 +12,7 @@ class Gestionnaire < ActiveRecord::Base has_many :followed_dossiers, through: :follows, source: :dossier has_many :follows has_many :preference_list_dossiers + has_many :avis after_create :build_default_preferences_list_dossier after_create :build_default_preferences_smart_listing_page @@ -24,6 +25,11 @@ class Gestionnaire < ActiveRecord::Base self[:procedure_filter] end + def can_view_dossier?(dossier_id) + avis.where(dossier_id: dossier_id).any? || + dossiers.where(id: dossier_id).any? + end + def toggle_follow_dossier dossier_id dossier = dossier_id dossier = Dossier.find(dossier_id) unless dossier_id.class == Dossier @@ -41,6 +47,10 @@ class Gestionnaire < ActiveRecord::Base Follow.where(gestionnaire_id: id, dossier_id: dossier_id).any? end + def assigned_on_procedure?(procedure_id) + procedures.find_by(id: procedure_id).present? + end + def build_default_preferences_list_dossier procedure_id=nil PreferenceListDossier.available_columns_for(procedure_id).each do |table| diff --git a/app/models/notification.rb b/app/models/notification.rb index af36da06e..0740ee823 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -5,7 +5,8 @@ class Notification < ActiveRecord::Base cerfa: 'cerfa', piece_justificative: 'piece_justificative', champs: 'champs', - submitted: 'submitted' + submitted: 'submitted', + avis: 'avis' } scope :unread, -> { where(already_read: false) } end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 8c863697c..864b3fcc3 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -3,7 +3,6 @@ class Procedure < ActiveRecord::Base has_many :types_de_champ, class_name: 'TypeDeChampPublic', dependent: :destroy has_many :types_de_champ_private, dependent: :destroy has_many :dossiers - has_many :notifications, through: :dossiers has_one :procedure_path, dependent: :destroy diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 18415ebbd..a401064cf 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -35,6 +35,8 @@ class NotificationService attribut when 'submitted' "Le dossier nº #{@dossier_id} a été déposé." + when 'avis' + 'Un nouvel avis a été rendu' else 'Notification par défaut' end diff --git a/app/views/avis_mailer/you_are_invited_on_dossier.html.haml b/app/views/avis_mailer/you_are_invited_on_dossier.html.haml new file mode 100644 index 000000000..26b129266 --- /dev/null +++ b/app/views/avis_mailer/you_are_invited_on_dossier.html.haml @@ -0,0 +1,28 @@ +%html + %body + %p + Bonjour, + %br + = "Vous avez été invité par #{@avis.claimant.email} à donner votre avis sur le dossier nº #{@avis.dossier.id} de la procédure : #{@avis.dossier.procedure.libelle}." + %br + Message de votre interlocuteur : + + %p{ style: 'border: 1px solid grey' } + = @avis.introduction + + - if @avis.gestionnaire.present? + %p + = link_to "Connectez-vous pour donner votre avis", new_gestionnaire_session_url + - else + %p + = link_to "Inscrivez-vous pour donner votre avis", avis_sign_up_url(@avis.id, @avis.email) + + Bonne journée, + %br + %br + L'équipe Téléprocédures Simplifiées + %br + %br + %hr + %br + Merci de ne pas répondre à cet email. Postez directement vos questions dans votre dossier sur la plateforme. diff --git a/app/views/backoffice/avis/sign_up.html.haml b/app/views/backoffice/avis/sign_up.html.haml new file mode 100644 index 000000000..c02191ce7 --- /dev/null +++ b/app/views/backoffice/avis/sign_up.html.haml @@ -0,0 +1,15 @@ +.avis-sign-up + .left + %p.description= @dossier.procedure.libelle + %p.dossier Dossier n°#{@dossier.id} + .right + %h1 Créez-vous un compte + + = form_for(Gestionnaire.new, url: { controller: 'backoffice/avis', action: :create_gestionnaire }, method: :post) do |f| + = f.label :email, 'Email' + = f.email_field :email, value: @email, disabled: true + + = f.label :password, 'Mot de passe' + = f.password_field :password, autofocus: true, required: true, placeholder: '8 caractères minimum' + + %button Créer un compte diff --git a/app/views/backoffice/dossiers/_list_invitations.html.haml b/app/views/backoffice/dossiers/_list_invitations.html.haml new file mode 100644 index 000000000..526bc5415 --- /dev/null +++ b/app/views/backoffice/dossiers/_list_invitations.html.haml @@ -0,0 +1,20 @@ +- if smart_listing.collection.any? + %table#dossiers-list.table + %thead + %th + Nº + %th + Procédure + %th + Invité le + %tbody + - smart_listing.collection.each do |avis| + %tr.dossier-row{ id: "tr_dossier_#{avis.dossier.id}", 'data-dossier_url' => backoffice_dossier_url(id: avis.dossier.id) } + %td= avis.dossier.id + %td= avis.dossier.procedure.libelle + %td= avis.created_at.strftime('%d/%m/%Y %H:%M') + = smart_listing.paginate + +- else + .center{ colspan: 2 } + %em Aucun dossier diff --git a/app/views/backoffice/invitations.html.haml b/app/views/backoffice/invitations.html.haml new file mode 100644 index 000000000..b9ffaad00 --- /dev/null +++ b/app/views/backoffice/invitations.html.haml @@ -0,0 +1,22 @@ +.col-md-12 + .default-data-block.default_visible + .row.show-block + .header + .title + .carret-right + .carret-down + = "#{@pending_avis.count} avis à rendre" + .body + = smart_listing_render :pending_avis + + %br + + .default-data-block + .row.show-block + .header + .title + .carret-right + .carret-down + = "#{@avis_with_answer.count} avis #{"rendu".pluralize(@avis_with_answer.count)}" + .body + = smart_listing_render :avis_with_answer diff --git a/app/views/backoffice/invitations.js.erb b/app/views/backoffice/invitations.js.erb new file mode 100644 index 000000000..a56437328 --- /dev/null +++ b/app/views/backoffice/invitations.js.erb @@ -0,0 +1,4 @@ +<%= smart_listing_update :pending_avis %> +<%= smart_listing_update :avis_with_answer %> + +link_init(); diff --git a/app/views/dossiers/_avis.html.haml b/app/views/dossiers/_avis.html.haml new file mode 100644 index 000000000..80c896070 --- /dev/null +++ b/app/views/dossiers/_avis.html.haml @@ -0,0 +1,52 @@ +- if current_gestionnaire && current_gestionnaire.assigned_on_procedure?(@facade.dossier.procedure_id) + + .default-data-block.default_visible + .row.show-block.infos + .header + .col-xs-12.title + .carret-right + .carret-down + AVIS EXTERNES + .body + .display-block-on-print + - dossier_facade.dossier.avis.by_latest.each do |avis| + - if avis.answer + .panel.panel-success + .panel-heading + %strong= avis.email_to_display + a donné son avis le + = avis.updated_at.localtime.strftime('%d/%m/%Y à %H:%M') + .panel-body + %strong Vous : + = avis.introduction + %hr + %strong= "#{avis.email_to_display} :" + = avis.answer + - else + .panel.panel-info + .panel-heading + Avis demandé à + %strong= avis.email_to_display + le + = avis.created_at.localtime.strftime('%d/%m/%Y à %H:%M') + .panel-body + %strong Vous : + = avis.introduction + %hr + .center + %em Avis en attente + .hidden-print + .panel.panel-default + .panel-heading + Demander un avis externe + .panel-body + .help-block + Invitez une personne externe à consulter le dossier et à vous donner un avis sur celui ci. + %br + Cette personne pourra également contribuer au fil de messagerie, mais ne pourra pas modifier le dossier. + = simple_form_for @new_avis, url: backoffice_dossier_avis_index_path(dossier_facade.dossier.object.id) do |f| + + = f.input 'email', label: "Email de la personne qui doit donner un avis" + = f.input 'introduction', label: "Message" + + = f.submit "Envoyer la demande d'avis", class: 'btn btn-default' diff --git a/app/views/dossiers/_dossier_show.html.haml b/app/views/dossiers/_dossier_show.html.haml index 632a32f20..cfbe4ee02 100644 --- a/app/views/dossiers/_dossier_show.html.haml +++ b/app/views/dossiers/_dossier_show.html.haml @@ -1,3 +1,5 @@ += render partial: 'dossiers/edit_avis', locals: { dossier_facade: @facade } + = render partial: 'dossiers/messagerie', locals: { dossier_facade: @facade } - if @facade.procedure.individual_with_siret @@ -51,8 +53,7 @@ = render partial: '/users/carte/map', locals: { dossier: @facade.dossier } = render partial: 'users/carte/init_carto', locals: { dossier: @facade.dossier } - -- if @current_gestionnaire && gestionnaire_signed_in? && @champs_private.count > 0 +- if @current_gestionnaire && gestionnaire_signed_in? && current_gestionnaire.assigned_on_procedure?(@facade.dossier.procedure_id) && @champs_private.count > 0 .default-data-block.default_visible .row.show-block#private-fields .header @@ -65,3 +66,5 @@ = (private_fields_count == 1) ? "1 champ" : "#{private_fields_count} champs" .body = render partial: '/dossiers/infos_private_fields' + += render partial: 'dossiers/avis', locals: { dossier_facade: @facade } diff --git a/app/views/dossiers/_edit_avis.html.haml b/app/views/dossiers/_edit_avis.html.haml new file mode 100644 index 000000000..491291793 --- /dev/null +++ b/app/views/dossiers/_edit_avis.html.haml @@ -0,0 +1,13 @@ +- if current_gestionnaire + - avis_for_dossier = current_gestionnaire.avis.for_dossier(dossier_facade.dossier.id).by_latest + - if avis_for_dossier.any? + .panel.panel-default + .panel-body + %h4 Votre avis est sollicité sur le dossier : + - avis_for_dossier.each do |avis| + %hr + %p= avis.introduction + = simple_form_for avis, url: backoffice_dossier_avis_path(dossier_facade.dossier, avis) do |f| + = f.input 'answer', label: "Votre avis" + - submit_label = if avis.answer then "Modifier votre avis" else "Enregistrer votre avis" end + = f.submit submit_label, class: 'btn btn-default' diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml index c1dfe2bd7..d2ea6ea5b 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_index.html.haml @@ -20,6 +20,10 @@ #infos-block .split-hr-left #procedure-list + - if current_gestionnaire.avis.any? + = link_to backoffice_invitations_path do + .procedure-list-element{ class: ('active' if request.path == backoffice_invitations_path) } + Invitations - current_gestionnaire.procedures.by_libelle.each do |procedure| = link_to backoffice_dossiers_procedure_path(procedure.id), { title: procedure.libelle } do .procedure-list-element{ class: ('active' if procedure.id.to_s == params[:id]) } diff --git a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml index a78fa8241..2560a0bb8 100644 --- a/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.html.haml @@ -2,8 +2,8 @@ .infos #dossier_id= t('dynamics.dossiers.numéro') + @facade.dossier.id.to_s -#action-block - - if gestionnaire_signed_in? +- if current_gestionnaire && current_gestionnaire.assigned_on_procedure?(@facade.dossier.procedure_id) + #action-block - if !@facade.dossier.read_only? || @facade.dossier.initiated? = link_to 'Passer en instruction', backoffice_dossier_receive_path(@facade.dossier), method: :post, class: 'btn btn-danger btn-block', data: { confirm: "Confirmer vous le passage en instruction de ce dossier ?" } diff --git a/app/views/layouts/left_panels/_left_panel_backofficecontroller_invitations.html.haml b/app/views/layouts/left_panels/_left_panel_backofficecontroller_invitations.html.haml new file mode 100644 index 000000000..b4114cab1 --- /dev/null +++ b/app/views/layouts/left_panels/_left_panel_backofficecontroller_invitations.html.haml @@ -0,0 +1 @@ += render partial: 'layouts/left_panels/left_panel_backoffice_dossierscontroller_index' diff --git a/app/views/layouts/navbars/_navbar_backoffice_dossierscontroller_show.html.haml b/app/views/layouts/navbars/_navbar_backoffice_dossierscontroller_show.html.haml index 97027181d..6604a98c1 100644 --- a/app/views/layouts/navbars/_navbar_backoffice_dossierscontroller_show.html.haml +++ b/app/views/layouts/navbars/_navbar_backoffice_dossierscontroller_show.html.haml @@ -1,40 +1,43 @@ .col-xs-7.main-info = @facade.dossier.procedure.libelle .col-xs-3.options - .row - .col-xs-12 - - if current_gestionnaire.follow?(@facade.dossier.id) - = link_to backoffice_dossier_follow_path(dossier_id: @facade.dossier.id), "data-method" => :put, class: "button-navbar-action", id: "suivre_dossier_#{@facade.dossier.id}" do - %i.fa.fa-user-times - Ne plus suivre - - else - = link_to backoffice_dossier_follow_path(dossier_id: @facade.dossier.id), 'data-method' => :put, class: 'button-navbar-action', id: "suivre_dossier_#{@facade.dossier.id}" do - %i.fa.fa-user-plus - Suivre le dossier - .row - .col-xs-12 - #invitations.dropdown-toggle{ 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false } - %i.fa.fa-user - = t('utils.involved') - .badge.progress-bar-info - = @facade.dossier.invites.count - .dropdown-menu.dropdown-menu-right.dropdown-pannel - %h4= t('dynamics.dossiers.followers.title') - %ul - - unless @facade.followers.empty? - - @facade.followers.each do |follower| - %li= follower.email - - else - = t('dynamics.dossiers.followers.empty') - %h4= t('dynamics.dossiers.invites.title') - %ul - - unless @facade.invites.empty? - - @facade.invites.each do |invite| - %li= invite.email - - else - = t('dynamics.dossiers.invites.empty') + - if current_gestionnaire.assigned_on_procedure?(@facade.dossier.procedure_id) + .row + .col-xs-12 + - if current_gestionnaire.follow?(@facade.dossier.id) + = link_to backoffice_dossier_follow_path(dossier_id: @facade.dossier.id), "data-method" => :put, class: "button-navbar-action", id: "suivre_dossier_#{@facade.dossier.id}" do + %i.fa.fa-user-times + Ne plus suivre + - else + = link_to backoffice_dossier_follow_path(dossier_id: @facade.dossier.id), 'data-method' => :put, class: 'button-navbar-action', id: "suivre_dossier_#{@facade.dossier.id}" do + %i.fa.fa-user-plus + Suivre le dossier + .row + .col-xs-12 + #invitations.dropdown-toggle{ 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false } + %i.fa.fa-user + = t('utils.involved') + .badge.progress-bar-info + = @facade.dossier.invites.count + .dropdown-menu.dropdown-menu-right.dropdown-pannel + %h4= t('dynamics.dossiers.followers.title') + %ul + - unless @facade.followers.empty? + - @facade.followers.each do |follower| + %li= follower.email + - else + = t('dynamics.dossiers.followers.empty') + %h4= t('dynamics.dossiers.invites.title') + %p + %b Attention, les invitations sur les dossiers vont disparaître en faveur des avis externes situés en bas de la page + %ul + - unless @facade.invites.empty? + - @facade.invites.each do |invite| + %li= invite.email + - else + = t('dynamics.dossiers.invites.empty') - %li - = form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline', id: 'send-invitation' do - = text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation', id: 'invitation-email' - = submit_tag 'Ajouter', class: 'btn btn-success', data: { confirm: "Envoyer l'invitation ?" } + %li + = form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline', id: 'send-invitation' do + = text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation', id: 'invitation-email' + = submit_tag 'Ajouter', class: 'btn btn-success', data: { confirm: "Envoyer l'invitation ?" } diff --git a/app/views/layouts/navbars/_navbar_backofficecontroller_invitations.html.haml b/app/views/layouts/navbars/_navbar_backofficecontroller_invitations.html.haml new file mode 100644 index 000000000..eb80c1517 --- /dev/null +++ b/app/views/layouts/navbars/_navbar_backofficecontroller_invitations.html.haml @@ -0,0 +1,2 @@ +.col-xs-10.main-info + INVITATIONS diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index a3bd49fb8..864ba4221 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -15,6 +15,7 @@ ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.irregular 'type_de_champ', 'types_de_champ' inflect.irregular 'type_de_champ_private', 'types_de_champ_private' inflect.irregular 'assign_to', 'assign_tos' + inflect.irregular('avis', 'avis') end # These inflection rules are supported but not enabled by default: @@ -24,4 +25,5 @@ end ActiveSupport::Inflector.inflections(:fr) do |inflect| inflect.plural(/$/, 's') inflect.plural(/(hib|ch|bij|caill|p|gen|jouj)ou$/i, '\1oux') + inflect.irregular('avis', 'avis') end diff --git a/config/routes.rb b/config/routes.rb index 16b0b090a..8e2c90217 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,6 +30,9 @@ Rails.application.routes.draw do put '/gestionnaires' => 'gestionnaires/registrations#update', :as => 'gestionnaires_registration' end + get 'avis/:id/sign_up/email/:email' => 'backoffice/avis#sign_up', constraints: { email: /.*/ }, as: 'avis_sign_up' + post 'avis/:id/sign_up/email/:email' => 'backoffice/avis#create_gestionnaire', constraints: { email: /.*/ } + devise_scope :administrateur do get '/administrateurs/sign_in/demo' => 'administrateurs/sessions#demo' end @@ -167,6 +170,8 @@ Rails.application.routes.draw do resource :private_formulaire + get 'invitations' + resources :dossiers do post 'receive' => 'dossiers#receive' post 'refuse' => 'dossiers#refuse' @@ -179,6 +184,7 @@ Rails.application.routes.draw do post 'reopen' => 'dossiers#reopen' put 'follow' => 'dossiers#follow' resources :commentaires, only: [:index] + resources :avis, only: [:create, :update] end namespace :dossiers do diff --git a/db/migrate/20170425100757_create_avis.rb b/db/migrate/20170425100757_create_avis.rb new file mode 100644 index 000000000..229be2178 --- /dev/null +++ b/db/migrate/20170425100757_create_avis.rb @@ -0,0 +1,13 @@ +class CreateAvis < ActiveRecord::Migration[5.0] + def change + create_table :avis do |t| + t.string :email + t.text :introduction + t.text :answer + t.references :gestionnaire + t.references :dossier + + t.timestamps + end + end +end diff --git a/db/migrate/20170523092900_add_claimant_to_avis.rb b/db/migrate/20170523092900_add_claimant_to_avis.rb new file mode 100644 index 000000000..c8a34e182 --- /dev/null +++ b/db/migrate/20170523092900_add_claimant_to_avis.rb @@ -0,0 +1,5 @@ +class AddClaimantToAvis < ActiveRecord::Migration[5.0] + def change + add_reference :avis, :claimant, foreign_key: { to_table: :gestionnaires }, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 4af90d2e2..796086d82 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170523081220) do +ActiveRecord::Schema.define(version: 20170523092900) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -71,6 +71,20 @@ ActiveRecord::Schema.define(version: 20170523081220) do t.index ["procedure_id"], name: "index_assign_tos_on_procedure_id", using: :btree end + create_table "avis", force: :cascade do |t| + t.string "email" + t.text "introduction" + t.text "answer" + t.integer "gestionnaire_id" + t.integer "dossier_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "claimant_id", null: false + t.index ["claimant_id"], name: "index_avis_on_claimant_id", using: :btree + t.index ["dossier_id"], name: "index_avis_on_dossier_id", using: :btree + t.index ["gestionnaire_id"], name: "index_avis_on_gestionnaire_id", using: :btree + end + create_table "cadastres", force: :cascade do |t| t.string "surface_intersection" t.float "surface_parcelle" @@ -434,6 +448,7 @@ ActiveRecord::Schema.define(version: 20170523081220) do t.index ["procedure_id"], name: "index_without_continuation_mails_on_procedure_id", using: :btree end + add_foreign_key "avis", "gestionnaires", column: "claimant_id" add_foreign_key "cerfas", "dossiers" add_foreign_key "closed_mails", "procedures" add_foreign_key "commentaires", "dossiers" diff --git a/spec/controllers/backoffice/avis_controller_spec.rb b/spec/controllers/backoffice/avis_controller_spec.rb new file mode 100644 index 000000000..c1af9658b --- /dev/null +++ b/spec/controllers/backoffice/avis_controller_spec.rb @@ -0,0 +1,186 @@ +require 'spec_helper' + +describe Backoffice::AvisController, type: :controller do + + describe '#POST create' do + let(:gestionnaire){ create(:gestionnaire) } + let!(:dossier){ create(:dossier, state: 'received') } + let!(:assign_to){ create(:assign_to, gestionnaire: gestionnaire, procedure: dossier.procedure )} + + subject { post :create, params: { dossier_id: dossier.id, avis: { email: gestionnaire.email, introduction: "Bonjour, regardez ce joli dossier." } } } + + context 'when gestionnaire is not authenticated' do + it { is_expected.to redirect_to new_user_session_path } + it { expect{ subject }.to_not change(Avis, :count) } + end + + context 'when gestionnaire is authenticated' do + before do + sign_in gestionnaire + end + + context 'When gestionnaire is known' do + it { is_expected.to redirect_to backoffice_dossier_path(dossier.id) } + it { expect{ subject }.to change(Avis, :count).by(1) } + it do + subject + expect(gestionnaire.avis.last).to_not eq(nil) + expect(gestionnaire.avis.last.email).to eq(nil) + expect(gestionnaire.avis.last.dossier_id).to eq(dossier.id) + end + end + end + end + + describe '#POST update' do + let(:gestionnaire){ create(:gestionnaire) } + let(:dossier){ create(:dossier, state: 'received') } + let(:avis){ create(:avis, dossier: dossier, gestionnaire: gestionnaire )} + + subject { post :update, params: { dossier_id: dossier.id, id: avis.id, avis: { answer: "Ok ce dossier est valide." } } } + + before :each do + notification = double('notification', notify: true) + allow(NotificationService).to receive(:new).and_return(notification) + end + + context 'when gestionnaire is not authenticated' do + it { is_expected.to redirect_to new_user_session_path } + it { expect(avis.answer).to be_nil } + end + + context 'when gestionnaire is authenticated' do + before do + sign_in gestionnaire + end + + context 'and is invited on dossier' do + it { is_expected.to redirect_to backoffice_dossier_path(dossier.id) } + it do + subject + expect(avis.reload.answer).to eq("Ok ce dossier est valide.") + expect(NotificationService).to have_received(:new).at_least(:once) + end + end + + context 'but is not invited on dossier' do + let(:gestionnaire2) { create(:gestionnaire) } + let(:avis){ create(:avis, dossier: dossier, gestionnaire: gestionnaire2 )} + + it { expect{ subject }.to raise_error(ActiveRecord::RecordNotFound) } + end + end + end + + describe '.sign_up' do + let(:invited_email) { 'invited@avis.com' } + let(:dossier) { create(:dossier) } + let!(:avis) { create(:avis, email: invited_email, dossier: dossier) } + let(:invitations_email) { true } + + context 'when the new gestionnaire has never signed up' do + before do + expect(Avis).to receive(:avis_exists_and_email_belongs_to_avis?) + .with(avis.id.to_s, invited_email) + .and_return(invitations_email) + get :sign_up, params: { id: avis.id, email: invited_email } + end + + context 'when the email belongs to the invitation' do + it { expect(subject.status).to eq(200) } + it { expect(assigns(:email)).to eq(invited_email) } + it { expect(assigns(:dossier)).to eq(dossier) } + end + + context 'when the email does not belong to the invitation' do + let(:invitations_email) { false } + + it { is_expected.to redirect_to root_path } + end + end + + context 'when the gestionnaire has already signed up and belongs to the invitation' do + let(:gestionnaire) { create(:gestionnaire, email: invited_email) } + let!(:avis) { create(:avis, dossier: dossier, gestionnaire: gestionnaire) } + + context 'when the gestionnaire is authenticated' do + before do + sign_in gestionnaire + get :sign_up, params: { id: avis.id, email: invited_email } + end + + it { is_expected.to redirect_to backoffice_dossier_url(avis.dossier) } + end + + context 'when the gestionnaire is not authenticated' do + before do + get :sign_up, params: { id: avis.id, email: invited_email } + end + + it { is_expected.to redirect_to new_gestionnaire_session_url } + end + end + + context 'when the gestionnaire has already signed up / is authenticated and does not belong to the invitation' do + let(:gestionnaire) { create(:gestionnaire, email: 'other@gmail.com') } + let!(:avis) { create(:avis, email: invited_email, dossier: dossier) } + + before do + sign_in gestionnaire + get :sign_up, params: { id: avis.id, email: invited_email } + end + + # redirected to dossier but then the gestionnaire gonna be banished ! + it { is_expected.to redirect_to backoffice_dossier_url(avis.dossier) } + end + end + + describe '.create_gestionnaire' do + let(:invited_email) { 'invited@avis.com' } + let(:dossier) { create(:dossier) } + let!(:avis) { create(:avis, email: invited_email, dossier: dossier) } + let(:avis_id) { avis.id } + let(:password) { '12345678' } + let(:created_gestionnaire) { Gestionnaire.find_by(email: invited_email) } + let(:invitations_email) { true } + + before do + allow(Avis).to receive(:link_avis_to_gestionnaire) + expect(Avis).to receive(:avis_exists_and_email_belongs_to_avis?) + .with(avis_id.to_s, invited_email) + .and_return(invitations_email) + + post :create_gestionnaire, params: { id: avis_id, + email: invited_email, + gestionnaire: { + password: password + } } + end + + context 'when the email does not belong to the invitation' do + let(:invitations_email) { false } + + it { is_expected.to redirect_to root_path } + end + + context 'when the email belongs to the invitation' do + context 'when the gestionnaire creation succeeds' do + it { expect(created_gestionnaire).to be_present } + it { expect(created_gestionnaire.valid_password?(password)).to be true } + + it { expect(Avis).to have_received(:link_avis_to_gestionnaire) } + + it { expect(subject.current_gestionnaire).to eq(created_gestionnaire) } + it { is_expected.to redirect_to backoffice_dossier_path(dossier) } + end + + context 'when the gestionnaire creation fails' do + let(:password) { '' } + + it { expect(created_gestionnaire).to be_nil } + it { is_expected.to redirect_to avis_sign_up_path(avis_id, invited_email) } + it { expect(flash.alert).to eq('Password : Le mot de passe est vide') } + end + end + end +end diff --git a/spec/controllers/backoffice/dossiers_controller_spec.rb b/spec/controllers/backoffice/dossiers_controller_spec.rb index 7ba92db57..a5889ec9f 100644 --- a/spec/controllers/backoffice/dossiers_controller_spec.rb +++ b/spec/controllers/backoffice/dossiers_controller_spec.rb @@ -97,7 +97,7 @@ describe Backoffice::DossiersController, type: :controller do describe 'all notifications unread are changed' do it do - expect(Notification).to receive(:where).with(dossier_id: dossier_id).and_return(Notification::ActiveRecord_Relation) + expect(Notification).to receive(:where).with(dossier_id: dossier_id.to_s).and_return(Notification::ActiveRecord_Relation) expect(Notification::ActiveRecord_Relation).to receive(:update_all).with(already_read: true).and_return(true) subject @@ -109,6 +109,32 @@ describe Backoffice::DossiersController, type: :controller do it { expect(subject).to redirect_to('/backoffice') } end + + describe 'he can invite somebody for avis' do + render_views + + it { expect(subject.body).to include("Invitez une personne externe à consulter le dossier et à vous donner un avis sur celui ci.") } + end + + context 'and is invited on a dossier' do + let(:dossier_invited){ create(:dossier, procedure: create(:procedure)) } + let!(:avis){ create(:avis, dossier: dossier_invited, gestionnaire: gestionnaire) } + + subject { get :show, params: { id: dossier_invited.id } } + + render_views + + it { expect(subject.status).to eq(200) } + it { expect(subject.body).to include("Votre avis est sollicité sur le dossier") } + it { expect(subject.body).to_not include("Invitez une personne externe à consulter le dossier et à vous donner un avis sur celui ci.") } + + describe 'the notifications are not marked as read' do + it do + expect(Notification).not_to receive(:where) + subject + end + end + end end context 'gestionnaire does not connected but dossier id is correct' do diff --git a/spec/controllers/backoffice_controller_spec.rb b/spec/controllers/backoffice_controller_spec.rb index 00db207ae..540f8db82 100644 --- a/spec/controllers/backoffice_controller_spec.rb +++ b/spec/controllers/backoffice_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe BackofficeController, type: :controller do describe 'GET #index' do - context 'when gestionnaire is not connected'do + context 'when gestionnaire is not connected' do before do get :index end @@ -10,7 +10,7 @@ describe BackofficeController, type: :controller do it { expect(response).to redirect_to :new_gestionnaire_session } end - context 'when gestionnaire is connected'do + context 'when gestionnaire is connected' do before do sign_in create(:gestionnaire) get :index @@ -19,4 +19,45 @@ describe BackofficeController, type: :controller do it { expect(response).to redirect_to :backoffice_dossiers } end end + + describe 'GET #invitations' do + context 'when gestionnaire is not invited on any dossiers' do + render_views + + before do + sign_in create(:gestionnaire) + get :invitations + end + + it { expect(response.status).to eq(200) } + it { expect(response.body).to include("INVITATIONS") } + it { expect(response.body).to include("0 avis à rendre") } + it { expect(response.body).to include("0 avis rendus") } + end + + context 'when gestionnaire is invited on a dossier' do + let(:dossier){ create(:dossier) } + let(:gestionnaire){ create(:gestionnaire) } + let!(:avis){ create(:avis, dossier: dossier, gestionnaire: gestionnaire) } + render_views + + before do + sign_in gestionnaire + get :invitations + end + + it { expect(response.status).to eq(200) } + it { expect(response.body).to include("1 avis à rendre") } + it { expect(response.body).to include("0 avis rendus") } + it { expect(response.body).to include(dossier.procedure.libelle) } + + context 'when avis is already sent' do + let!(:avis){ create(:avis, dossier: dossier, gestionnaire: gestionnaire, answer: "Voici mon avis.") } + + it { expect(response.body).to include("0 avis à rendre") } + it { expect(response.body).to include("1 avis rendu") } + it { expect(response.body).to include(dossier.procedure.libelle) } + end + end + end end diff --git a/spec/factories/avis.rb b/spec/factories/avis.rb new file mode 100644 index 000000000..7568cdfe9 --- /dev/null +++ b/spec/factories/avis.rb @@ -0,0 +1,23 @@ +FactoryGirl.define do + factory :avis do + introduction 'Bonjour, merci de me donner votre avis sur ce dossier' + + before(:create) do |avis, _evaluator| + unless avis.gestionnaire + avis.gestionnaire = create :gestionnaire + end + end + + before(:create) do |avis, _evaluator| + unless avis.dossier + avis.dossier = create :dossier + end + end + + before(:create) do |avis, _evaluator| + unless avis.claimant + avis.claimant = create :gestionnaire + end + end + end +end diff --git a/spec/mailers/avis_mailer_spec.rb b/spec/mailers/avis_mailer_spec.rb new file mode 100644 index 000000000..cc5320d7a --- /dev/null +++ b/spec/mailers/avis_mailer_spec.rb @@ -0,0 +1,14 @@ +require "rails_helper" + +RSpec.describe AvisMailer, type: :mailer do + describe '.you_are_invited_on_dossier' do + let(:avis) { create(:avis) } + + subject { described_class.you_are_invited_on_dossier(avis) } + + it { expect(subject.subject).to eq("Donnez votre avis sur le dossier nº #{avis.dossier.id} (#{avis.dossier.procedure.libelle})") } + it { expect(subject.body).to include("Vous avez été invité par #{avis.claimant.email} à donner votre avis sur le dossier nº #{avis.dossier.id} de la procédure : #{avis.dossier.procedure.libelle}.") } + it { expect(subject.body).to include(avis.introduction) } + + end +end diff --git a/spec/mailers/previews/avis_mailer_preview.rb b/spec/mailers/previews/avis_mailer_preview.rb new file mode 100644 index 000000000..c911615e6 --- /dev/null +++ b/spec/mailers/previews/avis_mailer_preview.rb @@ -0,0 +1,8 @@ +# Preview all emails at http://localhost:3000/rails/mailers/avis_mailer +class AvisMailerPreview < ActionMailer::Preview + + def you_are_invited_on_dossier + AvisMailer.you_are_invited_on_dossier(Avis.last) + end + +end diff --git a/spec/models/avis_spec.rb b/spec/models/avis_spec.rb new file mode 100644 index 000000000..231210158 --- /dev/null +++ b/spec/models/avis_spec.rb @@ -0,0 +1,89 @@ +require 'rails_helper' + +RSpec.describe Avis, type: :model do + let(:claimant) { create(:gestionnaire) } + + describe '.email_to_display' do + let(:invited_email) { 'invited@avis.com' } + let!(:avis) do + avis = create(:avis, email: invited_email, dossier: create(:dossier)) + avis.gestionnaire = nil + avis + end + + subject { avis.email_to_display } + + context 'when gestionnaire is not known' do + it{ is_expected.to eq(invited_email) } + end + + context 'when gestionnaire is known' do + let!(:avis) { create(:avis, email: nil, gestionnaire: create(:gestionnaire), dossier: create(:dossier)) } + + it{ is_expected.to eq(avis.gestionnaire.email) } + end + end + + describe '.by_latest' do + context 'with 3 avis' do + let!(:avis){ create(:avis) } + let!(:avis2){ create(:avis, updated_at: 4.hours.ago) } + let!(:avis3){ create(:avis, updated_at: 3.hours.ago) } + + subject { Avis.by_latest } + + it { expect(subject).to eq([avis, avis3, avis2])} + end + end + + describe ".link_avis_to_gestionnaire" do + let(:gestionnaire){ create(:gestionnaire) } + + subject{ Avis.link_avis_to_gestionnaire(gestionnaire) } + + context 'when there are 2 avis linked by email to a gestionnaire' do + let!(:avis){ create(:avis, email: gestionnaire.email, gestionnaire: nil) } + let!(:avis2){ create(:avis, email: gestionnaire.email, gestionnaire: nil) } + + before do + subject + avis.reload + avis2.reload + end + + it { expect(avis.email).to be_nil } + it { expect(avis.gestionnaire).to eq(gestionnaire) } + it { expect(avis2.email).to be_nil } + it { expect(avis2.gestionnaire).to eq(gestionnaire) } + end + end + + describe '.avis_exists_and_email_belongs_to_avis' do + let(:dossier) { create(:dossier) } + let(:invited_email) { 'invited@avis.com' } + let!(:avis) { create(:avis, email: invited_email, dossier: dossier) } + + subject { Avis.avis_exists_and_email_belongs_to_avis?(avis_id, email) } + + context 'when the avis is unknown' do + let(:avis_id) { 666 } + let(:email) { 'unknown@mystery.com' } + + it { is_expected.to be false } + end + + context 'when the avis is known' do + let(:avis_id) { avis.id } + + context 'when the email belongs to the invitation' do + let(:email) { invited_email } + it { is_expected.to be true } + end + + context 'when the email is unknown' do + let(:email) { 'unknown@mystery.com' } + it { is_expected.to be false } + end + end + end +end diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index 27cb3502e..fbfbfd76f 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -395,4 +395,27 @@ describe Gestionnaire, type: :model do it { is_expected.to eq(nil) } end end + + describe '.can_view_dossier?' do + subject{ gestionnaire.can_view_dossier?(dossier.id) } + + context 'when gestionnaire is assigned on dossier' do + let!(:dossier){ create(:dossier, procedure: procedure, state: 'received') } + + it { expect(subject).to be true } + end + + context 'when gestionnaire is invited on dossier' do + let(:dossier){ create(:dossier) } + let!(:avis){ create(:avis, dossier: dossier, gestionnaire: gestionnaire) } + + it { expect(subject).to be true } + end + + context 'when gestionnaire is neither assigned nor invited on dossier' do + let(:dossier){ create(:dossier) } + + it { expect(subject).to be false } + end + end end diff --git a/spec/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show_spec.rb b/spec/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show_spec.rb index dd61a7578..308acb09c 100644 --- a/spec/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show_spec.rb +++ b/spec/views/layouts/left_panels/_left_panel_backoffice_dossierscontroller_show_spec.rb @@ -6,6 +6,7 @@ describe 'layouts/left_panels/_left_panel_backoffice_dossierscontroller_show.htm let(:state) { 'draft' } let(:archived) { false } let(:gestionnaire) { create(:gestionnaire) } + let!(:assign_to) { create(:assign_to, gestionnaire: gestionnaire, procedure: dossier.procedure) } before do sign_in gestionnaire