Skip to content

Commit 637fca6

Browse files
theabradMrNagoo
authored andcommitted
LG-15440 We couldnt find records matching your address screen (#12066)
* add address errors page * add address proofing exception redirect * add changelog changelog: User-Facing Improvements, Doc Auth, add we couldnt find your address screen * linty mclinterson * refactor rate limiter code in session_errors_controller * rename rate limiter to resolution_rate_limiter * changed to resolution result instead of residential_resolution_result * add address_exception to resolution result * move address fail check to verify_info_concern * linty mclinterson * rate limiter fixups * redirect to address warning if there is ONLY an address exception * lint fix
1 parent 94bf059 commit 637fca6

File tree

12 files changed

+289
-13
lines changed

12 files changed

+289
-13
lines changed

app/controllers/concerns/idv/verify_info_concern.rb

+32
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,23 @@ def ssn_rate_limiter
7979
)
8080
end
8181

82+
def address_exception?(result)
83+
result.extra.dig(
84+
:proofing_results,
85+
:context,
86+
:stages,
87+
:resolution,
88+
:exception,
89+
).present? &&
90+
result.extra.dig(
91+
:proofing_results,
92+
:context,
93+
:stages,
94+
:resolution,
95+
:attributes_requiring_additional_verification,
96+
) == ['address']
97+
end
98+
8299
def idv_failure(result)
83100
proofing_results_exception = result.extra.dig(:proofing_results, :exception)
84101
has_exception = proofing_results_exception.present?
@@ -89,6 +106,7 @@ def idv_failure(result)
89106
:state_id,
90107
:mva_exception,
91108
).present?
109+
is_address_exception = address_exception?(result)
92110
is_threatmetrix_exception = result.extra.dig(
93111
:proofing_results,
94112
:context,
@@ -113,6 +131,9 @@ def idv_failure(result)
113131
elsif has_exception && is_mva_exception
114132
idv_failure_log_warning
115133
redirect_to state_id_warning_url
134+
elsif has_exception && is_address_exception
135+
idv_failure_log_address_warning
136+
redirect_to address_warning_url
116137
elsif (has_exception && is_threatmetrix_exception) ||
117138
(!has_exception && resolution_failed)
118139
idv_failure_log_warning
@@ -147,6 +168,13 @@ def idv_failure_log_error
147168
)
148169
end
149170

171+
def idv_failure_log_address_warning
172+
analytics.idv_doc_auth_address_warning_visited(
173+
step_name: STEP_NAME,
174+
remaining_submit_attempts: resolution_rate_limiter.remaining_count,
175+
)
176+
end
177+
150178
def idv_failure_log_warning
151179
analytics.idv_doc_auth_warning_visited(
152180
step_name: STEP_NAME,
@@ -166,6 +194,10 @@ def state_id_warning_url
166194
idv_session_errors_state_id_warning_url(flow: flow_param)
167195
end
168196

197+
def address_warning_url
198+
idv_session_errors_address_warning_url(flow: flow_param)
199+
end
200+
169201
def warning_url
170202
idv_session_errors_warning_url(flow: flow_param)
171203
end

app/controllers/idv/session_errors_controller.rb

+18-13
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,26 @@ def exception
1616
end
1717

1818
def warning
19-
rate_limiter = RateLimiter.new(
20-
user: idv_session_user,
21-
rate_limit_type: :idv_resolution,
22-
)
23-
2419
@step_indicator_steps = step_indicator_steps
25-
@remaining_submit_attempts = rate_limiter.remaining_count
26-
log_event(based_on_limiter: rate_limiter)
20+
@remaining_submit_attempts = resolution_rate_limiter.remaining_count
21+
log_event(based_on_limiter: resolution_rate_limiter)
2722
end
2823

2924
def state_id_warning
3025
log_event
3126
end
3227

28+
def address_warning
29+
@step_indicator_steps = step_indicator_steps
30+
@address_path = idv_address_url
31+
@remaining_submit_attempts = resolution_rate_limiter.remaining_count
32+
log_event(based_on_limiter: resolution_rate_limiter)
33+
end
34+
3335
def failure
34-
rate_limiter = RateLimiter.new(
35-
user: idv_session_user,
36-
rate_limit_type: :idv_resolution,
37-
)
38-
@expires_at = rate_limiter.expires_at
36+
@expires_at = resolution_rate_limiter.expires_at
3937
@sp_name = decorated_sp_session.sp_name
40-
log_event(based_on_limiter: rate_limiter)
38+
log_event(based_on_limiter: resolution_rate_limiter)
4139
end
4240

4341
def ssn_failure
@@ -63,6 +61,13 @@ def rate_limited
6361

6462
private
6563

64+
def resolution_rate_limiter
65+
@resolution_rate_limiter ||= RateLimiter.new(
66+
user: idv_session_user,
67+
rate_limit_type: :idv_resolution,
68+
)
69+
end
70+
6671
def confirm_two_factor_authenticated_or_user_id_in_session
6772
return if session[:doc_capture_user_id].present?
6873

app/services/analytics_events.rb

+12
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,18 @@ def idv_consent_checkbox_toggled(checked:, **extra)
12261226
)
12271227
end
12281228

1229+
# @param [String] step_name
1230+
# @param [Integer] remaining_submit_attempts (previously called "remaining_attempts")
1231+
# The user was sent to a warning page during the IDV flow
1232+
def idv_doc_auth_address_warning_visited(step_name:, remaining_submit_attempts:, **extra)
1233+
track_event(
1234+
:idv_doc_auth_address_warning_visited,
1235+
step_name: step_name,
1236+
remaining_submit_attempts: remaining_submit_attempts,
1237+
**extra,
1238+
)
1239+
end
1240+
12291241
# User has consented to share information with document upload and may
12301242
# view the "hybrid handoff" step next unless "skip_hybrid_handoff" param is true
12311243
# @param [Boolean] success Whether form validation was successful
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<% self.title = t('titles.failure.information_not_verified') %>
2+
3+
<% content_for(:pre_flash_content) do %>
4+
<%= render StepIndicatorComponent.new(
5+
steps: @step_indicator_steps,
6+
current_step: :verify_info,
7+
locale_scope: 'idv',
8+
class: 'margin-x-neg-2 margin-top-neg-4 tablet:margin-x-neg-6 tablet:margin-top-neg-4',
9+
) %>
10+
<% end %>
11+
12+
<%= render StatusPageComponent.new(status: :warning) do |c| %>
13+
<% c.with_header { t('idv.warning.address.heading') } %>
14+
15+
<p><%= t('idv.failure.address.warning') %></p>
16+
<p><%= t('idv.failure.attempts_html', count: @remaining_submit_attempts) %></p>
17+
18+
<% c.with_action_button(
19+
url: @address_path,
20+
class: 'margin-bottom-2',
21+
) { t('idv.forgot_password.try_again') } %>
22+
<% end %>
23+
24+
<%= render PageFooterComponent.new do %>
25+
<%= link_to t('links.cancel'), idv_cancel_path(step: :invalid_session) %>
26+
<% end %>

config/locales/en.yml

+2
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,7 @@ idv.errors.pattern_mismatch.zipcode: Enter a 5 or 9 digit ZIP Code
10601060
idv.errors.pattern_mismatch.zipcode_five: Enter a 5 digit ZIP Code
10611061
idv.errors.technical_difficulties: We are having technical difficulties
10621062
idv.errors.try_again_later: Try again later.
1063+
idv.failure.address.warning: Please check the information you entered and try again. If your mailing address is different than your residential address, try entering the address where you currently live.
10631064
idv.failure.attempts_html.one: You can try <strong>1 more time.</strong> Then you must wait 6 hours before trying again.
10641065
idv.failure.attempts_html.other: You can try <strong>%{count} more times.</strong> Then you must wait 6 hours before trying again.
10651066
idv.failure.button.try_online: Try again online
@@ -1205,6 +1206,7 @@ idv.unavailable.idv_explanation.without_sp: The agency that you are trying to ac
12051206
idv.unavailable.next_steps_html: '%{status_page_link_html} or exit %{app_name} and try again later.'
12061207
idv.unavailable.status_page_link: Get updates on our status page
12071208
idv.unavailable.technical_difficulties: Unfortunately, we are having technical difficulties and cannot verify your identity at this time.
1209+
idv.warning.address.heading: We couldn’t find records matching your address
12081210
idv.warning.sessions.heading: We couldn’t find records matching your personal information
12091211
idv.warning.state_id.cancel_button: Exit %{app_name}
12101212
idv.warning.state_id.explanation: Unfortunately, we’re experiencing technical difficulties with IDs from your state and are currently unable to verify your information.

config/locales/es.yml

+2
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,7 @@ idv.errors.pattern_mismatch.zipcode: Ingrese un código postal de 5 o 9 dígitos
10711071
idv.errors.pattern_mismatch.zipcode_five: Ingrese un código postal de 5 dígitos.
10721072
idv.errors.technical_difficulties: Estamos teniendo problemas técnicos
10731073
idv.errors.try_again_later: Vuelva a intentarlo más tarde.
1074+
idv.failure.address.warning: Revise la información que ingresó y vuelva a intentarlo. Si su dirección postal no es igual que su domicilio, intente ingresar la dirección donde vive actualmente.
10741075
idv.failure.attempts_html.one: Puede intentarlo <strong>una vez más.</strong> Luego debe esperar 6 horas antes de volver a intentarlo.
10751076
idv.failure.attempts_html.other: Puede intentarlo <strong>%{count} veces más.</strong> Luego debe esperar 6 horas antes de volver a intentarlo.
10761077
idv.failure.button.try_online: Vuelva a intentarlo en línea
@@ -1216,6 +1217,7 @@ idv.unavailable.idv_explanation.without_sp: La agencia a la que está intentando
12161217
idv.unavailable.next_steps_html: '%{status_page_link_html} o salga de %{app_name} y vuelva a intentarlo más tarde.'
12171218
idv.unavailable.status_page_link: Obtenga las actualizaciones en nuestra página de estado
12181219
idv.unavailable.technical_difficulties: Lamentablemente, tenemos problemas técnicos y no podemos verificar su identidad en este momento.
1220+
idv.warning.address.heading: No encontramos registros que coincidan con su dirección
12191221
idv.warning.sessions.heading: No encontramos registros que coincidan con sus datos personales
12201222
idv.warning.state_id.cancel_button: Salir de %{app_name}
12211223
idv.warning.state_id.explanation: Lamentablemente, tenemos problemas técnicos con las identificaciones de su estado y no podemos verificar su información en este momento.

config/locales/fr.yml

+2
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,7 @@ idv.errors.pattern_mismatch.zipcode: Saisissez un code postal à 5 ou 9 chiffres
10601060
idv.errors.pattern_mismatch.zipcode_five: Saisissez un code postal à 5 chiffres
10611061
idv.errors.technical_difficulties: Nous rencontrons des difficultés techniques
10621062
idv.errors.try_again_later: Veuillez réessayer ultérieurement.
1063+
idv.failure.address.warning: Veuillez vérifier les informations que vous avez saisies et réessayer. Si votre adresse postale est différente de votre adresse personnelle, veuillez saisir l’adresse où vous résidez actuellement.
10631064
idv.failure.attempts_html.one: Vous avez encore <strong>un essai.</strong> Vous devrez ensuite attendre 6 heures avant de réessayer.
10641065
idv.failure.attempts_html.other: Vous pouvez encore essayer <strong>%{count} fois de plus.</strong> Ensuite vous devrez ensuite attendre 6 heures avant de réessayer.
10651066
idv.failure.button.try_online: Réessayer en ligne
@@ -1205,6 +1206,7 @@ idv.unavailable.idv_explanation.without_sp: L’organisme auquel vous essayez d
12051206
idv.unavailable.next_steps_html: '%{status_page_link_html} ou quittez le site %{app_name} et réessayez plus tard.'
12061207
idv.unavailable.status_page_link: Obtenir les dernières informations sur notre page d’état des systèmes.
12071208
idv.unavailable.technical_difficulties: Malheureusement, nous rencontrons des difficultés techniques et ne pouvons pas vérifier votre identité pour le moment.
1209+
idv.warning.address.heading: Nous n’avons pas trouvé d’informations correspondant à votre adresse
12081210
idv.warning.sessions.heading: Nous n’avons pas trouvé de dossiers correspondant à vos informations personnelles
12091211
idv.warning.state_id.cancel_button: Quitter %{app_name}
12101212
idv.warning.state_id.explanation: Malheureusement, nous rencontrons des difficultés techniques avec les pièces d’identité de votre État et ne sommes pas en mesure de vérifier vos informations pour le moment.

config/locales/zh.yml

+2
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,7 @@ idv.errors.pattern_mismatch.zipcode: 输入 5 或 9 位的邮编
10731073
idv.errors.pattern_mismatch.zipcode_five: 输入 5 位的邮编
10741074
idv.errors.technical_difficulties: 我们目前遇到技术困难
10751075
idv.errors.try_again_later: 请稍后再试。
1076+
idv.failure.address.warning: 请检查一下你输入的信息,然后再试一下。如果你的邮寄地址与居住地址不同,请尝试输入你目前居住的地址。
10761077
idv.failure.attempts_html.one: 您可以再试<strong>1次。</strong> 然后您必须等6个小时才能再试。
10771078
idv.failure.attempts_html.other: 您可以再试<strong>%{count}次。</strong> 然后您必须等6个小时才能再试。
10781079
idv.failure.button.try_online: 在网上再试一下
@@ -1218,6 +1219,7 @@ idv.unavailable.idv_explanation.without_sp: 你试图访问的机构需要确保
12181219
idv.unavailable.next_steps_html: '%{status_page_link_html} 或者退出 %{app_name},稍后再试。'
12191220
idv.unavailable.status_page_link: 在我们的状态页面获得最新信息。
12201221
idv.unavailable.technical_difficulties: 很遗憾,我们这边现在遇到技术困难,目前无法验证你的身份。
1222+
idv.warning.address.heading: 我们找不到与你地址匹配的记录
12211223
idv.warning.sessions.heading: 我们找不到与你个人信息匹配的记录
12221224
idv.warning.state_id.cancel_button: 退出 %{app_name}
12231225
idv.warning.state_id.explanation: 遗憾的是,处理来自你所在州的身份证件时我们遇到技术困难,目前无法验证你的信息。

config/routes.rb

+1
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@
425425
put '/enter_password' => 'enter_password#create'
426426
get '/session/errors/warning' => 'session_errors#warning'
427427
get '/session/errors/state_id_warning' => 'session_errors#state_id_warning'
428+
get '/session/errors/address_warning' => 'session_errors#address_warning'
428429
get '/session/errors/failure' => 'session_errors#failure'
429430
get '/session/errors/ssn_failure' => 'session_errors#ssn_failure'
430431
get '/session/errors/exception' => 'session_errors#exception'

spec/controllers/idv/session_errors_controller_spec.rb

+62
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,68 @@
234234
end
235235
end
236236

237+
describe '#address_warning' do
238+
let(:action) { :address_warning }
239+
let(:template) { 'idv/session_errors/address_warning' }
240+
241+
subject(:response) { get action }
242+
it_behaves_like 'an idv session errors controller action'
243+
244+
context 'with rate limit attempts' do
245+
let(:user) { create(:user) }
246+
247+
before do
248+
RateLimiter.new(rate_limit_type: :idv_resolution, user: user).increment!
249+
end
250+
251+
it 'assigns remaining count' do
252+
response
253+
254+
expect(assigns(:remaining_submit_attempts)).to be_kind_of(Numeric)
255+
end
256+
257+
it 'assigns URL to try again' do
258+
response
259+
260+
expect(assigns(:address_path)).to eq(idv_address_url)
261+
end
262+
263+
it 'logs an event with attempts remaining' do
264+
response
265+
266+
expect(@analytics).to have_logged_event(
267+
'IdV: session error visited',
268+
type: action.to_s,
269+
remaining_submit_attempts: IdentityConfig.store.idv_max_attempts - 1,
270+
)
271+
end
272+
end
273+
274+
context 'while rate limited' do
275+
let(:user) { create(:user) }
276+
277+
before do
278+
RateLimiter.new(rate_limit_type: :idv_resolution, user: user).increment_to_limited!
279+
end
280+
281+
it 'assigns expiration time' do
282+
get action
283+
284+
expect(assigns(:expires_at)).not_to eq(Time.zone.now)
285+
end
286+
287+
it 'logs an event with attempts remaining' do
288+
get action
289+
290+
expect(@analytics).to have_logged_event(
291+
'IdV: session error visited',
292+
type: 'address_warning',
293+
remaining_submit_attempts: 0,
294+
)
295+
end
296+
end
297+
end
298+
237299
describe '#failure' do
238300
let(:action) { :failure }
239301
let(:template) { 'idv/session_errors/failure' }

spec/controllers/idv/verify_info_controller_spec.rb

+73
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,79 @@
543543
end
544544
end
545545

546+
context 'when instant verify address proofing results in an exception' do
547+
let(:document_capture_session) do
548+
DocumentCaptureSession.create(user:)
549+
end
550+
let(:success) { false }
551+
let(:errors) { {} }
552+
let(:exception) { nil }
553+
let(:error_attributes) { nil }
554+
let(:vendor_name) { 'instantverify_placeholder' }
555+
let(:async_state) do
556+
# Here we're trying to match the store to redis -> read from redis flow this data travels
557+
adjudicated_result = Proofing::Resolution::ResultAdjudicator.new(
558+
state_id_result: Proofing::StateIdResult.new(success: true),
559+
phone_finder_result: Proofing::AddressResult.new(
560+
success: success,
561+
errors: {},
562+
exception: exception,
563+
vendor_name: 'instant_verify_test',
564+
),
565+
device_profiling_result: Proofing::DdpResult.new(success: true),
566+
ipp_enrollment_in_progress: false,
567+
residential_resolution_result: Proofing::Resolution::Result.new(success: true),
568+
resolution_result: Proofing::Resolution::Result.new(
569+
success: success,
570+
errors: {},
571+
exception: 'fake exception',
572+
vendor_name: vendor_name,
573+
attributes_requiring_additional_verification: error_attributes,
574+
),
575+
same_address_as_id: nil,
576+
should_proof_state_id: true,
577+
applicant_pii: Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN,
578+
).adjudicated_result.to_h
579+
580+
document_capture_session.create_proofing_session
581+
582+
document_capture_session.store_proofing_result(adjudicated_result)
583+
584+
document_capture_session.load_proofing_result
585+
end
586+
before do
587+
allow(controller).to receive(:load_async_state).and_return(async_state)
588+
end
589+
590+
context 'address is the only exception' do
591+
let(:error_attributes) { ['address'] }
592+
593+
it 'redirects user to address warning' do
594+
put :show
595+
expect(response).to redirect_to idv_session_errors_address_warning_url
596+
end
597+
598+
it 'logs an event' do
599+
get :show
600+
601+
expect(@analytics).to have_logged_event(
602+
:idv_doc_auth_address_warning_visited,
603+
step_name: 'verify_info',
604+
remaining_submit_attempts: kind_of(Numeric),
605+
)
606+
end
607+
end
608+
609+
context 'there are more instant verify exceptions' do
610+
let(:error_attributes) { ['address', 'dob', 'ssn'] }
611+
612+
it 'redirects user to address warning' do
613+
put :show
614+
expect(response).to redirect_to idv_session_errors_exception_url
615+
end
616+
end
617+
end
618+
546619
context 'when the resolution proofing job fails and there is no exception' do
547620
before do
548621
allow(controller).to receive(:load_async_state).and_return(async_state)

0 commit comments

Comments
 (0)