From 69ad7db741a1d0fe90e9b7d551f594c39b46e14a Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Fri, 21 Feb 2025 15:30:37 -0500 Subject: [PATCH 01/22] create choose_id_type_controller --- app/controllers/idv/choose_id_type_controller.rb | 16 ++++++++++++++++ config/routes.rb | 2 ++ 2 files changed, 18 insertions(+) create mode 100644 app/controllers/idv/choose_id_type_controller.rb diff --git a/app/controllers/idv/choose_id_type_controller.rb b/app/controllers/idv/choose_id_type_controller.rb new file mode 100644 index 00000000000..993fb5d876a --- /dev/null +++ b/app/controllers/idv/choose_id_type_controller.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Idv + class ChooseIdTypeController < ApplicationController + include Idv::AvailabilityConcern + include IdvStepConcern + include StepIndicatorConcern + + def show + end + + def update + clear_future_steps! + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 4201dae14e7..31457b2e174 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -391,6 +391,8 @@ get '/hybrid_mobile/socure/document_capture_errors' => 'hybrid_mobile/socure/errors#show', as: :hybrid_mobile_socure_document_capture_errors get '/hybrid_handoff' => 'hybrid_handoff#show' put '/hybrid_handoff' => 'hybrid_handoff#update' + get '/choose_id_type' => 'choose_id_type#show' + put '/choose_id_type' => 'choose_id_type#update' get '/link_sent' => 'link_sent#show' put '/link_sent' => 'link_sent#update' get '/link_sent/poll' => 'link_sent_poll#show' From a5b464ad893088b637b768840918710eaa7e7b6c Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Tue, 25 Feb 2025 11:25:15 -0500 Subject: [PATCH 02/22] create choose_id_type page --- app/views/idv/choose_id_type/show.html.erb | 53 ++++++++++++++++++++++ config/locales/en.yml | 5 ++ config/locales/es.yml | 5 ++ config/locales/fr.yml | 5 ++ config/locales/zh.yml | 5 ++ 5 files changed, 73 insertions(+) create mode 100644 app/views/idv/choose_id_type/show.html.erb diff --git a/app/views/idv/choose_id_type/show.html.erb b/app/views/idv/choose_id_type/show.html.erb new file mode 100644 index 00000000000..1a7f23c07b9 --- /dev/null +++ b/app/views/idv/choose_id_type/show.html.erb @@ -0,0 +1,53 @@ +<% self.title = t('doc_auth.headings.choose_id_type') %> + +<% content_for(:pre_flash_content) do %> + <%= render StepIndicatorComponent.new( + steps: Idv::StepIndicatorConcern::STEP_INDICATOR_STEPS, + current_step: :verify_id, + locale_scope: 'idv', + class: 'margin-x-neg-2 margin-top-neg-4 tablet:margin-x-neg-6 tablet:margin-top-neg-4', + ) %> +<% end %> + +<%= render PageHeadingComponent.new do %> + <%= t('doc_auth.headings.choose_id_type') %> +<% end %> + +

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

+ +<%= new_tab_link_to( + t('doc_auth.info.id_types_learn_more'), + help_center_redirect_url( + category: 'verify-your-identity', + article: 'accepted-identification-documents', + ) + ) +%> + +<%= simple_form_for( + :doc_auth, + url: idv_choose_id_type_path, + method: :put, + ) do |f| %> +
+ <%= f.radio_button( + :choose_id_type_preference, + :drivers_license, + class: 'usa-radio__input usa-radio__input--bordered', + ) %> + <%= f.label :choose_id_type_preference_drivers_license, t('doc_auth.forms.id_type_preference.drivers_license'), class: 'usa-radio__label text-bold width-full' %> +
+
+ <%= f.radio_button( + :choose_id_type_preference, + :passport, + class: 'usa-radio__input usa-radio__input--bordered', + ) %> + <%= f.label :choose_id_type_preference_passport, t('doc_auth.forms.id_type_preference.passport'), class: 'usa-radio__label text-bold width-full' %> +
+ <%= f.submit t('forms.buttons.continue'), class: 'margin-top-5' %> +<% end %> + +<%= render 'idv/doc_auth/cancel', step: 'choose_id_type' %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 1bfcbb18e25..b70aa57d1ec 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -581,6 +581,8 @@ doc_auth.errors.upload_error: Sorry, something went wrong on our end. doc_auth.forms.change_file: Change file doc_auth.forms.choose_file_html: Drag file here or choose from folder doc_auth.forms.doc_success: We verified your information +doc_auth.forms.id_type_preference.drivers_license: U.S. driver’s license or state ID +doc_auth.forms.id_type_preference.passport: U.S. passport book doc_auth.forms.selected_file: Selected file doc_auth.headers.expired_id: Your ID may have expired doc_auth.headers.general.network_error: We are having technical difficulties @@ -594,6 +596,7 @@ doc_auth.headings.back: Back of your driver’s license or state ID doc_auth.headings.capture_complete: We verified your identity document doc_auth.headings.capture_scan_warning_html: We couldn’t read the barcode on your ID. If the information below is incorrect, please %{link_html} of your state‑issued ID. doc_auth.headings.capture_scan_warning_link: upload new photos +doc_auth.headings.choose_id_type: Choose your ID type doc_auth.headings.document_capture: Add photos of your driver’s license or state ID card doc_auth.headings.document_capture_back: Back of your ID doc_auth.headings.document_capture_front: Front of your ID @@ -635,6 +638,7 @@ doc_auth.info.capture_status_capturing: Capturing doc_auth.info.capture_status_none: Align doc_auth.info.capture_status_small_document: Move Closer doc_auth.info.capture_status_tap_to_capture: Tap to Capture +doc_auth.info.choose_id_type: Select the type of document that you have. You’ll need to take photos of your ID to verify your identity. doc_auth.info.exit.with_sp: Exit %{app_name} and return to %{sp_name} doc_auth.info.exit.without_sp: Exit identity verification and go to your account page doc_auth.info.getting_started_html: '%{sp_name} needs to make sure you are you — not someone pretending to be you. %{link_html}' @@ -644,6 +648,7 @@ doc_auth.info.how_to_verify_mobile: You have the option to verify your identity doc_auth.info.how_to_verify_troubleshooting_options_header: Want to learn more about how to verify your identity? doc_auth.info.hybrid_handoff: We’ll collect information about you by reading your state‑issued ID. doc_auth.info.hybrid_handoff_ipp_html: 'Don’t have a mobile phone? You can verify your identity at a United States Post Office instead.' +doc_auth.info.id_types_learn_more: Learn more about which ID types you can use doc_auth.info.image_loaded: Image loaded doc_auth.info.image_loading: Image loading doc_auth.info.image_updated: Image updated diff --git a/config/locales/es.yml b/config/locales/es.yml index 8ad0dddbe84..ee09de906fa 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -592,6 +592,8 @@ doc_auth.errors.upload_error: Lo sentimos, algo no funcionó bien. doc_auth.forms.change_file: Cambiar archivo doc_auth.forms.choose_file_html: Arrastrar el archivo aquí o seleccionarlo de la carpeta doc_auth.forms.doc_success: Verificamos su información +doc_auth.forms.id_type_preference.drivers_license: Licencia de conducir de los EE. UU. o identificación estatal +doc_auth.forms.id_type_preference.passport: Pasaporte estadounidense doc_auth.forms.selected_file: Archivo seleccionado doc_auth.headers.expired_id: Su identificación puede estar vencida doc_auth.headers.general.network_error: Estamos teniendo problemas técnicos @@ -605,6 +607,7 @@ doc_auth.headings.back: Reverso de su licencia de conducir o identificación est doc_auth.headings.capture_complete: Verificamos su documento de identidad doc_auth.headings.capture_scan_warning_html: No pudimos leer el código de barras en su identificación. Si la información que aparece a continuación es incorrecta, %{link_html} de su identificación emitida por el estado. doc_auth.headings.capture_scan_warning_link: cargue nuevas fotos +doc_auth.headings.choose_id_type: Elija el tipo de su identificación doc_auth.headings.document_capture: Añade fotos de tu licencia de conducir o credencial de identificación oficial doc_auth.headings.document_capture_back: Reverso de su identificación doc_auth.headings.document_capture_front: Frente de su identificación @@ -646,6 +649,7 @@ doc_auth.info.capture_status_capturing: Capturando doc_auth.info.capture_status_none: Alinear doc_auth.info.capture_status_small_document: Acercar doc_auth.info.capture_status_tap_to_capture: Tocar para capturar +doc_auth.info.choose_id_type: Seleccione el tipo de documento que tenga. Tendrá que tomar fotografías de su identificación para verificar su identidad. doc_auth.info.exit.with_sp: Salir de %{app_name} y volver a %{sp_name} doc_auth.info.exit.without_sp: Salga de la verificación de identidad y vaya a la página de su cuenta doc_auth.info.getting_started_html: '%{sp_name} necesita asegurarse de que se trata de usted y no de alguien que se hace pasar por usted. %{link_html}' @@ -655,6 +659,7 @@ doc_auth.info.how_to_verify_mobile: Tiene la opción de verificar su identidad e doc_auth.info.how_to_verify_troubleshooting_options_header: ¿Desea obtener más información sobre cómo verificar su identidad? doc_auth.info.hybrid_handoff: Recopilaremos información sobre usted leyendo su identificación emitida por el estado. doc_auth.info.hybrid_handoff_ipp_html: '¿No tiene un teléfono móvil? Puede verificar su identidad en una oficina de correos de los Estados Unidos.' +doc_auth.info.id_types_learn_more: Obtenga más información acerca de los tipos de identificación que puede usar doc_auth.info.image_loaded: Imagen cargada doc_auth.info.image_loading: Cargando la imagen doc_auth.info.image_updated: Imagen actualizada diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 7c63337f736..d01f2e1049b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -581,6 +581,8 @@ doc_auth.errors.upload_error: Désolé, il y a eu un problème de notre côté. doc_auth.forms.change_file: Changer de fichier doc_auth.forms.choose_file_html: Faites glisser le fichier ici ou choisissez dans un dossier doc_auth.forms.doc_success: Nous avons vérifié vos informations +doc_auth.forms.id_type_preference.drivers_license: Permis de conduire ou carte d’identité d’un État +doc_auth.forms.id_type_preference.passport: Passeport américain doc_auth.forms.selected_file: Fichier sélectionné doc_auth.headers.expired_id: Votre pièce d’identité est peut-être périmée doc_auth.headers.general.network_error: Nous rencontrons des difficultés techniques @@ -594,6 +596,7 @@ doc_auth.headings.back: Verso de votre permis de conduire ou de votre carte d’ doc_auth.headings.capture_complete: Nous avons vérifié votre pièce d’identité doc_auth.headings.capture_scan_warning_html: Nous n’avons pas pu lire le code-barres de votre pièce d’identité. Si les informations ci-dessous ne sont pas correctes, veuillez %{link_html} de votre carte d’identité délivrée par l’État. doc_auth.headings.capture_scan_warning_link: télécharger de nouvelles photos +doc_auth.headings.choose_id_type: Choisir le type de votre pièce d’identité doc_auth.headings.document_capture: Ajoutez des photos de votre permis de conduire ou de votre carte d’identité nationale doc_auth.headings.document_capture_back: Verso de votre pièce d’identité doc_auth.headings.document_capture_front: Recto de votre carte d’identité @@ -635,6 +638,7 @@ doc_auth.info.capture_status_capturing: Prise de la photo doc_auth.info.capture_status_none: Alignez doc_auth.info.capture_status_small_document: Approchez-vous doc_auth.info.capture_status_tap_to_capture: Appuyez pour prendre la photo +doc_auth.info.choose_id_type: Sélectionnez le type de document dont vous disposez. Vous devrez prendre des photos de votre pièce d’identité pour confirmer votre identité. doc_auth.info.exit.with_sp: Quitter %{app_name} et revenir à %{sp_name} doc_auth.info.exit.without_sp: Quitter la vérification d’identité et accéder à la page de votre compte doc_auth.info.getting_started_html: '%{sp_name} doit s’assurer qu’il s’agit bien de vous et non de quelqu’un qui se fait passer pour vous. %{link_html}' @@ -644,6 +648,7 @@ doc_auth.info.how_to_verify_mobile: Vous avez la possibilité de confirmer votre doc_auth.info.how_to_verify_troubleshooting_options_header: Vous voulez en savoir plus sur la façon de confirmer votre identité? doc_auth.info.hybrid_handoff: Nous recueillerons des informations vous concernant en lisant votre pièce d’identité délivrée par un État. doc_auth.info.hybrid_handoff_ipp_html: 'Vous n’avez pas de téléphone portable? Vous pouvez confirmer votre identité dans un bureau de poste américain participant.' +doc_auth.info.id_types_learn_more: En savoir plus sur les types de pièces d’identité que vous pouvez utiliser doc_auth.info.image_loaded: Image chargée doc_auth.info.image_loading: Image en cours de chargement doc_auth.info.image_updated: Image mise à jour diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 997492b7744..0dad9afd9b9 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -592,6 +592,8 @@ doc_auth.errors.upload_error: 抱歉,我们这边出错了。 doc_auth.forms.change_file: 更改文件 doc_auth.forms.choose_file_html: 将文件拖到此处或者从文件夹中选择。 doc_auth.forms.doc_success: 我们验证了你的信息 +doc_auth.forms.id_type_preference.drivers_license: 美国驾照或州身份证件 +doc_auth.forms.id_type_preference.passport: 美国护照本 doc_auth.forms.selected_file: 被选文件 doc_auth.headers.expired_id: 你的身份证件可能已过期 doc_auth.headers.general.network_error: 我们目前遇到技术困难 @@ -605,6 +607,7 @@ doc_auth.headings.back: 驾照或州政府颁发身份证件的背面。 doc_auth.headings.capture_complete: 我们验证了你的身份文件 doc_auth.headings.capture_scan_warning_html: 我们读取不到你身份证件上的条形码。如果以下信息不正确,请将州政府颁发的身份证件%{link_html}。 doc_auth.headings.capture_scan_warning_link: 上传新照片 +doc_auth.headings.choose_id_type: 选择你的身份证件类型 doc_auth.headings.document_capture: 添加你身份证件的照片 doc_auth.headings.document_capture_back: 你身份证件的背面 doc_auth.headings.document_capture_front: 你身份证件的正面 @@ -646,6 +649,7 @@ doc_auth.info.capture_status_capturing: 扫描中 doc_auth.info.capture_status_none: 对齐 doc_auth.info.capture_status_small_document: 靠近一些 doc_auth.info.capture_status_tap_to_capture: 点击来扫描 +doc_auth.info.choose_id_type: 选择你具备的身份证件类型你将需要拍你身份证件的照片来验证身份。 doc_auth.info.exit.with_sp: 退出 %{app_name} 并返回 %{sp_name} doc_auth.info.exit.without_sp: 退出身份验证并到你的账户页面 doc_auth.info.getting_started_html: '%{sp_name} 需要确保你是你,而不是别人冒充你。 了解更多有关验证你身份的信息 %{link_html}' @@ -655,6 +659,7 @@ doc_auth.info.how_to_verify_mobile: 你可以选择用你的手机在网上验 doc_auth.info.how_to_verify_troubleshooting_options_header: 想对验证身份获得更多了解吗? doc_auth.info.hybrid_handoff: 我们将通过读取州政府颁发给你的身份证件来收集你的信息。 doc_auth.info.hybrid_handoff_ipp_html: '没有手机?你可以去一个美国邮局验证身份。' +doc_auth.info.id_types_learn_more: 了解有关你能使用的身份证件类型的更多信息 doc_auth.info.image_loaded: 图像已加载 doc_auth.info.image_loading: 图像加载中 doc_auth.info.image_updated: 图像已上传 From 3e4da070043b71a915dea991f626fbb401932a7a Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Tue, 25 Feb 2025 17:18:09 -0500 Subject: [PATCH 03/22] add flow policy for choose_id_type and allow redirects to id page --- .../idv/choose_id_type_controller.rb | 42 +++++++++++++++++++ .../idv/hybrid_handoff_controller.rb | 16 ++++++- app/forms/idv/choose_id_type_form.rb | 21 ++++++++++ app/policies/idv/flow_policy.rb | 1 + .../idv/choose_id_type_controller_spec.rb | 25 +++++++++++ 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 app/forms/idv/choose_id_type_form.rb create mode 100644 spec/controllers/idv/choose_id_type_controller_spec.rb diff --git a/app/controllers/idv/choose_id_type_controller.rb b/app/controllers/idv/choose_id_type_controller.rb index 993fb5d876a..2cdc4355c05 100644 --- a/app/controllers/idv/choose_id_type_controller.rb +++ b/app/controllers/idv/choose_id_type_controller.rb @@ -11,6 +11,48 @@ def show def update clear_future_steps! + + @choose_id_type_form = Idv::ChooseIdTypeForm.new + + result = @choose_id_type_form.submit(choose_id_type_form_params) + + if result.success? + redirect_to next_step + else + render :show + end + end + + def self.step_info + Idv::StepInfo.new( + key: :choose_id_type, + controller: self, + next_steps: [:document_capture], + preconditions: ->(idv_session:, user:) { + idv_session.flow_path == 'standard' + }, + undo_step: ->(idv_session:, user:) do + end, + ) + end + + private + + def chosen_id_type + @choose_id_type_form.chosen_id_type.to_sym + end + + def next_step + if chosen_id_type == :drivers_license + idv_document_capture_url + elsif chosen_id_type == :passport + # page is not created yet redirect to in person for now + idv_in_person_url + end + end + + def choose_id_type_form_params + params.require(:doc_auth).permit(:choose_id_type_preference) end end end diff --git a/app/controllers/idv/hybrid_handoff_controller.rb b/app/controllers/idv/hybrid_handoff_controller.rb index d78224d68ea..98c6f6469d3 100644 --- a/app/controllers/idv/hybrid_handoff_controller.rb +++ b/app/controllers/idv/hybrid_handoff_controller.rb @@ -58,7 +58,7 @@ def self.step_info Idv::StepInfo.new( key: :hybrid_handoff, controller: self, - next_steps: [:link_sent, :document_capture, :socure_document_capture], + next_steps: [:choose_id_type, :link_sent, :document_capture, :socure_document_capture], preconditions: ->(idv_session:, user:) { idv_session.idv_consent_given? && (self.selected_remote(idv_session: idv_session) || # from opt-in screen @@ -149,7 +149,7 @@ def update_document_capture_session_requested_at(session_uuid) def bypass_send_link_steps idv_session.flow_path = 'standard' - redirect_to vendor_document_capture_url + redirect_to next_step analytics.idv_doc_auth_hybrid_handoff_submitted( **analytics_arguments.merge( @@ -158,6 +158,18 @@ def bypass_send_link_steps ) end + def passport_verification_enabled? + IdentityConfig.store.doc_auth_passports_enabled + end + + def next_step + if passport_verification_enabled? + idv_choose_id_type_url + else + idv_document_capture_url + end + end + def extra_view_variables { idv_phone_form: build_form } end diff --git a/app/forms/idv/choose_id_type_form.rb b/app/forms/idv/choose_id_type_form.rb new file mode 100644 index 00000000000..aed28fd8a1a --- /dev/null +++ b/app/forms/idv/choose_id_type_form.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Idv + class ChooseIdTypeForm + include ActiveModel::Model + + def initialize(chosen_id_type = :drivers_license) + @chosen_id_type = chosen_id_type + end + + def submit(params) + @chosen_id_type = params[:choose_id_type_preference] + + FormResponse.new(success: valid?, errors: errors) + end + + def chosen_id_type + @chosen_id_type + end + end +end diff --git a/app/policies/idv/flow_policy.rb b/app/policies/idv/flow_policy.rb index a8510c31f09..8385438f1e5 100644 --- a/app/policies/idv/flow_policy.rb +++ b/app/policies/idv/flow_policy.rb @@ -18,6 +18,7 @@ class FlowPolicy agreement: Idv::AgreementController.step_info, how_to_verify: Idv::HowToVerifyController.step_info, hybrid_handoff: Idv::HybridHandoffController.step_info, + choose_id_type: Idv::ChooseIdTypeController.step_info, link_sent: Idv::LinkSentController.step_info, document_capture: Idv::DocumentCaptureController.step_info, socure_document_capture: Idv::Socure::DocumentCaptureController.step_info, diff --git a/spec/controllers/idv/choose_id_type_controller_spec.rb b/spec/controllers/idv/choose_id_type_controller_spec.rb new file mode 100644 index 00000000000..fb91ca2139e --- /dev/null +++ b/spec/controllers/idv/choose_id_type_controller_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +RSpec.describe Idv::ChooseIdTypeController do + let(:user) { create(:user) } + + before do + stub_sign_in(user) + end + + describe '#show' do + it 'renders the show template' do + get :show + + expect(response).to render_template :show + end + end + + describe '#update' do + it 'invalidates future steps' do + expect(subject).to receive(:clear_future_steps!) + + put :update + end + end +end From 0ea95dec4a48978a7dd67223917677ad782818f4 Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Wed, 26 Feb 2025 13:42:27 -0500 Subject: [PATCH 04/22] use idv_session variables for passports --- .../idv/choose_id_type_controller.rb | 26 ++++++++++++++----- app/controllers/idv/welcome_controller.rb | 1 + app/forms/idv/choose_id_type_form.rb | 8 +++--- app/services/idv/session.rb | 4 +++ 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/app/controllers/idv/choose_id_type_controller.rb b/app/controllers/idv/choose_id_type_controller.rb index 2cdc4355c05..ddaab670c01 100644 --- a/app/controllers/idv/choose_id_type_controller.rb +++ b/app/controllers/idv/choose_id_type_controller.rb @@ -6,6 +6,8 @@ class ChooseIdTypeController < ApplicationController include IdvStepConcern include StepIndicatorConcern + before_action :redirect_if_passport_not_available + def show end @@ -17,6 +19,7 @@ def update result = @choose_id_type_form.submit(choose_id_type_form_params) if result.success? + set_passport_requested redirect_to next_step else render :show @@ -29,7 +32,8 @@ def self.step_info controller: self, next_steps: [:document_capture], preconditions: ->(idv_session:, user:) { - idv_session.flow_path == 'standard' + idv_session.flow_path == 'standard' && + idv_session.passport_allowed == true }, undo_step: ->(idv_session:, user:) do end, @@ -38,21 +42,29 @@ def self.step_info private - def chosen_id_type - @choose_id_type_form.chosen_id_type.to_sym + def redirect_if_passport_not_available + redirect_to idv_hybrid_handoff_url if !idv_session.passport_allowed + end + + def set_passport_requested + if choose_id_type_form_params[:choose_id_type_preference] == 'passport' + idv_session.passport_requested = true + else + idv_session.passport_requested = false + end end def next_step - if chosen_id_type == :drivers_license - idv_document_capture_url - elsif chosen_id_type == :passport + if idv_session.passport_requested # page is not created yet redirect to in person for now idv_in_person_url + else + idv_document_capture_url end end def choose_id_type_form_params - params.require(:doc_auth).permit(:choose_id_type_preference) + params.require(:doc_auth).permit(:choose_id_type_preference) end end end diff --git a/app/controllers/idv/welcome_controller.rb b/app/controllers/idv/welcome_controller.rb index d25415fbca5..b9b5badc77d 100644 --- a/app/controllers/idv/welcome_controller.rb +++ b/app/controllers/idv/welcome_controller.rb @@ -11,6 +11,7 @@ class WelcomeController < ApplicationController def show idv_session.proofing_started_at ||= Time.zone.now.iso8601 + idv_session.passport_allowed = IdentityConfig.store.doc_auth_passports_enabled analytics.idv_doc_auth_welcome_visited(**analytics_arguments) Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]) diff --git a/app/forms/idv/choose_id_type_form.rb b/app/forms/idv/choose_id_type_form.rb index aed28fd8a1a..874283e5fab 100644 --- a/app/forms/idv/choose_id_type_form.rb +++ b/app/forms/idv/choose_id_type_form.rb @@ -4,6 +4,10 @@ module Idv class ChooseIdTypeForm include ActiveModel::Model + attr_reader :chosen_id_type + + validates :chosen_id_type, inclusion: { in: %w[drivers_license passport]} + def initialize(chosen_id_type = :drivers_license) @chosen_id_type = chosen_id_type end @@ -13,9 +17,5 @@ def submit(params) FormResponse.new(success: valid?, errors: errors) end - - def chosen_id_type - @chosen_id_type - end end end diff --git a/app/services/idv/session.rb b/app/services/idv/session.rb index 70435fb86c8..f0707baf90a 100644 --- a/app/services/idv/session.rb +++ b/app/services/idv/session.rb @@ -16,6 +16,8 @@ module Idv # @attr idv_phone_step_document_capture_session_uuid [String, nil] # @attr mail_only_warning_shown [Boolean, nil] # @attr opted_in_to_in_person_proofing [Boolean, nil] + # @attr passport_allowed [Boolean, nil] + # @attr passport_requested [Boolean, nil] # @attr personal_key [String, nil] # @attr personal_key_acknowledged [Boolean, nil] # @attr phone_for_mobile_flow [String, nil] @@ -60,6 +62,8 @@ class Session idv_phone_step_document_capture_session_uuid mail_only_warning_shown opted_in_to_in_person_proofing + passport_allowed + passport_requested personal_key personal_key_acknowledged phone_for_mobile_flow From 3f20773d51ef2858bfe9892a312c434d73f4da4a Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Wed, 26 Feb 2025 16:38:13 -0500 Subject: [PATCH 05/22] add analytics events and form error messages --- .../idv/choose_id_type_controller.rb | 21 ++++++++- app/forms/idv/choose_id_type_form.rb | 4 +- app/services/analytics_events.rb | 45 +++++++++++++++++++ app/views/idv/choose_id_type/show.html.erb | 30 ++++++------- config/locales/en.yml | 1 + config/locales/es.yml | 1 + config/locales/fr.yml | 1 + config/locales/zh.yml | 1 + 8 files changed, 84 insertions(+), 20 deletions(-) diff --git a/app/controllers/idv/choose_id_type_controller.rb b/app/controllers/idv/choose_id_type_controller.rb index ddaab670c01..26cf01fc10f 100644 --- a/app/controllers/idv/choose_id_type_controller.rb +++ b/app/controllers/idv/choose_id_type_controller.rb @@ -9,6 +9,7 @@ class ChooseIdTypeController < ApplicationController before_action :redirect_if_passport_not_available def show + analytics.idv_doc_auth_choose_id_type_visited(**analytics_arguments) end def update @@ -18,6 +19,11 @@ def update result = @choose_id_type_form.submit(choose_id_type_form_params) + analytics.idv_doc_auth_choose_id_type_submitted( + **analytics_arguments.merge(result.to_h) + .merge({ chosen_id_type: chosen_id_type }), + ) + if result.success? set_passport_requested redirect_to next_step @@ -36,6 +42,7 @@ def self.step_info idv_session.passport_allowed == true }, undo_step: ->(idv_session:, user:) do + idv_session.passport_requested = nil end, ) end @@ -46,8 +53,12 @@ def redirect_if_passport_not_available redirect_to idv_hybrid_handoff_url if !idv_session.passport_allowed end + def chosen_id_type + choose_id_type_form_params[:choose_id_type_preference] + end + def set_passport_requested - if choose_id_type_form_params[:choose_id_type_preference] == 'passport' + if chosen_id_type == 'passport' idv_session.passport_requested = true else idv_session.passport_requested = false @@ -66,5 +77,13 @@ def next_step def choose_id_type_form_params params.require(:doc_auth).permit(:choose_id_type_preference) end + + def analytics_arguments + { + step: 'choose_id_type', + analytics_id: 'Doc Auth', + flow_path: idv_session.flow_path, + } + end end end diff --git a/app/forms/idv/choose_id_type_form.rb b/app/forms/idv/choose_id_type_form.rb index 874283e5fab..8e9907084b5 100644 --- a/app/forms/idv/choose_id_type_form.rb +++ b/app/forms/idv/choose_id_type_form.rb @@ -6,9 +6,7 @@ class ChooseIdTypeForm attr_reader :chosen_id_type - validates :chosen_id_type, inclusion: { in: %w[drivers_license passport]} - - def initialize(chosen_id_type = :drivers_license) + def initialize(chosen_id_type = nil) @chosen_id_type = chosen_id_type end diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 22c963a4e3f..f54af80bbad 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -1306,6 +1306,51 @@ def idv_doc_auth_capture_complete_visited( ) end + # @param [String] step Current IdV step + # @param [String] analytics_id Current IdV flow identifier + # @param ["hybrid","standard"] flow_path Document capture user flow + def idv_doc_auth_choose_id_type_visited( + step:, + analytics_id:, + flow_path:, + **extra + ) + track_event( + :idv_doc_auth_choose_id_type_visited, + step:, + analytics_id:, + flow_path:, + **extra, + ) + end + + # @param [Boolean] success + # @param [String] step Current IdV step + # @param [String] analytics_id Current IdV flow identifier + # @param ["hybrid","standard"] flow_path Document capture user flow + # @param ['drivers_license', 'passport'] chosen_id_type Chosen id type of the user + # @param [Hash] errors + def idv_doc_auth_choose_id_type_submitted( + success:, + step:, + analytics_id:, + flow_path:, + chosen_id_type:, + errors: nil, + **extra + ) + track_event( + :idv_doc_auth_choose_id_type_submitted, + success:, + step:, + analytics_id:, + flow_path:, + chosen_id_type:, + errors:, + **extra, + ) + end + # User returns from Socure document capture, but is waiting on a result to be fetched # @param ["hybrid","standard"] flow_path Document capture user flow # @param [String] step Current IdV step diff --git a/app/views/idv/choose_id_type/show.html.erb b/app/views/idv/choose_id_type/show.html.erb index 1a7f23c07b9..3f8658c89aa 100644 --- a/app/views/idv/choose_id_type/show.html.erb +++ b/app/views/idv/choose_id_type/show.html.erb @@ -31,22 +31,20 @@ url: idv_choose_id_type_path, method: :put, ) do |f| %> -
- <%= f.radio_button( - :choose_id_type_preference, - :drivers_license, - class: 'usa-radio__input usa-radio__input--bordered', - ) %> - <%= f.label :choose_id_type_preference_drivers_license, t('doc_auth.forms.id_type_preference.drivers_license'), class: 'usa-radio__label text-bold width-full' %> -
-
- <%= f.radio_button( - :choose_id_type_preference, - :passport, - class: 'usa-radio__input usa-radio__input--bordered', - ) %> - <%= f.label :choose_id_type_preference_passport, t('doc_auth.forms.id_type_preference.passport'), class: 'usa-radio__label text-bold width-full' %> -
+ <%= render ValidatedFieldComponent.new( + as: :radio_buttons, + collection: [ + [t('doc_auth.forms.id_type_preference.drivers_license'), :drivers_license], + [t('doc_auth.forms.id_type_preference.passport'), :passport], + ], + form: f, + input_html: { class: 'usa-radio__input--bordered' }, + name: :choose_id_type_preference, + required: true, + wrapper: :uswds_radio_buttons, + wrapper_html: { class: 'text-bold' }, + error_messages: { valueMissing: t('doc_auth.errors.choose_id_type_check')} + ) %> <%= f.submit t('forms.buttons.continue'), class: 'margin-top-5' %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index b70aa57d1ec..3bef6fc2858 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -531,6 +531,7 @@ doc_auth.errors.camera.blocked: Your camera is blocked doc_auth.errors.camera.blocked_detail_html: 'Allow access to your camera to take photos for %{app_name}.Try taking photos again and allowing permission. If that doesn’t work, you may need to check your device settings to allow access.' doc_auth.errors.camera.failed: Camera failed to start, please try again. doc_auth.errors.card_type: Try again with your driver’s license or state ID card. +doc_auth.errors.choose_id_type_check: Select the type of document that you have doc_auth.errors.consent_form: Before you can continue, you must give us permission. Please check the box below and then click continue. doc_auth.errors.doc_type_not_supported_heading: We only accept a driver’s license or a state ID doc_auth.errors.doc.doc_type_check: Your driver’s license or state ID must be issued by a U.S. state or territory. We do not accept other forms of ID, like passports or military IDs. diff --git a/config/locales/es.yml b/config/locales/es.yml index ee09de906fa..a470950d733 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -542,6 +542,7 @@ doc_auth.errors.camera.blocked: Su cámara está bloqueada doc_auth.errors.camera.blocked_detail_html: 'Permita el acceso a su cámara para tomar las fotografías de %{app_name}.Intente tomar las fotografías de nuevo permitiendo el acceso. Si eso no funciona, tal vez necesite revisar la configuración de su dispositivo para permitir el acceso.' doc_auth.errors.camera.failed: No se pudo activar la cámara; inténtelo de nuevo. doc_auth.errors.card_type: Inténtelo de nuevo con su licencia de conducir o tarjeta de identificación estatal. +doc_auth.errors.choose_id_type_check: Seleccione el tipo de documento que tenga doc_auth.errors.consent_form: Antes de continuar, debe darnos permiso. Marque la casilla a continuación y luego haga clic en continuar. doc_auth.errors.doc_type_not_supported_heading: Solo aceptamos una licencia de conducir o una identificación estatal. doc_auth.errors.doc.doc_type_check: Su licencia de conducir o identificación estatal debe ser emitida por un estado o territorio de los EE. UU. No aceptamos otras formas de identificación, como pasaportes o identificaciones militares. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index d01f2e1049b..b4a43c9e67e 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -531,6 +531,7 @@ doc_auth.errors.camera.blocked: Votre appareil photo est bloqué doc_auth.errors.camera.blocked_detail_html: 'Autorisez l’accès à votre caméra pour prendre des photos pour %{app_name}.Essayez à nouveau de prendre des photos en autorisant %{app_name} à accéder à votre appareil. Si cela ne marche pas, pensez à vérifier les paramètres de votre appareil en matière d’autorisations d’accès.' doc_auth.errors.camera.failed: L’appareil photo n’a pas réussi à démarrer, veuillez réessayer. doc_auth.errors.card_type: Réessayez avec votre permis de conduire ou carte d’identité d’un État. +doc_auth.errors.choose_id_type_check: Sélectionnez le type de document dont vous disposez doc_auth.errors.consent_form: Avant de pouvoir continuer, vous devez nous donner la permission. Veuillez cocher la case ci-dessous, puis cliquez sur Suite. doc_auth.errors.doc_type_not_supported_heading: Nous n’acceptons que les permis de conduire ou les cartes d’identité délivrées par un État doc_auth.errors.doc.doc_type_check: Votre permis de conduire ou votre carte d’identité doit être délivré par un État ou un territoire des États-Unis. Nous n’acceptons pas d’autres pièces d’identité, comme les passeports ou les cartes d’identité militaires. diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 0dad9afd9b9..6f84c42c6fa 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -542,6 +542,7 @@ doc_auth.errors.camera.blocked: 你的镜头被遮住了。 doc_auth.errors.camera.blocked_detail_html: '允许 %{app_name} 进入你的相机来拍照。尝试再次拍照并给予许可。如果还不行,你可能需要检查自己设备的设置来给予许可。' doc_auth.errors.camera.failed: 相机未开启,请再试一次。 doc_auth.errors.card_type: 再用你的驾照或州政府颁发的身份证件试一次。 +doc_auth.errors.choose_id_type_check: 选择你具备的身份证件类型 doc_auth.errors.consent_form: 在你能继续之前,你必须授予我们你的同意。请在下面的框打勾然后点击继续。 doc_auth.errors.doc_type_not_supported_heading: 我们只接受驾照或州政府颁发的 ID。 doc_auth.errors.doc.doc_type_check: 你的驾照或身份证件必须是美国一个州或属地颁发的。我们不接受任何其他形式的身份证件,比如护照和军队身份证件。 From c84fb2735cd24c36d7c12ae4fb9e39dcef1f824a Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Fri, 28 Feb 2025 12:00:41 -0500 Subject: [PATCH 06/22] create specs --- .../idv/hybrid_handoff_controller.rb | 6 +- .../idv/choose_id_type_controller_spec.rb | 116 +++++++++++++++++- .../idv/hybrid_handoff_controller_spec.rb | 22 ++++ .../idv/welcome_controller_spec.rb | 12 ++ spec/forms/idv/choose_id_type_form_spec.rb | 19 +++ spec/support/flow_policy_helper.rb | 5 + 6 files changed, 171 insertions(+), 9 deletions(-) create mode 100644 spec/forms/idv/choose_id_type_form_spec.rb diff --git a/app/controllers/idv/hybrid_handoff_controller.rb b/app/controllers/idv/hybrid_handoff_controller.rb index 98c6f6469d3..37a199b744f 100644 --- a/app/controllers/idv/hybrid_handoff_controller.rb +++ b/app/controllers/idv/hybrid_handoff_controller.rb @@ -158,12 +158,8 @@ def bypass_send_link_steps ) end - def passport_verification_enabled? - IdentityConfig.store.doc_auth_passports_enabled - end - def next_step - if passport_verification_enabled? + if idv_session.passport_allowed idv_choose_id_type_url else idv_document_capture_url diff --git a/spec/controllers/idv/choose_id_type_controller_spec.rb b/spec/controllers/idv/choose_id_type_controller_spec.rb index fb91ca2139e..4d3b891978f 100644 --- a/spec/controllers/idv/choose_id_type_controller_spec.rb +++ b/spec/controllers/idv/choose_id_type_controller_spec.rb @@ -1,25 +1,133 @@ require 'rails_helper' RSpec.describe Idv::ChooseIdTypeController do + include FlowPolicyHelper + let(:user) { create(:user) } before do stub_sign_in(user) + stub_up_to(:hybrid_handoff, idv_session: subject.idv_session) + stub_analytics + end + + describe '#step info' do + it 'returns a valid StepInfo object' do + expect(Idv::ChooseIdTypeController.step_info).to be_valid + end + end + + describe 'before actions' do + it 'includes redirect_if_passport_not_available before_action' do + expect(subject).to have_actions( + :before, + :redirect_if_passport_not_available, + ) + end end describe '#show' do - it 'renders the show template' do - get :show + context 'passport is not available' do + it 'redirects to hybrid hybrid handoff' do + subject.idv_session.passport_allowed = false + + get :show + + expect(response).to redirect_to(idv_hybrid_handoff_url) + end + end + + context 'passport is available' do + let(:analytics_name) { :idv_doc_auth_choose_id_type_visited } + let(:analytics_args) do + { + step: 'choose_id_type', + analytics_id: 'Doc Auth', + flow_path: 'standard', + } + end + + it 'renders the show template' do + subject.idv_session.passport_allowed = true + + get :show + + expect(response).to render_template :show + end - expect(response).to render_template :show + it 'sends analytics_visited event' do + subject.idv_session.passport_allowed = true + + get :show + + expect(@analytics).to have_logged_event(analytics_name, analytics_args) + end end end describe '#update' do + let(:chosen_id_type) { 'drivers_license' } + let(:analytics_name) { :idv_doc_auth_choose_id_type_submitted } + let (:analytics_args) do + { + success: true, + step: 'choose_id_type', + analytics_id: 'Doc Auth', + flow_path: 'standard', + chosen_id_type: chosen_id_type, + } + end + + let(:params) do + { doc_auth: { choose_id_type_preference: chosen_id_type } } + end + + before do + allow(subject.idv_session).to receive(:passport_allowed).and_return(true) + end + it 'invalidates future steps' do expect(subject).to receive(:clear_future_steps!) - put :update + put :update, params: params + end + + it 'sends analytics submitted event for id choice' do + put :update, params: params + + expect(@analytics).to have_logged_event(analytics_name, analytics_args) + end + + context 'user selects drivers license' do + it 'sets idv_session.passport_requested to false' do + put :update, params: params + + expect(subject.idv_session.passport_requested).to eq(false) + end + + it 'redirects to document capture session' do + put :update, params: params + + expect(response).to redirect_to(idv_document_capture_url) + end + end + + context 'user selects passport' do + let(:chosen_id_type) { 'passport' } + + it 'sets idv_session.passport_requested to true' do + put :update, params: params + + expect(subject.idv_session.passport_requested).to eq(true) + end + + # currently we do not have a passport route so it redirects to ipp route + # change when the new passport is added + it 'redirects to passport document capture' do + put :update, params: params + + expect(response).to redirect_to(idv_in_person_url) + end end end end diff --git a/spec/controllers/idv/hybrid_handoff_controller_spec.rb b/spec/controllers/idv/hybrid_handoff_controller_spec.rb index 00a45e6f853..3315e00fd6d 100644 --- a/spec/controllers/idv/hybrid_handoff_controller_spec.rb +++ b/spec/controllers/idv/hybrid_handoff_controller_spec.rb @@ -359,6 +359,28 @@ expect(@analytics).to have_logged_event(analytics_name, analytics_args) end + + context 'passports are not enabled' do + before do + allow(subject.idv_session).to receive(:passport_allowed).and_return(false) + end + it 'redirects to choose id type url' do + put :update, params: params + + expect(response).to redirect_to(idv_document_capture_url) + end + end + + context 'passports are enabled' do + before do + allow(subject.idv_session).to receive(:passport_allowed).and_return(true) + end + it 'redirects to choose id type url' do + put :update, params: params + + expect(response).to redirect_to(idv_choose_id_type_url) + end + end end end end diff --git a/spec/controllers/idv/welcome_controller_spec.rb b/spec/controllers/idv/welcome_controller_spec.rb index 793e1f6092a..26a66b36c83 100644 --- a/spec/controllers/idv/welcome_controller_spec.rb +++ b/spec/controllers/idv/welcome_controller_spec.rb @@ -100,6 +100,18 @@ expect(subject.idv_session.proofing_started_at).to eq(Time.zone.now.iso8601) end + context 'passports are enabled' do + before do + allow(IdentityConfig.store).to receive(:doc_auth_passports_enabled).and_return(true) + end + + it 'sets passport_allowed in idv session' do + get :show + + expect(subject.idv_session.passport_allowed).to eq(true) + end + end + context 'welcome already visited' do before do subject.idv_session.welcome_visited = true diff --git a/spec/forms/idv/choose_id_type_form_spec.rb b/spec/forms/idv/choose_id_type_form_spec.rb new file mode 100644 index 00000000000..c6c2f3b416e --- /dev/null +++ b/spec/forms/idv/choose_id_type_form_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +RSpec.describe Idv::ChooseIdTypeForm do + let(:subject) { Idv::ChooseIdTypeForm.new } + + describe '#submit' do + context 'when the form is valid' do + let(:params) { { choose_id_type_preference: 'passport' } } + + it 'returns a successful form response' do + result = subject.submit(params) + + expect(result).to be_kind_of(FormResponse) + expect(result.success?).to eq(true) + expect(result.errors).to be_empty + end + end + end +end diff --git a/spec/support/flow_policy_helper.rb b/spec/support/flow_policy_helper.rb index e99ad069d12..9c63c52c7e6 100644 --- a/spec/support/flow_policy_helper.rb +++ b/spec/support/flow_policy_helper.rb @@ -17,6 +17,9 @@ def stub_step(key:, idv_session:) idv_session.skip_doc_auth_from_how_to_verify = false when :hybrid_handoff idv_session.flow_path = 'standard' + when :choose_id_type + idv_session.flow_path = 'standard' + idv_session.passport_allowed == true when :link_sent idv_session.flow_path = 'hybrid' idv_session.pii_from_doc = Pii::StateId.new(**Idp::Constants::MOCK_IDV_APPLICANT) @@ -69,6 +72,8 @@ def keys_up_to(key:) %i[welcome agreement how_to_verify] when :hybrid_handoff %i[welcome agreement how_to_verify hybrid_handoff] + when :choose_id_type + %i[welcome agreement how_to_verify hybrid_handoff choose_id_type] when :link_sent %i[welcome agreement how_to_verify hybrid_handoff link_sent] when :document_capture From 19f907f8158db7b5d47cc45ebbd33f4942cb5e1b Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Fri, 28 Feb 2025 16:31:37 -0500 Subject: [PATCH 07/22] styling for radio button --- app/views/idv/choose_id_type/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/idv/choose_id_type/show.html.erb b/app/views/idv/choose_id_type/show.html.erb index 3f8658c89aa..cea3d14f988 100644 --- a/app/views/idv/choose_id_type/show.html.erb +++ b/app/views/idv/choose_id_type/show.html.erb @@ -39,10 +39,10 @@ ], form: f, input_html: { class: 'usa-radio__input--bordered' }, + item_label_class: 'usa-radio__label width-full', name: :choose_id_type_preference, required: true, wrapper: :uswds_radio_buttons, - wrapper_html: { class: 'text-bold' }, error_messages: { valueMissing: t('doc_auth.errors.choose_id_type_check')} ) %> <%= f.submit t('forms.buttons.continue'), class: 'margin-top-5' %> From 2f093a9058eb6e4d915a616023415711c031f7e9 Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Fri, 28 Feb 2025 16:44:54 -0500 Subject: [PATCH 08/22] lint fixes --- app/services/analytics_events.rb | 26 ++++++------- app/views/idv/choose_id_type/show.html.erb | 38 +++++++++---------- .../idv/choose_id_type_controller_spec.rb | 2 +- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index f54af80bbad..14138f721eb 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -1306,47 +1306,47 @@ def idv_doc_auth_capture_complete_visited( ) end + # @param [Boolean] success # @param [String] step Current IdV step # @param [String] analytics_id Current IdV flow identifier # @param ["hybrid","standard"] flow_path Document capture user flow - def idv_doc_auth_choose_id_type_visited( + # @param ['drivers_license', 'passport'] chosen_id_type Chosen id type of the user + # @param [Hash] errors + def idv_doc_auth_choose_id_type_submitted( + success:, step:, analytics_id:, flow_path:, + chosen_id_type:, + errors: nil, **extra ) track_event( - :idv_doc_auth_choose_id_type_visited, + :idv_doc_auth_choose_id_type_submitted, + success:, step:, analytics_id:, flow_path:, + chosen_id_type:, + errors:, **extra, ) end - # @param [Boolean] success # @param [String] step Current IdV step # @param [String] analytics_id Current IdV flow identifier # @param ["hybrid","standard"] flow_path Document capture user flow - # @param ['drivers_license', 'passport'] chosen_id_type Chosen id type of the user - # @param [Hash] errors - def idv_doc_auth_choose_id_type_submitted( - success:, + def idv_doc_auth_choose_id_type_visited( step:, analytics_id:, flow_path:, - chosen_id_type:, - errors: nil, **extra ) track_event( - :idv_doc_auth_choose_id_type_submitted, - success:, + :idv_doc_auth_choose_id_type_visited, step:, analytics_id:, flow_path:, - chosen_id_type:, - errors:, **extra, ) end diff --git a/app/views/idv/choose_id_type/show.html.erb b/app/views/idv/choose_id_type/show.html.erb index cea3d14f988..2fe93b67a14 100644 --- a/app/views/idv/choose_id_type/show.html.erb +++ b/app/views/idv/choose_id_type/show.html.erb @@ -22,29 +22,29 @@ help_center_redirect_url( category: 'verify-your-identity', article: 'accepted-identification-documents', - ) + ), ) %> <%= simple_form_for( - :doc_auth, - url: idv_choose_id_type_path, - method: :put, - ) do |f| %> - <%= render ValidatedFieldComponent.new( - as: :radio_buttons, - collection: [ - [t('doc_auth.forms.id_type_preference.drivers_license'), :drivers_license], - [t('doc_auth.forms.id_type_preference.passport'), :passport], - ], - form: f, - input_html: { class: 'usa-radio__input--bordered' }, - item_label_class: 'usa-radio__label width-full', - name: :choose_id_type_preference, - required: true, - wrapper: :uswds_radio_buttons, - error_messages: { valueMissing: t('doc_auth.errors.choose_id_type_check')} - ) %> + :doc_auth, + url: idv_choose_id_type_path, + method: :put, + ) do |f| %> + <%= render ValidatedFieldComponent.new( + as: :radio_buttons, + collection: [ + [t('doc_auth.forms.id_type_preference.drivers_license'), :drivers_license], + [t('doc_auth.forms.id_type_preference.passport'), :passport], + ], + form: f, + input_html: { class: 'usa-radio__input--bordered' }, + item_label_class: 'usa-radio__label width-full', + name: :choose_id_type_preference, + required: true, + wrapper: :uswds_radio_buttons, + error_messages: { valueMissing: t('doc_auth.errors.choose_id_type_check') }, + ) %> <%= f.submit t('forms.buttons.continue'), class: 'margin-top-5' %> <% end %> diff --git a/spec/controllers/idv/choose_id_type_controller_spec.rb b/spec/controllers/idv/choose_id_type_controller_spec.rb index 4d3b891978f..4ce4af5b9b4 100644 --- a/spec/controllers/idv/choose_id_type_controller_spec.rb +++ b/spec/controllers/idv/choose_id_type_controller_spec.rb @@ -68,7 +68,7 @@ describe '#update' do let(:chosen_id_type) { 'drivers_license' } let(:analytics_name) { :idv_doc_auth_choose_id_type_submitted } - let (:analytics_args) do + let(:analytics_args) do { success: true, step: 'choose_id_type', From 19b9dbad7a3618c8b658b3de8df1e899a5b800bc Mon Sep 17 00:00:00 2001 From: Alex Bradley Date: Fri, 28 Feb 2025 16:45:04 -0500 Subject: [PATCH 09/22] add changelog changelog: Upcoming Features, Doc Auth, add a choose your id screen for passports From 8bffa96a32fac6c4b1cacc02a533db78c4e1ac16 Mon Sep 17 00:00:00 2001 From: ashukla Date: Tue, 4 Mar 2025 09:39:56 -0600 Subject: [PATCH 10/22] Updated page styling --- app/assets/stylesheets/components/_index.scss | 1 + app/assets/stylesheets/components/_radio.scss | 10 ++++++++++ app/views/idv/choose_id_type/show.html.erb | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 app/assets/stylesheets/components/_radio.scss diff --git a/app/assets/stylesheets/components/_index.scss b/app/assets/stylesheets/components/_index.scss index ca1a7031e0c..d7078eb1a33 100644 --- a/app/assets/stylesheets/components/_index.scss +++ b/app/assets/stylesheets/components/_index.scss @@ -15,6 +15,7 @@ @forward 'header'; @forward 'page-heading'; @forward 'personal-key'; +@forward 'radio'; @forward 'spinner-button'; @forward 'spinner-dots'; @forward 'step-indicator'; diff --git a/app/assets/stylesheets/components/_radio.scss b/app/assets/stylesheets/components/_radio.scss new file mode 100644 index 00000000000..ad48ca71efa --- /dev/null +++ b/app/assets/stylesheets/components/_radio.scss @@ -0,0 +1,10 @@ +@use 'uswds-core' as *; + +.padding-for-radio { + padding: 1.5rem 1rem 1.5rem 2.375rem !important; + margin: 1rem 0 !important; +} + +.secondary-text-color-for-radio { + color: #0071bb !important; +} diff --git a/app/views/idv/choose_id_type/show.html.erb b/app/views/idv/choose_id_type/show.html.erb index 2fe93b67a14..abad33828dc 100644 --- a/app/views/idv/choose_id_type/show.html.erb +++ b/app/views/idv/choose_id_type/show.html.erb @@ -39,7 +39,7 @@ ], form: f, input_html: { class: 'usa-radio__input--bordered' }, - item_label_class: 'usa-radio__label width-full', + item_label_class: 'usa-radio__label text-bold width-full padding-for-radio secondary-text-color-for-radio', name: :choose_id_type_preference, required: true, wrapper: :uswds_radio_buttons, From 302bf128520a154f7659cc020af25068455a3aab Mon Sep 17 00:00:00 2001 From: ashukla Date: Tue, 4 Mar 2025 10:03:02 -0600 Subject: [PATCH 11/22] switching to usa-radio__input--tile --- app/assets/stylesheets/components/_index.scss | 1 - app/assets/stylesheets/components/_radio.scss | 10 ---------- app/views/idv/choose_id_type/show.html.erb | 4 ++-- 3 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 app/assets/stylesheets/components/_radio.scss diff --git a/app/assets/stylesheets/components/_index.scss b/app/assets/stylesheets/components/_index.scss index d7078eb1a33..ca1a7031e0c 100644 --- a/app/assets/stylesheets/components/_index.scss +++ b/app/assets/stylesheets/components/_index.scss @@ -15,7 +15,6 @@ @forward 'header'; @forward 'page-heading'; @forward 'personal-key'; -@forward 'radio'; @forward 'spinner-button'; @forward 'spinner-dots'; @forward 'step-indicator'; diff --git a/app/assets/stylesheets/components/_radio.scss b/app/assets/stylesheets/components/_radio.scss deleted file mode 100644 index ad48ca71efa..00000000000 --- a/app/assets/stylesheets/components/_radio.scss +++ /dev/null @@ -1,10 +0,0 @@ -@use 'uswds-core' as *; - -.padding-for-radio { - padding: 1.5rem 1rem 1.5rem 2.375rem !important; - margin: 1rem 0 !important; -} - -.secondary-text-color-for-radio { - color: #0071bb !important; -} diff --git a/app/views/idv/choose_id_type/show.html.erb b/app/views/idv/choose_id_type/show.html.erb index abad33828dc..ae4859cfdbd 100644 --- a/app/views/idv/choose_id_type/show.html.erb +++ b/app/views/idv/choose_id_type/show.html.erb @@ -38,8 +38,8 @@ [t('doc_auth.forms.id_type_preference.passport'), :passport], ], form: f, - input_html: { class: 'usa-radio__input--bordered' }, - item_label_class: 'usa-radio__label text-bold width-full padding-for-radio secondary-text-color-for-radio', + input_html: { class: 'usa-radio__input--tile' }, + item_label_class: 'usa-radio__label text-bold width-full', name: :choose_id_type_preference, required: true, wrapper: :uswds_radio_buttons, From b5ef6842c3e357d6cbe3b44dfb7db92fa046c027 Mon Sep 17 00:00:00 2001 From: ashukla Date: Tue, 4 Mar 2025 10:43:03 -0600 Subject: [PATCH 12/22] Added spacing --- app/views/idv/choose_id_type/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/idv/choose_id_type/show.html.erb b/app/views/idv/choose_id_type/show.html.erb index ae4859cfdbd..3e94a6b333c 100644 --- a/app/views/idv/choose_id_type/show.html.erb +++ b/app/views/idv/choose_id_type/show.html.erb @@ -39,7 +39,7 @@ ], form: f, input_html: { class: 'usa-radio__input--tile' }, - item_label_class: 'usa-radio__label text-bold width-full', + item_label_class: 'usa-radio__label text-bold width-full margin-y-2', name: :choose_id_type_preference, required: true, wrapper: :uswds_radio_buttons, From 1bf8abdbd8debef7aa6665ea07cdbb00ce71c0f0 Mon Sep 17 00:00:00 2001 From: ashukla Date: Tue, 4 Mar 2025 16:16:51 -0600 Subject: [PATCH 13/22] Updating spacing --- app/views/idv/choose_id_type/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/idv/choose_id_type/show.html.erb b/app/views/idv/choose_id_type/show.html.erb index 3e94a6b333c..a2e45997035 100644 --- a/app/views/idv/choose_id_type/show.html.erb +++ b/app/views/idv/choose_id_type/show.html.erb @@ -45,7 +45,7 @@ wrapper: :uswds_radio_buttons, error_messages: { valueMissing: t('doc_auth.errors.choose_id_type_check') }, ) %> - <%= f.submit t('forms.buttons.continue'), class: 'margin-top-5' %> + <%= f.submit t('forms.buttons.continue'), class: 'margin-y-2' %> <% end %> <%= render 'idv/doc_auth/cancel', step: 'choose_id_type' %> From 81c332e1718bf1b1596aa5c4c0e2342df4ff6b7f Mon Sep 17 00:00:00 2001 From: ashukla Date: Thu, 6 Mar 2025 10:30:27 -0600 Subject: [PATCH 14/22] Adding choose id to mobile flow --- app/controllers/idv/agreement_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/idv/agreement_controller.rb b/app/controllers/idv/agreement_controller.rb index 64ced91aba2..76d85fcf00a 100644 --- a/app/controllers/idv/agreement_controller.rb +++ b/app/controllers/idv/agreement_controller.rb @@ -40,7 +40,8 @@ def update if IdentityConfig.store.in_person_proofing_opt_in_enabled && IdentityConfig.store.in_person_proofing_enabled - redirect_to idv_how_to_verify_url + redirect_to idv_how_to_verify_url if !idv_session.skip_hybrid_handoff + redirect_to idv_choose_id_type_url if idv_session.skip_hybrid_handoff else redirect_to idv_hybrid_handoff_url end From df47f4ec4984f364114086f338b4925182d4dbc1 Mon Sep 17 00:00:00 2001 From: ashukla Date: Thu, 6 Mar 2025 12:25:38 -0600 Subject: [PATCH 15/22] Fixing specs and mobile flow --- app/controllers/idv/agreement_controller.rb | 6 +++--- app/controllers/idv/choose_id_type_controller.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/idv/agreement_controller.rb b/app/controllers/idv/agreement_controller.rb index 76d85fcf00a..276613cb79c 100644 --- a/app/controllers/idv/agreement_controller.rb +++ b/app/controllers/idv/agreement_controller.rb @@ -40,8 +40,8 @@ def update if IdentityConfig.store.in_person_proofing_opt_in_enabled && IdentityConfig.store.in_person_proofing_enabled - redirect_to idv_how_to_verify_url if !idv_session.skip_hybrid_handoff - redirect_to idv_choose_id_type_url if idv_session.skip_hybrid_handoff + redirect_to idv_how_to_verify_url if !params[:skip_hybrid_handoff] + redirect_to idv_choose_id_type_url if params[:skip_hybrid_handoff] else redirect_to idv_hybrid_handoff_url end @@ -54,7 +54,7 @@ def self.step_info Idv::StepInfo.new( key: :agreement, controller: self, - next_steps: [:hybrid_handoff, :document_capture, :how_to_verify], + next_steps: [:hybrid_handoff, :choose_id_type, :document_capture, :how_to_verify], preconditions: ->(idv_session:, user:) { idv_session.welcome_visited }, undo_step: ->(idv_session:, user:) do idv_session.idv_consent_given_at = nil diff --git a/app/controllers/idv/choose_id_type_controller.rb b/app/controllers/idv/choose_id_type_controller.rb index 26cf01fc10f..9c4a681a4e5 100644 --- a/app/controllers/idv/choose_id_type_controller.rb +++ b/app/controllers/idv/choose_id_type_controller.rb @@ -50,7 +50,7 @@ def self.step_info private def redirect_if_passport_not_available - redirect_to idv_hybrid_handoff_url if !idv_session.passport_allowed + redirect_to idv_how_to_verify_url if !idv_session.passport_allowed end def chosen_id_type From b37dd124d46e718bf1fda7c4804b4f403948321b Mon Sep 17 00:00:00 2001 From: ashukla Date: Thu, 6 Mar 2025 12:41:36 -0600 Subject: [PATCH 16/22] updating specs for new behaviours --- spec/controllers/idv/choose_id_type_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/idv/choose_id_type_controller_spec.rb b/spec/controllers/idv/choose_id_type_controller_spec.rb index 4ce4af5b9b4..d66a54e0381 100644 --- a/spec/controllers/idv/choose_id_type_controller_spec.rb +++ b/spec/controllers/idv/choose_id_type_controller_spec.rb @@ -28,12 +28,12 @@ describe '#show' do context 'passport is not available' do - it 'redirects to hybrid hybrid handoff' do + it 'redirects to how to verify' do subject.idv_session.passport_allowed = false get :show - expect(response).to redirect_to(idv_hybrid_handoff_url) + expect(response).to redirect_to(idv_how_to_verify_url) end end From c6d86cab7f288af4990591dce488cbce5f321869 Mon Sep 17 00:00:00 2001 From: ashukla Date: Mon, 10 Mar 2025 08:46:43 -0500 Subject: [PATCH 17/22] Resolving PR comment --- app/controllers/idv/agreement_controller.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/controllers/idv/agreement_controller.rb b/app/controllers/idv/agreement_controller.rb index 276613cb79c..2ccd9277a11 100644 --- a/app/controllers/idv/agreement_controller.rb +++ b/app/controllers/idv/agreement_controller.rb @@ -40,8 +40,11 @@ def update if IdentityConfig.store.in_person_proofing_opt_in_enabled && IdentityConfig.store.in_person_proofing_enabled - redirect_to idv_how_to_verify_url if !params[:skip_hybrid_handoff] - redirect_to idv_choose_id_type_url if params[:skip_hybrid_handoff] + if params[:skip_hybrid_handoff] + redirect_to idv_choose_id_type_url + else + redirect_to idv_how_to_verify_url + end else redirect_to idv_hybrid_handoff_url end From 7dc6d3925cc15f064e9f9d2f6ef4927b53c23852 Mon Sep 17 00:00:00 2001 From: ashukla Date: Mon, 10 Mar 2025 09:01:31 -0500 Subject: [PATCH 18/22] Resolving PR comment --- app/controllers/idv/choose_id_type_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/idv/choose_id_type_controller.rb b/app/controllers/idv/choose_id_type_controller.rb index 9c4a681a4e5..0f05aaba506 100644 --- a/app/controllers/idv/choose_id_type_controller.rb +++ b/app/controllers/idv/choose_id_type_controller.rb @@ -21,7 +21,7 @@ def update analytics.idv_doc_auth_choose_id_type_submitted( **analytics_arguments.merge(result.to_h) - .merge({ chosen_id_type: chosen_id_type }), + .merge({ chosen_id_type: }), ) if result.success? From 693159f6ddc9b2adf65b09f828a96ee7ad5398fa Mon Sep 17 00:00:00 2001 From: ashukla Date: Mon, 10 Mar 2025 10:17:34 -0500 Subject: [PATCH 19/22] Resolved PR comments, fixing specs --- .../idv/choose_id_type_controller.rb | 7 +----- app/forms/idv/choose_id_type_form.rb | 14 +++++++++++- .../idv/choose_id_type_controller_spec.rb | 2 +- spec/forms/idv/choose_id_type_form_spec.rb | 22 ++++++++++++++++++- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/app/controllers/idv/choose_id_type_controller.rb b/app/controllers/idv/choose_id_type_controller.rb index 0f05aaba506..75e668624d8 100644 --- a/app/controllers/idv/choose_id_type_controller.rb +++ b/app/controllers/idv/choose_id_type_controller.rb @@ -66,12 +66,7 @@ def set_passport_requested end def next_step - if idv_session.passport_requested - # page is not created yet redirect to in person for now - idv_in_person_url - else - idv_document_capture_url - end + idv_document_capture_url end def choose_id_type_form_params diff --git a/app/forms/idv/choose_id_type_form.rb b/app/forms/idv/choose_id_type_form.rb index 8e9907084b5..2de237f4f75 100644 --- a/app/forms/idv/choose_id_type_form.rb +++ b/app/forms/idv/choose_id_type_form.rb @@ -4,6 +4,7 @@ module Idv class ChooseIdTypeForm include ActiveModel::Model + validate :chosen_id_type_valid? attr_reader :chosen_id_type def initialize(chosen_id_type = nil) @@ -13,7 +14,18 @@ def initialize(chosen_id_type = nil) def submit(params) @chosen_id_type = params[:choose_id_type_preference] - FormResponse.new(success: valid?, errors: errors) + FormResponse.new(success: chosen_id_type_valid?, errors: errors) + end + + def chosen_id_type_valid? + valid_types = [:passport, :drivers_license] # Will remove once pasport added to id slugs + return true if valid_types.include? @chosen_id_type + errors.add( + :chosen_id_type, + :invalid, + message: "`choose_id_type` #{@chosen_id_type} is invalid, expected one of #{valid_types}", + ) + false end end end diff --git a/spec/controllers/idv/choose_id_type_controller_spec.rb b/spec/controllers/idv/choose_id_type_controller_spec.rb index d66a54e0381..7f1916055ed 100644 --- a/spec/controllers/idv/choose_id_type_controller_spec.rb +++ b/spec/controllers/idv/choose_id_type_controller_spec.rb @@ -126,7 +126,7 @@ it 'redirects to passport document capture' do put :update, params: params - expect(response).to redirect_to(idv_in_person_url) + expect(response).to redirect_to(idv_document_capture_url) end end end diff --git a/spec/forms/idv/choose_id_type_form_spec.rb b/spec/forms/idv/choose_id_type_form_spec.rb index c6c2f3b416e..f7bac37e28f 100644 --- a/spec/forms/idv/choose_id_type_form_spec.rb +++ b/spec/forms/idv/choose_id_type_form_spec.rb @@ -5,7 +5,7 @@ describe '#submit' do context 'when the form is valid' do - let(:params) { { choose_id_type_preference: 'passport' } } + let(:params) { { choose_id_type_preference: :passport } } it 'returns a successful form response' do result = subject.submit(params) @@ -15,5 +15,25 @@ expect(result.errors).to be_empty end end + context 'when the choose_id_type_preference is nil' do + let(:params) { { choose_id_type_preference: nil } } + it 'returns a failed form response when id type is nil' do + result = subject.submit(params) + + expect(result).to be_kind_of(FormResponse) + expect(result.success?).to eq(false) + expect(result.errors).not_to be_empty + end + end + context 'when the choose_id_type_preference is not supported type' do + let(:params) { { choose_id_type_preference: :unknown_id_type } } + it 'returns a failed form response when id type is nil' do + result = subject.submit(params) + + expect(result).to be_kind_of(FormResponse) + expect(result.success?).to eq(false) + expect(result.errors).not_to be_empty + end + end end end From f85da82c539ab9b6dcf593fd2b4c3f0890872e8c Mon Sep 17 00:00:00 2001 From: ashukla Date: Mon, 10 Mar 2025 10:58:01 -0500 Subject: [PATCH 20/22] Fixing specs --- app/forms/idv/choose_id_type_form.rb | 2 +- app/services/analytics_events.rb | 4 ++-- spec/forms/idv/choose_id_type_form_spec.rb | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/forms/idv/choose_id_type_form.rb b/app/forms/idv/choose_id_type_form.rb index 2de237f4f75..1b11407e19f 100644 --- a/app/forms/idv/choose_id_type_form.rb +++ b/app/forms/idv/choose_id_type_form.rb @@ -18,7 +18,7 @@ def submit(params) end def chosen_id_type_valid? - valid_types = [:passport, :drivers_license] # Will remove once pasport added to id slugs + valid_types = ['passport', 'drivers_license'] # Will remove once pasport added to id slugs return true if valid_types.include? @chosen_id_type errors.add( :chosen_id_type, diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 14138f721eb..91fbe481298 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -1318,7 +1318,7 @@ def idv_doc_auth_choose_id_type_submitted( analytics_id:, flow_path:, chosen_id_type:, - errors: nil, + error_details: nil, **extra ) track_event( @@ -1328,7 +1328,7 @@ def idv_doc_auth_choose_id_type_submitted( analytics_id:, flow_path:, chosen_id_type:, - errors:, + error_details:, **extra, ) end diff --git a/spec/forms/idv/choose_id_type_form_spec.rb b/spec/forms/idv/choose_id_type_form_spec.rb index f7bac37e28f..746b618673f 100644 --- a/spec/forms/idv/choose_id_type_form_spec.rb +++ b/spec/forms/idv/choose_id_type_form_spec.rb @@ -5,7 +5,7 @@ describe '#submit' do context 'when the form is valid' do - let(:params) { { choose_id_type_preference: :passport } } + let(:params) { { choose_id_type_preference: 'passport' } } it 'returns a successful form response' do result = subject.submit(params) @@ -26,7 +26,7 @@ end end context 'when the choose_id_type_preference is not supported type' do - let(:params) { { choose_id_type_preference: :unknown_id_type } } + let(:params) { { choose_id_type_preference: 'unknown-type' } } it 'returns a failed form response when id type is nil' do result = subject.submit(params) From 8c8f5e6d53df347c5e1ccf48578d5bccc892c607 Mon Sep 17 00:00:00 2001 From: ashukla Date: Mon, 10 Mar 2025 12:02:40 -0500 Subject: [PATCH 21/22] Fixing lint and feature tests --- app/services/analytics_events.rb | 2 +- .../idv/doc_auth/choose_id_type_spec.rb | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 spec/features/idv/doc_auth/choose_id_type_spec.rb diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 91fbe481298..4c071817c36 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -1311,7 +1311,7 @@ def idv_doc_auth_capture_complete_visited( # @param [String] analytics_id Current IdV flow identifier # @param ["hybrid","standard"] flow_path Document capture user flow # @param ['drivers_license', 'passport'] chosen_id_type Chosen id type of the user - # @param [Hash] errors + # @param [Hash] error_details def idv_doc_auth_choose_id_type_submitted( success:, step:, diff --git a/spec/features/idv/doc_auth/choose_id_type_spec.rb b/spec/features/idv/doc_auth/choose_id_type_spec.rb new file mode 100644 index 00000000000..e37c41ed509 --- /dev/null +++ b/spec/features/idv/doc_auth/choose_id_type_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +RSpec.feature 'choose id type step error checking' do + include DocAuthHelper + context 'desktop flow', :js do + before do + allow(IdentityConfig.store).to receive(:doc_auth_passports_enabled).and_return(true) + sign_in_and_2fa_user + complete_doc_auth_steps_before_hybrid_handoff_step + end + + it 'shows choose id type screen after hybrid handoff upload' do + expect(page).to have_content(t('doc_auth.headings.upload_from_computer')) + click_on t('forms.buttons.upload_photos') + expect(page).to have_current_path(idv_choose_id_type_url) + end + end + context 'mobile flow', :js, driver: :headless_chrome_mobile do + before do + allow(IdentityConfig.store).to receive(:doc_auth_passports_enabled).and_return(true) + 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) + sign_in_and_2fa_user + complete_doc_auth_steps_before_agreement_step + complete_agreement_step + end + + it 'shows choose id type screen after agreements' do + expect(page).to have_current_path(idv_choose_id_type_url) + end + end +end From 9b76e60503b5adcddccad511601b7ea9d161f236 Mon Sep 17 00:00:00 2001 From: ashukla Date: Mon, 10 Mar 2025 12:58:43 -0500 Subject: [PATCH 22/22] Updated spec to choose radio option and continue to doc capture --- spec/features/idv/doc_auth/choose_id_type_spec.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/spec/features/idv/doc_auth/choose_id_type_spec.rb b/spec/features/idv/doc_auth/choose_id_type_spec.rb index e37c41ed509..69cff5195ec 100644 --- a/spec/features/idv/doc_auth/choose_id_type_spec.rb +++ b/spec/features/idv/doc_auth/choose_id_type_spec.rb @@ -9,10 +9,13 @@ complete_doc_auth_steps_before_hybrid_handoff_step end - it 'shows choose id type screen after hybrid handoff upload' do + it 'shows choose id type screen and continues after passport option' do expect(page).to have_content(t('doc_auth.headings.upload_from_computer')) click_on t('forms.buttons.upload_photos') expect(page).to have_current_path(idv_choose_id_type_url) + choose(t('doc_auth.forms.id_type_preference.passport')) + click_on t('forms.buttons.continue') + expect(page).to have_current_path(idv_document_capture_url) end end context 'mobile flow', :js, driver: :headless_chrome_mobile do @@ -25,8 +28,11 @@ complete_agreement_step end - it 'shows choose id type screen after agreements' do + it 'shows choose id type screen and continues after drivers license option' do expect(page).to have_current_path(idv_choose_id_type_url) + choose(t('doc_auth.forms.id_type_preference.drivers_license')) + click_on t('forms.buttons.continue') + expect(page).to have_current_path(idv_document_capture_url) end end end