diff --git a/app/controllers/idv/document_capture_controller.rb b/app/controllers/idv/document_capture_controller.rb index dfc9b8257a9..caaa6695a23 100644 --- a/app/controllers/idv/document_capture_controller.rb +++ b/app/controllers/idv/document_capture_controller.rb @@ -96,7 +96,7 @@ def extra_view_variables skip_doc_auth_from_socure: idv_session.skip_doc_auth_from_socure, opted_in_to_in_person_proofing: idv_session.opted_in_to_in_person_proofing, doc_auth_selfie_capture: resolved_authn_context_result.facial_match?, - socure_errors_timeout_url: idv_socure_errors_timeout_url, + socure_errors_timeout_url: idv_socure_document_capture_errors_url(error_code: :timeout), }.merge( acuant_sdk_upgrade_a_b_testing_variables, ) diff --git a/app/controllers/idv/hybrid_mobile/document_capture_controller.rb b/app/controllers/idv/hybrid_mobile/document_capture_controller.rb index 873285b3d21..f3f9e52bbdd 100644 --- a/app/controllers/idv/hybrid_mobile/document_capture_controller.rb +++ b/app/controllers/idv/hybrid_mobile/document_capture_controller.rb @@ -64,7 +64,9 @@ def extra_view_variables failure_to_proof_url: return_to_sp_failure_to_proof_url(step: 'document_capture'), doc_auth_selfie_capture: resolved_authn_context_result.facial_match?, skip_doc_auth_from_socure: @skip_doc_auth_from_socure, - socure_errors_timeout_url: idv_hybrid_mobile_socure_errors_timeout_url, + socure_errors_timeout_url: idv_hybrid_mobile_socure_document_capture_errors_url( + error_code: :timeout, + ), }.merge( acuant_sdk_upgrade_a_b_testing_variables, ) diff --git a/app/controllers/idv/hybrid_mobile/socure/document_capture_controller.rb b/app/controllers/idv/hybrid_mobile/socure/document_capture_controller.rb index 46ebaf0230d..7ecc0384e3e 100644 --- a/app/controllers/idv/hybrid_mobile/socure/document_capture_controller.rb +++ b/app/controllers/idv/hybrid_mobile/socure/document_capture_controller.rb @@ -42,7 +42,9 @@ def show # placeholder until we get an error page for url not being present if @url.nil? - redirect_to idv_hybrid_mobile_socure_document_capture_errors_url + redirect_to idv_hybrid_mobile_socure_document_capture_errors_url( + error_code: :url_not_found, + ) return end @@ -98,7 +100,9 @@ def wait_for_result? # If the stored_result is nil, the job fetching the results has not completed. analytics.idv_doc_auth_document_capture_polling_wait_visited(**analytics_arguments) if wait_timed_out? - redirect_to idv_hybrid_mobile_socure_errors_timeout_path + redirect_to idv_hybrid_mobile_socure_document_capture_errors_url( + error_code: :timeout, + ) else @refresh_interval = IdentityConfig.store.doc_auth_socure_wait_polling_refresh_max_seconds diff --git a/app/controllers/idv/hybrid_mobile/socure/errors_controller.rb b/app/controllers/idv/hybrid_mobile/socure/errors_controller.rb index c216de5f9ad..43b47ac22cd 100644 --- a/app/controllers/idv/hybrid_mobile/socure/errors_controller.rb +++ b/app/controllers/idv/hybrid_mobile/socure/errors_controller.rb @@ -11,22 +11,19 @@ class ErrorsController < ApplicationController include SocureErrorsConcern def show - error_code = error_code_for(handle_stored_result) + error_code = error_params[:error_code] + if error_code.nil? + error_code = error_code_for(handle_stored_result) + end track_event(error_code: error_code) @presenter = socure_errors_presenter(error_code) end - def timeout - track_event(error_code: :timeout) - @presenter = socure_errors_presenter(:timeout) - render :show - end - def self.step_info Idv::StepInfo.new( key: :hybrid_socure_errors, controller: self, - action: :timeout, + action: :show, next_steps: [FlowPolicy::FINAL], preconditions: ->(idv_session:, user:) do true @@ -37,6 +34,10 @@ def self.step_info private + def error_params + params.permit(:error_code) + end + def rate_limiter RateLimiter.new(user: document_capture_session&.user, rate_limit_type: :idv_doc_auth) end diff --git a/app/controllers/idv/socure/document_capture_controller.rb b/app/controllers/idv/socure/document_capture_controller.rb index b7624ea2c4f..a25668f2e40 100644 --- a/app/controllers/idv/socure/document_capture_controller.rb +++ b/app/controllers/idv/socure/document_capture_controller.rb @@ -51,7 +51,7 @@ def show # placeholder until we get an error page for url not being present if @url.nil? - redirect_to idv_socure_document_capture_errors_url + redirect_to idv_socure_document_capture_errors_url(error_code: :url_not_found) return end @@ -119,7 +119,7 @@ def wait_for_result? # If the stored_result is nil, the job fetching the results has not completed. analytics.idv_doc_auth_document_capture_polling_wait_visited(**analytics_arguments) if wait_timed_out? - redirect_to idv_socure_errors_timeout_path + redirect_to idv_socure_document_capture_errors_url(error_code: :timeout) else @refresh_interval = IdentityConfig.store.doc_auth_socure_wait_polling_refresh_max_seconds diff --git a/app/controllers/idv/socure/errors_controller.rb b/app/controllers/idv/socure/errors_controller.rb index 3d6c9d3c21c..47ed86f0df9 100644 --- a/app/controllers/idv/socure/errors_controller.rb +++ b/app/controllers/idv/socure/errors_controller.rb @@ -12,22 +12,19 @@ class ErrorsController < ApplicationController before_action :confirm_step_allowed def show - error_code = error_code_for(handle_stored_result) + error_code = error_params[:error_code] + if error_code.nil? + error_code = error_code_for(handle_stored_result) + end track_event(error_code: error_code) @presenter = socure_errors_presenter(error_code) end - def timeout - track_event(error_code: :timeout) - @presenter = socure_errors_presenter(:timeout) - render :show - end - def self.step_info Idv::StepInfo.new( key: :socure_errors, controller: self, - action: :timeout, + action: :show, next_steps: [FlowPolicy::FINAL], preconditions: ->(idv_session:, user:) do true @@ -38,6 +35,10 @@ def self.step_info private + def error_params + params.permit(:error_code) + end + def rate_limiter RateLimiter.new(user: idv_session.current_user, rate_limit_type: :idv_doc_auth) end diff --git a/app/presenters/socure_error_presenter.rb b/app/presenters/socure_error_presenter.rb index e5f7c26f25b..96e04f224e2 100644 --- a/app/presenters/socure_error_presenter.rb +++ b/app/presenters/socure_error_presenter.rb @@ -26,6 +26,8 @@ def body_text end def rate_limit_text + return if error_code == :url_not_found + if remaining_attempts == 1 t('doc_auth.rate_limit_warning.singular_html') else @@ -67,7 +69,7 @@ def troubleshooting_heading end def options - return [] if error_code == :timeout + return [] if error_code == :timeout || error_code == :url_not_found [ { @@ -141,10 +143,10 @@ def remapped_error(error_code) end def heading_string_for(error_code) - case error_code + case error_code.to_sym when :network t('doc_auth.headers.general.network_error') - when :timeout + when :timeout, :url_not_found t('idv.errors.technical_difficulties') else # i18n-tasks-use t('doc_auth.headers.unreadable_id') @@ -158,10 +160,10 @@ def heading_string_for(error_code) end def error_string_for(error_code) - case error_code + case error_code.to_sym when :network t('doc_auth.errors.general.new_network_error') - when :timeout + when :timeout, :url_not_found t('idv.errors.try_again_later') else if remapped_error(error_code) == 'underage' # special handling because it says 'Login.gov' diff --git a/app/views/idv/socure/errors/timeout.html.erb b/app/views/idv/socure/errors/timeout.html.erb deleted file mode 100644 index a7210f8471f..00000000000 --- a/app/views/idv/socure/errors/timeout.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -<%= render( - 'idv/shared/error', - type: :warning, - heading: @presenter.heading, - action: @presenter.action, - secondary_action: @presenter.secondary_action, - current_step: :verify_id, - troubleshooting_heading: @presenter.troubleshooting_heading, - secondary_action_heading: @presenter.secondary_action_heading, - secondary_action_text: @presenter.secondary_action_text, - options: @presenter.options, - step_indicator_steps: @presenter.step_indicator_steps, - ) do -%> -

<%= @presenter.body_text %>

-

<%= @presenter.rate_limit_text %>

-<% end %> diff --git a/config/routes.rb b/config/routes.rb index 1b9940e00c3..c52b0e3a748 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -367,7 +367,6 @@ get '/socure/document_capture' => 'socure/document_capture#show' get '/socure/document_capture_update' => 'socure/document_capture#update', as: :socure_document_capture_update get '/socure/document_capture_errors' => 'socure/errors#show', as: :socure_document_capture_errors - get '/socure/errors/timeout' => 'socure/errors#timeout' # This route is included in SMS messages sent to users who start the IdV hybrid flow. It # should be kept short, and should not include underscores ("_"). get '/documents' => 'hybrid_mobile/entry#show', as: :hybrid_mobile_entry @@ -378,7 +377,6 @@ get '/hybrid_mobile/socure/document_capture' => 'hybrid_mobile/socure/document_capture#show' get '/hybrid_mobile/socure/document_capture_update' => 'hybrid_mobile/socure/document_capture#update', as: :hybrid_mobile_socure_document_capture_update get '/hybrid_mobile/socure/document_capture_errors' => 'hybrid_mobile/socure/errors#show', as: :hybrid_mobile_socure_document_capture_errors - get '/hybrid_mobile/socure/errors/timeout' => 'hybrid_mobile/socure/errors#timeout' get '/hybrid_handoff' => 'hybrid_handoff#show' put '/hybrid_handoff' => 'hybrid_handoff#update' get '/link_sent' => 'link_sent#show' diff --git a/spec/controllers/idv/hybrid_mobile/socure/document_capture_controller_spec.rb b/spec/controllers/idv/hybrid_mobile/socure/document_capture_controller_spec.rb index 81519ae409a..8b629416441 100644 --- a/spec/controllers/idv/hybrid_mobile/socure/document_capture_controller_spec.rb +++ b/spec/controllers/idv/hybrid_mobile/socure/document_capture_controller_spec.rb @@ -9,6 +9,7 @@ let(:user) { create(:user) } let(:stored_result) { nil } let(:socure_docv_enabled) { true } + let(:socure_docv_verification_data_test_mode) { false } let(:document_capture_session) do DocumentCaptureSession.create( @@ -17,8 +18,12 @@ ) end let(:document_capture_session_uuid) { document_capture_session&.uuid } - - let(:socure_docv_verification_data_test_mode) { false } + let(:no_url_socure_route) do + idv_hybrid_mobile_socure_document_capture_errors_url(error_code: :url_not_found) + end + let(:timeout_socure_route) do + idv_hybrid_mobile_socure_document_capture_errors_url(error_code: :timeout) + end before do allow(IdentityConfig.store).to receive(:socure_docv_enabled) @@ -244,7 +249,7 @@ it 'redirects to idv unavailable url' do get(:show) - expect(response).to redirect_to(idv_hybrid_mobile_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) expect(controller.send(:instance_variable_get, :@url)).not_to be end end @@ -289,7 +294,7 @@ it 'connection timeout still responds to user' do stub_request(:post, fake_socure_endpoint).to_raise(Faraday::ConnectionFailed) get(:show) - expect(response).to redirect_to(idv_hybrid_mobile_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end it 'socure error response still gives a result to user' do @@ -298,7 +303,7 @@ body: JSON.generate(failed_response_body), ) get(:show) - expect(response).to redirect_to(idv_hybrid_mobile_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end it 'socure nil response still gives a result to user' do @@ -307,7 +312,7 @@ body: nil, ) get(:show) - expect(response).to redirect_to(idv_hybrid_mobile_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end it 'socure nil response still gives a result to user' do @@ -316,7 +321,7 @@ body: JSON.generate(response_body_401), ) get(:show) - expect(response).to redirect_to(idv_hybrid_mobile_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end it 'socure nil response still gives a result to user' do @@ -325,7 +330,7 @@ body: JSON.generate(no_doc_found_response_body), ) get(:show) - expect(response).to redirect_to(idv_hybrid_mobile_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end end context 'reuse of valid capture app urls when appropriate' do @@ -427,7 +432,7 @@ it 'redirects to the hybrid mobile socure errors timeout page' do get(:update) - expect(response).to redirect_to(idv_hybrid_mobile_socure_errors_timeout_url) + expect(response).to redirect_to(timeout_socure_route) end end end diff --git a/spec/controllers/idv/socure/document_capture_controller_spec.rb b/spec/controllers/idv/socure/document_capture_controller_spec.rb index 3b4afd15a2d..453c7a7c3ed 100644 --- a/spec/controllers/idv/socure/document_capture_controller_spec.rb +++ b/spec/controllers/idv/socure/document_capture_controller_spec.rb @@ -10,6 +10,8 @@ let(:doc_auth_success) { true } let(:socure_docv_enabled) { true } let(:socure_docv_verification_data_test_mode) { false } + let(:no_url_socure_route) { idv_socure_document_capture_errors_url(error_code: :url_not_found) } + let(:timeout_socure_route) { idv_socure_document_capture_errors_url(error_code: :timeout) } let(:stored_result) do DocumentCaptureSessionResult.new( @@ -255,7 +257,7 @@ it 'redirects to the errors page' do get(:show) - expect(response).to redirect_to(idv_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) expect(controller.send(:instance_variable_get, :@url)).not_to be end end @@ -306,7 +308,7 @@ it 'connection timeout still responds to user' do stub_request(:post, fake_socure_endpoint).to_raise(Faraday::ConnectionFailed) get(:show) - expect(response).to redirect_to(idv_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end it 'socure error response still gives a result to user' do @@ -315,7 +317,7 @@ body: JSON.generate(failed_response_body), ) get(:show) - expect(response).to redirect_to(idv_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end it 'socure nil response still gives a result to user' do @@ -324,7 +326,7 @@ body: nil, ) get(:show) - expect(response).to redirect_to(idv_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end it 'socure nil response still gives a result to user' do @@ -333,7 +335,7 @@ body: JSON.generate(response_body_401), ) get(:show) - expect(response).to redirect_to(idv_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end it 'socure nil response still gives a result to user' do @@ -342,7 +344,7 @@ body: JSON.generate(no_doc_found_response_body), ) get(:show) - expect(response).to redirect_to(idv_socure_document_capture_errors_url) + expect(response).to redirect_to(no_url_socure_route) end end @@ -426,7 +428,7 @@ it 'redirect to a Try again page' do get(:update) - expect(response).to redirect_to(idv_socure_errors_timeout_path) + expect(response).to redirect_to(timeout_socure_route) end end diff --git a/spec/controllers/idv/socure/errors_controller_spec.rb b/spec/controllers/idv/socure/errors_controller_spec.rb index 91959eb830b..8d648e4d024 100644 --- a/spec/controllers/idv/socure/errors_controller_spec.rb +++ b/spec/controllers/idv/socure/errors_controller_spec.rb @@ -9,9 +9,9 @@ subject.idv_session.socure_docv_wait_polling_started_at = Time.zone.now end - describe '#timeout' do + describe '#show' do it 'logs an event' do - get(:timeout) + get(:show) expect(@analytics).to have_logged_event(:idv_doc_auth_socure_error_visited) end diff --git a/spec/features/idv/doc_auth/socure_document_capture_spec.rb b/spec/features/idv/doc_auth/socure_document_capture_spec.rb index 62d0a815d4c..10a09a4e27e 100644 --- a/spec/features/idv/doc_auth/socure_document_capture_spec.rb +++ b/spec/features/idv/doc_auth/socure_document_capture_spec.rb @@ -13,6 +13,7 @@ let(:fake_socure_document_capture_app_url) { 'https://verify.fake-socure.test/something' } let(:socure_docv_verification_data_test_mode) { false } let(:socure_docv_webhook_repeat_endpoints) { [] } + let(:timeout_socure_route) { idv_socure_document_capture_errors_url(error_code: :timeout) } before(:each) do allow(IdentityConfig.store).to receive(:socure_docv_enabled).and_return(true) @@ -79,7 +80,7 @@ # Timeout visit idv_socure_document_capture_update_path - expect(page).to have_current_path(idv_socure_errors_timeout_path) + expect(page).to have_current_path(timeout_socure_route) expect(page).to have_content(I18n.t('idv.errors.try_again_later')) # Try in person @@ -89,7 +90,7 @@ # Go back click_on t('forms.buttons.back') - expect(page).to have_current_path(idv_socure_errors_timeout_path) + expect(page).to have_current_path(timeout_socure_route) # Try Socure again click_on t('idv.failure.button.warning') diff --git a/spec/features/idv/hybrid_mobile/hybrid_socure_mobile_spec.rb b/spec/features/idv/hybrid_mobile/hybrid_socure_mobile_spec.rb index 3e14419a6eb..d7e70bc5a44 100644 --- a/spec/features/idv/hybrid_mobile/hybrid_socure_mobile_spec.rb +++ b/spec/features/idv/hybrid_mobile/hybrid_socure_mobile_spec.rb @@ -12,6 +12,9 @@ let(:socure_docv_verification_data_test_mode) { false } let(:fake_analytics) { FakeAnalytics.new } let(:socure_docv_webhook_repeat_endpoints) { [] } + let(:timeout_socure_route) do + idv_hybrid_mobile_socure_document_capture_errors_url(error_code: :timeout) + end before do allow(FeatureManagement).to receive(:doc_capture_polling_enabled?).and_return(true) @@ -215,7 +218,7 @@ # Timeout visit idv_hybrid_mobile_socure_document_capture_update_url - expect(page).to have_current_path(idv_hybrid_mobile_socure_errors_timeout_path) + expect(page).to have_current_path(timeout_socure_route) expect(page).to have_content(I18n.t('idv.errors.try_again_later')) # Try in person @@ -227,7 +230,7 @@ # Go back click_on t('forms.buttons.back') - expect(page).to have_current_path(idv_hybrid_mobile_socure_errors_timeout_path) + expect(page).to have_current_path(timeout_socure_route) # Try Socure again click_on t('idv.failure.button.warning') @@ -449,7 +452,7 @@ end shared_examples 'a properly categorized Socure error' do |socure_error_code, expected_header_key| - it 'shows the correct error page', js: true do + it 'shows the correct error page', allow_browser_log: true, js: true do user = nil perform_in_browser(:desktop) do diff --git a/spec/views/idv/shared/_document_capture.html.erb_spec.rb b/spec/views/idv/shared/_document_capture.html.erb_spec.rb index 17a5e1fa3dd..1240b181ede 100644 --- a/spec/views/idv/shared/_document_capture.html.erb_spec.rb +++ b/spec/views/idv/shared/_document_capture.html.erb_spec.rb @@ -18,7 +18,7 @@ let(:skip_doc_auth_from_how_to_verify) { false } let(:skip_doc_auth_from_handoff) { false } let(:skip_doc_auth_from_socure) { false } - let(:socure_errors_timeout_url) { idv_socure_errors_timeout_url } + let(:socure_errors_timeout_url) { idv_socure_document_capture_errors_url(error_code: :timeout) } let(:opted_in_to_in_person_proofing) { false } let(:presenter) { Idv::InPerson::UspsFormPresenter.new } let(:mock_client) { false } diff --git a/spec/views/idv/socure/errors/show.html.erb_spec.rb b/spec/views/idv/socure/errors/show.html.erb_spec.rb new file mode 100644 index 00000000000..0a7f08b90ea --- /dev/null +++ b/spec/views/idv/socure/errors/show.html.erb_spec.rb @@ -0,0 +1,124 @@ +require 'rails_helper' + +RSpec.describe 'idv/socure/errors/show.html.erb' do + include Devise::Test::ControllerHelpers + + let(:remaining_submit_attempts) { 5 } + let(:in_person_url) { nil } + let(:flow_path) { :standard } + let(:sp) { create(:service_provider) } + let(:error_code) { nil } + let(:decorated_sp_session) do + ServiceProviderSession.new( + sp:, + view_context: nil, + sp_session: nil, + service_provider_request: nil, + ) + end + let(:presenter) do + SocureErrorPresenter.new( + error_code:, + remaining_attempts: remaining_submit_attempts, + sp_name: decorated_sp_session&.sp_name || APP_NAME, + issuer: decorated_sp_session&.sp_issuer, + flow_path:, + ) + end + + context 'timeout error' do + let(:error_code) { :timeout } + + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) + assign(:presenter, presenter) + + render + end + + it 'shows correct h1' do + expect(rendered).to have_css('h1', text: t('idv.errors.technical_difficulties')) + end + + it 'shows try again' do + expect(rendered).to have_text(t('idv.errors.try_again_later')) + end + + it 'shows remaining attempts' do + expect(rendered).to have_text( + strip_tags(t('idv.failure.warning.attempts_html', count: remaining_submit_attempts)), + ) + end + + it 'shows a primary action' do + expect(rendered).to have_link( + t('idv.failure.button.warning'), + href: idv_socure_document_capture_path, + ) + end + + context 'In person verification disabled' do + it 'does not have the IPP h1' do + expect(rendered).not_to have_css('h1', text: t('in_person_proofing.headings.cta')) + end + + it 'does not explain in person verification' do + expect(rendered).not_to have_text(t('in_person_proofing.body.cta.prompt_detail')) + end + + it 'does not render a secondary cta for IPP' do + url = idv_in_person_direct_path + + expect(rendered).not_to have_link( + t('in_person_proofing.body.cta.button'), + href: %r{#{url}}, + ) + end + end + + context 'In person verification enabled' do + let(:sp) { create(:service_provider, in_person_proofing_enabled: true) } + + it 'has the IPP h1' do + expect(rendered).to have_css('h1', text: t('in_person_proofing.headings.cta')) + end + + it 'explains in person verification' do + expect(rendered).to have_text(t('in_person_proofing.body.cta.prompt_detail')) + end + + it 'has a secondary cta for IPP' do + url = idv_in_person_direct_path + expect(rendered).to have_link( + t('in_person_proofing.body.cta.button'), + href: %r{#{url}}, + ) + end + end + end + + context 'no capture app url' do + let(:error_code) { :url_not_found } + + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) + assign(:presenter, presenter) + + render + end + + it 'shows correct h1' do + expect(rendered).to have_css('h1', text: t('idv.errors.technical_difficulties')) + end + + it 'shows try again' do + expect(rendered).to have_text(t('idv.errors.try_again_later')) + end + + it 'does not show remaining attempts' do + expect(rendered).not_to have_text( + strip_tags(t('idv.failure.warning.attempts_html', count: remaining_submit_attempts)), + ) + end + end +end diff --git a/spec/views/idv/socure/errors/timeout.html.erb_spec.rb b/spec/views/idv/socure/errors/timeout.html.erb_spec.rb deleted file mode 100644 index 93c1a3c79a6..00000000000 --- a/spec/views/idv/socure/errors/timeout.html.erb_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'idv/socure/errors/timeout.html.erb' do - include Devise::Test::ControllerHelpers - - let(:remaining_submit_attempts) { 5 } - let(:in_person_url) { nil } - let(:error_code) { :timeout } - let(:flow_path) { :standard } - let(:sp) { create(:service_provider) } - let(:decorated_sp_session) do - ServiceProviderSession.new( - sp:, - view_context: nil, - sp_session: nil, - service_provider_request: nil, - ) - end - let(:presenter) do - SocureErrorPresenter.new( - error_code:, - remaining_attempts: remaining_submit_attempts, - sp_name: decorated_sp_session&.sp_name || APP_NAME, - issuer: decorated_sp_session&.sp_issuer, - flow_path:, - ) - end - - before do - allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) - assign(:presenter, presenter) - - render - end - - it 'shows correct h1' do - expect(rendered).to have_css('h1', text: t('idv.errors.technical_difficulties')) - end - - it 'shows try again' do - expect(rendered).to have_text(t('idv.errors.try_again_later')) - end - - it 'shows remaining attempts' do - expect(rendered).to have_text( - strip_tags(t('idv.failure.warning.attempts_html', count: remaining_submit_attempts)), - ) - end - - it 'shows a primary action' do - expect(rendered).to have_link( - t('idv.failure.button.warning'), - href: idv_socure_document_capture_path, - ) - end - - context 'In person verification disabled' do - it 'does not have the IPP h1' do - expect(rendered).not_to have_css('h1', text: t('in_person_proofing.headings.cta')) - end - - it 'does not explain in person verification' do - expect(rendered).not_to have_text(t('in_person_proofing.body.cta.prompt_detail')) - end - - it 'does not render a secondary cta for IPP' do - url = idv_in_person_direct_path - - expect(rendered).not_to have_link( - t('in_person_proofing.body.cta.button'), - href: %r{#{url}}, - ) - end - end - - context 'In person verification enabled' do - let(:sp) { create(:service_provider, in_person_proofing_enabled: true) } - - it 'has the IPP h1' do - expect(rendered).to have_css('h1', text: t('in_person_proofing.headings.cta')) - end - - it 'explains in person verification' do - expect(rendered).to have_text(t('in_person_proofing.body.cta.prompt_detail')) - end - - it 'has a secondary cta for IPP' do - url = idv_in_person_direct_path - expect(rendered).to have_link( - t('in_person_proofing.body.cta.button'), - href: %r{#{url}}, - ) - end - end -end