diff --git a/app/controllers/idv/document_capture_controller.rb b/app/controllers/idv/document_capture_controller.rb index 207630bda73..99ff49e8da4 100644 --- a/app/controllers/idv/document_capture_controller.rb +++ b/app/controllers/idv/document_capture_controller.rb @@ -63,6 +63,7 @@ def self.step_info idv_session.flow_path == 'standard' && ( # mobile idv_session.skip_hybrid_handoff || + idv_session.skip_doc_auth || !idv_session.selfie_check_required || # desktop but selfie not required idv_session.desktop_selfie_test_mode_enabled? ) diff --git a/app/controllers/idv/hybrid_handoff_controller.rb b/app/controllers/idv/hybrid_handoff_controller.rb index c50eae4f74d..829ff2abe7c 100644 --- a/app/controllers/idv/hybrid_handoff_controller.rb +++ b/app/controllers/idv/hybrid_handoff_controller.rb @@ -13,6 +13,8 @@ def show @upload_disabled = idv_session.selfie_check_required && !idv_session.desktop_selfie_test_mode_enabled? + @selfie_required = idv_session.selfie_check_required + analytics.idv_doc_auth_hybrid_handoff_visited(**analytics_arguments) Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( diff --git a/app/views/idv/hybrid_handoff/show.html.erb b/app/views/idv/hybrid_handoff/show.html.erb index fe09cd82f04..a7164548357 100644 --- a/app/views/idv/hybrid_handoff/show.html.erb +++ b/app/views/idv/hybrid_handoff/show.html.erb @@ -8,16 +8,56 @@ class: 'margin-x-neg-2 margin-top-neg-4 tablet:margin-x-neg-6 tablet:margin-top-neg-4', ) %> <% end %> +<%# ============== Non Selfie Section ========== %> +<% if !@selfie_required %> -<%= render PageHeadingComponent.new do %> - <%= t('doc_auth.headings.hybrid_handoff') %> -<% end %> + <%= render PageHeadingComponent.new do %> + <%= t('doc_auth.headings.hybrid_handoff') %> + <% end %> -

- <%= t('doc_auth.info.hybrid_handoff') %> -

+

+ <%= t('doc_auth.info.hybrid_handoff') %> +

-
+
+
+ <%= image_tag( + asset_url('idv/phone-icon.svg'), + alt: t('image_description.camera_mobile_phone'), + width: 88, + height: 88, + ) %> +
+
+
+ <%= t('doc_auth.info.tag') %> +
+

+ <%= t('doc_auth.headings.upload_from_phone') %> +

+ <%= t('doc_auth.info.upload_from_phone') %> + <%= simple_form_for( + idv_phone_form, + as: :doc_auth, + url: url_for(type: :mobile, combined: true), + method: 'PUT', + html: { autocomplete: 'off', + id: 'form-to-submit-photos-through-mobile', + 'aria-label': t('forms.buttons.send_link') }, + ) do |f| %> + <%= render PhoneInputComponent.new( + form: f, + required: true, + delivery_methods: [:sms], + class: 'margin-bottom-4', + ) %> + <%= f.submit t('forms.buttons.send_link') %> + <% end %> +
+
+<%# ============== Selfie Section ========== %> +<% else %> +
<%= image_tag( asset_url('idv/phone-icon.svg'), @@ -27,12 +67,9 @@ ) %>
-
- <%= t('doc_auth.info.tag') %> -
-

- <%= t('doc_auth.headings.upload_from_phone') %> -

+ <%= render PageHeadingComponent.new do %> + <%= t('doc_auth.headings.hybrid_handoff_selfie') %> + <% end %> <%= t('doc_auth.info.upload_from_phone') %> <%= simple_form_for( idv_phone_form, @@ -52,7 +89,8 @@ <%= f.submit t('forms.buttons.send_link') %> <% end %>
-
+
+<% end %> <% unless @upload_disabled %>
diff --git a/config/locales/doc_auth/en.yml b/config/locales/doc_auth/en.yml index a5d5dd2d1f0..461dba9627c 100644 --- a/config/locales/doc_auth/en.yml +++ b/config/locales/doc_auth/en.yml @@ -163,6 +163,7 @@ en: front: Front of your driver’s license or state ID how_to_verify: Choose how you want to verify your identity hybrid_handoff: How would you like to add your ID? + hybrid_handoff_selfie: Enter your phone number to switch devices interstitial: We are processing your images lets_go: How verifying your identity works no_ssn: Don’t have a Social Security number? diff --git a/config/locales/doc_auth/es.yml b/config/locales/doc_auth/es.yml index b6bd473dae3..f3a9d72d39f 100644 --- a/config/locales/doc_auth/es.yml +++ b/config/locales/doc_auth/es.yml @@ -194,6 +194,7 @@ es: front: Anverso de su licencia de conducir o identificación estatal how_to_verify: Elija cómo quiere verificar su identidad hybrid_handoff: '¿Cómo desea añadir su documento de identidad?' + hybrid_handoff_selfie: Ingrese su número de celular para cambiar de dispositivo interstitial: Estamos procesando sus imágenes lets_go: Cómo funciona la verificación de su identidad no_ssn: ¿No tiene un número de Seguro Social? diff --git a/config/locales/doc_auth/fr.yml b/config/locales/doc_auth/fr.yml index 68ac732127a..567d4a12b8c 100644 --- a/config/locales/doc_auth/fr.yml +++ b/config/locales/doc_auth/fr.yml @@ -203,6 +203,7 @@ fr: front: Recto de votre permis de conduire ou de votre carte d’identité de l’État how_to_verify: Choisissez la manière dont vous souhaitez confirmer votre identité hybrid_handoff: Comment voulez-vous ajouter votre identifiant ? + hybrid_handoff_selfie: Saisissez votre numéro de téléphone pour changer d’appareil interstitial: Nous traitons vos images lets_go: Comment fonctionne la vérification de votre identité no_ssn: Vous n’avez pas de numéro de sécurité sociale? diff --git a/spec/features/idv/doc_auth/document_capture_spec.rb b/spec/features/idv/doc_auth/document_capture_spec.rb index c791001e544..797e7136fa0 100644 --- a/spec/features/idv/doc_auth/document_capture_spec.rb +++ b/spec/features/idv/doc_auth/document_capture_spec.rb @@ -529,7 +529,8 @@ complete_doc_auth_steps_before_hybrid_handoff_step # we still have option to continue expect(page).to have_current_path(idv_hybrid_handoff_path) - expect(page).to have_content(t('doc_auth.headings.upload_from_phone')) + expect(page).to have_content(t('doc_auth.headings.hybrid_handoff_selfie')) + expect(page).not_to have_content(t('doc_auth.headings.hybrid_handoff')) expect(page).not_to have_content(t('doc_auth.info.upload_from_computer')) click_on t('forms.buttons.send_link') expect(page).to have_current_path(idv_link_sent_path) @@ -545,8 +546,9 @@ complete_doc_auth_steps_before_hybrid_handoff_step # we still have option to continue on handoff, since it's desktop no skip_hand_off expect(page).to have_current_path(idv_hybrid_handoff_path) + expect(page).to have_content(t('doc_auth.headings.hybrid_handoff_selfie')) + expect(page).not_to have_content(t('doc_auth.headings.hybrid_handoff')) expect(page).to have_content(t('doc_auth.info.upload_from_computer')) - expect(page).to have_content(t('doc_auth.headings.upload_from_phone')) click_on t('forms.buttons.upload_photos') expect(page).to have_current_path(idv_document_capture_url) expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) diff --git a/spec/features/idv/doc_auth/hybrid_handoff_spec.rb b/spec/features/idv/doc_auth/hybrid_handoff_spec.rb index 53f1bbd5248..f7ade66a6f0 100644 --- a/spec/features/idv/doc_auth/hybrid_handoff_spec.rb +++ b/spec/features/idv/doc_auth/hybrid_handoff_spec.rb @@ -11,8 +11,15 @@ let(:idv_send_link_attempt_window_in_minutes) do IdentityConfig.store.idv_send_link_attempt_window_in_minutes end + let(:doc_auth_selfie_capture_enabled) { false } + let(:biometric_comparison_required) { false } before do + allow(IdentityConfig.store).to receive(:doc_auth_selfie_capture_enabled). + and_return(doc_auth_selfie_capture_enabled) + if biometric_comparison_required + visit_idp_from_oidc_sp_with_ial2(biometric_comparison_required: biometric_comparison_required) + end sign_in_and_2fa_user allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics) allow_any_instance_of(ApplicationController).to receive(:irs_attempts_api_tracker). @@ -209,4 +216,31 @@ expect(document_capture_session).to have_attributes(requested_at: a_kind_of(Time)) end end + + context 'on a desktop device and selfie is allowed' do + let(:doc_auth_selfie_capture_enabled) { true } + before do + complete_doc_auth_steps_before_hybrid_handoff_step + end + + describe 'when selfie is required by sp' do + let(:biometric_comparison_required) { true } + it 'has expected UI elements' do + mobile_form = find('#form-to-submit-photos-through-mobile') + expect(mobile_form).to have_name(t('forms.buttons.send_link')) + expect(page).to have_selector('h1', text: t('doc_auth.headings.hybrid_handoff_selfie')) + end + end + + describe 'when selfie is not required by sp' do + let(:biometric_comparison_required) { false } + it 'has expected UI elements' do + mobile_form = find('#form-to-submit-photos-through-mobile') + desktop_form = find('#form-to-submit-photos-through-desktop') + + expect(mobile_form).to have_name(t('forms.buttons.send_link')) + expect(desktop_form).to have_name(t('forms.buttons.upload_photos')) + end + end + end end diff --git a/spec/views/idv/hybrid_handoff/show.html.erb_spec.rb b/spec/views/idv/hybrid_handoff/show.html.erb_spec.rb index eec29236ebf..8ee305e5127 100644 --- a/spec/views/idv/hybrid_handoff/show.html.erb_spec.rb +++ b/spec/views/idv/hybrid_handoff/show.html.erb_spec.rb @@ -12,22 +12,41 @@ } end - it 'has a form for starting mobile doc auth with an aria label tag' do - expect(rendered).to have_selector( - :xpath, - "//form[@aria-label=\"#{t('forms.buttons.send_link')}\"]", - ) - end + context 'when selfie is not required' do + before do + @selfie_required = false + end + it 'has a form for starting mobile doc auth with an aria label tag' do + expect(rendered).to have_selector( + :xpath, + "//form[@aria-label=\"#{t('forms.buttons.send_link')}\"]", + ) + end - it 'has a form for starting desktop doc auth with an aria label tag' do - expect(rendered).to have_selector( - :xpath, - "//form[@aria-label=\"#{t('forms.buttons.upload_photos')}\"]", - ) - end + it 'has a form for starting desktop doc auth with an aria label tag' do + expect(rendered).to have_selector( + :xpath, + "//form[@aria-label=\"#{t('forms.buttons.upload_photos')}\"]", + ) + end - it 'displays the expected headings from the "a" case' do - expect(rendered).to have_selector('h1', text: t('doc_auth.headings.hybrid_handoff')) - expect(rendered).to have_selector('h2', text: t('doc_auth.headings.upload_from_phone')) + it 'displays the expected headings from the "a" case' do + expect(rendered).to have_selector('h1', text: t('doc_auth.headings.hybrid_handoff')) + expect(rendered).to have_selector('h2', text: t('doc_auth.headings.upload_from_phone')) + end + end + context 'when selfie is required' do + before do + @selfie_required = true + end + it 'has a form for starting mobile doc auth with an aria label tag' do + expect(rendered).to have_selector( + :xpath, + "//form[@aria-label=\"#{t('forms.buttons.send_link')}\"]", + ) + end + it 'displays the expected headings from the "a" case' do + expect(rendered).to have_selector('h1', text: t('doc_auth.headings.hybrid_handoff_selfie')) + end end end