diff --git a/app/controllers/concerns/idv_step_concern.rb b/app/controllers/concerns/idv_step_concern.rb index 7db7c7f8859..c9396b0ff3f 100644 --- a/app/controllers/concerns/idv_step_concern.rb +++ b/app/controllers/concerns/idv_step_concern.rb @@ -53,9 +53,6 @@ def flow_path def confirm_hybrid_handoff_needed if params[:redo] idv_session.redo_document_capture = true - elsif idv_session.document_capture_complete? - redirect_to idv_ssn_url - return end # If we previously skipped hybrid handoff, keep doing that. @@ -70,29 +67,6 @@ def confirm_hybrid_handoff_needed private - def confirm_document_capture_not_complete - return unless idv_session.document_capture_complete? - - redirect_to idv_ssn_url - end - - def confirm_ssn_step_complete - return if pii.present? && idv_session.ssn.present? - redirect_to prev_url - end - - def confirm_document_capture_complete - return if idv_session.pii_from_doc.present? - - if flow_path == 'standard' - redirect_to idv_document_capture_url - elsif flow_path == 'hybrid' - redirect_to idv_link_sent_url - else # no flow_path - redirect_to idv_hybrid_handoff_path - end - end - def confirm_verify_info_step_complete return if idv_session.verify_info_step_complete? @@ -151,10 +125,11 @@ def confirm_step_allowed def url_for_latest_step step_info = flow_policy.info_for_latest_step + url_for(controller: step_info.controller, action: step_info.action) end - def clear_invalid_steps! - flow_policy.undo_steps_from_controller!(controller: self.class) + def clear_future_steps! + flow_policy.undo_future_steps_from_controller!(controller: self.class) end end diff --git a/app/controllers/idv/address_controller.rb b/app/controllers/idv/address_controller.rb index 8efc1c4679c..28f16d2d1d8 100644 --- a/app/controllers/idv/address_controller.rb +++ b/app/controllers/idv/address_controller.rb @@ -3,7 +3,8 @@ class AddressController < ApplicationController include IdvStepConcern before_action :confirm_not_rate_limited_after_doc_auth - before_action :confirm_document_capture_complete + before_action :confirm_step_allowed + before_action :confirm_verify_info_step_needed def new analytics.idv_address_visit @@ -12,6 +13,7 @@ def new end def update + clear_future_steps! form_result = idv_form.submit(profile_params) analytics.idv_address_submitted(**form_result.to_h) capture_address_edited(form_result) @@ -22,6 +24,16 @@ def update end end + def self.step_info + Idv::StepInfo.new( + key: :address, + controller: controller_name, + next_steps: [:verify_info], + preconditions: ->(idv_session:, user:) { idv_session.document_capture_complete? }, + undo_step: ->(idv_session:, user:) {}, + ) + end + private def idv_form diff --git a/app/controllers/idv/agreement_controller.rb b/app/controllers/idv/agreement_controller.rb index c2dcc75e20d..fe9d09d5a07 100644 --- a/app/controllers/idv/agreement_controller.rb +++ b/app/controllers/idv/agreement_controller.rb @@ -5,7 +5,7 @@ class AgreementController < ApplicationController before_action :confirm_not_rate_limited before_action :confirm_step_allowed - before_action :confirm_document_capture_not_complete + before_action :confirm_verify_info_step_needed def show analytics.idv_doc_auth_agreement_visited(**analytics_arguments) @@ -21,7 +21,7 @@ def show end def update - clear_invalid_steps! + clear_future_steps! skip_to_capture if params[:skip_hybrid_handoff] result = Idv::ConsentForm.new.submit(consent_form_params) @@ -49,7 +49,10 @@ def self.step_info controller: controller_name, next_steps: [:hybrid_handoff, :document_capture, :phone_question, :how_to_verify], preconditions: ->(idv_session:, user:) { idv_session.welcome_visited }, - undo_step: ->(idv_session:, user:) { idv_session.idv_consent_given = nil }, + undo_step: ->(idv_session:, user:) do + idv_session.idv_consent_given = nil + idv_session.skip_hybrid_handoff = nil + end, ) end diff --git a/app/controllers/idv/document_capture_controller.rb b/app/controllers/idv/document_capture_controller.rb index 24e2b51e70d..3adcf55a8a8 100644 --- a/app/controllers/idv/document_capture_controller.rb +++ b/app/controllers/idv/document_capture_controller.rb @@ -8,8 +8,7 @@ class DocumentCaptureController < ApplicationController before_action :confirm_not_rate_limited, except: [:update] before_action :confirm_step_allowed - before_action :confirm_hybrid_handoff_complete - before_action :confirm_document_capture_needed + before_action :confirm_verify_info_step_needed before_action :override_csp_to_allow_acuant def show @@ -22,7 +21,7 @@ def show end def update - clear_invalid_steps! + clear_future_steps! idv_session.redo_document_capture = nil # done with this redo # Not used in standard flow, here for data consistency with hybrid flow. document_capture_session.confirm_ocr @@ -59,31 +58,19 @@ def self.step_info Idv::StepInfo.new( key: :document_capture, controller: controller_name, - next_steps: [:success], # [:ssn], + next_steps: [:ssn], # :ipp_state_id preconditions: ->(idv_session:, user:) { idv_session.flow_path == 'standard' }, undo_step: ->(idv_session:, user:) do idv_session.pii_from_doc = nil idv_session.invalidate_in_person_pii_from_user! + idv_session.had_barcode_attention_error = nil + idv_session.had_barcode_read_failure = nil end, ) end private - def confirm_hybrid_handoff_complete - return if idv_session.flow_path.present? - - redirect_to idv_hybrid_handoff_url - end - - def confirm_document_capture_needed - return if idv_session.redo_document_capture - - return if idv_session.pii_from_doc.blank? && !idv_session.verify_info_step_complete? - - redirect_to idv_ssn_url - end - def cancel_establishing_in_person_enrollments UspsInPersonProofing::EnrollmentHelper. cancel_stale_establishing_enrollments_for_user(current_user) diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb index d6d52c2b89f..1ebebdcad08 100644 --- a/app/controllers/idv/getting_started_controller.rb +++ b/app/controllers/idv/getting_started_controller.rb @@ -3,7 +3,7 @@ class GettingStartedController < ApplicationController include IdvStepConcern before_action :confirm_not_rate_limited - before_action :confirm_document_capture_not_complete + before_action :confirm_verify_info_step_needed def show analytics.idv_doc_auth_getting_started_visited(**analytics_arguments) diff --git a/app/controllers/idv/how_to_verify_controller.rb b/app/controllers/idv/how_to_verify_controller.rb index f86fc672bb9..2713880a100 100644 --- a/app/controllers/idv/how_to_verify_controller.rb +++ b/app/controllers/idv/how_to_verify_controller.rb @@ -13,7 +13,7 @@ def show end def update - clear_invalid_steps! + clear_future_steps! result = Idv::HowToVerifyForm.new.submit(how_to_verify_form_params) analytics.idv_doc_auth_how_to_verify_submitted( diff --git a/app/controllers/idv/hybrid_handoff_controller.rb b/app/controllers/idv/hybrid_handoff_controller.rb index be83c31b68d..2717dbee6af 100644 --- a/app/controllers/idv/hybrid_handoff_controller.rb +++ b/app/controllers/idv/hybrid_handoff_controller.rb @@ -24,7 +24,7 @@ def show end def update - clear_invalid_steps! + clear_future_steps! irs_attempts_api_tracker.idv_document_upload_method_selected( upload_method: params[:type], ) @@ -42,7 +42,10 @@ def self.step_info controller: controller_name, next_steps: [:link_sent, :document_capture], preconditions: ->(idv_session:, user:) { idv_session.idv_consent_given }, - undo_step: ->(idv_session:, user:) { idv_session.flow_path = nil }, + undo_step: ->(idv_session:, user:) do + idv_session.flow_path = nil + idv_session.phone_for_mobile_flow = nil + end, ) end diff --git a/app/controllers/idv/in_person/verify_info_controller.rb b/app/controllers/idv/in_person/verify_info_controller.rb index fe0f26320af..ed41f1621e5 100644 --- a/app/controllers/idv/in_person/verify_info_controller.rb +++ b/app/controllers/idv/in_person/verify_info_controller.rb @@ -69,6 +69,11 @@ def analytics_arguments }.merge(ab_test_analytics_buckets). merge(**extra_analytics_properties) end + + def confirm_ssn_step_complete + return if pii.present? && idv_session.ssn.present? + redirect_to prev_url + end end end end diff --git a/app/controllers/idv/link_sent_controller.rb b/app/controllers/idv/link_sent_controller.rb index 2fa7f3cb78b..2cee5221f88 100644 --- a/app/controllers/idv/link_sent_controller.rb +++ b/app/controllers/idv/link_sent_controller.rb @@ -7,8 +7,7 @@ class LinkSentController < ApplicationController before_action :confirm_not_rate_limited before_action :confirm_step_allowed - before_action :confirm_hybrid_handoff_complete - before_action :confirm_document_capture_needed + before_action :confirm_verify_info_step_needed def show analytics.idv_doc_auth_link_sent_visited(**analytics_arguments) @@ -20,7 +19,7 @@ def show end def update - clear_invalid_steps! + clear_future_steps! analytics.idv_doc_auth_link_sent_submitted(**analytics_arguments) return render_document_capture_cancelled if document_capture_session&.cancelled_at @@ -45,35 +44,19 @@ def self.step_info Idv::StepInfo.new( key: :link_sent, controller: controller_name, - next_steps: [:success], # [:ssn], + next_steps: [:ssn], preconditions: ->(idv_session:, user:) { idv_session.flow_path == 'hybrid' }, undo_step: ->(idv_session:, user:) do idv_session.pii_from_doc = nil idv_session.invalidate_in_person_pii_from_user! + idv_session.had_barcode_attention_error = nil + idv_session.had_barcode_read_failure = nil end, ) end private - def confirm_hybrid_handoff_complete - return if idv_session.flow_path == 'hybrid' - - if idv_session.flow_path == 'standard' - redirect_to idv_document_capture_url - else - redirect_to idv_hybrid_handoff_url - end - end - - def confirm_document_capture_needed - return if idv_session.redo_document_capture - - return if idv_session.pii_from_doc.blank? && !idv_session.verify_info_step_complete? - - redirect_to idv_ssn_url - end - def analytics_arguments { step: 'link_sent', diff --git a/app/controllers/idv/phone_question_controller.rb b/app/controllers/idv/phone_question_controller.rb index 037b6b4faa7..1c4e6dee05d 100644 --- a/app/controllers/idv/phone_question_controller.rb +++ b/app/controllers/idv/phone_question_controller.rb @@ -16,7 +16,7 @@ def show end def phone_with_camera - clear_invalid_steps! + clear_future_steps! idv_session.phone_with_camera = true analytics.idv_doc_auth_phone_question_submitted(**analytics_arguments) @@ -24,7 +24,7 @@ def phone_with_camera end def phone_without_camera - clear_invalid_steps! + clear_future_steps! idv_session.flow_path = 'standard' idv_session.phone_with_camera = false analytics.idv_doc_auth_phone_question_submitted(**analytics_arguments) diff --git a/app/controllers/idv/ssn_controller.rb b/app/controllers/idv/ssn_controller.rb index 9e314571bad..0190c70870a 100644 --- a/app/controllers/idv/ssn_controller.rb +++ b/app/controllers/idv/ssn_controller.rb @@ -6,9 +6,8 @@ class SsnController < ApplicationController include ThreatMetrixConcern before_action :confirm_not_rate_limited_after_doc_auth + before_action :confirm_step_allowed before_action :confirm_verify_info_step_needed - before_action :confirm_document_capture_complete - before_action :confirm_repeat_ssn, only: :show before_action :override_csp_for_threat_metrix attr_reader :ssn_presenter @@ -34,6 +33,7 @@ def show end def update + clear_future_steps! ssn_form = Idv::SsnFormatForm.new(idv_session.ssn) form_response = ssn_form.submit(params.require(:doc_auth).permit(:ssn)) @ssn_presenter = Idv::SsnPresenter.new( @@ -58,15 +58,21 @@ def update end end - private - - def confirm_repeat_ssn - return if !idv_session.ssn - return if request.referer == idv_verify_info_url - - redirect_to idv_verify_info_url + def self.step_info + Idv::StepInfo.new( + key: :ssn, + controller: controller_name, + next_steps: [:verify_info], + preconditions: ->(idv_session:, user:) { idv_session.document_capture_complete? }, + undo_step: ->(idv_session:, user:) do + idv_session.ssn = nil + idv_session.threatmetrix_session_id = nil + end, + ) end + private + def next_url if idv_session.pii_from_doc[:state] == 'PR' && !ssn_presenter.updating_ssn? idv_address_url diff --git a/app/controllers/idv/verify_info_controller.rb b/app/controllers/idv/verify_info_controller.rb index b30db05794d..0b8d6d1ab79 100644 --- a/app/controllers/idv/verify_info_controller.rb +++ b/app/controllers/idv/verify_info_controller.rb @@ -6,12 +6,13 @@ class VerifyInfoController < ApplicationController include Steps::ThreatMetrixStepHelper before_action :confirm_not_rate_limited_after_doc_auth, except: [:show] - before_action :confirm_ssn_step_complete + before_action :confirm_step_allowed before_action :confirm_verify_info_step_needed def show @step_indicator_steps = step_indicator_steps @ssn = idv_session.ssn + @pii = pii analytics.idv_doc_auth_verify_visited(**analytics_arguments) Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]). @@ -22,6 +23,7 @@ def show end def update + clear_future_steps! success = shared_update if success @@ -35,6 +37,21 @@ def update end end + def self.step_info + Idv::StepInfo.new( + key: :verify_info, + controller: controller_name, + next_steps: [:success], # [:phone], + preconditions: ->(idv_session:, user:) do + idv_session.ssn && idv_session.document_capture_complete? + end, + undo_step: ->(idv_session:, user:) do + idv_session.resolution_successful = nil + idv_session.address_edited = nil + end, + ) + end + private def flow_param; end diff --git a/app/controllers/idv/welcome_controller.rb b/app/controllers/idv/welcome_controller.rb index 022381f9be0..9e2647a5d89 100644 --- a/app/controllers/idv/welcome_controller.rb +++ b/app/controllers/idv/welcome_controller.rb @@ -5,7 +5,7 @@ class WelcomeController < ApplicationController include GettingStartedAbTestConcern before_action :confirm_not_rate_limited - before_action :confirm_document_capture_not_complete + before_action :confirm_verify_info_step_needed before_action :maybe_redirect_for_getting_started_ab_test def show @@ -23,7 +23,7 @@ def show end def update - clear_invalid_steps! + clear_future_steps! analytics.idv_doc_auth_welcome_submitted(**analytics_arguments) create_document_capture_session @@ -40,7 +40,10 @@ def self.step_info controller: controller_name, next_steps: [:agreement], preconditions: ->(idv_session:, user:) { true }, - undo_step: ->(idv_session:, user:) { idv_session.welcome_visited = nil }, + undo_step: ->(idv_session:, user:) do + idv_session.welcome_visited = nil + idv_session.document_capture_session_uuid = nil + end, ) end diff --git a/app/policies/idv/flow_policy.rb b/app/policies/idv/flow_policy.rb index bbfd8ce9f48..01936ee9f61 100644 --- a/app/policies/idv/flow_policy.rb +++ b/app/policies/idv/flow_policy.rb @@ -18,11 +18,11 @@ def info_for_latest_step steps[latest_step] end - def undo_steps_from_controller!(controller:) + def undo_future_steps_from_controller!(controller:) controller_name = controller < ApplicationController ? controller.controller_name : controller key = controller_to_key(controller: controller_name) - undo_steps_from!(key: key) + undo_future_steps!(key: key) end private @@ -55,6 +55,9 @@ def steps hybrid_handoff: Idv::HybridHandoffController.step_info, link_sent: Idv::LinkSentController.step_info, document_capture: Idv::DocumentCaptureController.step_info, + ssn: Idv::SsnController.step_info, + verify_info: Idv::VerifyInfoController.step_info, + address: Idv::AddressController.step_info, } end @@ -72,6 +75,12 @@ def undo_steps_from!(key:) end end + def undo_future_steps!(key:) + steps[key].next_steps.each do |next_step| + undo_steps_from!(key: next_step) + end + end + def controller_to_key(controller:) steps.keys.each do |key| return key if steps[key].controller == controller diff --git a/spec/controllers/concerns/idv_step_concern_spec.rb b/spec/controllers/concerns/idv_step_concern_spec.rb index 9bae5a46998..baa096d9d88 100644 --- a/spec/controllers/concerns/idv_step_concern_spec.rb +++ b/spec/controllers/concerns/idv_step_concern_spec.rb @@ -64,9 +64,9 @@ def show idv_session.pii_from_doc = { first_name: 'Susan' } end - it 'redirects to ssn screen' do + it 'allows the back button and stays on page' do get :show - expect(response).to redirect_to(idv_ssn_url) + expect(response).to have_http_status(200) end context 'and redo specified' do @@ -206,65 +206,6 @@ def show end end - describe '#confirm_document_capture_not_complete' do - controller(idv_step_controller_class) do - before_action :confirm_document_capture_not_complete - end - - before(:each) do - sign_in(user) - routes.draw do - get 'show' => 'anonymous#show' - end - end - - context 'the user has not completed document capture' do - it 'does not redirect and renders the view' do - idv_session.pii_from_doc = nil - idv_session.resolution_successful = nil - - get :show - - expect(response.body).to eq('Hello') - expect(response.status).to eq(200) - end - end - - context 'the user has completed remote document capture but not verify_info' do - it 'redirects to the ssn step' do - idv_session.pii_from_doc = { first_name: 'Susan' } - idv_session.resolution_successful = false - - get :show - - expect(response).to redirect_to(idv_ssn_url) - end - end - - context 'the user has completed in person document capture but not verify_info' do - it 'redirects to the ssn step' do - subject.user_session['idv/in_person'] = {} - subject.user_session['idv/in_person'][:pii_from_user] = { first_name: 'Susan' } - idv_session.resolution_successful = false - - get :show - - expect(response).to redirect_to(idv_ssn_url) - end - end - - context 'the user has completed document capture and verify_info' do - it 'redirects to the ssn step' do - idv_session.pii_from_doc = nil - idv_session.resolution_successful = true - - get :show - - expect(response).to redirect_to(idv_ssn_url) - end - end - end - describe '#confirm_verify_info_step_complete' do controller(idv_step_controller_class) do before_action :confirm_verify_info_step_complete diff --git a/spec/controllers/idv/address_controller_spec.rb b/spec/controllers/idv/address_controller_spec.rb index 5f0e805c728..0b9f0a94e24 100644 --- a/spec/controllers/idv/address_controller_spec.rb +++ b/spec/controllers/idv/address_controller_spec.rb @@ -9,18 +9,35 @@ stub_sign_in(user) stub_analytics stub_idv_steps_before_verify_step(user) + subject.idv_session.welcome_visited = true + subject.idv_session.idv_consent_given = true subject.idv_session.flow_path = 'standard' subject.idv_session.pii_from_doc = pii_from_doc end - describe '#new' do - before do - get :new + describe '#step_info' do + it 'returns a valid StepInfo object' do + expect(Idv::AddressController.step_info).to be_valid end + end + describe '#new' do it 'logs an analytics event' do + get :new expect(@analytics).to have_logged_event('IdV: address visited') end + + context 'verify_info already submitted' do + before do + subject.idv_session.resolution_successful = true + end + + it 'redirects to enter_password' do + get :new + + expect(response).to redirect_to(idv_enter_password_url) + end + end end describe '#update' do @@ -63,6 +80,12 @@ ) end + it 'invalidates future steps' do + expect(subject).to receive(:clear_future_steps!) + + put :update, params: params + end + it 'logs an analytics event' do put :update, params: params expect(@analytics).to have_logged_event( diff --git a/spec/controllers/idv/agreement_controller_spec.rb b/spec/controllers/idv/agreement_controller_spec.rb index ff12f6194e9..36a95181335 100644 --- a/spec/controllers/idv/agreement_controller_spec.rb +++ b/spec/controllers/idv/agreement_controller_spec.rb @@ -79,22 +79,25 @@ context 'agreement already visited' do it 'does not redirect to hybrid_handoff' do - allow(subject.idv_session).to receive(:idv_consent_given).and_return(true) + subject.idv_session.idv_consent_given = true get :show expect(response).to render_template('idv/agreement/show') end - end - - context 'and document capture already completed' do - before do - subject.idv_session.pii_from_doc = { first_name: 'Susan' } - end - it 'redirects to ssn step' do - get :show - expect(response).to redirect_to(idv_ssn_url) + context 'and verify info already completed' do + before do + subject.idv_session.flow_path = 'standard' + subject.idv_session.pii_from_doc = { first_name: 'Susan' } + subject.idv_session.ssn = '123-45-6789' + subject.idv_session.resolution_successful = true + end + + it 'redirects to enter password step' do + get :show + expect(response).to redirect_to(idv_enter_password_url) + end end end end @@ -125,7 +128,7 @@ end it 'invalidates future steps' do - expect(subject).to receive(:clear_invalid_steps!) + expect(subject).to receive(:clear_future_steps!) put :update, params: params end diff --git a/spec/controllers/idv/document_capture_controller_spec.rb b/spec/controllers/idv/document_capture_controller_spec.rb index bf4e90620ed..56acad2f715 100644 --- a/spec/controllers/idv/document_capture_controller_spec.rb +++ b/spec/controllers/idv/document_capture_controller_spec.rb @@ -47,13 +47,6 @@ :check_for_mail_only_outage, ) end - - it 'checks that hybrid_handoff is complete' do - expect(subject).to have_actions( - :before, - :confirm_hybrid_handoff_complete, - ) - end end describe '#show' do @@ -119,12 +112,18 @@ end end - context 'with pii in idv_session' do - it 'redirects to ssn step' do + context 'verify info step is complete' do + it 'redirects to enter password step' do + subject.idv_session.welcome_visited = true + subject.idv_session.idv_consent_given = true + subject.idv_session.flow_path = 'standard' subject.idv_session.pii_from_doc = Idp::Constants::MOCK_IDV_APPLICANT + subject.idv_session.ssn = Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn] + subject.idv_session.resolution_successful = true + get :show - expect(response).to redirect_to(idv_ssn_url) + expect(response).to redirect_to(idv_enter_password_url) end end @@ -166,7 +165,7 @@ let(:result) { { success: true, errors: {} } } it 'invalidates future steps' do - expect(subject).to receive(:clear_invalid_steps!) + expect(subject).to receive(:clear_future_steps!) put :update end diff --git a/spec/controllers/idv/getting_started_controller_spec.rb b/spec/controllers/idv/getting_started_controller_spec.rb index 4f80bab9013..1b44b216b20 100644 --- a/spec/controllers/idv/getting_started_controller_spec.rb +++ b/spec/controllers/idv/getting_started_controller_spec.rb @@ -68,14 +68,18 @@ ) end - context 'document capture already completed' do + context 'verify info already completed' do before do + subject.idv_session.idv_consent_given = true + subject.idv_session.flow_path = 'standard' subject.idv_session.pii_from_doc = { first_name: 'Susan' } + subject.idv_session.ssn = '123-45-6789' + subject.idv_session.resolution_successful = true end - it 'redirects to ssn step' do + it 'redirects to enter password step' do get :show - expect(response).to redirect_to(idv_ssn_url) + expect(response).to redirect_to(idv_enter_password_url) end end diff --git a/spec/controllers/idv/how_to_verify_controller_spec.rb b/spec/controllers/idv/how_to_verify_controller_spec.rb index b129d8b1138..ba3ca5b3ac1 100644 --- a/spec/controllers/idv/how_to_verify_controller_spec.rb +++ b/spec/controllers/idv/how_to_verify_controller_spec.rb @@ -49,7 +49,7 @@ describe '#update' do it 'invalidates future steps' do - expect(subject).to receive(:clear_invalid_steps!) + expect(subject).to receive(:clear_future_steps!) put :update end diff --git a/spec/controllers/idv/hybrid_handoff_controller_spec.rb b/spec/controllers/idv/hybrid_handoff_controller_spec.rb index 6b9e0e10e38..83b28831bc3 100644 --- a/spec/controllers/idv/hybrid_handoff_controller_spec.rb +++ b/spec/controllers/idv/hybrid_handoff_controller_spec.rb @@ -221,7 +221,7 @@ let(:document_capture_session_uuid) { '09228b6d-dd39-4925-bf82-b69104095517' } it 'invalidates future steps' do - expect(subject).to receive(:clear_invalid_steps!) + expect(subject).to receive(:clear_future_steps!) put :update, params: params end diff --git a/spec/controllers/idv/link_sent_controller_spec.rb b/spec/controllers/idv/link_sent_controller_spec.rb index 44640a8a33f..1ed9c71067f 100644 --- a/spec/controllers/idv/link_sent_controller_spec.rb +++ b/spec/controllers/idv/link_sent_controller_spec.rb @@ -9,6 +9,8 @@ before do stub_sign_in(user) + subject.idv_session.welcome_visited = true + subject.idv_session.idv_consent_given = true subject.idv_session.flow_path = 'hybrid' stub_analytics stub_attempts_tracker @@ -37,10 +39,10 @@ ) end - it 'checks that hybrid_handoff is complete' do + it 'checks that step is allowed' do expect(subject).to have_actions( :before, - :confirm_hybrid_handoff_complete, + :confirm_step_allowed, ) end end @@ -76,17 +78,13 @@ ) end - context '#confirm_hybrid_handoff_complete' do - context 'no flow_path' do - it 'redirects to idv_hybrid_handoff_url' do - subject.idv_session.welcome_visited = true - subject.idv_session.idv_consent_given = true - subject.idv_session.flow_path = nil + context 'no flow_path in idv_session' do + it 'redirects to idv_hybrid_handoff_url' do + subject.idv_session.flow_path = nil - get :show + get :show - expect(response).to redirect_to(idv_hybrid_handoff_url) - end + expect(response).to redirect_to(idv_hybrid_handoff_url) end context 'flow_path is standard' do @@ -100,14 +98,14 @@ expect(response).to redirect_to(idv_document_capture_url) end end - end - context 'with pii in idv_session' do - it 'redirects to ssn step' do - subject.idv_session.pii_from_doc = Idp::Constants::MOCK_IDV_APPLICANT - get :show + context 'with pii in idv_session' do + it 'allows the back button and does not redirect' do + subject.idv_session.pii_from_doc = Idp::Constants::MOCK_IDV_APPLICANT + get :show - expect(response).to redirect_to(idv_ssn_url) + expect(response).to render_template :show + end end end end @@ -124,7 +122,7 @@ end it 'invalidates future steps' do - expect(subject).to receive(:clear_invalid_steps!) + expect(subject).to receive(:clear_future_steps!) put :update end diff --git a/spec/controllers/idv/phone_question_controller_spec.rb b/spec/controllers/idv/phone_question_controller_spec.rb index 32f25be8b42..d259a45d52f 100644 --- a/spec/controllers/idv/phone_question_controller_spec.rb +++ b/spec/controllers/idv/phone_question_controller_spec.rb @@ -145,7 +145,7 @@ let(:analytics_name) { :idv_doc_auth_phone_question_submitted } it 'invalidates future steps' do - expect(subject).to receive(:clear_invalid_steps!) + expect(subject).to receive(:clear_future_steps!) get :phone_with_camera end @@ -173,7 +173,7 @@ let(:analytics_name) { :idv_doc_auth_phone_question_submitted } it 'invalidates future steps' do - expect(subject).to receive(:clear_invalid_steps!) + expect(subject).to receive(:clear_future_steps!) get :phone_without_camera end diff --git a/spec/controllers/idv/ssn_controller_spec.rb b/spec/controllers/idv/ssn_controller_spec.rb index 60a251e7f80..3adea38c86e 100644 --- a/spec/controllers/idv/ssn_controller_spec.rb +++ b/spec/controllers/idv/ssn_controller_spec.rb @@ -19,6 +19,12 @@ allow(subject).to receive(:ab_test_analytics_buckets).and_return(ab_test_args) end + describe '#step_info' do + it 'returns a valid StepInfo object' do + expect(Idv::SsnController.step_info).to be_valid + end + end + describe 'before_actions' do it 'includes authentication before_action' do expect(subject).to have_actions( @@ -34,13 +40,6 @@ ) end - it 'checks that the previous step is complete' do - expect(subject).to have_actions( - :before, - :confirm_document_capture_complete, - ) - end - it 'overrides CSPs for ThreatMetrix' do expect(subject).to have_actions( :before, @@ -90,27 +89,14 @@ end context 'with an ssn in idv_session' do - let(:referer) { idv_document_capture_url } before do subject.idv_session.ssn = ssn - request.env['HTTP_REFERER'] = referer - end - - context 'referer is not verify_info' do - it 'redirects to verify_info' do - get :show - - expect(response).to redirect_to(idv_verify_info_url) - end end - context 'referer is verify_info' do - let(:referer) { idv_verify_info_url } - it 'does not redirect' do - get :show + it 'does not redirect and allows the back button' do + get :show - expect(response).to render_template 'idv/shared/ssn' - end + expect(response).to render_template 'idv/shared/ssn' end end @@ -176,6 +162,12 @@ end end + it 'invalidates future steps' do + expect(subject).to receive(:clear_future_steps!) + + put :update, params: params + end + it 'logs attempts api event' do expect(@irs_attempts_api_tracker).to receive(:idv_ssn_submitted).with( ssn: ssn, @@ -226,6 +218,8 @@ context 'when pii_from_doc is not present' do before do + subject.idv_session.welcome_visited = true + subject.idv_session.idv_consent_given = true subject.idv_session.flow_path = 'standard' subject.idv_session.pii_from_doc = nil end diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb index 4bcaa3dae30..a19c8b4c427 100644 --- a/spec/controllers/idv/verify_info_controller_spec.rb +++ b/spec/controllers/idv/verify_info_controller_spec.rb @@ -19,12 +19,20 @@ stub_analytics stub_attempts_tracker stub_idv_steps_before_verify_step(user) + subject.idv_session.welcome_visited = true + subject.idv_session.idv_consent_given = true subject.idv_session.flow_path = 'standard' subject.idv_session.pii_from_doc = Idp::Constants::MOCK_IDV_APPLICANT.dup subject.idv_session.ssn = Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn] allow(subject).to receive(:ab_test_analytics_buckets).and_return(ab_test_args) end + describe '#step_info' do + it 'returns a valid StepInfo object' do + expect(Idv::VerifyInfoController.step_info).to be_valid + end + end + describe 'before_actions' do it 'includes authentication before_action' do expect(subject).to have_actions( @@ -39,13 +47,6 @@ :check_for_mail_only_outage, ) end - - it 'confirms ssn step complete' do - expect(subject).to have_actions( - :before, - :confirm_ssn_step_complete, - ) - end end describe '#show' do @@ -365,6 +366,12 @@ end describe '#update' do + it 'invalidates future steps' do + expect(subject).to receive(:clear_future_steps!) + + put :update + end + it 'logs the correct analytics event' do put :update diff --git a/spec/controllers/idv/welcome_controller_spec.rb b/spec/controllers/idv/welcome_controller_spec.rb index c3d25a8128b..599893247ba 100644 --- a/spec/controllers/idv/welcome_controller_spec.rb +++ b/spec/controllers/idv/welcome_controller_spec.rb @@ -81,14 +81,17 @@ expect(response).to render_template('idv/welcome/show') end - context 'and document capture already completed' do + context 'and verify info already completed' do before do + subject.idv_session.flow_path = 'standard' subject.idv_session.pii_from_doc = { first_name: 'Susan' } + subject.idv_session.ssn = '123-45-6789' + subject.idv_session.resolution_successful = true end - it 'redirects to ssn step' do + it 'redirects to enter password step' do get :show - expect(response).to redirect_to(idv_ssn_url) + expect(response).to redirect_to(idv_enter_password_url) end end end @@ -140,7 +143,7 @@ end it 'invalidates future steps' do - expect(subject).to receive(:clear_invalid_steps!) + expect(subject).to receive(:clear_future_steps!) put :update end diff --git a/spec/features/idv/doc_auth/document_capture_spec.rb b/spec/features/idv/doc_auth/document_capture_spec.rb index 6224a75df38..1f58acd3191 100644 --- a/spec/features/idv/doc_auth/document_capture_spec.rb +++ b/spec/features/idv/doc_auth/document_capture_spec.rb @@ -182,7 +182,6 @@ expect_costing_for_document expect(DocAuthLog.find_by(user_id: user.id).state).to eq('MT') - visit(idv_document_capture_url) expect(page).to have_current_path(idv_ssn_url) fill_out_ssn_form_ok click_idv_continue diff --git a/spec/features/idv/doc_auth/redo_document_capture_spec.rb b/spec/features/idv/doc_auth/redo_document_capture_spec.rb index e35031ce7dd..83f14f5b618 100644 --- a/spec/features/idv/doc_auth/redo_document_capture_spec.rb +++ b/spec/features/idv/doc_auth/redo_document_capture_spec.rb @@ -54,10 +54,13 @@ DocAuth::Mock::DocAuthMockClient.reset! attach_and_submit_images + expect(current_path).to eq(idv_ssn_path) + expect(page).to have_css('[role="status"]') # We verified your ID + complete_ssn_step + expect(current_path).to eq(idv_verify_info_path) check t('forms.ssn.show') expect(page).to have_content(DocAuthHelper::GOOD_SSN) - expect(page).to have_css('[role="status"]') # We verified your ID end it 'document capture cannot be reached after submitting verify info step' do @@ -79,6 +82,7 @@ expect(page).to have_current_path(idv_document_capture_path) DocAuth::Mock::DocAuthMockClient.reset! attach_and_submit_images + complete_ssn_step complete_verify_step expect(page).to have_current_path(idv_phone_path) @@ -142,10 +146,13 @@ DocAuth::Mock::DocAuthMockClient.reset! attach_and_submit_images + expect(current_path).to eq(idv_ssn_path) + expect(page).to have_css('[role="status"]') # We verified your ID + complete_ssn_step + expect(current_path).to eq(idv_verify_info_path) check t('forms.ssn.show') expect(page).to have_content(DocAuthHelper::GOOD_SSN) - expect(page).to have_css('[role="status"]') # We verified your ID end end end diff --git a/spec/features/idv/end_to_end_idv_spec.rb b/spec/features/idv/end_to_end_idv_spec.rb index c2b51b73312..619b590320d 100644 --- a/spec/features/idv/end_to_end_idv_spec.rb +++ b/spec/features/idv/end_to_end_idv_spec.rb @@ -16,16 +16,13 @@ complete_welcome_step validate_agreement_page - try_to_go_back_from_agreement try_to_skip_ahead_from_agreement complete_agreement_step validate_hybrid_handoff_page - try_to_go_back_from_hybrid_handoff try_to_skip_ahead_from_hybrid_handoff complete_hybrid_handoff_step # upload photos - try_to_go_back_from_document_capture validate_document_capture_page complete_document_capture_step validate_document_capture_submit(user) @@ -33,7 +30,6 @@ validate_ssn_page complete_ssn_step - try_to_go_back_from_verify_info validate_verify_info_page complete_verify_step validate_verify_info_submit(user) @@ -56,6 +52,40 @@ validate_return_to_sp end + scenario 'Unsupervised proofing back button' do + visit_idp_from_sp_with_ial2(sp) + user = sign_up_and_2fa_ial1_user + + complete_welcome_step + + test_go_back_from_agreement + complete_agreement_step + + test_go_back_from_hybrid_handoff + complete_hybrid_handoff_step # upload photos + + test_go_back_from_document_capture + complete_document_capture_step + + test_go_back_from_ssn_page + complete_ssn_step + + test_go_back_from_verify_info + complete_verify_step + + validate_phone_page + visit_by_mail_and_return + complete_otp_verification_page(user) + + complete_enter_password_step(user) + + acknowledge_and_confirm_personal_key + + click_agree_and_continue + + validate_return_to_sp + end + context 'with an sp that allows in person proofing' do before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) @@ -357,7 +387,7 @@ def visit_by_mail_and_return expect(page).to have_current_path(idv_phone_path) end - def try_to_go_back_from_agreement + def test_go_back_from_agreement go_back expect(current_path).to eq(idv_welcome_path) complete_welcome_step @@ -368,7 +398,7 @@ def try_to_go_back_from_agreement ) end - def try_to_go_back_from_hybrid_handoff + def test_go_back_from_hybrid_handoff go_back expect(current_path).to eql(idv_agreement_path) expect(page).to have_checked_field( @@ -386,23 +416,37 @@ def try_to_go_back_from_hybrid_handoff complete_agreement_step end - def try_to_go_back_from_document_capture - visit(idv_agreement_path) + def test_go_back_from_document_capture + go_back + go_back expect(page).to have_current_path(idv_agreement_path) expect(page).to have_checked_field( t('doc_auth.instructions.consent', app_name: APP_NAME), visible: :all, ) - visit(idv_hybrid_handoff_url) + go_forward expect(page).to have_current_path(idv_hybrid_handoff_path) - visit(idv_document_capture_url) + go_forward + expect(page).to have_content(t('doc_auth.headings.front')) + expect(page).to have_content(t('doc_auth.headings.back')) end - def try_to_go_back_from_verify_info - visit(idv_document_capture_url) - expect(page).to have_current_path(idv_verify_info_path) - visit(idv_welcome_path) + def test_go_back_from_ssn_page + go_back + expect(page).to have_current_path(idv_document_capture_path) + go_forward + end + + def test_go_back_from_verify_info + go_back + go_back + expect(page).to have_current_path(idv_document_capture_path) + go_back + go_back + go_back + expect(page).to have_current_path(idv_welcome_path) + visit(idv_verify_info_path) expect(page).to have_current_path(idv_verify_info_path) end diff --git a/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb b/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb index 5f5db03ac0b..4f395c51e97 100644 --- a/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb +++ b/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb @@ -241,7 +241,9 @@ end perform_in_browser(:desktop) do - expect(page).to have_current_path(idv_verify_info_path, wait: 10) + expect(page).to have_current_path(idv_ssn_path, wait: 10) + complete_ssn_step + expect(page).to have_current_path(idv_verify_info_path) # verify orig pii no longer displayed expect(page).not_to have_text('DAVID') @@ -297,7 +299,9 @@ end perform_in_browser(:desktop) do - expect(page).to have_current_path(idv_verify_info_path, wait: 10) + expect(page).to have_current_path(idv_ssn_path, wait: 10) + complete_ssn_step + expect(page).to have_current_path(idv_verify_info_path) # verify orig pii no longer displayed expect(page).not_to have_text('DAVID') diff --git a/spec/policies/idv/flow_policy_spec.rb b/spec/policies/idv/flow_policy_spec.rb index 6c0c20f41f1..346086edc43 100644 --- a/spec/policies/idv/flow_policy_spec.rb +++ b/spec/policies/idv/flow_policy_spec.rb @@ -24,20 +24,48 @@ end end - context '#undo_steps_from_controller!' do - context 'user is on document_capture step' do + context '#undo_future_steps_from_controller!' do + context 'user is on verify_info step' do before do idv_session.welcome_visited = true + idv_session.document_capture_session_uuid = SecureRandom.uuid + idv_session.idv_consent_given = true + idv_session.skip_hybrid_handoff = true + idv_session.flow_path = 'standard' + idv_session.phone_for_mobile_flow = '201-555-1212' + + idv_session.pii_from_doc = Idp::Constants::MOCK_IDV_APPLICANT + idv_session.had_barcode_read_failure = true + idv_session.had_barcode_attention_error = true + + idv_session.ssn = Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn] + idv_session.threatmetrix_session_id = SecureRandom.uuid + + idv_session.address_edited = true end - it 'user goes back and submits welcome' do - subject.undo_steps_from_controller!(controller: Idv::WelcomeController) + it 'clears future steps when user goes back and submits welcome' do + subject.undo_future_steps_from_controller!(controller: Idv::WelcomeController) + + expect(idv_session.welcome_visited).not_to be_nil + expect(idv_session.document_capture_session_uuid).not_to be_nil - expect(idv_session.welcome_visited).to be_nil expect(idv_session.idv_consent_given).to be_nil + expect(idv_session.skip_hybrid_handoff).to be_nil + expect(idv_session.flow_path).to be_nil + expect(idv_session.phone_for_mobile_flow).to be_nil + + expect(idv_session.pii_from_doc).to be_nil + expect(idv_session.had_barcode_read_failure).to be_nil + expect(idv_session.had_barcode_attention_error).to be_nil + + expect(idv_session.ssn).to be_nil + expect(idv_session.threatmetrix_session_id).to be_nil + + expect(idv_session.address_edited).to be_nil end end end @@ -80,7 +108,7 @@ idv_session.flow_path = 'standard' expect(subject.info_for_latest_step.key).to eq(:document_capture) expect(subject.controller_allowed?(controller: Idv::DocumentCaptureController)).to be - # expect(subject.controller_allowed?(controller: Idv::SsnController)).not_to be + expect(subject.controller_allowed?(controller: Idv::SsnController)).not_to be end end @@ -91,7 +119,43 @@ idv_session.flow_path = 'hybrid' expect(subject.info_for_latest_step.key).to eq(:link_sent) expect(subject.controller_allowed?(controller: Idv::LinkSentController)).to be - # expect(subject.controller_allowed?(controller: Idv::SsnController)).not_to be + expect(subject.controller_allowed?(controller: Idv::SsnController)).not_to be + end + end + + context 'preconditions for ssn are present' do + before do + idv_session.welcome_visited = true + idv_session.idv_consent_given = true + idv_session.flow_path = 'standard' + idv_session.pii_from_doc = { pii: 'value' } + end + + it 'returns ssn for standard flow' do + expect(subject.info_for_latest_step.key).to eq(:ssn) + expect(subject.controller_allowed?(controller: Idv::SsnController)).to be + expect(subject.controller_allowed?(controller: Idv::VerifyInfoController)).not_to be + end + + it 'returns ssn for hybrid flow' do + idv_session.flow_path = 'hybrid' + expect(subject.info_for_latest_step.key).to eq(:ssn) + expect(subject.controller_allowed?(controller: Idv::SsnController)).to be + expect(subject.controller_allowed?(controller: Idv::VerifyInfoController)).not_to be + end + end + + context 'preconditions for verify_info are present' do + it 'returns verify_info' do + idv_session.welcome_visited = true + idv_session.idv_consent_given = true + idv_session.flow_path = 'standard' + idv_session.pii_from_doc = { pii: 'value' } + idv_session.ssn = '666666666' + + expect(subject.info_for_latest_step.key).to eq(:verify_info) + expect(subject.controller_allowed?(controller: Idv::VerifyInfoController)).to be + # expect(subject.controller_allowed?(controller: Idv::PhoneController)).not_to be end end end