diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 445d71961fd..852f94339a0 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -729,10 +729,6 @@ def idv_doc_auth_cancel_link_sent_submitted(**extra) track_event('IdV: doc auth cancel_link_sent submitted', **extra) end - def idv_doc_auth_cancel_send_link_submitted(**extra) - track_event('IdV: doc auth cancel_send_link submitted', **extra) - end - # @identity.idp.previous_event_name IdV: in person proofing cancel_update_ssn submitted def idv_doc_auth_cancel_update_ssn_submitted(**extra) track_event('IdV: doc auth cancel_update_ssn submitted', **extra) @@ -783,14 +779,6 @@ def idv_doc_auth_redo_document_capture_submitted(**extra) track_event('IdV: doc auth redo_document_capture submitted', **extra) end - def idv_doc_auth_send_link_visited(**extra) - track_event('IdV: doc auth send_link visited', **extra) - end - - def idv_doc_auth_send_link_submitted(**extra) - track_event('IdV: doc auth send_link submitted', **extra) - end - # @identity.idp.previous_event_name IdV: in person proofing ssn submitted def idv_doc_auth_ssn_submitted(**extra) track_event('IdV: doc auth ssn submitted', **extra) diff --git a/app/services/idv/actions/cancel_link_sent_action.rb b/app/services/idv/actions/cancel_link_sent_action.rb index a1d32d19ae2..b38e6c0b4ee 100644 --- a/app/services/idv/actions/cancel_link_sent_action.rb +++ b/app/services/idv/actions/cancel_link_sent_action.rb @@ -6,10 +6,7 @@ def self.analytics_submitted_event end def call - mark_step_incomplete(:send_link) - if IdentityConfig.store.doc_auth_combined_hybrid_handoff_enabled - mark_step_incomplete(:upload) - end + mark_step_incomplete(:upload) end end end diff --git a/app/services/idv/actions/cancel_send_link_action.rb b/app/services/idv/actions/cancel_send_link_action.rb deleted file mode 100644 index 1bf64fefef9..00000000000 --- a/app/services/idv/actions/cancel_send_link_action.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Idv - module Actions - class CancelSendLinkAction < Idv::Steps::DocAuthBaseStep - def self.analytics_submitted_event - :idv_doc_auth_cancel_send_link_submitted - end - - def call - mark_step_incomplete(:upload) - end - end - end -end diff --git a/app/services/idv/flows/doc_auth_flow.rb b/app/services/idv/flows/doc_auth_flow.rb index 2fdec534840..ff799eb7ebe 100644 --- a/app/services/idv/flows/doc_auth_flow.rb +++ b/app/services/idv/flows/doc_auth_flow.rb @@ -5,7 +5,6 @@ class DocAuthFlow < Flow::BaseFlow welcome: Idv::Steps::WelcomeStep, agreement: Idv::Steps::AgreementStep, upload: Idv::Steps::UploadStep, - send_link: Idv::Steps::SendLinkStep, link_sent: Idv::Steps::LinkSentStep, email_sent: Idv::Steps::EmailSentStep, document_capture: Idv::Steps::DocumentCaptureStep, @@ -30,7 +29,6 @@ class DocAuthFlow < Flow::BaseFlow OPTIONAL_SHOW_STEPS = {}.freeze ACTIONS = { - cancel_send_link: Idv::Actions::CancelSendLinkAction, cancel_link_sent: Idv::Actions::CancelLinkSentAction, redo_address: Idv::Actions::RedoAddressAction, redo_document_capture: Idv::Actions::RedoDocumentCaptureAction, diff --git a/app/services/idv/steps/send_link_step.rb b/app/services/idv/steps/send_link_step.rb deleted file mode 100644 index 62295b74dfa..00000000000 --- a/app/services/idv/steps/send_link_step.rb +++ /dev/null @@ -1,128 +0,0 @@ -module Idv - module Steps - class SendLinkStep < DocAuthBaseStep - include ActionView::Helpers::DateHelper - - STEP_INDICATOR_STEP = :verify_id - - def self.analytics_visited_event - :idv_doc_auth_send_link_visited - end - - def self.analytics_submitted_event - :idv_doc_auth_send_link_submitted - end - - def call - throttle.increment! - return throttled_failure if throttle.throttled? - telephony_result = send_link - failure_reason = nil - if !telephony_result.success? - failure_reason = { telephony: [telephony_result.error.class.name.demodulize] } - end - idv_session[:phone_for_mobile_flow] = permit(:phone)[:phone] - @flow.irs_attempts_api_tracker.idv_phone_upload_link_sent( - success: telephony_result.success?, - phone_number: formatted_destination_phone, - failure_reason: failure_reason, - ) - build_telephony_form_response(telephony_result) - end - - def extra_view_variables - { - idv_phone_form: build_form, - } - end - - private - - def build_form - Idv::PhoneForm.new( - previous_params: {}, - user: current_user, - delivery_methods: [:sms], - ) - end - - def build_telephony_form_response(telephony_result) - FormResponse.new( - success: telephony_result.success?, - errors: { message: telephony_result.error&.friendly_message }, - extra: { telephony_response: telephony_result.to_h }, - ) - end - - def throttled_failure - @flow.analytics.throttler_rate_limit_triggered( - throttle_type: :idv_send_link, - ) - message = I18n.t( - 'errors.doc_auth.send_link_throttle', - timeout: distance_of_time_in_words( - Time.zone.now, - [throttle.expires_at, Time.zone.now].compact.max, - except: :seconds, - ), - ) - - @flow.irs_attempts_api_tracker.idv_phone_send_link_rate_limited( - phone_number: formatted_destination_phone, - ) - - failure(message) - end - - def send_link - session_uuid = flow_session[:document_capture_session_uuid] - update_document_capture_session_requested_at(session_uuid) - Telephony.send_doc_auth_link( - to: formatted_destination_phone, - link: link(session_uuid), - country_code: Phonelib.parse(formatted_destination_phone).country, - sp_or_app_name: sp_or_app_name, - ) - end - - def sp_or_app_name - current_sp&.friendly_name.presence || APP_NAME - end - - def form_submit - params = permit(:phone) - params[:otp_delivery_preference] = 'sms' - build_form.submit(params) - end - - def formatted_destination_phone - raw_phone = permit(:phone)[:phone] - PhoneFormatter.format(raw_phone, country_code: 'US') - end - - def update_document_capture_session_requested_at(session_uuid) - document_capture_session = DocumentCaptureSession.find_by(uuid: session_uuid) - return unless document_capture_session - document_capture_session.update!( - requested_at: Time.zone.now, - cancelled_at: nil, - issuer: sp_session[:issuer], - ) - end - - def link(session_uuid) - idv_capture_doc_dashes_url( - 'document-capture-session': session_uuid, - request_id: sp_session[:request_id], - ) - end - - def throttle - @throttle ||= Throttle.new( - user: current_user, - throttle_type: :idv_send_link, - ) - end - end - end -end diff --git a/app/services/idv/steps/upload_step.rb b/app/services/idv/steps/upload_step.rb index 4d4ded41f61..718a145b0ca 100644 --- a/app/services/idv/steps/upload_step.rb +++ b/app/services/idv/steps/upload_step.rb @@ -21,27 +21,14 @@ def call # app/views/idv/doc_auth/upload.html.erb if params[:type] == 'desktop' handle_desktop_selection - elsif params[:combined] - # The user was shown the new combined view and - # submitted a phone number to this step with feature flag on - # OR - # The user was originally shown the new combined view, - # but has submitted to a step with the feature flag off - # (50/50 from new to old) - handle_phone_submission else - handle_mobile_selection + return bypass_send_link_steps if mobile_device? + handle_phone_submission end end def extra_view_variables - if IdentityConfig.store.doc_auth_combined_hybrid_handoff_enabled - { - idv_phone_form: build_form, - } - else - {} - end + { idv_phone_form: build_form } end private @@ -63,26 +50,13 @@ def build_form end def form_submit - return super if !IdentityConfig.store.doc_auth_combined_hybrid_handoff_enabled - return super if params[:type] == 'desktop' - - # Remove after 50/50 deploy w/ flag - return super if params[:type] != 'combined' + return super unless params[:type] == 'mobile' params = permit(:phone) params[:otp_delivery_preference] = 'sms' build_form.submit(params) end - # To be removed after 50/50 - def handle_mobile_selection - if mobile_device? - bypass_send_link_steps - else - send_user_to_send_link_step - end - end - def handle_phone_submission throttle.increment! return throttled_failure if throttle.throttled? @@ -125,13 +99,7 @@ def send_user_to_email_sent_step form_response(destination: :email_sent) end - def send_user_to_send_link_step - mark_step_complete(:email_sent) - form_response(destination: :send_link) - end - def bypass_send_link_steps - mark_step_complete(:send_link) mark_step_complete(:link_sent) mark_step_complete(:email_sent) form_response(destination: :document_capture) diff --git a/app/views/idv/doc_auth/_combined_upload.html.erb b/app/views/idv/doc_auth/_combined_upload.html.erb deleted file mode 100644 index c3a4b6a2127..00000000000 --- a/app/views/idv/doc_auth/_combined_upload.html.erb +++ /dev/null @@ -1,74 +0,0 @@ -<% title t('titles.doc_auth.upload') %> - -<%= render 'idv/doc_auth/error_messages', flow_session: flow_session %> - -<%= render PageHeadingComponent.new do %> - <%= t('doc_auth.headings.combined_upload') %> -<% end %> - -

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

- -
-
- <%= 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.combined_upload_from_phone') %> -

- <%= t('doc_auth.info.combined_upload_from_phone') %> - <%= simple_form_for( - idv_phone_form, - as: :doc_auth, - url: url_for(type: :mobile, combined: true), - method: 'PUT', - html: { autocomplete: 'off' }, - ) do |f| %> - <%= render PhoneInputComponent.new( - form: f, - required: true, - delivery_methods: [:sms], - class: 'margin-bottom-4', - ) %> - <%= f.submit t('forms.buttons.send_link') %> - <% end %> -
-
- -
-
-
- <%= image_tag( - asset_url('idv/laptop-icon.svg'), - alt: t('image_description.laptop'), - width: 88, - height: 88, - ) %> -
-
-

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

- <%= t('doc_auth.info.combined_upload_from_computer') %>  - <%= simple_form_for( - :doc_auth, - url: url_for(type: :desktop), - method: 'PUT', - class: 'margin-bottom-4', - ) do |f| %> - <%= f.submit t('forms.buttons.upload_photos'), outline: true %> - <% end %> -
-
- -<%= render 'idv/doc_auth/cancel', step: 'upload' %> diff --git a/app/views/idv/doc_auth/_upload.html.erb b/app/views/idv/doc_auth/_upload.html.erb deleted file mode 100644 index 860a2c7e252..00000000000 --- a/app/views/idv/doc_auth/_upload.html.erb +++ /dev/null @@ -1,55 +0,0 @@ -<% title t('titles.doc_auth.upload') %> - -<%= render 'idv/doc_auth/error_messages', flow_session: flow_session %> - -<%= render PageHeadingComponent.new do %> - <%= t('doc_auth.headings.upload') %> -<% end %> - -

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

- -
- -
-
- <%= 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( - :doc_auth, - url: url_for(type: :mobile), - method: 'PUT', - html: { autocomplete: 'off', class: 'margin-top-2' }, - ) do |f| %> - <%= f.submit t('doc_auth.buttons.use_phone'), wide: false, class: 'margin-top-05' %> - <% end %> -
-
- -
- -<%= t('doc_auth.info.upload_from_computer') %>  -<%= simple_form_for( - :doc_auth, - url: url_for(type: :desktop), - method: 'PUT', - html: { class: 'display-inline' }, - ) do |f| %> - <%= f.submit t('doc_auth.info.upload_computer_link'), unstyled: true, big: false %> -<% end %> - -<%= render 'idv/doc_auth/cancel', step: 'upload' %> diff --git a/app/views/idv/doc_auth/send_link.html.erb b/app/views/idv/doc_auth/send_link.html.erb deleted file mode 100644 index 1e49331ba97..00000000000 --- a/app/views/idv/doc_auth/send_link.html.erb +++ /dev/null @@ -1,33 +0,0 @@ -<% title t('titles.doc_auth.take_photo') %> - -<% if flow_session[:error_message] %> - <%= render AlertComponent.new( - type: :error, - class: 'margin-bottom-4', - message: flow_session[:error_message], - ) %> -<% end %> - -<%= render PageHeadingComponent.new.with_content(t('doc_auth.headings.take_picture')) %> - -

<%= t('doc_auth.info.take_picture') %>

- -

<%= t('doc_auth.info.camera_required') %>

- -

<%= t('doc_auth.instructions.send_sms') %>

-<%= simple_form_for( - idv_phone_form, - as: :doc_auth, - url: url_for, - method: 'PUT', - html: { autocomplete: 'off' }, - ) do |f| %> - <%= render PhoneInputComponent.new( - form: f, - required: true, - delivery_methods: [:sms], - class: 'margin-bottom-4', - ) %> - <%= f.submit t('forms.buttons.continue'), class: 'margin-top-4' %> -<% end %> -<%= render 'idv/shared/back', action: 'cancel_send_link' %> diff --git a/app/views/idv/doc_auth/upload.html.erb b/app/views/idv/doc_auth/upload.html.erb index 16061aa99d4..c3a4b6a2127 100644 --- a/app/views/idv/doc_auth/upload.html.erb +++ b/app/views/idv/doc_auth/upload.html.erb @@ -1,10 +1,74 @@ -<% if IdentityConfig.store.doc_auth_combined_hybrid_handoff_enabled %> - <%= render partial: 'idv/doc_auth/combined_upload', locals: { - flow_session: flow_session, - idv_phone_form: idv_phone_form, - } %> -<% else %> - <%= render partial: 'idv/doc_auth/upload', locals: { - flow_session: flow_session, - } %> +<% title t('titles.doc_auth.upload') %> + +<%= render 'idv/doc_auth/error_messages', flow_session: flow_session %> + +<%= render PageHeadingComponent.new do %> + <%= t('doc_auth.headings.combined_upload') %> <% end %> + +

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

+ +
+
+ <%= 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.combined_upload_from_phone') %> +

+ <%= t('doc_auth.info.combined_upload_from_phone') %> + <%= simple_form_for( + idv_phone_form, + as: :doc_auth, + url: url_for(type: :mobile, combined: true), + method: 'PUT', + html: { autocomplete: 'off' }, + ) do |f| %> + <%= render PhoneInputComponent.new( + form: f, + required: true, + delivery_methods: [:sms], + class: 'margin-bottom-4', + ) %> + <%= f.submit t('forms.buttons.send_link') %> + <% end %> +
+
+ +
+
+
+ <%= image_tag( + asset_url('idv/laptop-icon.svg'), + alt: t('image_description.laptop'), + width: 88, + height: 88, + ) %> +
+
+

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

+ <%= t('doc_auth.info.combined_upload_from_computer') %>  + <%= simple_form_for( + :doc_auth, + url: url_for(type: :desktop), + method: 'PUT', + class: 'margin-bottom-4', + ) do |f| %> + <%= f.submit t('forms.buttons.upload_photos'), outline: true %> + <% end %> +
+
+ +<%= render 'idv/doc_auth/cancel', step: 'upload' %> diff --git a/config/application.yml.default b/config/application.yml.default index c421f959f4a..2e7d6b6579f 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -67,7 +67,6 @@ broken_personal_key_window_start: '2021-07-29T00:00:00Z' broken_personal_key_window_finish: '2021-09-22T00:00:00Z' component_previews_enabled: false country_phone_number_overrides: '{}' -doc_auth_combined_hybrid_handoff_enabled: false doc_auth_error_dpi_threshold: 290 doc_auth_error_sharpness_threshold: 40 doc_auth_error_glare_threshold: 40 diff --git a/config/locales/doc_auth/en.yml b/config/locales/doc_auth/en.yml index 0f64ead3cda..b1bb7d6f29f 100644 --- a/config/locales/doc_auth/en.yml +++ b/config/locales/doc_auth/en.yml @@ -13,7 +13,6 @@ en: take_picture: Take photo take_picture_retry: Retake photo upload_picture: Upload photo - use_phone: Use your phone errors: alerts: barcode_content_check: We couldn’t read the barcode on the back of your ID. It @@ -126,10 +125,7 @@ en: secure_account: Secure your account ssn: Enter your Social Security number ssn_update: Update your Social Security number - take_picture: Take a photo with a phone text_message: We sent a message to your phone - upload: How would you like to upload your state-issued ID? - upload_from_phone: Take a photo with a mobile phone to upload your ID verify_identity: Verify your identity welcome: Get started verifying your identity hybrid_flow_warning: @@ -145,7 +141,6 @@ en: info: address_guidance_puerto_rico_html: For Puerto Rico residents:

Please enter urbanization or condominium on address line 2. - camera_required: Your mobile phone must have a camera and a web browser. capture_status_big_document: Too Close capture_status_capturing: Capturing capture_status_none: Align @@ -183,12 +178,7 @@ en: ssn: We need your Social Security number to verify your name, date of birth and address. tag: Recommended - take_picture: Use the camera on your mobile phone and upload images of your - ID. We only use the images to verify your identity. upload: We’ll collect information about you by reading your state-issued ID. - upload_computer_link: Upload from your computer - upload_from_computer: Don’t have a phone? - upload_from_phone: Upload pictures directly from your phone camera verify_identity: We’ll ask for your personal information to verify your identity against public records. welcome_html: '%{sp_name} needs to make sure you are you — not someone @@ -205,8 +195,6 @@ en: instructions to verify your identity. learn_more: Learn more about our privacy and security measures privacy: Our privacy and security standards - send_sms: We’ll send a text message to your device with a link. Follow that - link to your browser to take photos of the front and back of your ID. switch_back: Switch back to your computer to finish verifying your identity. switch_back_image: Arrow pointing from phone to computer test_ssn: In the test environment only SSNs that begin with “900-” or “666-” are diff --git a/config/locales/doc_auth/es.yml b/config/locales/doc_auth/es.yml index a96b69ebe16..7947eb82664 100644 --- a/config/locales/doc_auth/es.yml +++ b/config/locales/doc_auth/es.yml @@ -13,7 +13,6 @@ es: take_picture: Tomar una foto take_picture_retry: Retirar la foto upload_picture: Subir foto - use_phone: Usa tu telefono errors: alerts: barcode_content_check: No pudimos leer el código de barras en el reverso de su @@ -152,11 +151,7 @@ es: secure_account: Asegure su cuenta ssn: Ingresa tu número de Seguro Social ssn_update: Actualice su número de Seguro Social - take_picture: Toma una foto con un teléfono text_message: Enviamos un mensaje a su teléfono - upload: '¿Cómo le gustaría subir su documento de identidad expedido por el - estado?' - upload_from_phone: Tome una foto con un teléfono móvil para cargar su identificación verify_identity: Verifique su identidad welcome: Comience a verificar su identidad hybrid_flow_warning: @@ -175,7 +170,6 @@ es: address_guidance_puerto_rico_html: Para residentes de Puerto Rico:

Incluyan en su dirección la urbanización o departamento en la línea de dirección 2. - camera_required: Su teléfono móvil debe tener una cámara y un navegador web. capture_status_big_document: Demasiado cerca capture_status_capturing: Capturando capture_status_none: Alinea @@ -218,13 +212,8 @@ es: ssn: Necesitamos tu número de Seguro Social para validar tu nombre, fecha de nacimiento y dirección. tag: Recomendado - take_picture: Use la cámara en su teléfono móvil y cargue imágenes de su - identificación. Solo usamos las imágenes para verificar su identidad. upload: Recopilaremos información sobre usted leyendo su documento de identidad expedido por el estado. - upload_computer_link: Sube desde tu computadora - upload_from_computer: '¿No tiene un teléfono?' - upload_from_phone: Sube imágenes directamente desde la cámara de tu teléfono verify_identity: Le preguntaremos sus datos personales para verificar su identidad comparándola con los registros públicos. welcome_html: '%{sp_name} necesita asegurarse de que es usted y no es alguien @@ -241,9 +230,6 @@ es: escritorio y siga las instrucciones para verificar su identidad. learn_more: Obtenga más información sobre nuestras medidas de privacidad y seguridad privacy: Nuestras normas de privacidad y seguridad - send_sms: Le enviaremos un mensaje de texto a su dispositivo con un enlace. Siga - ese enlace a su navegador para tomar fotografías de la parte delantera y - trasera de su identificación. switch_back: Regrese a su computadora para continuar con la verificación de su identidad. switch_back_image: Flecha que apunta del teléfono a la computadora diff --git a/config/locales/doc_auth/fr.yml b/config/locales/doc_auth/fr.yml index 6c7d9492db9..8b0b4c90aed 100644 --- a/config/locales/doc_auth/fr.yml +++ b/config/locales/doc_auth/fr.yml @@ -13,7 +13,6 @@ fr: take_picture: Prendre une photo take_picture_retry: Reprendre la photo upload_picture: Télécharger une photo - use_phone: Utilisez votre téléphone errors: alerts: barcode_content_check: Nous n’avons pas pu lire le code-barres au verso de votre @@ -158,12 +157,7 @@ fr: secure_account: Sécuriser votre compte ssn: Saisissez votre numéro de sécurité sociale ssn_update: Mettre à jour votre numéro de Sécurité Sociale - take_picture: Prendre une photo avec un téléphone text_message: Nous avons envoyé un message à votre téléphone - upload: Comment souhaitez-vous télécharger votre carte d’identité délivrée par - l’État? - upload_from_phone: Prenez une photo avec un téléphone portable pour télécharger - votre pièce d’identité verify_identity: Vérifier votre identité welcome: Commencez à vérifier votre identité hybrid_flow_warning: @@ -181,7 +175,6 @@ fr: address_guidance_puerto_rico_html: Pour les résidents de Porto Rico:

Veuillez indiquer l’urbanisation ou la copropriété à la ligne 2 de votre adresse. - camera_required: Votre téléphone portable doit avoir une caméra et un navigateur Web. capture_status_big_document: Trop près capture_status_capturing: Prendre la photo capture_status_none: Alignez @@ -226,15 +219,8 @@ fr: ssn: Nous avons besoin de votre numéro de sécurité sociale pour vérifier votre nom, date de naissance et adresse. tag: Recommandation - take_picture: Utilisez l’appareil photo sur votre téléphone portable et - téléchargez des images de votre identifiant. Nous utilisons uniquement - les images pour vérifier votre identité. upload: Nous recueillons des informations sur vous en lisant votre carte d’identité délivrée par l’État. - upload_computer_link: Téléchargez depuis votre ordinateur - upload_from_computer: Vous n’avez pas de téléphone? - upload_from_phone: Téléchargez des images directement depuis l’appareil photo de - votre téléphone verify_identity: Nous vous demanderons vos informations personnelles afin de vérifier votre identité par rapport aux registres publics. welcome_html: '%{sp_name} doit s’assurer que vous êtes bien vous, et non @@ -251,9 +237,6 @@ fr: suivez les instructions pour vérifier votre identité. learn_more: En savoir plus sur nos mesures de confidentialité et de sécurité privacy: Nos normes de confidentialité et de sécurité - send_sms: Nous enverrons un message texte à votre appareil avec un lien. Suivez - ce lien vers votre navigateur pour prendre des photos du recto et du - verso de votre identifiant. switch_back: Retournez sur votre ordinateur pour continuer à vérifier votre identité. switch_back_image: Flèche pointant du téléphone vers l’ordinateur test_ssn: Dans l’environnement de test seuls les SSN commençant par “900-” ou diff --git a/config/locales/titles/en.yml b/config/locales/titles/en.yml index 2d898e0715e..69b0502a0ca 100644 --- a/config/locales/titles/en.yml +++ b/config/locales/titles/en.yml @@ -16,7 +16,6 @@ en: processing_images: Processing your images ssn: Enter your Social Security number switch_back: Switch back to your computer - take_photo: Take photos of your ID with a phone upload: Verify your ID verify: Verify your identity edit_info: diff --git a/config/locales/titles/es.yml b/config/locales/titles/es.yml index 27a3c09aa19..d16b719cb1e 100644 --- a/config/locales/titles/es.yml +++ b/config/locales/titles/es.yml @@ -16,7 +16,6 @@ es: processing_images: Procesando tus imágenes ssn: Ingresa tu número del seguro social switch_back: Regresar a tu computadora - take_photo: Toma fotos de tu identificación con un teléfono upload: Verifica tu identificación verify: Verifica tu identidad edit_info: diff --git a/config/locales/titles/fr.yml b/config/locales/titles/fr.yml index 0718e36a78d..086c69e29eb 100644 --- a/config/locales/titles/fr.yml +++ b/config/locales/titles/fr.yml @@ -16,7 +16,6 @@ fr: processing_images: Traitement de vos images ssn: Entrez votre numéro de sécurité sociale switch_back: Retournez sur votre ordinateur - take_photo: Prenez des photos de votre pièce d’identité avec un téléphone upload: Vérifiez votre pièce d’identité verify: Vérifiez votre identité edit_info: diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 3b100b9cb70..b0af1c63604 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -157,7 +157,6 @@ def self.build_store(config_map) config.add(:doc_auth_attempt_window_in_minutes, type: :integer) config.add(:doc_auth_client_glare_threshold, type: :integer) config.add(:doc_auth_client_sharpness_threshold, type: :integer) - config.add(:doc_auth_combined_hybrid_handoff_enabled, type: :boolean) config.add(:doc_auth_document_capture_controller_enabled, type: :boolean) config.add(:doc_auth_enable_presigned_s3_urls, type: :boolean) config.add(:doc_auth_error_dpi_threshold, type: :integer) diff --git a/spec/controllers/idv/doc_auth_controller_spec.rb b/spec/controllers/idv/doc_auth_controller_spec.rb index 7170c1abfd5..552020d5227 100644 --- a/spec/controllers/idv/doc_auth_controller_spec.rb +++ b/spec/controllers/idv/doc_auth_controller_spec.rb @@ -454,7 +454,6 @@ def mock_document_capture_step receive(:flow_session).and_return( 'document_capture_session_uuid' => document_capture_session_uuid, 'Idv::Steps::WelcomeStep' => true, - 'Idv::Steps::SendLinkStep' => true, 'Idv::Steps::LinkSentStep' => true, 'Idv::Steps::EmailSentStep' => true, 'Idv::Steps::UploadStep' => true, diff --git a/spec/features/idv/actions/cancel_link_sent_action_spec.rb b/spec/features/idv/actions/cancel_link_sent_action_spec.rb index 8b6b1d80398..88b9ec4dd04 100644 --- a/spec/features/idv/actions/cancel_link_sent_action_spec.rb +++ b/spec/features/idv/actions/cancel_link_sent_action_spec.rb @@ -9,9 +9,9 @@ complete_doc_auth_steps_before_link_sent_step end - it 'returns to send link step' do + it 'returns to link sent step', js: true do click_doc_auth_back_link - expect(page).to have_current_path(idv_doc_auth_send_link_step) + expect(page).to have_current_path(idv_doc_auth_upload_step) end end diff --git a/spec/features/idv/actions/cancel_send_link_action_spec.rb b/spec/features/idv/actions/cancel_send_link_action_spec.rb deleted file mode 100644 index 82bd3e79bf4..00000000000 --- a/spec/features/idv/actions/cancel_send_link_action_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'rails_helper' - -feature 'doc auth cancel send link action' do - include IdvStepHelper - include DocAuthHelper - - before do - sign_in_and_2fa_user - complete_doc_auth_steps_before_send_link_step - end - - it 'returns to upload step' do - click_doc_auth_back_link - - expect(page).to have_current_path(idv_doc_auth_upload_step) - end -end diff --git a/spec/features/idv/doc_auth/agreement_step_spec.rb b/spec/features/idv/doc_auth/agreement_step_spec.rb index 4a1ff8ce46b..5846655fc07 100644 --- a/spec/features/idv/doc_auth/agreement_step_spec.rb +++ b/spec/features/idv/doc_auth/agreement_step_spec.rb @@ -62,8 +62,7 @@ def expect_doc_auth_first_step sign_in_and_2fa_user complete_doc_auth_steps_before_agreement_step - check t('doc_auth.instructions.consent', app_name: APP_NAME) - click_continue + complete_agreement_step end it 'progresses to document capture' do diff --git a/spec/features/idv/doc_auth/link_sent_step_spec.rb b/spec/features/idv/doc_auth/link_sent_step_spec.rb index 157a3ef8fe1..b87e2b3ce35 100644 --- a/spec/features/idv/doc_auth/link_sent_step_spec.rb +++ b/spec/features/idv/doc_auth/link_sent_step_spec.rb @@ -5,128 +5,12 @@ include DocAuthHelper include DocCaptureHelper - context 'with combined upload step disabled' do - let(:user) { sign_in_and_2fa_user } - let(:doc_capture_polling_enabled) { false } - - before do - allow(FeatureManagement).to receive(:doc_capture_polling_enabled?). - and_return(doc_capture_polling_enabled) - user - complete_doc_auth_steps_before_link_sent_step - end - - it 'proceeds to the next page with valid info' do - expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) - - mock_doc_captured(user.id) - click_idv_continue - - expect(page).to have_current_path(idv_ssn_path) - end - - it 'proceeds to the next page if the user does not have a phone' do - user = create(:user, :with_authentication_app, :with_piv_or_cac) - sign_in_and_2fa_user(user) - complete_doc_auth_steps_before_link_sent_step - mock_doc_captured(user.id) - click_idv_continue - - expect(page).to have_current_path(idv_ssn_path) - end - - it 'does not proceed to the next page if the capture flow is incomplete' do - click_idv_continue - - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - end - - it 'does not proceed to the next page if the capture flow is unsuccessful' do - mock_doc_captured(user.id, DocAuth::Response.new(success: false)) - - click_idv_continue - - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - end - - context 'cancelled' do - before do - document_capture_session = user.document_capture_sessions.last - document_capture_session.cancelled_at = Time.zone.now - document_capture_session.save! - end - - it 'redirects to before hybrid flow started and shows alert text' do - click_idv_continue - - expect(page).to have_current_path(idv_doc_auth_upload_step) - expect(page).to have_css( - '.usa-alert--error', - text: t('errors.doc_auth.document_capture_cancelled'), - ) - end - end - - shared_examples 'with doc capture polling enabled' do - metadata[:js] = true - let(:doc_capture_polling_enabled) { true } - - it 'automatically advances when the mobile flow is complete' do - expect(page).to_not have_css 'meta[http-equiv="refresh"]', visible: false - expect(page).to_not have_button(t('forms.buttons.continue')) - expect(page).to_not have_content(t('doc_auth.info.link_sent_complete_no_polling')) - expect(page).to have_content(t('doc_auth.info.link_sent_complete_polling')) - - mock_doc_captured(user.id) - - expect(page).to have_content(t('doc_auth.headings.ssn'), wait: 6) - expect(page).to have_current_path(idv_ssn_path) - end - end - - shared_examples 'with doc capture polling disabled' do - let(:doc_capture_polling_enabled) { false } - - context 'clicks back link' do - before do - click_doc_auth_back_link - - visit idv_doc_auth_link_sent_step - end - - it 'redirects to send link step' do - expect(page).to have_current_path(idv_doc_auth_send_link_step) - end - end - - it 'refreshes page 4x with meta refresh extending timeout by 40 min and can start over' do - 4.times do - expect(page).to have_css 'meta[http-equiv="refresh"]', visible: false - visit idv_doc_auth_link_sent_step - end - expect(page).to_not have_css 'meta[http-equiv="refresh"]', visible: false - - click_doc_auth_back_link - click_doc_auth_back_link - click_link t('links.cancel') - click_on t('idv.cancel.actions.start_over') - complete_doc_auth_steps_before_link_sent_step - expect(page).to have_css 'meta[http-equiv="refresh"]', visible: false - end - end - - it_behaves_like 'with doc capture polling enabled' - it_behaves_like 'with doc capture polling disabled' - end - context 'with combined upload step enabled', js: true do let(:user) { sign_in_and_2fa_user } let(:doc_capture_polling_enabled) { false } let(:phone_number) { '415-555-0199' } before do - allow(IdentityConfig.store). - to(receive(:doc_auth_combined_hybrid_handoff_enabled).and_return(true)) allow(FeatureManagement). to(receive(:doc_capture_polling_enabled?).and_return(doc_capture_polling_enabled)) user diff --git a/spec/features/idv/doc_auth/send_link_step_spec.rb b/spec/features/idv/doc_auth/send_link_step_spec.rb deleted file mode 100644 index e6d6f04df58..00000000000 --- a/spec/features/idv/doc_auth/send_link_step_spec.rb +++ /dev/null @@ -1,212 +0,0 @@ -require 'rails_helper' - -feature 'doc auth send link step' do - include IdvStepHelper - include DocAuthHelper - include ActionView::Helpers::DateHelper - - before do - sign_in_and_2fa_user(user) - complete_doc_auth_steps_before_send_link_step - end - - let(:idv_send_link_max_attempts) { IdentityConfig.store.idv_send_link_max_attempts } - let(:idv_send_link_attempt_window_in_minutes) do - IdentityConfig.store.idv_send_link_attempt_window_in_minutes - end - let(:document_capture_session) { DocumentCaptureSession.create! } - let(:fake_analytics) { FakeAnalytics.new } - let(:fake_attempts_tracker) { IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new } - let(:user) { user_with_2fa } - - it "defaults phone to user's 2fa phone numebr" do - field = page.find_field(t('two_factor_authentication.phone_label')) - expect(field.value).to eq('+1 202-555-1212') - end - - it 'proceeds to the next page with valid info' do - expect_any_instance_of(IrsAttemptsApi::Tracker).to receive(:track_event).with( - :idv_phone_upload_link_sent, - success: true, - phone_number: '+1 415-555-0199', - failure_reason: nil, - ) - expect(Telephony).to receive(:send_doc_auth_link). - with(hash_including(to: '+1 415-555-0199')). - and_call_original - - expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) - - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue - - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - end - - it 'sends a link that does not contain any underscores' do - # because URLs with underscores sometimes get messed up by carriers - expect(Telephony).to receive(:send_doc_auth_link).and_wrap_original do |impl, config| - expect(config[:link]).to_not include('_') - - impl.call(**config) - end - expect_any_instance_of(IrsAttemptsApi::Tracker).to receive(:track_event).with( - :idv_phone_upload_link_sent, - success: true, - phone_number: '+1 415-555-0199', - failure_reason: nil, - ) - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue - - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - end - - it 'does not proceed to the next page with invalid info' do - fill_in :doc_auth_phone, with: '' - click_idv_continue - - expect(page).to have_current_path(idv_doc_auth_send_link_step) - end - - it 'does not proceed if Telephony raises an error' do - expect_any_instance_of(IrsAttemptsApi::Tracker).to receive(:track_event).with( - :idv_phone_upload_link_sent, - success: false, - phone_number: '+1 225-555-1000', - failure_reason: { telephony: ['TelephonyError'] }, - ) - fill_in :doc_auth_phone, with: '225-555-1000' - click_idv_continue - - expect(page).to have_current_path(idv_doc_auth_send_link_step) - expect(page).to have_content I18n.t('telephony.error.friendly_message.generic') - end - - it 'displays error if user selects a country to which we cannot send SMS', js: true do - page.find('div[aria-label="Country code"]').click - within(page.find('.iti__flag-container', visible: :all)) do - find('span', text: 'Sri Lanka').click - end - focused_input = page.find('.phone-input__number:focus') - - error_message_id = focused_input[:'aria-describedby']&.split(' ')&.find do |id| - page.has_css?(".usa-error-message##{id}") - end - expect(error_message_id).to_not be_empty - - error_message = page.find_by_id(error_message_id) - expect(error_message).to have_content( - t( - 'two_factor_authentication.otp_delivery_preference.sms_unsupported', - location: 'Sri Lanka', - ), - ) - click_continue - expect(page.find(':focus')).to match_css('.phone-input__number') - end - - it 'throttles sending the link' do - allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics) - allow_any_instance_of(ApplicationController).to receive( - :irs_attempts_api_tracker, - ).and_return(fake_attempts_tracker) - - user = user_with_2fa - sign_in_and_2fa_user(user) - complete_doc_auth_steps_before_send_link_step - timeout = distance_of_time_in_words( - Throttle.attempt_window_in_minutes(:idv_send_link).minutes, - ) - - expect(fake_attempts_tracker).to receive( - :idv_phone_send_link_rate_limited, - ).with({ phone_number: '+1 415-555-0199' }) - - freeze_time do - (idv_send_link_max_attempts - 1).times do - expect(page).to_not have_content( - I18n.t('errors.doc_auth.send_link_throttle', timeout: timeout), - ) - - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue - - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - click_doc_auth_back_link - end - - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue - expect(page).to have_current_path(idv_doc_auth_send_link_step) - expect(page).to have_content(I18n.t('errors.doc_auth.send_link_throttle', timeout: timeout)) - end - expect(fake_analytics).to have_logged_event( - 'Throttler Rate Limit Triggered', - throttle_type: :idv_send_link, - ) - - # Manual expiration is needed for now since the Throttle uses Redis ttl instead of expiretime - Throttle.new(throttle_type: :idv_send_link, user: user).reset! - travel_to(Time.zone.now + idv_send_link_attempt_window_in_minutes.minutes) do - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - end - end - - it 'includes expected URL parameters' do - allow_any_instance_of(Flow::BaseFlow).to receive(:flow_session).and_return( - document_capture_session_uuid: document_capture_session.uuid, - ) - expect_any_instance_of(IrsAttemptsApi::Tracker).to receive(:track_event).with( - :idv_phone_upload_link_sent, - success: true, - phone_number: '+1 415-555-0199', - failure_reason: nil, - ) - expect(Telephony).to receive(:send_doc_auth_link).and_wrap_original do |impl, config| - params = Rack::Utils.parse_nested_query URI(config[:link]).query - expect(params).to eq('document-capture-session' => document_capture_session.uuid) - - impl.call(**config) - end - - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue - end - - it 'sets requested_at on the capture session' do - allow_any_instance_of(Flow::BaseFlow).to receive(:flow_session).and_return( - document_capture_session_uuid: document_capture_session.uuid, - ) - - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue - - document_capture_session.reload - expect(document_capture_session).to have_attributes(requested_at: a_kind_of(Time)) - end - - context 'when user is from Puerto Rico' do - let(:phone) { '+1 787-555-1212' } - let(:formatted_phone) { '(787) 555-1212' } - let(:user) do - create( - :user, - :signed_up, - with: { phone: phone }, - password: Features::SessionHelper::VALID_PASSWORD, - ) - end - - it "defaults phone to user's 2fa phone number", :js do - field = page.find_field(t('two_factor_authentication.phone_label')) - expect(field.value).to eq(formatted_phone) - end - it "allows submitting to user's 2fa phone number", :js do - click_idv_continue - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - end - end -end diff --git a/spec/features/idv/doc_auth/upload_step_spec.rb b/spec/features/idv/doc_auth/upload_step_spec.rb index 47f00985e9a..45034434ac0 100644 --- a/spec/features/idv/doc_auth/upload_step_spec.rb +++ b/spec/features/idv/doc_auth/upload_step_spec.rb @@ -5,279 +5,227 @@ include DocAuthHelper include ActionView::Helpers::DateHelper - context 'with combined hybrid handoff disabled', js: true do - let(:fake_analytics) { FakeAnalytics.new } - let(:fake_attempts_tracker) { IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new } + let(:fake_analytics) { FakeAnalytics.new } + let(:fake_attempts_tracker) { IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new } + let(:document_capture_session) { DocumentCaptureSession.create! } + let(:idv_send_link_max_attempts) { 3 } + let(:idv_send_link_attempt_window_in_minutes) do + IdentityConfig.store.idv_send_link_attempt_window_in_minutes + end + + before do + sign_in_and_2fa_user + allow_any_instance_of(Idv::Steps::UploadStep).to receive(:mobile_device?).and_return(true) + complete_doc_auth_steps_before_upload_step + allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics) + allow_any_instance_of(ApplicationController).to receive(:irs_attempts_api_tracker). + and_return(fake_attempts_tracker) + end + context 'on a desktop device', js: true do before do - allow(IdentityConfig.store). - to receive(:doc_auth_combined_hybrid_handoff_enabled). - and_return(false) - sign_in_and_2fa_user - allow_any_instance_of(Idv::Steps::UploadStep).to receive(:mobile_device?).and_return(true) - complete_doc_auth_steps_before_upload_step - allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics) - allow_any_instance_of(ApplicationController).to receive(:irs_attempts_api_tracker). - and_return(fake_attempts_tracker) + allow_any_instance_of(Idv::Steps::UploadStep).to receive(:mobile_device?).and_return(false) end - context 'on a desktop device' do - before do - allow_any_instance_of(Idv::Steps::UploadStep).to receive(:mobile_device?).and_return(false) - end - - it 'proceeds to document capture when user chooses to upload from computer' do - expect(fake_attempts_tracker).to receive( - :idv_document_upload_method_selected, - ).with({ upload_method: 'desktop' }) - - expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) - - click_on t('doc_auth.info.upload_computer_link') + it 'displays with the expected content' do + expect(page).to have_content(t('doc_auth.headings.combined_upload_from_computer')) + expect(page).to have_content(t('doc_auth.info.combined_upload_from_computer')) + expect(page).to have_content(t('doc_auth.headings.combined_upload_from_phone')) + end - expect(page).to have_current_path(idv_doc_auth_document_capture_step) - expect(fake_analytics).to have_logged_event( - 'IdV: doc auth upload submitted', - hash_including(step: 'upload', destination: :document_capture), - ) - end + it 'proceeds to document capture when user chooses to upload from computer' do + expect(fake_attempts_tracker).to receive( + :idv_document_upload_method_selected, + ).with({ upload_method: 'desktop' }) - it 'proceeds to send link to phone page when user chooses to use phone' do - expect(fake_attempts_tracker).to receive( - :idv_document_upload_method_selected, - ).with({ upload_method: 'mobile' }) + expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) - click_on t('doc_auth.buttons.use_phone') + click_upload_from_computer - expect(page).to have_current_path(idv_doc_auth_send_link_step) - expect(fake_analytics).to have_logged_event( - 'IdV: doc auth upload submitted', - hash_including(step: 'upload', destination: :send_link), - ) - end + expect(page).to have_current_path(idv_doc_auth_document_capture_step) + expect(fake_analytics).to have_logged_event( + 'IdV: doc auth upload submitted', + hash_including(step: 'upload', destination: :document_capture), + ) end - end - context 'with combined hybrid handoff enabled' do - let(:fake_analytics) { FakeAnalytics.new } - let(:fake_attempts_tracker) { IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new } - let(:document_capture_session) { DocumentCaptureSession.create! } - let(:idv_send_link_max_attempts) { 3 } - let(:idv_send_link_attempt_window_in_minutes) do - IdentityConfig.store.idv_send_link_attempt_window_in_minutes + it "defaults phone to user's 2fa phone number" do + field = page.find_field(t('two_factor_authentication.phone_label')) + expect(field.value).to eq('(202) 555-1212') end - before do - allow(IdentityConfig.store). - to receive(:doc_auth_combined_hybrid_handoff_enabled). - and_return(true) - sign_in_and_2fa_user - allow_any_instance_of(Idv::Steps::UploadStep).to receive(:mobile_device?).and_return(true) - complete_doc_auth_steps_before_upload_step - allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics) - allow_any_instance_of(ApplicationController).to receive(:irs_attempts_api_tracker). - and_return(fake_attempts_tracker) + it 'proceeds to link sent page when user chooses to use phone' do + expect(fake_attempts_tracker).to receive( + :idv_document_upload_method_selected, + ).with({ upload_method: 'mobile' }) + + click_send_link + + expect(page).to have_current_path(idv_doc_auth_link_sent_step) + expect(fake_analytics).to have_logged_event( + 'IdV: doc auth upload submitted', + hash_including(step: 'upload', destination: :link_sent), + ) end - context 'on a desktop device', js: true do - before do - allow_any_instance_of(Idv::Steps::UploadStep).to receive(:mobile_device?).and_return(false) - end + it 'proceeds to the next page with valid info' do + expect(fake_attempts_tracker).to receive( + :idv_phone_upload_link_sent, + ).with( + success: true, + phone_number: '+1 415-555-0199', + failure_reason: nil, + ) - it 'proceeds to document capture when user chooses to upload from computer' do - expect(fake_attempts_tracker).to receive( - :idv_document_upload_method_selected, - ).with({ upload_method: 'desktop' }) + expect(Telephony).to receive(:send_doc_auth_link). + with(hash_including(to: '+1 415-555-0199')). + and_call_original - expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) + expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) - click_upload_from_computer + fill_in :doc_auth_phone, with: '415-555-0199' + click_send_link - expect(page).to have_current_path(idv_doc_auth_document_capture_step) - expect(fake_analytics).to have_logged_event( - 'IdV: doc auth upload submitted', - hash_including(step: 'upload', destination: :document_capture), - ) - end + expect(page).to have_current_path(idv_doc_auth_link_sent_step) + end - it "defaults phone to user's 2fa phone number" do - field = page.find_field(t('two_factor_authentication.phone_label')) - expect(field.value).to eq('(202) 555-1212') - end + it 'does not proceed to the next page with invalid info' do + fill_in :doc_auth_phone, with: '' + click_send_link - it 'proceeds to link sent page when user chooses to use phone' do - expect(fake_attempts_tracker).to receive( - :idv_document_upload_method_selected, - ).with({ upload_method: 'mobile' }) + expect(page).to have_current_path(idv_doc_auth_upload_step, ignore_query: true) + end - click_send_link + it 'sends a link that does not contain any underscores' do + # because URLs with underscores sometimes get messed up by carriers + expect(Telephony).to receive(:send_doc_auth_link).and_wrap_original do |impl, config| + expect(config[:link]).to_not include('_') - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - expect(fake_analytics).to have_logged_event( - 'IdV: doc auth upload submitted', - hash_including(step: 'upload', destination: :link_sent), - ) + impl.call(**config) end - it 'proceeds to the next page with valid info' do - expect(fake_attempts_tracker).to receive( - :idv_phone_upload_link_sent, - ).with( - success: true, - phone_number: '+1 415-555-0199', - failure_reason: nil, - ) + fill_in :doc_auth_phone, with: '415-555-0199' + click_send_link - expect(Telephony).to receive(:send_doc_auth_link). - with(hash_including(to: '+1 415-555-0199')). - and_call_original + expect(page).to have_current_path(idv_doc_auth_link_sent_step) + end - expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) + it 'does not proceed if Telephony raises an error', js: true do + expect(fake_attempts_tracker).to receive(:idv_phone_upload_link_sent).with( + success: false, + phone_number: '+1 225-555-1000', + failure_reason: { telephony: ['TelephonyError'] }, + ) + fill_in :doc_auth_phone, with: '225-555-1000' + click_send_link + + expect(page).to have_current_path(idv_doc_auth_upload_step, ignore_query: true) + expect(page).to have_content I18n.t('telephony.error.friendly_message.generic') + end - fill_in :doc_auth_phone, with: '415-555-0199' - click_send_link + it 'displays error if user selects a country to which we cannot send SMS', js: true do + page.find('div[aria-label="Country code"]').click + within(page.find('.iti__flag-container', visible: :all)) do + find('span', text: 'Sri Lanka').click + end + focused_input = page.find('.phone-input__number:focus') - expect(page).to have_current_path(idv_doc_auth_link_sent_step) + error_message_id = focused_input[:'aria-describedby']&.split(' ')&.find do |id| + page.has_css?(".usa-error-message##{id}") end + expect(error_message_id).to_not be_empty + + error_message = page.find_by_id(error_message_id) + expect(error_message).to have_content( + t( + 'two_factor_authentication.otp_delivery_preference.sms_unsupported', + location: 'Sri Lanka', + ), + ) + click_send_link + expect(page.find(':focus')).to match_css('.phone-input__number') + end - it 'does not proceed to the next page with invalid info' do - fill_in :doc_auth_phone, with: '' - click_send_link + it 'throttles sending the link', js: true do + user = user_with_2fa + sign_in_and_2fa_user(user) + complete_doc_auth_steps_before_upload_step + timeout = distance_of_time_in_words( + Throttle.attempt_window_in_minutes(:idv_send_link).minutes, + ) + allow(IdentityConfig.store).to receive(:idv_send_link_max_attempts). + and_return(idv_send_link_max_attempts) + + expect(fake_attempts_tracker).to receive( + :idv_phone_send_link_rate_limited, + ).with({ phone_number: '+1 415-555-0199' }) + + freeze_time do + (idv_send_link_max_attempts - 1).times do + expect(page).to_not have_content( + I18n.t('errors.doc_auth.send_link_throttle', timeout: timeout), + ) - expect(page).to have_current_path(idv_doc_auth_upload_step, ignore_query: true) - end + fill_in :doc_auth_phone, with: '415-555-0199' + click_send_link - it 'sends a link that does not contain any underscores' do - # because URLs with underscores sometimes get messed up by carriers - expect(Telephony).to receive(:send_doc_auth_link).and_wrap_original do |impl, config| - expect(config[:link]).to_not include('_') + expect(page).to have_current_path(idv_doc_auth_link_sent_step) - impl.call(**config) + click_doc_auth_back_link end fill_in :doc_auth_phone, with: '415-555-0199' - click_send_link - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - end - - it 'does not proceed if Telephony raises an error', js: true do - expect(fake_attempts_tracker).to receive(:idv_phone_upload_link_sent).with( - success: false, - phone_number: '+1 225-555-1000', - failure_reason: { telephony: ['TelephonyError'] }, - ) - fill_in :doc_auth_phone, with: '225-555-1000' click_send_link - expect(page).to have_current_path(idv_doc_auth_upload_step, ignore_query: true) - expect(page).to have_content I18n.t('telephony.error.friendly_message.generic') - end - - it 'displays error if user selects a country to which we cannot send SMS', js: true do - page.find('div[aria-label="Country code"]').click - within(page.find('.iti__flag-container', visible: :all)) do - find('span', text: 'Sri Lanka').click - end - focused_input = page.find('.phone-input__number:focus') - - error_message_id = focused_input[:'aria-describedby']&.split(' ')&.find do |id| - page.has_css?(".usa-error-message##{id}") - end - expect(error_message_id).to_not be_empty - - error_message = page.find_by_id(error_message_id) - expect(error_message).to have_content( - t( - 'two_factor_authentication.otp_delivery_preference.sms_unsupported', - location: 'Sri Lanka', + expect(page).to have_content( + I18n.t( + 'errors.doc_auth.send_link_throttle', + timeout: timeout, ), ) + end + expect(fake_analytics).to have_logged_event( + 'Throttler Rate Limit Triggered', + throttle_type: :idv_send_link, + ) + + # Manual expiration is needed for now since the Throttle uses + # Redis ttl instead of expiretime + Throttle.new(throttle_type: :idv_send_link, user: user).reset! + travel_to(Time.zone.now + idv_send_link_attempt_window_in_minutes.minutes) do + fill_in :doc_auth_phone, with: '415-555-0199' click_send_link - expect(page.find(':focus')).to match_css('.phone-input__number') + expect(page).to have_current_path(idv_doc_auth_link_sent_step) end + end - it 'throttles sending the link', js: true do - user = user_with_2fa - sign_in_and_2fa_user(user) - complete_doc_auth_steps_before_upload_step - timeout = distance_of_time_in_words( - Throttle.attempt_window_in_minutes(:idv_send_link).minutes, - ) - allow(IdentityConfig.store).to receive(:idv_send_link_max_attempts). - and_return(idv_send_link_max_attempts) - - expect(fake_attempts_tracker).to receive( - :idv_phone_send_link_rate_limited, - ).with({ phone_number: '+1 415-555-0199' }) - - freeze_time do - (idv_send_link_max_attempts - 1).times do - expect(page).to_not have_content( - I18n.t('errors.doc_auth.send_link_throttle', timeout: timeout), - ) - - fill_in :doc_auth_phone, with: '415-555-0199' - click_send_link - - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - - click_doc_auth_back_link - end - - fill_in :doc_auth_phone, with: '415-555-0199' + it 'includes expected URL parameters' do + allow_any_instance_of(Flow::BaseFlow).to receive(:flow_session).and_return( + document_capture_session_uuid: document_capture_session.uuid, + ) - click_send_link - expect(page).to have_current_path(idv_doc_auth_upload_step, ignore_query: true) - expect(page).to have_content( - I18n.t( - 'errors.doc_auth.send_link_throttle', - timeout: timeout, - ), - ) - end - expect(fake_analytics).to have_logged_event( - 'Throttler Rate Limit Triggered', - throttle_type: :idv_send_link, - ) + expect(Telephony).to receive(:send_doc_auth_link).and_wrap_original do |impl, config| + params = Rack::Utils.parse_nested_query URI(config[:link]).query + expect(params).to eq('document-capture-session' => document_capture_session.uuid) - # Manual expiration is needed for now since the Throttle uses - # Redis ttl instead of expiretime - Throttle.new(throttle_type: :idv_send_link, user: user).reset! - travel_to(Time.zone.now + idv_send_link_attempt_window_in_minutes.minutes) do - fill_in :doc_auth_phone, with: '415-555-0199' - click_send_link - expect(page).to have_current_path(idv_doc_auth_link_sent_step) - end + impl.call(**config) end - it 'includes expected URL parameters' do - allow_any_instance_of(Flow::BaseFlow).to receive(:flow_session).and_return( - document_capture_session_uuid: document_capture_session.uuid, - ) - - expect(Telephony).to receive(:send_doc_auth_link).and_wrap_original do |impl, config| - params = Rack::Utils.parse_nested_query URI(config[:link]).query - expect(params).to eq('document-capture-session' => document_capture_session.uuid) - - impl.call(**config) - end - - fill_in :doc_auth_phone, with: '415-555-0199' - click_send_link - end + fill_in :doc_auth_phone, with: '415-555-0199' + click_send_link + end - it 'sets requested_at on the capture session' do - allow_any_instance_of(Flow::BaseFlow).to receive(:flow_session).and_return( - document_capture_session_uuid: document_capture_session.uuid, - ) + it 'sets requested_at on the capture session' do + allow_any_instance_of(Flow::BaseFlow).to receive(:flow_session).and_return( + document_capture_session_uuid: document_capture_session.uuid, + ) - fill_in :doc_auth_phone, with: '415-555-0199' - click_send_link + fill_in :doc_auth_phone, with: '415-555-0199' + click_send_link - document_capture_session.reload - expect(document_capture_session).to have_attributes(requested_at: a_kind_of(Time)) - end + document_capture_session.reload + expect(document_capture_session).to have_attributes(requested_at: a_kind_of(Time)) end end end diff --git a/spec/features/idv/hybrid_flow_spec.rb b/spec/features/idv/hybrid_flow_spec.rb index a1e2049191c..e1f5b6638f4 100644 --- a/spec/features/idv/hybrid_flow_spec.rb +++ b/spec/features/idv/hybrid_flow_spec.rb @@ -4,6 +4,8 @@ include IdvHelper include DocAuthHelper + let(:phone_number) { '415-555-0199' } + before do allow(FeatureManagement).to receive(:doc_capture_polling_enabled?).and_return(true) allow(IdentityConfig.store).to receive(:doc_auth_enable_presigned_s3_urls).and_return(true) @@ -23,9 +25,9 @@ perform_in_browser(:desktop) do user = sign_in_and_2fa_user - complete_doc_auth_steps_before_send_link_step - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue + complete_doc_auth_steps_before_upload_step + clear_and_fill_in(:doc_auth_phone, phone_number) + click_send_link expect(page).to have_content(t('doc_auth.headings.text_message')) end @@ -66,9 +68,9 @@ perform_in_browser(:desktop) do user = sign_in_and_2fa_user - complete_doc_auth_steps_before_send_link_step - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue + complete_doc_auth_steps_before_upload_step + clear_and_fill_in(:doc_auth_phone, phone_number) + click_send_link expect(page).to have_content(t('doc_auth.headings.text_message')) end @@ -83,9 +85,8 @@ perform_in_browser(:desktop) do expect(page).to_not have_content(t('doc_auth.headings.text_message'), wait: 10) - click_on t('doc_auth.buttons.use_phone') - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue + clear_and_fill_in(:doc_auth_phone, phone_number) + click_send_link expect(page).to have_content(t('doc_auth.headings.text_message')) end diff --git a/spec/features/idv/in_person_spec.rb b/spec/features/idv/in_person_spec.rb index 4b5af8607eb..decca7926fd 100644 --- a/spec/features/idv/in_person_spec.rb +++ b/spec/features/idv/in_person_spec.rb @@ -321,12 +321,12 @@ it 'resumes desktop session with in-person proofing', allow_browser_log: true do user = nil - + phone_number = '415-555-0199' perform_in_browser(:desktop) do user = sign_in_and_2fa_user - complete_doc_auth_steps_before_send_link_step - fill_in :doc_auth_phone, with: '415-555-0199' - click_idv_continue + complete_doc_auth_steps_before_upload_step + clear_and_fill_in(:doc_auth_phone, phone_number) + click_send_link expect(page).to have_content(t('doc_auth.headings.text_message')) end diff --git a/spec/services/idv/steps/send_link_step_spec.rb b/spec/services/idv/steps/send_link_step_spec.rb deleted file mode 100644 index dcf7b0bbed7..00000000000 --- a/spec/services/idv/steps/send_link_step_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -require 'rails_helper' - -describe Idv::Steps::SendLinkStep do - let(:user) { build(:user) } - - let(:service_provider) do - create( - :service_provider, - issuer: 'http://sp.example.com', - app_id: '123', - ) - end - - let(:request) do - double( - 'request', - remote_ip: Faker::Internet.ip_v4_address, - headers: { 'X-Amzn-Trace-Id' => amzn_trace_id }, - ) - end - - let(:params) do - ActionController::Parameters.new( - { - doc_auth: { phone: '(201) 555-1212' }, - }, - ) - end - - let(:controller) do - instance_double( - 'controller', - session: { sp: { issuer: service_provider.issuer } }, - params: params, - current_user: user, - current_sp: service_provider, - analytics: FakeAnalytics.new, - url_options: {}, - request: request, - ) - end - - let(:amzn_trace_id) { SecureRandom.uuid } - - let(:pii_from_doc) do - { - ssn: '123-45-6789', - first_name: 'bob', - } - end - - let(:flow) do - Idv::Flows::DocAuthFlow.new(controller, {}, 'idv/doc_auth').tap do |flow| - flow.flow_session = { pii_from_doc: pii_from_doc } - end - end - - let(:irs_attempts_api_tracker) do - IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new - end - - subject(:step) do - Idv::Steps::SendLinkStep.new(flow) - end - - before do - allow(controller).to receive(:irs_attempts_api_tracker). - and_return(irs_attempts_api_tracker) - end - - describe '#extra_view_variables' do - it 'includes form' do - expect(step.extra_view_variables).to include( - { - idv_phone_form: be_an_instance_of(Idv::PhoneForm), - }, - ) - end - end - - describe 'the return value from #call' do - let(:response) { step.call } - - it 'includes the telephony response' do - expect(response.extra[:telephony_response]).to eq( - { - errors: {}, - message_id: 'fake-message-id', - request_id: 'fake-message-request-id', - success: true, - }, - ) - end - end -end diff --git a/spec/services/idv/steps/upload_step_spec.rb b/spec/services/idv/steps/upload_step_spec.rb index 5d3beba11de..151d395acd2 100644 --- a/spec/services/idv/steps/upload_step_spec.rb +++ b/spec/services/idv/steps/upload_step_spec.rb @@ -61,15 +61,12 @@ end subject(:step) do - Idv::Steps::SendLinkStep.new(flow) + Idv::Steps::UploadStep.new(flow) end before do allow(controller).to receive(:irs_attempts_api_tracker). and_return(irs_attempts_api_tracker) - allow(IdentityConfig.store). - to receive(:doc_auth_combined_hybrid_handoff_enabled). - and_return(true) end describe '#extra_view_variables' do diff --git a/spec/support/features/doc_auth_helper.rb b/spec/support/features/doc_auth_helper.rb index f1e35464b2f..9b2f061cbfb 100644 --- a/spec/support/features/doc_auth_helper.rb +++ b/spec/support/features/doc_auth_helper.rb @@ -18,6 +18,11 @@ def session_from_completed_flow_steps(finished_step) session end + def clear_and_fill_in(field_name, text) + fill_in field_name, with: '' + fill_in field_name, with: text + end + def fill_out_ssn_form_with_ssn_that_fails_resolution fill_in t('idv.form.ssn_label_html'), with: SSN_THAT_FAILS_RESOLUTION end @@ -62,10 +67,6 @@ def idv_doc_auth_document_capture_step idv_doc_auth_step_path(step: :document_capture) end - def idv_doc_auth_send_link_step - idv_doc_auth_step_path(step: :send_link) - end - def idv_doc_auth_link_sent_step idv_doc_auth_step_path(step: :link_sent) end @@ -90,7 +91,11 @@ def complete_doc_auth_steps_before_agreement_step(expect_accessible: false) end def complete_agreement_step - find('label', text: t('doc_auth.instructions.consent', app_name: APP_NAME)).click + find( + 'label', + text: t('doc_auth.instructions.consent', app_name: APP_NAME), + wait: 5, + ).click click_on t('doc_auth.buttons.continue') end @@ -101,7 +106,7 @@ def complete_doc_auth_steps_before_upload_step(expect_accessible: false) end def complete_upload_step - click_on t('doc_auth.info.upload_computer_link') + click_on t('forms.buttons.upload_photos') end def complete_doc_auth_steps_before_document_capture_step(expect_accessible: false) @@ -126,7 +131,7 @@ def complete_document_capture_step_with_yml(proofing_yml) def complete_doc_auth_steps_before_email_sent_step allow(BrowserCache).to receive(:parse).and_return(mobile_device) complete_doc_auth_steps_before_upload_step - click_on t('doc_auth.info.upload_computer_link') + complete_upload_step end def complete_doc_auth_steps_before_phone_otp_step(expect_accessible: false) @@ -170,21 +175,9 @@ def complete_doc_auth_steps_before_address_step(expect_accessible: false) click_button t('idv.buttons.change_address_label') end - def complete_doc_auth_steps_before_send_link_step - complete_doc_auth_steps_before_upload_step - if IdentityConfig.store.doc_auth_combined_hybrid_handoff_enabled - click_on t('forms.buttons.send_link') - else - click_on t('doc_auth.buttons.use_phone') - end - end - def complete_doc_auth_steps_before_link_sent_step - complete_doc_auth_steps_before_send_link_step - if !IdentityConfig.store.doc_auth_combined_hybrid_handoff_enabled - fill_out_doc_auth_phone_form_ok - end - click_idv_continue + complete_doc_auth_steps_before_upload_step + click_send_link end def complete_all_doc_auth_steps(expect_accessible: false) diff --git a/spec/views/idv/doc_auth/upload.html.erb_spec.rb b/spec/views/idv/doc_auth/upload.html.erb_spec.rb deleted file mode 100644 index 0d04aa4c2bb..00000000000 --- a/spec/views/idv/doc_auth/upload.html.erb_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'rails_helper' - -describe 'idv/doc_auth/upload.html.erb' do - let(:flow_session) { {} } - let(:user_fully_authenticated) { true } - - before do - allow(view).to receive(:flow_session).and_return(flow_session) - allow(view).to receive(:user_fully_authenticated?).and_return(user_fully_authenticated) - allow(view).to receive(:url_for).and_return('https://www.example.com/') - allow(view).to receive(:user_signing_up?).and_return(false) - - render template: 'idv/doc_auth/upload' - end - - it 'renders the headings and info' do - expect(rendered).to have_content(t('doc_auth.headings.upload')) - expect(rendered).to have_content(t('doc_auth.info.upload')) - expect(rendered).to have_content(t('doc_auth.headings.upload_from_phone')) - end -end