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:
Keirua 2020-07-21 17:39:39 +02:00 committed by GitHub
commit f583b16f92
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 101 additions and 4 deletions

View file

@ -24,11 +24,14 @@ class ActiveStorage::DownloadableFile
private
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)
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
def using_local_backend?

View file

@ -138,6 +138,55 @@ feature 'Instructing a dossier:' do
expect(page).to have_text("Dossier envoyé")
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)
visit '/'
click_on 'Connexion'

View file

@ -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'] }
)
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,
desired_capabilities: capabilities,
options: options
options: options).tap do |driver|
# Set download dir for Chrome < 77
driver.browser.download_path = download_path
end
end
# FIXME: remove this line when https://github.com/rspec/rspec-rails/issues/1897 has been fixed

View 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