Skip to content

Commit d857c85

Browse files
committed
feat(usager): show non-blocking info message when external data is pending or in technical error
1 parent 8371a28 commit d857c85

6 files changed

Lines changed: 59 additions & 0 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
= @form.text_field(:external_id, input_opts(value: pretty_siret(@champ.external_id), id: @champ.focusable_input_id, aria: { **labelledby_id_attr, describedby: "#{@champ.describedby_id} #{@champ.error_id(:value)}" }, data: { controller: 'format', format: 'siret', }, required: @champ.required?, class: "width-33-desktop"))
2+
3+
- if @champ.external_data_status_message.present?
4+
%p.fr-info-text{ role: 'status' }= t("shared.champs.external_data.#{@champ.external_data_status_message}")

app/models/concerns/champ_external_data_concern.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ module ChampExternalDataConcern
6767
def pending? = waiting_for_job? || fetching?
6868
def done? = fetched? || external_error?
6969

70+
# Non-blocking status surfaced to the usager while they can still submit.
71+
# Returns :pending or :technical_error, or nil when there is nothing to show:
72+
# fetched, an explicit :not_found (handled by a blocking validation error),
73+
# or when the data is required for a logic condition (legacy blocking).
74+
def external_data_status_message
75+
return nil if external_data_required_for_conditions?
76+
return :pending if pending?
77+
return :technical_error if external_error? && fetch_external_data_exceptions&.first&.kind != :not_found
78+
79+
nil
80+
end
81+
7082
def has_async_external_data? = false
7183

7284
def external_data_needed_for_validation? = has_async_external_data?

config/i18n-tasks.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ search:
9999
## Consider these keys used:
100100
ignore_unused:
101101
- 'errors.format'
102+
- 'shared.champs.external_data.*' # dynamic key: t("shared.champs.external_data.#{external_data_status_message}")
102103
- 'user_mailer.*.subject'
103104
- 'activerecord.models.*'
104105
- 'activerecord.attributes.*'

config/locales/shared.en.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ en:
2323
move_down: Move down
2424

2525
champs:
26+
external_data:
27+
pending: "Automatic verification of the number is in progress. You can continue submitting; the information will be retrieved as soon as possible."
28+
technical_error: "Automatic verification is temporarily unavailable. You can continue submitting; the information will be retrieved as soon as possible."
2629
drop_down_list:
2730
other: Enter another option
2831
other_label: Enter your option

config/locales/shared.fr.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ fr:
2525
move_down: Déplacer vers le bas
2626

2727
champs:
28+
external_data:
29+
pending: "La vérification automatique du numéro est en cours. Vous pouvez poursuivre le dépôt ; les informations seront récupérées dès que possible."
30+
technical_error: "La vérification automatique est temporairement indisponible. Vous pouvez poursuivre le dépôt ; les informations seront récupérées dès que possible."
2831
rna:
2932
show:
3033
not_filled: non renseigné

spec/models/concerns/champ_external_data_concern_spec.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,43 @@
7979
end
8080
end
8181

82+
describe '#external_data_status_message' do
83+
let(:champ) { Champs::SiretChamp.new }
84+
85+
it 'returns nil when fetched' do
86+
allow(champ).to receive_messages(pending?: false, external_error?: false)
87+
expect(champ.external_data_status_message).to be_nil
88+
end
89+
90+
it 'returns :pending when pending and not required for conditions' do
91+
allow(champ).to receive_messages(pending?: true, external_error?: false, external_data_required_for_conditions?: false)
92+
expect(champ.external_data_status_message).to eq(:pending)
93+
end
94+
95+
it 'returns :technical_error on external_error with non-not_found kind' do
96+
allow(champ).to receive_messages(
97+
pending?: false, external_error?: true,
98+
external_data_required_for_conditions?: false,
99+
fetch_external_data_exceptions: [ExternalDataException.new(error: 'x', code: 503, kind: :technical_error)]
100+
)
101+
expect(champ.external_data_status_message).to eq(:technical_error)
102+
end
103+
104+
it 'returns nil on :not_found (handled by the validation error)' do
105+
allow(champ).to receive_messages(
106+
pending?: false, external_error?: true,
107+
external_data_required_for_conditions?: false,
108+
fetch_external_data_exceptions: [ExternalDataException.new(error: 'x', code: 404, kind: :not_found)]
109+
)
110+
expect(champ.external_data_status_message).to be_nil
111+
end
112+
113+
it 'returns nil when external_data_required_for_conditions? is true' do
114+
allow(champ).to receive_messages(pending?: true, external_error?: false, external_data_required_for_conditions?: true)
115+
expect(champ.external_data_status_message).to be_nil
116+
end
117+
end
118+
82119
describe 'the state machine' do
83120
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :rnf }]) }
84121
let(:dossier) { create(:dossier, procedure:) }

0 commit comments

Comments
 (0)