commit
e3908065d6
22 changed files with 161 additions and 39 deletions
2
Gemfile
2
Gemfile
|
@ -5,7 +5,7 @@ gem 'actiontext', git: 'https://github.com/kobaltz/actiontext.git', branch: 'arc
|
||||||
gem 'active_link_to' # Automatically set a class on active links
|
gem 'active_link_to' # Automatically set a class on active links
|
||||||
gem 'active_model_serializers'
|
gem 'active_model_serializers'
|
||||||
gem 'active_storage_validations'
|
gem 'active_storage_validations'
|
||||||
gem 'activestorage-openstack', git: 'https://github.com/tchak/activestorage-openstack.git', branch: 'fix-activestorage-filename-wrap'
|
gem 'activestorage-openstack'
|
||||||
gem 'administrate'
|
gem 'administrate'
|
||||||
gem 'after_party'
|
gem 'after_party'
|
||||||
gem 'anchored'
|
gem 'anchored'
|
||||||
|
|
20
Gemfile.lock
20
Gemfile.lock
|
@ -15,17 +15,6 @@ GIT
|
||||||
open4 (~> 1.3.4)
|
open4 (~> 1.3.4)
|
||||||
rake
|
rake
|
||||||
|
|
||||||
GIT
|
|
||||||
remote: https://github.com/tchak/activestorage-openstack.git
|
|
||||||
revision: 907582f14d785fb965baebe9524c0162b1bd57c9
|
|
||||||
branch: fix-activestorage-filename-wrap
|
|
||||||
specs:
|
|
||||||
activestorage-openstack (1.3.0)
|
|
||||||
fog-openstack (~> 1.0)
|
|
||||||
marcel
|
|
||||||
mime-types
|
|
||||||
rails (>= 5.2.2)
|
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
|
@ -77,6 +66,11 @@ GEM
|
||||||
actionpack (= 5.2.4.1)
|
actionpack (= 5.2.4.1)
|
||||||
activerecord (= 5.2.4.1)
|
activerecord (= 5.2.4.1)
|
||||||
marcel (~> 0.3.1)
|
marcel (~> 0.3.1)
|
||||||
|
activestorage-openstack (1.4.1)
|
||||||
|
fog-openstack (~> 1.0)
|
||||||
|
marcel
|
||||||
|
mime-types
|
||||||
|
rails (>= 5.2.2)
|
||||||
activesupport (5.2.4.1)
|
activesupport (5.2.4.1)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
|
@ -458,7 +452,7 @@ GEM
|
||||||
byebug (~> 10.0)
|
byebug (~> 10.0)
|
||||||
pry (~> 0.10)
|
pry (~> 0.10)
|
||||||
public_suffix (4.0.3)
|
public_suffix (4.0.3)
|
||||||
puma (3.12.2)
|
puma (3.12.4)
|
||||||
pundit (2.0.1)
|
pundit (2.0.1)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
rack (2.2.2)
|
rack (2.2.2)
|
||||||
|
@ -723,7 +717,7 @@ DEPENDENCIES
|
||||||
active_link_to
|
active_link_to
|
||||||
active_model_serializers
|
active_model_serializers
|
||||||
active_storage_validations
|
active_storage_validations
|
||||||
activestorage-openstack!
|
activestorage-openstack
|
||||||
administrate
|
administrate
|
||||||
after_party
|
after_party
|
||||||
anchored
|
anchored
|
||||||
|
|
|
@ -52,6 +52,10 @@
|
||||||
p {
|
p {
|
||||||
margin-bottom: $default-spacer;
|
margin-bottom: $default-spacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type='date'] {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.editable-champ {
|
.editable-champ {
|
||||||
|
|
|
@ -23,6 +23,7 @@ module CreateAvisConcern
|
||||||
{
|
{
|
||||||
email: email,
|
email: email,
|
||||||
introduction: create_avis_params[:introduction],
|
introduction: create_avis_params[:introduction],
|
||||||
|
introduction_file: create_avis_params[:introduction_file],
|
||||||
claimant: current_instructeur,
|
claimant: current_instructeur,
|
||||||
dossier: dossier,
|
dossier: dossier,
|
||||||
confidentiel: confidentiel
|
confidentiel: confidentiel
|
||||||
|
@ -43,7 +44,6 @@ module CreateAvisConcern
|
||||||
sent_emails_addresses << avis.email_to_display
|
sent_emails_addresses << avis.email_to_display
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
flash.notice = "Une demande d'avis a été envoyée à #{sent_emails_addresses.uniq.join(", ")}"
|
flash.notice = "Une demande d'avis a été envoyée à #{sent_emails_addresses.uniq.join(", ")}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -61,6 +61,6 @@ module CreateAvisConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_avis_params
|
def create_avis_params
|
||||||
params.require(:avis).permit(:introduction, :confidentiel, :invite_linked_dossiers, emails: [])
|
params.require(:avis).permit(:introduction_file, :introduction, :confidentiel, :invite_linked_dossiers, emails: [])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -74,6 +74,9 @@ module NewAdministrateur
|
||||||
else
|
else
|
||||||
params.require(:procedure).permit(*editable_params, :duree_conservation_dossiers_dans_ds, :duree_conservation_dossiers_hors_ds, :for_individual, :path)
|
params.require(:procedure).permit(*editable_params, :duree_conservation_dossiers_dans_ds, :duree_conservation_dossiers_hors_ds, :for_individual, :path)
|
||||||
end
|
end
|
||||||
|
if permited_params[:auto_archive_on].present?
|
||||||
|
permited_params[:auto_archive_on] = Date.parse(permited_params[:auto_archive_on]) + 1.day
|
||||||
|
end
|
||||||
permited_params
|
permited_params
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ module DossierHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def highlight_if_unseen_class(seen_at, updated_at)
|
def highlight_if_unseen_class(seen_at, updated_at)
|
||||||
if seen_at&.<(updated_at)
|
if updated_at.present? && seen_at&.<(updated_at)
|
||||||
"highlighted"
|
"highlighted"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,7 @@ class Avis < ApplicationRecord
|
||||||
belongs_to :claimant, class_name: 'Instructeur'
|
belongs_to :claimant, class_name: 'Instructeur'
|
||||||
|
|
||||||
has_one_attached :piece_justificative_file
|
has_one_attached :piece_justificative_file
|
||||||
|
has_one_attached :introduction_file
|
||||||
|
|
||||||
validates :email, format: { with: Devise.email_regexp, message: "n'est pas valide" }, allow_nil: true
|
validates :email, format: { with: Devise.email_regexp, message: "n'est pas valide" }, allow_nil: true
|
||||||
validates :claimant, presence: true
|
validates :claimant, presence: true
|
||||||
|
|
|
@ -187,7 +187,7 @@ class Dossier < ApplicationRecord
|
||||||
.joins('LEFT OUTER JOIN "commentaires" ON "commentaires" . "dossier_id" = "dossiers" . "id" and commentaires.updated_at > follows.messagerie_seen_at and "commentaires"."email" != \'contact@tps.apientreprise.fr\' AND "commentaires"."email" != \'contact@demarches-simplifiees.fr\'')
|
.joins('LEFT OUTER JOIN "commentaires" ON "commentaires" . "dossier_id" = "dossiers" . "id" and commentaires.updated_at > follows.messagerie_seen_at and "commentaires"."email" != \'contact@tps.apientreprise.fr\' AND "commentaires"."email" != \'contact@demarches-simplifiees.fr\'')
|
||||||
|
|
||||||
updated_demandes = joined_dossiers
|
updated_demandes = joined_dossiers
|
||||||
.where('champs.updated_at > follows.demande_seen_at')
|
.where('champs.updated_at > follows.demande_seen_at OR groupe_instructeur_updated_at > follows.demande_seen_at')
|
||||||
|
|
||||||
updated_annotations = joined_dossiers
|
updated_annotations = joined_dossiers
|
||||||
.where('champs_privates_dossiers.updated_at > follows.annotations_privees_seen_at')
|
.where('champs_privates_dossiers.updated_at > follows.annotations_privees_seen_at')
|
||||||
|
@ -301,7 +301,7 @@ class Dossier < ApplicationRecord
|
||||||
|
|
||||||
def assign_to_groupe_instructeur(groupe_instructeur, author = nil)
|
def assign_to_groupe_instructeur(groupe_instructeur, author = nil)
|
||||||
if groupe_instructeur.procedure == procedure && groupe_instructeur != self.groupe_instructeur
|
if groupe_instructeur.procedure == procedure && groupe_instructeur != self.groupe_instructeur
|
||||||
if update(groupe_instructeur: groupe_instructeur)
|
if update(groupe_instructeur: groupe_instructeur, groupe_instructeur_updated_at: Time.zone.now)
|
||||||
unfollow_stale_instructeurs
|
unfollow_stale_instructeurs
|
||||||
|
|
||||||
if author.present?
|
if author.present?
|
||||||
|
|
|
@ -98,7 +98,8 @@ class Instructeur < ApplicationRecord
|
||||||
.find_by(instructeur: self, dossier: dossier)
|
.find_by(instructeur: self, dossier: dossier)
|
||||||
|
|
||||||
if follow.present?
|
if follow.present?
|
||||||
demande = follow.dossier.champs.updated_since?(follow.demande_seen_at).any?
|
demande = follow.dossier.champs.updated_since?(follow.demande_seen_at).any? || follow.dossier.groupe_instructeur_updated_at&.>(follow.demande_seen_at)
|
||||||
|
demande = false if demande.nil?
|
||||||
|
|
||||||
annotations_privees = follow.dossier.champs_private.updated_since?(follow.annotations_privees_seen_at).any?
|
annotations_privees = follow.dossier.champs_private.updated_since?(follow.annotations_privees_seen_at).any?
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
- @expired_dossiers.group_by(&:procedure).each do |procedure, dossiers|
|
- @expired_dossiers.group_by(&:procedure).each do |procedure, dossiers|
|
||||||
%dl
|
%dl
|
||||||
%dt
|
%dt
|
||||||
|
- if procedure.present?
|
||||||
#{procedure.libelle} (#{link_to(procedure.id, manager_procedure_url(procedure))}) :
|
#{procedure.libelle} (#{link_to(procedure.id, manager_procedure_url(procedure))}) :
|
||||||
|
- else
|
||||||
|
Procédure supprimée
|
||||||
%dd
|
%dd
|
||||||
= dossiers.map { |d| link_to(d.id, manager_dossier_url(d)) }.join(', ').html_safe
|
= dossiers.map { |d| link_to(d.id, manager_dossier_url(d)) }.join(', ').html_safe
|
||||||
|
|
||||||
|
@ -14,7 +17,10 @@
|
||||||
- @expiring_dossiers.group_by(&:procedure).each do |procedure, dossiers|
|
- @expiring_dossiers.group_by(&:procedure).each do |procedure, dossiers|
|
||||||
%dl
|
%dl
|
||||||
%dt
|
%dt
|
||||||
|
- if procedure.present?
|
||||||
#{procedure.libelle} (#{link_to(procedure.id, manager_procedure_url(procedure))}) :
|
#{procedure.libelle} (#{link_to(procedure.id, manager_procedure_url(procedure))}) :
|
||||||
|
- else
|
||||||
|
Procédure supprimée
|
||||||
%dd
|
%dd
|
||||||
= dossiers.map { |d| link_to(d.id, manager_dossier_url(d)) }.join(', ').html_safe
|
= dossiers.map { |d| link_to(d.id, manager_dossier_url(d)) }.join(', ').html_safe
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
%span.date Demande d'avis envoyée le #{l(@avis.created_at, format: '%d/%m/%y')}
|
%span.date Demande d'avis envoyée le #{l(@avis.created_at, format: '%d/%m/%y')}
|
||||||
%p.introduction= @avis.introduction
|
%p.introduction= @avis.introduction
|
||||||
|
|
||||||
|
- if @avis.introduction_file.attached?
|
||||||
|
= render partial: 'shared/attachment/show', locals: { attachment: @avis.introduction_file.attachment }
|
||||||
|
%br/
|
||||||
|
|
||||||
= form_for @avis, url: instructeur_avis_path(@avis), html: { class: 'form' } do |f|
|
= form_for @avis, url: instructeur_avis_path(@avis), html: { class: 'form' } do |f|
|
||||||
= f.text_area :answer, rows: 3, placeholder: 'Votre avis', required: true
|
= f.text_area :answer, rows: 3, placeholder: 'Votre avis', required: true
|
||||||
= render 'shared/attachment/edit',
|
= render 'shared/attachment/edit',
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
= form_for avis, url: url, html: { class: 'form' } do |f|
|
= form_for avis, url: url, html: { class: 'form' } do |f|
|
||||||
= f.email_field :emails, placeholder: 'Adresses email, séparées par des virgules', required: true, multiple: true, onchange: "javascript:DS.replaceSemicolonByComma(event);"
|
= f.email_field :emails, placeholder: 'Adresses email, séparées par des virgules', required: true, multiple: true, onchange: "javascript:DS.replaceSemicolonByComma(event);"
|
||||||
= f.text_area :introduction, rows: 3, value: avis.introduction || '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
|
||||||
|
%p.tab-title Ajouter une pièce jointe
|
||||||
|
.form-group
|
||||||
|
= render 'shared/attachment/edit',
|
||||||
|
{ form: f,
|
||||||
|
attached_file: avis.introduction_file,
|
||||||
|
user_can_destroy: true }
|
||||||
|
|
||||||
- if linked_dossiers.present?
|
- if linked_dossiers.present?
|
||||||
= f.check_box :invite_linked_dossiers, {}, true, false
|
= f.check_box :invite_linked_dossiers, {}, true, false
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
.container.groupe-instructeur
|
.container.groupe-instructeur
|
||||||
|
|
||||||
.card
|
.card
|
||||||
.card-title Réaffectation des dossiers du groupe « {@groupe_instructeur.label} »
|
.card-title Réaffectation des dossiers du groupe « #{@groupe_instructeur.label} »
|
||||||
%p
|
%p
|
||||||
Le groupe « #{@groupe_instructeur.label} » contient des dossiers. Afin de procéder à sa suppression, vous devez réaffecter ses dossiers à un autre groupe instructeur.
|
Le groupe « #{@groupe_instructeur.label} » contient des dossiers. Afin de procéder à sa suppression, vous devez réaffecter ses dossiers à un autre groupe instructeur.
|
||||||
|
|
||||||
|
|
|
@ -106,19 +106,19 @@
|
||||||
= f.text_field :web_hook_url, class: 'form-control', placeholder: 'https://callback.exemple.fr/'
|
= f.text_field :web_hook_url, class: 'form-control', placeholder: 'https://callback.exemple.fr/'
|
||||||
|
|
||||||
= f.label :auto_archive_on do
|
= f.label :auto_archive_on do
|
||||||
Clôture automatique à 00h01 le :
|
Date limite de dépôt des dossiers
|
||||||
= f.date_field :auto_archive_on, id: 'auto_archive_on', value: @procedure.auto_archive_on
|
%p.notice
|
||||||
|
Si une date est définie, aucun dossier ne pourra plus être déposé ou modifié après cette limite.
|
||||||
%p.explication
|
%p.notice
|
||||||
La clôture automatique suspend la publication de la démarche et entraîne le passage de tous les dossiers "en construction"
|
Le
|
||||||
(c'est à dire ceux qui ont été déposés), au statut "en instruction", ce qui ne permet plus aux usagers de les modifier.
|
- value = @procedure.auto_archive_on ? @procedure.auto_archive_on - 1.day : nil
|
||||||
|
= f.date_field :auto_archive_on, id: 'auto_archive_on', value: value
|
||||||
|
à 23 h 59
|
||||||
|
|
||||||
= f.label :declarative_with_state do
|
= f.label :declarative_with_state do
|
||||||
Démarche déclarative
|
Démarche déclarative
|
||||||
|
%p.notice
|
||||||
|
Par défaut, un dossier déposé peut être complété ou corrigé par le demandeur jusqu'à sa mise en instruction.<br>
|
||||||
|
Dans une démarche déclarative, une fois déposé, un dossier ne peut plus être modifié.
|
||||||
|
Soit il passe immédiatement « en instruction » pour être traité soit il est immédiatement « accepté ».
|
||||||
= f.select :declarative_with_state, Procedure.declarative_attributes_for_select, { prompt: 'Non' }, class: 'form-control'
|
= f.select :declarative_with_state, Procedure.declarative_attributes_for_select, { prompt: 'Non' }, class: 'form-control'
|
||||||
|
|
||||||
%p.explication
|
|
||||||
Par défaut, une démarche n’est pas déclarative ; à son dépôt, un dossier est « en construction ». Vous pouvez choisir de la rendre déclarative, afin que tous les dossiers déposés passent immédiatement au statut « en instruction » ou « accepté ».
|
|
||||||
%br
|
|
||||||
%br
|
|
||||||
Dans le cadre d’une démarche déclarative, au dépôt, seul l’email associé à l’état choisi est envoyé. (ex: démarche déclarative « accepté » : envoi uniquement de l’email d'acceptation)
|
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
%tbody
|
%tbody
|
||||||
- if dossier.procedure.routee?
|
- if dossier.procedure.routee?
|
||||||
%th= dossier.procedure.routing_criteria_name
|
%th= dossier.procedure.routing_criteria_name
|
||||||
%td= dossier.groupe_instructeur.label
|
%td{ class: highlight_if_unseen_class(demande_seen_at, dossier.groupe_instructeur_updated_at) }= dossier.groupe_instructeur.label
|
||||||
%td
|
%td.updated-at
|
||||||
|
%span{ class: highlight_if_unseen_class(demande_seen_at, dossier.groupe_instructeur_updated_at) }
|
||||||
|
modifié le
|
||||||
|
= try_format_datetime(dossier.updated_at)
|
||||||
= render partial: "shared/dossiers/champ_row", locals: { champs: champs, demande_seen_at: demande_seen_at, profile: profile, repetition: false }
|
= render partial: "shared/dossiers/champ_row", locals: { champs: champs, demande_seen_at: demande_seen_at, profile: profile, repetition: false }
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddGroupeInstructeurUpdatedAtToDossiers < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :dossiers, :groupe_instructeur_updated_at, :timestamp
|
||||||
|
end
|
||||||
|
end
|
|
@ -252,6 +252,7 @@ ActiveRecord::Schema.define(version: 2020_02_27_100001) do
|
||||||
t.datetime "brouillon_close_to_expiration_notice_sent_at"
|
t.datetime "brouillon_close_to_expiration_notice_sent_at"
|
||||||
t.index "to_tsvector('french'::regconfig, (search_terms || private_search_terms))", name: "index_dossiers_on_search_terms_private_search_terms", using: :gin
|
t.index "to_tsvector('french'::regconfig, (search_terms || private_search_terms))", name: "index_dossiers_on_search_terms_private_search_terms", using: :gin
|
||||||
t.index "to_tsvector('french'::regconfig, search_terms)", name: "index_dossiers_on_search_terms", using: :gin
|
t.index "to_tsvector('french'::regconfig, search_terms)", name: "index_dossiers_on_search_terms", using: :gin
|
||||||
|
t.datetime "groupe_instructeur_updated_at"
|
||||||
t.index ["archived"], name: "index_dossiers_on_archived"
|
t.index ["archived"], name: "index_dossiers_on_archived"
|
||||||
t.index ["groupe_instructeur_id"], name: "index_dossiers_on_groupe_instructeur_id"
|
t.index ["groupe_instructeur_id"], name: "index_dossiers_on_groupe_instructeur_id"
|
||||||
t.index ["hidden_at"], name: "index_dossiers_on_hidden_at"
|
t.index ["hidden_at"], name: "index_dossiers_on_hidden_at"
|
||||||
|
|
|
@ -126,7 +126,9 @@ describe Instructeurs::AvisController, type: :controller do
|
||||||
let(:invite_linked_dossiers) { nil }
|
let(:invite_linked_dossiers) { nil }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
post :create_avis, params: { id: previous_avis.id, avis: { emails: emails, introduction: intro, confidentiel: asked_confidentiel, invite_linked_dossiers: invite_linked_dossiers } }
|
@introduction_file = Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf')
|
||||||
|
post :create_avis, params: { id: previous_avis.id, avis: { emails: emails, introduction: intro, confidentiel: asked_confidentiel, invite_linked_dossiers: invite_linked_dossiers, introduction_file: @introduction_file } }
|
||||||
|
created_avis.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when an invalid email' do
|
context 'when an invalid email' do
|
||||||
|
@ -139,6 +141,16 @@ describe Instructeurs::AvisController, type: :controller do
|
||||||
it { expect(Avis.last).to eq(previous_avis) }
|
it { expect(Avis.last).to eq(previous_avis) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'ask review with attachment' do
|
||||||
|
let(:previous_avis_confidentiel) { false }
|
||||||
|
let(:asked_confidentiel) { false }
|
||||||
|
let(:emails) { ["toto@totomail.com"] }
|
||||||
|
|
||||||
|
it { expect(created_avis.introduction_file).to be_attached }
|
||||||
|
it { expect(created_avis.introduction_file.filename).to eq("piece_justificative_0.pdf") }
|
||||||
|
it { expect(flash.notice).to eq("Une demande d'avis a été envoyée à toto@totomail.com") }
|
||||||
|
end
|
||||||
|
|
||||||
context 'with multiple emails' do
|
context 'with multiple emails' do
|
||||||
let(:asked_confidentiel) { false }
|
let(:asked_confidentiel) { false }
|
||||||
let(:previous_avis_confidentiel) { false }
|
let(:previous_avis_confidentiel) { false }
|
||||||
|
|
|
@ -113,7 +113,7 @@ feature 'Inviting an expert:' do
|
||||||
expect(page).to have_text('Cet avis est confidentiel')
|
expect(page).to have_text('Cet avis est confidentiel')
|
||||||
|
|
||||||
fill_in 'avis_answer', with: 'Ma réponse d’expert : c’est un oui.'
|
fill_in 'avis_answer', with: 'Ma réponse d’expert : c’est un oui.'
|
||||||
find('.attachment input[type=file]').attach_file(Rails.root + 'spec/fixtures/files/RIB.pdf')
|
find('.attachment input[name="avis[piece_justificative_file]"]').attach_file(Rails.root + 'spec/fixtures/files/RIB.pdf')
|
||||||
click_on 'Envoyer votre avis'
|
click_on 'Envoyer votre avis'
|
||||||
|
|
||||||
expect(page).to have_content('Votre réponse est enregistrée')
|
expect(page).to have_content('Votre réponse est enregistrée')
|
||||||
|
|
|
@ -38,6 +38,13 @@ feature 'The routing', js: true do
|
||||||
|
|
||||||
victor = User.find_by(email: 'victor@inst.com').instructeur
|
victor = User.find_by(email: 'victor@inst.com').instructeur
|
||||||
|
|
||||||
|
# add superwoman to littéraire groupe
|
||||||
|
find('input.select2-search__field').send_keys('superwoman@inst.com', :enter)
|
||||||
|
perform_enqueued_jobs { click_on 'Affecter' }
|
||||||
|
expect(page).to have_text("L’instructeur superwoman@inst.com a été affecté")
|
||||||
|
|
||||||
|
superwoman = User.find_by(email: 'superwoman@inst.com').instructeur
|
||||||
|
|
||||||
# add scientifique groupe
|
# add scientifique groupe
|
||||||
click_on 'Groupes d’instructeurs'
|
click_on 'Groupes d’instructeurs'
|
||||||
fill_in 'Ajouter un groupe', with: 'scientifique'
|
fill_in 'Ajouter un groupe', with: 'scientifique'
|
||||||
|
@ -51,6 +58,11 @@ feature 'The routing', js: true do
|
||||||
|
|
||||||
marie = User.find_by(email: 'marie@inst.com').instructeur
|
marie = User.find_by(email: 'marie@inst.com').instructeur
|
||||||
|
|
||||||
|
# add superwoman to scientifique groupe
|
||||||
|
find('input.select2-search__field').send_keys('superwoman@inst.com', :enter)
|
||||||
|
perform_enqueued_jobs { click_on 'Affecter' }
|
||||||
|
expect(page).to have_text("L’instructeur superwoman@inst.com a été affecté")
|
||||||
|
|
||||||
# publish
|
# publish
|
||||||
publish_procedure(procedure)
|
publish_procedure(procedure)
|
||||||
log_out(old_layout: true)
|
log_out(old_layout: true)
|
||||||
|
@ -134,6 +146,31 @@ feature 'The routing', js: true do
|
||||||
expect(page).to have_current_path(instructeur_procedures_path)
|
expect(page).to have_current_path(instructeur_procedures_path)
|
||||||
expect(find('.procedure-stats')).not_to have_css('span.notifications')
|
expect(find('.procedure-stats')).not_to have_css('span.notifications')
|
||||||
log_out
|
log_out
|
||||||
|
|
||||||
|
# the instructeurs who belong to scientifique AND litteraire groups manage scientifique and litterraire dossiers
|
||||||
|
register_instructeur_and_log_in(superwoman.email)
|
||||||
|
visit procedure_path(procedure, params: { statut: 'tous' })
|
||||||
|
expect(page).to have_text(litteraire_user.email)
|
||||||
|
expect(page).to have_text(scientifique_user.email)
|
||||||
|
|
||||||
|
# follow the dossier
|
||||||
|
click_on scientifique_user.email
|
||||||
|
click_on 'Suivre le dossier'
|
||||||
|
|
||||||
|
visit procedure_path(procedure, params: { statut: 'tous' })
|
||||||
|
click_on litteraire_user.email
|
||||||
|
click_on 'Suivre le dossier'
|
||||||
|
log_out
|
||||||
|
|
||||||
|
# scientifique_user updates its group
|
||||||
|
user_update_group(scientifique_user, 'littéraire')
|
||||||
|
|
||||||
|
# the instructeurs who belong to scientifique AND litteraire groups should have a notification
|
||||||
|
visit new_user_session_path
|
||||||
|
sign_in_with superwoman.user.email, password
|
||||||
|
|
||||||
|
expect(page).to have_current_path(instructeur_procedures_path)
|
||||||
|
expect(find('.procedure-stats')).to have_css('span.notifications')
|
||||||
end
|
end
|
||||||
|
|
||||||
def publish_procedure(procedure)
|
def publish_procedure(procedure)
|
||||||
|
@ -164,6 +201,19 @@ feature 'The routing', js: true do
|
||||||
log_out
|
log_out
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def user_update_group(user, new_group)
|
||||||
|
login_as user, scope: :user
|
||||||
|
visit dossiers_path
|
||||||
|
click_on user.dossiers.first.id.to_s
|
||||||
|
click_on "Modifier mon dossier"
|
||||||
|
|
||||||
|
select(new_group, from: 'dossier_groupe_instructeur_id')
|
||||||
|
click_on "Enregistrer les modifications du dossier"
|
||||||
|
expect(page).to have_text(new_group)
|
||||||
|
|
||||||
|
log_out
|
||||||
|
end
|
||||||
|
|
||||||
def register_instructeur_and_log_in(email)
|
def register_instructeur_and_log_in(email)
|
||||||
confirmation_email = emails_sent_to(email)
|
confirmation_email = emails_sent_to(email)
|
||||||
.filter { |m| m.subject == 'Activez votre compte instructeur' }
|
.filter { |m| m.subject == 'Activez votre compte instructeur' }
|
||||||
|
|
|
@ -223,6 +223,13 @@ describe Instructeur, type: :model do
|
||||||
it { is_expected.to match({ demande: true, annotations_privees: false, avis: false, messagerie: false }) }
|
it { is_expected.to match({ demande: true, annotations_privees: false, avis: false, messagerie: false }) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when there is a modification on groupe instructeur' do
|
||||||
|
let(:groupe_instructeur) { create(:groupe_instructeur, instructeurs: [instructeur], procedure: dossier.procedure) }
|
||||||
|
before { dossier.assign_to_groupe_instructeur(groupe_instructeur) }
|
||||||
|
|
||||||
|
it { is_expected.to match({ demande: true, annotations_privees: false, avis: false, messagerie: false }) }
|
||||||
|
end
|
||||||
|
|
||||||
context 'when there is a modification on private champs' do
|
context 'when there is a modification on private champs' do
|
||||||
before { dossier.champs_private.first.update_attribute('value', 'toto') }
|
before { dossier.champs_private.first.update_attribute('value', 'toto') }
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,31 @@ describe 'shared/dossiers/champs.html.haml', type: :view do
|
||||||
expect(subject).to include(procedure.routing_criteria_name)
|
expect(subject).to include(procedure.routing_criteria_name)
|
||||||
expect(subject).to include(dossier.groupe_instructeur.label)
|
expect(subject).to include(dossier.groupe_instructeur.label)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with seen_at" do
|
||||||
|
let(:dossier) { create(:dossier) }
|
||||||
|
let(:nouveau_groupe_instructeur) { create(:groupe_instructeur, procedure: dossier.procedure) }
|
||||||
|
let(:champ1) { create(:champ, :checkbox, value: "on") }
|
||||||
|
let(:champs) { [champ1] }
|
||||||
|
|
||||||
|
context "with a demande_seen_at after groupe_instructeur_updated_at" do
|
||||||
|
let(:demande_seen_at) { dossier.groupe_instructeur_updated_at + 1.hour }
|
||||||
|
|
||||||
|
it "expect to not highlight new group instructeur label" do
|
||||||
|
dossier.assign_to_groupe_instructeur(nouveau_groupe_instructeur)
|
||||||
|
expect(subject).not_to have_css(".highlighted")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with a demande_seen_at before groupe_instructeur_updated_at" do
|
||||||
|
let(:demande_seen_at) { dossier.groupe_instructeur_updated_at - 1.hour }
|
||||||
|
|
||||||
|
it "expect to not highlight new group instructeur label" do
|
||||||
|
dossier.assign_to_groupe_instructeur(nouveau_groupe_instructeur)
|
||||||
|
expect(subject).to have_css(".highlighted")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with a dossier champ, but we are not authorized to acces the dossier" do
|
context "with a dossier champ, but we are not authorized to acces the dossier" do
|
||||||
|
|
Loading…
Reference in a new issue