From 29ef5b313ce14445900647959845e5e604d87e36 Mon Sep 17 00:00:00 2001 From: mfo Date: Tue, 21 May 2024 14:21:21 +0200 Subject: [PATCH] fix(data): clean Champs::PieceJustificativeChamp for annotations that had been cloned --- app/models/champ.rb | 1 + ...hamps_private_piece_justificatives_task.rb | 34 ++++++++++++ ..._private_piece_justificatives_task_spec.rb | 54 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 app/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task.rb create mode 100644 spec/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task_spec.rb diff --git a/app/models/champ.rb b/app/models/champ.rb index 92fbca7d0..2cb0bb4ec 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -39,6 +39,7 @@ class Champ < ApplicationRecord :departement?, :region?, :textarea?, + :piece_justificative?, :titre_identite?, :header_section?, :checkbox?, diff --git a/app/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task.rb b/app/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task.rb new file mode 100644 index 000000000..ad32ece93 --- /dev/null +++ b/app/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Maintenance + class BackfillClonedChampsPrivatePieceJustificativesTask < MaintenanceTasks::Task + def collection + Dossier.en_brouillon.where.not(parent_dossier_id: nil) + end + + def process(cloned_dossier) + cloned_dossier.champs_private + .filter { checkable_pj?(_1, cloned_dossier) } + .map do |cloned_champ| + parent_champ = cloned_dossier.parent_dossier + .champs_private + .find { _1.stable_id == cloned_champ.stable_id } + + next if !parent_champ + + parent_blob_ids = parent_champ.piece_justificative_file.map(&:blob_id) + cloned_blob_ids = cloned_champ.piece_justificative_file.map(&:blob_id) + + if parent_blob_ids.sort == cloned_blob_ids.sort + cloned_champ.piece_justificative_file.detach + end + end + end + + def checkable_pj?(champ, dossier) + return false if champ.type != "Champs::PieceJustificativeChamp" + return false if !champ.piece_justificative_file.attached? + true + end + end +end diff --git a/spec/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task_spec.rb b/spec/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task_spec.rb new file mode 100644 index 000000000..2029c1991 --- /dev/null +++ b/spec/tasks/maintenance/backfill_cloned_champs_private_piece_justificatives_task_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require "rails_helper" + +module Maintenance + RSpec.describe BackfillClonedChampsPrivatePieceJustificativesTask do + describe "#process" do + let(:procedure) { create(:procedure, types_de_champ_private:) } + let(:types_de_champ_private) { [{ type: :piece_justificative }, { type: :text }] } + + let(:parent_dossier) { create(:dossier, procedure:) } + let(:cloned_dossier) { create(:dossier, procedure:) } + + let(:parent_champ_pj) { parent_dossier.champs_private.find(&:piece_justificative?) } + let(:cloned_champ_pj) { cloned_dossier.champs_private.find(&:piece_justificative?) } + + before do + cloned_dossier.update(parent_dossier:) # used on factorie, does not seed private_champs.. + parent_champ_pj.piece_justificative_file.attach( + io: StringIO.new("x" * 2), + filename: "me.jpg", + content_type: "image/png", + metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE } + ) + end + + subject { described_class.process(cloned_dossier) } + + context 'when dossier and parent have the same pjs' do + it 'detaches sames blob between parent_dossier and dossier' do + cloned_champ_pj.piece_justificative_file.attach(parent_champ_pj.piece_justificative_file.first.blob) + + subject + expect(cloned_champ_pj.reload.piece_justificative_file.attached?).to be_falsey + end + end + + context 'when dossier and parent have different pjs' do + it 'keeps different blobs between parent_dossier and dossier' do + cloned_champ_pj.piece_justificative_file.attach( + io: StringIO.new("x" * 2), + filename: "me.jpg", + content_type: "image/png", + metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE } + ) + + described_class.process(cloned_dossier) + subject + expect(cloned_champ_pj.reload.piece_justificative_file.attached?).to be_truthy + end + end + end + end +end