diff --git a/app/controllers/idv/verify_info_controller.rb b/app/controllers/idv/verify_info_controller.rb index 8de40d8bd79..3f4fba22aa5 100644 --- a/app/controllers/idv/verify_info_controller.rb +++ b/app/controllers/idv/verify_info_controller.rb @@ -14,11 +14,13 @@ def show call('verify', :view, true) if ssn_throttle.throttled? + idv_failure_log_throttled(:proof_ssn) redirect_to idv_session_errors_ssn_failure_url return end if resolution_throttle.throttled? + idv_failure_log_throttled(:idv_resolution) redirect_to throttled_url return end @@ -37,6 +39,7 @@ def update ssn_throttle.increment! if ssn_throttle.throttled? + idv_failure_log_throttled(:proof_ssn) analytics.throttler_rate_limit_triggered( throttle_type: :proof_ssn, step_name: 'verify_info', @@ -46,6 +49,7 @@ def update end if resolution_throttle.throttled? + idv_failure_log_throttled(:idv_resolution) redirect_to throttled_url return end @@ -155,7 +159,7 @@ def idv_failure(result) resolution_throttle.increment! if proofing_results_exception.blank? if resolution_throttle.throttled? - idv_failure_log_throttled + idv_failure_log_throttled(:idv_resolution) redirect_to throttled_url elsif proofing_results_exception.present? idv_failure_log_error @@ -166,12 +170,16 @@ def idv_failure(result) end end - def idv_failure_log_throttled - irs_attempts_api_tracker.idv_verification_rate_limited - analytics.throttler_rate_limit_triggered( - throttle_type: :idv_resolution, - step_name: self.class.name, - ) + def idv_failure_log_throttled(throttle_type) + if throttle_type == :idv_resolution + irs_attempts_api_tracker.idv_verification_rate_limited(throttle_context: 'single-session') + analytics.throttler_rate_limit_triggered( + throttle_type: :idv_resolution, + step_name: self.class.name, + ) + elsif throttle_type == :proof_ssn + irs_attempts_api_tracker.idv_verification_rate_limited(throttle_context: 'multi-session') + end end def idv_failure_log_error diff --git a/app/controllers/idv_controller.rb b/app/controllers/idv_controller.rb index f3abd443709..5718a18851d 100644 --- a/app/controllers/idv_controller.rb +++ b/app/controllers/idv_controller.rb @@ -15,7 +15,7 @@ def index elsif active_profile? redirect_to idv_activated_url elsif idv_attempter_throttled? - irs_attempts_api_tracker.idv_verification_rate_limited + irs_attempts_api_tracker.idv_verification_rate_limited(throttle_context: 'single-session') analytics.throttler_rate_limit_triggered( throttle_type: :idv_resolution, ) diff --git a/app/services/idv/steps/verify_base_step.rb b/app/services/idv/steps/verify_base_step.rb index b2a49f63565..f28af31beda 100644 --- a/app/services/idv/steps/verify_base_step.rb +++ b/app/services/idv/steps/verify_base_step.rb @@ -90,7 +90,9 @@ def idv_failure(result) end def idv_failure_log_throttled - @flow.irs_attempts_api_tracker.idv_verification_rate_limited + @flow.irs_attempts_api_tracker.idv_verification_rate_limited( + throttle_context: 'single-session', + ) @flow.analytics.throttler_rate_limit_triggered( throttle_type: :idv_resolution, step_name: self.class.name, @@ -179,6 +181,9 @@ def enqueue_job throttle.increment! if throttle.throttled? + @flow.irs_attempts_api_tracker.idv_verification_rate_limited( + throttle_context: 'multi-session', + ) @flow.analytics.throttler_rate_limit_triggered( throttle_type: :proof_ssn, step_name: self.class, diff --git a/app/services/irs_attempts_api/tracker_events.rb b/app/services/irs_attempts_api/tracker_events.rb index a5ea08e78ec..9beb1538895 100644 --- a/app/services/irs_attempts_api/tracker_events.rb +++ b/app/services/irs_attempts_api/tracker_events.rb @@ -282,10 +282,12 @@ def idv_ssn_submitted(ssn:) ) end + # @param [String] throttle_context - Either single-session or multi-session # Track when idv verification is rate limited during idv flow - def idv_verification_rate_limited + def idv_verification_rate_limited(throttle_context:) track_event( :idv_verification_rate_limited, + throttle_context: throttle_context, ) end diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb index ac56fda9afd..cc09d93aee3 100644 --- a/spec/controllers/idv/verify_info_controller_spec.rb +++ b/spec/controllers/idv/verify_info_controller_spec.rb @@ -12,6 +12,16 @@ end let(:user) { create(:user) } + let(:analytics_hash) do + { + analytics_id: 'Doc Auth', + flow_path: 'standard', + irs_reproofing: false, + step: 'verify', + } + end + let(:ssn_throttle_hash) { { throttle_context: 'multi-session' } } + let(:proofing_throttle_hash) { { throttle_context: 'single-session' } } before do allow(subject).to receive(:flow_session).and_return(flow_session) @@ -38,10 +48,7 @@ let(:analytics_name) { 'IdV: doc auth verify visited' } let(:analytics_args) do { - analytics_id: 'Doc Auth', - flow_path: 'standard', - irs_reproofing: false, - step: 'verify', + **analytics_hash, step_count: 1, } end @@ -115,21 +122,17 @@ end end - context 'when the user is ssn throttled' do - before do - Throttle.new( - target: Pii::Fingerprinter.fingerprint( - Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn], - ), - throttle_type: :proof_ssn, - ).increment_to_throttled! - end + it 'redirects to ssn failure url' do + get :show - it 'redirects to ssn failure url' do - get :show + expect(response).to redirect_to idv_session_errors_ssn_failure_url + end - expect(response).to redirect_to idv_session_errors_ssn_failure_url - end + it 'logs the correct attempts event' do + expect(@irs_attempts_api_tracker).to receive(:idv_verification_rate_limited). + with(ssn_throttle_hash) + + get :show end end @@ -146,23 +149,30 @@ expect(response).to redirect_to idv_session_errors_failure_url end + + it 'logs the correct attempts event' do + expect(@irs_attempts_api_tracker).to receive(:idv_verification_rate_limited). + with(proofing_throttle_hash) + + get :show + end end end describe '#update' do + before do + stub_attempts_tracker + end + it 'logs the correct analytics event' do stub_analytics - stub_attempts_tracker put :update expect(@analytics).to have_logged_event( 'IdV: doc auth verify submitted', { - analytics_id: 'Doc Auth', - flow_path: 'standard', - irs_reproofing: false, - step: 'verify', + **analytics_hash, step_count: 0, }, ) @@ -191,6 +201,13 @@ expect(response).to redirect_to idv_session_errors_ssn_failure_url end + + it 'logs the correct attempts event' do + expect(@irs_attempts_api_tracker).to receive(:idv_verification_rate_limited). + with(ssn_throttle_hash) + + put :update + end end context 'when the user is proofing throttled' do @@ -206,6 +223,13 @@ expect(response).to redirect_to idv_session_errors_failure_url end + + it 'logs the correct attempts event' do + expect(@irs_attempts_api_tracker).to receive(:idv_verification_rate_limited). + with(proofing_throttle_hash) + + put :update + end end end end diff --git a/spec/controllers/idv_controller_spec.rb b/spec/controllers/idv_controller_spec.rb index 7851c9090d9..8775f2e6003 100644 --- a/spec/controllers/idv_controller_spec.rb +++ b/spec/controllers/idv_controller_spec.rb @@ -1,12 +1,18 @@ require 'rails_helper' describe IdvController do + before do + stub_sign_in + end + describe '#index' do - it 'tracks page visit' do - stub_sign_in + let(:analytics_name) { 'IdV: intro visited' } + before do stub_analytics + end - expect(@analytics).to receive(:track_event).with('IdV: intro visited') + it 'tracks page visit' do + expect(@analytics).to receive(:track_event).with(analytics_name) get :index end @@ -15,29 +21,37 @@ profile = create(:profile, :active, :verified) stub_sign_in(profile.user) - stub_analytics - expect(@analytics).to_not receive(:track_event).with('IdV: intro visited') + expect(@analytics).to_not receive(:track_event).with(analytics_name) get :index end - it 'redirects to failure page if number of attempts has been exceeded' do - stub_attempts_tracker - expect(@irs_attempts_api_tracker).to receive(:track_event). - with(:idv_verification_rate_limited) - user = create(:user) - profile = create( - :profile, - user: user, - ) - Throttle.new(throttle_type: :idv_resolution, user: user).increment_to_throttled! + context 'if number of attempts has been exceeded' do + before do + user = create(:user) + profile = create( + :profile, + user: user, + ) + Throttle.new(throttle_type: :idv_resolution, user: user).increment_to_throttled! - stub_sign_in(profile.user) + stub_sign_in(profile.user) + end - get :index + it 'redirects to failure page' do + get :index - expect(response).to redirect_to idv_session_errors_failure_url + expect(response).to redirect_to idv_session_errors_failure_url + end + + it 'logs appropriate attempts event' do + stub_attempts_tracker + expect(@irs_attempts_api_tracker).to receive(:idv_verification_rate_limited). + with({ throttle_context: 'single-session' }) + + get :index + end end it 'redirects to account recovery if user has a password reset profile' do @@ -51,28 +65,20 @@ end it 'redirects to doc auth if doc auth is enabled and exclusive' do - stub_sign_in - get :index expect(response).to redirect_to idv_doc_auth_path end - context 'with a VA inherited proofing session' do - before do - stub_sign_in - allow(controller).to receive(:va_inherited_proofing?).and_return(true) - end + it 'redirects to inherited proofing with a VA inherited proofing session' do + allow(controller).to receive(:va_inherited_proofing?).and_return(true) - it 'redirects to inherited proofing' do - get :index - expect(response).to redirect_to idv_inherited_proofing_path - end + get :index + expect(response).to redirect_to idv_inherited_proofing_path end context 'no SP context' do let(:user) { build(:user, password: ControllerHelper::VALID_PASSWORD) } - let(:idv_sp_required) { false } before do stub_sign_in(user) @@ -131,8 +137,6 @@ context 'user does not have an active profile' do it 'does not allow direct access' do - stub_sign_in - get :activated expect(response).to redirect_to idv_url diff --git a/spec/features/idv/doc_auth/verify_info_step_spec.rb b/spec/features/idv/doc_auth/verify_info_step_spec.rb index 078cb82e81f..de6815cdee9 100644 --- a/spec/features/idv/doc_auth/verify_info_step_spec.rb +++ b/spec/features/idv/doc_auth/verify_info_step_spec.rb @@ -7,6 +7,42 @@ let(:fake_analytics) { FakeAnalytics.new } let(:fake_attempts_tracker) { IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new } + let(:mock_ssn_a) { DocAuthHelper::GOOD_SSN } + let(:masked_ssn_a) { '9**-**-***4' } + let(:mock_zip_code) { '12345' } + let(:mock_ssn_b) { '900456789' } + let(:masked_ssn_b) { '9**-**-***9' } + let(:unmasked_ssn_b) { '900-45-6789' } + let(:fake_pii_details) do + { + document_state: 'MT', + document_number: '1111111111111', + document_issued: '2019-12-31', + document_expiration: '2099-12-31', + first_name: 'FAKEY', + last_name: 'MCFAKERSON', + date_of_birth: '1938-10-06', + address: '1 FAKE RD', + } + end + let(:mock_state_id_jurisdiction) { [Idp::Constants::MOCK_IDV_APPLICANT[:state_id_jurisdiction]] } + let(:proof_resolution_args) do + { + trace_id: anything, + threatmetrix_session_id: anything, + request_ip: kind_of(String), + } + end + + let(:forms_ssn_show) { 'forms.ssn.show' } + let(:forms_buttons_submit_update) { 'forms.buttons.submit.update' } + let(:idv_buttons_change_ssn_label) { 'idv.buttons.change_ssn_label' } + let(:idv_form_ssn_label_html) { 'idv.form.ssn_label_html' } + let(:idv_failure_button_warning) { 'idv.failure.button.warning' } + let(:step_verify_info_controller) { 'Idv::VerifyInfoController' } + let(:ananlyics_throttle_event) { 'Throttler Rate Limit Triggered' } + let(:idv_failure_timeout) { 'idv.failure.timeout' } + before do allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics) allow_any_instance_of(ApplicationController).to receive(:irs_attempts_api_tracker). @@ -29,48 +65,41 @@ expect(page).to have_content(t('step_indicator.flows.idv.verify_info')) # SSN is masked until revealed - expect(page).to have_text('9**-**-***4') - expect(page).not_to have_text(DocAuthHelper::GOOD_SSN) - check t('forms.ssn.show') - expect(page).not_to have_text('9**-**-***4') - expect(page).to have_text(DocAuthHelper::GOOD_SSN) + expect(page).to have_text(masked_ssn_a) + expect(page).not_to have_text(mock_ssn_a) + check t(forms_ssn_show) + expect(page).not_to have_text(masked_ssn_a) + expect(page).to have_text(mock_ssn_a) end it 'allows the user to enter in a new address and displays updated info' do click_button t('idv.buttons.change_address_label') - fill_in 'idv_form_zipcode', with: '12345' - click_button t('forms.buttons.submit.update') + fill_in 'idv_form_zipcode', with: mock_zip_code + click_button t(forms_buttons_submit_update) expect(page).to have_current_path(idv_verify_info_path) - expect(page).to have_content('12345') + expect(page).to have_content(mock_zip_code) end it 'allows the user to enter in a new ssn and displays updated info' do - click_button t('idv.buttons.change_ssn_label') - fill_in t('idv.form.ssn_label_html'), with: '900456789' - click_button t('forms.buttons.submit.update') + click_button t(idv_buttons_change_ssn_label) + fill_in t(idv_form_ssn_label_html), with: mock_ssn_b + click_button t(forms_buttons_submit_update) expect(page).to have_current_path(idv_verify_info_path) - expect(page).to have_text('9**-**-***9') - check t('forms.ssn.show') - expect(page).to have_text('900-45-6789') + expect(page).to have_text(masked_ssn_b) + check t(forms_ssn_show) + expect(page).to have_text(unmasked_ssn_b) end it 'proceeds to the next page upon confirmation' do expect(fake_attempts_tracker).to receive(:idv_verification_submitted).with( success: true, failure_reason: nil, - document_state: 'MT', - document_number: '1111111111111', - document_issued: '2019-12-31', - document_expiration: '2099-12-31', - first_name: 'FAKEY', - last_name: 'MCFAKERSON', - date_of_birth: '1938-10-06', - address: '1 FAKE RD', - ssn: '900-66-1234', + **fake_pii_details, + ssn: mock_ssn_a, ) sign_in_and_2fa_user complete_doc_auth_steps_before_verify_step @@ -92,15 +121,8 @@ expect(fake_attempts_tracker).to receive(:idv_verification_submitted).with( success: false, failure_reason: { ssn: ['Unverified SSN.'] }, - document_state: 'MT', - document_number: '1111111111111', - document_issued: '2019-12-31', - document_expiration: '2099-12-31', - first_name: 'FAKEY', - last_name: 'MCFAKERSON', - date_of_birth: '1938-10-06', - address: '1 FAKE RD', - ssn: '123-45-6666', + **fake_pii_details, + ssn: DocAuthHelper::SSN_THAT_FAILS_RESOLUTION, ) sign_in_and_2fa_user complete_doc_auth_steps_before_ssn_step @@ -109,7 +131,7 @@ click_idv_continue expect(page).to have_current_path(idv_session_errors_warning_path) - click_on t('idv.failure.button.warning') + click_on t(idv_failure_button_warning) expect(page).to have_current_path(idv_verify_info_path) end @@ -118,15 +140,8 @@ expect(fake_attempts_tracker).to receive(:idv_verification_submitted).with( success: false, failure_reason: nil, - document_state: 'MT', - document_number: '1111111111111', - document_issued: '2019-12-31', - document_expiration: '2099-12-31', - first_name: 'FAKEY', - last_name: 'MCFAKERSON', - date_of_birth: '1938-10-06', - address: '1 FAKE RD', - ssn: '000-00-0000', + **fake_pii_details, + ssn: DocAuthHelper::SSN_THAT_RAISES_EXCEPTION, ) sign_in_and_2fa_user complete_doc_auth_steps_before_ssn_step @@ -137,12 +152,12 @@ expect(fake_analytics).to have_logged_event( 'IdV: doc auth exception visited', - step_name: 'Idv::VerifyInfoController', + step_name: step_verify_info_controller, remaining_attempts: 5, ) expect(page).to have_current_path(idv_session_errors_exception_path) - click_on t('idv.failure.button.warning') + click_on t(idv_failure_button_warning) expect(page).to have_current_path(idv_verify_info_path) end @@ -154,7 +169,9 @@ allow(IdentityConfig.store).to receive(:idv_max_attempts). and_return(max_resolution_attempts) - expect(fake_attempts_tracker).to receive(:idv_verification_rate_limited) + expect(fake_attempts_tracker).to receive(:idv_verification_rate_limited).at_least(1).times. + with({ throttle_context: 'single-session' }) + sign_in_and_2fa_user complete_doc_auth_steps_before_ssn_step fill_out_ssn_form_with_ssn_that_fails_resolution @@ -174,9 +191,9 @@ click_idv_continue expect(page).to have_current_path(idv_session_errors_failure_path) expect(fake_analytics).to have_logged_event( - 'Throttler Rate Limit Triggered', + ananlyics_throttle_event, throttle_type: :idv_resolution, - step_name: 'Idv::VerifyInfoController', + step_name: step_verify_info_controller, ) visit idv_verify_info_url @@ -204,6 +221,9 @@ allow(IdentityConfig.store).to receive(:proof_ssn_max_attempts). and_return(max_ssn_attempts) + expect(fake_attempts_tracker).to receive(:idv_verification_rate_limited).at_least(1).times. + with({ throttle_context: 'multi-session' }) + sign_in_and_2fa_user complete_doc_auth_steps_before_ssn_step fill_out_ssn_form_with_ssn_that_fails_resolution @@ -217,7 +237,7 @@ click_idv_continue expect(page).to have_current_path(idv_session_errors_ssn_failure_path) expect(fake_analytics).to have_logged_event( - 'Throttler Rate Limit Triggered', + ananlyics_throttle_event, throttle_type: :proof_ssn, step_name: 'verify_info', ) @@ -238,7 +258,7 @@ context 'when the user lives in an AAMVA supported state' do it 'performs a resolution and state ID check' do allow(IdentityConfig.store).to receive(:aamva_supported_jurisdictions).and_return( - [Idp::Constants::MOCK_IDV_APPLICANT[:state_id_jurisdiction]], + mock_state_id_jurisdiction, ) user = create(:user, :signed_up) expect_any_instance_of(Idv::Agent). @@ -246,10 +266,8 @@ with( anything, should_proof_state_id: true, - trace_id: anything, - threatmetrix_session_id: anything, user_id: user.id, - request_ip: kind_of(String), + **proof_resolution_args, ). and_call_original @@ -265,7 +283,7 @@ it 'does not perform the state ID check' do allow(IdentityConfig.store).to receive(:aamva_supported_jurisdictions).and_return( IdentityConfig.store.aamva_supported_jurisdictions - - [Idp::Constants::MOCK_IDV_APPLICANT[:state_id_jurisdiction]], + mock_state_id_jurisdiction, ) user = create(:user, :signed_up) expect_any_instance_of(Idv::Agent). @@ -273,10 +291,8 @@ with( anything, should_proof_state_id: false, - trace_id: anything, - threatmetrix_session_id: anything, user_id: user.id, - request_ip: kind_of(String), + **proof_resolution_args, ). and_call_original @@ -298,10 +314,8 @@ with( anything, should_proof_state_id: false, - trace_id: anything, - threatmetrix_session_id: anything, user_id: user.id, - request_ip: kind_of(String), + **proof_resolution_args, ). and_call_original @@ -324,7 +338,7 @@ click_idv_continue expect(fake_analytics).to have_logged_event('Proofing Resolution Result Missing') - expect(page).to have_content(t('idv.failure.timeout')) + expect(page).to have_content(t(idv_failure_timeout)) expect(page).to have_current_path(idv_verify_info_path) allow(DocumentCaptureSession).to receive(:find_by).and_call_original click_idv_continue @@ -335,15 +349,8 @@ expect(fake_attempts_tracker).to receive(:idv_verification_submitted).with( success: false, failure_reason: { idv_verification: [:timeout] }, - document_state: 'MT', - document_number: '1111111111111', - document_issued: '2019-12-31', - document_expiration: '2099-12-31', - first_name: 'FAKEY', - last_name: 'MCFAKERSON', - date_of_birth: '1938-10-06', - address: '1 FAKE RD', - ssn: '900-66-1234', + **fake_pii_details, + ssn: mock_ssn_a, ) sign_in_and_2fa_user complete_doc_auth_steps_before_verify_step @@ -352,7 +359,7 @@ and_return(nil) click_idv_continue - expect(page).to have_content(t('idv.failure.timeout')) + expect(page).to have_content(t(idv_failure_timeout)) expect(page).to have_current_path(idv_verify_info_path) allow(DocumentCaptureSession).to receive(:find_by).and_call_original end @@ -367,7 +374,7 @@ and_return(nil) click_idv_continue - expect(page).to have_content(t('idv.failure.timeout')) + expect(page).to have_content(t(idv_failure_timeout)) expect(page).to have_current_path(idv_verify_info_path) allow(DocumentCaptureSession).to receive(:find_by).and_call_original click_idv_continue @@ -379,17 +386,16 @@ before do allow(IdentityConfig.store).to receive(:doc_auth_ssn_controller_enabled). and_return(true) - allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics) sign_in_and_2fa_user complete_doc_auth_steps_before_verify_step end it 'uses ssn controller to enter a new ssn and displays updated info' do - click_link t('idv.buttons.change_ssn_label') + click_link t(idv_buttons_change_ssn_label) expect(page).to have_current_path(idv_ssn_path) - fill_in t('idv.form.ssn_label_html'), with: '900456789' - click_button t('forms.buttons.submit.update') + fill_in t(idv_form_ssn_label_html), with: mock_ssn_b + click_button t(forms_buttons_submit_update) expect(fake_analytics).to have_logged_event( 'IdV: doc auth redo_ssn submitted', @@ -397,9 +403,9 @@ expect(page).to have_current_path(idv_verify_info_path) - expect(page).to have_text('9**-**-***9') - check t('forms.ssn.show') - expect(page).to have_text('900-45-6789') + expect(page).to have_text(masked_ssn_b) + check t(forms_ssn_show) + expect(page).to have_text(unmasked_ssn_b) end end end diff --git a/spec/services/idv/steps/in_person/verify_step_spec.rb b/spec/services/idv/steps/in_person/verify_step_spec.rb index 2af92fd9a8f..61fac585527 100644 --- a/spec/services/idv/steps/in_person/verify_step_spec.rb +++ b/spec/services/idv/steps/in_person/verify_step_spec.rb @@ -15,14 +15,21 @@ remote_ip: Faker::Internet.ip_v4_address, ) end + let(:controller_args) do + { + request: request, + session: { sp: { issuer: service_provider.issuer } }, + url_options: {}, + } + end + let(:controller) do instance_double( 'controller', analytics: FakeAnalytics.new, + irs_attempts_api_tracker: IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new, current_user: user, - request: request, - session: { sp: { issuer: service_provider.issuer } }, - url_options: {}, + **controller_args, ) end @@ -30,9 +37,13 @@ Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN.dup end + let(:flow_args) do + [{}, 'idv/in_person'] + end + let(:pii_hash) { { pii_from_user: pii } } let(:flow) do - Idv::Flows::InPersonFlow.new(controller, {}, 'idv/in_person').tap do |flow| - flow.flow_session = { pii_from_user: pii } + Idv::Flows::InPersonFlow.new(controller, *flow_args).tap do |flow| + flow.flow_session = pii_hash end end @@ -72,38 +83,36 @@ end context 'when pii_from_user is blank' do + let(:idv_in_person_step) { 'Idv::Steps::InPerson::SsnStep' } let(:flow) do - Idv::Flows::InPersonFlow.new(controller, {}, 'idv/in_person').tap do |flow| - flow.flow_session = { 'Idv::Steps::InPerson::SsnStep' => true, pii_from_user: {} } + Idv::Flows::InPersonFlow.new(controller, *flow_args).tap do |flow| + flow.flow_session = { idv_in_person_step => true, pii_from_user: {} } end end it 'marks step as incomplete' do - expect(flow.flow_session['Idv::Steps::InPerson::SsnStep']).to eq true + expect(flow.flow_session[idv_in_person_step]).to eq true result = step.call - expect(flow.flow_session['Idv::Steps::InPerson::SsnStep']).to eq nil + expect(flow.flow_session[idv_in_person_step]).to eq nil expect(result.success?).to eq false end end context 'when different users use the same SSN within the same timeframe' do let(:user2) { create(:user) } - let(:flow2) do - end let(:controller2) do instance_double( 'controller', analytics: FakeAnalytics.new, + irs_attempts_api_tracker: IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new, current_user: user2, - request: request, - session: { sp: { issuer: service_provider.issuer } }, - url_options: {}, + **controller_args, ) end - def build_step(controller) - flow = Idv::Flows::InPersonFlow.new(controller, {}, 'idv/in_person').tap do |flow| - flow.flow_session = { pii_from_user: pii } + def build_step(controller_instance) + flow = Idv::Flows::InPersonFlow.new(controller_instance, *flow_args).tap do |flow| + flow.flow_session = { **pii_hash } end Idv::Steps::InPerson::VerifyStep.new(flow) @@ -115,21 +124,21 @@ def build_step(controller) and_return(10) end - def redirect(step) - step.instance_variable_get(:@flow).instance_variable_get(:@redirect) + def redirect(step_instance) + step_instance.instance_variable_get(:@flow).instance_variable_get(:@redirect) end it 'throttles them all' do expect(build_step(controller).call).to be_kind_of(ApplicationJob) expect(build_step(controller2).call).to be_kind_of(ApplicationJob) - step = build_step(controller) - expect(step.call).to be_nil, 'does not enqueue a job' - expect(redirect(step)).to eq(idv_session_errors_ssn_failure_url) + user1_step = build_step(controller) + expect(user1_step.call).to be_nil, 'does not enqueue a job' + expect(redirect(user1_step)).to eq(idv_session_errors_ssn_failure_url) - step2 = build_step(controller2) - expect(step2.call).to be_nil, 'does not enqueue a job' - expect(redirect(step2)).to eq(idv_session_errors_ssn_failure_url) + user2_step = build_step(controller2) + expect(user2_step.call).to be_nil, 'does not enqueue a job' + expect(redirect(user2_step)).to eq(idv_session_errors_ssn_failure_url) end end diff --git a/spec/support/features/doc_auth_helper.rb b/spec/support/features/doc_auth_helper.rb index dbb97ec2516..37a1cc175dc 100644 --- a/spec/support/features/doc_auth_helper.rb +++ b/spec/support/features/doc_auth_helper.rb @@ -5,6 +5,7 @@ module DocAuthHelper GOOD_SSN = Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn] SSN_THAT_FAILS_RESOLUTION = '123-45-6666' + SSN_THAT_RAISES_EXCEPTION = '000-00-0000' def session_from_completed_flow_steps(finished_step) session = { doc_auth: {} } @@ -20,7 +21,7 @@ def fill_out_ssn_form_with_ssn_that_fails_resolution end def fill_out_ssn_form_with_ssn_that_raises_exception - fill_in t('idv.form.ssn_label_html'), with: '000-00-0000' + fill_in t('idv.form.ssn_label_html'), with: SSN_THAT_RAISES_EXCEPTION end def fill_out_ssn_form_ok