From 10a1ae553430e4041a3ef2a38c66ed6b0a178b22 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Thu, 19 Sep 2024 11:09:01 +0200 Subject: [PATCH] Revert "Merge pull request #10771 from tchak/refactor-champs-revert" This reverts commit c902061ebfdb4181641ea5ba9e31d55b622000c2, reversing changes made to b4ed11c78831ccbfad32495b190dee509ee12c84. --- app/controllers/api/v1/dossiers_controller.rb | 1 - app/controllers/champs/champ_controller.rb | 6 +- app/models/attestation_template.rb | 8 +- app/models/champ.rb | 4 +- app/models/champs/repetition_champ.rb | 2 +- .../concerns/champs_validate_concern.rb | 8 +- app/models/concerns/dossier_champs_concern.rb | 17 +--- .../concerns/dossier_sections_concern.rb | 2 +- app/models/dossier.rb | 40 +++++++--- app/models/dossier_preloader.rb | 74 ++++++++++++------ app/models/procedure.rb | 14 ++++ app/models/procedure_revision.rb | 5 ++ .../procedure_revision_type_de_champ.rb | 4 +- app/models/type_de_champ.rb | 4 - .../_instruction_button_motivation.html.haml | 2 +- .../champs/repetition_controller_spec.rb | 2 +- spec/models/champ_spec.rb | 77 +++++++++---------- spec/models/champs/cnaf_champ_spec.rb | 5 +- .../champs/decimal_number_champ_spec.rb | 1 - spec/models/champs/departement_champ_spec.rb | 5 +- spec/models/champs/dgfip_champ_spec.rb | 5 +- spec/models/champs/dossier_link_champ_spec.rb | 1 - .../champs/drop_down_list_champ_spec.rb | 5 +- spec/models/champs/email_champ_spec.rb | 12 +-- spec/models/champs/epci_champ_spec.rb | 5 +- spec/models/champs/iban_champ_spec.rb | 5 +- .../champs/integer_number_champ_spec.rb | 5 +- .../multiple_drop_down_list_champ_spec.rb | 5 +- spec/models/champs/phone_champ_spec.rb | 5 +- spec/models/champs/rna_champ_spec.rb | 5 +- .../concerns/dossier_champs_concern_spec.rb | 27 ++----- .../dossier_searchable_concern_spec.rb | 6 +- .../concerns/dossier_sections_concern_spec.rb | 12 +-- .../engagement_juridique_champ_spec.rb | 5 +- .../services/procedure_export_service_spec.rb | 10 +-- 35 files changed, 189 insertions(+), 205 deletions(-) rename spec/models/{champs => }/engagement_juridique_champ_spec.rb (83%) diff --git a/app/controllers/api/v1/dossiers_controller.rb b/app/controllers/api/v1/dossiers_controller.rb index 09c7d8fe4..bf2470517 100644 --- a/app/controllers/api/v1/dossiers_controller.rb +++ b/app/controllers/api/v1/dossiers_controller.rb @@ -18,7 +18,6 @@ class API::V1::DossiersController < APIController def show dossier = @dossiers.for_api.find(params[:id]) - DossierPreloader.load_one(dossier) render json: { dossier: DossierSerializer.new(dossier).as_json } rescue ActiveRecord::RecordNotFound diff --git a/app/controllers/champs/champ_controller.rb b/app/controllers/champs/champ_controller.rb index 5af93d346..8d82161bb 100644 --- a/app/controllers/champs/champ_controller.rb +++ b/app/controllers/champs/champ_controller.rb @@ -9,11 +9,7 @@ class Champs::ChampController < ApplicationController def find_champ dossier = policy_scope(Dossier).includes(:champs, revision: [:types_de_champ]).find(params[:dossier_id]) type_de_champ = dossier.find_type_de_champ_by_stable_id(params[:stable_id]) - if type_de_champ.repetition? - dossier.project_champ(type_de_champ, nil) - else - dossier.champ_for_update(type_de_champ, params_row_id, updated_by: current_user.email) - end + dossier.champ_for_update(type_de_champ, params_row_id, updated_by: current_user.email) end def params_row_id diff --git a/app/models/attestation_template.rb b/app/models/attestation_template.rb index 8aba5d352..fe4ca085f 100644 --- a/app/models/attestation_template.rb +++ b/app/models/attestation_template.rb @@ -87,13 +87,13 @@ class AttestationTemplate < ApplicationRecord end def unspecified_champs_for_dossier(dossier) - types_de_champ_by_tag_id = dossier.revision.types_de_champ.index_by { "tdc#{_1.stable_id}" } + champs_by_stable_id = dossier.champs_for_revision(root: true).index_by { "tdc#{_1.stable_id}" } used_tags.filter_map do |used_tag| - corresponding_type_de_champ = types_de_champ_by_tag_id[used_tag] + corresponding_champ = champs_by_stable_id[used_tag] - if corresponding_type_de_champ && dossier.project_champ(corresponding_type_de_champ, nil).blank? - corresponding_type_de_champ + if corresponding_champ && corresponding_champ.blank? + corresponding_champ end end end diff --git a/app/models/champ.rb b/app/models/champ.rb index 20dcc3133..ebf6186d9 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -6,8 +6,6 @@ class Champ < ApplicationRecord self.ignored_columns += [:type_de_champ_id] - attr_readonly :stable_id - belongs_to :dossier, inverse_of: false, touch: true, optional: false belongs_to :parent, class_name: 'Champ', optional: true has_many_attached :piece_justificative_file @@ -95,7 +93,7 @@ class Champ < ApplicationRecord end def child? - row_id.present? + parent_id.present? end # used for the `required` html attribute diff --git a/app/models/champs/repetition_champ.rb b/app/models/champs/repetition_champ.rb index 0731dea3e..7ea9d83cd 100644 --- a/app/models/champs/repetition_champ.rb +++ b/app/models/champs/repetition_champ.rb @@ -37,7 +37,7 @@ class Champs::RepetitionChamp < Champ end def blank? - row_ids.empty? + champs.empty? end def search_terms diff --git a/app/models/concerns/champs_validate_concern.rb b/app/models/concerns/champs_validate_concern.rb index ab5b2595b..bef65d73b 100644 --- a/app/models/concerns/champs_validate_concern.rb +++ b/app/models/concerns/champs_validate_concern.rb @@ -16,9 +16,9 @@ module ChampsValidateConcern def validate_champ_value? case validation_context when :champs_public_value - public? && in_dossier_revision? && visible? + public? && visible? when :champs_private_value - private? && in_dossier_revision? && visible? + private? && visible? else false end @@ -27,9 +27,5 @@ module ChampsValidateConcern def validate_champ_value_or_prefill? validate_champ_value? || validation_context == :prefill end - - def in_dossier_revision? - dossier.revision.types_de_champ.any? { _1.stable_id == stable_id } - end end end diff --git a/app/models/concerns/dossier_champs_concern.rb b/app/models/concerns/dossier_champs_concern.rb index 8e1f3d57a..485343e5c 100644 --- a/app/models/concerns/dossier_champs_concern.rb +++ b/app/models/concerns/dossier_champs_concern.rb @@ -33,7 +33,6 @@ module DossierChampsConcern end def project_champ(type_de_champ, row_id) - check_valid_row_id?(type_de_champ, row_id) champ = champs_by_public_id[type_de_champ.public_id(row_id)] if champ.nil? type_de_champ.build_champ(dossier: self, row_id:) @@ -57,8 +56,8 @@ module DossierChampsConcern revision .types_de_champ .filter { _1.stable_id.in?(stable_ids) } - .filter { !_1.child?(revision) } - .map { _1.repetition? ? project_champ(_1, nil) : champ_for_update(_1, nil, updated_by: nil) } + .filter { !revision.child?(_1) } + .map { champ_for_update(_1, nil, updated_by: nil) } end def champ_for_update(type_de_champ, row_id, updated_by:) @@ -82,7 +81,6 @@ module DossierChampsConcern end def champ_for_export(type_de_champ, row_id) - check_valid_row_id?(type_de_champ, row_id) champ = champs_by_public_id[type_de_champ.public_id(row_id)] if champ.blank? || !champ.visible? nil @@ -98,7 +96,6 @@ module DossierChampsConcern end def champ_with_attributes_for_update(type_de_champ, row_id, updated_by:) - check_valid_row_id?(type_de_champ, row_id) attributes = type_de_champ.params_for_champ # TODO: Once we have the right index in place, we should change this to use `create_or_find_by` instead of `find_or_create_by` champ = champs @@ -127,14 +124,4 @@ module DossierChampsConcern [champ, attributes] end - - def check_valid_row_id?(type_de_champ, row_id) - if type_de_champ.child?(revision) - if row_id.blank? - raise "type_de_champ #{type_de_champ.stable_id} must have a row_id because it is part of a repetition" - end - elsif row_id.present? - raise "type_de_champ #{type_de_champ.stable_id} can not have a row_id because it is not part of a repetition" - end - end end diff --git a/app/models/concerns/dossier_sections_concern.rb b/app/models/concerns/dossier_sections_concern.rb index c4644dba3..679e5b896 100644 --- a/app/models/concerns/dossier_sections_concern.rb +++ b/app/models/concerns/dossier_sections_concern.rb @@ -19,7 +19,7 @@ module DossierSectionsConcern end def auto_numbering_section_headers_for?(type_de_champ) - return false if type_de_champ.child?(revision) + return false if revision.child?(type_de_champ) sections_for(type_de_champ)&.none? { _1.libelle =~ /^\d/ } end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index e2b64d26f..eee97cee9 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -51,6 +51,7 @@ class Dossier < ApplicationRecord has_many :champs_to_destroy, -> { order(:parent_id) }, class_name: 'Champ', inverse_of: false, dependent: :destroy has_many :champs_public, -> { root.public_only }, class_name: 'Champ', inverse_of: false has_many :champs_private, -> { root.private_only }, class_name: 'Champ', inverse_of: false + has_many :prefilled_champs_public, -> { root.public_only.prefilled }, class_name: 'Champ', inverse_of: false has_many :commentaires, inverse_of: :dossier, dependent: :destroy has_many :preloaded_commentaires, -> { includes(:dossier_correction, piece_jointe_attachments: :blob) }, class_name: 'Commentaire', inverse_of: :dossier @@ -269,16 +270,33 @@ class Dossier < ApplicationRecord scope :en_cours, -> { not_archived.state_en_construction_ou_instruction } scope :without_followers, -> { where.missing(:follows) } scope :with_followers, -> { left_outer_joins(:follows).where.not(follows: { id: nil }) } + scope :with_champs, -> { + includes(champs_public: [ + :geo_areas, + piece_justificative_file_attachments: :blob, + champs: [piece_justificative_file_attachments: :blob] + ]) + } + scope :brouillons_recently_updated, -> { updated_since(2.days.ago).state_brouillon.order_by_updated_at } + scope :with_annotations, -> { + includes(champs_private: [ + :geo_areas, + piece_justificative_file_attachments: :blob, + champs: [piece_justificative_file_attachments: :blob] + ]) + } scope :for_api, -> { - includes(commentaires: { piece_jointe_attachments: :blob }, - justificatif_motivation_attachment: :blob, - attestation: [], - avis: { piece_justificative_file_attachment: :blob }, - traitement: [], - etablissement: [], - individual: [], - user: []) + with_champs + .with_annotations + .includes(commentaires: { piece_jointe_attachments: :blob }, + justificatif_motivation_attachment: :blob, + attestation: [], + avis: { piece_justificative_file_attachment: :blob }, + traitement: [], + etablissement: [], + individual: [], + user: []) } scope :with_notifiable_procedure, -> (opts = { notify_on_closed: false }) do @@ -423,6 +441,8 @@ class Dossier < ApplicationRecord validates :mandataire_last_name, presence: true, if: :for_tiers? validates :for_tiers, inclusion: { in: [true, false] }, if: -> { revision&.procedure&.for_individual? } + validates_associated :prefilled_champs_public, on: :champs_public_value + def types_de_champ_public types_de_champ end @@ -929,7 +949,7 @@ class Dossier < ApplicationRecord end def remove_titres_identite! - champs.filter(&:titre_identite?).map(&:piece_justificative_file).each(&:purge_later) + champs_public.filter(&:titre_identite?).map(&:piece_justificative_file).each(&:purge_later) end def remove_piece_justificative_file_not_visible! @@ -1144,7 +1164,7 @@ class Dossier < ApplicationRecord end def has_annotations? - revision.types_de_champ_private.present? + revision.revision_types_de_champ_private.present? end def hide_info_with_accuse_lecture? diff --git a/app/models/dossier_preloader.rb b/app/models/dossier_preloader.rb index 4eea05534..7c6dcd4ac 100644 --- a/app/models/dossier_preloader.rb +++ b/app/models/dossier_preloader.rb @@ -37,12 +37,18 @@ class DossierPreloader private - def revisions(pj_template: false) + def revisions @revisions ||= ProcedureRevision.where(id: @dossiers.pluck(:revision_id).uniq) - .includes(types_de_champ: pj_template ? { piece_justificative_template_attachment: :blob } : []) + .includes(types_de_champ: { piece_justificative_template_attachment: :blob }) .index_by(&:id) end + # returns: { revision_id : { stable_id : position } } + def positions + @positions ||= revisions + .transform_values { |revision| revision.revision_types_de_champ.map { [_1.stable_id, _1.position] }.to_h } + end + def load_dossiers(dossiers, pj_template: false) to_include = @includes_for_champ.dup to_include << [piece_justificative_file_attachments: :blob] @@ -52,10 +58,16 @@ class DossierPreloader .where(dossier_id: dossiers) .to_a - champs_by_dossier = all_champs.group_by(&:dossier_id) + children_champs, root_champs = all_champs.partition(&:child?) + champs_by_dossier = root_champs.group_by(&:dossier_id) + champs_by_dossier_by_parent = children_champs + .group_by(&:dossier_id) + .transform_values do |champs| + champs.group_by(&:parent_id) + end dossiers.each do |dossier| - load_dossier(dossier, champs_by_dossier[dossier.id] || [], pj_template:) + load_dossier(dossier, champs_by_dossier[dossier.id] || [], champs_by_dossier_by_parent[dossier.id] || {}) end load_etablissements(all_champs) @@ -74,30 +86,17 @@ class DossierPreloader end end - def load_dossier(dossier, champs, pj_template: false) - revision = revisions(pj_template:)[dossier.revision_id] + def load_dossier(dossier, champs, children_by_parent = {}) + revision = revisions[dossier.revision_id] if revision.present? dossier.association(:revision).target = revision end - dossier.association(:champs).target = champs - dossier.association(:champs_public).target = dossier.champs_for_revision(scope: :public, root: true) - dossier.association(:champs_private).target = dossier.champs_for_revision(scope: :private, root: true) - # remove once parent_id is deprecated - champs_by_parent_id = champs.group_by(&:parent_id) + champs_public, champs_private = champs.partition(&:public?) - champs.each do |champ| - champ.association(:dossier).target = dossier - - # remove once parent_id is deprecated - if champ.repetition? - children = champs_by_parent_id.fetch(champ.id, []) - children.each do |child| - child.association(:parent).target = champ - end - champ.association(:champs).target = children - end - end + dossier.association(:champs).target = [] + load_champs(dossier, :champs_public, champs_public, dossier, children_by_parent) + load_champs(dossier, :champs_private, champs_private, dossier, children_by_parent) # We need to do this because of the check on `Etablissement#champ` in # `Etablissement#libelle_for_export`. By assigning `nil` to `target` we mark association @@ -106,4 +105,33 @@ class DossierPreloader dossier.etablissement.association(:champ).target = nil end end + + def load_champs(parent, name, champs, dossier, children_by_parent) + if champs.empty? + parent.association(name).target = [] # tells to Rails association has been loaded + return + end + + champs.each do |champ| + champ.association(:dossier).target = dossier + + if parent.is_a?(Champ) + champ.association(:parent).target = parent + end + end + + dossier.association(:champs).target += champs + + parent.association(name).target = champs + .filter { positions[dossier.revision_id][_1.stable_id].present? } + .sort_by { [_1.row_id, positions[dossier.revision_id][_1.stable_id]] } + + # Load children champs + champs.filter(&:block?).each do |parent_champ| + champs = children_by_parent[parent_champ.id] || [] + parent_champ.association(:dossier).target = dossier + + load_champs(parent_champ, :champs, champs, dossier, children_by_parent) + end + end end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 1265171b0..a67fa05ef 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -207,6 +207,20 @@ class Procedure < ApplicationRecord includes(:draft_revision, :published_revision, administrateurs: :user) } + scope :for_download, -> { + includes( + :groupe_instructeurs, + dossiers: { + champs_public: [ + piece_justificative_file_attachments: :blob, + champs: [ + piece_justificative_file_attachments: :blob + ] + ] + } + ) + } + validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :description, presence: true, allow_blank: false, allow_nil: false validates :administrateurs, presence: true diff --git a/app/models/procedure_revision.rb b/app/models/procedure_revision.rb index 80d4b7b2c..3f073fb6d 100644 --- a/app/models/procedure_revision.rb +++ b/app/models/procedure_revision.rb @@ -219,6 +219,11 @@ class ProcedureRevision < ApplicationRecord .find { _1.type_de_champ_id == tdc.id }.parent&.type_de_champ end + def child?(tdc) + revision_types_de_champ + .find { _1.type_de_champ_id == tdc.id }.child? + end + def remove_children_of(tdc) children_of(tdc).each do |child| remove_type_de_champ(child.stable_id) diff --git a/app/models/procedure_revision_type_de_champ.rb b/app/models/procedure_revision_type_de_champ.rb index b8e538c97..503595143 100644 --- a/app/models/procedure_revision_type_de_champ.rb +++ b/app/models/procedure_revision_type_de_champ.rb @@ -32,8 +32,8 @@ class ProcedureRevisionTypeDeChamp < ApplicationRecord end def siblings - if child? - revision.revision_types_de_champ.where(parent_id:).ordered + if parent_id.present? + revision.revision_types_de_champ.where(parent_id: parent_id).ordered elsif private? revision.revision_types_de_champ_private else diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 3d1d3b164..45448e633 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -456,10 +456,6 @@ class TypeDeChamp < ApplicationRecord !private? end - def child?(revision) - revision.revision_types_de_champ.find { _1.type_de_champ_id == id }&.child? - end - def filename_for_attachement(attachment_sym) attachment = send(attachment_sym) if attachment.attached? diff --git a/app/views/instructeurs/dossiers/_instruction_button_motivation.html.haml b/app/views/instructeurs/dossiers/_instruction_button_motivation.html.haml index 56c83c685..76b4d576e 100644 --- a/app/views/instructeurs/dossiers/_instruction_button_motivation.html.haml +++ b/app/views/instructeurs/dossiers/_instruction_button_motivation.html.haml @@ -12,7 +12,7 @@ - if unspecified_attestation_champs.present? .warning Attention, les valeurs suivantes n’ont pas été renseignées mais sont nécessaires pour pouvoir envoyer une attestation valide : - - unspecified_annotations_privees, unspecified_champs = unspecified_attestation_champs.partition(&:private?) + - unspecified_annotations_privees, unspecified_champs = unspecified_attestation_champs.partition(&:private) - if unspecified_champs.present? %h4 Champs de la demande diff --git a/spec/controllers/champs/repetition_controller_spec.rb b/spec/controllers/champs/repetition_controller_spec.rb index 583ec2c88..d2c5aca3f 100644 --- a/spec/controllers/champs/repetition_controller_spec.rb +++ b/spec/controllers/champs/repetition_controller_spec.rb @@ -9,7 +9,7 @@ describe Champs::RepetitionController, type: :controller do it 'removes repetition' do rows, repetitions = dossier.champs.partition(&:child?) repetition = repetitions.first - expect { delete :remove, params: { dossier_id: dossier, stable_id: repetition.stable_id, row_id: rows.first.row_id }, format: :turbo_stream } + expect { delete :remove, params: { dossier_id: repetition.dossier, stable_id: repetition.stable_id, row_id: rows.first.row_id }, format: :turbo_stream } .to change { dossier.reload.champs.size }.from(3).to(1) end end diff --git a/spec/models/champ_spec.rb b/spec/models/champ_spec.rb index 6375ee4dd..50b033a58 100644 --- a/spec/models/champ_spec.rb +++ b/spec/models/champ_spec.rb @@ -8,50 +8,31 @@ describe Champ do let(:champ) { Champ.new(value: value) } let(:value) { '' } let(:mandatory) { true } + before { allow(champ).to receive(:type_de_champ).and_return(type_de_champ) } - context 'with champ' do - before { allow(champ).to receive(:type_de_champ).and_return(type_de_champ) } + context 'when mandatory and blank' do + it { expect(champ.mandatory_blank?).to be(true) } + end - context 'when mandatory and blank' do - it { expect(champ.mandatory_blank?).to be(true) } - end + context 'when carte mandatory and blank' do + let(:type_de_champ) { build(:type_de_champ_carte, mandatory: mandatory) } + let(:champ) { Champs::CarteChamp.new(value: value) } + let(:value) { nil } + it { expect(champ.mandatory_blank?).to be(true) } + end - context 'when carte mandatory and blank' do - let(:type_de_champ) { build(:type_de_champ_carte, mandatory: mandatory) } - let(:champ) { Champs::CarteChamp.new(value: value) } - let(:value) { nil } - it { expect(champ.mandatory_blank?).to be(true) } - end + context 'when multiple_drop_down_list mandatory and blank' do + let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, mandatory: mandatory) } + let(:champ) { Champs::MultipleDropDownListChamp.new(value: value) } + let(:value) { '[]' } + it { expect(champ.mandatory_blank?).to be(true) } + end - context 'when multiple_drop_down_list mandatory and blank' do - let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, mandatory: mandatory) } - let(:champ) { Champs::MultipleDropDownListChamp.new(value: value) } - let(:value) { '[]' } - it { expect(champ.mandatory_blank?).to be(true) } - end + context 'when repetition blank' do + let(:type_de_champ) { build(:type_de_champ_repetition) } + let(:champ) { Champs::RepetitionChamp.new } - context 'when repetition blank' do - let(:type_de_champ) { build(:type_de_champ_repetition) } - let(:champ) { Champs::RepetitionChamp.new(dossier: Dossier.new(revision: ProcedureRevision.new)) } - - it { expect(champ.blank?).to be(true) } - end - - context 'when not blank' do - let(:value) { 'yop' } - it { expect(champ.mandatory_blank?).to be(false) } - end - - context 'when not mandatory' do - let(:mandatory) { false } - it { expect(champ.mandatory_blank?).to be(false) } - end - - context 'when not mandatory or blank' do - let(:value) { 'u' } - let(:mandatory) { false } - it { expect(champ.mandatory_blank?).to be(false) } - end + it { expect(champ.blank?).to be(true) } end context 'when repetition not blank' do @@ -61,6 +42,22 @@ describe Champ do it { expect(champ.blank?).to be(false) } end + + context 'when not blank' do + let(:value) { 'yop' } + it { expect(champ.mandatory_blank?).to be(false) } + end + + context 'when not mandatory' do + let(:mandatory) { false } + it { expect(champ.mandatory_blank?).to be(false) } + end + + context 'when not mandatory or blank' do + let(:value) { 'u' } + let(:mandatory) { false } + it { expect(champ.mandatory_blank?).to be(false) } + end end describe "associations" do @@ -128,7 +125,7 @@ describe Champ do let(:standalone_champ) { build(:champ, type_de_champ: build(:type_de_champ), dossier: build(:dossier)) } let(:public_sections) { dossier.champs_public.filter(&:header_section?) } let(:private_sections) { dossier.champs_private.filter(&:header_section?) } - let(:sections_in_repetition) { dossier.champs.filter(&:child?).filter(&:header_section?) } + let(:sections_in_repetition) { champ_in_repetition.parent.champs.filter(&:header_section?) } it 'returns the sibling sections of a champ' do expect(public_sections).not_to be_empty diff --git a/spec/models/champs/cnaf_champ_spec.rb b/spec/models/champs/cnaf_champ_spec.rb index acc7d0ae0..f8f03ad08 100644 --- a/spec/models/champs/cnaf_champ_spec.rb +++ b/spec/models/champs/cnaf_champ_spec.rb @@ -2,10 +2,7 @@ describe Champs::CnafChamp, type: :model do let(:champ) { described_class.new(dossier: build(:dossier)) } - before do - allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_cnaf)) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_cnaf)) } describe 'numero_allocataire and code_postal' do before do champ.numero_allocataire = '1234567' diff --git a/spec/models/champs/decimal_number_champ_spec.rb b/spec/models/champs/decimal_number_champ_spec.rb index 8603f2f9a..78958b7a8 100644 --- a/spec/models/champs/decimal_number_champ_spec.rb +++ b/spec/models/champs/decimal_number_champ_spec.rb @@ -6,7 +6,6 @@ describe Champs::DecimalNumberChamp do before do allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_decimal_number)) allow(champ).to receive(:visible?).and_return(true) - allow(champ).to receive(:in_dossier_revision?).and_return(true) champ.run_callbacks(:validation) end subject { champ.validate(:champs_public_value) } diff --git a/spec/models/champs/departement_champ_spec.rb b/spec/models/champs/departement_champ_spec.rb index 3bfb5f41c..9794e01a7 100644 --- a/spec/models/champs/departement_champ_spec.rb +++ b/spec/models/champs/departement_champ_spec.rb @@ -4,10 +4,7 @@ describe Champs::DepartementChamp, type: :model do describe 'validations' do describe 'external link' do let(:champ) { described_class.new(external_id: external_id, dossier: build(:dossier)) } - before do - allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_departements)) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_departements)) } subject { champ.validate(:champs_public_value) } context 'when nil' do diff --git a/spec/models/champs/dgfip_champ_spec.rb b/spec/models/champs/dgfip_champ_spec.rb index bafa48adb..bfe94d895 100644 --- a/spec/models/champs/dgfip_champ_spec.rb +++ b/spec/models/champs/dgfip_champ_spec.rb @@ -40,10 +40,7 @@ describe Champs::DgfipChamp, type: :model do let(:numero_fiscal) { '1122299999092' } let(:reference_avis) { 'FC22299999092' } let(:champ) { described_class.new(dossier: build(:dossier)) } - before do - allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_dgfip)) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_dgfip)) } let(:validation_context) { :champs_public_value } subject { champ.valid?(validation_context) } diff --git a/spec/models/champs/dossier_link_champ_spec.rb b/spec/models/champs/dossier_link_champ_spec.rb index d5f5e4550..411631c39 100644 --- a/spec/models/champs/dossier_link_champ_spec.rb +++ b/spec/models/champs/dossier_link_champ_spec.rb @@ -42,7 +42,6 @@ describe Champs::DossierLinkChamp, type: :model do before do allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_dossier_link, mandatory:)) - allow(champ).to receive(:in_dossier_revision?).and_return(true) champ.run_callbacks(:validation) end diff --git a/spec/models/champs/drop_down_list_champ_spec.rb b/spec/models/champs/drop_down_list_champ_spec.rb index d69487b08..842adf8f4 100644 --- a/spec/models/champs/drop_down_list_champ_spec.rb +++ b/spec/models/champs/drop_down_list_champ_spec.rb @@ -4,10 +4,7 @@ describe Champs::DropDownListChamp do describe 'validations' do describe 'inclusion' do let(:champ) { described_class.new(other:, value:, dossier: build(:dossier)) } - before do - allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_drop_down_list, drop_down_other: other)) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_drop_down_list, drop_down_other: other)) } subject { champ.validate(:champs_public_value) } context 'when the other value is accepted' do diff --git a/spec/models/champs/email_champ_spec.rb b/spec/models/champs/email_champ_spec.rb index f23705648..e24775296 100644 --- a/spec/models/champs/email_champ_spec.rb +++ b/spec/models/champs/email_champ_spec.rb @@ -2,10 +2,8 @@ describe Champs::EmailChamp do describe 'validation' do - let(:procedure) { create(:procedure, types_de_champ_public: [{}, { type: :email }, {}]) } - let(:dossier) { create(:dossier, procedure:) } - let(:champ) { dossier.champs.second } - before { champ.value = value } + let(:champ) { described_class.new(value:, dossier: build(:dossier)) } + before { allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_email)) } subject { champ.validate(:champs_public_value) } context 'when nil' do @@ -81,11 +79,5 @@ describe Champs::EmailChamp do expect { subject }.to change { champ.value }.from(value).to('username@mailserver.domain') end end - - context 'when type_de_champ is not in dossier revision anymore' do - before { dossier.revision.remove_type_de_champ(champ.stable_id) } - let(:value) { 'username' } - it { is_expected.to be_truthy } - end end end diff --git a/spec/models/champs/epci_champ_spec.rb b/spec/models/champs/epci_champ_spec.rb index 58d7b7868..d79cc7df6 100644 --- a/spec/models/champs/epci_champ_spec.rb +++ b/spec/models/champs/epci_champ_spec.rb @@ -6,10 +6,7 @@ describe Champs::EpciChamp, type: :model do describe 'code_departement' do let(:champ) { Champs::EpciChamp.new(code_departement: code_departement, dossier: build(:dossier)) } - before do - allow(champ).to receive(:visible?).and_return(true) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:visible?).and_return(true) } context 'when nil' do let(:code_departement) { nil } diff --git a/spec/models/champs/iban_champ_spec.rb b/spec/models/champs/iban_champ_spec.rb index bf7c63e2f..7088f9a34 100644 --- a/spec/models/champs/iban_champ_spec.rb +++ b/spec/models/champs/iban_champ_spec.rb @@ -3,10 +3,7 @@ describe Champs::IbanChamp do describe '#valid?' do let(:champ) { Champs::IbanChamp.new(dossier: build(:dossier)) } - before do - allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_iban)) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_iban)) } def with_value(value) champ.tap { _1.value = value } end diff --git a/spec/models/champs/integer_number_champ_spec.rb b/spec/models/champs/integer_number_champ_spec.rb index 8a5d2182f..4367a2465 100644 --- a/spec/models/champs/integer_number_champ_spec.rb +++ b/spec/models/champs/integer_number_champ_spec.rb @@ -2,10 +2,7 @@ describe Champs::IntegerNumberChamp do let(:champ) { Champs::IntegerNumberChamp.new(value:, dossier: build(:dossier)) } - before do - allow(champ).to receive(:visible?).and_return(true) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:visible?).and_return(true) } subject { champ.validate(:champs_public_value) } describe '#valid?' do diff --git a/spec/models/champs/multiple_drop_down_list_champ_spec.rb b/spec/models/champs/multiple_drop_down_list_champ_spec.rb index 704572c47..6ee9805c3 100644 --- a/spec/models/champs/multiple_drop_down_list_champ_spec.rb +++ b/spec/models/champs/multiple_drop_down_list_champ_spec.rb @@ -4,10 +4,7 @@ describe Champs::MultipleDropDownListChamp do let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, drop_down_list_value: "val1\r\nval2\r\nval3\r\n[brackets] val4") } let(:value) { nil } let(:champ) { Champs::MultipleDropDownListChamp.new(value:, dossier: build(:dossier)) } - before do - allow(champ).to receive(:type_de_champ).and_return(type_de_champ) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:type_de_champ).and_return(type_de_champ) } describe 'validations' do subject { champ.validate(:champs_public_value) } diff --git a/spec/models/champs/phone_champ_spec.rb b/spec/models/champs/phone_champ_spec.rb index 0653bf39d..c90951bc7 100644 --- a/spec/models/champs/phone_champ_spec.rb +++ b/spec/models/champs/phone_champ_spec.rb @@ -2,10 +2,7 @@ describe Champs::PhoneChamp do let(:champ) { Champs::PhoneChamp.new(dossier: build(:dossier)) } - before do - allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_phone)) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_phone)) } describe '#validate' do it do expect(champ_with_value(nil).validate(:champs_public_value)).to be_truthy diff --git a/spec/models/champs/rna_champ_spec.rb b/spec/models/champs/rna_champ_spec.rb index c2968f752..248f27c06 100644 --- a/spec/models/champs/rna_champ_spec.rb +++ b/spec/models/champs/rna_champ_spec.rb @@ -2,10 +2,7 @@ describe Champs::RNAChamp do let(:champ) { Champs::RNAChamp.new(value: "W182736273", dossier: build(:dossier)) } - before do - allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_rna)) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - end + before { allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_rna)) } def with_value(value) champ.tap { _1.value = value } end diff --git a/spec/models/concerns/dossier_champs_concern_spec.rb b/spec/models/concerns/dossier_champs_concern_spec.rb index 5e68d5e99..ce6581fbb 100644 --- a/spec/models/concerns/dossier_champs_concern_spec.rb +++ b/spec/models/concerns/dossier_champs_concern_spec.rb @@ -35,6 +35,7 @@ RSpec.describe DossierChampsConcern do let(:type_de_champ_repetition) { dossier.find_type_de_champ_by_stable_id(993) } let(:type_de_champ_public) { dossier.find_type_de_champ_by_stable_id(99) } let(:type_de_champ_private) { dossier.find_type_de_champ_by_stable_id(995) } + let(:row_ids) { dossier.project_champ(type_de_champ_repetition, nil).row_ids } context "public champ" do let(:row_id) { nil } @@ -44,20 +45,13 @@ RSpec.describe DossierChampsConcern do context "in repetition" do let(:type_de_champ_public) { dossier.find_type_de_champ_by_stable_id(994) } - let(:row_id) { dossier.project_champ(type_de_champ_repetition, nil).row_ids.first } + let(:row_id) { row_ids.first } it { expect(subject.persisted?).to be_truthy expect(subject.row_id).to eq(row_id) expect(subject.parent_id).not_to be_nil } - - context "invalid row_id" do - let(:type_de_champ_public) { dossier.find_type_de_champ_by_stable_id(99) } - it { - expect { subject }.to raise_error("type_de_champ #{type_de_champ_public.stable_id} can not have a row_id because it is not part of a repetition") - } - end end context "missing champ" do @@ -70,20 +64,13 @@ RSpec.describe DossierChampsConcern do context "in repetition" do let(:type_de_champ_public) { dossier.find_type_de_champ_by_stable_id(994) } - let(:row_id) { ULID.generate } + let(:row_id) { row_ids.first } it { expect(subject.new_record?).to be_truthy expect(subject.is_a?(Champs::TextChamp)).to be_truthy expect(subject.row_id).to eq(row_id) } - - context "invalid row_id" do - let(:type_de_champ_public) { dossier.find_type_de_champ_by_stable_id(99) } - it { - expect { subject }.to raise_error("type_de_champ #{type_de_champ_public.stable_id} can not have a row_id because it is not part of a repetition") - } - end end end end @@ -135,6 +122,7 @@ RSpec.describe DossierChampsConcern do let(:type_de_champ_repetition) { dossier.find_type_de_champ_by_stable_id(993) } let(:type_de_champ_public) { dossier.find_type_de_champ_by_stable_id(99) } let(:type_de_champ_private) { dossier.find_type_de_champ_by_stable_id(995) } + let(:row_ids) { dossier.project_champ(type_de_champ_repetition, nil).row_ids } let(:row_id) { nil } context "public champ" do @@ -147,7 +135,7 @@ RSpec.describe DossierChampsConcern do context "in repetition" do let(:type_de_champ_public) { dossier.find_type_de_champ_by_stable_id(994) } - let(:row_id) { ULID.generate } + let(:row_id) { row_ids.first } it { expect(subject.persisted?).to be_truthy @@ -166,7 +154,7 @@ RSpec.describe DossierChampsConcern do context "in repetition" do let(:type_de_champ_public) { dossier.find_type_de_champ_by_stable_id(994) } - let(:row_id) { ULID.generate } + let(:row_id) { row_ids.first } it { expect(subject.persisted?).to be_truthy @@ -190,7 +178,8 @@ RSpec.describe DossierChampsConcern do describe "#update_champs_attributes(public)" do let(:type_de_champ_repetition) { dossier.find_type_de_champ_by_stable_id(993) } - let(:row_id) { ULID.generate } + let(:row_ids) { dossier.project_champ(type_de_champ_repetition, nil).row_ids } + let(:row_id) { row_ids.first } let(:attributes) do { diff --git a/spec/models/concerns/dossier_searchable_concern_spec.rb b/spec/models/concerns/dossier_searchable_concern_spec.rb index d1b0c1114..560184c6c 100644 --- a/spec/models/concerns/dossier_searchable_concern_spec.rb +++ b/spec/models/concerns/dossier_searchable_concern_spec.rb @@ -38,8 +38,10 @@ describe DossierSearchableConcern do end it "update columns en construction" do - dossier.update_champs_attributes({ champ_public.public_id => { value: 'nouvelle valeur publique' } }, :public, updated_by: 'test') - dossier.update_champs_attributes({ champ_private.public_id => { value: 'nouvelle valeur privee' } }, :private, updated_by: 'test') + dossier.update( + champs_public_attributes: [{ id: champ_public.id, value: 'nouvelle valeur publique' }], + champs_private_attributes: [{ id: champ_private.id, value: 'nouvelle valeur privee' }] + ) assert_enqueued_jobs(1, only: DossierIndexSearchTermsJob) do dossier.passer_en_construction diff --git a/spec/models/concerns/dossier_sections_concern_spec.rb b/spec/models/concerns/dossier_sections_concern_spec.rb index 17f86be88..43b0b556f 100644 --- a/spec/models/concerns/dossier_sections_concern_spec.rb +++ b/spec/models/concerns/dossier_sections_concern_spec.rb @@ -50,12 +50,12 @@ describe DossierSectionsConcern do describe '#index_for_section_header' do include Logic let(:number_stable_id) { 99 } - let(:types_de_champ) do - [ - { type: :header_section, libelle: "Infos" }, { type: :integer_number, stable_id: number_stable_id }, - { type: :header_section, libelle: "Details", condition: ds_eq(champ_value(99), constant(5)) }, { type: :header_section, libelle: "Conclusion" } - ] - end + let(:types_de_champ) { + [ + { type: :header_section, libelle: "Infos" }, { type: :integer_number, stable_id: number_stable_id }, + { type: :header_section, libelle: "Details", condition: ds_eq(champ_value(99), constant(5)) }, { type: :header_section, libelle: "Conclusion" } + ] +} let(:procedure) { create(:procedure, :for_individual, types_de_champ_public: types_de_champ) } let(:dossier) { create(:dossier, procedure: procedure) } diff --git a/spec/models/champs/engagement_juridique_champ_spec.rb b/spec/models/engagement_juridique_champ_spec.rb similarity index 83% rename from spec/models/champs/engagement_juridique_champ_spec.rb rename to spec/models/engagement_juridique_champ_spec.rb index 795cd7813..55b51df08 100644 --- a/spec/models/champs/engagement_juridique_champ_spec.rb +++ b/spec/models/engagement_juridique_champ_spec.rb @@ -7,10 +7,7 @@ describe Champs::EngagementJuridiqueChamp do .new(dossier: build(:dossier)) .tap { _1.value = value } end - before { - allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_engagement_juridique)) - allow(champ).to receive(:in_dossier_revision?).and_return(true) - } + before { allow(champ).to receive(:type_de_champ).and_return(build(:type_de_champ_engagement_juridique)) } subject { champ.validate(:champs_public_value) } context 'with [A-Z]' do diff --git a/spec/services/procedure_export_service_spec.rb b/spec/services/procedure_export_service_spec.rb index 34cecb9f1..a92466a17 100644 --- a/spec/services/procedure_export_service_spec.rb +++ b/spec/services/procedure_export_service_spec.rb @@ -390,11 +390,11 @@ describe ProcedureExportService do context 'with long libelle composed of utf8 characteres' do before do - procedure.active_revision.types_de_champ_public.each do |type_de_champ| - type_de_champ.update!(libelle: "#{type_de_champ.id} - ?/[] ééé ééé ééééééé ééééééé éééééééé. ééé éé éééééééé éé ééé. ééééé éééééééé ééé ééé.") + procedure.active_revision.types_de_champ_public.each do |c| + c.update!(libelle: "#{c.id} - ?/[] ééé ééé ééééééé ééééééé éééééééé. ééé éé éééééééé éé ééé. ééééé éééééééé ééé ééé.") end - procedure.active_revision.children_of(champ_repetition.type_de_champ).each do |type_de_champ| - type_de_champ.update!(libelle: "#{type_de_champ.id} - Quam rem nam maiores numquam dolorem nesciunt. Cum et possimus et aut. Fugit voluptas qui qui.") + champ_repetition.champs.each do |c| + c.type_de_champ.update!(libelle: "#{c.id} - Quam rem nam maiores numquam dolorem nesciunt. Cum et possimus et aut. Fugit voluptas qui qui.") end end @@ -417,7 +417,7 @@ describe ProcedureExportService do context 'with empty repetition' do before do dossiers.flat_map { |dossier| dossier.champs_public.filter(&:repetition?) }.each do |champ| - Champ.where(row_id: champ.row_ids).destroy_all + champ.champs.destroy_all end end