From 5876dab0960d58c77df4ce452c14c7b1563cf295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Carceles?= Date: Mon, 9 Jan 2023 15:29:18 +0100 Subject: [PATCH 01/10] siret champ can fetch it's own etablissement --- app/models/champs/siret_champ.rb | 2 + ...t_champ_etablissement_fetchable_concern.rb | 34 +++++++ ...mp_etablissement_fetchable_concern_spec.rb | 94 +++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 app/models/concerns/siret_champ_etablissement_fetchable_concern.rb create mode 100644 spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb diff --git a/app/models/champs/siret_champ.rb b/app/models/champs/siret_champ.rb index 97c816fbf..0901c3227 100644 --- a/app/models/champs/siret_champ.rb +++ b/app/models/champs/siret_champ.rb @@ -21,6 +21,8 @@ # type_de_champ_id :integer # class Champs::SiretChamp < Champ + include SiretChampEtablissementFetchableConcern + def search_terms etablissement.present? ? etablissement.search_terms : [value] end diff --git a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb new file mode 100644 index 000000000..8d53f0a4c --- /dev/null +++ b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb @@ -0,0 +1,34 @@ +module SiretChampEtablissementFetchableConcern + extend ActiveSupport::Concern + + def fetch_etablissement!(siret, user) + return clear if siret.empty? + return clear(error: :invalid) unless Siret.new(siret: siret).valid? # i18n-tasks-use t('errors.messages.invalid_siret') + return clear(error: :not_found) unless (etablissement = APIEntrepriseService.create_etablissement(self, siret, user.id)) # i18n-tasks-use t('errors.messages.siret_not_found') + + return update_etablissement!(etablissement) + rescue => error + if error.try(:network_error?) && !APIEntrepriseService.api_up? + # TODO: notify ops + etablissement = APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id) + return update_etablissement!(etablissement, error: :api_entreprise_down) + else + Sentry.capture_exception(error, extra: { dossier_id: dossier_id, siret: siret }) + return clear(error: :network_error) # i18n-tasks-use t('errors.messages.siret_network_error') + end + end + + private + + def update_etablissement!(etablissement, error: nil) + update!(value: etablissement.siret, etablissement: etablissement) + error.presence || etablissement.siret + end + + def clear(error: nil) + etablissement_to_destroy = etablissement + update!(value: '', etablissement: nil) + etablissement_to_destroy&.destroy + error.presence + end +end diff --git a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb new file mode 100644 index 000000000..77b754dac --- /dev/null +++ b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb @@ -0,0 +1,94 @@ +RSpec.describe SiretChampEtablissementFetchableConcern do + describe '.fetch_etablissement!' do + let(:api_etablissement_status) { 200 } + let(:api_etablissement_body) { File.read('spec/fixtures/files/api_entreprise/etablissements.json') } + let(:token_expired) { false } + let!(:champ) { create(:champ_siret) } + + before do + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/) + .to_return(status: api_etablissement_status, body: api_etablissement_body) + allow_any_instance_of(APIEntrepriseToken).to receive(:roles) + .and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"]) + allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(token_expired) + end + + subject(:fetch_etablissement!) { champ.fetch_etablissement!(siret, build_stubbed(:user)) } + + shared_examples 'an error occured' do |error| + it { expect { fetch_etablissement! }.to change { champ.reload.value }.to('') } + + it { expect { fetch_etablissement! }.to change { champ.reload.etablissement }.to(nil) } + + it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(-1) } + + it { expect(fetch_etablissement!).to eq(error) } + end + + context 'when the SIRET is empty' do + let(:siret) { '' } + + it_behaves_like 'an error occured', nil + end + + context 'when the SIRET is invalid' do + let(:siret) { '1234' } + + it_behaves_like 'an error occured', :invalid + end + + context 'when the API is unavailable due to network error' do + let(:siret) { '82161143100015' } + let(:api_etablissement_status) { 503 } + + before { expect(APIEntrepriseService).to receive(:api_up?).and_return(true) } + + it_behaves_like 'an error occured', :network_error + + it 'sends the error to Sentry' do + expect(Sentry).to receive(:capture_exception) + fetch_etablissement! + end + end + + context 'when the API is unavailable due to an api maintenance or pb' do + let(:siret) { '82161143100015' } + let(:api_etablissement_status) { 502 } + + before { expect(APIEntrepriseService).to receive(:api_up?).and_return(false) } + + it { expect { fetch_etablissement! }.to change { champ.reload.value }.to(siret) } + + it { expect { fetch_etablissement! }.to change { champ.reload.etablissement } } + + it { expect { fetch_etablissement! }.to change { champ.reload.etablissement.as_degraded_mode? }.to(true) } + + it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(1) } + + it { expect(fetch_etablissement!).to eq(:api_entreprise_down) } + end + + context 'when the SIRET is valid but unknown' do + let(:siret) { '00000000000000' } + let(:api_etablissement_status) { 404 } + + it_behaves_like 'an error occured', :not_found + end + + context 'when the SIRET informations are retrieved successfully' do + let(:siret) { '41816609600051' } + let(:api_etablissement_status) { 200 } + let(:api_etablissement_body) { File.read('spec/fixtures/files/api_entreprise/etablissements.json') } + + it { expect { fetch_etablissement! }.to change { champ.reload.value }.to(siret) } + + it { expect { fetch_etablissement! }.to change { champ.reload.etablissement.siret }.to(siret) } + + it { expect { fetch_etablissement! }.to change { champ.reload.etablissement.naf }.to("6202A") } + + it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(1) } + + it { expect(fetch_etablissement!).to eq(siret) } + end + end +end From 88136daf140ff4ca59a17787fe613bca700fc1f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Carceles?= Date: Mon, 9 Jan 2023 16:22:13 +0100 Subject: [PATCH 02/10] refactor siret controller to use that new ability --- app/controllers/champs/siret_controller.rb | 57 +------------------ app/views/champs/siret/show.turbo_stream.haml | 2 +- 2 files changed, 2 insertions(+), 57 deletions(-) diff --git a/app/controllers/champs/siret_controller.rb b/app/controllers/champs/siret_controller.rb index 2ef8aefd5..f8112bf6b 100644 --- a/app/controllers/champs/siret_controller.rb +++ b/app/controllers/champs/siret_controller.rb @@ -3,61 +3,6 @@ class Champs::SiretController < ApplicationController def show @champ = policy_scope(Champ).find(params[:champ_id]) - @siret = read_param_value(@champ.input_name, 'value') - @etablissement = @champ.etablissement - - if @siret.empty? - return clear_siret_and_etablissement - end - - if !Siret.new(siret: @siret).valid? - # i18n-tasks-use t('errors.messages.invalid_siret') - return siret_error(:invalid) - end - - begin - etablissement = find_etablissement_with_siret - rescue => error - if error.try(:network_error?) && !APIEntrepriseService.api_up? - # TODO: notify ops - etablissement = APIEntrepriseService.create_etablissement_as_degraded_mode(@champ, @siret, current_user.id) - - if !@champ.nil? - @champ.update!(value: etablissement.siret, etablissement: etablissement) - end - - @siret = :api_entreprise_down - return - else - Sentry.capture_exception(error, extra: { dossier_id: @champ.dossier_id, siret: @siret }) - # i18n-tasks-use t('errors.messages.siret_network_error') - return siret_error(:network_error) - end - end - if etablissement.nil? - # i18n-tasks-use t('errors.messages.siret_not_found') - return siret_error(:not_found) - end - - @etablissement = etablissement - if !@champ.nil? - @champ.update!(value: etablissement.siret, etablissement: etablissement) - end - end - - private - - def find_etablissement_with_siret - APIEntrepriseService.create_etablissement(@champ, @siret, current_user.id) - end - - def clear_siret_and_etablissement - @champ.update!(value: '') - @etablissement&.destroy - end - - def siret_error(error) - clear_siret_and_etablissement - @siret = error + @siret = @champ.fetch_etablissement!(read_param_value(@champ.input_name, 'value'), current_user) end end diff --git a/app/views/champs/siret/show.turbo_stream.haml b/app/views/champs/siret/show.turbo_stream.haml index be1c3a1c8..2e56df6aa 100644 --- a/app/views/champs/siret/show.turbo_stream.haml +++ b/app/views/champs/siret/show.turbo_stream.haml @@ -1 +1 @@ -= turbo_stream.update dom_id(@champ, :siret_info), partial: 'shared/champs/siret/etablissement', locals: { siret: @siret, etablissement: @etablissement } += turbo_stream.update dom_id(@champ, :siret_info), partial: 'shared/champs/siret/etablissement', locals: { siret: @siret, etablissement: @champ.etablissement } From 3eb76d8a43bcad3ad3710e2e283657fb157754c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Carceles?= Date: Wed, 11 Jan 2023 10:45:54 +0100 Subject: [PATCH 03/10] allow siret prefilling --- app/models/type_de_champ.rb | 3 ++- config/locales/en.yml | 2 ++ config/locales/fr.yml | 2 ++ spec/models/prefill_params_spec.rb | 1 - spec/models/type_de_champ_spec.rb | 2 +- 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 87745457f..d0342260e 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -272,7 +272,8 @@ class TypeDeChamp < ApplicationRecord TypeDeChamp.type_champs.fetch(:drop_down_list), TypeDeChamp.type_champs.fetch(:repetition), TypeDeChamp.type_champs.fetch(:multiple_drop_down_list), - TypeDeChamp.type_champs.fetch(:epci) + TypeDeChamp.type_champs.fetch(:epci), + TypeDeChamp.type_champs.fetch(:siret) ]) end diff --git a/config/locales/en.yml b/config/locales/en.yml index 42e1bae25..be8827d22 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -136,6 +136,7 @@ en: date_html: ISO8601 date datetime_html: ISO8601 datetime drop_down_list_other_html: Any value + siret_html: A SIRET number repetition_html: A array of hashes with possible values for each field of the repetition. epci_html: An array of the department code and the EPCI one. examples: @@ -154,6 +155,7 @@ en: date: "2023-02-01" datetime: "2023-02-01T10:30" checkbox: "true" + siret: 828212345600023 prefill_link_title: Prefill link (GET) prefill_link_info: Use the button to copy the link, then remplace the values with your data. prefill_link_too_long: Warning, the prefill link is too long and may not work on all browsers. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 7188425cc..46355b052 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -127,6 +127,7 @@ fr: datetime_html: Datetime au format ISO8601 date_html: Date au format ISO8601 drop_down_list_other_html: Toute valeur + siret_html: Un numéro de SIRET repetition_html: Un tableau de dictionnaires avec les valeurs possibles pour chaque champ de la répétition. epci_html: Un tableau contenant le code de département et celui de l'EPCI. examples: @@ -146,6 +147,7 @@ fr: date: "2023-02-01" datetime: "2023-02-01T10:30" checkbox: "true" + siret: 82812345600023 prefill_link_title: Lien de préremplissage (GET) prefill_link_info: Copiez le lien grâce au bouton ci-dessous et remplacez les valeurs par les données dont vous disposez. prefill_link_too_long: Attention, ce lien de préremplissage est trop long et risque de ne pas fonctionner sur certains navigateurs. diff --git a/spec/models/prefill_params_spec.rb b/spec/models/prefill_params_spec.rb index 3356cf448..232883a1c 100644 --- a/spec/models/prefill_params_spec.rb +++ b/spec/models/prefill_params_spec.rb @@ -217,7 +217,6 @@ RSpec.describe PrefillParams do it_behaves_like "a champ public value that is unauthorized", :regions, "value" it_behaves_like "a champ public value that is unauthorized", :departements, "value" it_behaves_like "a champ public value that is unauthorized", :communes, "value" - it_behaves_like "a champ public value that is unauthorized", :siret, "value" it_behaves_like "a champ public value that is unauthorized", :rna, "value" it_behaves_like "a champ public value that is unauthorized", :annuaire_education, "value" it_behaves_like "a champ public value that is unauthorized", :multiple_drop_down_list, ["value"] diff --git a/spec/models/type_de_champ_spec.rb b/spec/models/type_de_champ_spec.rb index d2225c4c6..3b0707ecf 100644 --- a/spec/models/type_de_champ_spec.rb +++ b/spec/models/type_de_champ_spec.rb @@ -255,6 +255,7 @@ describe TypeDeChamp do it_behaves_like "a prefillable type de champ", :type_de_champ_repetition it_behaves_like "a prefillable type de champ", :type_de_champ_multiple_drop_down_list it_behaves_like "a prefillable type de champ", :type_de_champ_epci + it_behaves_like "a prefillable type de champ", :type_de_champ_siret it_behaves_like "a non-prefillable type de champ", :type_de_champ_number it_behaves_like "a non-prefillable type de champ", :type_de_champ_dossier_link @@ -269,7 +270,6 @@ describe TypeDeChamp do it_behaves_like "a non-prefillable type de champ", :type_de_champ_mesri it_behaves_like "a non-prefillable type de champ", :type_de_champ_carte it_behaves_like "a non-prefillable type de champ", :type_de_champ_address - it_behaves_like "a non-prefillable type de champ", :type_de_champ_siret it_behaves_like "a non-prefillable type de champ", :type_de_champ_rna it_behaves_like "a non-prefillable type de champ", :type_de_champ_annuaire_education end From df2eaa95425b39d2047d5af3cd73ec078e3ab821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Carceles?= Date: Wed, 11 Jan 2023 15:04:45 +0100 Subject: [PATCH 04/10] don't clean the siret champ value Cleaning the value is useless, when fetching the etablissement, as the value will be re-written by the dossier update, when the user fills in the dossier. --- ...t_champ_etablissement_fetchable_concern.rb | 2 +- .../champs/siret_controller_spec.rb | 24 +++++++------------ ...mp_etablissement_fetchable_concern_spec.rb | 2 -- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb index 8d53f0a4c..3beb7b652 100644 --- a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb +++ b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb @@ -27,7 +27,7 @@ module SiretChampEtablissementFetchableConcern def clear(error: nil) etablissement_to_destroy = etablissement - update!(value: '', etablissement: nil) + update!(etablissement: nil) etablissement_to_destroy&.destroy error.presence end diff --git a/spec/controllers/champs/siret_controller_spec.rb b/spec/controllers/champs/siret_controller_spec.rb index daee4b3da..36dcca443 100644 --- a/spec/controllers/champs/siret_controller_spec.rb +++ b/spec/controllers/champs/siret_controller_spec.rb @@ -39,10 +39,8 @@ describe Champs::SiretController, type: :controller do context 'when the SIRET is empty' do subject! { get :show, params: params, format: :turbo_stream } - it 'clears the etablissement and SIRET on the model' do - champ.reload - expect(champ.etablissement).to be_nil - expect(champ.value).to be_empty + it 'clears the etablissement on the model' do + expect(champ.reload.etablissement).to be_nil end it 'clears any information or error message' do @@ -55,10 +53,8 @@ describe Champs::SiretController, type: :controller do subject! { get :show, params: params, format: :turbo_stream } - it 'clears the etablissement and SIRET on the model' do - champ.reload - expect(champ.etablissement).to be_nil - expect(champ.value).to be_empty + it 'clears the etablissement on the model' do + expect(champ.reload.etablissement).to be_nil end it 'displays a “SIRET is invalid” error message' do @@ -76,10 +72,8 @@ describe Champs::SiretController, type: :controller do subject! { get :show, params: params, format: :turbo_stream } - it 'clears the etablissement and SIRET on the model' do - champ.reload - expect(champ.etablissement).to be_nil - expect(champ.value).to be_empty + it 'clears the etablissement on the model' do + expect(champ.reload.etablissement).to be_nil end it 'displays a “API is unavailable” error message' do @@ -115,10 +109,8 @@ describe Champs::SiretController, type: :controller do subject! { get :show, params: params, format: :turbo_stream } - it 'clears the etablissement and SIRET on the model' do - champ.reload - expect(champ.etablissement).to be_nil - expect(champ.value).to be_empty + it 'clears the etablissement on the model' do + expect(champ.reload.etablissement).to be_nil end it 'displays a “SIRET not found” error message' do diff --git a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb index 77b754dac..c916bc7b9 100644 --- a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb +++ b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb @@ -16,8 +16,6 @@ RSpec.describe SiretChampEtablissementFetchableConcern do subject(:fetch_etablissement!) { champ.fetch_etablissement!(siret, build_stubbed(:user)) } shared_examples 'an error occured' do |error| - it { expect { fetch_etablissement! }.to change { champ.reload.value }.to('') } - it { expect { fetch_etablissement! }.to change { champ.reload.etablissement }.to(nil) } it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(-1) } From b6c74b0e83321772387aaefcb7d252314918f2cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Carceles?= Date: Wed, 11 Jan 2023 15:07:16 +0100 Subject: [PATCH 05/10] fetch etablissement when editing the dossier --- .../siret_component/siret_component.html.haml | 2 +- app/javascript/controllers/turbo_input_controller.tsx | 7 ++++++- spec/models/concern/dossier_prefillable_concern_spec.rb | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/components/editable_champ/siret_component/siret_component.html.haml b/app/components/editable_champ/siret_component/siret_component.html.haml index 0bcdcdb47..1970d85cc 100644 --- a/app/components/editable_champ/siret_component/siret_component.html.haml +++ b/app/components/editable_champ/siret_component/siret_component.html.haml @@ -2,7 +2,7 @@ id: @champ.input_id, aria: { describedby: @champ.describedby_id }, placeholder: t(".placeholder"), - data: { controller: 'turbo-input', turbo_input_url_value: champs_siret_path(@champ.id) }, + data: { controller: 'turbo-input', turbo_input_load_on_connect_value: @champ.prefilled? && @champ.value.present? && @champ.etablissement.blank?, turbo_input_url_value: champs_siret_path(@champ.id) }, required: @champ.required?, pattern: "[0-9]{14}", title: t(".title"), diff --git a/app/javascript/controllers/turbo_input_controller.tsx b/app/javascript/controllers/turbo_input_controller.tsx index d194a7f3c..e2ad35db3 100644 --- a/app/javascript/controllers/turbo_input_controller.tsx +++ b/app/javascript/controllers/turbo_input_controller.tsx @@ -4,13 +4,18 @@ import { ApplicationController } from './application_controller'; export class TurboInputController extends ApplicationController { static values = { - url: String + url: String, + loadOnConnect: { type: Boolean, default: false } }; declare readonly urlValue: string; + declare readonly loadOnConnectValue: boolean; connect(): void { this.on('input', () => this.debounce(this.load, 200)); + if (this.loadOnConnectValue) { + this.load(); + } } private load(): void { diff --git a/spec/models/concern/dossier_prefillable_concern_spec.rb b/spec/models/concern/dossier_prefillable_concern_spec.rb index 3ab8f73e9..32a52cad8 100644 --- a/spec/models/concern/dossier_prefillable_concern_spec.rb +++ b/spec/models/concern/dossier_prefillable_concern_spec.rb @@ -6,7 +6,10 @@ RSpec.describe DossierPrefillableConcern do let(:dossier) { create(:dossier, :brouillon, procedure: procedure) } let(:types_de_champ_public) { [] } - subject(:fill) { dossier.prefill!(values); dossier.reload } + subject(:fill) do + dossier.prefill!(values) + dossier.reload + end shared_examples 'a dossier marked as prefilled' do it 'marks the dossier as prefilled' do From 2ad4e4c01f02c3f17449580a82a8b2040e3d8bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Carceles?= Date: Sat, 14 Jan 2023 10:13:26 +0100 Subject: [PATCH 06/10] refacto: better error management --- app/controllers/champs/siret_controller.rb | 7 +++- ...t_champ_etablissement_fetchable_concern.rb | 32 +++++++++++-------- ...mp_etablissement_fetchable_concern_spec.rb | 18 ++++++++--- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/app/controllers/champs/siret_controller.rb b/app/controllers/champs/siret_controller.rb index f8112bf6b..23e4ab2ee 100644 --- a/app/controllers/champs/siret_controller.rb +++ b/app/controllers/champs/siret_controller.rb @@ -3,6 +3,11 @@ class Champs::SiretController < ApplicationController def show @champ = policy_scope(Champ).find(params[:champ_id]) - @siret = @champ.fetch_etablissement!(read_param_value(@champ.input_name, 'value'), current_user) + + if @champ.fetch_etablissement!(read_param_value(@champ.input_name, 'value'), current_user) + @siret = @champ.etablissement.siret + else + @siret = @champ.etablissement_fetch_error_key + end end end diff --git a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb index 3beb7b652..cdc629372 100644 --- a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb +++ b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb @@ -1,34 +1,38 @@ module SiretChampEtablissementFetchableConcern extend ActiveSupport::Concern - def fetch_etablissement!(siret, user) - return clear if siret.empty? - return clear(error: :invalid) unless Siret.new(siret: siret).valid? # i18n-tasks-use t('errors.messages.invalid_siret') - return clear(error: :not_found) unless (etablissement = APIEntrepriseService.create_etablissement(self, siret, user.id)) # i18n-tasks-use t('errors.messages.siret_not_found') + attr_reader :etablissement_fetch_error_key - return update_etablissement!(etablissement) + def fetch_etablissement!(siret, user) + return clear_etablissement!(:empty) if siret.empty? + return clear_etablissement!(:invalid) unless Siret.new(siret: siret).valid? # i18n-tasks-use t('errors.messages.invalid_siret') + return clear_etablissement!(:not_found) unless (etablissement = APIEntrepriseService.create_etablissement(self, siret, user&.id)) # i18n-tasks-use t('errors.messages.siret_not_found') + + update!(value: siret, etablissement: etablissement) rescue => error if error.try(:network_error?) && !APIEntrepriseService.api_up? # TODO: notify ops - etablissement = APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id) - return update_etablissement!(etablissement, error: :api_entreprise_down) + update!( + value: siret, + etablissement: APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id) + ) + @etablissement_fetch_error_key = :api_entreprise_down + false else Sentry.capture_exception(error, extra: { dossier_id: dossier_id, siret: siret }) - return clear(error: :network_error) # i18n-tasks-use t('errors.messages.siret_network_error') + clear_etablissement!(:network_error) # i18n-tasks-use t('errors.messages.siret_network_error') end end private - def update_etablissement!(etablissement, error: nil) - update!(value: etablissement.siret, etablissement: etablissement) - error.presence || etablissement.siret - end + def clear_etablissement!(error_key) + @etablissement_fetch_error_key = error_key - def clear(error: nil) etablissement_to_destroy = etablissement update!(etablissement: nil) etablissement_to_destroy&.destroy - error.presence + + false end end diff --git a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb index c916bc7b9..a69ef2a3b 100644 --- a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb +++ b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb @@ -20,13 +20,18 @@ RSpec.describe SiretChampEtablissementFetchableConcern do it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(-1) } - it { expect(fetch_etablissement!).to eq(error) } + it { expect(fetch_etablissement!).to eq(false) } + + it 'populates the etablissement_fetch_error_key' do + fetch_etablissement! + expect(champ.etablissement_fetch_error_key).to eq(error) + end end context 'when the SIRET is empty' do let(:siret) { '' } - it_behaves_like 'an error occured', nil + it_behaves_like 'an error occured', :empty end context 'when the SIRET is invalid' do @@ -63,7 +68,12 @@ RSpec.describe SiretChampEtablissementFetchableConcern do it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(1) } - it { expect(fetch_etablissement!).to eq(:api_entreprise_down) } + it { expect(fetch_etablissement!).to eq(false) } + + it 'populates the etablissement_fetch_error_key' do + fetch_etablissement! + expect(champ.etablissement_fetch_error_key).to eq(:api_entreprise_down) + end end context 'when the SIRET is valid but unknown' do @@ -86,7 +96,7 @@ RSpec.describe SiretChampEtablissementFetchableConcern do it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(1) } - it { expect(fetch_etablissement!).to eq(siret) } + it { expect(fetch_etablissement!).to eq(true) } end end end From 30eef3e128f0bae45424616ff1fb728587ce9b30 Mon Sep 17 00:00:00 2001 From: sebastiencarceles Date: Mon, 16 Jan 2023 15:14:53 +0100 Subject: [PATCH 07/10] review: detailled error message --- ...iret_champ_etablissement_fetchable_concern.rb | 10 +++++++++- .../shared/champs/siret/_etablissement.html.haml | 7 +++++-- config/locales/en.yml | 5 +++-- config/locales/fr.yml | 5 +++-- spec/controllers/champs/siret_controller_spec.rb | 16 +++++++++++++++- ...champ_etablissement_fetchable_concern_spec.rb | 10 ++++++++-- 6 files changed, 43 insertions(+), 10 deletions(-) diff --git a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb index cdc629372..6a36176b6 100644 --- a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb +++ b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb @@ -5,7 +5,8 @@ module SiretChampEtablissementFetchableConcern def fetch_etablissement!(siret, user) return clear_etablissement!(:empty) if siret.empty? - return clear_etablissement!(:invalid) unless Siret.new(siret: siret).valid? # i18n-tasks-use t('errors.messages.invalid_siret') + return clear_etablissement!(:invalid_length) if invalid_because?(siret, :length) # i18n-tasks-use t('errors.messages.invalid_siret_length') + return clear_etablissement!(:invalid_checksum) if invalid_because?(siret, :checksum) # i18n-tasks-use t('errors.messages.invalid_siret_checksum') return clear_etablissement!(:not_found) unless (etablissement = APIEntrepriseService.create_etablissement(self, siret, user&.id)) # i18n-tasks-use t('errors.messages.siret_not_found') update!(value: siret, etablissement: etablissement) @@ -35,4 +36,11 @@ module SiretChampEtablissementFetchableConcern false end + + def invalid_because?(siret, criteria) + validatable_siret = Siret.new(siret: siret) + return false if validatable_siret.valid? + + validatable_siret.errors.details[:siret].any? && validatable_siret.errors.details[:siret].first[:error] == criteria + end end diff --git a/app/views/shared/champs/siret/_etablissement.html.haml b/app/views/shared/champs/siret/_etablissement.html.haml index e93adaa15..71c9ec5f3 100644 --- a/app/views/shared/champs/siret/_etablissement.html.haml +++ b/app/views/shared/champs/siret/_etablissement.html.haml @@ -1,6 +1,9 @@ - case siret -- when :invalid - Le numéro de SIRET doit comporter exactement 14 chiffres. +- when :invalid_length + = t('errors.messages.invalid_siret_length') + +- when :invalid_checksum + = t('errors.messages.invalid_siret_checksum') - when :not_found Nous n’avons pas trouvé d’établissement correspondant à ce numéro de SIRET. diff --git a/config/locales/en.yml b/config/locales/en.yml index be8827d22..b0be49749 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -155,7 +155,7 @@ en: date: "2023-02-01" datetime: "2023-02-01T10:30" checkbox: "true" - siret: 828212345600023 + siret: 13002526500013 prefill_link_title: Prefill link (GET) prefill_link_info: Use the button to copy the link, then remplace the values with your data. prefill_link_too_long: Warning, the prefill link is too long and may not work on all browsers. @@ -511,7 +511,8 @@ en: dossier_not_found: "The file does not exist or you do not have access to it." # # dossier_map_not_activated: "The file does not have access to the map." targeted_user_link_expired: "This invitation link or the file is no longer available." - invalid_siret: "The SIRET is incorrect" + invalid_siret_length: "The SIRET number must contain exactly 14 numbers." + invalid_siret_checksum: "The SIRET number is invalid." procedure_not_found: "The procedure does not exist" siret_unknown: 'Sorry, we did not find any establishment registered under this SIRET number.' siret_network_error: 'Désolé, la récupération des informations SIRET est temporairement indisponible. Veuillez réessayer dans quelques instants.' diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 46355b052..8d22ce686 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -147,7 +147,7 @@ fr: date: "2023-02-01" datetime: "2023-02-01T10:30" checkbox: "true" - siret: 82812345600023 + siret: 13002526500013 prefill_link_title: Lien de préremplissage (GET) prefill_link_info: Copiez le lien grâce au bouton ci-dessous et remplacez les valeurs par les données dont vous disposez. prefill_link_too_long: Attention, ce lien de préremplissage est trop long et risque de ne pas fonctionner sur certains navigateurs. @@ -507,7 +507,8 @@ fr: dossier_not_found: "Le dossier n’existe pas ou vous n’y avez pas accès." # dossier_map_not_activated: "Le dossier n’a pas accès à la cartographie." targeted_user_link_expired: "Ce lien d’invitation n’est plus valable ou le dossier n’est plus accessible." - invalid_siret: "Le siret est incorrect" + invalid_siret_length: "Le numéro de SIRET doit comporter exactement 14 chiffres." + invalid_siret_checksum: "Le format du numéro de SIRET est invalide." procedure_not_found: "La démarche n’existe pas" siret_unknown: 'Désolé, nous n’avons pas trouvé d’établissement enregistré correspondant à ce numéro SIRET.' siret_network_error: 'Désolé, la récupération des informations SIRET est temporairement indisponible. Veuillez réessayer dans quelques instants.' diff --git a/spec/controllers/champs/siret_controller_spec.rb b/spec/controllers/champs/siret_controller_spec.rb index 36dcca443..81a9b6dbd 100644 --- a/spec/controllers/champs/siret_controller_spec.rb +++ b/spec/controllers/champs/siret_controller_spec.rb @@ -48,7 +48,7 @@ describe Champs::SiretController, type: :controller do end end - context 'when the SIRET is invalid' do + context "when the SIRET is invalid because of it's length" do let(:siret) { '1234' } subject! { get :show, params: params, format: :turbo_stream } @@ -62,6 +62,20 @@ describe Champs::SiretController, type: :controller do end end + context "when the SIRET is invalid because of it's checksum" do + let(:siret) { '82812345600023' } + + subject! { get :show, params: params, format: :turbo_stream } + + it 'clears the etablissement on the model' do + expect(champ.reload.etablissement).to be_nil + end + + it 'displays a “SIRET is invalid” error message' do + expect(response.body).to include('Le format du numéro de SIRET est invalide.') + end + end + context 'when the API is unavailable due to network error' do let(:siret) { '82161143100015' } let(:api_etablissement_status) { 503 } diff --git a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb index a69ef2a3b..19151c31a 100644 --- a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb +++ b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb @@ -34,10 +34,16 @@ RSpec.describe SiretChampEtablissementFetchableConcern do it_behaves_like 'an error occured', :empty end - context 'when the SIRET is invalid' do + context "when the SIRET is invalid because of it's length" do let(:siret) { '1234' } - it_behaves_like 'an error occured', :invalid + it_behaves_like 'an error occured', :invalid_length + end + + context "when the SIRET is invalid because of it's checksum" do + let(:siret) { '82812345600023' } + + it_behaves_like 'an error occured', :invalid_checksum end context 'when the API is unavailable due to network error' do From 5dce401a14ebec4ffdb445e5b14a649dc0a23dbc Mon Sep 17 00:00:00 2001 From: sebastiencarceles Date: Mon, 16 Jan 2023 15:30:15 +0100 Subject: [PATCH 08/10] review: add missing spec --- spec/models/prefill_params_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/models/prefill_params_spec.rb b/spec/models/prefill_params_spec.rb index 232883a1c..af016b47b 100644 --- a/spec/models/prefill_params_spec.rb +++ b/spec/models/prefill_params_spec.rb @@ -142,6 +142,7 @@ RSpec.describe PrefillParams do it_behaves_like "a champ public value that is authorized", :communes, ['01', '01457'] it_behaves_like "a champ public value that is authorized", :multiple_drop_down_list, ["val1", "val2"] it_behaves_like "a champ public value that is authorized", :epci, ['01', '200042935'] + it_behaves_like "a champ public value that is authorized", :siret, "13002526500013" context "when the public type de champ is authorized (repetition)" do let(:types_de_champ_public) { [{ type: :repetition, children: [{ type: :text }] }] } @@ -175,6 +176,7 @@ RSpec.describe PrefillParams do it_behaves_like "a champ private value that is authorized", :checkbox, "false" it_behaves_like "a champ private value that is authorized", :drop_down_list, "value" it_behaves_like "a champ private value that is authorized", :regions, "93" + it_behaves_like "a champ private value that is authorized", :siret, "13002526500013" it_behaves_like "a champ private value that is authorized", :departements, "03" it_behaves_like "a champ private value that is authorized", :communes, ['01', '01457'] it_behaves_like "a champ private value that is authorized", :multiple_drop_down_list, ["val1", "val2"] From 498e5d7487f03cae0853bbeb04adbe3c67dcd1e3 Mon Sep 17 00:00:00 2001 From: sebastiencarceles Date: Wed, 25 Jan 2023 12:05:00 +0100 Subject: [PATCH 09/10] cover use case with a feature spec --- spec/support/shared_examples_for_prefilled_dossier.rb | 7 ++----- spec/system/users/dossier_prefill_get_spec.rb | 9 ++++++++- spec/system/users/dossier_prefill_post_spec.rb | 9 ++++++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/spec/support/shared_examples_for_prefilled_dossier.rb b/spec/support/shared_examples_for_prefilled_dossier.rb index 239506e59..d2db50bc9 100644 --- a/spec/support/shared_examples_for_prefilled_dossier.rb +++ b/spec/support/shared_examples_for_prefilled_dossier.rb @@ -1,13 +1,9 @@ shared_examples "the user has got a prefilled dossier, owned by themselves" do scenario "the user has got a prefilled dossier, owned by themselves" do - siret = '41816609600051' - stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/) - .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json')) - expect(dossier.user).to eq(user) expect(page).to have_current_path siret_dossier_path(procedure.dossiers.last) - fill_in 'Numéro SIRET', with: siret + fill_in 'Numéro SIRET', with: siret_value click_on 'Valider' expect(page).to have_current_path(etablissement_dossier_path(dossier)) @@ -18,6 +14,7 @@ shared_examples "the user has got a prefilled dossier, owned by themselves" do expect(page).to have_field(type_de_champ_text.libelle, with: text_value) expect(page).to have_field(type_de_champ_phone.libelle, with: phone_value) expect(page).to have_css('label', text: type_de_champ_phone.libelle) + expect(page).to have_field(type_de_champ_siret.libelle, with: siret_value) expect(page).to have_css('h3', text: type_de_champ_repetition.libelle) expect(page).to have_field(text_repetition_libelle, with: text_repetition_value) expect(page).to have_field(integer_repetition_libelle, with: integer_repetition_value) diff --git a/spec/system/users/dossier_prefill_get_spec.rb b/spec/system/users/dossier_prefill_get_spec.rb index eedf28cec..21b40fa1f 100644 --- a/spec/system/users/dossier_prefill_get_spec.rb +++ b/spec/system/users/dossier_prefill_get_spec.rb @@ -1,4 +1,4 @@ -describe 'Prefilling a dossier (with a GET request):' do +describe 'Prefilling a dossier (with a GET request):', js: true do let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) } let(:password) { 'my-s3cure-p4ssword' } @@ -8,13 +8,16 @@ describe 'Prefilling a dossier (with a GET request):' do let(:type_de_champ_text) { create(:type_de_champ_text, procedure: procedure) } let(:type_de_champ_phone) { create(:type_de_champ_phone, procedure: procedure) } + let(:type_de_champ_siret) { create(:type_de_champ_siret, procedure: procedure) } let(:type_de_champ_datetime) { create(:type_de_champ_datetime, procedure: procedure) } let(:type_de_champ_multiple_drop_down_list) { create(:type_de_champ_multiple_drop_down_list, procedure: procedure) } let(:type_de_champ_epci) { create(:type_de_champ_epci, procedure: procedure) } let(:type_de_champ_commune) { create(:type_de_champ_communes, procedure: procedure) } let(:type_de_champ_repetition) { create(:type_de_champ_repetition, :with_types_de_champ, procedure: procedure) } + let(:text_value) { "My Neighbor Totoro is the best movie ever" } let(:phone_value) { "invalid phone value" } + let(:siret_value) { '41816609600051' } let(:datetime_value) { "2023-02-01T10:32" } let(:multiple_drop_down_list_values) { [ @@ -39,6 +42,7 @@ describe 'Prefilling a dossier (with a GET request):' do "champ_#{type_de_champ_multiple_drop_down_list.to_typed_id_for_query}" => multiple_drop_down_list_values, "champ_#{type_de_champ_epci.to_typed_id_for_query}" => epci_value, "champ_#{type_de_champ_commune.to_typed_id_for_query}" => commune_value, + "champ_#{type_de_champ_siret.to_typed_id_for_query}" => siret_value, "champ_#{type_de_champ_repetition.to_typed_id_for_query}" => [ { "champ_#{sub_type_de_champs_repetition.first.to_typed_id_for_query}": text_repetition_value, @@ -52,6 +56,9 @@ describe 'Prefilling a dossier (with a GET request):' do allow(Rails).to receive(:cache).and_return(memory_store) Rails.cache.clear + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\//) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json')) + VCR.insert_cassette('api_geo_departements') VCR.insert_cassette('api_geo_communes') VCR.insert_cassette('api_geo_epcis') diff --git a/spec/system/users/dossier_prefill_post_spec.rb b/spec/system/users/dossier_prefill_post_spec.rb index 5fc2119e8..eebb5462d 100644 --- a/spec/system/users/dossier_prefill_post_spec.rb +++ b/spec/system/users/dossier_prefill_post_spec.rb @@ -1,4 +1,4 @@ -describe 'Prefilling a dossier (with a POST request):' do +describe 'Prefilling a dossier (with a POST request):', js: true do let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) } let(:password) { 'my-s3cure-p4ssword' } @@ -8,13 +8,16 @@ describe 'Prefilling a dossier (with a POST request):' do let(:type_de_champ_text) { create(:type_de_champ_text, procedure: procedure) } let(:type_de_champ_phone) { create(:type_de_champ_phone, procedure: procedure) } + let(:type_de_champ_siret) { create(:type_de_champ_siret, procedure: procedure) } let(:type_de_champ_datetime) { create(:type_de_champ_datetime, procedure: procedure) } let(:type_de_champ_multiple_drop_down_list) { create(:type_de_champ_multiple_drop_down_list, procedure: procedure) } let(:type_de_champ_epci) { create(:type_de_champ_epci, procedure: procedure) } let(:type_de_champ_repetition) { create(:type_de_champ_repetition, :with_types_de_champ, procedure: procedure) } let(:type_de_champ_commune) { create(:type_de_champ_communes, procedure: procedure) } + let(:text_value) { "My Neighbor Totoro is the best movie ever" } let(:phone_value) { "invalid phone value" } + let(:siret_value) { '41816609600051' } let(:datetime_value) { "2023-02-01T10:32" } let(:multiple_drop_down_list_values) { [ @@ -34,6 +37,9 @@ describe 'Prefilling a dossier (with a POST request):' do allow(Rails).to receive(:cache).and_return(memory_store) Rails.cache.clear + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret_value}/) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json')) + VCR.insert_cassette('api_geo_departements') VCR.insert_cassette('api_geo_communes') VCR.insert_cassette('api_geo_epcis') @@ -132,6 +138,7 @@ describe 'Prefilling a dossier (with a POST request):' do params: { "champ_#{type_de_champ_text.to_typed_id_for_query}" => text_value, "champ_#{type_de_champ_phone.to_typed_id_for_query}" => phone_value, + "champ_#{type_de_champ_siret.to_typed_id_for_query}" => siret_value, "champ_#{type_de_champ_repetition.to_typed_id_for_query}" => [ { "champ_#{sub_type_de_champs_repetition.first.to_typed_id_for_query}": text_repetition_value, From becf4da70a487b7673f5768d867632773bfd2983 Mon Sep 17 00:00:00 2001 From: sebastiencarceles Date: Thu, 2 Feb 2023 09:59:59 +0100 Subject: [PATCH 10/10] fix raison social fetch --- app/services/api_entreprise_service.rb | 3 +++ spec/controllers/champs/siret_controller_spec.rb | 2 ++ spec/controllers/users/dossiers_controller_spec.rb | 2 ++ .../siret_champ_etablissement_fetchable_concern_spec.rb | 7 +++++++ spec/services/api_entreprise_service_spec.rb | 9 +++++++++ spec/system/users/dossier_prefill_get_spec.rb | 3 +++ spec/system/users/dossier_prefill_post_spec.rb | 3 +++ 7 files changed, 29 insertions(+) diff --git a/app/services/api_entreprise_service.rb b/app/services/api_entreprise_service.rb index 8eb5f4ed8..5f429d629 100644 --- a/app/services/api_entreprise_service.rb +++ b/app/services/api_entreprise_service.rb @@ -15,6 +15,9 @@ class APIEntrepriseService etablissement_params = APIEntreprise::EtablissementAdapter.new(siret, procedure_id).to_params return nil if etablissement_params.empty? + entreprise_params = APIEntreprise::EntrepriseAdapter.new(siret, procedure_id).to_params + etablissement_params.merge!(entreprise_params) if entreprise_params.any? + etablissement = dossier_or_champ.build_etablissement(etablissement_params) etablissement.save! diff --git a/spec/controllers/champs/siret_controller_spec.rb b/spec/controllers/champs/siret_controller_spec.rb index 81a9b6dbd..2b1f5f42a 100644 --- a/spec/controllers/champs/siret_controller_spec.rb +++ b/spec/controllers/champs/siret_controller_spec.rb @@ -31,6 +31,8 @@ describe Champs::SiretController, type: :controller do sign_in user stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/) .to_return(status: api_etablissement_status, body: api_etablissement_body) + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret[0..8]}/) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json')) allow_any_instance_of(APIEntrepriseToken).to receive(:roles) .and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"]) allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(token_expired) diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index 3f760ff38..57398f090 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -196,6 +196,8 @@ describe Users::DossiersController, type: :controller do sign_in(user) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/) .to_return(status: api_etablissement_status, body: api_etablissement_body) + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}/) + .to_return(body: File.read('spec/fixtures/files/api_entreprise/entreprises.json'), status: 200) allow_any_instance_of(APIEntrepriseToken).to receive(:roles) .and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"]) allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(token_expired) diff --git a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb index 19151c31a..6a2c11120 100644 --- a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb +++ b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb @@ -8,6 +8,8 @@ RSpec.describe SiretChampEtablissementFetchableConcern do before do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/) .to_return(status: api_etablissement_status, body: api_etablissement_body) + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret[0..8]}/) + .to_return(body: File.read('spec/fixtures/files/api_entreprise/entreprises.json'), status: 200) allow_any_instance_of(APIEntrepriseToken).to receive(:roles) .and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"]) allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(token_expired) @@ -103,6 +105,11 @@ RSpec.describe SiretChampEtablissementFetchableConcern do it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(1) } it { expect(fetch_etablissement!).to eq(true) } + + it "fetches the entreprise raison sociale" do + fetch_etablissement! + expect(champ.reload.etablissement.entreprise_raison_sociale).to eq("OCTO-TECHNOLOGY") + end end end end diff --git a/spec/services/api_entreprise_service_spec.rb b/spec/services/api_entreprise_service_spec.rb index 93ec39539..fd7cc7ada 100644 --- a/spec/services/api_entreprise_service_spec.rb +++ b/spec/services/api_entreprise_service_spec.rb @@ -15,11 +15,16 @@ describe APIEntrepriseService do before do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/) .to_return(body: etablissements_body, status: etablissements_status) + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret[0..8]}/) + .to_return(body: entreprises_body, status: entreprises_status) end let(:siret) { '41816609600051' } + let(:raison_sociale) { "OCTO-TECHNOLOGY" } let(:etablissements_status) { 200 } let(:etablissements_body) { File.read('spec/fixtures/files/api_entreprise/etablissements.json') } + let(:entreprises_status) { 200 } + let(:entreprises_body) { File.read('spec/fixtures/files/api_entreprise/entreprises.json') } let(:valid_token) { "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" } let(:procedure) { create(:procedure, api_entreprise_token: valid_token) } let(:dossier) { create(:dossier, procedure: procedure) } @@ -35,6 +40,10 @@ describe APIEntrepriseService do expect(subject[:siret]).to eq(siret) end + it 'should fetch entreprise params' do + expect(subject[:entreprise_raison_sociale]).to eq(raison_sociale) + end + it_behaves_like 'schedule fetch of all etablissement params' end diff --git a/spec/system/users/dossier_prefill_get_spec.rb b/spec/system/users/dossier_prefill_get_spec.rb index 21b40fa1f..ada1cf6bc 100644 --- a/spec/system/users/dossier_prefill_get_spec.rb +++ b/spec/system/users/dossier_prefill_get_spec.rb @@ -59,6 +59,9 @@ describe 'Prefilling a dossier (with a GET request):', js: true do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\//) .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json')) + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret_value[0..8]}/) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json')) + VCR.insert_cassette('api_geo_departements') VCR.insert_cassette('api_geo_communes') VCR.insert_cassette('api_geo_epcis') diff --git a/spec/system/users/dossier_prefill_post_spec.rb b/spec/system/users/dossier_prefill_post_spec.rb index eebb5462d..a9b4eae82 100644 --- a/spec/system/users/dossier_prefill_post_spec.rb +++ b/spec/system/users/dossier_prefill_post_spec.rb @@ -40,6 +40,9 @@ describe 'Prefilling a dossier (with a POST request):', js: true do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret_value}/) .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json')) + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret_value[0..8]}/) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json')) + VCR.insert_cassette('api_geo_departements') VCR.insert_cassette('api_geo_communes') VCR.insert_cassette('api_geo_epcis')