demarches-normaliennes/spec/services/procedure_export_service_spec.rb

405 lines
13 KiB
Ruby
Raw Normal View History

2019-06-25 15:46:10 +02:00
require 'csv'
describe ProcedureExportService do
describe 'to_data' do
2019-06-25 15:46:10 +02:00
let(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs) }
subject do
Tempfile.create do |f|
f << ProcedureExportService.new(procedure, procedure.dossiers).to_xlsx
f.rewind
SimpleXlsxReader.open(f.path)
end
end
2019-06-25 15:46:10 +02:00
let(:dossiers_sheet) { subject.sheets.first }
let(:etablissements_sheet) { subject.sheets.second }
let(:avis_sheet) { subject.sheets.third }
let(:repetition_sheet) { subject.sheets.fourth }
2018-12-10 15:33:34 +01:00
before do
# change one tdc place to check if the header is ordered
2020-08-27 19:57:21 +02:00
tdc_first = procedure.active_revision.revision_types_de_champ.first
tdc_last = procedure.active_revision.revision_types_de_champ.last
2018-12-10 15:33:34 +01:00
2020-08-27 19:57:21 +02:00
tdc_first.update(position: tdc_last.position + 1)
2018-12-20 12:00:27 +01:00
procedure.reload
2018-12-10 15:33:34 +01:00
end
describe 'sheets' do
it 'should have a sheet for each record type' do
2019-06-25 15:46:10 +02:00
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis'])
end
end
describe 'Dossiers sheet' do
let!(:dossier) { create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure: procedure) }
2019-06-25 15:46:10 +02:00
let(:nominal_headers) do
[
2019-06-25 15:46:10 +02:00
"ID",
"Email",
"Civilité",
"Nom",
"Prénom",
"Archivé",
"État du dossier",
"Dernière mise à jour le",
"Déposé le",
"Passé en instruction le",
"Traité le",
"Motivation de la décision",
"Instructeurs",
"textarea",
"date",
"datetime",
"number",
"decimal_number",
"integer_number",
"checkbox",
"civilite",
"email",
"phone",
"address",
"yes_no",
"simple_drop_down_list",
"multiple_drop_down_list",
"linked_drop_down_list",
"pays",
"regions",
"departements",
"communes",
"communes (Code insee)",
2019-06-25 15:46:10 +02:00
"engagement",
"dossier_link",
"piece_justificative",
"siret",
"carte",
2020-09-17 17:09:16 +02:00
"titre_identite",
2020-09-22 16:04:57 +02:00
"iban",
2021-01-14 17:29:57 +01:00
"annuaire_education",
2021-09-24 14:21:13 +02:00
"cnaf",
2019-06-25 15:46:10 +02:00
"text"
]
end
it 'should have headers' do
2019-06-25 15:46:10 +02:00
expect(dossiers_sheet.headers).to match(nominal_headers)
end
it 'should have data' do
expect(dossiers_sheet.data.size).to eq(1)
expect(etablissements_sheet.data.size).to eq(1)
# SimpleXlsxReader is transforming datetimes in utc... It is only used in test so we just hack around.
offset = dossier.en_construction_at.utc_offset
en_construction_at = Time.zone.at(dossiers_sheet.data[0][8] - offset.seconds)
en_instruction_at = Time.zone.at(dossiers_sheet.data[0][9] - offset.seconds)
2019-06-25 15:46:10 +02:00
expect(en_construction_at).to eq(dossier.en_construction_at.round)
expect(en_instruction_at).to eq(dossier.en_instruction_at.round)
end
context 'with a birthdate' do
before { procedure.update(ask_birthday: true) }
let(:birthdate_headers) { nominal_headers.insert(nominal_headers.index('Archivé'), 'Date de naissance') }
it { expect(dossiers_sheet.headers).to match(birthdate_headers) }
it { expect(dossiers_sheet.data[0][dossiers_sheet.headers.index('Date de naissance')]).to be_a(Date) }
end
context 'with a procedure routee' do
before { procedure.groupe_instructeurs.create(label: '2') }
let(:routee_headers) { nominal_headers.insert(nominal_headers.index('textarea'), 'Groupe instructeur') }
it { expect(dossiers_sheet.headers).to match(routee_headers) }
2019-06-25 15:46:10 +02:00
it { expect(dossiers_sheet.data[0][dossiers_sheet.headers.index('Groupe instructeur')]).to eq('défaut') }
end
2019-06-25 15:46:10 +02:00
end
describe 'Etablissement sheet' do
2019-06-25 15:46:10 +02:00
let(:procedure) { create(:procedure, :published, :with_all_champs) }
let!(:dossier) { create(:dossier, :en_instruction, :with_populated_champs, :with_entreprise, procedure: procedure) }
2019-06-25 15:46:10 +02:00
let(:dossier_etablissement) { etablissements_sheet.data[1] }
let(:champ_etablissement) { etablissements_sheet.data[0] }
let(:nominal_headers) do
[
"ID",
"Email",
"Entreprise raison sociale",
"Archivé",
"État du dossier",
"Dernière mise à jour le",
"Déposé le",
"Passé en instruction le",
"Traité le",
"Motivation de la décision",
"Instructeurs",
"textarea",
"date",
"datetime",
"number",
"decimal_number",
"integer_number",
"checkbox",
"civilite",
"email",
"phone",
"address",
"yes_no",
"simple_drop_down_list",
"multiple_drop_down_list",
"linked_drop_down_list",
"pays",
"regions",
"departements",
"communes",
"communes (Code insee)",
2019-06-25 15:46:10 +02:00
"engagement",
"dossier_link",
"piece_justificative",
"siret",
"carte",
2020-09-17 17:09:16 +02:00
"titre_identite",
2020-09-22 16:04:57 +02:00
"iban",
2021-01-14 17:29:57 +01:00
"annuaire_education",
2021-09-24 14:21:13 +02:00
"cnaf",
2019-06-25 15:46:10 +02:00
"text"
]
end
2019-06-25 15:46:10 +02:00
context 'as csv' do
subject do
Tempfile.create do |f|
f << ProcedureExportService.new(procedure, procedure.dossiers).to_csv
f.rewind
CSV.read(f.path)
end
end
2019-06-25 15:46:10 +02:00
let(:nominal_headers) do
[
2019-06-25 15:46:10 +02:00
"ID",
"Email",
"Établissement SIRET",
"Établissement siège social",
"Établissement NAF",
"Établissement libellé NAF",
"Établissement Adresse",
"Établissement numero voie",
"Établissement type voie",
"Établissement nom voie",
"Établissement complément adresse",
"Établissement code postal",
"Établissement localité",
"Établissement code INSEE localité",
"Entreprise SIREN",
"Entreprise capital social",
"Entreprise numero TVA intracommunautaire",
"Entreprise forme juridique",
"Entreprise forme juridique code",
"Entreprise nom commercial",
"Entreprise raison sociale",
"Entreprise SIRET siège social",
"Entreprise code effectif entreprise",
"Entreprise date de création",
"Entreprise nom",
"Entreprise prénom",
"Association RNA",
"Association titre",
"Association objet",
"Association date de création",
"Association date de déclaration",
"Association date de publication",
"Archivé",
"État du dossier",
"Dernière mise à jour le",
"Déposé le",
"Passé en instruction le",
"Traité le",
"Motivation de la décision",
"Instructeurs",
"textarea",
"date",
"datetime",
"number",
"decimal_number",
"integer_number",
"checkbox",
"civilite",
"email",
"phone",
"address",
"yes_no",
"simple_drop_down_list",
"multiple_drop_down_list",
"linked_drop_down_list",
"pays",
"regions",
"departements",
"communes",
"communes (Code insee)",
2019-06-25 15:46:10 +02:00
"engagement",
"dossier_link",
"piece_justificative",
"siret",
"carte",
2020-09-17 17:09:16 +02:00
"titre_identite",
2020-09-22 16:04:57 +02:00
"iban",
2021-01-14 17:29:57 +01:00
"annuaire_education",
2021-09-24 14:21:13 +02:00
"cnaf",
2019-06-25 15:46:10 +02:00
"text"
]
2019-06-25 15:46:10 +02:00
end
2019-06-25 15:46:10 +02:00
let(:dossiers_sheet_headers) { subject.first }
2019-06-25 15:46:10 +02:00
it 'should have headers' do
expect(dossiers_sheet_headers).to match(nominal_headers)
end
end
2019-06-25 15:46:10 +02:00
it 'should have headers' do
expect(dossiers_sheet.headers).to match(nominal_headers)
expect(etablissements_sheet.headers).to eq([
"Dossier ID",
"Champ",
"Établissement SIRET",
"Etablissement enseigne",
2019-06-25 15:46:10 +02:00
"Établissement siège social",
"Établissement NAF",
"Établissement libellé NAF",
"Établissement Adresse",
"Établissement numero voie",
"Établissement type voie",
"Établissement nom voie",
"Établissement complément adresse",
"Établissement code postal",
"Établissement localité",
"Établissement code INSEE localité",
"Entreprise SIREN",
"Entreprise capital social",
"Entreprise numero TVA intracommunautaire",
"Entreprise forme juridique",
"Entreprise forme juridique code",
"Entreprise nom commercial",
"Entreprise raison sociale",
"Entreprise SIRET siège social",
"Entreprise code effectif entreprise",
"Entreprise date de création",
"Entreprise nom",
"Entreprise prénom",
"Association RNA",
"Association titre",
"Association objet",
"Association date de création",
"Association date de déclaration",
"Association date de publication"
])
end
2019-06-25 15:46:10 +02:00
it 'should have data' do
expect(etablissements_sheet.data.size).to eq(2)
expect(dossier_etablissement[1]).to eq("Dossier")
expect(champ_etablissement[1]).to eq("siret")
end
end
describe 'Avis sheet' do
let!(:dossier) { create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure: procedure) }
2019-06-25 15:46:10 +02:00
let!(:avis) { create(:avis, :with_answer, dossier: dossier) }
2019-06-25 15:46:10 +02:00
it 'should have headers' do
expect(avis_sheet.headers).to eq([
"Dossier ID",
"Question / Introduction",
"Réponse",
"Créé le",
"Répondu le",
"Instructeur",
"Expert"
2019-06-25 15:46:10 +02:00
])
end
2019-06-25 15:46:10 +02:00
it 'should have data' do
expect(avis_sheet.data.size).to eq(1)
end
end
describe 'Repetitions sheet' do
2019-06-25 15:46:10 +02:00
let!(:dossiers) do
[
create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure: procedure),
create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure: procedure)
2019-06-25 15:46:10 +02:00
]
end
let(:champ_repetition) { dossiers.first.champs.find { |champ| champ.type_champ == 'repetition' } }
it 'should have sheets' do
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', champ_repetition.libelle_for_export])
end
context 'with cloned procedure' do
let(:other_parent) { create(:type_de_champ_repetition, stable_id: champ_repetition.stable_id) }
before do
create(:procedure_revision_type_de_champ, type_de_champ: other_parent, revision: create(:procedure).active_revision)
create(:type_de_champ, parent: other_parent)
end
it 'should have headers' do
expect(repetition_sheet.headers).to eq([
"Dossier ID",
"Ligne",
"Nom",
"Age"
])
end
end
2019-06-25 15:46:10 +02:00
it 'should have data' do
expect(repetition_sheet.data.size).to eq(4)
end
2019-06-25 15:46:10 +02:00
context 'with invalid characters' do
before do
champ_repetition.type_de_champ.update(libelle: 'A / B \ C *[]?')
2019-06-25 15:46:10 +02:00
end
it 'should have valid sheet name' do
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', "(#{champ_repetition.type_de_champ.stable_id}) A - B - C"])
end
end
context 'with long libelle composed of utf8 characteres' do
before do
procedure.types_de_champ.each do |c|
c.update!(libelle: "#{c.id} - ?/[] ééé ééé ééééééé ééééééé éééééééé. ééé éé éééééééé éé ééé. ééééé éééééééé ééé ééé.")
end
champ_repetition.champs.each do |c|
c.type_de_champ.update!(libelle: "#{c.id} - Quam rem nam maiores numquam dolorem nesciunt. Cum et possimus et aut. Fugit voluptas qui qui.")
end
end
it 'should have valid sheet name' do
expect { subject }.not_to raise_error
end
end
2019-06-25 15:46:10 +02:00
context 'with non unique labels' do
let(:dossier) { create(:dossier, :en_instruction, :with_populated_champs, :with_individual, procedure: procedure) }
2019-06-25 15:46:10 +02:00
let(:champ_repetition) { dossier.champs.find { |champ| champ.type_champ == 'repetition' } }
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, procedure: procedure, libelle: champ_repetition.libelle) }
let!(:another_champ_repetition) { create(:champ_repetition, type_de_champ: type_de_champ_repetition, dossier: dossier) }
2019-06-25 15:46:10 +02:00
it 'should have sheets' do
expect(subject.sheets.map(&:name)).to eq(['Dossiers', 'Etablissements', 'Avis', champ_repetition.libelle_for_export, another_champ_repetition.libelle_for_export])
end
end
end
end
end