rend plus robuste la création de l'archive

This commit is contained in:
Christophe Robillard 2021-04-21 16:54:15 +02:00
parent 59a08ad307
commit 8bee53fe77
6 changed files with 62 additions and 24 deletions

View file

@ -16,8 +16,14 @@ module Instructeurs
type = params[:type]
month = Date.strptime(params[:month], '%Y-%m') if params[:month].present?
ArchiveCreationJob.perform_later(procedure, current_instructeur, type, month)
flash[:notice] = "Votre demande a été prise en compte. Selon le nombre de dossiers, cela peut prendre quelques minutes. Vous recevrez un courriel lorsque le fichier sera disponible."
archive = ProcedureArchiveService.new(procedure).create_pending_archive(current_instructeur, type, month)
if archive.pending?
ArchiveCreationJob.perform_later(procedure, archive, current_instructeur)
flash[:notice] = "Votre demande a été prise en compte. Selon le nombre de dossiers, cela peut prendre quelques minutes. Vous recevrez un courriel lorsque le fichier sera disponible."
else
flash[:notice] = "Cette archive a déjà été générée."
end
redirect_to instructeur_archives_path(procedure)
end
private

View file

@ -1,7 +1,7 @@
class ArchiveCreationJob < ApplicationJob
def perform(procedure, instructeur, type, month)
def perform(procedure, archive, instructeur)
ProcedureArchiveService
.new(procedure)
.create_archive(instructeur, type, month)
.collect_files_archive(archive, instructeur)
end
end

View file

@ -5,25 +5,35 @@ class ProcedureArchiveService
@procedure = procedure
end
def create_archive(instructeur, type, month = nil)
def create_pending_archive(instructeur, type, month=nil)
groupe_instructeurs = instructeur
.groupe_instructeurs
.where(procedure: @procedure)
if type == 'everything'
archive = Archive.for_groupe_instructeur(groupe_instructeurs).find_by(
content_type: type,
month: month
)
if archive.nil?
archive = Archive.create!(
content_type: type,
month: month,
groupe_instructeurs: groupe_instructeurs
)
end
archive
end
def collect_files_archive(archive, instructeur)
if archive.content_type == 'everything'
dossiers = @procedure.dossiers.state_termine
else
dossiers = @procedure.dossiers.processed_in_month(month)
dossiers = @procedure.dossiers.processed_in_month(archive.month)
end
files = create_list_of_attachments(dossiers)
archive = Archive.create!(
content_type: type,
month: month,
groupe_instructeurs: groupe_instructeurs
)
tmp_file = Tempfile.new(['tc', '.zip'])
Zip::OutputStream.open(tmp_file) do |zipfile|

View file

@ -52,7 +52,7 @@
%span.icon.retry
= t(:archive_pending_html, created_period: time_ago_in_words(matching_archive.created_at), scope: [:instructeurs, :procedure])
- elsif @dossiers_termines.count > 0
= link_to instructeur_archives_path(@procedure, type: 'everything'), method: :post, class: "button", remote: true do
= link_to instructeur_archives_path(@procedure, type: 'everything'), method: :post, class: "button" do
%span.icon.new-folder
Demander la création
- else

View file

@ -33,15 +33,16 @@ describe Instructeurs::ArchivesController, type: :controller do
describe '#create' do
let(:month) { '21-03' }
let(:date_month) { Date.strptime(month, "%Y-%m") }
let(:archive) { create(:archive) }
let(:subject) do
post :create, {
xhr: true,
params: { procedure_id: procedure1.id, type: 'monthly', month: month }
}
end
it "performs archive creation job" do
expect { subject }.to have_enqueued_job(ArchiveCreationJob).with(procedure1, instructeur, 'monthly', date_month)
allow_any_instance_of(ProcedureArchiveService).to receive(:create_pending_archive).and_return(archive)
expect { subject }.to have_enqueued_job(ArchiveCreationJob).with(procedure1, archive, instructeur)
expect(flash.notice).to include("Votre demande a été prise en compte")
end
end

View file

@ -1,12 +1,34 @@
describe ProcedureArchiveService do
describe '#create_archive' do
let(:procedure) { create(:procedure, :published) }
let(:instructeur) { create(:instructeur) }
let(:service) { ProcedureArchiveService.new(procedure) }
let(:year) { 2020 }
let(:month) { 3 }
let(:date_month) { Date.strptime("#{year}-#{month}", "%Y-%m") }
describe '#create_pending_archive' do
context 'for a specific month' do
it 'creates a pending archive' do
archive = service.create_pending_archive(instructeur, 'monthly', date_month)
expect(archive.content_type).to eq 'monthly'
expect(archive.month).to eq date_month
expect(archive.pending?).to be_truthy
end
end
context 'for all months' do
it 'creates a pending archive' do
archive = service.create_pending_archive(instructeur, 'everything')
expect(archive.content_type).to eq 'everything'
expect(archive.month).to eq nil
expect(archive.pending?).to be_truthy
end
end
end
describe '#collect_files_archive' do
before do
create_dossier_for_month(year, month)
create_dossier_for_month(2020, month)
@ -15,40 +37,39 @@ describe ProcedureArchiveService do
after { Timecop.return }
context 'for a specific month' do
let(:archive) { create(:archive, content_type: 'monthly', status: 'pending', month: date_month) }
let(:year) { 2021 }
let(:mailer) { double('mailer', deliver_later: true) }
it 'creates a monthly archive' do
it 'collect files' do
expect(InstructeurMailer).to receive(:send_archive).and_return(mailer)
service.create_archive(instructeur, 'monthly', date_month)
service.collect_files_archive(archive, instructeur)
archive = Archive.last
archive.file.open do |f|
files = ZipTricks::FileReader.read_zip_structure(io: f)
expect(files.size).to be 2
expect(files.first.filename).to include("export")
expect(files.last.filename).to include("attestation")
end
expect(archive.content_type).to eq 'monthly'
expect(archive.file.attached?).to be_truthy
end
end
context 'for all months' do
let(:archive) { create(:archive, content_type: 'everything', status: 'pending') }
let(:mailer) { double('mailer', deliver_later: true) }
it 'creates a everything archive' do
it 'collect files' do
expect(InstructeurMailer).to receive(:send_archive).and_return(mailer)
service.create_archive(instructeur, 'everything')
service.collect_files_archive(archive, instructeur)
archive = Archive.last
archive.file.open do |f|
files = ZipTricks::FileReader.read_zip_structure(io: f)
expect(files.size).to be 4
end
expect(archive.content_type).to eq 'everything'
expect(archive.file.attached?).to be_truthy
end
end