From 3a33d8af45d9fe7d49902ea36731ecb0d1713bae Mon Sep 17 00:00:00 2001 From: mfo Date: Fri, 30 Aug 2024 17:24:11 +0200 Subject: [PATCH] fix(data): unlock broken dossier due to bad release --- ...ue_dossier_with_invalid_repetition_task.rb | 24 +++++++++++++++++ ...ssier_with_invalid_repetition_task_spec.rb | 27 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 app/tasks/maintenance/rescue_dossier_with_invalid_repetition_task.rb create mode 100644 spec/tasks/maintenance/rescue_dossier_with_invalid_repetition_task_spec.rb diff --git a/app/tasks/maintenance/rescue_dossier_with_invalid_repetition_task.rb b/app/tasks/maintenance/rescue_dossier_with_invalid_repetition_task.rb new file mode 100644 index 000000000..c65ac899a --- /dev/null +++ b/app/tasks/maintenance/rescue_dossier_with_invalid_repetition_task.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Maintenance + class RescueDossierWithInvalidRepetitionTask < MaintenanceTasks::Task + INVALID_RELEASE_DATETIME = DateTime.new(2024, 8, 30, 12) + def collection + Dossier.where("last_champ_updated_at > ?", INVALID_RELEASE_DATETIME).pluck(:id) # heure de l'incident + end + + def process(dossier_id) + Dossier.find(dossier_id) + .champs + .filter { _1.row_id.present? && _1.parent_id.blank? } + .each(&:destroy!) + rescue ActiveRecord::RecordNotFound + # some dossier had already been destroyed + end + + def count + # Optionally, define the number of rows that will be iterated over + # This is used to track the task's progress + end + end +end diff --git a/spec/tasks/maintenance/rescue_dossier_with_invalid_repetition_task_spec.rb b/spec/tasks/maintenance/rescue_dossier_with_invalid_repetition_task_spec.rb new file mode 100644 index 000000000..963adf048 --- /dev/null +++ b/spec/tasks/maintenance/rescue_dossier_with_invalid_repetition_task_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "rails_helper" + +module Maintenance + RSpec.describe RescueDossierWithInvalidRepetitionTask do + describe "#process" do + let(:procedure) { create(:procedure, types_de_champ_public:) } + let(:types_de_champ_public) do + [ + { type: :repetition, children: [{ type: :text, mandatory: true }] }, + { type: :checkbox } + ] + end + let(:dossier) { create(:dossier, :with_populated_champs, procedure:) } + let(:invalid_champ) { dossier.champs.find(&:checkbox?) } + + # reproduce bad data + before { invalid_champ.update!(row_id: dossier.champs[1].row_id) } + + it "dissociate champ having a row_id without a parent_id" do + expect { described_class.process(dossier) } + .to change { Champ.exists?(invalid_champ.id) }.from(true).to(false) + end + end + end +end