Merge pull request #10190 from demarches-simplifiees/add-AR-feature-ldu

ETQ Admin je peux configurer une démarche avec accusé de lecture
This commit is contained in:
Lisa Durand 2024-04-16 09:58:13 +00:00 committed by GitHub
commit 7a80574afc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
47 changed files with 491 additions and 96 deletions

View file

@ -6,7 +6,9 @@ describe Instructeurs::DossiersController, type: :controller do
let(:administration) { create(:administration) }
let(:instructeurs) { [instructeur] }
let(:procedure) { create(:procedure, :published, :for_individual, instructeurs: instructeurs) }
let(:procedure_accuse_lecture) { create(:procedure, :published, :for_individual, :accuse_lecture, instructeurs: instructeurs) }
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
let(:dossier_accuse_lecture) { create(:dossier, :en_construction, :with_individual, procedure: procedure_accuse_lecture) }
let(:dossier_for_tiers) { create(:dossier, :en_construction, :for_tiers_with_notification, procedure: procedure) }
let(:dossier_for_tiers_without_notif) { create(:dossier, :en_construction, :for_tiers_without_notification, procedure: procedure) }
let(:fake_justificatif) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }
@ -376,6 +378,34 @@ describe Instructeurs::DossiersController, type: :controller do
end
end
context "with accuse de lecture procedure" do
before do
dossier_accuse_lecture.passer_en_instruction!(instructeur: instructeur)
sign_in(instructeur.user)
end
context 'with classer_sans_suite' do
subject { post :terminer, params: { process_action: "classer_sans_suite", procedure_id: procedure_accuse_lecture.id, dossier_id: dossier_accuse_lecture.id }, format: :turbo_stream }
it 'Notification accuse de lecture email is sent and not the others' do
expect(NotificationMailer).to receive(:send_accuse_lecture_notification)
.with(dossier_accuse_lecture).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
expect(NotificationMailer).not_to receive(:send_sans_suite_notification)
.with(dossier_accuse_lecture)
subject
end
it { expect(subject.body).to include('header-top') }
it 'creates a commentaire' do
expect { subject }.to change { Commentaire.count }.by(1)
expect(dossier_accuse_lecture.commentaires.last.body).to eq("<p>Bonjour,</p><p>Nous vous informons qu'une décision sur votre dossier a été rendue.</p>Cordialement,<br>#{procedure_accuse_lecture.service.nom}")
end
end
end
context "with classer_sans_suite" do
before do
dossier.passer_en_instruction!(instructeur: instructeur)

View file

@ -283,6 +283,10 @@ FactoryBot.define do
referentiel_de_programmation: { c: 3 })
end
end
trait :accuse_lecture do
accuse_lecture { true }
end
end
end

View file

@ -29,6 +29,25 @@ RSpec.describe NotificationMailer, type: :mailer do
end
end
describe 'send_notification_for_tiers with accuse lecture procedure' do
let(:dossier_for_tiers) { create(:dossier, :accepte, :for_tiers_with_notification, procedure: create(:procedure, :accuse_lecture, :for_individual)) }
subject { described_class.send_notification_for_tiers(dossier_for_tiers) }
it { expect(subject.subject).to include("Votre dossier rempli par le mandataire #{dossier_for_tiers.mandataire_first_name} #{dossier_for_tiers.mandataire_last_name} a été mis à jour") }
it { expect(subject.to).to eq([dossier_for_tiers.individual.email]) }
it { expect(subject.body).to include("a été traité le") }
it { expect(subject.body).to include("Pour en savoir plus, veuillez vous rapprocher de\r\n<a href=\"mailto:#{dossier_for_tiers.user.email}\">#{dossier_for_tiers.user.email}</a>.") }
end
describe 'send_accuse_lecture_notification' do
let(:dossier) { create(:dossier, :accepte, procedure: create(:procedure, :accuse_lecture)) }
subject { described_class.send_accuse_lecture_notification(dossier) }
it { expect(subject.subject).to include("La décision a été rendue pour votre démarche #{dossier.procedure.libelle}") }
it { expect(subject.body).to include("Pour en connaitre la nature, veuillez vous connecter à votre compte\r\n<a href=\"#{dossier_url(dossier)}\">demarches-simplifiees.fr</a>") }
end
describe 'send_en_construction_notification' do
let(:dossier) { create(:dossier, :en_construction, :with_individual, user: user, procedure:) }

View file

@ -23,6 +23,10 @@ class NotificationMailerPreview < ActionMailer::Preview
NotificationMailer.send_notification_for_tiers(dossier)
end
def send_accuse_lecture_notification
NotificationMailer.send_accuse_lecture_notification(dossier)
end
private
def dossier

View file

@ -1,5 +1,6 @@
describe 'user access to the list of their dossiers', js: true do
let(:user) { create(:user) }
let(:procedure_accuse_lecture) { create(:procedure, :accuse_lecture) }
let!(:dossier_brouillon) { create(:dossier, user: user) }
let!(:dossier_en_construction) { create(:dossier, :with_populated_champs, :en_construction, user: user) }
let!(:dossier_en_construction_2) { create(:dossier, :en_construction, user: user) }
@ -9,6 +10,8 @@ describe 'user access to the list of their dossiers', js: true do
let!(:dossier_a_corriger) { create(:dossier_correction, dossier: dossier_en_construction_2) }
let!(:dossier_archived) { create(:dossier, :en_instruction, :archived, user: user) }
let!(:dossier_for_tiers) { create(:dossier, :en_instruction, :for_tiers_with_notification, user: user) }
let!(:dossier_en_construction_with_accuse_lecture) { create(:dossier, :en_construction, user: user, procedure: procedure_accuse_lecture) }
let!(:dossier_accepte_with_accuse_lecture) { create(:dossier, :accepte, user: user, procedure: procedure_accuse_lecture) }
let(:dossiers_per_page) { 25 }
let(:last_updated_dossier) { dossier_en_construction }
@ -31,8 +34,8 @@ describe 'user access to the list of their dossiers', js: true do
expect(page).to have_content(dossier_en_construction.procedure.libelle)
expect(page).to have_content(dossier_en_instruction.procedure.libelle)
expect(page).to have_content(dossier_archived.procedure.libelle)
expect(page).to have_text('6 en cours')
expect(page).to have_text('2 traités')
expect(page).to have_text('7 en cours')
expect(page).to have_text('3 traités')
end
it 'the list must be ordered by last updated' do
@ -55,8 +58,8 @@ describe 'user access to the list of their dossiers', js: true do
page.click_link("Suivant")
page.click_link("Suivant")
expect(page).to have_link(dossier_en_instruction.procedure.libelle)
expect(page).to have_text('6 en cours')
expect(page).to have_text('2 traités')
expect(page).to have_text('7 en cours')
expect(page).to have_text('3 traités')
end
end
@ -70,9 +73,9 @@ describe 'user access to the list of their dossiers', js: true do
context 'when user uses filter' do
scenario 'user filters state on tab "en-cours"' do
expect(page).to have_text('6 en cours')
expect(page).to have_text('2 traités')
expect(page).to have_text('6 sur 6 dossiers')
expect(page).to have_text('7 en cours')
expect(page).to have_text('3 traités')
expect(page).to have_text('7 sur 7 dossiers')
click_on('Sélectionner un filtre')
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Brouillon', 'En construction', 'En instruction', 'À corriger']
@ -92,9 +95,9 @@ describe 'user access to the list of their dossiers', js: true do
scenario 'user filters state on tab "traité"' do
visit dossiers_path(statut: 'traites')
expect(page).to have_text('6 en cours')
expect(page).to have_text('2 traités')
expect(page).to have_text('2 sur 2 dossiers')
expect(page).to have_text('7 en cours')
expect(page).to have_text('3 traités')
expect(page).to have_text('3 sur 3 dossiers')
click_on('Sélectionner un filtre')
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
@ -105,18 +108,29 @@ describe 'user access to the list of their dossiers', js: true do
click_on('Sélectionner un filtre')
click_on('Annuler')
expect(page).to have_text('2 sur 2 dossiers')
click_on('Sélectionner un filtre')
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
select('Accepté', from: 'Statut')
click_on('Appliquer les filtres')
# we expect 1 dossier because we want do hide decision for dossier with accuse de lecture
expect(page).to have_text('1 dossier')
expect(page).to have_select 'Statut', selected: 'Accepté', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
click_on('Sélectionner un filtre')
click_on('Annuler')
expect(page).to have_text('3 sur 3 dossiers')
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
end
scenario 'user filters by created_at' do
dossier_en_construction.update!(created_at: Date.yesterday)
expect(page).to have_text('6 sur 6 dossiers')
expect(page).to have_text('7 sur 7 dossiers')
click_on('Sélectionner un filtre')
fill_in 'from_created_at_date', with: Date.today
click_on('Appliquer les filtres')
expect(page).to have_text('5 sur 5 dossiers')
expect(page).to have_text('6 sur 6 dossiers')
end
scenario 'user uses multiple filters' do
@ -124,26 +138,26 @@ describe 'user access to the list of their dossiers', js: true do
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Brouillon', 'En construction', 'En instruction', 'À corriger']
expect(page).to have_text('6 sur 6 dossiers')
expect(page).to have_text('7 sur 7 dossiers')
click_on('Sélectionner un filtre')
fill_in 'from_created_at_date', with: Date.today
click_on('Appliquer les filtres')
expect(page).to have_text('5 sur 5 dossiers')
expect(page).to have_text('6 sur 6 dossiers')
expect(page).to have_text('1 filtre actif')
click_on('Sélectionner un filtre')
select('En construction', from: 'Statut')
click_on('Appliquer les filtres')
expect(page).to have_text('1 dossier')
expect(page).to have_text('2 dossiers')
expect(page).to have_text('2 filtres actifs')
click_on('Sélectionner un filtre')
fill_in 'from_depose_at_date', with: Date.today
click_on('Appliquer les filtres')
expect(page).to have_text('1 dossier')
expect(page).to have_text('2 sur 2 dossiers')
expect(page).to have_text('3 filtres actifs')
click_on('3 filtres actifs')
expect(page).to have_text('6 sur 6 dossiers')
expect(page).to have_text('7 sur 7 dossiers')
expect(page).not_to have_text('5 filtres actifs')
end
end
@ -285,8 +299,8 @@ describe 'user access to the list of their dossiers', js: true do
describe "filter by procedure" do
context "when dossiers are on different procedures" do
it "can filter by procedure" do
expect(page).to have_text('6 en cours')
expect(page).to have_text('2 traités')
expect(page).to have_text('7 en cours')
expect(page).to have_text('3 traités')
expect(page).to have_select('procedure_id', selected: 'Toutes les démarches')
select dossier_brouillon.procedure.libelle, from: 'procedure_id'
expect(page).to have_text('1 en cours')

View file

@ -173,4 +173,32 @@ describe 'instructeurs/dossiers/show', type: :view do
end
end
end
describe 'accuse de lecture ' do
context 'dossier not termine' do
let(:dossier) { create(:dossier, :en_instruction, procedure: create(:procedure, :accuse_lecture)) }
it 'does not display a text about accuse de lecture for instructeur' do
expect(subject).not_to have_text('Cette démarche est soumise à un accusé de lecture')
end
end
context 'dossier termine with accuse de lecture not accepted by user' do
let(:dossier) { create(:dossier, :accepte, procedure: create(:procedure, :accuse_lecture)) }
it 'displays a text about accuse de lecture for instructeur' do
expect(subject).to have_text('Cette démarche est soumise à un accusé de lecture')
expect(subject).to have_text('Lusager na pas encore pris connaissance de la décision concernant son dossier')
end
end
context 'dossier termine with accuse de lecture accepted by user' do
let(:dossier) { create(:dossier, :accepte, accuse_lecture_agreement_at: Time.zone.now, procedure: create(:procedure, :accuse_lecture)) }
it 'displays a text about accuse de lecture for instructeur' do
expect(subject).to have_text('Cette démarche est soumise à un accusé de lecture')
expect(subject).to have_text('Lusager a pris connaissance de la décision concernant son dossier le')
end
end
end
end

View file

@ -1,6 +1,6 @@
describe 'shared/dossiers/_infos_generales', type: :view do
let(:dossier) { create(:dossier, :en_construction) }
subject { render }
subject { render 'shared/dossiers/infos_generales', dossier: dossier, profile: 'instructeur' }
before do
sign_in(current_role.user)
allow(view).to receive(:current_instructeur).and_return(current_role)
@ -32,6 +32,14 @@ describe 'shared/dossiers/_infos_generales', type: :view do
end
end
context 'with a motivation and procedure with accuse de lecture' do
let(:dossier) { create :dossier, :accepte, :with_justificatif, procedure: create(:procedure, :accuse_lecture) }
it 'still displays the motivation text for the instructeur' do
expect(subject).to have_content(dossier.motivation)
end
end
context 'with an attestation' do
let(:dossier) { create :dossier, :accepte, :with_attestation }

View file

@ -59,4 +59,23 @@ describe 'users/dossiers/demande', type: :view do
expect(rendered).to have_text(dossier.individual.email.to_s)
end
end
context 'when a dossier is accepte with motivation' do
let(:dossier) { create(:dossier, :accepte, :with_motivation) }
it 'displays the motivation' do
expect(rendered).not_to have_text('Cette démarche est soumise à un accusé de lecture.')
expect(rendered).to have_text('Motivation')
end
end
context 'when a dossier is accepte with motivation and with accuse de lecture' do
let(:dossier) { create(:dossier, :accepte, :with_motivation, procedure: create(:procedure, :accuse_lecture)) }
it 'display information about accuse de lecture and not the motivation' do
expect(rendered).to have_text('Cette démarche est soumise à un accusé de lecture.')
expect(rendered).not_to have_text('Motivation')
expect(rendered).not_to have_text('Lusager na pas encore pris connaissance de la décision concernant son dossier')
end
end
end

View file

@ -1,10 +1,13 @@
describe 'users/dossiers/index', type: :view do
let(:user) { create(:user) }
let(:procedure_accuse_lecture) { create(:procedure, :accuse_lecture) }
let(:dossier_brouillon) { create(:dossier, state: Dossier.states.fetch(:brouillon), user: user) }
let(:dossier_en_construction) { create(:dossier, state: Dossier.states.fetch(:en_construction), user: user) }
let(:dossier_en_construction_with_accuse_lecture) { create(:dossier, state: Dossier.states.fetch(:en_construction), user: user, procedure: procedure_accuse_lecture) }
let(:dossier_termine) { create(:dossier, state: Dossier.states.fetch(:accepte), user: user) }
let(:dossier_termine_with_accuse_lecture) { create(:dossier, state: Dossier.states.fetch(:accepte), user: user, procedure: procedure_accuse_lecture) }
let(:dossiers_invites) { [] }
let(:user_dossiers) { Kaminari.paginate_array([dossier_brouillon, dossier_en_construction, dossier_termine]).page(1) }
let(:user_dossiers) { Kaminari.paginate_array([dossier_brouillon, dossier_en_construction, dossier_termine, dossier_en_construction_with_accuse_lecture, dossier_termine_with_accuse_lecture]).page(1) }
let(:statut) { 'en-cours' }
let(:filter) { DossiersFilter.new(user, ActionController::Parameters.new(random_param: 'random_param')) }
@ -28,7 +31,7 @@ describe 'users/dossiers/index', type: :view do
end
it 'affiche les dossiers' do
expect(rendered).to have_selector('.card', count: 3)
expect(rendered).to have_selector('.card', count: 5)
end
it 'affiche les informations des dossiers' do
@ -40,6 +43,9 @@ describe 'users/dossiers/index', type: :view do
expect(rendered).to have_text(dossier_en_construction.id.to_s)
expect(rendered).to have_text(dossier_en_construction.procedure.libelle)
expect(rendered).to have_link(dossier_en_construction.procedure.libelle, href: dossier_path(dossier_en_construction))
expect(rendered).to have_selector('.fr-badge', text: 'traité', count: 1)
expect(rendered).to have_selector('.fr-badge', text: 'en construction', count: 2)
end
it 'naffiche pas une alerte pour continuer à remplir un dossier' do
@ -132,13 +138,13 @@ describe 'users/dossiers/index', type: :view do
it "cache key depends on dossiers list" do
render
expect(rendered).to have_text(/3\s+en cours/)
expect(rendered).to have_text(/5\s+en cours/)
assign(:user_dossiers, Kaminari.paginate_array(user_dossiers.concat([create(:dossier, :en_construction, user: user)])).page(1))
user.reload
render
expect(rendered).to have_text(/4\s+en cours/)
expect(rendered).to have_text(/6\s+en cours/)
end
it "cache key dpeends on dossier invites" do

View file

@ -18,6 +18,26 @@ describe 'users/dossiers/show/header', type: :view do
expect(rendered).to have_link("Demande", href: demande_dossier_path(dossier))
end
context "when the procedure is with accuse de lecture with a dossier en construction" do
let(:procedure) { create(:procedure, :accuse_lecture) }
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
it "affiche les informations du dossier" do
expect(rendered).to have_text("Dossier nº #{dossier.id}")
expect(rendered).to have_text("en construction")
end
end
context "when the procedure is with accuse de lecture with a dossier termine" do
let(:procedure) { create(:procedure, :accuse_lecture) }
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
it "n'affiche pas les informations de décision" do
expect(rendered).to have_text("Dossier nº #{dossier.id}")
expect(rendered).to have_text("traité")
end
end
context "when the procedure is closed with a dossier en construction" do
let(:procedure) { create(:procedure, :closed) }
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }

View file

@ -92,4 +92,12 @@ describe 'users/dossiers/show/_status_overview', type: :view do
it { is_expected.to have_selector('.status-explanation .sans-suite') }
it { is_expected.to have_text(dossier.motivation) }
end
context 'when terminé but the procedure has an accuse de lecture' do
let(:dossier) { create(:dossier, :sans_suite, :with_motivation, procedure: create(:procedure, :accuse_lecture)) }
it { is_expected.not_to have_selector('.status-explanation .sans-suite') }
it { is_expected.not_to have_text(dossier.motivation) }
it { is_expected.to have_text('Cette démarche est soumise à un accusé de lecture.') }
end
end