From 9425f2cc581298dbcb4579427f8f31d9d14180de Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 5 Mar 2024 14:00:54 +0100 Subject: [PATCH] fix(user.france_connect_informations): has_many, not has_one --- app/graphql/types/dossier_type.rb | 2 +- app/models/dossier.rb | 11 +++++------ app/models/user.rb | 13 ++++++++----- app/services/pieces_justificatives_service.rb | 2 +- app/views/dossiers/show.pdf.prawn | 4 ++-- app/views/layouts/_account_dropdown.haml | 2 +- app/views/shared/dossiers/_demande.html.haml | 4 ++-- app/views/shared/dossiers/_edit.html.haml | 4 ++-- spec/factories/user.rb | 2 +- .../concern/dossier_searchable_concern_spec.rb | 2 +- spec/models/dossier_spec.rb | 15 ++++++++++++--- spec/models/user_spec.rb | 7 ++++--- .../instructeur/dossiers/show.html.haml_spec.rb | 2 +- .../users/dossiers/demande.html.haml_spec.rb | 2 +- 14 files changed, 42 insertions(+), 30 deletions(-) diff --git a/app/graphql/types/dossier_type.rb b/app/graphql/types/dossier_type.rb index f608b4d0b..2aca07737 100644 --- a/app/graphql/types/dossier_type.rb +++ b/app/graphql/types/dossier_type.rb @@ -212,7 +212,7 @@ module Types private def user_loader - Loaders::Record.for(User, includes: :france_connect_information).load(object.user_id) + Loaders::Record.for(User, includes: :france_connect_informations).load(object.user_id) end end end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 936b5e9a9..211270eb8 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -129,7 +129,7 @@ class Dossier < ApplicationRecord belongs_to :batch_operation, optional: true has_many :dossier_batch_operations, dependent: :destroy has_many :batch_operations, through: :dossier_batch_operations - has_one :france_connect_information, through: :user + has_many :france_connect_informations, through: :user has_one :procedure, through: :revision has_one :attestation_template, through: :procedure @@ -439,8 +439,7 @@ class Dossier < ApplicationRecord scope :not_having_batch_operation, -> { where(batch_operation_id: nil) } delegate :siret, :siren, to: :etablissement, allow_nil: true - delegate :france_connect_information, to: :user, allow_nil: true - + delegate :france_connected_with_one_identity?, to: :user, allow_nil: true before_save :build_default_champs_for_new_dossier, if: Proc.new { revision_id_was.nil? && parent_dossier_id.nil? && editing_fork_origin_id.nil? } after_save :send_web_hook @@ -518,8 +517,8 @@ class Dossier < ApplicationRecord def build_default_individual if procedure.for_individual? && individual.blank? - self.individual = if france_connect_information.present? - Individual.from_france_connect(france_connect_information) + self.individual = if france_connected_with_one_identity? + Individual.from_france_connect(france_connect_informations.first) else Individual.new end @@ -1389,7 +1388,7 @@ class Dossier < ApplicationRecord def user_from_france_connect? return false if user_deleted? - user.france_connect_information.present? + user.france_connected_with_one_identity? end def champs_by_stable_id_with_row diff --git a/app/models/user.rb b/app/models/user.rb index 19d829aec..ad6be60bb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -22,15 +22,15 @@ class User < ApplicationRecord has_many :deleted_dossiers has_many :merge_logs, dependent: :destroy has_many :requested_merge_from, class_name: 'User', dependent: :nullify, inverse_of: :requested_merge_into, foreign_key: :requested_merge_into_id + has_many :france_connect_informations, dependent: :destroy - has_one :france_connect_information, dependent: :destroy has_one :instructeur, dependent: :destroy has_one :administrateur, dependent: :destroy has_one :gestionnaire, dependent: :destroy has_one :expert, dependent: :destroy belongs_to :requested_merge_into, class_name: 'User', optional: true - accepts_nested_attributes_for :france_connect_information + accepts_nested_attributes_for :france_connect_informations default_scope { eager_load(:instructeur, :administrateur, :expert) } @@ -103,7 +103,7 @@ class User < ApplicationRecord if user.valid? if user.instructeur.nil? user.create_instructeur! - user.update(france_connect_information: nil) + user.france_connect_informations.delete_all end user.instructeur.administrateurs << administrateurs @@ -127,7 +127,7 @@ class User < ApplicationRecord if user.valid? && user.administrateur.nil? user.create_administrateur! - user.update(france_connect_information: nil) + user.france_connect_informations.delete_all AdminUpdateDefaultZonesJob.perform_later(user.administrateur) end @@ -176,6 +176,10 @@ class User < ApplicationRecord !administrateur? && !instructeur? end + def france_connected_with_one_identity? + france_connect_informations.size == 1 + end + def can_be_deleted? !administrateur? && !instructeur? && !expert? end @@ -190,7 +194,6 @@ class User < ApplicationRecord Invite.where(dossier: dossiers).destroy_all delete_and_keep_track_dossiers(super_admin, reason: :user_removed) - destroy! end end diff --git a/app/services/pieces_justificatives_service.rb b/app/services/pieces_justificatives_service.rb index 2d5a002a9..21f9ecb51 100644 --- a/app/services/pieces_justificatives_service.rb +++ b/app/services/pieces_justificatives_service.rb @@ -38,7 +38,7 @@ class PiecesJustificativesService pdfs = [] procedure = dossiers.first.procedure - dossiers = dossiers.includes(:individual, :traitement, :etablissement, user: :france_connect_information, avis: :expert, commentaires: [:instructeur, :expert]) + dossiers = dossiers.includes(:individual, :traitement, :etablissement, user: :france_connect_informations, avis: :expert, commentaires: [:instructeur, :expert]) dossiers = DossierPreloader.new(dossiers).in_batches dossiers.each do |dossier| dossier.association(:procedure).target = procedure diff --git a/app/views/dossiers/show.pdf.prawn b/app/views/dossiers/show.pdf.prawn index eaf32db3b..74dec4234 100644 --- a/app/views/dossiers/show.pdf.prawn +++ b/app/views/dossiers/show.pdf.prawn @@ -334,8 +334,8 @@ prawn_document(page_size: "A4") do |pdf| add_title(pdf, "Identité du demandeur") - if @dossier.france_connect_information.present? - format_in_2_columns(pdf, 'Informations FranceConnect', france_connect_informations(@dossier.france_connect_information)) + if @dossier.france_connected_with_one_identity? + format_in_2_columns(pdf, 'Informations FranceConnect', france_connect_information(@dossier.france_connect_informations.first)) end format_in_2_columns(pdf, "Email", @dossier.user_email_for(:display)) diff --git a/app/views/layouts/_account_dropdown.haml b/app/views/layouts/_account_dropdown.haml index cb1f38d49..d46aec7f1 100644 --- a/app/views/layouts/_account_dropdown.haml +++ b/app/views/layouts/_account_dropdown.haml @@ -2,7 +2,7 @@ .fr-nav__item %button.account-btn.fr-translate__btn.fr-btn{ "aria-controls" => "account", "aria-expanded" => "false", :title => t('my_account', scope: [:layouts]) } %span= current_email - - if dossier.present? && dossier&.france_connect_information.present? + - if dossier.present? && dossier&.france_connected_with_one_identity? %span  via FranceConnect %span{ class: "fr-badge fr-badge--sm fr-ml-1w #{color_by_role(nav_bar_profile)}" } diff --git a/app/views/shared/dossiers/_demande.html.haml b/app/views/shared/dossiers/_demande.html.haml index 57b4bf49b..3a34f9f14 100644 --- a/app/views/shared/dossiers/_demande.html.haml +++ b/app/views/shared/dossiers/_demande.html.haml @@ -1,6 +1,6 @@ -- if dossier.france_connect_information.present? && current_user.instructeur? && !current_user.owns_or_invite?(dossier) +- if dossier.france_connected_with_one_identity? && current_user.instructeur? && !current_user.owns_or_invite?(dossier) - content_for(:notice_info) do - = render partial: "shared/dossiers/france_connect_informations_notice", locals: { user_information: dossier.france_connect_information } + = render partial: "shared/dossiers/france_connect_informations_notice", locals: { user_information: dossier.france_connect_informations.first } .fr-container.counter-start-header-section.dossier-show{ class: class_names("dossier-show-instructeur" => profile =="instructeur") } .fr-grid-row.fr-grid-row--center diff --git a/app/views/shared/dossiers/_edit.html.haml b/app/views/shared/dossiers/_edit.html.haml index 90379bb1d..75701fe17 100644 --- a/app/views/shared/dossiers/_edit.html.haml +++ b/app/views/shared/dossiers/_edit.html.haml @@ -1,8 +1,8 @@ - dossier_for_editing = dossier.en_construction? ? dossier.owner_editing_fork : dossier -- if dossier.france_connect_information.present? && current_user.instructeur? && !current_user.owns_or_invite?(dossier) +- if dossier.france_connected_with_one_identity? && current_user.instructeur? && !current_user.owns_or_invite?(dossier) - content_for(:notice_info) do - = render partial: "shared/dossiers/france_connect_informations_notice", locals: { user_information: dossier.france_connect_information } + = render partial: "shared/dossiers/france_connect_informations_notice", locals: { user_information: dossier.france_connect_informations.first } .dossier-edit.container.counter-start-header-section diff --git a/spec/factories/user.rb b/spec/factories/user.rb index 11fc4c1c9..4370d7ea8 100644 --- a/spec/factories/user.rb +++ b/spec/factories/user.rb @@ -14,7 +14,7 @@ FactoryBot.define do end trait :with_fci do - association :france_connect_information + france_connect_informations { [association(:france_connect_information)] } end end end diff --git a/spec/models/concern/dossier_searchable_concern_spec.rb b/spec/models/concern/dossier_searchable_concern_spec.rb index c0a8a8fd2..a13f78d8a 100644 --- a/spec/models/concern/dossier_searchable_concern_spec.rb +++ b/spec/models/concern/dossier_searchable_concern_spec.rb @@ -11,7 +11,7 @@ describe DossierSearchableConcern do let(:procedure) { create(:procedure, :with_type_de_champ, :with_type_de_champ_private) } let(:dossier) { create(:dossier, etablissement: etablissement, user: user, procedure: procedure) } let(:france_connect_information) { build(:france_connect_information, given_name: 'Chris', family_name: 'Harrisson') } - let(:user) { build(:user, france_connect_information: france_connect_information) } + let(:user) { build(:user, france_connect_informations: [france_connect_information]) } before do champ_public.update_attribute(:value, "champ public") diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 94d205a90..59f09c579 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -307,8 +307,7 @@ describe Dossier, type: :model do end context 'and the user signs-in using France Connect' do - let(:france_connect_information) { build(:france_connect_information) } - let(:user) { build(:user, france_connect_information: france_connect_information) } + let(:user) { create(:user, france_connect_informations: [build(:france_connect_information)]) } it 'fills the individual with the informations from France Connect' do subject @@ -317,6 +316,16 @@ describe Dossier, type: :model do expect(dossier.individual.gender).to eq(Individual::GENDER_FEMALE) end end + context 'and the user signs-in using France Connect many times' do + let(:user) { create(:user, france_connect_informations: [build(:france_connect_information), build(:france_connect_information)]) } + + it 'fills the individual with the informations from France Connect' do + subject + expect(dossier.individual.nom).to eq(nil) + expect(dossier.individual.prenom).to eq(nil) + expect(dossier.individual.gender).to eq(nil) + end + end end context 'when the dossier belongs to a procedure for moral personas' do @@ -2108,7 +2117,7 @@ describe Dossier, type: :model do let(:dossier) { create(:dossier) } context 'user france connected' do - let(:dossier) { build(:dossier, user: build(:user, france_connect_information: build(:france_connect_information))) } + let(:dossier) { build(:dossier, user: build(:user, france_connect_informations: [build(:france_connect_information)])) } it { expect(dossier.spreadsheet_columns(types_de_champ: [])).to include(["FranceConnect ?", true]) } end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 307cc78a0..4e875ac9f 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -348,7 +348,7 @@ describe User, type: :model do expect(dossier_termine.user).to be_nil expect(dossier_termine.user_email_for(:display)).to eq(user.email) expect(dossier_termine.valid?).to be_truthy - expect(dossier_termine.france_connect_information).to be_nil + expect(dossier_termine.france_connect_informations).to be_empty expect { dossier_termine.user_email_for(:notification) }.to raise_error(RuntimeError) expect(User.find_by(id: user.id)).to be_nil @@ -356,12 +356,13 @@ describe User, type: :model do end context 'with fci' do - let(:user) { create(:user, :with_fci) } - let!(:fci) { create(:france_connect_information, user:) } + let!(:user) { create(:user, france_connect_informations: [build(:france_connect_information), build(:france_connect_information)]) } let(:reason) { :user_expired } subject { user.delete_and_keep_track_dossiers_also_delete_user(super_admin, reason:) } it { expect { subject }.not_to raise_error } + it { expect { subject }.to change { FranceConnectInformation.count }.from(2).to(0) } + it { expect { subject }.to change { User.count }.from(1).to(0) } end end diff --git a/spec/views/instructeur/dossiers/show.html.haml_spec.rb b/spec/views/instructeur/dossiers/show.html.haml_spec.rb index 9f5563340..f3b509e37 100644 --- a/spec/views/instructeur/dossiers/show.html.haml_spec.rb +++ b/spec/views/instructeur/dossiers/show.html.haml_spec.rb @@ -172,7 +172,7 @@ describe 'instructeurs/dossiers/show', type: :view do context 'when the user is logged in with france connect' do let(:france_connect_information) { build(:france_connect_information) } - let(:user) { build(:user, france_connect_information: france_connect_information) } + let(:user) { build(:user, france_connect_informations: [france_connect_information]) } let(:procedure1) { create(:procedure, :with_type_de_champ, for_individual: true) } let(:dossier) { create(:dossier, procedure: procedure1, user: user) } diff --git a/spec/views/users/dossiers/demande.html.haml_spec.rb b/spec/views/users/dossiers/demande.html.haml_spec.rb index 5c9679225..55d185dff 100644 --- a/spec/views/users/dossiers/demande.html.haml_spec.rb +++ b/spec/views/users/dossiers/demande.html.haml_spec.rb @@ -36,7 +36,7 @@ describe 'users/dossiers/demande', type: :view do context 'when the user is logged in with france connect' do let(:france_connect_information) { build(:france_connect_information) } - let(:user) { build(:user, france_connect_information: france_connect_information) } + let(:user) { build(:user, france_connect_informations: [france_connect_information]) } let(:procedure1) { create(:procedure, :with_type_de_champ, for_individual: true) } let(:dossier) { create(:dossier, procedure: procedure1, user: user) }