Affiche un message d'erreur clair lorsque l'API-Entreprise est indisponible (#3831)
Un message d'erreur clair est affiché lorsque la récupération des informations à partir du n° SIRET est temporairement indisponible
This commit is contained in:
commit
011b575900
15 changed files with 173 additions and 82 deletions
|
@ -7,25 +7,25 @@ class Champs::SiretController < ApplicationController
|
|||
find_etablisement
|
||||
|
||||
if @siret.empty?
|
||||
@champ&.update!(value: '')
|
||||
@etablissement&.destroy
|
||||
elsif @siret.present? && @siret.length == 14
|
||||
etablissement = find_etablisement_with_siret
|
||||
if etablissement.present?
|
||||
@etablissement = etablissement
|
||||
return clear_siret_and_etablissement
|
||||
end
|
||||
|
||||
if !@champ.nil?
|
||||
@champ.update!(value: etablissement.siret, etablissement: etablissement)
|
||||
end
|
||||
else
|
||||
@champ&.update!(value: '')
|
||||
@etablissement&.destroy
|
||||
@siret = :not_found
|
||||
end
|
||||
else
|
||||
@champ&.update!(value: '')
|
||||
@etablissement&.destroy
|
||||
@siret = :invalid
|
||||
if @siret.present? && @siret.length != 14
|
||||
return siret_error(:invalid)
|
||||
end
|
||||
|
||||
begin
|
||||
etablissement = find_etablissement_with_siret
|
||||
rescue RestClient::RequestFailed
|
||||
return siret_error(:network_error)
|
||||
end
|
||||
if etablissement.blank?
|
||||
return siret_error(:not_found)
|
||||
end
|
||||
|
||||
@etablissement = etablissement
|
||||
if !@champ.nil?
|
||||
@champ.update!(value: etablissement.siret, etablissement: etablissement)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -49,10 +49,20 @@ class Champs::SiretController < ApplicationController
|
|||
@procedure_id = @champ&.dossier&.procedure_id || 'aperçu'
|
||||
end
|
||||
|
||||
def find_etablisement_with_siret
|
||||
def find_etablissement_with_siret
|
||||
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(@siret, @procedure_id)
|
||||
if etablissement_attributes.present?
|
||||
Etablissement.new(etablissement_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def clear_siret_and_etablissement
|
||||
@champ&.update!(value: '')
|
||||
@etablissement&.destroy
|
||||
end
|
||||
|
||||
def siret_error(error)
|
||||
clear_siret_and_etablissement
|
||||
@siret = error
|
||||
end
|
||||
end
|
||||
|
|
|
@ -91,7 +91,11 @@ module Users
|
|||
end
|
||||
|
||||
sanitized_siret = siret_model.siret
|
||||
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(sanitized_siret, @dossier.procedure.id)
|
||||
begin
|
||||
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(sanitized_siret, @dossier.procedure.id)
|
||||
rescue RestClient::RequestFailed
|
||||
return render_siret_error(t('errors.messages.siret_network_error'))
|
||||
end
|
||||
if etablissement_attributes.blank?
|
||||
return render_siret_error(t('errors.messages.siret_unknown'))
|
||||
end
|
||||
|
|
|
@ -2,7 +2,11 @@ class EtablissementUpdateJob < ApplicationJob
|
|||
queue_as :default
|
||||
|
||||
def perform(dossier, siret)
|
||||
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(siret, dossier.procedure_id)
|
||||
begin
|
||||
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(siret, dossier.procedure_id)
|
||||
rescue
|
||||
return
|
||||
end
|
||||
|
||||
if etablissement_attributes.present?
|
||||
if dossier.etablissement.present?
|
||||
|
|
|
@ -7,9 +7,11 @@ class ApiEntreprise::Adapter
|
|||
end
|
||||
|
||||
def data_source
|
||||
@data_source ||= get_resource
|
||||
rescue
|
||||
@data_source = nil
|
||||
begin
|
||||
@data_source ||= get_resource
|
||||
rescue RestClient::ResourceNotFound
|
||||
@data_source = nil
|
||||
end
|
||||
end
|
||||
|
||||
def to_params
|
||||
|
|
|
@ -34,8 +34,10 @@ class ApiEntreprise::API
|
|||
|
||||
if response.success?
|
||||
JSON.parse(response.body, symbolize_names: true)
|
||||
else
|
||||
elsif response.code == 404 || response.code == 422
|
||||
raise RestClient::ResourceNotFound
|
||||
else
|
||||
raise RestClient::RequestFailed
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
class ApiEntrepriseService
|
||||
# Retrieve all informations we can get about a SIRET.
|
||||
#
|
||||
# Returns nil if the SIRET is unknown; and nested params
|
||||
# suitable for being saved into a Etablissement object otherwise.
|
||||
#
|
||||
# Raises a RestClient::RequestFailed exception on transcient errors
|
||||
# (timeout, 5XX HTTP error code, etc.)
|
||||
def self.get_etablissement_params_for_siret(siret, procedure_id)
|
||||
etablissement_params = ApiEntreprise::EtablissementAdapter.new(siret, procedure_id).to_params
|
||||
entreprise_params = ApiEntreprise::EntrepriseAdapter.new(siret, procedure_id).to_params
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
Nous n’avons pas trouvé d’établissement correspondant à ce numéro de SIRET.
|
||||
= link_to('Plus d’informations', "https://faq.demarches-simplifiees.fr/article/4-erreur-siret", target: '_blank', rel: 'noopener')
|
||||
|
||||
- when :network_error
|
||||
= t('errors.messages.siret_network_error')
|
||||
|
||||
- else
|
||||
- if siret.present? && siret == etablissement&.siret
|
||||
= render partial: 'shared/dossiers/editable_champs/etablissement_titre', locals: { etablissement: etablissement }
|
||||
|
|
|
@ -182,7 +182,8 @@ fr:
|
|||
dossier_map_not_activated: "Le dossier n'a pas accès à la cartographie."
|
||||
invalid_siret: "Le siret est incorrect"
|
||||
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_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.'
|
||||
etablissement_fail: 'Désolé, nous n’avons pas réussi à enregistrer l’établissement correspondant à ce numéro SIRET'
|
||||
france_connect:
|
||||
connexion: "Erreur lors de la connexion à France Connect."
|
||||
|
|
|
@ -20,74 +20,105 @@ describe Champs::SiretController, type: :controller do
|
|||
end
|
||||
let(:siret) { '' }
|
||||
|
||||
context 'when user is connected' do
|
||||
context 'when the user is signed in' do
|
||||
render_views
|
||||
before { sign_in user }
|
||||
|
||||
context 'when siret empty' do
|
||||
before {
|
||||
get :show, params: params, format: 'js'
|
||||
}
|
||||
context 'when the SIRET is empty' do
|
||||
subject! { get :show, params: params, format: 'js' }
|
||||
|
||||
it 'empty info message' do
|
||||
it 'clears the etablissement and SIRET on the model' do
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
end
|
||||
|
||||
it 'clears any information or error message' do
|
||||
expect(response.body).to include('.siret-info-1')
|
||||
expect(response.body).to include('innerHTML = ""')
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when siret invalid' do
|
||||
context 'when the SIRET is invalid' do
|
||||
let(:siret) { '1234' }
|
||||
before {
|
||||
get :show, params: params, format: 'js'
|
||||
}
|
||||
|
||||
it 'invalid error' do
|
||||
subject! { get :show, params: params, format: 'js' }
|
||||
|
||||
it 'clears the etablissement and SIRET on the model' do
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
end
|
||||
|
||||
it 'displays a “SIRET is invalid” error message' do
|
||||
expect(response.body).to include('Le numéro de SIRET doit comporter exactement 14 chiffres.')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the API is unavailable' do
|
||||
let(:siret) { '82161143100015' }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:find_etablissement_with_siret).and_raise(RestClient::RequestFailed)
|
||||
end
|
||||
|
||||
subject! { get :show, params: params, format: 'js' }
|
||||
|
||||
it 'clears the etablissement and SIRET on the model' do
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
end
|
||||
|
||||
it 'displays a “API is unavailable” error message' do
|
||||
expect(response.body).to include(I18n.t('errors.messages.siret_network_error'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when siret not found' do
|
||||
let(:siret) { '0' * 14 }
|
||||
before {
|
||||
expect(subject).to receive(:find_etablisement_with_siret).and_return(false)
|
||||
get :show, params: params, format: 'js'
|
||||
}
|
||||
context 'when the SIRET is valid but unknown' do
|
||||
let(:siret) { '00000000000000' }
|
||||
|
||||
it 'not found error' do
|
||||
before do
|
||||
allow(controller).to receive(:find_etablissement_with_siret).and_return(false)
|
||||
end
|
||||
|
||||
subject! { get :show, params: params, format: 'js' }
|
||||
|
||||
it 'clears the etablissement and SIRET on the model' do
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
end
|
||||
|
||||
it 'displays a “SIRET not found” error message' do
|
||||
expect(response.body).to include('Nous n’avons pas trouvé d’établissement correspondant à ce numéro de SIRET.')
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when siret found' do
|
||||
context 'when the SIRET informations are retrieved successfully' do
|
||||
let(:siret) { etablissement.siret }
|
||||
let(:etablissement) { build(:etablissement) }
|
||||
before {
|
||||
expect(subject).to receive(:find_etablisement_with_siret).and_return(etablissement)
|
||||
get :show, params: params, format: 'js'
|
||||
}
|
||||
|
||||
it 'etablissement info message' do
|
||||
expect(response.body).to include(etablissement.entreprise_raison_sociale)
|
||||
before do
|
||||
allow(controller).to receive(:find_etablissement_with_siret).and_return(etablissement)
|
||||
end
|
||||
|
||||
subject! { get :show, params: params, format: 'js' }
|
||||
|
||||
it 'populates the etablissement and SIRET on the model' do
|
||||
champ.reload
|
||||
expect(champ.value).to eq(etablissement.siret)
|
||||
expect(champ.etablissement.siret).to eq(etablissement.siret)
|
||||
end
|
||||
|
||||
it 'displays the name of the company' do
|
||||
expect(response.body).to include(etablissement.entreprise_raison_sociale)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not connected' do
|
||||
before {
|
||||
get :show, params: { position: '1' }, format: 'js'
|
||||
}
|
||||
context 'when user is not signed in' do
|
||||
subject! { get :show, params: { position: '1' }, format: 'js' }
|
||||
|
||||
it { expect(response.code).to eq('401') }
|
||||
end
|
||||
|
|
|
@ -278,6 +278,13 @@ describe Users::DossiersController, type: :controller do
|
|||
context 'with a valid SIRET' do
|
||||
let(:params_siret) { '440 117 620 01530' }
|
||||
|
||||
context 'When API-Entreprise is down' do
|
||||
let(:api_etablissement_status) { 502 }
|
||||
let(:api_body_status) { File.read('spec/fixtures/files/api_entreprise/exercices_unavailable.json') }
|
||||
|
||||
it_behaves_like 'the request fails with an error', I18n.t('errors.messages.siret_network_error')
|
||||
end
|
||||
|
||||
context 'when API-Entreprise doesn’t know this SIRET' do
|
||||
let(:api_etablissement_status) { 404 }
|
||||
let(:api_body_status) { '' }
|
||||
|
|
7
spec/fixtures/files/api_entreprise/entreprises_unavailable.json
vendored
Normal file
7
spec/fixtures/files/api_entreprise/entreprises_unavailable.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"errors": [
|
||||
"Erreur interne du serveur",
|
||||
"Le siret ou siren indiqué n'existe pas, n'est pas connu ou ne comporte aucune information pour cet appel"
|
||||
],
|
||||
"gateway_error": true
|
||||
}
|
|
@ -2,21 +2,35 @@ require 'spec_helper'
|
|||
|
||||
describe ApiEntreprise::API do
|
||||
let(:procedure_id) { 12 }
|
||||
|
||||
describe '.entreprise' do
|
||||
subject { described_class.entreprise(siren, procedure_id) }
|
||||
|
||||
before do
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=/)
|
||||
.to_return(status: status, body: body)
|
||||
end
|
||||
|
||||
context 'when the service is unavailable' do
|
||||
let(:siren) { '111111111' }
|
||||
let(:status) { 502 }
|
||||
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_unavailable.json') }
|
||||
|
||||
it 'raises RestClient::RequestFailed' do
|
||||
expect { subject }.to raise_error(RestClient::RequestFailed)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when siren does not exist' do
|
||||
let(:siren) { '111111111' }
|
||||
let(:status) { 404 }
|
||||
let(:body) { '' }
|
||||
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_not_found.json') }
|
||||
|
||||
it 'raises RestClient::ResourceNotFound' do
|
||||
expect { subject }.to raise_error(RestClient::ResourceNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when siret exist' do
|
||||
let(:siren) { '418166096' }
|
||||
let(:status) { 200 }
|
||||
|
|
|
@ -11,7 +11,7 @@ describe ApiEntreprise::EntrepriseAdapter do
|
|||
.to_return(body: body, status: status)
|
||||
end
|
||||
|
||||
context "when SIRET is OK" do
|
||||
context "when the SIRET is valid" do
|
||||
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises.json') }
|
||||
let(:status) { 200 }
|
||||
|
||||
|
@ -70,12 +70,21 @@ describe ApiEntreprise::EntrepriseAdapter do
|
|||
end
|
||||
end
|
||||
|
||||
context "when SIRET is KO" do
|
||||
context "when the SIRET is unknown" do
|
||||
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_not_found.json') }
|
||||
let(:status) { 206 }
|
||||
let(:status) { 404 }
|
||||
|
||||
it '#to_params class est une Hash ?' do
|
||||
expect(subject).to eq({})
|
||||
end
|
||||
end
|
||||
|
||||
context "when the service is unavailable" do
|
||||
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_unavailable.json') }
|
||||
let(:status) { 502 }
|
||||
|
||||
it 'raises an exception' do
|
||||
expect { subject }.to raise_error(RestClient::RequestFailed)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,25 +10,15 @@ describe ApiEntreprise::ExercicesAdapter do
|
|||
.to_return(body: File.read('spec/fixtures/files/api_entreprise/exercices.json', status: 200))
|
||||
end
|
||||
|
||||
it '#to_params class est un Hash ?' do
|
||||
expect(subject).to be_an_instance_of(Hash)
|
||||
end
|
||||
it { is_expected.to be_an_instance_of(Hash) }
|
||||
|
||||
it 'have 3 exercices' do
|
||||
it 'contains several exercices attributes' do
|
||||
expect(subject[:exercices_attributes].size).to eq(3)
|
||||
end
|
||||
|
||||
context 'Attributs Exercices' do
|
||||
it 'L\'exercice contient bien un ca' do
|
||||
expect(subject[:exercices_attributes][0][:ca]).to eq('21009417')
|
||||
end
|
||||
|
||||
it 'L\'exercice contient bien une date de fin d\'exercice' do
|
||||
expect(subject[:exercices_attributes][0][:date_fin_exercice]).to eq("2013-12-31T00:00:00+01:00")
|
||||
end
|
||||
|
||||
it 'L\'exercice contient bien une date_fin_exercice_timestamp' do
|
||||
expect(subject[:exercices_attributes][0][:date_fin_exercice_timestamp]).to eq(1388444400)
|
||||
end
|
||||
it 'contains informations in each exercices_attributes' do
|
||||
expect(subject[:exercices_attributes][0][:ca]).to eq('21009417')
|
||||
expect(subject[:exercices_attributes][0][:date_fin_exercice]).to eq("2013-12-31T00:00:00+01:00")
|
||||
expect(subject[:exercices_attributes][0][:date_fin_exercice_timestamp]).to eq(1388444400)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ describe ApiEntreprise::RNAAdapter do
|
|||
context 'when siret is not valid' do
|
||||
let(:siret) { '234567' }
|
||||
let(:body) { '' }
|
||||
let(:status) { '404' }
|
||||
let(:status) { 404 }
|
||||
|
||||
it { is_expected.to eq({}) }
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue