Skip to content

Commit

Permalink
Merge pull request #7909 from betagouv/fix_conditionnal_export
Browse files Browse the repository at this point in the history
fix(export): met une valeur null aux champs cachés lors des exports
  • Loading branch information
LeSim authored Oct 14, 2022
2 parents b0db7e7 + d5d031e commit e4ceaa1
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 51 deletions.
9 changes: 8 additions & 1 deletion app/models/dossier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,14 @@ def self.champs_for_export(champs, types_de_champ)
types_de_champ.flat_map do |type_de_champ|
champ_or_new = champs.find { |champ| champ.stable_id == type_de_champ.stable_id }
champ_or_new ||= type_de_champ.champ.build
Array.wrap(champ_or_new.for_export || [nil]).map.with_index do |champ_value, index|

champ_values = if champ_or_new.visible?
champ_or_new.for_export || [nil]
else
[nil]
end

Array.wrap(champ_values).map.with_index do |champ_value, index|
[type_de_champ.libelle_for_export(index), champ_value]
end
end
Expand Down
133 changes: 83 additions & 50 deletions spec/models/dossier_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1483,67 +1483,100 @@
end

describe "champs_for_export" do
let(:procedure) { create(:procedure, :with_type_de_champ, :with_datetime, :with_yes_no, :with_explication, :with_commune, :with_repetition, zones: [create(:zone)]) }
let(:text_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:text) } }
let(:yes_no_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:yes_no) } }
let(:datetime_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:datetime) } }
let(:explication_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:explication) } }
let(:commune_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:communes) } }
let(:repetition_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:repetition) } }
let(:repetition_champ) { dossier.champs.find(&:repetition?) }
let(:repetition_second_revision_champ) { dossier_second_revision.champs.find(&:repetition?) }
let(:dossier) { create(:dossier, procedure: procedure) }
let(:dossier_second_revision) { create(:dossier, procedure: procedure) }
let(:dossier_champs_for_export) { Dossier.champs_for_export(dossier.champs, procedure.types_de_champ_for_procedure_presentation.not_repetition) }
let(:dossier_second_revision_champs_for_export) { Dossier.champs_for_export(dossier_second_revision.champs, procedure.types_de_champ_for_procedure_presentation.not_repetition) }
let(:repetition_second_revision_champs_for_export) { Dossier.champs_for_export(repetition_second_revision_champ.champs, procedure.types_de_champ_for_procedure_presentation.repetition) }
context 'with a unconditionnal procedure' do
let(:procedure) { create(:procedure, :with_type_de_champ, :with_datetime, :with_yes_no, :with_explication, :with_commune, :with_repetition, zones: [create(:zone)]) }
let(:text_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:text) } }
let(:yes_no_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:yes_no) } }
let(:datetime_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:datetime) } }
let(:explication_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:explication) } }
let(:commune_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:communes) } }
let(:repetition_type_de_champ) { procedure.types_de_champ.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:repetition) } }
let(:repetition_champ) { dossier.champs.find(&:repetition?) }
let(:repetition_second_revision_champ) { dossier_second_revision.champs.find(&:repetition?) }
let(:dossier) { create(:dossier, procedure: procedure) }
let(:dossier_second_revision) { create(:dossier, procedure: procedure) }
let(:dossier_champs_for_export) { Dossier.champs_for_export(dossier.champs, procedure.types_de_champ_for_procedure_presentation.not_repetition) }
let(:dossier_second_revision_champs_for_export) { Dossier.champs_for_export(dossier_second_revision.champs, procedure.types_de_champ_for_procedure_presentation.not_repetition) }
let(:repetition_second_revision_champs_for_export) { Dossier.champs_for_export(repetition_second_revision_champ.champs, procedure.types_de_champ_for_procedure_presentation.repetition) }

context "when procedure published" do
before do
procedure.publish!
dossier
procedure.draft_revision.remove_type_de_champ(text_type_de_champ.stable_id)
procedure.draft_revision.add_type_de_champ(type_champ: TypeDeChamp.type_champs.fetch(:text), libelle: 'New text field')
procedure.draft_revision.find_and_ensure_exclusive_use(yes_no_type_de_champ.stable_id).update(libelle: 'Updated yes/no')
procedure.draft_revision.find_and_ensure_exclusive_use(commune_type_de_champ.stable_id).update(libelle: 'Commune de naissance')
procedure.draft_revision.find_and_ensure_exclusive_use(repetition_type_de_champ.stable_id).update(libelle: 'Repetition')
procedure.update(published_revision: procedure.draft_revision, draft_revision: procedure.create_new_revision)
dossier.reload
procedure.reload
end

context "when procedure published" do
before do
procedure.publish!
dossier
procedure.draft_revision.remove_type_de_champ(text_type_de_champ.stable_id)
procedure.draft_revision.add_type_de_champ(type_champ: TypeDeChamp.type_champs.fetch(:text), libelle: 'New text field')
procedure.draft_revision.find_and_ensure_exclusive_use(yes_no_type_de_champ.stable_id).update(libelle: 'Updated yes/no')
procedure.draft_revision.find_and_ensure_exclusive_use(commune_type_de_champ.stable_id).update(libelle: 'Commune de naissance')
procedure.draft_revision.find_and_ensure_exclusive_use(repetition_type_de_champ.stable_id).update(libelle: 'Repetition')
procedure.update(published_revision: procedure.draft_revision, draft_revision: procedure.create_new_revision)
dossier.reload
procedure.reload
end
it "should have champs from all revisions" do
expect(dossier.types_de_champ.map(&:libelle)).to eq([text_type_de_champ.libelle, datetime_type_de_champ.libelle, "Yes/no", explication_type_de_champ.libelle, commune_type_de_champ.libelle, repetition_type_de_champ.libelle])
expect(dossier_second_revision.types_de_champ.map(&:libelle)).to eq([datetime_type_de_champ.libelle, "Updated yes/no", explication_type_de_champ.libelle, 'Commune de naissance', "Repetition", "New text field"])
expect(dossier_champs_for_export.map { |(libelle)| libelle }).to eq([datetime_type_de_champ.libelle, text_type_de_champ.libelle, "Updated yes/no", "Commune de naissance", "Commune de naissance (Code insee)", "Commune de naissance (Département)", "New text field"])
expect(dossier_champs_for_export).to eq(dossier_second_revision_champs_for_export)
expect(repetition_second_revision_champs_for_export.map { |(libelle)| libelle }).to eq(procedure.types_de_champ_for_procedure_presentation.repetition.map(&:libelle_for_export))
expect(repetition_second_revision_champs_for_export.first.size).to eq(2)
end

it "should have champs from all revisions" do
expect(dossier.types_de_champ.map(&:libelle)).to eq([text_type_de_champ.libelle, datetime_type_de_champ.libelle, "Yes/no", explication_type_de_champ.libelle, commune_type_de_champ.libelle, repetition_type_de_champ.libelle])
expect(dossier_second_revision.types_de_champ.map(&:libelle)).to eq([datetime_type_de_champ.libelle, "Updated yes/no", explication_type_de_champ.libelle, 'Commune de naissance', "Repetition", "New text field"])
expect(dossier_champs_for_export.map { |(libelle)| libelle }).to eq([datetime_type_de_champ.libelle, text_type_de_champ.libelle, "Updated yes/no", "Commune de naissance", "Commune de naissance (Code insee)", "Commune de naissance (Département)", "New text field"])
expect(dossier_champs_for_export).to eq(dossier_second_revision_champs_for_export)
expect(repetition_second_revision_champs_for_export.map { |(libelle)| libelle }).to eq(procedure.types_de_champ_for_procedure_presentation.repetition.map(&:libelle_for_export))
expect(repetition_second_revision_champs_for_export.first.size).to eq(2)
end
context 'within a repetition having a type de champs commune (multiple values for export)' do
it 'works' do
proc_test = create(:procedure)

context 'within a repetition having a type de champs commune (multiple values for export)' do
it 'works' do
proc_test = create(:procedure)
draft = proc_test.draft_revision

draft = proc_test.draft_revision
tdc_repetition = draft.add_type_de_champ(type_champ: :repetition, libelle: "repetition")
draft.add_type_de_champ(type_champ: :communes, libelle: "communes", parent_stable_id: tdc_repetition.stable_id)

dossier_test = create(:dossier, procedure: proc_test)
repetition = proc_test.types_de_champ_for_procedure_presentation.repetition.first
type_champs = proc_test.types_de_champ_for_procedure_presentation(repetition).to_a
expect(type_champs.size).to eq(1)
expect(Dossier.champs_for_export(dossier.champs, type_champs).size).to eq(3)
end
end
end

tdc_repetition = draft.add_type_de_champ(type_champ: :repetition, libelle: "repetition")
draft.add_type_de_champ(type_champ: :communes, libelle: "communes", parent_stable_id: tdc_repetition.stable_id)
context "when procedure brouillon" do
let(:procedure) { create(:procedure, :with_type_de_champ, :with_explication) }

dossier_test = create(:dossier, procedure: proc_test)
repetition = proc_test.types_de_champ_for_procedure_presentation.repetition.first
type_champs = proc_test.types_de_champ_for_procedure_presentation(repetition).to_a
expect(type_champs.size).to eq(1)
expect(Dossier.champs_for_export(dossier.champs, type_champs).size).to eq(3)
it "should not contain non-exportable types de champ" do
expect(dossier_champs_for_export.map { |(libelle)| libelle }).to eq([text_type_de_champ.libelle])
end
end
end

context "when procedure brouillon" do
let(:procedure) { create(:procedure, :with_type_de_champ, :with_explication) }
context 'with a procedure with a condition' do
include Logic
let(:types_de_champ) { [{ type: :yes_no }, { type: :text }] }
let(:procedure) { create(:procedure, types_de_champ_public: types_de_champ) }
let(:dossier) { create(:dossier, procedure:) }
let(:yes_no_tdc) { procedure.types_de_champ.first }
let(:text_tdc) { procedure.types_de_champ.second }

subject { Dossier.champs_for_export(dossier.champs, dossier.champs.map(&:type_de_champ)) }

before do
text_tdc.update(condition: ds_eq(champ_value(yes_no_tdc.stable_id), constant(true)))

yes_no, text = dossier.champs
yes_no.update(value: yes_no_value)
text.update(value: 'text')
end

context 'with a champ visible' do
let(:yes_no_value) { 'true' }

it { is_expected.to eq([[yes_no_tdc.libelle, "Oui"], [text_tdc.libelle, "text"]]) }
end

context 'with a champ invisible' do
let(:yes_no_value) { 'false' }

it "should not contain non-exportable types de champ" do
expect(dossier_champs_for_export.map { |(libelle)| libelle }).to eq([text_type_de_champ.libelle])
it { is_expected.to eq([[yes_no_tdc.libelle, "Non"], [text_tdc.libelle, nil]]) }
end
end
end
Expand Down

0 comments on commit e4ceaa1

Please sign in to comment.