Merge pull request #4779 from tchak/destory_dossiers_en_construction_next
Préparation de la suppression périodique des dossiers en construction (suite)
This commit is contained in:
commit
f0ece8c8f2
13 changed files with 474 additions and 129 deletions
7
app/jobs/expired_dossiers_deletion_job.rb
Normal file
7
app/jobs/expired_dossiers_deletion_job.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
class ExpiredDossiersDeletionJob < ApplicationJob
|
||||
queue_as :cron
|
||||
|
||||
def perform(*args)
|
||||
ExpiredDossiersDeletionService.process_dossiers_brouillon
|
||||
end
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
class SeekAndDestroyExpiredDossiersJob < ApplicationJob
|
||||
queue_as :cron
|
||||
|
||||
def perform(*args)
|
||||
Dossier.send_brouillon_expiration_notices
|
||||
Dossier.destroy_brouillons_and_notify
|
||||
end
|
||||
end
|
|
@ -3,8 +3,7 @@ class WarnExpiringDossiersJob < ApplicationJob
|
|||
|
||||
def perform(*args)
|
||||
expiring, expired = Dossier
|
||||
.includes(:procedure)
|
||||
.nearing_end_of_retention
|
||||
.en_instruction_close_to_expiration
|
||||
.partition(&:retention_expired?)
|
||||
|
||||
AdministrationMailer.dossier_expiration_summary(expiring, expired).deliver_later
|
||||
|
|
|
@ -69,26 +69,26 @@ class DossierMailer < ApplicationMailer
|
|||
mail(to: user.email, subject: @subject)
|
||||
end
|
||||
|
||||
def notify_automatic_deletion_to_user(user, dossier_hashes)
|
||||
def notify_automatic_deletion_to_user(email, dossier_hashes)
|
||||
@subject = default_i18n_subject(count: dossier_hashes.count)
|
||||
@dossier_hashes = dossier_hashes
|
||||
|
||||
mail(to: user.email, subject: @subject)
|
||||
mail(to: email, subject: @subject)
|
||||
end
|
||||
|
||||
def notify_automatic_deletion_to_administration(user, dossier_hashes)
|
||||
def notify_automatic_deletion_to_administration(email, dossier_hashes)
|
||||
@subject = default_i18n_subject(count: dossier_hashes.count)
|
||||
@dossier_hashes = dossier_hashes
|
||||
|
||||
mail(to: user.email, subject: @subject)
|
||||
mail(to: email, subject: @subject)
|
||||
end
|
||||
|
||||
def notify_en_construction_near_deletion(user, dossiers, for_user)
|
||||
def notify_en_construction_near_deletion(email, dossiers, for_user)
|
||||
@subject = default_i18n_subject(count: dossiers.count)
|
||||
@dossiers = dossiers
|
||||
@for_user = for_user
|
||||
|
||||
mail(to: user.email, subject: @subject)
|
||||
mail(to: email, subject: @subject)
|
||||
end
|
||||
|
||||
def notify_groupe_instructeur_changed(instructeur, dossier)
|
||||
|
|
|
@ -22,8 +22,6 @@ class Dossier < ApplicationRecord
|
|||
|
||||
TAILLE_MAX_ZIP = 50.megabytes
|
||||
|
||||
DRAFT_EXPIRATION = 1.month + 5.days
|
||||
|
||||
has_one :etablissement, dependent: :destroy
|
||||
has_one :individual, validate: false, dependent: :destroy
|
||||
has_one :attestation, dependent: :destroy
|
||||
|
@ -140,7 +138,6 @@ class Dossier < ApplicationRecord
|
|||
scope :en_cours, -> { not_archived.state_en_construction_ou_instruction }
|
||||
scope :without_followers, -> { left_outer_joins(:follows).where(follows: { id: nil }) }
|
||||
scope :with_champs, -> { includes(champs: :type_de_champ) }
|
||||
scope :nearing_end_of_retention, -> (duration = '1 month') { joins(:procedure).where("en_instruction_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - now() < interval ?", duration) }
|
||||
scope :for_api, -> {
|
||||
includes(commentaires: { piece_jointe_attachment: :blob },
|
||||
champs: [
|
||||
|
@ -170,10 +167,24 @@ class Dossier < ApplicationRecord
|
|||
scope :brouillon_close_to_expiration, -> do
|
||||
brouillon
|
||||
.joins(:procedure)
|
||||
.where("dossiers.created_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - (1 * interval '1 month') <= now()")
|
||||
.where("dossiers.created_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - INTERVAL '1 month' <= now()")
|
||||
end
|
||||
scope :expired_brouillon, -> { brouillon.where("brouillon_close_to_expiration_notice_sent_at < ?", (Time.zone.now - (DRAFT_EXPIRATION))) }
|
||||
scope :without_notice_sent, -> { where(brouillon_close_to_expiration_notice_sent_at: nil) }
|
||||
scope :en_construction_close_to_expiration, -> do
|
||||
en_construction
|
||||
.joins(:procedure)
|
||||
.where("dossiers.en_construction_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - INTERVAL '1 month' <= now()")
|
||||
end
|
||||
scope :en_instruction_close_to_expiration, -> do
|
||||
en_instruction
|
||||
.joins(:procedure)
|
||||
.where("dossiers.en_instruction_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - INTERVAL '1 month' <= now()")
|
||||
end
|
||||
|
||||
scope :brouillon_expired, -> { brouillon.where("brouillon_close_to_expiration_notice_sent_at < (now() - INTERVAL '1 month 5 days')") }
|
||||
scope :en_construction_expired, -> { en_construction.where("en_construction_close_to_expiration_notice_sent_at < (now() - INTERVAL '1 month 5 days')") }
|
||||
|
||||
scope :without_brouillon_expiration_notice_sent, -> { where(brouillon_close_to_expiration_notice_sent_at: nil) }
|
||||
scope :without_en_construction_expiration_notice_sent, -> { where(en_construction_close_to_expiration_notice_sent_at: nil) }
|
||||
|
||||
scope :for_procedure, -> (procedure) { includes(:user, :groupe_instructeur).where(groupe_instructeurs: { procedure: procedure }) }
|
||||
scope :for_api_v2, -> { includes(procedure: [:administrateurs], etablissement: [], individual: []) }
|
||||
|
@ -669,36 +680,4 @@ class Dossier < ApplicationRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.send_brouillon_expiration_notices
|
||||
brouillons = Dossier
|
||||
.brouillon_close_to_expiration
|
||||
.without_notice_sent
|
||||
|
||||
brouillons
|
||||
.includes(:user)
|
||||
.group_by(&:user)
|
||||
.each do |(user, dossiers)|
|
||||
DossierMailer.notify_brouillon_near_deletion(user, dossiers).deliver_later
|
||||
end
|
||||
|
||||
brouillons.update_all(brouillon_close_to_expiration_notice_sent_at: Time.zone.now)
|
||||
end
|
||||
|
||||
def self.destroy_brouillons_and_notify
|
||||
expired_brouillons = Dossier.expired_brouillon
|
||||
|
||||
expired_brouillons
|
||||
.includes(:procedure, :user)
|
||||
.group_by(&:user)
|
||||
.each do |(user, dossiers)|
|
||||
dossier_hashes = dossiers.map(&:hash_for_deletion_mail)
|
||||
DossierMailer.notify_brouillon_deletion(user, dossier_hashes).deliver_later
|
||||
|
||||
dossiers.each do |dossier|
|
||||
DeletedDossier.create_from_dossier(dossier)
|
||||
dossier.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
105
app/services/expired_dossiers_deletion_service.rb
Normal file
105
app/services/expired_dossiers_deletion_service.rb
Normal file
|
@ -0,0 +1,105 @@
|
|||
class ExpiredDossiersDeletionService
|
||||
def self.process_expired_dossiers_brouillon
|
||||
send_brouillon_expiration_notices
|
||||
delete_expired_brouillons_and_notify
|
||||
end
|
||||
|
||||
def self.process_expired_dossiers_en_construction
|
||||
send_en_construction_expiration_notices
|
||||
delete_expired_en_construction_and_notify
|
||||
end
|
||||
|
||||
def self.send_brouillon_expiration_notices
|
||||
dossiers_close_to_expiration = Dossier
|
||||
.brouillon_close_to_expiration
|
||||
.without_brouillon_expiration_notice_sent
|
||||
|
||||
dossiers_close_to_expiration
|
||||
.includes(:user, :procedure)
|
||||
.group_by(&:user)
|
||||
.each do |(user, dossiers)|
|
||||
DossierMailer.notify_brouillon_near_deletion(user, dossiers).deliver_later
|
||||
end
|
||||
|
||||
dossiers_close_to_expiration.update_all(brouillon_close_to_expiration_notice_sent_at: Time.zone.now)
|
||||
end
|
||||
|
||||
def self.send_en_construction_expiration_notices
|
||||
dossiers_close_to_expiration = Dossier
|
||||
.en_construction_close_to_expiration
|
||||
.without_en_construction_expiration_notice_sent
|
||||
|
||||
dossiers_close_to_expiration
|
||||
.includes(:user)
|
||||
.group_by(&:user)
|
||||
.each do |(user, dossiers)|
|
||||
DossierMailer.notify_en_construction_near_deletion(
|
||||
user.email,
|
||||
dossiers,
|
||||
true
|
||||
).deliver_later
|
||||
end
|
||||
|
||||
group_by_fonctionnaire_email(dossiers_close_to_expiration).each do |(destinataire, dossiers)|
|
||||
DossierMailer.notify_en_construction_near_deletion(
|
||||
destinataire,
|
||||
dossiers,
|
||||
false
|
||||
).deliver_later
|
||||
end
|
||||
|
||||
dossiers_close_to_expiration.update_all(en_construction_close_to_expiration_notice_sent_at: Time.zone.now)
|
||||
end
|
||||
|
||||
def self.delete_expired_brouillons_and_notify
|
||||
dossiers_to_remove = Dossier.brouillon_expired
|
||||
|
||||
dossiers_to_remove
|
||||
.includes(:user, :procedure)
|
||||
.group_by(&:user)
|
||||
.each do |(user, dossiers)|
|
||||
DossierMailer.notify_brouillon_deletion(user, dossiers.map(&:hash_for_deletion_mail)).deliver_later
|
||||
end
|
||||
|
||||
dossiers_to_remove.each do |dossier|
|
||||
DeletedDossier.create_from_dossier(dossier)
|
||||
dossier.destroy
|
||||
end
|
||||
end
|
||||
|
||||
def self.delete_expired_en_construction_and_notify
|
||||
dossiers_to_remove = Dossier.en_construction_expired
|
||||
|
||||
dossiers_to_remove
|
||||
.includes(:user)
|
||||
.group_by(&:user)
|
||||
.each do |(user, dossiers)|
|
||||
DossierMailer.notify_automatic_deletion_to_user(
|
||||
user.email,
|
||||
dossiers.map(&:hash_for_deletion_mail)
|
||||
).deliver_later
|
||||
end
|
||||
|
||||
self.group_by_fonctionnaire_email(dossiers_to_remove).each do |(destinataire, dossiers)|
|
||||
DossierMailer.notify_automatic_deletion_to_administration(
|
||||
destinataire,
|
||||
dossiers.map(&:hash_for_deletion_mail)
|
||||
).deliver_later
|
||||
end
|
||||
|
||||
dossiers_to_remove.each do |dossier|
|
||||
DeletedDossier.create_from_dossier(dossier)
|
||||
dossier.destroy
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.group_by_fonctionnaire_email(dossiers)
|
||||
dossiers
|
||||
.includes(:followers_instructeurs, procedure: [:administrateurs])
|
||||
.each_with_object(Hash.new { |h, k| h[k] = Set.new }) do |dossier, h|
|
||||
(dossier.followers_instructeurs + dossier.procedure.administrateurs).each { |destinataire| h[destinataire.email] << dossier }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
%ul
|
||||
- @dossier_hashes.each do |d|
|
||||
%li= link_to("n° #{d[:id]} (#{d[:procedure_libelle]})", dossier_url(d))
|
||||
%li= "n° #{d[:id]} (#{d[:procedure_libelle]})"
|
||||
|
||||
%p= t('.dossier_will_not_be_processed', count: @dossier_hashes.count)
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddEnConstructionCloseToExpirationToDossiers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :dossiers, :en_construction_close_to_expiration_notice_sent_at, :datetime
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_03_04_155418) do
|
||||
ActiveRecord::Schema.define(version: 2020_03_05_155418) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -253,6 +253,7 @@ ActiveRecord::Schema.define(version: 2020_03_04_155418) do
|
|||
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.datetime "groupe_instructeur_updated_at"
|
||||
t.datetime "en_construction_close_to_expiration_notice_sent_at"
|
||||
t.index ["archived"], name: "index_dossiers_on_archived"
|
||||
t.index ["groupe_instructeur_id"], name: "index_dossiers_on_groupe_instructeur_id"
|
||||
t.index ["hidden_at"], name: "index_dossiers_on_hidden_at"
|
||||
|
|
|
@ -104,8 +104,9 @@ RSpec.describe DossierMailer, type: :mailer do
|
|||
@date_suppression = dossier.created_at + duree.months
|
||||
end
|
||||
|
||||
subject { described_class.notify_automatic_deletion_to_user(dossier.user, [dossier.hash_for_deletion_mail]) }
|
||||
subject { described_class.notify_automatic_deletion_to_user(dossier.user.email, [dossier.hash_for_deletion_mail]) }
|
||||
|
||||
it { expect(subject.to).to eq([dossier.user.email]) }
|
||||
it { expect(subject.subject).to eq("Un dossier a été supprimé automatiquement") }
|
||||
it { expect(subject.body).to include("n° #{dossier.id} ") }
|
||||
it { expect(subject.body).to include(dossier.procedure.libelle) }
|
||||
|
@ -129,7 +130,7 @@ RSpec.describe DossierMailer, type: :mailer do
|
|||
@date_suppression = dossier.created_at + duree.months
|
||||
end
|
||||
|
||||
subject { described_class.notify_en_construction_near_deletion(dossier.user, [dossier], true) }
|
||||
subject { described_class.notify_en_construction_near_deletion(dossier.user.email, [dossier], true) }
|
||||
|
||||
it { expect(subject.subject).to eq("Un dossier en construction va bientôt être supprimé") }
|
||||
it { expect(subject.body).to include("n° #{dossier.id} ") }
|
||||
|
@ -146,8 +147,9 @@ RSpec.describe DossierMailer, type: :mailer do
|
|||
@date_suppression = dossier.created_at + duree.months
|
||||
end
|
||||
|
||||
subject { described_class.notify_en_construction_near_deletion(dossier.user, [dossier], false) }
|
||||
subject { described_class.notify_en_construction_near_deletion(dossier.user.email, [dossier], false) }
|
||||
|
||||
it { expect(subject.to).to eq([dossier.user.email]) }
|
||||
it { expect(subject.subject).to eq("Un dossier en construction va bientôt être supprimé") }
|
||||
it { expect(subject.body).to include("n° #{dossier.id} ") }
|
||||
it { expect(subject.body).to include(dossier.procedure.libelle) }
|
||||
|
|
|
@ -37,6 +37,16 @@ class DossierMailerPreview < ActionMailer::Preview
|
|||
DossierMailer.notify_brouillon_deletion(User.new(email: "usager@example.com"), dossier_hashes)
|
||||
end
|
||||
|
||||
def notify_automatic_deletion_to_user
|
||||
dossier_hashes = [dossier, dossier].map(&:hash_for_deletion_mail)
|
||||
DossierMailer.notify_automatic_deletion_to_user("usager@example.com", dossier_hashes)
|
||||
end
|
||||
|
||||
def notify_automatic_deletion_to_administration
|
||||
dossier_hashes = [dossier, dossier].map(&:hash_for_deletion_mail)
|
||||
DossierMailer.notify_automatic_deletion_to_administration("admin@example.com", dossier_hashes)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deleted_dossier
|
||||
|
|
|
@ -45,29 +45,54 @@ describe Dossier do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'nearing_end_of_retention' do
|
||||
describe 'brouillon_close_to_expiration' do
|
||||
let(:procedure) { create(:procedure, duree_conservation_dossiers_dans_ds: 6) }
|
||||
let!(:young_dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||
let!(:expiring_dossier) { create(:dossier, created_at: 170.days.ago, procedure: procedure) }
|
||||
let!(:just_expired_dossier) { create(:dossier, created_at: (6.months + 1.hour + 10.seconds).ago, procedure: procedure) }
|
||||
let!(:long_expired_dossier) { create(:dossier, created_at: 1.year.ago, procedure: procedure) }
|
||||
|
||||
subject { Dossier.brouillon_close_to_expiration }
|
||||
|
||||
it do
|
||||
is_expected.not_to include(young_dossier)
|
||||
is_expected.to include(expiring_dossier)
|
||||
is_expected.to include(just_expired_dossier)
|
||||
is_expected.to include(long_expired_dossier)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'en_construction_close_to_expiration' do
|
||||
let(:procedure) { create(:procedure, duree_conservation_dossiers_dans_ds: 6) }
|
||||
let!(:young_dossier) { create(:dossier, procedure: procedure) }
|
||||
let!(:expiring_dossier) { create(:dossier, :en_construction, en_construction_at: 170.days.ago, procedure: procedure) }
|
||||
let!(:just_expired_dossier) { create(:dossier, :en_construction, en_construction_at: (6.months + 1.hour + 10.seconds).ago, procedure: procedure) }
|
||||
let!(:long_expired_dossier) { create(:dossier, :en_construction, en_construction_at: 1.year.ago, procedure: procedure) }
|
||||
|
||||
subject { Dossier.en_construction_close_to_expiration }
|
||||
|
||||
it do
|
||||
is_expected.not_to include(young_dossier)
|
||||
is_expected.to include(expiring_dossier)
|
||||
is_expected.to include(just_expired_dossier)
|
||||
is_expected.to include(long_expired_dossier)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'en_instruction_close_to_expiration' do
|
||||
let(:procedure) { create(:procedure, duree_conservation_dossiers_dans_ds: 6) }
|
||||
let!(:young_dossier) { create(:dossier, procedure: procedure) }
|
||||
let!(:expiring_dossier) { create(:dossier, :en_instruction, en_instruction_at: 170.days.ago, procedure: procedure) }
|
||||
let!(:just_expired_dossier) { create(:dossier, :en_instruction, en_instruction_at: (6.months + 1.hour + 10.seconds).ago, procedure: procedure) }
|
||||
let!(:long_expired_dossier) { create(:dossier, :en_instruction, en_instruction_at: 1.year.ago, procedure: procedure) }
|
||||
|
||||
context 'with default delay to end of retention' do
|
||||
subject { Dossier.nearing_end_of_retention }
|
||||
subject { Dossier.en_instruction_close_to_expiration }
|
||||
|
||||
it { is_expected.not_to include(young_dossier) }
|
||||
it { is_expected.to include(expiring_dossier) }
|
||||
it { is_expected.to include(just_expired_dossier) }
|
||||
it { is_expected.to include(long_expired_dossier) }
|
||||
end
|
||||
|
||||
context 'with custom delay to end of retention' do
|
||||
subject { Dossier.nearing_end_of_retention('0') }
|
||||
|
||||
it { is_expected.not_to include(young_dossier) }
|
||||
it { is_expected.not_to include(expiring_dossier) }
|
||||
it { is_expected.to include(just_expired_dossier) }
|
||||
it { is_expected.to include(long_expired_dossier) }
|
||||
it do
|
||||
is_expected.not_to include(young_dossier)
|
||||
is_expected.to include(expiring_dossier)
|
||||
is_expected.to include(just_expired_dossier)
|
||||
is_expected.to include(long_expired_dossier)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1072,60 +1097,6 @@ describe Dossier do
|
|||
it { expect(Dossier.for_procedure(procedure_2)).to contain_exactly(dossier_2_1) }
|
||||
end
|
||||
|
||||
describe '#send_brouillon_expiration_notices' do
|
||||
before { Timecop.freeze(Time.zone.parse('12/12/2012 15:00:00')) }
|
||||
|
||||
let!(:procedure) { create(:procedure, duree_conservation_dossiers_dans_ds: 6) }
|
||||
let!(:date_close_to_expiration) { Time.zone.now - procedure.duree_conservation_dossiers_dans_ds.months + 1.month }
|
||||
let!(:date_expired) { Time.zone.now - procedure.duree_conservation_dossiers_dans_ds.months - 6.days }
|
||||
let!(:date_not_expired) { Time.zone.now - procedure.duree_conservation_dossiers_dans_ds.months + 2.months }
|
||||
|
||||
after { Timecop.return }
|
||||
|
||||
context "Envoi de message pour les dossiers expirant dans - d'un mois" do
|
||||
let!(:expired_brouillon) { create(:dossier, procedure: procedure, created_at: date_expired) }
|
||||
let!(:brouillon_close_to_expiration) { create(:dossier, procedure: procedure, created_at: date_close_to_expiration) }
|
||||
let!(:brouillon_close_but_with_notice_sent) { create(:dossier, procedure: procedure, created_at: date_close_to_expiration, brouillon_close_to_expiration_notice_sent_at: Time.zone.now) }
|
||||
let!(:valid_brouillon) { create(:dossier, procedure: procedure, created_at: date_not_expired) }
|
||||
|
||||
before do
|
||||
allow(DossierMailer).to receive(:notify_brouillon_near_deletion).and_return(double(deliver_later: nil))
|
||||
Dossier.send_brouillon_expiration_notices
|
||||
end
|
||||
|
||||
it 'verification de la creation de mail' do
|
||||
expect(DossierMailer).to have_received(:notify_brouillon_near_deletion).with(brouillon_close_to_expiration.user, [brouillon_close_to_expiration])
|
||||
expect(DossierMailer).to have_received(:notify_brouillon_near_deletion).with(expired_brouillon.user, [expired_brouillon])
|
||||
end
|
||||
|
||||
it 'Verification du changement d etat du champ' do
|
||||
expect(brouillon_close_to_expiration.reload.brouillon_close_to_expiration_notice_sent_at).not_to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy_brouillons_and_notify' do
|
||||
let!(:today) { Time.zone.now.at_midnight }
|
||||
|
||||
let!(:expired_brouillon) { create(:dossier, brouillon_close_to_expiration_notice_sent_at: today - (Dossier::DRAFT_EXPIRATION + 1.day)) }
|
||||
let!(:other_brouillon) { create(:dossier, brouillon_close_to_expiration_notice_sent_at: today - (Dossier::DRAFT_EXPIRATION - 1.day)) }
|
||||
|
||||
before do
|
||||
allow(DossierMailer).to receive(:notify_brouillon_deletion).and_return(double(deliver_later: nil))
|
||||
Dossier.destroy_brouillons_and_notify
|
||||
end
|
||||
|
||||
it 'notifies deletion' do
|
||||
expect(DossierMailer).to have_received(:notify_brouillon_deletion).once
|
||||
expect(DossierMailer).to have_received(:notify_brouillon_deletion).with(expired_brouillon.user, [expired_brouillon.hash_for_deletion_mail])
|
||||
end
|
||||
|
||||
it 'deletes the expired brouillon' do
|
||||
expect(DeletedDossier.find_by(dossier_id: expired_brouillon.id)).to be_present
|
||||
expect { expired_brouillon.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#geo_position' do
|
||||
let(:lat) { "46.538192" }
|
||||
let(:lon) { "2.428462" }
|
||||
|
|
274
spec/services/expired_dossiers_deletion_service_spec.rb
Normal file
274
spec/services/expired_dossiers_deletion_service_spec.rb
Normal file
|
@ -0,0 +1,274 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ExpiredDossiersDeletionService do
|
||||
describe '#process_expired_dossiers_brouillon' do
|
||||
let(:draft_expiration) { 1.month + 5.days }
|
||||
let!(:today) { Time.zone.now.at_midnight }
|
||||
let!(:procedure) { create(:procedure, duree_conservation_dossiers_dans_ds: 6) }
|
||||
let!(:date_close_to_expiration) { Date.today - procedure.duree_conservation_dossiers_dans_ds.months + 1.month }
|
||||
let!(:date_expired) { Date.today - procedure.duree_conservation_dossiers_dans_ds.months - 6.days }
|
||||
let!(:date_not_expired) { Date.today - procedure.duree_conservation_dossiers_dans_ds.months + 2.months }
|
||||
|
||||
context 'send messages for dossiers expiring soon and delete expired' do
|
||||
let!(:expired_brouillon) { create(:dossier, procedure: procedure, created_at: date_expired, brouillon_close_to_expiration_notice_sent_at: today - (draft_expiration + 1.day)) }
|
||||
let!(:brouillon_close_to_expiration) { create(:dossier, procedure: procedure, created_at: date_close_to_expiration) }
|
||||
let!(:brouillon_close_but_with_notice_sent) { create(:dossier, procedure: procedure, created_at: date_close_to_expiration, brouillon_close_to_expiration_notice_sent_at: Time.zone.now) }
|
||||
let!(:valid_brouillon) { create(:dossier, procedure: procedure, created_at: date_not_expired) }
|
||||
|
||||
before do
|
||||
allow(DossierMailer).to receive(:notify_brouillon_near_deletion).and_return(double(deliver_later: nil))
|
||||
allow(DossierMailer).to receive(:notify_brouillon_deletion).and_return(double(deliver_later: nil))
|
||||
|
||||
ExpiredDossiersDeletionService.process_expired_dossiers_brouillon
|
||||
end
|
||||
|
||||
it 'emails should be sent' do
|
||||
expect(DossierMailer).to have_received(:notify_brouillon_near_deletion).once
|
||||
expect(DossierMailer).to have_received(:notify_brouillon_near_deletion).with(brouillon_close_to_expiration.user, [brouillon_close_to_expiration])
|
||||
end
|
||||
|
||||
it 'dossier state should change' do
|
||||
expect(brouillon_close_to_expiration.reload.brouillon_close_to_expiration_notice_sent_at).not_to be_nil
|
||||
end
|
||||
|
||||
it 'deletes and notify expired brouillon' do
|
||||
expect(DossierMailer).to have_received(:notify_brouillon_deletion).once
|
||||
expect(DossierMailer).to have_received(:notify_brouillon_deletion).with(expired_brouillon.user, [expired_brouillon.hash_for_deletion_mail])
|
||||
|
||||
expect(DeletedDossier.find_by(dossier_id: expired_brouillon.id)).to be_present
|
||||
expect { expired_brouillon.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#send_brouillon_expiration_notices' do
|
||||
let!(:conservation_par_defaut) { 3.months }
|
||||
|
||||
before { Timecop.freeze(Time.zone.now) }
|
||||
after { Timecop.return }
|
||||
|
||||
before do
|
||||
allow(DossierMailer).to receive(:notify_brouillon_near_deletion).and_return(double(deliver_later: nil))
|
||||
end
|
||||
|
||||
context 'with a single dossier' do
|
||||
let!(:dossier) { create(:dossier, created_at: created_at) }
|
||||
|
||||
before { ExpiredDossiersDeletionService.send_brouillon_expiration_notices }
|
||||
|
||||
context 'when the dossier is not closed to expiration' do
|
||||
let(:created_at) { (conservation_par_defaut - 1.month - 1.day).ago }
|
||||
|
||||
it { expect(dossier.reload.brouillon_close_to_expiration_notice_sent_at).to be_nil }
|
||||
it { expect(DossierMailer).not_to have_received(:notify_brouillon_near_deletion) }
|
||||
end
|
||||
|
||||
context 'when the dossier is closed to expiration' do
|
||||
let(:created_at) { (conservation_par_defaut - 1.month + 1.day).ago }
|
||||
|
||||
it { expect(dossier.reload.brouillon_close_to_expiration_notice_sent_at).not_to be_nil }
|
||||
it { expect(DossierMailer).to have_received(:notify_brouillon_near_deletion).once }
|
||||
it { expect(DossierMailer).to have_received(:notify_brouillon_near_deletion).with(dossier.user, [dossier]) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with 2 dossiers to notice' do
|
||||
let!(:user) { create(:user) }
|
||||
let!(:dossier_1) { create(:dossier, user: user, created_at: (conservation_par_defaut - 1.month + 1.day).ago) }
|
||||
let!(:dossier_2) { create(:dossier, user: user, created_at: (conservation_par_defaut - 1.month + 1.day).ago) }
|
||||
|
||||
before { ExpiredDossiersDeletionService.send_brouillon_expiration_notices }
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_brouillon_near_deletion).once }
|
||||
it { expect(DossierMailer).to have_received(:notify_brouillon_near_deletion).with(user, match_array([dossier_1, dossier_2])) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#delete_expired_brouillons_and_notify' do
|
||||
let!(:warning_period) { 1.month + 5.days }
|
||||
|
||||
before { Timecop.freeze(Time.zone.now) }
|
||||
after { Timecop.return }
|
||||
|
||||
before do
|
||||
allow(DossierMailer).to receive(:notify_brouillon_deletion).and_return(double(deliver_later: nil))
|
||||
end
|
||||
|
||||
context 'with a single dossier' do
|
||||
let!(:dossier) { create(:dossier, brouillon_close_to_expiration_notice_sent_at: notice_sent_at) }
|
||||
|
||||
before { ExpiredDossiersDeletionService.delete_expired_brouillons_and_notify }
|
||||
|
||||
context 'when no notice has been sent' do
|
||||
let(:notice_sent_at) { nil }
|
||||
|
||||
it { expect { dossier.reload }.not_to raise_error }
|
||||
it { expect(DossierMailer).not_to have_received(:notify_brouillon_deletion) }
|
||||
end
|
||||
|
||||
context 'when a notice has been sent not so long ago' do
|
||||
let(:notice_sent_at) { (warning_period - 1.day).ago }
|
||||
|
||||
it { expect { dossier.reload }.not_to raise_error }
|
||||
it { expect(DossierMailer).not_to have_received(:notify_brouillon_deletion) }
|
||||
end
|
||||
|
||||
context 'when a notice has been sent a long time ago' do
|
||||
let(:notice_sent_at) { (warning_period + 1.day).ago }
|
||||
|
||||
it { expect { dossier.reload }.to raise_error(ActiveRecord::RecordNotFound) }
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_brouillon_deletion).once }
|
||||
it { expect(DossierMailer).to have_received(:notify_brouillon_deletion).with(dossier.user, [dossier.hash_for_deletion_mail]) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with 2 dossiers to delete' do
|
||||
let!(:user) { create(:user) }
|
||||
let!(:dossier_1) { create(:dossier, user: user, brouillon_close_to_expiration_notice_sent_at: (warning_period + 1.day).ago) }
|
||||
let!(:dossier_2) { create(:dossier, user: user, brouillon_close_to_expiration_notice_sent_at: (warning_period + 1.day).ago) }
|
||||
|
||||
before { ExpiredDossiersDeletionService.delete_expired_brouillons_and_notify }
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_brouillon_deletion).once }
|
||||
it { expect(DossierMailer).to have_received(:notify_brouillon_deletion).with(user, match_array([dossier_1, dossier_2].map(&:hash_for_deletion_mail))) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#send_en_construction_expiration_notices' do
|
||||
let!(:conservation_par_defaut) { 3.months }
|
||||
|
||||
before { Timecop.freeze(Time.zone.now) }
|
||||
after { Timecop.return }
|
||||
|
||||
before do
|
||||
allow(DossierMailer).to receive(:notify_en_construction_near_deletion).and_return(double(deliver_later: nil))
|
||||
end
|
||||
|
||||
context 'with a single dossier' do
|
||||
let!(:dossier) { create(:dossier, :en_construction, :followed, en_construction_at: en_construction_at) }
|
||||
|
||||
before { ExpiredDossiersDeletionService.send_en_construction_expiration_notices }
|
||||
|
||||
context 'when the dossier is not near deletion' do
|
||||
let(:en_construction_at) { (conservation_par_defaut - 1.month - 1.day).ago }
|
||||
|
||||
it { expect(dossier.reload.en_construction_close_to_expiration_notice_sent_at).to be_nil }
|
||||
it { expect(DossierMailer).not_to have_received(:notify_en_construction_near_deletion) }
|
||||
end
|
||||
|
||||
context 'when the dossier is near deletion' do
|
||||
let(:en_construction_at) { (conservation_par_defaut - 1.month + 1.day).ago }
|
||||
|
||||
it { expect(dossier.reload.en_construction_close_to_expiration_notice_sent_at).not_to be_nil }
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).thrice }
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(dossier.user.email, [dossier], true) }
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(dossier.procedure.administrateurs.first.email, [dossier], false) }
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(dossier.followers_instructeurs.first.email, [dossier], false) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with 2 dossiers to notice' do
|
||||
let!(:user) { create(:user) }
|
||||
let!(:dossier_1) { create(:dossier, :en_construction, user: user, en_construction_at: (conservation_par_defaut - 1.month + 1.day).ago) }
|
||||
let!(:dossier_2) { create(:dossier, :en_construction, user: user, en_construction_at: (conservation_par_defaut - 1.month + 1.day).ago) }
|
||||
|
||||
let!(:instructeur) { create(:instructeur) }
|
||||
|
||||
before do
|
||||
instructeur.followed_dossiers << dossier_1 << dossier_2
|
||||
ExpiredDossiersDeletionService.send_en_construction_expiration_notices
|
||||
end
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).exactly(4).times }
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(user.email, match_array([dossier_1, dossier_2]), true) }
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(instructeur.email, match_array([dossier_1, dossier_2]), false) }
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(dossier_1.procedure.administrateurs.first.email, [dossier_1], false) }
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(dossier_2.procedure.administrateurs.first.email, [dossier_2], false) }
|
||||
end
|
||||
|
||||
context 'when an instructeur is also administrateur' do
|
||||
let!(:procedure) { create(:procedure) }
|
||||
let!(:administrateur) { procedure.administrateurs.first }
|
||||
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure, en_construction_at: (conservation_par_defaut - 1.month + 1.day).ago) }
|
||||
|
||||
before do
|
||||
administrateur.instructeur.followed_dossiers << dossier
|
||||
ExpiredDossiersDeletionService.send_en_construction_expiration_notices
|
||||
end
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).exactly(2).times }
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(dossier.user.email, [dossier], true) }
|
||||
it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(administrateur.email, [dossier], false) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#delete_expired_en_construction_and_notify' do
|
||||
let!(:warning_period) { 1.month + 5.days }
|
||||
|
||||
before { Timecop.freeze(Time.zone.now) }
|
||||
after { Timecop.return }
|
||||
|
||||
before do
|
||||
allow(DossierMailer).to receive(:notify_automatic_deletion_to_user).and_return(double(deliver_later: nil))
|
||||
allow(DossierMailer).to receive(:notify_automatic_deletion_to_administration).and_return(double(deliver_later: nil))
|
||||
end
|
||||
|
||||
context 'with a single dossier' do
|
||||
let!(:dossier) { create(:dossier, :en_construction, :followed, en_construction_close_to_expiration_notice_sent_at: notice_sent_at) }
|
||||
|
||||
before { ExpiredDossiersDeletionService.delete_expired_en_construction_and_notify }
|
||||
|
||||
context 'when no notice has been sent' do
|
||||
let(:notice_sent_at) { nil }
|
||||
|
||||
it { expect { dossier.reload }.not_to raise_error }
|
||||
it { expect(DossierMailer).not_to have_received(:notify_automatic_deletion_to_user) }
|
||||
it { expect(DossierMailer).not_to have_received(:notify_automatic_deletion_to_administration) }
|
||||
end
|
||||
|
||||
context 'when a notice has been sent not so long ago' do
|
||||
let(:notice_sent_at) { (warning_period - 1.day).ago }
|
||||
|
||||
it { expect { dossier.reload }.not_to raise_error }
|
||||
it { expect(DossierMailer).not_to have_received(:notify_automatic_deletion_to_user) }
|
||||
it { expect(DossierMailer).not_to have_received(:notify_automatic_deletion_to_administration) }
|
||||
end
|
||||
|
||||
context 'when a notice has been sent a long time ago' do
|
||||
let(:notice_sent_at) { (warning_period + 1.day).ago }
|
||||
|
||||
it { expect { dossier.reload }.to raise_error(ActiveRecord::RecordNotFound) }
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_user).once }
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_user).with(dossier.user.email, [dossier.hash_for_deletion_mail]) }
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).twice }
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with(dossier.procedure.administrateurs.first.email, [dossier.hash_for_deletion_mail]) }
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with(dossier.followers_instructeurs.first.email, [dossier.hash_for_deletion_mail]) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with 2 dossiers to delete' do
|
||||
let!(:user) { create(:user) }
|
||||
let!(:dossier_1) { create(:dossier, :en_construction, user: user, en_construction_close_to_expiration_notice_sent_at: (warning_period + 1.day).ago) }
|
||||
let!(:dossier_2) { create(:dossier, :en_construction, user: user, en_construction_close_to_expiration_notice_sent_at: (warning_period + 1.day).ago) }
|
||||
|
||||
let!(:instructeur) { create(:instructeur) }
|
||||
|
||||
before do
|
||||
instructeur.followed_dossiers << dossier_1 << dossier_2
|
||||
ExpiredDossiersDeletionService.delete_expired_en_construction_and_notify
|
||||
end
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_user).once }
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_user).with(user.email, match_array([dossier_1, dossier_2].map(&:hash_for_deletion_mail))) }
|
||||
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).thrice }
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with(instructeur.email, match_array([dossier_1, dossier_2].map(&:hash_for_deletion_mail))) }
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with(dossier_1.procedure.administrateurs.first.email, [dossier_1.hash_for_deletion_mail]) }
|
||||
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with(dossier_2.procedure.administrateurs.first.email, [dossier_2.hash_for_deletion_mail]) }
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue