From 99a9bc3829d0a63747db0eb0f4c884e2279d0dc3 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Wed, 4 Dec 2024 12:51:36 +0100 Subject: [PATCH] fix(dossier): when a champ type changes on update, ensure we have an instance of the right class --- app/models/concerns/dossier_champs_concern.rb | 9 ++++- .../concerns/dossier_champs_concern_spec.rb | 40 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/app/models/concerns/dossier_champs_concern.rb b/app/models/concerns/dossier_champs_concern.rb index 0f373bd74d6..6392393a1fb 100644 --- a/app/models/concerns/dossier_champs_concern.rb +++ b/app/models/concerns/dossier_champs_concern.rb @@ -177,9 +177,11 @@ def champ_with_attributes_for_update(type_de_champ, row_id, updated_by:) attributes[:value_json] = nil attributes[:external_id] = nil attributes[:data] = nil + champ = champ.becomes!(attributes[:type].constantize) + champ.save! end - reset_champs_cache + reset_champ_cache(champ) [champ, attributes] end @@ -202,6 +204,11 @@ def reset_champs_cache @project_champs_private = nil end + def reset_champ_cache(champ) + champs_by_public_id[champ.public_id]&.reload + reset_champs_cache + end + def reload_champs_cache champs.reload if persisted? reset_champs_cache diff --git a/spec/models/concerns/dossier_champs_concern_spec.rb b/spec/models/concerns/dossier_champs_concern_spec.rb index 351a7a1b7db..4fe86b3a78a 100644 --- a/spec/models/concerns/dossier_champs_concern_spec.rb +++ b/spec/models/concerns/dossier_champs_concern_spec.rb @@ -268,6 +268,25 @@ } end end + + context "champ with type change" do + let(:procedure) { create(:procedure, :published, types_de_champ_public: [{ type: :text, libelle: "Un champ text", stable_id: 99 }]) } + let(:dossier) { create(:dossier, :with_populated_champs, procedure:) } + + before do + tdc = dossier.procedure.draft_revision.find_and_ensure_exclusive_use(99) + tdc.update!(type_champ: TypeDeChamp.type_champs.fetch(:checkbox)) + dossier.procedure.publish_revision! + perform_enqueued_jobs + dossier.reload + end + + it { + expect(subject.persisted?).to be_truthy + expect(subject.is_a?(Champs::CheckboxChamp)).to be_truthy + expect(subject.value).to be_nil + } + end end context "private champ" do @@ -323,6 +342,27 @@ expect(champ_994.value).to eq("Greer") } end + + context "champ with type change" do + let(:procedure) { create(:procedure, :published, types_de_champ_public: [{ type: :text, libelle: "Un champ text", stable_id: 99 }]) } + let(:dossier) { create(:dossier, :with_populated_champs, procedure:) } + let(:attributes) { { "99" => { primary_value: "primary" } } } + + before do + tdc = dossier.procedure.draft_revision.find_and_ensure_exclusive_use(99) + tdc.update!(type_champ: TypeDeChamp.type_champs.fetch(:linked_drop_down_list), drop_down_options: ["--primary--", "secondary"]) + dossier.procedure.publish_revision! + perform_enqueued_jobs + dossier.reload + end + + it { + subject + expect(dossier.champs.any?(&:changed_for_autosave?)).to be_truthy + expect(champ_99.changed?).to be_truthy + expect(champ_99.value).to eq('["primary",""]') + } + end end describe "#update_champs_attributes(private)" do