diff --git a/.rubocop.yml b/.rubocop.yml index 41ffc3e03..fad8c07b2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -93,6 +93,10 @@ Metrics/MethodLength: RSpec/NestedGroups: Enabled: false +RSpec/SpecFilePathFormat: + Exclude: + - "spec/**/*hubee*" + Naming/VariableNumber: Enabled: false diff --git a/Gemfile b/Gemfile index 40f3e3fa9..6183661a7 100644 --- a/Gemfile +++ b/Gemfile @@ -77,6 +77,11 @@ gem 'ransack' gem 'wicked' gem 'rest-client' +gem 'faraday' +gem 'faraday-gzip' +gem 'faraday-net_http' +gem 'faraday-retry' +gem 'faraday-encoding' group :development, :test do gem 'awesome_print' @@ -101,10 +106,10 @@ group :development do # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md gem 'rack-mini-profiler', '~> 3.3' gem 'rubocop', require: false - gem 'rubocop-rails' - gem 'rubocop-rspec' gem 'rubocop-capybara' gem 'rubocop-factory_bot' + gem 'rubocop-rails' + gem 'rubocop-rspec' gem 'rubocop-rspec_rails' gem 'better_errors' diff --git a/Gemfile.lock b/Gemfile.lock index a8619c1c5..239305ec2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -157,11 +157,18 @@ GEM faraday-net_http (>= 2.0, < 3.4) json logger + faraday-encoding (0.0.6) + faraday + faraday-gzip (2.0.1) + faraday (>= 1.0) + zlib (~> 3.0) faraday-net_http (3.3.0) net-http faraday-net_http_persistent (2.3.0) faraday (~> 2.5) net-http-persistent (>= 4.0.4, < 5) + faraday-retry (2.2.1) + faraday (~> 2.0) ferrum (0.15) addressable (~> 2.5) concurrent-ruby (~> 1.1) @@ -561,6 +568,7 @@ GEM nokogiri (~> 1.8) yajl-ruby (1.4.3) zeitwerk (2.7.1) + zlib (3.1.1) PLATFORMS aarch64-linux @@ -585,6 +593,11 @@ DEPENDENCIES cuprite draper factory_bot_rails + faraday + faraday-encoding + faraday-gzip + faraday-net_http + faraday-retry gaffe good_job (~> 3.99) guard-rspec diff --git a/app/clients/abstract_hubee_api_client.rb b/app/clients/abstract_hubee_api_client.rb new file mode 100644 index 000000000..9081c04aa --- /dev/null +++ b/app/clients/abstract_hubee_api_client.rb @@ -0,0 +1,23 @@ +require 'faraday' + +class AbstractHubEEAPIClient + protected + + def http_connection(&block) + Faraday.new do |conn| + conn.request :retry, max: 5 + conn.response :raise_error + conn.response :json + conn.options.timeout = 2 + yield(conn) if block + end + end + + def consumer_key + Rails.application.credentials.hubee_consumer_key + end + + def consumer_secret + Rails.application.credentials.hubee_consumer_secret + end +end diff --git a/app/clients/abstract_insee_api_client.rb b/app/clients/abstract_insee_api_client.rb new file mode 100644 index 000000000..5b836e6fa --- /dev/null +++ b/app/clients/abstract_insee_api_client.rb @@ -0,0 +1,23 @@ +require 'faraday' + +class AbstractINSEEAPIClient + protected + + def http_connection(&block) + @http_connection ||= Faraday.new do |conn| + conn.request :retry, max: 5 + conn.response :raise_error + conn.response :json + conn.options.timeout = 2 + yield(conn) if block + end + end + + def consumer_key + Rails.application.credentials.insee_consumer_key + end + + def consumer_secret + Rails.application.credentials.insee_consumer_secret + end +end diff --git a/app/clients/formulaire_qf_api_client.rb b/app/clients/formulaire_qf_api_client.rb new file mode 100644 index 000000000..45cf86a64 --- /dev/null +++ b/app/clients/formulaire_qf_api_client.rb @@ -0,0 +1,33 @@ +# :nocov: +class FormulaireQFAPIClient + def create_collectivity(organization:, editor_id: nil) + params = { + siret: organization.siret, + code_cog: organization.code_commune_etablissement, + departement: organization.code_postal_etablissement[0..1], + name: organization.denomination, + status: 'active', + editor: editor_id + } + + http_connection.post("#{host}/api/collectivites", params.to_json) + end + + private + + def host + Rails.application.credentials.formulaire_qf.host + end + + def http_connection(&block) + Faraday.new do |conn| + conn.headers['Content-Type'] = 'application/json' + conn.request :authorization, 'Bearer', -> { secret } + yield(conn) if block + end + end + + def secret + Rails.application.credentials.formulaire_qf.secret + end +end diff --git a/app/clients/hubee_api_authentication.rb b/app/clients/hubee_api_authentication.rb new file mode 100644 index 000000000..e7e0a6819 --- /dev/null +++ b/app/clients/hubee_api_authentication.rb @@ -0,0 +1,29 @@ +# :nocov: +class HubEEAPIAuthentication < AbstractHubEEAPIClient + def access_token + http_connection.post( + auth_url, + 'grant_type=client_credentials&scope=ADMIN', + { + 'Authorization' => "Basic #{encoded_client_id_and_secret}" + } + ).body['access_token'] + end + + private + + def auth_url + Rails.application.credentials.hubee_auth_url + end + + def encoded_client_id_and_secret + Base64.strict_encode64("#{consumer_key}:#{consumer_secret}") + end + + def http_connection(&block) + @http_connection ||= super do |conn| + conn.response :json + yield(conn) if block + end + end +end diff --git a/app/clients/hubee_api_client.rb b/app/clients/hubee_api_client.rb new file mode 100644 index 000000000..bb90c4f46 --- /dev/null +++ b/app/clients/hubee_api_client.rb @@ -0,0 +1,131 @@ +# :nocov: +class HubEEAPIClient < AbstractHubEEAPIClient # rubocop:disable Metrics/ClassLength + class NotFound < StandardError; end + class AlreadyExists < StandardError; end + + def find_or_create_organization(organization, email_demandeur = nil) + find_organization(organization) + rescue NotFound + create_organization(organization, email_demandeur) + end + + def find_organization(organization) + http_connection.get("#{host}/referential/v1/organizations/SI-#{organization.siret}-#{organization.code_commune_etablissement}").body + rescue Faraday::ResourceNotFound + raise NotFound + end + + def create_organization(organization, email) + http_connection.post( + "#{host}/referential/v1/organizations", + { + type: 'SI', + companyRegister: organization.siret, + branchCode: organization.code_commune_etablissement, + email:, + name: organization.denomination, + country: 'France', + postalCode: organization.code_postal_etablissement, + territory: organization.code_commune_etablissement, + status: 'Actif' + }.to_json, + 'Content-Type' => 'application/json' + ).body + rescue Faraday::BadRequestError => e + raise AlreadyExists if already_exists_error?(e) + + raise + end + + def create_subscription(authorization_request, organization_payload, process_code, editor_payload = {}) + subscription_payload = find_or_create_inactive_subscription(authorization_request, organization_payload, process_code) + activate_subscription(authorization_request, subscription_payload, editor_payload) + subscription_payload + end + + def find_subscription(_authorization_request, organization_payload, process_code) + request = http_connection { |conn| conn.request :gzip }.get( + "#{host}/referential/v1/subscriptions", + companyRegister: organization_payload['companyRegister'], + processCode: process_code + ) + request.body.first + end + + protected + + def host + Rails.application.credentials.hubee_api_url + end + + def already_exists_error?(faraday_error) + faraday_error.response[:body]['errors'].any? do |error| + error['message'].include?('already exists') + end + end + + def http_connection(&block) + super do |conn| + conn.request :authorization, 'Bearer', -> { HubEEAPIAuthentication.new.access_token } + yield(conn) if block + end + end + + private + + def activate_subscription(authorization_request, subscription_payload, editor_payload = {}) # rubocop:disable Metrics/AbcSize + subscription_id = authorization_request.extra_infos['hubee_subscription_id'] + return if subscription_id.blank? + + payload = subscription_payload.with_indifferent_access.merge({ + status: 'Actif', + activateDateTime: DateTime.now.iso8601, + accessMode: 'API', + notificationFrequency: 'Aucune' + }.with_indifferent_access) + + payload.delete('id') + payload.delete('creationDateTime') + payload.merge!(editor_payload.with_indifferent_access) + + http_connection.put( + "#{host}/referential/v1/subscriptions/#{subscription_id}", + payload.to_json, + 'Content-Type' => 'application/json' + ).body + end + + def create_inactive_subscription(authorization_request, organization_payload, process_code) # rubocop:disable Metrics/AbcSize + http_connection.post( + "#{host}/referential/v1/subscriptions", + { + datapassId: authorization_request.external_id.to_i, + notificationFrequency: 'Aucune', + processCode: process_code, + subscriber: { + type: 'SI', + companyRegister: organization_payload['companyRegister'], + branchCode: organization_payload['branchCode'] + }, + email: authorization_request.demandeur.email, + status: 'Inactif', + localAdministrator: { + email: authorization_request.demandeur.email + }, + validateDateTime: DateTime.now.iso8601, + updateDateTime: DateTime.now.iso8601 + }.to_json, + 'Content-Type' => 'application/json' + ).body + rescue Faraday::BadRequestError => e + raise AlreadyExists if already_exists_error?(e) + + raise + end + + def find_or_create_inactive_subscription(authorization_request, organization_payload, process_code) + create_inactive_subscription(authorization_request, organization_payload, process_code) + rescue HubEEAPIClient::AlreadyExists + find_subscription(authorization_request, organization_payload, process_code) + end +end diff --git a/app/clients/insee_api_authentication.rb b/app/clients/insee_api_authentication.rb new file mode 100644 index 000000000..85154071c --- /dev/null +++ b/app/clients/insee_api_authentication.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class INSEEAPIAuthentication < AbstractINSEEAPIClient + def access_token + http_connection.post( + 'https://api.insee.fr/token', + 'grant_type=client_credentials', + { + 'Authorization' => "Basic #{encoded_client_id_and_secret}" + } + ).body['access_token'] + end + + private + + def encoded_client_id_and_secret + Base64.strict_encode64("#{consumer_key}:#{consumer_secret}") + end +end diff --git a/app/clients/insee_sirene_api_client.rb b/app/clients/insee_sirene_api_client.rb new file mode 100644 index 000000000..488ca977f --- /dev/null +++ b/app/clients/insee_sirene_api_client.rb @@ -0,0 +1,15 @@ +class INSEESireneAPIClient < AbstractINSEEAPIClient + def etablissement(siret:) + http_connection.get( + "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{siret}" + ).body + end + + protected + + def http_connection + super do |conn| + conn.request :authorization, 'Bearer', -> { INSEEAPIAuthentication.new.access_token } + end + end +end diff --git a/app/interactors/datapass_webhook/adapt_v2_to_v1.rb b/app/interactors/datapass_webhook/adapt_v2_to_v1.rb index 7a4dc7f91..3130b36e8 100644 --- a/app/interactors/datapass_webhook/adapt_v2_to_v1.rb +++ b/app/interactors/datapass_webhook/adapt_v2_to_v1.rb @@ -1,6 +1,7 @@ class DatapassWebhook::AdaptV2ToV1 < ApplicationInteractor def call context.event = context.event.sub('authorization_request', 'enrollment') + context.authorization_request_data = generic_data.dup context.data = build_data end @@ -21,7 +22,8 @@ def build_data 'previous_enrollment_id' => nil, 'scopes' => generic_data['scopes'].index_with { |_scope| true }, 'team_members' => build_team_members, - 'events' => [] + 'events' => [], + 'service_provider' => context.data['service_provider'] } } end diff --git a/app/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity.rb b/app/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity.rb new file mode 100644 index 000000000..c2c3600c2 --- /dev/null +++ b/app/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity.rb @@ -0,0 +1,14 @@ +class DatapassWebhook::APIParticulier::CreateFormulaireQFCollectivity < ApplicationInteractor + delegate :authorization_request, to: :context + delegate :organization, to: :authorization_request, private: true + + def call + FormulaireQFAPIClient.new.create_collectivity(organization:, editor_id:) + end + + private + + def editor_id + authorization_request.extra_infos.dig('service_provider', 'id') + end +end diff --git a/app/interactors/datapass_webhook/api_particulier/create_hubee_organization.rb b/app/interactors/datapass_webhook/api_particulier/create_hubee_organization.rb new file mode 100644 index 000000000..0cda5568d --- /dev/null +++ b/app/interactors/datapass_webhook/api_particulier/create_hubee_organization.rb @@ -0,0 +1,27 @@ +class DatapassWebhook::APIParticulier::CreateHubEEOrganization < ApplicationInteractor + delegate :authorization_request, :hubee_organization_payload, to: :context + + def call + context.hubee_organization_payload = find_or_create_organization_on_hubee + save_hubee_organization_id_to_authorization_request + end + + private + + def build_hubee_organization_id + "SI-#{hubee_organization_payload['companyRegister']}-#{hubee_organization_payload['branchCode']}" + end + + def find_or_create_organization_on_hubee + hubee_api_client.find_or_create_organization(authorization_request.organization, authorization_request.demandeur.email) + end + + def hubee_api_client + @hubee_api_client ||= HubEEAPIClient.new + end + + def save_hubee_organization_id_to_authorization_request + authorization_request.extra_infos['hubee_organization_id'] = build_hubee_organization_id + authorization_request.save! + end +end diff --git a/app/interactors/datapass_webhook/api_particulier/create_hubee_subscription.rb b/app/interactors/datapass_webhook/api_particulier/create_hubee_subscription.rb new file mode 100644 index 000000000..86779ed05 --- /dev/null +++ b/app/interactors/datapass_webhook/api_particulier/create_hubee_subscription.rb @@ -0,0 +1,52 @@ +class DatapassWebhook::APIParticulier::CreateHubEESubscription < ApplicationInteractor + delegate :authorization_request, :hubee_organization_payload, :hubee_subscription_payload, to: :context + + def call + context.hubee_subscription_payload = create_subscription_on_hubee + save_hubee_subscription_id_to_authorization_request + end + + private + + def create_subscription_on_hubee + hubee_api_client.create_subscription(authorization_request, hubee_organization_payload, process_code, editor_payload) + end + + def editor_organization + @editor_organization ||= Organization.new(service_provider['siret']) + end + + def editor_payload + return {} unless editor_subscription? + + { + delegationActor: { + branchCode: editor_organization.code_commune_etablissement, + companyRegister: editor_organization.siret, + type: 'EDT' + }, + accessMode: 'API' + } + end + + def editor_subscription? + service_provider['type'] == 'editor' + end + + def hubee_api_client + @hubee_api_client ||= HubEEAPIClient.new + end + + def process_code + 'FormulaireQF' + end + + def save_hubee_subscription_id_to_authorization_request + authorization_request.extra_infos['hubee_subscription_id'] = hubee_subscription_payload['id'] + authorization_request.save! + end + + def service_provider + @service_provider ||= Hash(authorization_request.extra_infos['service_provider']) + end +end diff --git a/app/interactors/datapass_webhook/create_or_prolong_token.rb b/app/interactors/datapass_webhook/create_or_prolong_token.rb index cf67e2202..d1c7530cc 100644 --- a/app/interactors/datapass_webhook/create_or_prolong_token.rb +++ b/app/interactors/datapass_webhook/create_or_prolong_token.rb @@ -1,6 +1,11 @@ class DatapassWebhook::CreateOrProlongToken < ApplicationInteractor + before do + context.modalities ||= %w[params] + end + def call return if %w[approve validate].exclude?(context.event) + return if context.modalities.exclude?('params') token = create_or_prolong_token diff --git a/app/interactors/datapass_webhook/find_or_create_authorization_request.rb b/app/interactors/datapass_webhook/find_or_create_authorization_request.rb index c8c7ef392..3c968ec07 100644 --- a/app/interactors/datapass_webhook/find_or_create_authorization_request.rb +++ b/app/interactors/datapass_webhook/find_or_create_authorization_request.rb @@ -83,10 +83,17 @@ def authorization_request_attributes ).merge(authorization_request_attributes_for_current_event).merge( 'last_update' => fired_at_as_datetime, 'previous_external_id' => context.data['pass']['copied_from_enrollment_id'], - 'api' => context.api + 'api' => context.api, + 'extra_infos' => extra_infos_with_service_provider ) end + def extra_infos_with_service_provider + context.authorization_request.extra_infos.merge({ + 'service_provider' => Hash(context.data.dig('pass', 'service_provider')) + }) + end + def authorization_request_attributes_for_current_event authorization_request_attributes_for_current_event = {} diff --git a/app/interactors/datapass_webhook/schedule_create_formulaire_qf_resources_job.rb b/app/interactors/datapass_webhook/schedule_create_formulaire_qf_resources_job.rb new file mode 100644 index 000000000..d566d84ac --- /dev/null +++ b/app/interactors/datapass_webhook/schedule_create_formulaire_qf_resources_job.rb @@ -0,0 +1,8 @@ +class DatapassWebhook::ScheduleCreateFormulaireQFResourcesJob < ApplicationInteractor + def call + return unless context.event == 'approve' + return unless context.modalities.include?('formulaire_qf') + + CreateFormulaireQFResourcesJob.perform_later(context.authorization_request.id) + end +end diff --git a/app/jobs/create_formulaire_qf_resources_job.rb b/app/jobs/create_formulaire_qf_resources_job.rb new file mode 100644 index 000000000..b60c13883 --- /dev/null +++ b/app/jobs/create_formulaire_qf_resources_job.rb @@ -0,0 +1,7 @@ +class CreateFormulaireQFResourcesJob < ApplicationJob + def perform(authorization_request_id) + authorization_request = AuthorizationRequest.find(authorization_request_id) + + DatapassWebhook::CreateFormulaireQFResources.call(authorization_request:) + end +end diff --git a/app/models/authorization_request.rb b/app/models/authorization_request.rb index c28ca94fc..d9afc014e 100644 --- a/app/models/authorization_request.rb +++ b/app/models/authorization_request.rb @@ -76,6 +76,10 @@ def most_recent_token has_one :contact_technique, through: :contact_technique_authorization_request_role has_one :contact_metier, through: :contact_metier_authorization_request_role + def organization + @organization ||= Organization.new(siret) + end + def contacts_no_demandeur contacts.reject { |user| user == demandeur } end diff --git a/app/models/organization.rb b/app/models/organization.rb new file mode 100644 index 000000000..d3bb2917f --- /dev/null +++ b/app/models/organization.rb @@ -0,0 +1,37 @@ +class Organization + attr_reader :siret + + def initialize(siret) + @siret = siret + end + + def denomination + unite_legale_insee_payload['denominationUniteLegale'] + end + + def code_commune_etablissement + adresse_etablissement_insee_payload['codeCommuneEtablissement'] + end + + def code_postal_etablissement + adresse_etablissement_insee_payload['codePostalEtablissement'] + end + + private + + def adresse_etablissement_insee_payload + etablissement_insee_payload['adresseEtablissement'] + end + + def etablissement_insee_payload + insee_payload['etablissement'] + end + + def unite_legale_insee_payload + etablissement_insee_payload['uniteLegale'] + end + + def insee_payload + @insee_payload ||= INSEESireneAPIClient.new.etablissement(siret:) + end +end diff --git a/app/organizers/datapass_webhook/api_particulier.rb b/app/organizers/datapass_webhook/api_particulier.rb index b6076ebc1..f5328703c 100644 --- a/app/organizers/datapass_webhook/api_particulier.rb +++ b/app/organizers/datapass_webhook/api_particulier.rb @@ -8,6 +8,8 @@ class APIParticulier < ApplicationOrganizer } context.api = 'particulier' + context.authorization_request_data ||= {} + context.modalities = context.authorization_request_data['modalities'].presence || %w[params] end organize ::DatapassWebhook::FindOrCreateUser, @@ -17,6 +19,7 @@ class APIParticulier < ApplicationOrganizer ::DatapassWebhook::RefuseCurrentAuthorizationRequest, ::DatapassWebhook::RevokeCurrentToken, ::DatapassWebhook::UpdateMailjetContacts, + ::DatapassWebhook::ScheduleCreateFormulaireQFResourcesJob, ::DatapassWebhook::ExtractMailjetVariables, ::DatapassWebhook::ScheduleAuthorizationRequestEmails, ::DatapassWebhook::APIParticulier::NotifyReporters diff --git a/app/organizers/datapass_webhook/create_formulaire_qf_resources.rb b/app/organizers/datapass_webhook/create_formulaire_qf_resources.rb new file mode 100644 index 000000000..3d26751cb --- /dev/null +++ b/app/organizers/datapass_webhook/create_formulaire_qf_resources.rb @@ -0,0 +1,18 @@ +class DatapassWebhook::CreateFormulaireQFResources < ApplicationOrganizer + organize DatapassWebhook::APIParticulier::CreateHubEEOrganization, + DatapassWebhook::APIParticulier::CreateHubEESubscription, + DatapassWebhook::APIParticulier::CreateFormulaireQFCollectivity + + around do |interactor| + interactor.call + rescue StandardError => e + Sentry.set_context( + 'DataPass webhook: create FormulaireQF resources', + payload: { + authorization_request_id: context.authorization_request.id + } + ) + + Sentry.capture_exception(e) + end +end diff --git a/config/credentials/production.yml.enc b/config/credentials/production.yml.enc index 876d33cf9..224505042 100644 --- a/config/credentials/production.yml.enc +++ b/config/credentials/production.yml.enc @@ -1 +1 @@ -tv7dkgECrEHO7XjFVI+uBHMKL+R7IMLx6Gu8uYD2JEp6FH1m9lq9L6AySYlAHV9VqZhkLEgtSX3s69y4c2/tssBu/xxGD8dFhUL1vx7ebYxEM5Wjz1Kv4wLF+YEgf8MziyPnQHCH1HsWwfa2JrF9SHCThkUhADeJOU+FU+TlDbnnAxMMRQm2OKQo9/1tUrhoK+gGHZD9zOuB1UdKe49n2TxZfbI7wss29n9L/vWaiyVE8DS4DWe9PZj9c0HjCdToUl0Do7PwQNHw7COW26cqmGxZ2lEq3SCwLlLpWFzSz8HJUhTdElVpf8oPm18aepQEqeTnO+wG+PFp9B6Ty/wWEM2qVAOBifudBm8Th3eeHPlYtP33IUF2up0fu6uQHv57M0kN6dBvMD82S4IyQIjI89TWq2Y4/XL2nYz3RhqBkavskfxT50fLhfsRS3I7FAjNT4MezKOP6dG+1xiJpAjO+Aji3vkK3R0h6s4NIC6UtRYhJbASoK0bDInh0T+FZ12KvsUeXpWaCOA6LNpKAoPHahRZWG85yqxfddtfDw2HLDQtYyYJ7NPT0whMT9g01XFZh7IRoTXNUHJhZfo2Nr9hGJlZn6jZ74x2ucE4Qd9oS4OI4bTv/ZTc6BuALSLU0RfqHsW8EbYZn8j1DFdtDHmRLBRhQ8pbTqIEHX2FI72FgM7I0a6Ba6vseC01tQwSsVkr1M3bhFUHMkGc28C7vK680T9J7oNhE6pQq8FqnPDuQuO+ZOjLiV+Meuo450EAqFuppCrfjR4xuIUh+jE6wr9lmtakYkFU8BrtC7v5FcrRNp1IT9bYcUl8NE8JtpKWqXfM46/e32b8yqRsK9aUd3UdPtXLDT/LxHlqn1R3j76+RSE89WQQBwqUTVjw23AZt3IKjN87P7SpBYY6caDAgRewv+2BS7BYngP0fYIBBpmg9jKX4TvvJuULiH+tU9+iIL6hLg7PNQRim7t9WusLDKb/cSCacB9tvE5wS8L7ohmUzjZAW1yx04DfWJA2ejvUhToAaQEBerPRIj5/GvonmuSL6XDGzDJzipMmHg4gYQ/PhJHghJzdIOFZhYhEobNbNYGYK1rOUkdHJbxu0EMlVqEt8PnVs1JJavkHx5ms2GgQ9aO3E+1Uz0BhN7oX9SxE7WU54BVQOWiEhEp6ctobDUJKYSy+mZMP3G7fa/+8JkmjKkxSaP+SG48O73AzkS/AnC6mHOK38JRyK1/Wcj1gi4MJGJEQ90FuRjKUdlABbk3Kyx0FznrRhrGrkqV2V5H+D7XgeG5SrCVXJFiysuPk40j1dXofoulBE4POi0GVvTQTmU+s0XmIIrEF2khbASQ3TmBfOM5VS2+A88wPCVRUrWWO5bTAMbpfd0EO9hOZz5uuOIo2JP7GkC83w5pSz/JRdsbd/Ra1FLpb4/GVk5X+1KRuIn50izxue9nN7i6P4/JgBiEDBBvKVC/WJXbjH6vbX2l6v8NCYJxSoj5AeRiAPKfta0lONPzMaBZCs8tyLGu1BHZ4LlTdUv4BfyyyBXvd21G52g6zATDX5oEb9nBoELgjhZLPTSyNcsbinQfLZ1BW+QHEUabqjgj+VZwGXKiWpzHNMdl06jy8QLUK+4AKgyB+oighsQoCq1JT0+prowqG/5Fim3HkDn80rN0MtWJXVT9cQP4ac73feJqP2UPG05WeudLIzO8V2cZAYbHvsrujE2XDx2Vpe1kz6AmnRfSQJj/VfBHMM1uUSv3EqiE9N/DdHXQTrciX0wXgWXOEEhCUsK5WmOGQAWfpEBZTkCHclrYOLkTa4Cb+zyXxGzmCI9RMmbWVpoK+OBjtrZmb9nmRo/LlhXRcWfga1IiLxAfqQN6CaXo1RrG8ph2GVGs+v5Z9BA78hz5Hbo/wUBv7NwkujEwz4XkDo/B0nbSJKOZzD9PJPRPNi1eNAg7sUCypH/7XXcuDCwlo064I+O3t9IxxBud7cXV11If+zVw/MYZy42Ucv77hyM19nBO8rddhGVUJj1oizzaIDJ8/lzEHXuRPre5RxqBKg2t3uhBcqwzIpvKYqwGtsklF/iQlKm6nDM+ZV1UgKz/F2kolQLHdoAf/sQSxsoPRl691r4kQXECcXeZqTP+3d1DnvNXTafBLf5Gvi9fB3VcaroDr80BbwpUrNbVTBLFm9JCO/yzDN0hvhchxk0V339DSOl/uL3tbK0qyOqiwl2hDwlcERxJZa+xdliam66Jn1WjUwrt49Ai5dKAEauQpIk40V91g1T/T/6RQDKnZzKO8prcug5NFLA/LgXzoYE/2pH+5O3PnD6C2rz1BxpsoYHetn2mjqzubsFPe9VX1AEBD2FlteZtGRFq64NByAowKqQwXUJ5RmwcN+JH/E/WZp6ZbZJES2tJwRf8eTpusU7ig1V0HkpBsqAMNQqYiCuLHBmttOPcOImEDHYCSLkxWgxrm47YMimhvtfQNmV1GPrDpvyap5FwfSqMHgmfQFR8tJla7L0I5PMt/DvQTtwIe9ch1pZ/EfYVnbQuCcJMqWowsXxutZAyhqUFU1X+sVUkmas6GY7wc3/yvxhSSpDiV18qebfUnsNQ4cnVapybVa0SgxOKx2WEHikcncJauGQcY2oW7ZugLE4mvOWNlV6GGodhj8vyyrfo1oYtUX9oXXhiFF0SZr+/ZpmDQYNoA9rpd+nCQbmzTy9BzdAYFDaHx51bJWdHZmXZ5reXwKPU39LmrEbZh5mU5rHpVGJQ1NgCt1mrMoCinJ0zUeuZFRzJbYcfiI3rzmaNVujwbzWXLc8tXf8i2cFiNerdRozpVXUxcKX8hdmxp3F7d/xK4OoSj8Nve7A4JMpnc640XX7gyGmoXwn1qZLhFEpexDlB6Sy7M57mzbGcYlpg/DkeOfMQP8CCU3GNLskQdgNntgznRrs2BSBLJ1AqbC2ZuclBA32sMwGVLPYkL5PzwD5YXiLdpIAGW6pYIm4Kl8WSptX0lWZ79i5LLdUn9gjd3X5LqPj4eh2TzEySiS46jBjE86L9pvEiCr3o0trZ52m49Lk+SoyQB/D/Rc5qT9JtfoI1qAaV10cVJAIuW0Ww5o21W+vGytOVjgBND1u3Ktvuf0gpUvm8oNOgy/OfrT1djXNqqEOd3q1ZWinxlKQpwfPQ63DHbVvZsOxUhsMAXFUJyKHisIakvYouBC6891k/6rhr6yNELjHYS+4dA2OTqai0+BPb0CDha47Mo8aHiSXngVai/r6fNl6AUhblPEKG7evi3y1jcNdRHWLyQBwnMYTgn+BLRJM49LNLLXdwXZP6PXRsyDtkf8oKuWKdJFTXv9m+NQJnMOBgUyX3WxvlOqd/p8VSCJlb8Yl3dqh2O/VrA1FMAXuPPYJKM81qBOjLbKG8+j2REGhSQbRNTLF2eBuY5aQUVdfZ9vN9C12pW6xp0fYP9S3I9GYHi8LLJg0QQpuq9F7Q8dB0OglrnYysqKCb7GtOHhxgILqhBvfWvIZ0N65o9tFDCUc2GDNlzK6URLCRWp4tLGZITv6c0i4onYM15GywV/rTyku7updCrjZcImCfeQvtE73vTpLKR86+I0ix2w2qbtx8tNZA78iW/AOixIeBUcVQ1S/cSHuGYQAKMc3mBwTe7FFCfIlfhwPKnXMeWMEBjaQ4o8YHf0i1IgiwHsKCTRT3B5WVCF/ENkuMfQflyf1nfOE4BLGbgXhzM49OnqRbEX8kDNO/clx1uNYQRC/1ruDM7+Y7HxYeMb1UCfWHStCWMBD0hOWdUiVloDPbj6QyJoq9OuDTcn1Y3xs6FU/VdPc2aZeyL2hnSXf+DQBH3sBArtB4y76oUqgFqtYrj9YZHiq7FOp1irDjWuZ6ITxbAAlhghZcFurlc9RQPs9z1zyfqkllAQPc0V600tM/OE8kEaVg0aV5jJA+XLe+OvFsp8DM4W8Nkrks1BSEd94r4wRtyxv+vDgejXqWO3HwdNEWpOXkhtSXzuxfAj5FkItj/HKaxDS6tKLVnNnz8g1VamEdREYCkHwjNg5WwXCQQkhW7Io/VN6jwyGOAuMvBP8U5CtEmR2Ej0OmxTagxgLv9fzQA/wuuYJWzDSdlPk3LPCWct6L4xkxP8+RqjD7HjxclcyPRKYTDi1eS3i7z9JkFEpO7r2hSUE9YyZEmwudgvYAKY/ZDNJGrpuOoMer7XSDS4TWwPQ0HEXcT4aJU9oKQ3Ce5H9QMhh+R3NhG8CZPymoVA0Si2jFCmwDTmMb/+7563a20STO6Qq/xCLpHLIDWQKjcS/VpA2n7GUETh+vcjX/yDxTJrcj5niE/i0Bcf2r8ibPDaLqBbB9UO1oL0YGMNw9/jBKS+SKs65c3UrYtlUwGVJGl9JcxSPZTjNKmw4acfQZ73QaxmfUq3gDofXdshq02xL1ATg==--h4gZdNZdw5pFYh0p--MeT3D9sz1WMJUcSe1jGZ4Q== \ No newline at end of file +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--tgGTVwo/lU3jhCuB--9N1N4TlMV/Rw+Vk07mxh/w== diff --git a/config/credentials/sandbox.yml.enc b/config/credentials/sandbox.yml.enc index a9fa2cd98..72a5512a2 100644 --- a/config/credentials/sandbox.yml.enc +++ b/config/credentials/sandbox.yml.enc @@ -1 +1 @@ -WXXMzkxUMGPk9DyWjuIoBM7ei3Qxi1M3mgKXW0jpEmW3DD7SJ4CVm7VnfuerOq59nDBeugTdY34h6DWSXQQ+d/ZpgxDDBX/TASWj5tBYjjYu+g7bYGsvXwYnGNJd7xnAD8zCndBAhwfQn7TXnCzhCCytrNvLen61+scndaPRNv3ipIC/ct+NlsogiEyB/3XXntZhm7Seu/2UdO5VNSFzQlW03m+6r226Tv/17oMPR8+ZF6z/jY+igJBhOQIAD8pKfSau+ju/mSJMVdKCkM+AYWQKiDHYwS5LJIKsdK3sRIIuXbDeijo2EgiwV9HniUbloD6ElDpTf0VAj4s30ZYxIJGfy0S4ZIOsmummBk+jUEoi3GqwFMNpgMRwpVVTnDdI+opVOk6trSf0F9dv2sD8j20jXBR1lrSLN/7RXgpd+iunivJ1191AxdLsDuz/nFkUye1fGDwc/lM6BaO3/ADbFVJTpg3ro7NvUt22T9uVq5X87jRLbJ2kNkKhtiz+cAaeEp5M++Lxl9kWTDgHOQY5p/YhZnuyri7yschIqyKU3KOGMxOPns+/BOpSRS+XrJwmXxRlYGqSQKgy+ryI8XC3k97/p8tSuaYbPQr9CN1x18TPxQ5quLn9rvjYVjlyOuF2bwxV3hHiqECn+y/IYTx6Mzagk1wLeixYb8Xwgu270DzyEooac15kAfGJxeeCer1Ao/UJpahJFOsc31xKeleufyUfducCO4jFEcsipVCBAvMWY9XeFGSv0byE5CO6GkFNwZIvArnKWahGkDBg7cMehp6QdvwuzxJCDUeZLXg2ESdXoFHgVFpk/o4wRBcrC1N1bNbcwhLasKisSxN02y81qeyCxuVc3cfvdPz4MPLsIRRqUzIupayramNsUI83+35+JhIA3UGCCIxt77btVFg8c77untKWHEVc5hquN1/KofSBHYAcL7C+Ja//nGCSSyPQd8dU15V1hMzA4ts8re07eEPFxkozpGMviDLO5w1iDuKb0nf5A3V+5sFhakMzL4Pdy269m43vuUXU+teop0q+nSt2/TOTqd524FU28ZTpTgR37fdp8brdKA5PrfguPJfTHWLBoo6o7mQxEcyEyLIypQe713klLK1fp6IJsKw1GwT9CJI7PQppIxCGqPKIP9uDtVNvKG0UcX05L+L4E9k88j5i7ZuCvb0P92bbMLmld1Thsx2OdGCbCDjdnDdgAJFFRDSdZmL8GbaZHRNhojQ5Q0UEJrs7P+ow+2pfl+mfxn1H8cALc6uceC+MpZqyyNp+CEzDL/gVdugmuXm5BeFKOTwomn5aZ5uZ/2NcobHyym9DyLqFhUjalN3kaR4eAGRBy0ey+SYuaSHVbLLwenKw2KPWQeitadbjOyFowwFOU5ZTnRqC5JedBLq8wYCGqdihmT0+GfvL8KMU8bE2AUSXBz4RdUdIPyeqXdXZT+L79Xf0T63FrZjSTP8AqyZh+0xrNhVycWFXGRPN3GgfisEFI9+fFSWsMqqn+1g98btMfQMBixd2H47ZXWjgpbULHVjbE7nGiaa4Dauwr72SuGvU608B2EZcgdF9SrpXCjwarJz5ntdAc3erS/I=--cnVnlQsoPPSaGR9D--QaXFsqNdQvQ/Hw7vpmCLuw== \ No newline at end of file +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--pR1hfy5qn2BKDerm--YWGU6sMyb9WOczKW30enzA== \ No newline at end of file diff --git a/config/credentials/staging.yml.enc b/config/credentials/staging.yml.enc index 0a007e35d..c9aedb5a2 100644 --- a/config/credentials/staging.yml.enc +++ b/config/credentials/staging.yml.enc @@ -1 +1 @@ -9JD9jNdU7DCiqe0LAHSWFuB7ANmPinU32C0Fv1YkQhItRWtWKcGo+fsbv/Z/T2UbwKB8CMBRM2zwL4sKedcWBw+uTACeA/86k1kQJXuLZO/X3XuTAf2jOLLLo11YLXBYthN2tkXl+qXH2dyOvZxjSsAc+pKKe1VZkl7+XIgikEgXZw2lSjf7RV9XS3i/QwO63XkedHuTbLTSPh4U9pCsa8oFALQzVyenBiLtgi2PIbFXdYpzdd5ZlDinWGFIz7rg2qIe2s1q0bVFjMSCi+7n7yLtS0yZy7jYVfvXBh2bOrfKGd8L+9akOG1nhWu7FaY/4wxxnlaTeN9uBqZkbVOPpecE35MYmjhpuw+PCaSiussADICqutiSPkqXpUtZHPYJ2EGcT1p6aRBU9ZQzs2eywVOp5rcbuKVVnUdEb6JLNt81OLiG0Mh3efq2q9bDTT9ygBReRqFVNr/sNq4wWPTb1dBbua8q44zJmDzL659mJZWlyPZjjIga+vrq/KfYQ7XIluZk17Fd4ESJ09a8AAYvDF1alzWsEs4ne2/SZGZHlDczrQEb4kq12h2PwKx5PNxdJQudrCR3acp8D6gjHr0XOGHcbH6jwaWe2VLXp1ovx4pf6su9JsvhJ+2wdPyeBof4vLGPhakScor8BVefVo88yYGUFvXV43NGIwbHlJYlUqv60jV17stiwKhVddUDyEdL34DJqCMYn1PuEsvAIKhVVKKPV/MPZT2PXto0QU5eD/167caa5JFMSYxNvUfIrgRAEtvhBJlnSB5psKi8DVIWt6rFPHDQoykVl6Ow5tkJCheXnggsrZX/a+SzyC6nqWXf9Dw1p1d7lIaaH+bSuiugBZTAZj5MmE9t/yOJMWmpN8+OXf4CErlcFIlphg3EBP8TTK8A44dMEzAvqABcpyCAsBi+spOg55lpmJAdbWwm+OtQ1fgOFS0CrShCIMs0gAOAaZQQKLgVaWHx93y1Fx0e5qP8B+CzxKBjZY1YgCTfPORGD71VZhOhA0X7zme9Ot0Y1DmQ04aQvqRmACrEN95pyqYZ7FWFFG1Mzy2VGb7INpeiXBaWPpaoWCdOkh7SBB+Foj6klXY1hbB+jPaxP4jqsOMheVXBLMRcJCps1Ax+mTqiMN9OHi0ibT2kGS+Ir/CuLtHTPTMD1mkHQN4PNH7HTemCdk0Fi87PAYtdG/f4IqlFAvPI5VSp04wDv1vN9iSxSVOjO6n2DULcAjhT22DHU87Lb2vsvzRNG88GoY9gGmOKiEUxkwKWV85/D3MzV376kY6R699jfsh7Ms2GiyWH5fKD3ZqS+LdN7+0bkarPdKYqtBaB/e2Gsx1YHB1l8ZW3IpXONA0s8gvH+OxJg3xNaH13m8DZKPK20ZOZWdW+3VIF/54e2NhS49D4KXutuo5xB2YGSRLpDSMoIYscJID7cc+VK2Gqmf07AlvpmUYW2S2mO5dgzu+KOPVzBkTQ+rhUsthEdUIpQXn1y94SLlxgJcMlA3deqXLfQZwKG/mNAuqmvx/t5xkMyvhz3OdGHek2Os6wesQ/t4TqkUs4iY6WHolZ0TARP+hRDRtLMdNtwP7V0vSfWSvrZut9UypfEqKlrWtiPIgpZlRaro8uQkoaweTpPR6CQJ6klnsoOQj6B7pbscg9E6X4tM15Ld8IogItn9Ted5OyxwroWUc=--ikgyIcb4z3MncQnj--HZOkrCFarVAis0DMXy0oaw== \ No newline at end of file +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--3vwK8dvGCDo4Bq3H--IREQaAm34LMx0SQuHy1fVw== \ No newline at end of file diff --git a/config/credentials/test.yml.enc b/config/credentials/test.yml.enc index de8b4b441..26ec8c3a3 100644 --- a/config/credentials/test.yml.enc +++ b/config/credentials/test.yml.enc @@ -1 +1 @@ -ADXpePqAwH/J5T8SGYvBbmZcw5VWezhEngFQVDYROdye9KoQ6OJ46aNYpBQW2W6wofG2IBQq19hpNcI8/X31I1RMOyvcRCnfeJ8nSFiCEH/6vnxySB3gpxEMfosQ2BZs3QOWe/ulB3JcoZE1nFMbD8GTBXK8U7YUHUNeAqJowOQ/5AE0/jVkDkoV2s/cZAdiSxAdvSU+flib16yrjVKdPlyyLDs6lnyNx9deps8Hd/FYy09bBvJ8srROXBLPpCaagYoKvxHSJTidj/n9yQ29Pdj4vyylaDaN2kCXZAVQ+XTwM/hz8bBhYlZZ6McWQU9QHyM/WeU7pTPMy+yNVTUvF2A5z4vd4vW4fON1rUOlHSULUNSyhvSWfZcmXF4LTpKX5By0qOFs8fbUrUZI2upto1wcCDL2e4bbw2TXxL1sZSNBzBN8da7w4pKeCppJshA4glDGN+z7jWHnn8mD1lqG1YuoVsmGwLDnoWbvQ+Ke5+0VVLiH4A6pzWC+oD0ZQF8ENDT8LpFwojwwB6EsfECG0GjWcEFEWyWddYTQ4QEv8360U/gpWAAZUp5Qcc9V5QZ+XNzFJS6Q3fLGxK+juOnRMcc8DJTEZUlFIemB6fDTAUCUODLjJdBYmj2rL+la4Ib8zYozqoLHNQYPPKentwl0bgQQSHiDMkXohDLb8nYcvg66KGdcRdvCtE7y1Q5vgNX4C+CkrWNGuynuQ4wpHnQ/b7vmJQYNpaDjNsHpkjSxnBACBz7RgLFA+xtF0JAYTvW8jbrWQNDrTzp1SZA/53RBZYRsbNUJ0g8FHkFQTZpvsLDVw/0A6uv2avnOrtM3N//v+arwMU6Pmw5uy4iK9OhzExmjf+wfsmBwDHWyMF54nzN0uW7kwpau5b5lmiRhYYxVfJZyPUm0Pyvba/ZhkznYOtItA+xiTLpeJrghqXD5TCDl8r3bvVACQzQsBcYCC7kbWPJ3AKfsH7ml7v5zVj2a1gx8JZ+TKIF9i97lbOZ9XrktmdFmXsVE4CmFkpYpwWfzmOoO4hJQDqNu5164WyUEEURPNVa1e+nmtQNB6rK0ckL+nJ0bQDoVEx1JgJcgvkGlUF41vv2i4v0gqI7lECsCaLTnL9czKuKMf/BwYOSZVttBaSJDGi2HVbXmWfBdbJrcR4oVs/Y+UJ17Pi8PBA5k4L/Tzc9LZ4b4WgX3A7TYMdTMASTaILOMA8QC1uqz4+YIvp7TI4spOtQz6djrzMkNpQoyogcXWvxFIeYhetEz6W+RHKOQe6GMLYY9sQQ5E0DNcICkVpJ2IuixDdpE2tU5U9IaCofJ3dMWx32vH8xTqXyvzQRS0b2NXBw/7zn15qs5I+T1JiS+L/EWDf/HyPlsqiZsFSkiAdmmZPV6eOGd2L/eZ0RmmKna2bMeuCdk44oREJxW9nrTobODsX+CYLCqN+ckNIQW9BxDoBkIdh7hM+omM3SW5ZYL5LQby8z/YsIMECkdf7Pj4bD5+KSvJ2UMP8mnCMghXMYJJd3oKZCkij1oZhrelYYp9APNKF3wsG7skJoO7iBc+v+aAi95FKPo64wy+xySICXVd1/SCI2Gqiju0FvGTVcLt0hcmmG01mA4nGX5b3f5AzX/x7g1HjxEdL80AyEAPW5/o94yE2eOaWHwCEDRbp6xwT8vMtobyyB0Lm/ns4vA3UBljmafsvzUBWBEhid83ns0IjSWzVYtuY2PrU/E3/i9Btw0J2oa1va89iA/yWFH1O4dZhdfhSUFt6HE1ydf16GRoLINHbTzVolJCtlivfdP2oRzFQDKrmQaXYGSMGbxLHNam45CopHPWThkx1AY9xs=--qBCUG6JSF8JVLmIJ--BlPRDPPc+M7l/sFLkzoRDQ== \ No newline at end of file +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--1iVrN2uZYhSZST7Q--wTX5GsuCHbFXF8Ki2bYStA== \ No newline at end of file diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 6cc7380eb..cac5b73cd 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -15,4 +15,9 @@ inflect.acronym 'HTTP' inflect.acronym 'FAQ' + + inflect.acronym 'HubEE' + inflect.acronym 'INSEE' + + inflect.acronym 'QF' end diff --git a/db/migrate/20240624152759_add_extra_infos_to_authorization_requests.rb b/db/migrate/20240624152759_add_extra_infos_to_authorization_requests.rb new file mode 100644 index 000000000..3db463e21 --- /dev/null +++ b/db/migrate/20240624152759_add_extra_infos_to_authorization_requests.rb @@ -0,0 +1,5 @@ +class AddExtraInfosToAuthorizationRequests < ActiveRecord::Migration[7.1] + def change + add_column :authorization_requests, :extra_infos, :jsonb, default: {} + end +end diff --git a/db/schema.rb b/db/schema.rb index 9e3385e3b..a5141ef0d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -34,6 +34,7 @@ t.string "siret" t.string "api", null: false t.string "demarche" + t.jsonb "extra_infos", default: {} t.uuid "public_id" t.index ["external_id"], name: "index_authorization_requests_on_external_id", unique: true, where: "(external_id IS NOT NULL)" end diff --git a/spec/clients/hubee_api_client_spec.rb b/spec/clients/hubee_api_client_spec.rb new file mode 100644 index 000000000..9e6b335d1 --- /dev/null +++ b/spec/clients/hubee_api_client_spec.rb @@ -0,0 +1,67 @@ +RSpec.describe HubEEAPIClient do + let(:hubee_api_authentication) { instance_double(HubEEAPIAuthentication, access_token: 'access_token') } + + before do + allow(HubEEAPIAuthentication).to receive(:new).and_return(hubee_api_authentication) + end + + describe '#find_organization' do + subject(:find_organization_payload) { described_class.new.find_organization(organization) } + + let(:organization) { Organization.new(siret) } + let(:siret) { '13002526500013' } + let(:code_commune) { '13055' } + let(:host) { Rails.application.credentials.hubee_api_url } + + before do + allow(organization).to receive(:code_commune_etablissement).and_return(code_commune) + end + + context 'when the API returns a 200' do + let(:valid_payload) { hubee_organization_payload(siret:, code_commune:) } + + before do + stub_request(:get, "#{host}/referential/v1/organizations/SI-#{siret}-#{code_commune}").to_return( + status: 200, + headers: { 'Content-Type' => 'application/json' }, + body: valid_payload.to_json + ) + end + + it 'renders a valid json from payload' do + expect(find_organization_payload).to eq(valid_payload) + end + end + + context 'when API returns 404' do + before do + stub_request(:get, "#{host}/referential/v1/organizations/SI-#{siret}-#{code_commune}").to_return( + status: 404, + headers: { 'Content-Type' => 'application/json' }, + body: { + 'header' => { + 'statut' => 404, + 'message' => "Aucun élément trouvé pour le siret #{siret}" + } + }.to_json + ) + end + + it 'raises a NotFound error' do + expect { find_organization_payload }.to raise_error(HubEEAPIClient::NotFound) + end + end + + context 'when API returns unknown status' do + before do + stub_request(:get, "#{host}/referential/v1/organizations/SI-#{siret}-#{code_commune}").to_return( + status: 500 + ) + end + + it 'raises an error' do + expect { find_organization_payload }.to raise_error(Faraday::Error) + end + end + end +end diff --git a/spec/clients/insee_sirene_api_client_spec.rb b/spec/clients/insee_sirene_api_client_spec.rb new file mode 100644 index 000000000..1695076fe --- /dev/null +++ b/spec/clients/insee_sirene_api_client_spec.rb @@ -0,0 +1,43 @@ +RSpec.describe INSEESireneAPIClient do + let(:insee_api_authentication) { instance_double(INSEEAPIAuthentication, access_token: 'access_token') } + + before do + allow(INSEEAPIAuthentication).to receive(:new).and_return(insee_api_authentication) + end + + describe '#etablissement' do + subject(:etablissement_payload) { described_class.new.etablissement(siret:) } + + let(:siret) { '13002526500013' } + + context 'when the API returns a 200' do + let(:valid_payload) { insee_sirene_api_etablissement_valid_payload(siret:) } + + before do + stub_request(:get, "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{siret}").to_return( + status: 200, + headers: { 'Content-Type' => 'application/json' }, + body: valid_payload.to_json + ) + end + + it 'renders a valid json from payload' do + expect(etablissement_payload).to eq(valid_payload) + end + end + + context 'when API returns something else than 200' do + before do + stub_request(:get, "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{siret}").to_return( + status: 404, + headers: { 'Content-Type' => 'application/json' }, + body: '' + ) + end + + it 'raises an error' do + expect { etablissement_payload }.to raise_error(Faraday::Error) + end + end + end +end diff --git a/spec/factories/datapass_webhooks.rb b/spec/factories/datapass_webhooks.rb index b574ba846..cd813e636 100644 --- a/spec/factories/datapass_webhooks.rb +++ b/spec/factories/datapass_webhooks.rb @@ -63,6 +63,15 @@ 'entreprises' => true } end + + service_provider do + { + 'id' => '3d_ouest', + 'type' => 'editor', + 'siret' => '44973625500018', + 'code' => '22113' + } + end end factory :datapass_webhook_team_member_model, class: Hash do diff --git a/spec/factories/datapass_webhooks_v2.rb b/spec/factories/datapass_webhooks_v2.rb index 323b5dddd..6360112b0 100644 --- a/spec/factories/datapass_webhooks_v2.rb +++ b/spec/factories/datapass_webhooks_v2.rb @@ -60,5 +60,9 @@ contact_metier_given_name { 'Jacques' } contact_metier_family_name { 'Metier' } contact_metier_job_title { 'CMO' } + + modalities do + %w[params] + end end end diff --git a/spec/fixtures/insee/13002526500013.json b/spec/fixtures/insee/13002526500013.json new file mode 100644 index 000000000..af5c31feb --- /dev/null +++ b/spec/fixtures/insee/13002526500013.json @@ -0,0 +1,102 @@ +{ + "header": { + "statut": 200, + "message": "ok" + }, + "etablissement": { + "siren": "130025265", + "nic": "00013", + "siret": "13002526500013", + "statutDiffusionEtablissement": "O", + "dateCreationEtablissement": "2017-05-24", + "trancheEffectifsEtablissement": "22", + "anneeEffectifsEtablissement": "2021", + "activitePrincipaleRegistreMetiersEtablissement": null, + "dateDernierTraitementEtablissement": "2023-11-30T10:17:12", + "etablissementSiege": true, + "nombrePeriodesEtablissement": 1, + "uniteLegale": { + "etatAdministratifUniteLegale": "A", + "statutDiffusionUniteLegale": "O", + "dateCreationUniteLegale": "2017-05-24", + "categorieJuridiqueUniteLegale": "7120", + "denominationUniteLegale": "DIRECTION INTERMINISTERIELLE DU NUMERIQUE", + "sigleUniteLegale": "DINUM", + "denominationUsuelle1UniteLegale": null, + "denominationUsuelle2UniteLegale": null, + "denominationUsuelle3UniteLegale": null, + "sexeUniteLegale": null, + "nomUniteLegale": null, + "nomUsageUniteLegale": null, + "prenom1UniteLegale": null, + "prenom2UniteLegale": null, + "prenom3UniteLegale": null, + "prenom4UniteLegale": null, + "prenomUsuelUniteLegale": null, + "pseudonymeUniteLegale": null, + "activitePrincipaleUniteLegale": "84.11Z", + "nomenclatureActivitePrincipaleUniteLegale": "NAFRev2", + "identifiantAssociationUniteLegale": null, + "economieSocialeSolidaireUniteLegale": "N", + "societeMissionUniteLegale": null, + "caractereEmployeurUniteLegale": "N", + "trancheEffectifsUniteLegale": "22", + "anneeEffectifsUniteLegale": "2021", + "nicSiegeUniteLegale": "00013", + "dateDernierTraitementUniteLegale": "2023-11-30T10:17:13", + "categorieEntreprise": "PME", + "anneeCategorieEntreprise": "2021" + }, + "adresseEtablissement": { + "complementAdresseEtablissement": null, + "numeroVoieEtablissement": "20", + "indiceRepetitionEtablissement": null, + "typeVoieEtablissement": "AV", + "libelleVoieEtablissement": "DE SEGUR", + "codePostalEtablissement": "75007", + "libelleCommuneEtablissement": "PARIS 7", + "libelleCommuneEtrangerEtablissement": null, + "distributionSpecialeEtablissement": null, + "codeCommuneEtablissement": "75107", + "codeCedexEtablissement": null, + "libelleCedexEtablissement": null, + "codePaysEtrangerEtablissement": null, + "libellePaysEtrangerEtablissement": null + }, + "adresse2Etablissement": { + "complementAdresse2Etablissement": null, + "numeroVoie2Etablissement": null, + "indiceRepetition2Etablissement": null, + "typeVoie2Etablissement": null, + "libelleVoie2Etablissement": null, + "codePostal2Etablissement": null, + "libelleCommune2Etablissement": null, + "libelleCommuneEtranger2Etablissement": null, + "distributionSpeciale2Etablissement": null, + "codeCommune2Etablissement": null, + "codeCedex2Etablissement": null, + "libelleCedex2Etablissement": null, + "codePaysEtranger2Etablissement": null, + "libellePaysEtranger2Etablissement": null + }, + "periodesEtablissement": [ + { + "dateFin": null, + "dateDebut": "2017-05-24", + "etatAdministratifEtablissement": "A", + "changementEtatAdministratifEtablissement": false, + "enseigne1Etablissement": null, + "enseigne2Etablissement": null, + "enseigne3Etablissement": null, + "changementEnseigneEtablissement": false, + "denominationUsuelleEtablissement": null, + "changementDenominationUsuelleEtablissement": false, + "activitePrincipaleEtablissement": "84.11Z", + "nomenclatureActivitePrincipaleEtablissement": "NAFRev2", + "changementActivitePrincipaleEtablissement": false, + "caractereEmployeurEtablissement": "N", + "changementCaractereEmployeurEtablissement": false + } + ] + } +} \ No newline at end of file diff --git a/spec/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity_spec.rb b/spec/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity_spec.rb new file mode 100644 index 000000000..024c08c3a --- /dev/null +++ b/spec/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +RSpec.describe DatapassWebhook::APIParticulier::CreateFormulaireQFCollectivity, type: :interactor do + subject(:interactor) { described_class.call(**params) } + + let(:authorization_request) { create(:authorization_request) } + let(:formulaire_qf_api_client) { instance_double(FormulaireQFAPIClient) } + let(:params) { { authorization_request: } } + let(:organization) { authorization_request.organization } + let(:editor_id) { 'SUPEREDITOR' } + + before do + allow(FormulaireQFAPIClient).to receive(:new).and_return(formulaire_qf_api_client) + allow(formulaire_qf_api_client).to receive(:create_collectivity) + + authorization_request.extra_infos['service_provider'] = { 'id' => editor_id } + end + + it 'creates a collectivity on FormulaireQF' do + expect(formulaire_qf_api_client).to receive(:create_collectivity).with(organization:, editor_id:) + interactor + end + + it { is_expected.to be_a_success } +end diff --git a/spec/interactors/datapass_webhook/api_particulier/create_hubee_organization_spec.rb b/spec/interactors/datapass_webhook/api_particulier/create_hubee_organization_spec.rb new file mode 100644 index 000000000..927367197 --- /dev/null +++ b/spec/interactors/datapass_webhook/api_particulier/create_hubee_organization_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' + +RSpec.describe DatapassWebhook::APIParticulier::CreateHubEEOrganization, type: :interactor do + subject(:interactor) { described_class.call(**params) } + + let(:authorization_request) { create(:authorization_request, :with_demandeur) } + let(:hubee_api_client) { instance_double(HubEEAPIClient) } + let(:params) { { authorization_request: } } + let(:stripped_organization_payload) { { 'companyRegister' => '123456789', 'branchCode' => '123456' } } + + context 'when everything works as expected' do + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive(:find_or_create_organization).and_return(stripped_organization_payload) + end + + it 'finds or creates an HubEE organization' do + expect(hubee_api_client).to receive(:find_or_create_organization).with(authorization_request.organization, authorization_request.demandeur.email) + interactor + end + + it 'saves the HubEE organization id to the authorization request' do + expect { + interactor + }.to change { authorization_request.reload.extra_infos['hubee_organization_id'] }.from(nil).to('SI-123456789-123456') + end + + it 'adds the HubEE organization payload to the context' do + expect(interactor.hubee_organization_payload).to eq(stripped_organization_payload) + end + + it { is_expected.to be_a_success } + end + + context 'when HubEE raises an error' do + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive(:find_or_create_organization).and_raise(Faraday::BadRequestError) + end + + it 'raises an error' do + expect { + interactor + }.to raise_error(Faraday::BadRequestError) + end + end +end diff --git a/spec/interactors/datapass_webhook/api_particulier/create_hubee_subscription_spec.rb b/spec/interactors/datapass_webhook/api_particulier/create_hubee_subscription_spec.rb new file mode 100644 index 000000000..c8e78269f --- /dev/null +++ b/spec/interactors/datapass_webhook/api_particulier/create_hubee_subscription_spec.rb @@ -0,0 +1,82 @@ +require 'rails_helper' + +RSpec.describe DatapassWebhook::APIParticulier::CreateHubEESubscription, type: :interactor do + subject(:interactor) { described_class.call(**params) } + + let(:authorization_request) { create(:authorization_request) } + let(:hubee_api_client) { instance_double(HubEEAPIClient) } + let(:stripped_hubee_organization_payload) { { 'branchCode' => '132456', 'companyRegister' => '123456789', 'id' => '123456789' } } + let(:stripped_hubee_subscription_payload) { { 'id' => 'ABC123456789' } } + let(:params) { { authorization_request:, hubee_organization_payload: stripped_hubee_organization_payload } } + + context 'when everything works as expected' do + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive(:create_subscription).and_return(stripped_hubee_subscription_payload) + end + + context 'when the authorization request has a service provider' do + let(:authorization_request) { create(:authorization_request, extra_infos: { 'service_provider' => service_provider }) } + let(:editor_siret) { '13002526500013' } + let(:service_provider) { { 'type' => 'editor', 'siret' => editor_siret } } + + context 'when the service provider is an editor' do + let(:insee_api_authentication) { instance_double(INSEEAPIAuthentication, access_token: 'access_token') } + let(:insee_payload) { insee_sirene_api_etablissement_valid_payload(siret: editor_siret, full: true) } + + before do + allow(INSEEAPIAuthentication).to receive(:new).and_return(insee_api_authentication) + stub_request(:get, "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{editor_siret}").to_return( + status: 200, + headers: { 'Content-Type' => 'application/json' }, + body: insee_payload.to_json + ) + end + + it 'creates a subscription on HubEE with the editor payload' do + expect(hubee_api_client).to receive(:create_subscription).with(authorization_request, stripped_hubee_organization_payload, 'FormulaireQF', { delegationActor: { branchCode: '75107', companyRegister: '13002526500013', type: 'EDT' }, accessMode: 'API' }) + interactor + end + end + + context 'when the service provider is not an editor' do + let(:service_provider) { { 'type' => 'service', 'siret' => '123456' } } + + it 'creates a subscription on HubEE without the editor payload' do + expect(hubee_api_client).to receive(:create_subscription).with(authorization_request, stripped_hubee_organization_payload, 'FormulaireQF', {}) + interactor + end + end + end + + context 'when the authorization request does not have a service provider' do + it 'creates a subscription on HubEE' do + expect(hubee_api_client).to receive(:create_subscription).with(authorization_request, stripped_hubee_organization_payload, 'FormulaireQF', {}) + interactor + end + end + + it 'saves the HubEE subscription id to the authorization request' do + expect { + interactor + }.to change { authorization_request.reload.extra_infos['hubee_subscription_id'] }.from(nil).to('ABC123456789') + end + + it 'adds the HubEE subscription payload to the context' do + expect(interactor.hubee_subscription_payload).to eq(stripped_hubee_subscription_payload) + end + + it { is_expected.to be_a_success } + end + + context 'when HubEE raises an error' do + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive(:create_subscription).and_raise(Faraday::BadRequestError) + end + + it 'raises an error' do + expect { interactor }.to raise_error(Faraday::BadRequestError) + end + end +end diff --git a/spec/interactors/datapass_webhook/find_or_create_authorization_request_spec.rb b/spec/interactors/datapass_webhook/find_or_create_authorization_request_spec.rb index 9b7854ebf..14f33d553 100644 --- a/spec/interactors/datapass_webhook/find_or_create_authorization_request_spec.rb +++ b/spec/interactors/datapass_webhook/find_or_create_authorization_request_spec.rb @@ -68,6 +68,10 @@ expect(subject.reopening).to be_falsey end + it 'stores the service provider in extra_infos' do + expect { subject }.to change { authorization_request.reload.extra_infos['service_provider'] } + end + context 'when it is the same demandeur' do let(:demandeur) { build(:datapass_webhook_team_member_model, type: 'demandeur', email: authorization_request.demandeur.email) } diff --git a/spec/jobs/create_formulaire_qf_resources_job_spec.rb b/spec/jobs/create_formulaire_qf_resources_job_spec.rb new file mode 100644 index 000000000..983cbaebd --- /dev/null +++ b/spec/jobs/create_formulaire_qf_resources_job_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +RSpec.describe CreateFormulaireQFResourcesJob do + describe '#perform' do + subject do + described_class.perform_now(authorization_request_id) + end + + let(:authorization_request) { create(:authorization_request, :with_demandeur, :with_contact_technique) } + let(:authorization_request_id) { authorization_request.id } + + before do + allow(DatapassWebhook::CreateFormulaireQFResources).to receive(:call).with(authorization_request:) + end + + it 'creates FormulaireQF resources' do + subject + + expect(DatapassWebhook::CreateFormulaireQFResources).to have_received(:call).with(authorization_request:) + end + end +end diff --git a/spec/organizers/datapass_webhook/create_formulaire_qf_resources_spec.rb b/spec/organizers/datapass_webhook/create_formulaire_qf_resources_spec.rb new file mode 100644 index 000000000..99669ea98 --- /dev/null +++ b/spec/organizers/datapass_webhook/create_formulaire_qf_resources_spec.rb @@ -0,0 +1,68 @@ +require 'rails_helper' + +RSpec.describe DatapassWebhook::CreateFormulaireQFResources do + subject(:interactor) { described_class.call(authorization_request:) } + + let(:hubee_api_client) { instance_double(HubEEAPIClient) } + let(:insee_api_authentication) { instance_double(INSEEAPIAuthentication, access_token: 'access_token') } + let(:insee_payload) { insee_sirene_api_etablissement_valid_payload(siret: editor_siret, full: true) } + let(:authorization_request) { create(:authorization_request, :with_demandeur, api: 'particulier') } + let(:subscription_payload) { hubee_subscription_payload(authorization_request:) } + let(:editor_siret) { '13002526500013' } + let(:service_provider) { { 'type' => 'editor', 'siret' => editor_siret } } + let(:formulaire_qf_api_client) { instance_double(FormulaireQFAPIClient) } + let(:siret) { '12345678901234' } + let(:code_commune) { '12345' } + + let(:organization_payload) { hubee_organization_payload(siret:, code_commune:) } + + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive_messages(find_or_create_organization: organization_payload, create_subscription: subscription_payload) + allow(INSEEAPIAuthentication).to receive(:new).and_return(insee_api_authentication) + stub_request(:get, "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{editor_siret}").to_return( + status: 200, + headers: { 'Content-Type' => 'application/json' }, + body: insee_payload.to_json + ) + allow(FormulaireQFAPIClient).to receive(:new).and_return(formulaire_qf_api_client) + allow(formulaire_qf_api_client).to receive(:create_collectivity) + end + + it 'stores the organization id on the authorization request' do + interactor + + expect(authorization_request.reload.extra_infos['hubee_organization_id']).to eq("SI-#{siret}-#{code_commune}") + end + + it 'creates a subscription on HubEE' do + expect(hubee_api_client).to receive(:create_subscription) + + interactor + end + + it 'stores the subscription id on the authorization request' do + interactor + + expect(authorization_request.reload.extra_infos['hubee_subscription_id']).to eq(subscription_payload['id']) + end + + describe 'subscription creation' do + context 'when subscription failed' do + before do + allow(hubee_api_client).to receive(:create_subscription).and_raise(Faraday::Error) + end + + it { is_expected.to be_a_success } + + it 'captures an error' do + expect(Sentry).to receive(:set_context).with( + 'DataPass webhook: create FormulaireQF resources', + payload: { authorization_request_id: authorization_request.id } + ) + expect(Sentry).to receive(:capture_exception).with(Faraday::Error) + interactor + end + end + end +end diff --git a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb index 6c857b030..67ed26e67 100644 --- a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb +++ b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb @@ -41,6 +41,62 @@ expect(last_token.api).to eq('particulier') end + context 'when modalities does no include params' do + before do + datapass_webhook_params['data']['data']['modalities'] = ['formulaire_qf'] + end + + it 'does not create a token' do + expect { + subject + }.not_to change(Token, :count) + end + end + + describe 'modalities' do + context 'when modalities does not include formulaire_qf' do + before do + datapass_webhook_params['data']['data']['modalities'] = ['params'] + end + + it 'does not schedule a job to create formulaire qf resources' do + expect { + subject + }.not_to have_enqueued_job(CreateFormulaireQFResourcesJob) + end + end + + context 'when modalities include formulaire_qf' do + before do + datapass_webhook_params['data']['data']['modalities'] = ['formulaire_qf'] + end + + context 'when event is approve' do + before do + datapass_webhook_params['event'] = 'approve' + end + + it 'schedules a job to create formulaire qf resources' do + expect { + subject + }.to have_enqueued_job(CreateFormulaireQFResourcesJob) + end + end + + context 'when event not approve' do + before do + datapass_webhook_params['event'] = 'reject' + end + + it 'does not schedule a job to create formulaire qf resources' do + expect { + subject + }.not_to have_enqueued_job(CreateFormulaireQFResourcesJob) + end + end + end + end + describe 'Mailjet adding contacts' do it 'adds contacts to Entreprise mailjet list' do expect(Mailjet::Contactslist_managemanycontacts).to receive(:create).with( @@ -71,4 +127,8 @@ subject end end + + it 'affects authorization request data to authorization_request_data on context' do + expect(subject.authorization_request_data).to eq(datapass_webhook_params['data']['data']) + end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index f63c9ac57..2cee3272f 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -84,6 +84,8 @@ config.include SpecsHelper config.include FeatureHelper, type: :feature config.include ExternalUrlHelper, type: :feature + config.include INSEESireneAPIMocks + config.include HubEEAPIMocks config.around(:each, :js) do |example| example.run_with_retry retry: example.metadata[:retry] || 3 diff --git a/spec/support/hubee_api_mocks.rb b/spec/support/hubee_api_mocks.rb new file mode 100644 index 000000000..cc21d99b1 --- /dev/null +++ b/spec/support/hubee_api_mocks.rb @@ -0,0 +1,40 @@ +module HubEEAPIMocks + def hubee_organization_payload(siret: '13002526500013', code_commune: '75017') + { + 'country' => 'France', + 'code' => 'DINUM', + 'postalCode' => '75007', + 'type' => 'SI', + 'companyRegister' => siret, + 'createDateTime' => '2021-05-20T15:59:02.569+00:00', + 'branchCode' => code_commune, + 'phoneNumber' => '0000000000', + 'name' => 'DIRECTION INTERMINISTERIELLE DU NUMERIQUE', + 'updateDateTime' => '2022-01-27T19:42:07.386+00:00', + 'email' => 'datapass@yopmail.com', + 'territory' => 'PARIS 7', + 'status' => 'Actif' + } + end + + def hubee_subscription_payload(authorization_request:, organization_payload: hubee_organization_payload, process_code: 'TEST') + { + 'id' => SecureRandom.uuid, + 'datapassId' => authorization_request.external_id.to_i, + 'notificationFrequency' => 'unitaire', + 'processCode' => process_code, + 'email' => authorization_request.demandeur.email, + 'localAdministrator' => { + 'email' => authorization_request.demandeur.email + }, + 'status' => 'Actif', + 'subscriber' => { + 'branchCode' => organization_payload['branchCode'], + 'companyRegister' => organization_payload['companyRegister'], + 'type' => 'SI' + }, + 'creationDateTime' => '2024-06-24T16:01:27.142+00:00', + 'updateDateTime' => '2024-06-24T16:01:27+0000' + } + end +end diff --git a/spec/support/insee_sirene_api_mocks.rb b/spec/support/insee_sirene_api_mocks.rb new file mode 100644 index 000000000..4014cf0c9 --- /dev/null +++ b/spec/support/insee_sirene_api_mocks.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module INSEESireneAPIMocks + def insee_sirene_api_etablissement_valid_payload(siret:, full: false) + if full + read_json_fixture("insee/#{siret}.json") + else + { + 'header' => { + 'statut' => 200, + 'message' => 'OK' + }, + 'etablissement' => { + 'siren' => siret.first(9) + } + } + end + end + + def insee_sirene_api_not_found_payload + { + 'header' => { + 'statut' => 404, + 'message' => 'Not Found' + } + } + end + + def read_json_fixture(file) + JSON.parse(Rails.root.join('spec', 'fixtures', file).read) + end +end