Merge pull request #7183 from betagouv/fix-in-batch-for-zip-exports

fix(export.to_zip): crashes because we are trying to call ActiveRecord.in_batches with on an instance of Array
This commit is contained in:
mfo 2022-04-22 05:21:09 +02:00 committed by GitHub
commit 38e152f755
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 4 deletions

View file

@ -3,16 +3,18 @@ class ProcedureExportService
def initialize(procedure, dossiers) def initialize(procedure, dossiers)
@procedure = procedure @procedure = procedure
@dossiers = dossiers.downloadable_sorted_batch @dossiers = dossiers
@tables = [:dossiers, :etablissements, :avis] + champs_repetables_options @tables = [:dossiers, :etablissements, :avis] + champs_repetables_options
end end
def to_csv def to_csv
@dossiers = @dossiers.downloadable_sorted_batch
io = StringIO.new(SpreadsheetArchitect.to_csv(options_for(:dossiers, :csv))) io = StringIO.new(SpreadsheetArchitect.to_csv(options_for(:dossiers, :csv)))
create_blob(io, :csv) create_blob(io, :csv)
end end
def to_xlsx def to_xlsx
@dossiers = @dossiers.downloadable_sorted_batch
# We recursively build multi page spreadsheet # We recursively build multi page spreadsheet
io = @tables.reduce(nil) do |package, table| io = @tables.reduce(nil) do |package, table|
SpreadsheetArchitect.to_axlsx_package(options_for(table, :xlsx), package) SpreadsheetArchitect.to_axlsx_package(options_for(table, :xlsx), package)
@ -21,6 +23,7 @@ class ProcedureExportService
end end
def to_ods def to_ods
@dossiers = @dossiers.downloadable_sorted_batch
# We recursively build multi page spreadsheet # We recursively build multi page spreadsheet
io = StringIO.new(@tables.reduce(nil) do |spreadsheet, table| io = StringIO.new(@tables.reduce(nil) do |spreadsheet, table|
SpreadsheetArchitect.to_rodf_spreadsheet(options_for(table, :ods), spreadsheet) SpreadsheetArchitect.to_rodf_spreadsheet(options_for(table, :ods), spreadsheet)

View file

@ -1,10 +1,12 @@
require 'csv' require 'csv'
describe ProcedureExportService do describe ProcedureExportService do
describe 'to_data' do
let(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs) } let(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs) }
let(:service) { ProcedureExportService.new(procedure, procedure.dossiers) }
describe 'to_xlsx' do
subject do subject do
ProcedureExportService.new(procedure, procedure.dossiers) service
.to_xlsx .to_xlsx
.open { |f| SimpleXlsxReader.open(f.path) } .open { |f| SimpleXlsxReader.open(f.path) }
end end
@ -406,4 +408,46 @@ describe ProcedureExportService do
end end
end end
end end
describe 'to_zip' do
subject { service.to_zip }
context 'without files' do
it 'does not raises in_batches' do
expect { subject }.not_to raise_error(NoMethodError)
end
it 'returns an empty blob' do
expect(subject).to be_an_instance_of(ActiveStorage::Blob)
end
end
context 'with files (and http calls)' do
let!(:dossier) { create(:dossier, :accepte, :with_populated_champs, :with_individual, procedure: procedure) }
before do
allow_any_instance_of(ActiveStorage::Attachment).to receive(:url).and_return("https://opengraph.githubassets.com/d0e7862b24d8026a3c03516d865b28151eb3859029c6c6c2e86605891fbdcd7a/socketry/async-io")
end
it 'returns a blob with valid files' do
VCR.use_cassette('archive/new_file_to_get_200') do
subject
File.write('tmp.zip', subject.download, mode: 'wb')
File.open('tmp.zip') do |fd|
files = ZipTricks::FileReader.read_zip_structure(io: fd)
structure = [
"#{service.send(:base_filename)}/",
"#{service.send(:base_filename)}/dossier-#{dossier.id}/",
"#{service.send(:base_filename)}/dossier-#{dossier.id}/pieces_justificatives/",
"#{service.send(:base_filename)}/dossier-#{dossier.id}/#{ActiveStorage::DownloadableFile.timestamped_filename(ActiveStorage::Attachment.where(record_type: "Champ").first)}",
"#{service.send(:base_filename)}/dossier-#{dossier.id}/#{ActiveStorage::DownloadableFile.timestamped_filename(PiecesJustificativesService.generate_dossier_export(dossier))}"
]
expect(files.size).to eq(structure.size)
expect(files.map(&:filename)).to match_array(structure)
end
FileUtils.remove_entry_secure('tmp.zip')
end
end
end
end
end end