2024-04-29 00:17:15 +02:00
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
2022-04-25 12:41:01 +02:00
|
|
|
|
RSpec.describe Dossiers::MessageComponent, type: :component do
|
|
|
|
|
let(:component) do
|
|
|
|
|
described_class.new(
|
|
|
|
|
commentaire: commentaire,
|
|
|
|
|
connected_user: connected_user,
|
|
|
|
|
messagerie_seen_at: seen_at,
|
2023-12-10 18:25:58 +01:00
|
|
|
|
show_reply_button: show_reply_button,
|
|
|
|
|
groupe_gestionnaire: groupe_gestionnaire
|
2022-04-25 12:41:01 +02:00
|
|
|
|
)
|
|
|
|
|
end
|
2017-12-05 17:20:10 +01:00
|
|
|
|
let(:seen_at) { commentaire.created_at + 1.hour }
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
describe 'for dossier' do
|
|
|
|
|
let(:connected_user) { dossier.user }
|
|
|
|
|
let(:dossier) { create(:dossier, :en_construction) }
|
|
|
|
|
let(:show_reply_button) { true }
|
|
|
|
|
let(:commentaire) { create(:commentaire, dossier: dossier) }
|
|
|
|
|
let(:groupe_gestionnaire) { nil }
|
2022-04-25 12:41:01 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
subject { render_inline(component).to_html }
|
2019-07-16 12:11:24 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
it { is_expected.to have_button("Répondre") }
|
2017-12-05 17:20:10 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'escape <img> tag' do
|
|
|
|
|
before { commentaire.update(body: '<img src="demarches-simplifiees.fr" />Hello') }
|
|
|
|
|
it { is_expected.not_to have_selector('img[src="demarches-simplifiees.fr"]') }
|
|
|
|
|
end
|
2020-05-12 17:58:00 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'with a seen_at after commentaire created_at' do
|
|
|
|
|
let(:seen_at) { commentaire.created_at + 1.hour }
|
2020-05-12 17:58:00 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
it { is_expected.not_to have_css(".highlighted") }
|
2020-05-12 17:58:00 +02:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'with a seen_at after commentaire created_at' do
|
|
|
|
|
let(:seen_at) { commentaire.created_at - 1.hour }
|
2020-05-12 17:58:00 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
it { is_expected.to have_css(".highlighted") }
|
2020-05-12 17:58:00 +02:00
|
|
|
|
end
|
2021-11-15 11:30:41 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'with an instructeur message' do
|
2021-11-15 11:30:41 +01:00
|
|
|
|
let(:instructeur) { create(:instructeur) }
|
2024-08-31 21:04:32 +02:00
|
|
|
|
let(:procedure) { create(:procedure, hide_instructeurs_email: true) }
|
2023-12-10 18:25:58 +01:00
|
|
|
|
let(:commentaire) { create(:commentaire, instructeur: instructeur, body: 'Second message') }
|
2021-11-15 11:30:41 +01:00
|
|
|
|
let(:dossier) { create(:dossier, :en_construction, commentaires: [commentaire], procedure: procedure) }
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'on a procedure with anonymous instructeurs' do
|
|
|
|
|
context 'redacts the instructeur email' do
|
|
|
|
|
it { is_expected.to have_text(commentaire.body) }
|
|
|
|
|
it { is_expected.to have_text("Instructeur n° #{instructeur.id}") }
|
|
|
|
|
it { is_expected.not_to have_text(instructeur.email) }
|
2023-12-07 15:41:50 +01:00
|
|
|
|
end
|
2021-11-15 13:53:32 +01:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'on a procedure where instructeurs names are not redacted' do
|
2024-08-31 21:04:32 +02:00
|
|
|
|
let(:procedure) { create(:procedure, hide_instructeurs_email: false) }
|
2021-11-15 13:53:32 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'redacts the instructeur email but keeps the name' do
|
|
|
|
|
it { is_expected.to have_text(commentaire.body) }
|
|
|
|
|
it { is_expected.to have_text(instructeur.email.split('@').first) }
|
|
|
|
|
it { is_expected.not_to have_text(instructeur.email) }
|
|
|
|
|
end
|
2021-11-15 11:30:41 +01:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
describe 'delete message button for instructeur' do
|
|
|
|
|
let(:instructeur) { create(:instructeur) }
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
let(:dossier) { create(:dossier, :en_construction, commentaires: [commentaire], procedure: procedure) }
|
|
|
|
|
let(:connected_user) { instructeur }
|
|
|
|
|
let(:form_url) { component.helpers.instructeur_commentaire_path(commentaire.dossier.procedure, commentaire.dossier, commentaire) }
|
|
|
|
|
|
|
|
|
|
context 'on a procedure where commentaire had been written by connected instructeur' do
|
|
|
|
|
let(:commentaire) { create(:commentaire, instructeur: instructeur, body: 'Second message') }
|
|
|
|
|
|
|
|
|
|
it do
|
|
|
|
|
is_expected.to have_selector("form[action=\"#{form_url}\"]")
|
|
|
|
|
is_expected.to have_button(component.t('.delete_button'))
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'on a procedure where commentaire had been written by connected instructeur and discarded' do
|
|
|
|
|
let(:commentaire) { create(:commentaire, instructeur: instructeur, body: 'Second message', discarded_at: 2.days.ago) }
|
|
|
|
|
|
|
|
|
|
it { is_expected.not_to have_selector("form[action=\"#{form_url}\"]") }
|
|
|
|
|
it { is_expected.to have_selector(".rich-text", text: component.t('.deleted_body')) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'on a procedure where commentaire had been written by connected an user' do
|
|
|
|
|
let(:commentaire) { create(:commentaire, email: create(:user).email, body: 'Second message') }
|
|
|
|
|
|
|
|
|
|
it { is_expected.not_to have_selector("form[action=\"#{form_url}\"]") }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'on a procedure where commentaire had been written by connected an expert' do
|
|
|
|
|
let(:commentaire) { create(:commentaire, expert: create(:expert), body: 'Second message') }
|
|
|
|
|
|
|
|
|
|
it { is_expected.not_to have_selector("form[action=\"#{form_url}\"]") }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'on a procedure where commentaire had been written another instructeur' do
|
|
|
|
|
let(:commentaire) { create(:commentaire, instructeur: create(:instructeur), body: 'Second message') }
|
|
|
|
|
|
|
|
|
|
it { is_expected.not_to have_selector("form[action=\"#{form_url}\"]") }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when commentaire is a correction' do
|
|
|
|
|
let(:commentaire) { create(:commentaire, instructeur:, body: 'Please fix this') }
|
|
|
|
|
before { create(:dossier_correction, commentaire:, dossier:) }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to have_button(component.t('.delete_with_correction_button')) }
|
|
|
|
|
end
|
|
|
|
|
end
|
2021-11-15 11:30:41 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
describe 'autolink simple urls' do
|
|
|
|
|
let(:commentaire) { create(:commentaire, instructeur: instructeur, body: "rdv sur https://demarches.gouv.fr") }
|
|
|
|
|
it { is_expected.to have_link("https://demarches.gouv.fr", href: "https://demarches.gouv.fr") }
|
2021-11-15 11:30:41 +01:00
|
|
|
|
end
|
2023-12-10 18:25:58 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '#commentaire_from_guest?' do
|
|
|
|
|
let!(:guest) { create(:invite, dossier: dossier) }
|
2021-11-15 11:30:41 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
subject { component.send(:commentaire_from_guest?) }
|
2021-11-15 11:30:41 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'when the commentaire sender is not a guest' do
|
|
|
|
|
let(:commentaire) { create(:commentaire, dossier: dossier, email: "michel@pref.fr") }
|
|
|
|
|
it { is_expected.to be false }
|
2021-11-15 11:30:41 +01:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'when the commentaire sender is a guest on this dossier' do
|
|
|
|
|
let(:commentaire) { create(:commentaire, dossier: dossier, email: guest.email) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '#commentaire_date' do
|
|
|
|
|
let(:present_date) { Time.zone.local(2018, 9, 2, 10, 5, 0) }
|
|
|
|
|
let(:creation_date) { present_date }
|
|
|
|
|
let(:commentaire) do
|
|
|
|
|
Timecop.freeze(creation_date) { create(:commentaire, email: "michel@pref.fr") }
|
|
|
|
|
end
|
2021-11-15 11:30:41 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
subject do
|
|
|
|
|
Timecop.freeze(present_date) { component.send(:commentaire_date) }
|
2021-11-15 11:30:41 +01:00
|
|
|
|
end
|
2023-12-07 15:41:50 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
it 'doesn’t include the creation year' do
|
|
|
|
|
expect(subject).to eq 'le 2 septembre à 10 h 05'
|
|
|
|
|
end
|
2023-12-07 15:41:50 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'when displaying a commentaire created on a previous year' do
|
|
|
|
|
let(:creation_date) { present_date.prev_year }
|
|
|
|
|
it 'includes the creation year' do
|
|
|
|
|
expect(subject).to eq 'le 2 septembre 2017 à 10 h 05'
|
|
|
|
|
end
|
2023-12-07 15:41:50 +01:00
|
|
|
|
end
|
2023-11-06 19:01:25 +01:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'when formatting the first day of the month' do
|
|
|
|
|
let(:present_date) { Time.zone.local(2018, 9, 1, 10, 5, 0) }
|
|
|
|
|
it 'includes the ordinal' do
|
|
|
|
|
expect(subject).to eq 'le 1er septembre à 10 h 05'
|
|
|
|
|
end
|
|
|
|
|
end
|
2023-11-06 19:01:25 +01:00
|
|
|
|
end
|
2022-04-25 12:41:01 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
describe '#correction_badge' do
|
|
|
|
|
let(:resolved_at) { nil }
|
2022-04-25 12:41:01 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
before do
|
|
|
|
|
create(:dossier_correction, commentaire:, dossier:, resolved_at:)
|
|
|
|
|
end
|
2022-04-25 12:41:01 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
it 'returns a badge à corriger' do
|
|
|
|
|
expect(subject).to have_text('à corriger')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'connected as instructeur' do
|
|
|
|
|
let(:connected_user) { create(:instructeur) }
|
|
|
|
|
|
|
|
|
|
it 'returns a badge en attente' do
|
|
|
|
|
expect(subject).to have_text('en attente')
|
|
|
|
|
end
|
|
|
|
|
end
|
2022-04-25 12:41:01 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'when the correction is resolved' do
|
|
|
|
|
let(:resolved_at) { 1.minute.ago }
|
|
|
|
|
|
|
|
|
|
it 'returns a badge corrigé' do
|
|
|
|
|
expect(subject).to have_text("corrigé")
|
|
|
|
|
end
|
|
|
|
|
end
|
2022-04-25 12:41:01 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
describe 'groupe_gestionnaire' do
|
|
|
|
|
let(:show_reply_button) { false }
|
2024-06-01 22:50:48 +02:00
|
|
|
|
let(:commentaire) { create(:commentaire_groupe_gestionnaire, sender: administrateurs(:default_admin)) }
|
2023-12-10 18:25:58 +01:00
|
|
|
|
let(:groupe_gestionnaire) { commentaire.groupe_gestionnaire }
|
|
|
|
|
let(:connected_user) { commentaire.sender }
|
|
|
|
|
subject { render_inline(component).to_html }
|
|
|
|
|
|
|
|
|
|
it { is_expected.not_to have_button("Répondre") }
|
|
|
|
|
|
|
|
|
|
context 'escape <img> tag' do
|
|
|
|
|
before { commentaire.update(body: '<img src="demarches-simplifiees.fr" />Hello') }
|
|
|
|
|
it { is_expected.not_to have_selector('img[src="demarches-simplifiees.fr"]') }
|
2022-04-25 12:41:01 +02:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'with a seen_at after commentaire created_at' do
|
|
|
|
|
let(:seen_at) { commentaire.created_at + 1.hour }
|
|
|
|
|
|
|
|
|
|
it { is_expected.not_to have_css(".highlighted") }
|
2022-04-25 12:41:01 +02:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'with a seen_at after commentaire created_at' do
|
|
|
|
|
let(:seen_at) { commentaire.created_at - 1.hour }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to have_css(".highlighted") }
|
2022-04-25 12:41:01 +02:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'with an gestionnaire message' do
|
|
|
|
|
let(:gestionnaire) { create(:gestionnaire) }
|
2024-06-01 22:50:48 +02:00
|
|
|
|
let(:commentaire) { create(:commentaire_groupe_gestionnaire, sender: administrateurs(:default_admin), gestionnaire: gestionnaire, body: 'Second message') }
|
2023-12-10 18:25:58 +01:00
|
|
|
|
|
|
|
|
|
it 'should display gestionnaire\'s email' do
|
|
|
|
|
is_expected.to have_text(gestionnaire.email)
|
2022-04-25 12:41:01 +02:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
describe 'delete message button for gestionnaire' do
|
|
|
|
|
let(:connected_user) { gestionnaire }
|
|
|
|
|
let(:form_url) { component.helpers.gestionnaire_groupe_gestionnaire_commentaire_path(groupe_gestionnaire, commentaire) }
|
|
|
|
|
|
|
|
|
|
context 'when commentaire had been written by connected gestionnaire' do
|
|
|
|
|
it { is_expected.to have_selector("form[action=\"#{form_url}\"]") }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when commentaire had been written by connected gestionnaire and discarded' do
|
2024-06-01 22:50:48 +02:00
|
|
|
|
let(:commentaire) { create(:commentaire_groupe_gestionnaire, sender: administrateurs(:default_admin), gestionnaire: gestionnaire, body: 'Second message', discarded_at: 2.days.ago) }
|
2023-12-10 18:25:58 +01:00
|
|
|
|
|
|
|
|
|
it { is_expected.not_to have_selector("form[action=\"#{form_url}\"]") }
|
|
|
|
|
it { is_expected.to have_selector(".rich-text", text: component.t('.deleted_body')) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'on a procedure where commentaire had been written another gestionnaire' do
|
2024-06-01 22:50:48 +02:00
|
|
|
|
let(:commentaire) { create(:commentaire_groupe_gestionnaire, sender: administrateurs(:default_admin), gestionnaire: create(:gestionnaire), body: 'Second message') }
|
2023-12-10 18:25:58 +01:00
|
|
|
|
|
|
|
|
|
it { is_expected.not_to have_selector("form[action=\"#{form_url}\"]") }
|
|
|
|
|
end
|
2022-04-25 12:41:01 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
2023-06-02 15:46:23 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
describe '#commentaire_from_guest?' do
|
|
|
|
|
subject { component.send(:commentaire_from_guest?) }
|
2023-06-02 15:46:23 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
it { is_expected.to be false }
|
2023-06-02 15:46:23 +02:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
describe '#commentaire_date' do
|
|
|
|
|
let(:present_date) { Time.zone.local(2018, 9, 2, 10, 5, 0) }
|
|
|
|
|
let(:creation_date) { present_date }
|
|
|
|
|
let(:commentaire) do
|
2024-06-01 22:50:48 +02:00
|
|
|
|
Timecop.freeze(creation_date) { create(:commentaire_groupe_gestionnaire, sender: administrateurs(:default_admin)) }
|
2023-12-10 18:25:58 +01:00
|
|
|
|
end
|
2023-06-02 15:46:23 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
subject do
|
|
|
|
|
Timecop.freeze(present_date) { component.send(:commentaire_date) }
|
|
|
|
|
end
|
2023-06-02 15:46:23 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
it 'doesn’t include the creation year' do
|
|
|
|
|
expect(subject).to eq 'le 2 septembre à 10 h 05'
|
2023-06-02 15:46:23 +02:00
|
|
|
|
end
|
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'when displaying a commentaire created on a previous year' do
|
|
|
|
|
let(:creation_date) { present_date.prev_year }
|
|
|
|
|
it 'includes the creation year' do
|
|
|
|
|
expect(subject).to eq 'le 2 septembre 2017 à 10 h 05'
|
|
|
|
|
end
|
|
|
|
|
end
|
2023-06-02 15:46:23 +02:00
|
|
|
|
|
2023-12-10 18:25:58 +01:00
|
|
|
|
context 'when formatting the first day of the month' do
|
|
|
|
|
let(:present_date) { Time.zone.local(2018, 9, 1, 10, 5, 0) }
|
|
|
|
|
it 'includes the ordinal' do
|
|
|
|
|
expect(subject).to eq 'le 1er septembre à 10 h 05'
|
|
|
|
|
end
|
2023-06-02 15:46:23 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
2023-12-10 18:25:58 +01:00
|
|
|
|
|
|
|
|
|
describe '#correction_badge' do
|
|
|
|
|
subject { component.send(:correction_badge) }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to eq nil }
|
|
|
|
|
end
|
2023-06-02 15:46:23 +02:00
|
|
|
|
end
|
2017-12-05 17:20:10 +01:00
|
|
|
|
end
|