diff --git a/app/components/editable_champ/rna_component/rna_component.html.haml b/app/components/editable_champ/rna_component/rna_component.html.haml index 25f153605..12ee063a4 100644 --- a/app/components/editable_champ/rna_component/rna_component.html.haml +++ b/app/components/editable_champ/rna_component/rna_component.html.haml @@ -9,4 +9,4 @@ class: "width-33-desktop", maxlength: 10 .rna-info{ id: dom_id(@champ, :rna_info) } - = render 'shared/champs/rna/association', champ: @champ + = render 'shared/champs/rna/association', champ: @champ, network_error: false, rna: @champ.value diff --git a/app/controllers/champs/rna_controller.rb b/app/controllers/champs/rna_controller.rb index ea2845896..adad8cac5 100644 --- a/app/controllers/champs/rna_controller.rb +++ b/app/controllers/champs/rna_controller.rb @@ -4,11 +4,13 @@ class Champs::RNAController < ApplicationController def show @champ = policy_scope(Champ).find(params[:champ_id]) @rna = read_param_value(@champ.input_name, 'value') + @network_error = false begin data = APIEntreprise::RNAAdapter.new(@rna, @champ.procedure_id).to_params - @champ.update(data: data, value: @rna, skip_cleanup: true, skip_fetch: true) - rescue => error - @champ.update(data: nil, value: @rna, skip_cleanup: true, skip_fetch: true) + @champ.update!(data: data, value: @rna, skip_cleanup: true, skip_fetch: true) + rescue APIEntreprise::API::Error, ActiveRecord::RecordInvalid => error + @network_error = true if error.try(:network_error?) && !APIEntrepriseService.api_up? + @champ.update(data: nil, value: nil, skip_cleanup: true, skip_fetch: true) end end end diff --git a/app/views/champs/rna/show.turbo_stream.haml b/app/views/champs/rna/show.turbo_stream.haml index 969511a3d..e87d3b7e1 100644 --- a/app/views/champs/rna/show.turbo_stream.haml +++ b/app/views/champs/rna/show.turbo_stream.haml @@ -1 +1 @@ -= turbo_stream.update dom_id(@champ, :rna_info), partial: 'shared/champs/rna/association', locals: { champ: @champ } += turbo_stream.update dom_id(@champ, :rna_info), partial: 'shared/champs/rna/association', locals: { champ: @champ, network_error: @network_error, rna: @rna } diff --git a/app/views/shared/champs/rna/_association.html.haml b/app/views/shared/champs/rna/_association.html.haml index 16daf4bad..bda49c3d9 100644 --- a/app/views/shared/champs/rna/_association.html.haml +++ b/app/views/shared/champs/rna/_association.html.haml @@ -1,4 +1,6 @@ -- if champ.value.present? && champ.data.blank? +- if network_error + %p.pt-1= t('.network_error') +- elsif @rna.present? && champ.data.blank? %p.pt-1= t('.not_found') - elsif champ.value.present? %p.pt-1= t('.data_fetched', title: champ.title) diff --git a/config/locales/shared.en.yml b/config/locales/shared.en.yml index b02ddfb4f..cad983781 100644 --- a/config/locales/shared.en.yml +++ b/config/locales/shared.en.yml @@ -24,6 +24,7 @@ en: association: data_fetched: "This RNA number is linked to %{title}" not_found: "No association found" + network_error: "A network error has prevented the association associated with this RNA to be fetched" dgfip: show: not_filled: not filled diff --git a/config/locales/shared.fr.yml b/config/locales/shared.fr.yml index 1d3f41563..5076310da 100644 --- a/config/locales/shared.fr.yml +++ b/config/locales/shared.fr.yml @@ -26,6 +26,7 @@ fr: association: data_fetched: "Ce RNA correspond à %{title}" not_found: "Aucun établissement trouvé" + network_error: "Une erreur réseau a empêché l'association liée à ce RNA d'être trouvée" dgfip: show: not_filled: non renseigné diff --git a/spec/controllers/champs/rna_controller_spec.rb b/spec/controllers/champs/rna_controller_spec.rb new file mode 100644 index 000000000..06554632a --- /dev/null +++ b/spec/controllers/champs/rna_controller_spec.rb @@ -0,0 +1,157 @@ +describe Champs::RNAController, type: :controller do + let(:user) { create(:user) } + let(:procedure) { create(:procedure, :published, :with_rna) } + + describe '#show' do + let(:dossier) { create(:dossier, user: user, procedure: procedure) } + let(:champ) { dossier.champs.first } + + let(:champs_attributes) do + champ_attributes = [] + champ_attributes[champ.id] = { value: rna } + champ_attributes + end + let(:params) do + { + champ_id: champ.id, + dossier: { + champs_attributes: champs_attributes + } + } + end + + context 'when the user is signed in' do + render_views + + before do + sign_in user + stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/associations\//) + .to_return(body: body, status: status) + allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(false) + end + + context 'when the RNA is empty' do + let(:rna) { '' } + let(:status) { 422 } + let(:body) { '' } + + subject! { get :show, params: params, format: :turbo_stream } + + it 'clears the data and value on the model' do + champ.reload + expect(champ.data).to eq({}) + expect(champ.value).to eq("") + end + + it 'clears any information or error message' do + expect(response.body).to include(ActionView::RecordIdentifier.dom_id(champ, :rna_info)) + end + end + + context 'when the RNA is invalid' do + let(:rna) { '1234' } + let(:status) { 422 } + let(:body) { '' } + + subject! { get :show, params: params, format: :turbo_stream } + + it 'clears the data and value on the model' do + champ.reload + expect(champ.data).to be_nil + expect(champ.value).to be_nil + end + + it 'displays a “RNA is invalid” error message' do + expect(response.body).to include("Aucun établissement trouvé") + end + end + + context 'when the RNA is unknow' do + let(:rna) { 'W111111111' } + let(:status) { 404 } + let(:body) { '' } + + subject! { get :show, params: params, format: :turbo_stream } + + it 'clears the data on the model' do + champ.reload + expect(champ.data).to eq({}) + end + + it 'displays a “RNA is invalid” error message' do + expect(response.body).to include("Aucun établissement trouvé") + end + end + + context 'when the API is unavailable due to network error' do + let(:rna) { 'W595001988' } + let(:status) { 503 } + let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') } + + before do + expect(APIEntrepriseService).to receive(:api_up?).and_return(false) + end + + subject! { get :show, params: params, format: :turbo_stream } + + it 'clears the data and value on the model' do + champ.reload + expect(champ.data).to be_nil + expect(champ.value).to be_nil + end + + it 'displays a “API is unavailable” error message' do + expect(response.body).to include("Une erreur réseau a empêché l'association liée à ce RNA d'être trouvée") + end + end + + context 'when the RNA informations are retrieved successfully' do + let(:rna) { 'W595001988' } + let(:status) { 200 } + let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') } + let(:expected_data) do + { "association_id"=>"W595001988", + "association_titre"=>"UN SUR QUATRE", + "association_objet"=>"valoriser, transmettre et partager auprès des publics les plus larges possibles, les bienfaits de l'immigration, la richesse de la diversité et la curiosité de l'autre autrement", + "association_siret"=>nil, + "association_date_creation"=>"2014-01-23", + "association_date_declaration"=>"2014-01-24", + "association_date_publication"=>"2014-02-08", + "association_date_dissolution"=>"0001-01-01", + "association_adresse_siege"=> { + "complement"=>"", + "numero_voie"=>"61", + "type_voie"=>"RUE", + "libelle_voie"=>"des Noyers", + "distribution"=>"_", + "code_insee"=>"93063", + "code_postal"=>"93230", + "commune"=>"Romainville" + }, + "association_code_civilite_dirigeant"=>"PM", + "association_civilite_dirigeant"=>"Monsieur le Président", + "association_code_etat"=>"A", + "association_etat"=>"Active", + "association_code_groupement"=>"S", + "association_groupement"=>"simple", + "association_mise_a_jour"=>1392295833, + "association_rna"=>"W595001988" } + end + + subject! { get :show, params: params, format: :turbo_stream } + + it 'populates the data and RNA on the model' do + champ.reload + expect(champ.value).to eq(rna) + expect(champ.data).to eq(expected_data) + end + end + end + + context 'when user is not signed in' do + subject! { get :show, params: { champ_id: champ.id }, format: :turbo_stream } + + it { expect(response.code).to eq('401') } + end + end +end diff --git a/spec/lib/api_entreprise/rna_adapter_spec.rb b/spec/lib/api_entreprise/rna_adapter_spec.rb index 9edd2f05a..b20172751 100644 --- a/spec/lib/api_entreprise/rna_adapter_spec.rb +++ b/spec/lib/api_entreprise/rna_adapter_spec.rb @@ -1,8 +1,8 @@ describe APIEntreprise::RNAAdapter do - let(:siret) { '50480511000013' } + let(:rna) { 'W111111111' } let(:procedure) { create(:procedure) } let(:procedure_id) { procedure.id } - let(:adapter) { described_class.new(siret, procedure_id) } + let(:adapter) { described_class.new(rna, procedure_id) } subject { adapter.to_params } @@ -12,8 +12,8 @@ describe APIEntreprise::RNAAdapter do allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(false) end - context 'when siret is not valid' do - let(:siret) { '234567' } + context 'when rna is not valid' do + let(:rna) { '234567' } let(:body) { '' } let(:status) { 404 } @@ -45,7 +45,7 @@ describe APIEntreprise::RNAAdapter do end context "when depreciated adapter is used" do - let(:adapter) { described_class.new(siret, procedure_id, true) } + let(:adapter) { described_class.new(rna, procedure_id, true) } let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') } let(:status) { 200 }