Merge pull request #5400 from betagouv/add-test-for-zip-download
Ajout d'un test pour le telechargement de zips de dossier
This commit is contained in:
commit
f583b16f92
4 changed files with 101 additions and 4 deletions
|
@ -24,11 +24,14 @@ class ActiveStorage::DownloadableFile
|
||||||
private
|
private
|
||||||
|
|
||||||
def self.timestamped_filename(piece_justificative)
|
def self.timestamped_filename(piece_justificative)
|
||||||
|
# we pad the original file name with a timestamp
|
||||||
|
# and a short id in order to help identify multiple versions and avoid name collisions
|
||||||
extension = File.extname(piece_justificative.filename.to_s)
|
extension = File.extname(piece_justificative.filename.to_s)
|
||||||
basename = File.basename(piece_justificative.filename.to_s, extension)
|
basename = File.basename(piece_justificative.filename.to_s, extension)
|
||||||
timestamp = piece_justificative.created_at.strftime("%d-%m-%Y-%H-%S")
|
timestamp = piece_justificative.created_at.strftime("%d-%m-%Y-%H-%M")
|
||||||
|
id = piece_justificative.id % 10000
|
||||||
|
|
||||||
"#{basename}-#{timestamp}#{extension}"
|
"#{basename}-#{timestamp}-#{id}#{extension}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def using_local_backend?
|
def using_local_backend?
|
||||||
|
|
|
@ -138,6 +138,55 @@ feature 'Instructing a dossier:' do
|
||||||
expect(page).to have_text("Dossier envoyé")
|
expect(page).to have_text("Dossier envoyé")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with dossiers having attached files', js: true do
|
||||||
|
let(:procedure) { create(:procedure, :published, :with_piece_justificative, instructeurs: [instructeur]) }
|
||||||
|
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||||
|
let(:champ) { dossier.champs.first }
|
||||||
|
let(:path) { 'spec/fixtures/files/piece_justificative_0.pdf' }
|
||||||
|
let(:commentaire) { create(:commentaire, instructeur: instructeur, dossier: dossier) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
champ.piece_justificative_file.attach(io: File.open(path), filename: "piece_justificative_0.pdf", content_type: "application/pdf")
|
||||||
|
|
||||||
|
log_in(instructeur.email, password)
|
||||||
|
visit instructeur_dossier_path(procedure, dossier)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'A instructeur can download an archive containing a single attachment' do
|
||||||
|
find(:css, '.attached').click
|
||||||
|
click_on 'Télécharger toutes les pièces jointes'
|
||||||
|
# For some reason, clicking the download link does not trigger the download in the headless browser ;
|
||||||
|
# So we need to go to the download link directly
|
||||||
|
visit telecharger_pjs_instructeur_dossier_path(procedure, dossier)
|
||||||
|
|
||||||
|
DownloadHelpers.wait_for_download
|
||||||
|
files = ZipTricks::FileReader.read_zip_structure(io: File.open(DownloadHelpers.download))
|
||||||
|
|
||||||
|
expect(DownloadHelpers.download).to include "dossier-#{dossier.id}.zip"
|
||||||
|
expect(files.size).to be 1
|
||||||
|
expect(files[0].filename.include?('piece_justificative_0')).to be_truthy
|
||||||
|
expect(files[0].uncompressed_size).to be File.size(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'A instructeur can download an archive containing several identical attachments' do
|
||||||
|
commentaire.piece_jointe.attach(io: File.open(path), filename: "piece_justificative_0.pdf", content_type: "application/pdf")
|
||||||
|
|
||||||
|
visit telecharger_pjs_instructeur_dossier_path(procedure, dossier)
|
||||||
|
DownloadHelpers.wait_for_download
|
||||||
|
files = ZipTricks::FileReader.read_zip_structure(io: File.open(DownloadHelpers.download))
|
||||||
|
|
||||||
|
expect(DownloadHelpers.download).to include "dossier-#{dossier.id}.zip"
|
||||||
|
expect(files.size).to be 2
|
||||||
|
expect(files[0].filename.include?('piece_justificative_0')).to be_truthy
|
||||||
|
expect(files[1].filename.include?('piece_justificative_0')).to be_truthy
|
||||||
|
expect(files[0].filename).not_to eq files[1].filename
|
||||||
|
expect(files[0].uncompressed_size).to be File.size(path)
|
||||||
|
expect(files[1].uncompressed_size).to be File.size(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
after { DownloadHelpers.clear_downloads }
|
||||||
|
end
|
||||||
|
|
||||||
def log_in(email, password, check_email: true)
|
def log_in(email, password, check_email: true)
|
||||||
visit '/'
|
visit '/'
|
||||||
click_on 'Connexion'
|
click_on 'Connexion'
|
||||||
|
|
|
@ -45,10 +45,19 @@ Capybara.register_driver :headless_chrome do |app|
|
||||||
chromeOptions: { args: ['disable-dev-shm-usage', 'disable-software-rasterizer', 'mute-audio', 'window-size=1440,900'] }
|
chromeOptions: { args: ['disable-dev-shm-usage', 'disable-software-rasterizer', 'mute-audio', 'window-size=1440,900'] }
|
||||||
)
|
)
|
||||||
|
|
||||||
Capybara::Selenium::Driver.new app,
|
download_path = Capybara.save_path
|
||||||
|
# Chromedriver 77 requires setting this for headless mode on linux
|
||||||
|
# Different versions of Chrome/selenium-webdriver require setting differently - just set them all
|
||||||
|
options.add_preference('download.default_directory', download_path)
|
||||||
|
options.add_preference(:download, default_directory: download_path)
|
||||||
|
|
||||||
|
Capybara::Selenium::Driver.new(app,
|
||||||
browser: :chrome,
|
browser: :chrome,
|
||||||
desired_capabilities: capabilities,
|
desired_capabilities: capabilities,
|
||||||
options: options
|
options: options).tap do |driver|
|
||||||
|
# Set download dir for Chrome < 77
|
||||||
|
driver.browser.download_path = download_path
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# FIXME: remove this line when https://github.com/rspec/rspec-rails/issues/1897 has been fixed
|
# FIXME: remove this line when https://github.com/rspec/rspec-rails/issues/1897 has been fixed
|
||||||
|
|
36
spec/support/download_helpers.rb
Normal file
36
spec/support/download_helpers.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
module DownloadHelpers
|
||||||
|
TIMEOUT = 2
|
||||||
|
|
||||||
|
extend self
|
||||||
|
|
||||||
|
def downloads
|
||||||
|
Dir[Capybara.save_path.join("*.zip")]
|
||||||
|
end
|
||||||
|
|
||||||
|
def download
|
||||||
|
downloads.first
|
||||||
|
end
|
||||||
|
|
||||||
|
def download_content
|
||||||
|
wait_for_download
|
||||||
|
File.read(download)
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait_for_download
|
||||||
|
Timeout.timeout(TIMEOUT) do
|
||||||
|
sleep 0.1 until downloaded?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def downloaded?
|
||||||
|
!downloading? && downloads.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
def downloading?
|
||||||
|
downloads.grep(/\.part$/).any?
|
||||||
|
end
|
||||||
|
|
||||||
|
def clear_downloads
|
||||||
|
FileUtils.rm_f(downloads)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue