Merge pull request #10797 from demarches-simplifiees/gallery_v2

ETQ instructeur je vois la provenance des pièces jointes ainsi que leur date d'ajout ou de mise à jour
This commit is contained in:
Eric Leroy-Terquem 2024-10-11 11:23:19 +00:00 committed by GitHub
commit ba330bfa98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 377 additions and 98 deletions

View file

@ -52,7 +52,15 @@
flex-wrap: wrap;
.gallery-item {
margin: 0 2rem 1.5rem 0;
margin: 0 2rem 3rem 0;
.fr-download {
margin-bottom: 0;
}
.fr-text--sm {
margin-bottom: 0;
}
}
}

View file

@ -0,0 +1,86 @@
# frozen_string_literal: true
class Attachment::GalleryItemComponent < ApplicationComponent
include GalleryHelper
attr_reader :attachment, :seen_at
def initialize(attachment:, gallery_demande: false, seen_at: nil)
@attachment = attachment
@gallery_demande = gallery_demande
@seen_at = seen_at
end
def blob
attachment.blob
end
def gallery_demande? = @gallery_demande
def libelle
from_dossier? ? attachment.record.libelle : 'Pièce jointe au message'
end
def origin
case
when from_dossier?
'Dossier usager'
when from_messagerie_instructeur?
'Messagerie (instructeur)'
when from_messagerie_usager?
'Messagerie (usager)'
end
end
def title
"#{libelle} -- #{sanitize(blob.filename.to_s)}"
end
def gallery_link(blob, &block)
if displayable_image?(blob)
link_to image_url(blob_url(attachment)), title: title, data: { src: blob.url }, class: 'gallery-link' do
yield
end
elsif displayable_pdf?(blob)
link_to blob.url, id: blob.id, data: { iframe: true, src: blob.url }, class: 'gallery-link', type: blob.content_type, title: title do
yield
end
end
end
def created_at
attachment.record.created_at
end
def updated?
from_dossier? && updated_at > attachment.record.dossier.depose_at
end
def updated_at
blob.created_at
end
def badge_updated_class
class_names(
"fr-badge fr-badge--sm" => true,
"highlighted" => seen_at.present? && updated_at&.>(seen_at)
)
end
private
def from_dossier?
attachment.record.class.in?([Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp])
end
def from_messagerie?
attachment.record.is_a?(Commentaire)
end
def from_messagerie_instructeur?
from_messagerie? && attachment.record.instructeur.present?
end
def from_messagerie_usager?
from_messagerie? && attachment.record.instructeur.nil?
end
end

View file

@ -0,0 +1,3 @@
en:
created_at: "Added on %{datetime}"
updated_at: "Updated on %{datetime}"

View file

@ -0,0 +1,3 @@
fr:
created_at: "Ajoutée le %{datetime}"
updated_at: "Modifiée le %{datetime}"

View file

@ -0,0 +1,26 @@
.gallery-item
- if !gallery_demande?
%p.fr-tag.fr-tag--sm.fr-mb-3v= origin
- if displayable_pdf?(blob) || displayable_image?(blob)
= gallery_link(blob) do
.thumbnail
= image_tag(representation_url_for(attachment), loading: :lazy)
.fr-btn.fr-btn--tertiary.fr-btn--icon-left.fr-icon-eye{ role: :button }
Visualiser
- if !gallery_demande?
.fr-text--sm.fr-mt-2v.fr-mb-1v
= libelle.truncate(25)
= render Attachment::ShowComponent.new(attachment:, truncate: true, new_tab: gallery_demande?)
- if !gallery_demande?
.fr-mt-2v.fr-mb-2v{ class: badge_updated_class }
= t(updated? ? '.updated_at' : '.created_at', datetime: helpers.try_format_datetime(updated_at, format: :veryshort))
- else
.thumbnail
= image_tag('apercu-indisponible.png')
- if !gallery_demande?
.fr-text--sm.fr-mt-2v.fr-mb-1v
= libelle.truncate(25)
= render Attachment::ShowComponent.new(attachment:, truncate: true, new_tab: gallery_demande?)
- if !gallery_demande?
.fr-mt-2v.fr-mb-2v{ class: badge_updated_class }
= t(updated? ? '.updated_at' : '.created_at', datetime: helpers.try_format_datetime(updated_at, format: :veryshort))

View file

@ -13,11 +13,13 @@ module Instructeurs
before_action :redirect_on_dossier_not_found, only: :show
before_action :redirect_on_dossier_in_batch_operation, only: [:archive, :unarchive, :follow, :unfollow, :passer_en_instruction, :repasser_en_construction, :repasser_en_instruction, :terminer, :restore, :destroy, :extend_conservation]
before_action :set_gallery_attachments, only: [:show, :pieces_jointes, :annotations_privees, :avis, :messagerie, :personnes_impliquees, :reaffectation]
after_action :mark_demande_as_read, only: :show
after_action :mark_messagerie_as_read, only: [:messagerie, :create_commentaire, :pending_correction]
after_action :mark_avis_as_read, only: [:avis, :create_avis]
after_action :mark_annotations_privees_as_read, only: [:annotations_privees, :update_annotations]
after_action :mark_pieces_jointes_as_read, only: [:pieces_jointes]
def extend_conservation
dossier.extend_conservation(1.month)
@ -371,25 +373,8 @@ module Instructeurs
end
def pieces_jointes
@dossier = current_instructeur.dossiers.find(params[:dossier_id])
champs_attachments_and_libelles = @dossier
.champs
.filter { _1.class.in?([Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp]) }
.flat_map do |c|
c.piece_justificative_file.map do |attachment|
[attachment, c.libelle]
end
end
commentaires_attachments_and_libelles = @dossier
.commentaires
.map(&:piece_jointe)
.map(&:attachments)
.flatten
.map { [_1, 'Messagerie'] }
@attachments_and_libelles = champs_attachments_and_libelles + commentaires_attachments_and_libelles
@dossier = dossier
@pieces_jointes_seen_at = current_instructeur.follows.find_by(dossier: dossier)&.pieces_jointes_seen_at
end
private
@ -471,6 +456,10 @@ module Instructeurs
current_instructeur.mark_tab_as_seen(dossier, :annotations_privees)
end
def mark_pieces_jointes_as_read
current_instructeur.mark_tab_as_seen(dossier, :pieces_jointes)
end
def aasm_error_message(exception, target_state:)
if exception.originating_state == target_state
"Le dossier est déjà #{dossier_display_state(target_state, lower: true)}."
@ -498,5 +487,26 @@ module Instructeurs
redirect_back(fallback_location: instructeur_dossier_path(procedure, dossier_in_batch))
end
end
def set_gallery_attachments
gallery_attachments_ids = Rails.cache.fetch([dossier, "gallery_attachments"], expires_in: 10.minutes) do
champs_attachments_ids = dossier
.champs
.where(type: [Champs::PieceJustificativeChamp.name, Champs::TitreIdentiteChamp.name])
.flat_map(&:piece_justificative_file)
.map(&:id)
commentaires_attachments_ids = dossier
.commentaires
.includes(piece_jointe_attachments: :blob)
.map(&:piece_jointe)
.map(&:attachments)
.flatten
.map(&:id)
champs_attachments_ids + commentaires_attachments_ids
end
@gallery_attachments = ActiveStorage::Attachment.where(id: gallery_attachments_ids)
end
end
end

View file

@ -341,7 +341,10 @@ module Users
@commentaire = CommentaireService.create(current_user, dossier, commentaire_params)
if @commentaire.errors.empty?
@commentaire.dossier.update!(last_commentaire_updated_at: Time.zone.now)
timestamps = [:last_commentaire_updated_at, :updated_at]
timestamps << :last_commentaire_piece_jointe_updated_at if @commentaire.piece_jointe.attached?
@commentaire.dossier.touch(*timestamps)
flash.notice = t('.message_send')
redirect_to messagerie_dossier_path(dossier)

View file

@ -9,6 +9,12 @@ module GalleryHelper
blob.variable? && blob.content_type.in?(AUTHORIZED_IMAGE_TYPES)
end
def representation_url_for(attachment)
return variant_url_for(attachment) if displayable_image?(attachment.blob)
preview_url_for(attachment) if displayable_pdf?(attachment.blob)
end
def preview_url_for(attachment)
preview = attachment.preview(resize_to_limit: [400, 400])
preview.image.attached? ? preview.processed.url : 'pdf-placeholder.png'

View file

@ -71,6 +71,7 @@ module DossierCloneConcern
diff = make_diff(editing_fork)
apply_diff(diff)
touch(:last_champ_updated_at)
touch(:last_champ_piece_jointe_updated_at) if diff[:updated].any? { |c| c.class.in?([Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp]) }
end
reload
index_search_terms_later

View file

@ -377,7 +377,9 @@ class Dossier < ApplicationRecord
' OR groupe_instructeur_updated_at > follows.demande_seen_at' \
' OR last_champ_private_updated_at > follows.annotations_privees_seen_at' \
' OR last_avis_updated_at > follows.avis_seen_at' \
' OR last_commentaire_updated_at > follows.messagerie_seen_at')
' OR last_commentaire_updated_at > follows.messagerie_seen_at' \
' OR last_commentaire_piece_jointe_updated_at > follows.pieces_jointes_seen_at' \
' OR last_champ_piece_jointe_updated_at > follows.pieces_jointes_seen_at')
.distinct
end

View file

@ -18,5 +18,6 @@ class Follow < ApplicationRecord
self.annotations_privees_seen_at ||= Time.zone.now
self.avis_seen_at ||= Time.zone.now
self.messagerie_seen_at ||= Time.zone.now
self.pieces_jointes_seen_at ||= Time.zone.now
end
end

View file

@ -125,10 +125,11 @@ class Instructeur < ApplicationRecord
annotations_privees = dossier.last_champ_private_updated_at&.>(follow.annotations_privees_seen_at) || false
avis_notif = dossier.last_avis_updated_at&.>(follow.avis_seen_at) || false
messagerie = dossier.last_commentaire_updated_at&.>(follow.messagerie_seen_at) || false
pieces_jointes = dossier.last_champ_piece_jointe_updated_at&.>(follow.pieces_jointes_seen_at) || dossier.last_commentaire_piece_jointe_updated_at&.>(follow.pieces_jointes_seen_at) || false
annotations_hash(demande, annotations_privees, avis_notif, messagerie)
annotations_hash(demande, annotations_privees, avis_notif, messagerie, pieces_jointes)
else
annotations_hash(false, false, false, false)
annotations_hash(false, false, false, false, false)
end
end
@ -314,12 +315,13 @@ class Instructeur < ApplicationRecord
private
def annotations_hash(demande, annotations_privees, avis, messagerie)
def annotations_hash(demande, annotations_privees, avis, messagerie, pieces_jointes)
{
demande: demande,
annotations_privees: annotations_privees,
avis: avis,
messagerie: messagerie
messagerie: messagerie,
pieces_jointes: pieces_jointes
}
end

View file

@ -7,7 +7,7 @@
.sub-header
= render partial: 'instructeurs/dossiers/header_top', locals: { dossier: }
= render partial: 'instructeurs/dossiers/header_bottom', locals: { dossier: }
= render partial: 'instructeurs/dossiers/header_bottom', locals: { dossier:, gallery_attachments: }
.fr-container
.print-header

View file

@ -7,9 +7,10 @@
instructeur_dossier_path(dossier.procedure, dossier),
notification: notifications_summary[:demande])
- if dossier.champs.map(&:piece_justificative_file).flatten.any?
- if gallery_attachments.present?
= dynamic_tab_item(t('views.instructeurs.dossiers.tab_steps.attachments'),
pieces_jointes_instructeur_dossier_path(dossier.procedure, dossier))
pieces_jointes_instructeur_dossier_path(dossier.procedure, dossier),
notification: notifications_summary[:pieces_jointes])
= dynamic_tab_item(t('views.instructeurs.dossiers.tab_steps.private_annotations'),
annotations_privees_instructeur_dossier_path(dossier.procedure, dossier),

View file

@ -1,6 +1,6 @@
- content_for(:title, "Annotations privées · Dossier nº #{@dossier.id} (#{@dossier.owner_name})")
= render partial: "header", locals: { dossier: @dossier }
= render partial: "header", locals: { dossier: @dossier, gallery_attachments: @gallery_attachments }
#dossier-annotations-privees
.fr-container

View file

@ -1,6 +1,6 @@
- content_for(:title, "Avis · Dossier nº #{@dossier.id} (#{@dossier.owner_name})")
= render partial: "header", locals: { dossier: @dossier }
= render partial: "header", locals: { dossier: @dossier, gallery_attachments: @gallery_attachments }
.container
.fr-grid-row

View file

@ -1,6 +1,6 @@
- content_for(:title, "Avis · Dossier nº #{@dossier.id} (#{@dossier.owner_name})")
= render partial: "header", locals: { dossier: @dossier }
= render partial: "header", locals: { dossier: @dossier, gallery_attachments: @gallery_attachments }
.container
.fr-grid-row

View file

@ -1,5 +1,5 @@
- content_for(:title, "Messagerie · Dossier nº #{@dossier.id} (#{@dossier.owner_name})")
= render partial: "header", locals: { dossier: @dossier }
= render partial: "header", locals: { dossier: @dossier, gallery_attachments: @gallery_attachments }
= render partial: "shared/dossiers/messagerie", locals: { dossier: @dossier, connected_user: current_instructeur, messagerie_seen_at: @messagerie_seen_at , new_commentaire: @commentaire, form_url: commentaire_instructeur_dossier_path(@dossier.procedure, @dossier) }

View file

@ -1,6 +1,6 @@
- content_for(:title, "Personnes impliquées · Dossier nº #{@dossier.id} (#{@dossier.owner_name})")
= render partial: "header", locals: { dossier: @dossier }
= render partial: "header", locals: { dossier: @dossier, gallery_attachments: @gallery_attachments }
.personnes-impliquees.container
= render partial: 'instructeurs/dossiers/envoyer_dossier_block', locals: { dossier: @dossier, potential_recipients: @potential_recipients }

View file

@ -1,35 +1,8 @@
- content_for(:title, "Pièces jointes")
= render partial: "header", locals: { dossier: @dossier }
= render partial: "header", locals: { dossier: @dossier, gallery_attachments: @gallery_attachments }
.fr-container
.gallery.gallery-pieces-jointes{ "data-controller": "lightbox" }
- @attachments_and_libelles.each do |attachment, libelle|
.gallery-item
- blob = attachment.blob
- if displayable_pdf?(blob)
= link_to blob.url, id: blob.id, data: { iframe: true, src: blob.url }, class: 'gallery-link', type: blob.content_type, title: "#{libelle} -- #{sanitize(blob.filename.to_s)}" do
.thumbnail
= image_tag(preview_url_for(attachment), loading: :lazy)
.fr-btn.fr-btn--tertiary.fr-btn--icon-left.fr-icon-eye{ role: :button }
Visualiser
.champ-libelle
= libelle.truncate(25)
= render Attachment::ShowComponent.new(attachment: attachment, truncate: true)
- elsif displayable_image?(blob)
= link_to image_url(blob_url(attachment)), title: "#{libelle} -- #{sanitize(blob.filename.to_s)}", data: { src: blob.url }, class: 'gallery-link' do
.thumbnail
= image_tag(variant_url_for(attachment), loading: :lazy)
.fr-btn.fr-btn--tertiary.fr-btn--icon-left.fr-icon-eye{ role: :button }
Visualiser
.champ-libelle
= libelle.truncate(25)
= render Attachment::ShowComponent.new(attachment: attachment, truncate: true)
- else
.thumbnail
= image_tag('apercu-indisponible.png')
.champ-libelle
= libelle.truncate(25)
= render Attachment::ShowComponent.new(attachment: attachment, truncate: true)
- @gallery_attachments.each do |attachment|
= render Attachment::GalleryItemComponent.new(attachment:, seen_at: @pieces_jointes_seen_at)

View file

@ -1,6 +1,6 @@
- content_for(:title, "Réaffectation · Dossier nº #{@dossier.id} (#{@dossier.owner_name})")
= render partial: "header", locals: { dossier: @dossier }
= render partial: "header", locals: { dossier: @dossier, gallery_attachments: @gallery_attachments }
.container.groupe-instructeur

View file

@ -1,6 +1,6 @@
- content_for(:title, "Demande · Dossier nº #{@dossier.id} (#{@dossier.owner_name})")
= render partial: "header", locals: { dossier: @dossier }
= render partial: "header", locals: { dossier: @dossier, gallery_attachments: @gallery_attachments }
- if @dossier.etablissement&.as_degraded_mode?

View file

@ -2,25 +2,7 @@
- if profile == 'instructeur'
.gallery-items-list
- champ.piece_justificative_file.attachments.with_all_variant_records.each do |attachment|
.gallery-item
- blob = attachment.blob
- if displayable_pdf?(blob)
= link_to blob.url, id: blob.id, data: { iframe: true, src: blob.url }, class: 'gallery-link', type: blob.content_type, title: "#{champ.libelle} -- #{sanitize(blob.filename.to_s)}" do
.thumbnail
= image_tag(preview_url_for(attachment), loading: :lazy)
.fr-btn.fr-btn--tertiary.fr-btn--icon-left.fr-icon-eye{ role: :button }
= 'Visualiser'
- elsif displayable_image?(blob)
= link_to image_url(blob_url(attachment)), title: "#{champ.libelle} -- #{sanitize(blob.filename.to_s)}", data: { src: blob.url }, class: 'gallery-link' do
.thumbnail
= image_tag(variant_url_for(attachment), loading: :lazy)
.fr-btn.fr-btn--tertiary.fr-btn--icon-left.fr-icon-eye{ role: :button }
= 'Visualiser'
- else
.thumbnail
= image_tag('apercu-indisponible.png')
= render Attachment::ShowComponent.new(attachment:, new_tab: true, truncate: true)
= render Attachment::GalleryItemComponent.new(attachment:, gallery_demande: true)
- else
%ul
- champ.piece_justificative_file.attachments.each do |attachment|

View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
class AddPiecesJointesUpdatesToDossiers < ActiveRecord::Migration[7.0]
def change
add_column :dossiers, :last_champ_piece_jointe_updated_at, :datetime
add_column :dossiers, :last_commentaire_piece_jointe_updated_at, :datetime
end
end

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
class AddPiecesJointesSeenAtToFollows < ActiveRecord::Migration[7.0]
def up
add_column :follows, :pieces_jointes_seen_at, :datetime
change_column_default :follows, :pieces_jointes_seen_at, from: nil, to: 'CURRENT_TIMESTAMP'
end
def down
remove_column :follows, :pieces_jointes_seen_at
end
end

View file

@ -0,0 +1,14 @@
# frozen_string_literal: true
class BackfillFollowsWithPiecesJointesSeenAt < ActiveRecord::Migration[7.0]
disable_ddl_transaction!
def up
Follow.in_batches do |relation|
relation.update_all pieces_jointes_seen_at: Time.zone.now
sleep(0.001) # throttle
end
end
def down
end
end

View file

@ -488,8 +488,10 @@ ActiveRecord::Schema[7.0].define(version: 2024_09_23_125619) do
t.datetime "hidden_by_user_at", precision: nil
t.datetime "identity_updated_at", precision: nil
t.datetime "last_avis_updated_at", precision: nil
t.datetime "last_champ_piece_jointe_updated_at"
t.datetime "last_champ_private_updated_at", precision: nil
t.datetime "last_champ_updated_at", precision: nil
t.datetime "last_commentaire_piece_jointe_updated_at"
t.datetime "last_commentaire_updated_at", precision: nil
t.string "mandataire_first_name"
t.string "mandataire_last_name"
@ -689,6 +691,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_09_23_125619) do
t.integer "dossier_id", null: false
t.integer "instructeur_id", null: false
t.datetime "messagerie_seen_at", precision: nil, null: false
t.datetime "pieces_jointes_seen_at"
t.datetime "unfollowed_at", precision: nil
t.datetime "updated_at", precision: nil
t.index ["dossier_id"], name: "index_follows_on_dossier_id"

View file

@ -0,0 +1,104 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Attachment::GalleryItemComponent, type: :component do
let(:instructeur) { create(:instructeur) }
let(:procedure) { create(:procedure, :published, types_de_champ_public:) }
let(:types_de_champ_public) { [{ type: :piece_justificative }] }
let(:dossier) { create(:dossier, :with_populated_champs, :en_construction, procedure:) }
let(:filename) { attachment.blob.filename.to_s }
let(:gallery_demande) { false }
let(:seen_at) { nil }
let(:now) { Time.zone.now }
let(:component) { described_class.new(attachment: attachment, gallery_demande:, seen_at: seen_at) }
subject { render_inline(component).to_html }
context "when attachment is from a piece justificative champ" do
let(:champ) { dossier.champs.first }
let(:libelle) { champ.libelle }
let(:attachment) { champ.piece_justificative_file.attachments.first }
# Correspond au cas standard où le blob est créé avant le dépôt du dossier
before { dossier.touch(:depose_at) }
it "displays libelle, link, tag and renders title" do
expect(subject).to have_text(libelle)
expect(subject).not_to have_text('Pièce jointe au message')
expect(subject).to have_link(filename)
expect(subject).to have_text('Dossier usager')
expect(component.title).to eq("#{libelle} -- #{filename}")
end
it "displays when gallery item has been added" do
expect(subject).to have_text('Ajoutée le')
expect(subject).not_to have_css('.highlighted')
expect(subject).to have_text(component.helpers.try_format_datetime(attachment.record.created_at, format: :veryshort))
end
context "when gallery item has been updated" do
# un nouveau blob est créé après modification d'un champ pièce justificative
before { attachment.blob.touch(:created_at) }
it 'displays the right text' do
expect(subject).to have_text('Modifiée le')
end
end
context "when gallery item is in page Demande" do
let(:gallery_demande) { true }
it "does not display libelle" do
expect(subject).not_to have_text(libelle)
end
end
end
context "when attachment is from a commentaire" do
let(:commentaire) { create(:commentaire, :with_file, dossier: dossier) }
let(:attachment) { commentaire.piece_jointe.first }
context 'from an usager' do
it "displays a generic libelle, link, tag and renders title" do
expect(subject).to have_text('Pièce jointe au message')
expect(subject).to have_link(filename)
expect(subject).to have_text('Messagerie (usager)')
expect(component.title).to eq("Pièce jointe au message -- #{filename}")
end
context "when instructeur has not seen it yet" do
let(:seen_at) { now - 1.day }
before do
attachment.blob.update(created_at: now)
end
it 'displays datetime in the right style' do
expect(subject).to have_css('.highlighted')
end
end
context "when instructeur has already seen it" do
let!(:seen_at) { now }
before do
freeze_time
attachment.blob.touch(:created_at)
end
it 'displays datetime in the right style' do
expect(subject).not_to have_css('.highlighted')
end
end
end
context 'from an instructeur' do
before { commentaire.update!(instructeur:) }
it "displays the right tag" do
expect(subject).to have_text('Messagerie (instructeur)')
end
end
end
end

View file

@ -1513,7 +1513,9 @@ describe Instructeurs::DossiersController, type: :controller do
expect(response.body).to include('Télécharger le fichier logo_test_procedure.png')
expect(response.body).to include('Télécharger le fichier RIB.pdf')
expect(response.body).to include('Visualiser')
expect(assigns(:attachments_and_libelles).count).to eq 3
expect(assigns(:gallery_attachments).count).to eq 3
expect(assigns(:gallery_attachments)).to all(be_a(ActiveStorage::Attachment))
expect([Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp, Commentaire]).to include(*assigns(:gallery_attachments).map { _1.record.class })
end
end
end

View file

@ -74,4 +74,20 @@ RSpec.describe GalleryHelper, type: :helper do
it { is_expected.to eq("pdf-placeholder.png") }
end
end
describe ".representation_url_for" do
subject { representation_url_for(attachment) }
context "when attachment is an image with no variant" do
let(:file) { fixture_file_upload('spec/fixtures/files/logo_test_procedure.png', 'image/png') }
it { is_expected.to eq("apercu-indisponible.png") }
end
context "when attachment is a pdf with no preview" do
let(:file) { fixture_file_upload('spec/fixtures/files/RIB.pdf', 'application/pdf') }
it { is_expected.to eq("pdf-placeholder.png") }
end
end
end

View file

@ -44,7 +44,9 @@ RSpec.describe DossierCloneConcern do
expect(new_dossier.last_avis_updated_at).to be_nil
expect(new_dossier.last_champ_private_updated_at).to be_nil
expect(new_dossier.last_champ_updated_at).to be_nil
expect(new_dossier.last_champ_piece_jointe_updated_at).to be_nil
expect(new_dossier.last_commentaire_updated_at).to be_nil
expect(new_dossier.last_commentaire_piece_jointe_updated_at).to be_nil
expect(new_dossier.motivation).to be_nil
expect(new_dossier.processed_at).to be_nil
end

View file

@ -196,7 +196,7 @@ describe Instructeur, type: :model do
subject { instructeur.notifications_for_dossier(dossier) }
context 'when the instructeur has just followed the dossier' do
it { is_expected.to match({ demande: false, annotations_privees: false, avis: false, messagerie: false }) }
it { is_expected.to match({ demande: false, annotations_privees: false, avis: false, messagerie: false, pieces_jointes: false }) }
end
context 'when there is a modification on public champs' do
@ -205,20 +205,20 @@ describe Instructeur, type: :model do
dossier.update(last_champ_updated_at: Time.zone.now)
}
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, pieces_jointes: false }) }
end
context 'when there is a modification on identity' do
before { dossier.update(identity_updated_at: Time.zone.now) }
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, pieces_jointes: false }) }
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, DossierAssignment.modes.fetch(:auto)) }
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, pieces_jointes: false }) }
end
context 'when there is a modification on private champs' do
@ -227,7 +227,7 @@ describe Instructeur, type: :model do
dossier.update(last_champ_private_updated_at: Time.zone.now)
}
it { is_expected.to match({ demande: false, annotations_privees: true, avis: false, messagerie: false }) }
it { is_expected.to match({ demande: false, annotations_privees: true, avis: false, messagerie: false, pieces_jointes: false }) }
end
context 'when there is a modification on avis' do
@ -236,23 +236,34 @@ describe Instructeur, type: :model do
dossier.update(last_avis_updated_at: Time.zone.now)
}
it { is_expected.to match({ demande: false, annotations_privees: false, avis: true, messagerie: false }) }
it { is_expected.to match({ demande: false, annotations_privees: false, avis: true, messagerie: false, pieces_jointes: false }) }
end
context 'messagerie' do
context 'when there is a new commentaire' do
before {
create(:commentaire, dossier: dossier, email: 'a@b.com')
dossier.update(last_commentaire_updated_at: Time.zone.now)
}
context 'without a file' do
before {
create(:commentaire, dossier: dossier, email: 'a@b.com')
dossier.update(last_commentaire_updated_at: Time.zone.now)
}
it { is_expected.to match({ demande: false, annotations_privees: false, avis: false, messagerie: true }) }
it { is_expected.to match({ demande: false, annotations_privees: false, avis: false, messagerie: true, pieces_jointes: false }) }
end
context 'with a file' do
before {
create(:commentaire, :with_file, dossier: dossier, email: 'a@b.com')
dossier.update(last_commentaire_updated_at: Time.zone.now, last_commentaire_piece_jointe_updated_at: Time.zone.now)
}
it { is_expected.to match({ demande: false, annotations_privees: false, avis: false, messagerie: true, pieces_jointes: true }) }
end
end
context 'when there is a new commentaire issued by tps' do
before { create(:commentaire, dossier: dossier, email: CONTACT_EMAIL) }
it { is_expected.to match({ demande: false, annotations_privees: false, avis: false, messagerie: false }) }
it { is_expected.to match({ demande: false, annotations_privees: false, avis: false, messagerie: false, pieces_jointes: false }) }
end
end
end