From 4cbb8e91f2b80b01127ad842d75036da4426e888 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Thu, 7 Sep 2023 10:03:17 +0200 Subject: [PATCH] Workable draft prefill identity (no link or query help) --- .../api/public/v1/dossiers_controller.rb | 2 +- app/controllers/users/commencer_controller.rb | 8 +- .../concerns/dossier_prefillable_concern.rb | 5 +- app/models/dossier.rb | 2 +- .../{prefill_params.rb => prefill_champs.rb} | 2 +- app/models/prefill_identity.rb | 20 +++ .../dossier_prefillable_concern_spec.rb | 146 +++++++++++------- ..._params_spec.rb => prefill_champs_spec.rb} | 28 ++-- spec/models/prefill_identity_spec.rb | 35 +++++ 9 files changed, 169 insertions(+), 79 deletions(-) rename app/models/{prefill_params.rb => prefill_champs.rb} (99%) create mode 100644 app/models/prefill_identity.rb rename spec/models/{prefill_params_spec.rb => prefill_champs_spec.rb} (94%) create mode 100644 spec/models/prefill_identity_spec.rb diff --git a/app/controllers/api/public/v1/dossiers_controller.rb b/app/controllers/api/public/v1/dossiers_controller.rb index 3503a2def..86d455028 100644 --- a/app/controllers/api/public/v1/dossiers_controller.rb +++ b/app/controllers/api/public/v1/dossiers_controller.rb @@ -9,7 +9,7 @@ class API::Public::V1::DossiersController < API::Public::V1::BaseController ) dossier.build_default_individual if dossier.save - dossier.prefill!(PrefillParams.new(dossier, params.to_unsafe_h).to_a) + dossier.prefill!(PrefillChamps.new(dossier, params.to_unsafe_h).to_a, PrefillIdentity.new(dossier, params.to_unsafe_h).to_h) render json: serialize_dossier(dossier), status: :created else render_bad_request(dossier.errors.full_messages.to_sentence) diff --git a/app/controllers/users/commencer_controller.rb b/app/controllers/users/commencer_controller.rb index 9f007c92b..1c6bfbebe 100644 --- a/app/controllers/users/commencer_controller.rb +++ b/app/controllers/users/commencer_controller.rb @@ -78,11 +78,11 @@ module Users end def commencer_page_is_reloaded? - session[:prefill_token].present? && session[:prefill_params_digest] == PrefillParams.digest(params) + session[:prefill_token].present? && session[:prefill_params_digest] == PrefillChamps.digest(params) end def prefill_params_present? - params.keys.find { |param| param.split('_').first == "champ" } + params.keys.find { ['champ', 'identite'].include?(_1.split('_').first) } end def retrieve_procedure @@ -101,10 +101,10 @@ module Users ) @prefilled_dossier.build_default_individual if @prefilled_dossier.save - @prefilled_dossier.prefill!(PrefillParams.new(@prefilled_dossier, params.to_unsafe_h).to_a) + @prefilled_dossier.prefill!(PrefillChamps.new(@prefilled_dossier, params.to_unsafe_h).to_a, PrefillIdentity.new(@prefilled_dossier, params.to_unsafe_h).to_h) end session[:prefill_token] = @prefilled_dossier.prefill_token - session[:prefill_params_digest] = PrefillParams.digest(params) + session[:prefill_params_digest] = PrefillChamps.digest(params) end def retrieve_prefilled_dossier(prefill_token) diff --git a/app/models/concerns/dossier_prefillable_concern.rb b/app/models/concerns/dossier_prefillable_concern.rb index baf440e4a..1b716c6b2 100644 --- a/app/models/concerns/dossier_prefillable_concern.rb +++ b/app/models/concerns/dossier_prefillable_concern.rb @@ -3,11 +3,12 @@ module DossierPrefillableConcern extend ActiveSupport::Concern - def prefill!(champs_attributes) - return unless champs_attributes.any? + def prefill!(champs_attributes, identity_attributes) + return if champs_attributes.empty? && identity_attributes.empty? attributes = { prefilled: true } attributes[:champs_attributes] = champs_attributes.map { |h| h.merge(prefilled: true) } + attributes[:individual_attributes] = identity_attributes assign_attributes(attributes) save(validate: false) diff --git a/app/models/dossier.rb b/app/models/dossier.rb index b68cc94c9..3ba28e16b 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -132,6 +132,7 @@ class Dossier < ApplicationRecord accepts_nested_attributes_for :champs_private accepts_nested_attributes_for :champs_public_all accepts_nested_attributes_for :champs_private_all + accepts_nested_attributes_for :individual include AASM @@ -418,7 +419,6 @@ class Dossier < ApplicationRecord end scope :not_having_batch_operation, -> { where(batch_operation_id: nil) } - accepts_nested_attributes_for :individual delegate :siret, :siren, to: :etablissement, allow_nil: true delegate :france_connect_information, to: :user, allow_nil: true diff --git a/app/models/prefill_params.rb b/app/models/prefill_champs.rb similarity index 99% rename from app/models/prefill_params.rb rename to app/models/prefill_champs.rb index 4237b5bdb..f013c96d4 100644 --- a/app/models/prefill_params.rb +++ b/app/models/prefill_champs.rb @@ -1,4 +1,4 @@ -class PrefillParams +class PrefillChamps attr_reader :dossier, :params def initialize(dossier, params) diff --git a/app/models/prefill_identity.rb b/app/models/prefill_identity.rb new file mode 100644 index 000000000..c4419b094 --- /dev/null +++ b/app/models/prefill_identity.rb @@ -0,0 +1,20 @@ +class PrefillIdentity + attr_reader :dossier, :params + + def initialize(dossier, params) + @dossier = dossier + @params = params + end + + def to_h + if dossier.procedure.for_individual? + { + prenom: params["identite_prenom"], + nom: params["identite_nom"], + gender: ["M.", "Mme"].include?(params["identite_genre"]) ? params["identite_genre"] : nil + } + else + {} + end + end +end diff --git a/spec/models/concern/dossier_prefillable_concern_spec.rb b/spec/models/concern/dossier_prefillable_concern_spec.rb index 649e651ad..11baf2dfb 100644 --- a/spec/models/concern/dossier_prefillable_concern_spec.rb +++ b/spec/models/concern/dossier_prefillable_concern_spec.rb @@ -6,9 +6,11 @@ RSpec.describe DossierPrefillableConcern do let(:dossier) { create(:dossier, :brouillon, procedure: procedure) } let(:types_de_champ_public) { [] } let(:types_de_champ_private) { [] } + let(:identity_attributes) { {} } + let(:values) { [] } subject(:fill) do - dossier.prefill!(values) + dossier.prefill!(values, identity_attributes) dossier.reload end @@ -18,75 +20,107 @@ RSpec.describe DossierPrefillableConcern do end end - context 'when champs_attributes is empty' do - let(:values) { [] } + context "when dossier is for individual" do + let(:procedure) { create(:procedure, :published, :for_individual, types_de_champ_public:, types_de_champ_private:) } + let(:dossier) { create(:dossier, :brouillon, :with_individual, procedure: procedure) } - it "doesn't mark the dossier as prefilled" do - expect { fill }.not_to change { dossier.reload.prefilled }.from(nil) - end - - it "doesn't change champs_public" do - expect { fill }.not_to change { dossier.champs_public.to_a } - end - end - - context 'when champs_attributes has values' do - context 'when the champs are valid' do - let(:types_de_champ_public) { [{ type: :text }, { type: :phone }] } - let(:types_de_champ_private) { [{ type: :text }] } - - let(:type_de_champ_1) { procedure.published_revision.types_de_champ_public.first } - let(:value_1) { "any value" } - let(:champ_id_1) { find_champ_by_stable_id(dossier, type_de_champ_1.stable_id).id } - - let(:type_de_champ_2) { procedure.published_revision.types_de_champ_public.second } - let(:value_2) { "33612345678" } - let(:champ_id_2) { find_champ_by_stable_id(dossier, type_de_champ_2.stable_id).id } - - let(:type_de_champ_3) { procedure.published_revision.types_de_champ_private.first } - let(:value_3) { "some value" } - let(:champ_id_3) { find_champ_by_stable_id(dossier, type_de_champ_3.stable_id).id } - - let(:values) { [{ id: champ_id_1, value: value_1 }, { id: champ_id_2, value: value_2 }, { id: champ_id_3, value: value_3 }] } + context "when identity_attributes is present" do + let(:identity_attributes) { { "prenom" => "Prénom", "nom" => "Nom", "gender" => "Mme" } } it_behaves_like 'a dossier marked as prefilled' - it "updates the champs with the new values and mark them as prefilled" do + it "updates the individual" do fill - - expect(dossier.champs_public.first.value).to eq(value_1) - expect(dossier.champs_public.first.prefilled).to eq(true) - expect(dossier.champs_public.last.value).to eq(value_2) - expect(dossier.champs_public.last.prefilled).to eq(true) - expect(dossier.champs_private.first.value).to eq(value_3) - expect(dossier.champs_private.first.prefilled).to eq(true) + expect(dossier.individual.prenom).to eq("Prénom") + expect(dossier.individual.nom).to eq("Nom") + expect(dossier.individual.gender).to eq("Mme") end end - context 'when a champ is invalid' do - let(:types_de_champ_public) { [{ type: :phone }] } - let(:type_de_champ_1) { procedure.published_revision.types_de_champ_public.first } - let(:value) { "a non phone value" } - let(:champ_id) { find_champ_by_stable_id(dossier, type_de_champ_1.stable_id).id } - - let(:values) { [{ id: champ_id, value: value }] } - - it_behaves_like 'a dossier marked as prefilled' - - it "still updates the champ" do - expect { fill }.to change { dossier.champs_public.first.value }.from(nil).to(value) + context 'when champs_attributes is empty' do + it "doesn't mark the dossier as prefilled" do + expect { fill }.not_to change { dossier.reload.prefilled }.from(nil) end - it "still marks it as prefilled" do - expect { fill }.to change { dossier.champs_public.first.prefilled }.from(nil).to(true) + it "doesn't change champs_public" do + expect { fill }.not_to change { dossier.champs_public.to_a } + end + end + + context 'when champs_attributes has values' do + context 'when the champs are valid' do + let(:types_de_champ_public) { [{ type: :text }, { type: :phone }] } + let(:types_de_champ_private) { [{ type: :text }] } + + let(:type_de_champ_1) { procedure.published_revision.types_de_champ_public.first } + let(:value_1) { "any value" } + let(:champ_id_1) { find_champ_by_stable_id(dossier, type_de_champ_1.stable_id).id } + + let(:type_de_champ_2) { procedure.published_revision.types_de_champ_public.second } + let(:value_2) { "33612345678" } + let(:champ_id_2) { find_champ_by_stable_id(dossier, type_de_champ_2.stable_id).id } + + let(:type_de_champ_3) { procedure.published_revision.types_de_champ_private.first } + let(:value_3) { "some value" } + let(:champ_id_3) { find_champ_by_stable_id(dossier, type_de_champ_3.stable_id).id } + + let(:values) { [{ id: champ_id_1, value: value_1 }, { id: champ_id_2, value: value_2 }, { id: champ_id_3, value: value_3 }] } + + it_behaves_like 'a dossier marked as prefilled' + + it "updates the champs with the new values and mark them as prefilled" do + fill + + expect(dossier.champs_public.first.value).to eq(value_1) + expect(dossier.champs_public.first.prefilled).to eq(true) + expect(dossier.champs_public.last.value).to eq(value_2) + expect(dossier.champs_public.last.prefilled).to eq(true) + expect(dossier.champs_private.first.value).to eq(value_3) + expect(dossier.champs_private.first.prefilled).to eq(true) + end + end + + context 'when a champ is invalid' do + let(:types_de_champ_public) { [{ type: :phone }] } + let(:type_de_champ_1) { procedure.published_revision.types_de_champ_public.first } + let(:value) { "a non phone value" } + let(:champ_id) { find_champ_by_stable_id(dossier, type_de_champ_1.stable_id).id } + + let(:values) { [{ id: champ_id, value: value }] } + + it_behaves_like 'a dossier marked as prefilled' + + it "still updates the champ" do + expect { fill }.to change { dossier.champs_public.first.value }.from(nil).to(value) + end + + it "still marks it as prefilled" do + expect { fill }.to change { dossier.champs_public.first.prefilled }.from(nil).to(true) + end end end end - end - private + context "when dossier is for entreprise" do + let(:procedure) { create(:procedure, :published, types_de_champ_public:) } + let(:dossier) { create(:dossier, :brouillon, :with_entreprise, procedure: procedure) } - def find_champ_by_stable_id(dossier, stable_id) - dossier.champs.joins(:type_de_champ).find_by(types_de_champ: { stable_id: stable_id }) + context "when identity_attributes is present" do + let(:identity_attributes) { { "siret" => "50000123456789", id: dossier.user.id } } + + it_behaves_like 'a dossier marked as prefilled' + + it "updates the dossier user" do + fill + expect(dossier.user.siret).to eq("50000123456789") + end + end + end + + private + + def find_champ_by_stable_id(dossier, stable_id) + dossier.champs.joins(:type_de_champ).find_by(types_de_champ: { stable_id: stable_id }) + end end end diff --git a/spec/models/prefill_params_spec.rb b/spec/models/prefill_champs_spec.rb similarity index 94% rename from spec/models/prefill_params_spec.rb rename to spec/models/prefill_champs_spec.rb index 76952d5c7..82b1bc22d 100644 --- a/spec/models/prefill_params_spec.rb +++ b/spec/models/prefill_champs_spec.rb @@ -1,11 +1,11 @@ -RSpec.describe PrefillParams do - describe "#to_a" do +RSpec.describe PrefillChamps do + describe "#to_a", vcr: { cassette_name: 'api_geo_all' } do let(:procedure) { create(:procedure, :published, types_de_champ_public:, types_de_champ_private:) } let(:dossier) { create(:dossier, :brouillon, procedure: procedure) } let(:types_de_champ_public) { [] } let(:types_de_champ_private) { [] } - subject(:prefill_params_array) { described_class.new(dossier, params).to_a } + subject(:prefill_champs_array) { described_class.new(dossier, params).to_a } context "when the stable ids match the TypeDeChamp of the corresponding procedure" do let(:types_de_champ_public) { [{ type: :text }, { type: :textarea }] } @@ -25,7 +25,7 @@ RSpec.describe PrefillParams do } it "builds an array of hash(id, value) matching all the given params" do - expect(prefill_params_array).to match([ + expect(prefill_champs_array).to match_array([ { id: champ_id_1, value: value_1 }, { id: champ_id_2, value: value_2 } ]) @@ -39,7 +39,7 @@ RSpec.describe PrefillParams do let(:params) { { type_de_champ.to_typed_id_for_query => "value" } } it "filters out the champ" do - expect(prefill_params_array).to match([]) + expect(prefill_champs_array).to match([]) end end @@ -47,7 +47,7 @@ RSpec.describe PrefillParams do let(:params) { { "champ_jane_doe" => "value" } } it "filters out the unknown params" do - expect(prefill_params_array).to match([]) + expect(prefill_champs_array).to match([]) end end @@ -57,7 +57,7 @@ RSpec.describe PrefillParams do let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => "value" } } it "filters out the param" do - expect(prefill_params_array).to match([]) + expect(prefill_champs_array).to match([]) end end @@ -70,7 +70,7 @@ RSpec.describe PrefillParams do let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => value } } it "builds an array of hash matching the given params" do - expect(prefill_params_array).to match([{ id: champ.id }.merge(attributes(champ, value))]) + expect(prefill_champs_array).to match([{ id: champ.id }.merge(attributes(champ, value))]) end end end @@ -84,7 +84,7 @@ RSpec.describe PrefillParams do let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => value } } it "builds an array of hash matching the given params" do - expect(prefill_params_array).to match([{ id: champ.id }.merge(attributes(champ, value))]) + expect(prefill_champs_array).to match([{ id: champ.id }.merge(attributes(champ, value))]) end end end @@ -97,7 +97,7 @@ RSpec.describe PrefillParams do context "when the type de champ is unauthorized (#{type_de_champ_type})" do it "filters out the param" do - expect(prefill_params_array).to match([]) + expect(prefill_champs_array).to match([]) end end end @@ -139,7 +139,7 @@ RSpec.describe PrefillParams do let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => [{ "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value }, { "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value2 }] } } it "builds an array of hash(id, value) matching the given params" do - expect(prefill_params_array).to match([{ id: type_de_champ_child.champ.first.id, value: type_de_champ_child_value }, { id: type_de_champ_child.champ.second.id, value: type_de_champ_child_value2 }]) + expect(prefill_champs_array).to match([{ id: type_de_champ_child.champ.first.id, value: type_de_champ_child_value }, { id: type_de_champ_child.champ.second.id, value: type_de_champ_child_value2 }]) end end @@ -181,7 +181,7 @@ RSpec.describe PrefillParams do let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => [{ "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value }, { "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value2 }] } } it "builds an array of hash(id, value) matching the given params" do - expect(prefill_params_array).to match([{ id: type_de_champ_child.champ.first.id, value: type_de_champ_child_value }, { id: type_de_champ_child.champ.second.id, value: type_de_champ_child_value2 }]) + expect(prefill_champs_array).to match([{ id: type_de_champ_child.champ.first.id, value: type_de_champ_child_value }, { id: type_de_champ_child.champ.second.id, value: type_de_champ_child_value2 }]) end end @@ -217,7 +217,7 @@ RSpec.describe PrefillParams do let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => "value" } } it "builds an array of hash(id, value) matching the given params" do - expect(prefill_params_array).to match([]) + expect(prefill_champs_array).to match([]) end end @@ -229,7 +229,7 @@ RSpec.describe PrefillParams do let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => ["{\"wrong\":\"value\"}", "{\"wrong\":\"value2\"}"] } } it "builds an array of hash(id, value) matching the given params" do - expect(prefill_params_array).to match([]) + expect(prefill_champs_array).to match([]) end end end diff --git a/spec/models/prefill_identity_spec.rb b/spec/models/prefill_identity_spec.rb new file mode 100644 index 000000000..38b964c79 --- /dev/null +++ b/spec/models/prefill_identity_spec.rb @@ -0,0 +1,35 @@ +RSpec.describe PrefillIdentity do + describe "#to_h" do + let(:dossier) { create(:dossier, :brouillon, :with_individual) } + + subject(:prefill_identity_hash) { described_class.new(dossier, params).to_h } + + context "if genre is correct" do + let(:params) { + { + "identite_prenom" => "Prénom", + "identite_nom" => "Nom", + "identite_genre" => "Mme", + } + } + + it "builds an array of hash(id, value) matching all the given params" do + expect(prefill_identity_hash).to match({ prenom: "Prénom", nom: "Nom", gender: "Mme" }) + end + end + + context "if genre is not correct" do + let(:params) { + { + "identite_prenom" => "Prénom", + "identite_nom" => "Nom", + "identite_genre" => "error", + } + } + + it "builds an array of hash(id, value) matching all the given params" do + expect(prefill_identity_hash).to match({ prenom: "Prénom", nom: "Nom", gender: nil }) + end + end + end +end