diff --git a/app/controllers/idv/how_to_verify_controller.rb b/app/controllers/idv/how_to_verify_controller.rb index 413a2e6cfb3..f9c14d7a9f0 100644 --- a/app/controllers/idv/how_to_verify_controller.rb +++ b/app/controllers/idv/how_to_verify_controller.rb @@ -61,7 +61,9 @@ def self.step_info controller: self, next_steps: [:hybrid_handoff, :document_capture], preconditions: ->(idv_session:, user:) do - self.enabled? && idv_session.idv_consent_given + self.enabled? && + idv_session.idv_consent_given && + idv_session.service_provider&.in_person_proofing_enabled end, undo_step: ->(idv_session:, user:) { idv_session.skip_doc_auth = nil }, ) diff --git a/spec/controllers/idv/how_to_verify_controller_spec.rb b/spec/controllers/idv/how_to_verify_controller_spec.rb index 6d3c2c72923..e07e917d64f 100644 --- a/spec/controllers/idv/how_to_verify_controller_spec.rb +++ b/spec/controllers/idv/how_to_verify_controller_spec.rb @@ -6,6 +6,9 @@ let(:ab_test_args) do { sample_bucket1: :sample_value1, sample_bucket2: :sample_value2 } end + let(:service_provider) do + create(:service_provider, :active, :in_person_proofing_enabled) + end before do allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { true } @@ -14,6 +17,7 @@ stub_analytics allow(@analytics).to receive(:track_event) allow(subject).to receive(:ab_test_analytics_buckets).and_return(ab_test_args) + allow(subject.idv_session).to receive(:service_provider).and_return(service_provider) subject.idv_session.welcome_visited = true subject.idv_session.idv_consent_given = true end @@ -73,12 +77,29 @@ end context 'when both ipp and opt-in ipp are enabled' do - it 'renders the show template for how to verify' do - get :show + context 'when the ServiceProvider has IPP enabled' do + it 'renders the show template for how to verify' do + get :show + + expect(Idv::HowToVerifyController.enabled?).to be true + expect(subject.idv_session.service_provider.in_person_proofing_enabled).to be true + expect(subject.idv_session.skip_doc_auth).to be_nil + expect(response).to render_template :show + end + end - expect(Idv::HowToVerifyController.enabled?).to be true - expect(subject.idv_session.skip_doc_auth).to be_nil - expect(response).to render_template :show + context 'when the ServiceProvider has IPP disabled' do + let(:service_provider) do + create(:service_provider, :active) + end + + it 'redirects to hybrid_handoff' do + get :show + + expect(Idv::HowToVerifyController.enabled?).to be true + expect(subject.idv_session.service_provider.in_person_proofing_enabled).to be false + expect(response).to redirect_to(idv_hybrid_handoff_url) + end end end end @@ -94,6 +115,7 @@ irs_reproofing: false, }.merge(ab_test_args) end + it 'renders the show template' do get :show @@ -127,6 +149,7 @@ } end let(:analytics_name) { :idv_doc_auth_how_to_verify_submitted } + context 'no selection made' do let(:analytics_args) do { diff --git a/spec/factories/service_providers.rb b/spec/factories/service_providers.rb index 085f0adedeb..e0843f73190 100644 --- a/spec/factories/service_providers.rb +++ b/spec/factories/service_providers.rb @@ -42,6 +42,10 @@ active { true } end + trait :in_person_proofing_enabled do + in_person_proofing_enabled { true } + end + trait :irs do friendly_name { 'An IRS Service Provider' } ial { 2 } diff --git a/spec/features/accessibility/idv_pages_spec.rb b/spec/features/accessibility/idv_pages_spec.rb index 295b25f7db3..0985a390be4 100644 --- a/spec/features/accessibility/idv_pages_spec.rb +++ b/spec/features/accessibility/idv_pages_spec.rb @@ -5,6 +5,10 @@ describe 'IDV pages' do include IdvStepHelper + let(:service_provider) do + create(:service_provider, :active, :in_person_proofing_enabled) + end + scenario 'home page' do sign_in_and_2fa_user @@ -16,6 +20,7 @@ scenario 'how to verify page' do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled).and_return(true) + allow_any_instance_of(Idv::Session).to receive(:service_provider).and_return(service_provider) sign_in_and_2fa_user visit idv_welcome_url diff --git a/spec/features/idv/doc_auth/how_to_verify_spec.rb b/spec/features/idv/doc_auth/how_to_verify_spec.rb index 10d1c157503..2460e1c50d6 100644 --- a/spec/features/idv/doc_auth/how_to_verify_spec.rb +++ b/spec/features/idv/doc_auth/how_to_verify_spec.rb @@ -4,83 +4,179 @@ include IdvHelper include DocAuthHelper + let(:user) { user_with_2fa } + let(:ipp_service_provider) { create(:service_provider, :active, :in_person_proofing_enabled) } + context 'when ipp is enabled and opt-in ipp is disabled' do - before do - allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { true } - allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { false } + context 'and when sp has opted into ipp' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { true } + allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { false } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(true) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) - sign_in_and_2fa_user - complete_doc_auth_steps_before_agreement_step - complete_agreement_step + complete_doc_auth_steps_before_agreement_step + complete_agreement_step + end + + it 'skips when disabled and redirects to hybrid handoff' do + expect(page).to have_current_path(idv_hybrid_handoff_url) + end end - it 'skips when disabled and redirects to hybrid handoff' do - expect(page).to have_current_path(idv_hybrid_handoff_url) + context 'and when sp has not opted into ipp' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { true } + allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { false } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(false) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) + + complete_doc_auth_steps_before_agreement_step + complete_agreement_step + end + + it 'skips when disabled and redirects to hybrid handoff' do + expect(page).to have_current_path(idv_hybrid_handoff_url) + end end end context 'when ipp is disabled and opt-in ipp is enabled' do - before do - allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { false } - allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { true } + context 'and when sp has opted into ipp' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { false } + allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { true } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(true) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) - sign_in_and_2fa_user - complete_doc_auth_steps_before_agreement_step - complete_agreement_step + complete_doc_auth_steps_before_agreement_step + complete_agreement_step + end + + it 'skips when disabled and redirects to hybrid handoff' do + expect(page).to have_current_path(idv_hybrid_handoff_url) + end end - it 'skips when disabled and redirects to hybird handoff' do - expect(page).to have_current_path(idv_hybrid_handoff_url) + context 'and when sp has not opted into ipp' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { false } + allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { true } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(false) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) + + complete_doc_auth_steps_before_agreement_step + complete_agreement_step + end + + it 'skips when disabled and redirects to hybrid handoff' do + expect(page).to have_current_path(idv_hybrid_handoff_url) + end end end context 'when both ipp and opt-in ipp are disabled' do - before do - allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { false } - allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { false } + context 'and when sp has opted into ipp' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { false } + allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { false } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(true) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) - sign_in_and_2fa_user - complete_doc_auth_steps_before_agreement_step - complete_agreement_step + complete_doc_auth_steps_before_agreement_step + complete_agreement_step + end + + it 'skips when disabled and redirects to hybrid handoff' do + expect(page).to have_current_path(idv_hybrid_handoff_url) + end end - it 'skips when disabled and redirects to hybird handoff' do - expect(page).to have_current_path(idv_hybrid_handoff_url) + context 'and when sp has not opted into ipp' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { false } + allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { false } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(false) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) + + complete_doc_auth_steps_before_agreement_step + complete_agreement_step + end + + it 'skips when disabled and redirects to hybrid handoff' do + expect(page).to have_current_path(idv_hybrid_handoff_url) + end end end context 'when both ipp and opt-in ipp are enabled' do - before do - allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { true } - allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { true } + context 'and when sp has opted into ipp' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { true } + allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { true } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(true) - sign_in_and_2fa_user - complete_doc_auth_steps_before_agreement_step - complete_agreement_step - end + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) + complete_doc_auth_steps_before_agreement_step + complete_agreement_step + end + + it 'displays expected content and requires a choice' do + expect(page).to have_current_path(idv_how_to_verify_path) + + # Try to continue without an option + click_continue + + expect(page).to have_current_path(idv_how_to_verify_path) + expect(page).to have_content(t('errors.doc_auth.how_to_verify_form')) - it 'displays expected content and requires a choice' do - expect(page).to have_current_path(idv_how_to_verify_path) + complete_how_to_verify_step(remote: true) + expect(page).to have_current_path(idv_hybrid_handoff_url) + + # go back and also test remote: false case + page.go_back + complete_how_to_verify_step(remote: false) + expect(page).to have_current_path(idv_document_capture_path) + end + end - # Try to continue without an option - click_continue + context 'and when sp has not opted into ipp' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { true } + allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { true } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(false) - expect(page).to have_current_path(idv_how_to_verify_path) - expect(page).to have_content(t('errors.doc_auth.how_to_verify_form')) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) + complete_doc_auth_steps_before_agreement_step + complete_agreement_step + end - complete_how_to_verify_step(remote: true) - expect(page).to have_current_path(idv_hybrid_handoff_url) + it 'skips when disabled and redirects to hybrid handoff' do + expect(page).to have_current_path(idv_hybrid_handoff_url) + end end end - describe 'navigating to How To Verify from Agreement page in 50/50 state' do + describe 'navigating to How To Verify from Agreement page in 50/50 state + when the sp has opted into ipp' do + let(:user) { user_with_2fa } before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { true } allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { initial_opt_in_enabled } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(true) - sign_in_and_2fa_user + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) complete_doc_auth_steps_before_agreement_step complete_agreement_step end diff --git a/spec/features/idv/steps/in_person_opt_in_ipp_spec.rb b/spec/features/idv/steps/in_person_opt_in_ipp_spec.rb index b8f3f6a1dff..8fdba30c11a 100644 --- a/spec/features/idv/steps/in_person_opt_in_ipp_spec.rb +++ b/spec/features/idv/steps/in_person_opt_in_ipp_spec.rb @@ -7,6 +7,8 @@ include InPersonHelper org = 'test_org' + let(:ipp_service_provider) { create(:service_provider, :active, :in_person_proofing_enabled) } + before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled).and_return(true) @@ -19,11 +21,13 @@ before do allow(IdentityConfig.store).to receive(:proofing_device_profiling).and_return(:enabled) allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_org_id).and_return(org) + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(true) end it 'allows the user to continue down the happy path selecting to opt in', allow_browser_log: true do - sign_in_and_2fa_user(user) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) # complete welcome step, agreement step, how to verify step (and opts into Opt-in Ipp) begin_in_person_proofing_with_opt_in_ipp_enabled_and_opting_in @@ -121,7 +125,7 @@ it 'works for a happy path when the user opts into opt-in ipp', allow_browser_log: true do user = user_with_2fa - sign_in_and_2fa_user(user) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) # complete welcome step, agreement step, how to verify step (and opts into Opt-in Ipp) begin_in_person_proofing_with_opt_in_ipp_enabled_and_opting_in @@ -268,10 +272,29 @@ expect(page).to have_current_path(account_path) end + context 'when the service provider does not participate in IPP', + allow_browser_log: true do + before do + allow(IdentityConfig.store).to receive(:proofing_device_profiling).and_return(:enabled) + allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_org_id).and_return(org) + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(false) + end + + it 'skips how to verify and goes to hybrid_handoff' do + user = user_with_2fa + sign_in_and_2fa_user(user) + visit_idp_from_sp_with_ial2(:oidc) + complete_welcome_step + complete_agreement_step + expect(page).to have_current_path(idv_hybrid_handoff_url) + end + end + it 'works for a happy path when the user opts out of opt-in ipp', allow_browser_log: true do user = user_with_2fa - sign_in_and_2fa_user(user) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) # complete welcome step, agreement step, how to verify step (and opts out of Opt-in Ipp) begin_in_person_proofing_with_opt_in_ipp_enabled_and_opting_out @@ -416,6 +439,8 @@ before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { false } allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) { true } + allow_any_instance_of(ServiceProvider).to receive(:in_person_proofing_enabled). + and_return(true) end it 'skips how to verify and continues along the normal path' do @@ -435,7 +460,7 @@ it 'works properly along the normal path when in_person_proofing_enabled is true' do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { true } - sign_in_and_2fa_user(user) + sign_in_and_2fa_user(user, issuer: ipp_service_provider.issuer) visit_idp_from_sp_with_ial2(:oidc) complete_welcome_step complete_agreement_step diff --git a/spec/support/features/idv_helper.rb b/spec/support/features/idv_helper.rb index 951e805d358..48fd84d9db2 100644 --- a/spec/support/features/idv_helper.rb +++ b/spec/support/features/idv_helper.rb @@ -93,8 +93,8 @@ def visit_idp_from_sp_with_ial2(sp, **extra) visit_idp_from_saml_sp_with_ial2 elsif sp == :oidc @state = SecureRandom.hex - @client_id = sp_oidc_issuer @nonce = SecureRandom.hex + @client_id = sp_oidc_issuer visit_idp_from_oidc_sp_with_ial2(state: @state, client_id: @client_id, nonce: @nonce, **extra) end end diff --git a/spec/support/features/session_helper.rb b/spec/support/features/session_helper.rb index ed1e55d8d72..b5754b5dc38 100644 --- a/spec/support/features/session_helper.rb +++ b/spec/support/features/session_helper.rb @@ -204,7 +204,7 @@ def sign_in_before_2fa(user = create(:user)) user end - def sign_in_with_warden(user, auth_method: nil) + def sign_in_with_warden(user, auth_method: nil, issuer: nil) login_as(user, scope: :user, run_callbacks: false) Warden.on_next_request do |proxy| @@ -213,12 +213,13 @@ def sign_in_with_warden(user, auth_method: nil) if auth_method session['warden.user.user.session']['auth_events'] = [{ auth_method:, at: Time.zone.now }] end + session['sp'] = { issuer: } if issuer end visit account_path end - def sign_in_and_2fa_user(user = user_with_2fa) - sign_in_with_warden(user, auth_method: 'phone') + def sign_in_and_2fa_user(user = user_with_2fa, issuer: nil) + sign_in_with_warden(user, auth_method: 'phone', issuer:) user end