2024-04-29 00:17:15 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2021-06-15 11:33:17 +02:00
|
|
|
describe ProcedureStatsConcern do
|
2023-01-20 14:28:02 +01:00
|
|
|
describe '#stats_dossiers_funnel' do
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
|
|
|
subject(:stats_dossiers_funnel) { procedure.stats_dossiers_funnel }
|
|
|
|
|
|
|
|
before do
|
|
|
|
create_list(:dossier, 2, :brouillon, procedure: procedure)
|
|
|
|
create(:dossier, :en_instruction, procedure: procedure)
|
2023-02-23 13:13:01 +01:00
|
|
|
create(:dossier, procedure: procedure, for_procedure_preview: true)
|
|
|
|
create(:dossier, :accepte, procedure: procedure, hidden_by_administration_at: Time.zone.now)
|
2023-01-20 14:28:02 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the funnel stats" do
|
|
|
|
expect(stats_dossiers_funnel).to match(
|
|
|
|
[
|
2024-03-18 10:39:11 +01:00
|
|
|
['Tous (dont brouillon)', procedure.dossiers.visible_by_user_or_administration.count],
|
2023-02-23 13:13:01 +01:00
|
|
|
['Déposés', procedure.dossiers.visible_by_administration.count],
|
|
|
|
['Instruction débutée', procedure.dossiers.visible_by_administration.state_instruction_commencee.count],
|
|
|
|
['Traités', procedure.dossiers.visible_by_administration.state_termine.count]
|
2023-01-20 14:28:02 +01:00
|
|
|
]
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-06-16 14:41:09 +02:00
|
|
|
describe '#usual_traitement_time_for_recent_dossiers' do
|
2021-06-15 11:33:17 +02:00
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
Timecop.freeze(Time.utc(2019, 6, 1, 12, 0))
|
|
|
|
|
|
|
|
delays.each do |delay|
|
2023-11-14 17:51:30 +01:00
|
|
|
create_dossier(depose_at: 1.week.ago - delay, en_instruction_at: 1.week.ago - delay + 12.hours, processed_at: 1.week.ago)
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
after { Timecop.return }
|
|
|
|
|
|
|
|
context 'when there are several processed dossiers' do
|
|
|
|
let(:delays) { [1.day, 2.days, 2.days, 2.days, 2.days, 3.days, 3.days, 3.days, 3.days, 12.days] }
|
|
|
|
|
|
|
|
it 'returns a time representative of the dossier instruction delay' do
|
2023-11-21 12:33:39 +01:00
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30)[0]).to be_between(1.day, 2.days)
|
2023-11-14 17:51:30 +01:00
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30)[1]).to be_between(2.days, 3.days)
|
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30)[2]).to be_between(11.days, 12.days)
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when there are very old dossiers' do
|
2023-11-21 12:33:39 +01:00
|
|
|
let(:delays) { [1.day, 2.days, 3.days, 3.days, 4.days] }
|
2023-11-14 17:51:30 +01:00
|
|
|
let!(:old_dossier) { create_dossier(depose_at: 3.months.ago, en_instruction_at: 2.months.ago, processed_at: 2.months.ago) }
|
2021-06-15 11:33:17 +02:00
|
|
|
|
|
|
|
it 'ignores dossiers older than 1 month' do
|
2023-11-14 17:51:30 +01:00
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30)[0]).to be_between(1.day, 2.days)
|
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30)[1]).to be_between(2.days, 3.days)
|
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30)[2]).to be_between(3.days, 4.days)
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when there is a dossier with bad data' do
|
2023-11-21 12:33:39 +01:00
|
|
|
let(:delays) { [1.day, 2.days, 3.days, 3.days, 4.days] }
|
2023-11-14 17:51:30 +01:00
|
|
|
let!(:bad_dossier) { create_dossier(depose_at: nil, en_instruction_at: nil, processed_at: 10.days.ago) }
|
2021-06-15 11:33:17 +02:00
|
|
|
|
|
|
|
it 'ignores bad dossiers' do
|
2023-11-14 17:51:30 +01:00
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30)[0]).to be_between(21.hours, 36.hours.days)
|
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30)[1]).to be_between(2.days, 3.days)
|
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30)[2]).to be_between(3.days, 4.days)
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when there is only one processed dossier' do
|
|
|
|
let(:delays) { [1.day] }
|
2023-11-14 17:51:30 +01:00
|
|
|
it { expect(procedure.usual_traitement_time_for_recent_dossiers(30)).to be_nil }
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'where there is no processed dossier' do
|
|
|
|
let(:delays) { [] }
|
2021-06-17 10:30:27 +02:00
|
|
|
it { expect(procedure.usual_traitement_time_for_recent_dossiers(30)).to eq nil }
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
2023-11-14 17:51:30 +01:00
|
|
|
|
|
|
|
context 'with real data' do
|
|
|
|
include ActionView::Helpers::DateHelper
|
|
|
|
let(:delays) { [] }
|
|
|
|
before do
|
|
|
|
csv = CSV.read(Rails.root.join('spec/fixtures/files/data/treatment-expected-3months.csv'))
|
2023-11-21 12:33:39 +01:00
|
|
|
traitement_times = csv[1..] # strip header
|
2023-11-14 17:51:30 +01:00
|
|
|
.flatten
|
2023-11-21 12:33:39 +01:00
|
|
|
.map { { processed_at: _1.to_f, depose_at: 0 } }
|
2023-11-14 17:51:30 +01:00
|
|
|
allow(procedure).to receive(:traitement_times).and_return(traitement_times)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'works' do
|
2023-11-21 12:33:39 +01:00
|
|
|
expect(procedure.usual_traitement_time_for_recent_dossiers(30).map { distance_of_time_in_words(_1) }).to eq(["3 mois", "6 mois", "environ un an"])
|
2023-11-14 17:51:30 +01:00
|
|
|
end
|
|
|
|
end
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
|
|
|
|
2021-06-16 14:41:09 +02:00
|
|
|
describe '.usual_traitement_time_by_month_in_days' do
|
2021-06-15 11:33:17 +02:00
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
|
|
|
def create_dossiers(delays_by_month)
|
|
|
|
delays_by_month.each_with_index do |delays, index|
|
|
|
|
delays.each do |delay|
|
2023-11-14 17:51:30 +01:00
|
|
|
processed_at = (index.months + 1.week).ago
|
|
|
|
create_dossier(depose_at: processed_at - delay, en_instruction_at: processed_at - delay + 12.hours, processed_at: processed_at)
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
2021-06-16 14:41:09 +02:00
|
|
|
Timecop.freeze(Time.utc(2019, 6, 25, 12, 0))
|
2021-06-15 11:33:17 +02:00
|
|
|
|
|
|
|
create_dossiers(delays_by_month)
|
|
|
|
end
|
|
|
|
|
|
|
|
after { Timecop.return }
|
|
|
|
|
|
|
|
context 'when there are several processed dossiers' do
|
2021-06-16 15:13:36 +02:00
|
|
|
let(:delays_by_month) {
|
|
|
|
[
|
|
|
|
[90.days, 90.days],
|
|
|
|
[1.day, 2.days, 2.days, 2.days, 2.days, 3.days, 3.days, 3.days, 3.days, 12.days],
|
|
|
|
[30.days, 60.days, 60.days, 60.days]
|
|
|
|
]
|
|
|
|
}
|
2021-06-16 14:41:09 +02:00
|
|
|
|
|
|
|
it 'computes a time representative of the dossier instruction delay for each month except current month' do
|
|
|
|
expect(procedure.usual_traitement_time_by_month_in_days['avril 2019']).to eq 60
|
|
|
|
expect(procedure.usual_traitement_time_by_month_in_days['mai 2019']).to eq 4
|
|
|
|
expect(procedure.usual_traitement_time_by_month_in_days['juin 2019']).to eq nil
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2023-11-14 17:51:30 +01:00
|
|
|
def create_dossier(depose_at:, en_instruction_at:, processed_at:)
|
|
|
|
dossier = create(:dossier, :accepte, procedure: procedure, depose_at:, en_instruction_at:, processed_at:)
|
2021-06-15 11:33:17 +02:00
|
|
|
end
|
|
|
|
end
|