From 0e54ca314df88a756f901788814aa53e73bee2e8 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 8 Mar 2024 15:46:11 +0100 Subject: [PATCH 1/2] bug(rebase): rebase a dossier when its repetition had been removed on newer version of published_revision crashes --- .../users/dossiers_controller_spec.rb | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index 88d0865ba..ca9dd6328 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -515,8 +515,9 @@ describe Users::DossiersController, type: :controller do describe '#submit_en_construction' do before { sign_in(user) } - - let!(:dossier) { create(:dossier, :en_construction, user: user) } + let(:procedure) { create(:procedure, :published, types_de_champ_public:) } + let(:types_de_champ_public) { [{ type: :text }] } + let(:dossier) { create(:dossier, :en_construction, procedure:, user:) } let(:first_champ) { dossier.owner_editing_fork.champs_public.first } let(:anchor_to_first_champ) { controller.helpers.link_to I18n.t('views.users.dossiers.fix_champ'), modifier_dossier_path(anchor: first_champ.labelledby_id), class: 'error-anchor' } let(:value) { 'beautiful value' } @@ -560,10 +561,8 @@ describe Users::DossiersController, type: :controller do context 'when a mandatory champ is missing' do let(:value) { nil } render_views - before do - first_champ.type_de_champ.update(mandatory: true, libelle: 'l') - subject - end + let(:types_de_champ_public) { [{ type: :text, mandatory: true, libelle: 'l' }] } + before { subject } it { expect(response).to render_template(:modifier) } it { expect(response.body).to have_content("doit ĂȘtre rempli") } @@ -580,6 +579,25 @@ describe Users::DossiersController, type: :controller do end end + context 'when dossier repetition had been removed in newer version' do + let(:dossier) { create(:dossier, :en_construction, :with_populated_champs, procedure:, user:) } + let(:types_de_champ_public) { [{ type: :repetition, libelle: 'repetition', children: [{ type: :text, libelle: 'child' }] }] } + let(:editing_fork) { dossier.owner_editing_fork } + let(:champ_repetition) { editing_fork.champs.find(&:repetition?) } + before do + editing_fork + + procedure.draft_revision.remove_type_de_champ(editing_fork.champs.find(&:repetition?).stable_id) + procedure.publish_revision! + + editing_fork.reload + editing_fork.rebase! + end + let(:submit_payload) { { id: dossier.id } } + + it { expect { subject }.not_to raise_error } + end + context 'when dossier was already submitted' do before { post :submit_en_construction, params: payload } From 4a26b61d1b0533fbfc964a210b7a8eb0ec9b9f10 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 8 Mar 2024 15:55:50 +0100 Subject: [PATCH 2/2] fix(rebase): rebase a dossier when its repetition had been removed on newer version does not crash --- app/models/concerns/dossier_rebase_concern.rb | 4 +++- app/models/procedure_revision_change.rb | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/concerns/dossier_rebase_concern.rb b/app/models/concerns/dossier_rebase_concern.rb index 322809b52..86ef8d06c 100644 --- a/app/models/concerns/dossier_rebase_concern.rb +++ b/app/models/concerns/dossier_rebase_concern.rb @@ -71,7 +71,9 @@ module DossierRebaseConcern .each { add_new_champs_for_revision(_1) } # remove champ - changes_by_op[:remove].each { champs_by_stable_id[_1.stable_id].destroy_all } + children_champ, root_champ = changes_by_op[:remove].partition(&:child?) + children_champ.each { champs_by_stable_id[_1.stable_id].delete_all } + root_champ.each { champs_by_stable_id[_1.stable_id].delete_all } # update champ changes_by_op[:update].each { apply(_1, champs_by_stable_id[_1.stable_id]) } diff --git a/app/models/procedure_revision_change.rb b/app/models/procedure_revision_change.rb index 2bb4a95f9..fc412cc26 100644 --- a/app/models/procedure_revision_change.rb +++ b/app/models/procedure_revision_change.rb @@ -7,6 +7,7 @@ class ProcedureRevisionChange def label = @type_de_champ.libelle def stable_id = @type_de_champ.stable_id def private? = @type_de_champ.private? + def child? = @type_de_champ.child? def to_h = { op:, stable_id:, label:, private: private? }