siret champ can fetch it's own etablissement

This commit is contained in:
Sébastien Carceles 2023-01-09 15:29:18 +01:00 committed by sebastiencarceles
parent b9080e2ff5
commit 5876dab096
3 changed files with 130 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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