diff --git a/app/clients/rdv_solidarites_client.rb b/app/clients/rdv_solidarites_client.rb index 740024879..4a6253e17 100644 --- a/app/clients/rdv_solidarites_client.rb +++ b/app/clients/rdv_solidarites_client.rb @@ -13,6 +13,14 @@ def create_user(request_body) ) end + def get_user(user_id) + Faraday.get( + "#{@url}/api/rdvinsertion/users/#{user_id}", + {}, + request_headers + ) + end + def create_user_profiles(user_id, organisation_ids) Faraday.post( "#{@url}/api/rdvinsertion/user_profiles/create_many", diff --git a/app/jobs/inbound_webhooks/rdv_solidarites/process_rdv_job.rb b/app/jobs/inbound_webhooks/rdv_solidarites/process_rdv_job.rb index 2c8b94553..71cde5c2e 100644 --- a/app/jobs/inbound_webhooks/rdv_solidarites/process_rdv_job.rb +++ b/app/jobs/inbound_webhooks/rdv_solidarites/process_rdv_job.rb @@ -112,6 +112,7 @@ def rdv_solidarites_user_ids rdv_solidarites_rdv.user_ids end + # rubocop:disable Metrics/AbcSize def find_or_create_users existing_users = User.where(rdv_solidarites_user_id: rdv_solidarites_user_ids).to_a @@ -119,18 +120,26 @@ def find_or_create_users user.id.in?(existing_users.map(&:rdv_solidarites_user_id)) end - new_users = new_rdv_solidarites_users.map do |user| + new_users = new_rdv_solidarites_users.map do |rdv_solidarites_user| User.create!( - rdv_solidarites_user_id: user.id, - organisations: [organisation], + rdv_solidarites_user_id: rdv_solidarites_user.id, created_through: "rdv_solidarites_webhook", created_from_structure: organisation, - **user.attributes.slice(*User::SHARED_ATTRIBUTES_WITH_RDV_SOLIDARITES).compact_blank + organisation_ids: retrieve_user_organisation_ids(rdv_solidarites_user.id), + **rdv_solidarites_user.attributes.slice(*User::SHARED_ATTRIBUTES_WITH_RDV_SOLIDARITES).compact_blank ) end @users = existing_users + new_users end + # rubocop:enable Metrics/AbcSize + + def retrieve_user_organisation_ids(rdv_solidarites_user_id) + rdv_solidarites_organisation_ids = agents.first.with_rdv_solidarites_session do + call_service!(RdvSolidaritesApi::RetrieveUser, rdv_solidarites_user_id:).user.organisation_ids + end + Organisation.where(rdv_solidarites_organisation_id: rdv_solidarites_organisation_ids).ids + end def participations_attributes_destroyed return [] if rdv.nil? diff --git a/app/models/agent.rb b/app/models/agent.rb index c095aeaf2..5dc21b488 100644 --- a/app/models/agent.rb +++ b/app/models/agent.rb @@ -48,6 +48,14 @@ def department_organisations(department_id) organisations.select { |organisation| organisation.department_id == department_id } end + def with_rdv_solidarites_session(&) + # This ensure Current.rdv_solidarites_client would call the agent rdv_solidarites_client + Current.agent = self + yield + ensure + Current.agent = nil + end + private # This is to make sure an agent can't be set as super_admin through an agent creation or update in the app. diff --git a/app/models/rdv_solidarites/user.rb b/app/models/rdv_solidarites/user.rb index c003f54bc..c65404a2f 100644 --- a/app/models/rdv_solidarites/user.rb +++ b/app/models/rdv_solidarites/user.rb @@ -9,5 +9,15 @@ class User < Base def deleted? email&.ends_with?("@deleted.rdv-solidarites.fr") end + + def organisation_ids + @attributes[:user_profiles].map do |user_profile_attributes| + user_profile_attributes.dig(:organisation, :id) + end.compact + end + + def user_profiles + @attributes[:user_profiles].to_a + end end end diff --git a/app/services/invitations/verify_organisation_creneaux_availability.rb b/app/services/invitations/verify_organisation_creneaux_availability.rb index f59db8d4c..372483a39 100644 --- a/app/services/invitations/verify_organisation_creneaux_availability.rb +++ b/app/services/invitations/verify_organisation_creneaux_availability.rb @@ -2,16 +2,17 @@ module Invitations class VerifyOrganisationCreneauxAvailability < BaseService def initialize(organisation_id:) @organisation = Organisation.find(organisation_id) - # On prend le premier agent de l'organisation pour les appels à l'API RDVSP - Current.agent = @organisation.agents.first @invitations_params_without_creneau = [] @grouped_invitation_params_by_category = [] end def call - process_invitations - process_invitations_params_without_creneau - result.grouped_invitation_params_by_category = @grouped_invitation_params_by_category + # On prend le premier agent de l'organisation pour les appels à l'API RDVSP + @organisation.agents.first.with_rdv_solidarites_session do + process_invitations + process_invitations_params_without_creneau + result.grouped_invitation_params_by_category = @grouped_invitation_params_by_category + end end private diff --git a/app/services/rdv_solidarites_api/retrieve_user.rb b/app/services/rdv_solidarites_api/retrieve_user.rb new file mode 100644 index 000000000..50b80dd24 --- /dev/null +++ b/app/services/rdv_solidarites_api/retrieve_user.rb @@ -0,0 +1,19 @@ +module RdvSolidaritesApi + class RetrieveUser < Base + def initialize(rdv_solidarites_user_id:) + @rdv_solidarites_user_id = rdv_solidarites_user_id + end + + def call + request! + result.user = + RdvSolidarites::User.new(rdv_solidarites_response_body["user"]) + end + + private + + def rdv_solidarites_response + @rdv_solidarites_response ||= rdv_solidarites_client.get_user(@rdv_solidarites_user_id) + end + end +end diff --git a/lib/organisations/destroy_multiple.rb b/lib/organisations/destroy_multiple.rb index b3188597a..a90f4a460 100644 --- a/lib/organisations/destroy_multiple.rb +++ b/lib/organisations/destroy_multiple.rb @@ -46,21 +46,11 @@ def display_organisation_info(organisation) end def organisation_exists_in_rdv_solidarites?(organisation) - with_faked_agent_auth(organisation) do + organisation.agents.first.with_rdv_solidarites_session do RdvSolidaritesApi::RetrieveOrganisation .call(rdv_solidarites_organisation_id: organisation.rdv_solidarites_organisation_id) .success? end end - - def with_faked_agent_auth(organisation) - return yield if Current.agent.present? - - Current.agent = organisation.agents.first - result = yield - Current.agent = nil - - result - end end end diff --git a/lib/users/transfer_referent.rb b/lib/users/transfer_referent.rb index e849d803d..fda975d26 100644 --- a/lib/users/transfer_referent.rb +++ b/lib/users/transfer_referent.rb @@ -10,17 +10,14 @@ def initialize(source_referent_id:, target_referent_id:) def call ReferentAssignation.where(agent: source_referent).find_each do |referent_assignation| - set_current_agent(referent_assignation) - assign_target_and_remove_source_referent(referent_assignation) + referent_assignation.agent.with_rdv_solidarites_session do + assign_target_and_remove_source_referent(referent_assignation) + end end end private - def set_current_agent(referent_assignation) - Current.agent = referent_assignation.agent - end - def assign_target_and_remove_source_referent(referent_assignation) assignation_service = Users::AssignReferent.call(user: referent_assignation.user, agent: target_referent) diff --git a/spec/jobs/inbound_webhooks/rdv_solidarites/process_rdv_job_spec.rb b/spec/jobs/inbound_webhooks/rdv_solidarites/process_rdv_job_spec.rb index 345eddb3f..7eb2f57bc 100644 --- a/spec/jobs/inbound_webhooks/rdv_solidarites/process_rdv_job_spec.rb +++ b/spec/jobs/inbound_webhooks/rdv_solidarites/process_rdv_job_spec.rb @@ -223,18 +223,32 @@ let!(:new_follow_up) do build(:follow_up, motif_category: motif_category, user: new_user) end + let!(:other_rdv_solidarites_organisation_id) { 22_424 } + let!(:other_user_organisation) do + create(:organisation, rdv_solidarites_organisation_id: other_rdv_solidarites_organisation_id) + end before do allow(User).to receive(:create!).and_return(new_user) allow(FollowUp).to receive(:find_or_create_by!) .with(user: new_user, motif_category: motif_category) .and_return(new_follow_up) + + allow(RdvSolidaritesApi::RetrieveUser).to receive(:call) + .with(rdv_solidarites_user_id: user_id1) + .and_return( + OpenStruct.new( + success?: true, + user: OpenStruct.new(organisation_ids: [rdv_solidarites_organisation_id, + other_rdv_solidarites_organisation_id]) + ) + ) end it "creates the user" do expect(User).to receive(:create!).with( rdv_solidarites_user_id: user_id1, - organisations: [organisation], + organisation_ids: [organisation.id, other_user_organisation.id], first_name: "James", last_name: "Cameron", address: "50 rue Victor Hugo 93500 Pantin", diff --git a/spec/services/rdv_solidarites_api/retrieve_user_spec.rb b/spec/services/rdv_solidarites_api/retrieve_user_spec.rb new file mode 100644 index 000000000..27b0f126d --- /dev/null +++ b/spec/services/rdv_solidarites_api/retrieve_user_spec.rb @@ -0,0 +1,53 @@ +describe RdvSolidaritesApi::RetrieveUser, type: :service do + subject do + described_class.call(rdv_solidarites_user_id:) + end + + let(:rdv_solidarites_client) { instance_double(RdvSolidaritesClient) } + let!(:rdv_solidarites_user_id) { 1717 } + + describe "#call" do + let!(:user_attributes) do + { + "id" => 1717, + "first_name" => "Léonard", + "last_name" => "De Vinci" + } + end + + before do + allow(Current).to receive(:rdv_solidarites_client).and_return(rdv_solidarites_client) + allow(rdv_solidarites_client).to receive(:get_user) + .with(rdv_solidarites_user_id) + .and_return(OpenStruct.new(success?: true, body: { "user" => user_attributes }.to_json)) + end + + context "when it succeeds" do + it("is a success") { is_a_success } + + it "calls the rdv solidarites client" do + expect(rdv_solidarites_client).to receive(:get_user) + subject + end + + it "returns the user" do + expect(subject.user.id).to eq(rdv_solidarites_user_id) + expect(subject.user.first_name).to eq("Léonard") + expect(subject.user.last_name).to eq("De Vinci") + end + end + + context "when it fails" do + before do + allow(rdv_solidarites_client).to receive(:get_user) + .and_return(OpenStruct.new(success?: false, body: { error_messages: ["some error"] }.to_json)) + end + + it("is a failure") { is_a_failure } + + it "returns the error" do + expect(subject.errors).to eq(["Erreur RDV-Solidarités: some error"]) + end + end + end +end