<%= javascript_packs_tag_once('otp-delivery-preference') %>
diff --git a/app/views/users/verify_personal_key/new.html.erb b/app/views/users/verify_personal_key/new.html.erb
index 41b70507399..4929b1f3fb2 100644
--- a/app/views/users/verify_personal_key/new.html.erb
+++ b/app/views/users/verify_personal_key/new.html.erb
@@ -1,8 +1,12 @@
-<%= simple_form_for('', url: create_verify_personal_key_path, method: 'post') do |f| %>
-
-
- <%= t('forms.personal_key.title') %>
-
+<%= simple_form_for('', url: create_verify_personal_key_path, method: 'post', html: { class: 'margin-top-8' }) do |f| %>
+
+ <%= render AlertIconComponent.new(
+ icon_name: :personal_key,
+ class: 'alert-icon--centered-top',
+ ) %>
+
+ <%= render PageHeadingComponent.new.with_content(t('forms.personal_key.title')) %>
+
<%= t('forms.personal_key.instructions') %>
@@ -10,17 +14,15 @@
<%= render 'shared/personal_key_input', code: '', form: f %>
-
- <%= button_tag t('forms.buttons.continue'), type: 'submit', class: 'usa-button usa-button--wide' %>
-
+ <%= f.submit t('forms.buttons.continue'), class: 'display-block margin-y-5' %>
<% end %>
-
- <%= t('forms.personal_key.alternative') %>
- <%= button_to(
- reactivate_account_path, method: :put,
- class: 'usa-button usa-button--unstyled', form_class: 'display-inline-block padding-left-1'
- ) { t('links.reverify') } %>
-
+<%= t('forms.personal_key.alternative') %>
+<%= render ButtonComponent.new(
+ action: ->(**tag_options, &block) do
+ button_to(reactivate_account_path, method: :put, **tag_options, &block)
+ end,
+ unstyled: true,
+ ).with_content(t('links.reverify')) %>
<%= render 'shared/cancel', link: account_path %>
diff --git a/config/application.yml.default b/config/application.yml.default
index 788586fcf0a..4d730b64a56 100644
--- a/config/application.yml.default
+++ b/config/application.yml.default
@@ -71,7 +71,6 @@ 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
-doc_auth_ssn_controller_enabled: false
database_pool_extra_connections_for_worker: 4
database_pool_idp: 5
database_statement_timeout: 2_500
@@ -88,6 +87,7 @@ doc_auth_extend_timeout_by_minutes: 40
doc_capture_polling_enabled: true
doc_auth_client_glare_threshold: 50
doc_auth_client_sharpness_threshold: 50
+doc_auth_document_capture_controller_enabled: false
doc_auth_enable_presigned_s3_urls: false
doc_auth_s3_request_timeout: 5
doc_auth_error_dpi_threshold: 290
@@ -132,6 +132,7 @@ idv_send_link_attempt_window_in_minutes: 10
idv_send_link_max_attempts: 5
ie11_support_end_date: '2022-12-31'
idv_sp_required: false
+in_person_capture_secondary_id_enabled: false
in_person_cta_variant_testing_enabled: true
in_person_cta_variant_testing_percents: '{"B":100}'
in_person_email_reminder_early_benchmark_in_days: 11
@@ -143,11 +144,6 @@ in_person_results_delay_in_hours: 1
in_person_completion_survey_url: 'https://login.gov'
in_person_verify_info_controller_enabled: false
include_slo_in_saml_metadata: false
-inherited_proofing_enabled: false
-inherited_proofing_va_base_url: 'https://staging-api.va.gov'
-inherited_proofing_max_attempts: 2
-inherited_proofing_max_attempt_window_in_minutes: 1
-va_inherited_proofing_mock_enabled: false
irs_attempt_api_audience: 'https://irs.gov'
irs_attempt_api_auth_tokens: ''
irs_attempt_api_csp_id: 'LOGIN.gov'
@@ -159,6 +155,7 @@ irs_attempt_api_event_ttl_seconds: 86400
irs_attempt_api_event_count_default: 1000
irs_attempt_api_event_count_max: 10000
irs_attempt_api_payload_size_logging_enabled: true
+irs_attempt_api_track_tmx_fraud_check_event: false
key_pair_generation_percent: 0
logins_per_ip_track_only_mode: false
# LexisNexis #####################################################
@@ -333,6 +330,7 @@ usps_ipp_request_timeout: 10
usps_ipp_sponsor_id: ''
usps_ipp_username: ''
usps_mock_fallback: true
+usps_ipp_transliteration_enabled: false
get_usps_proofing_results_job_cron: '0/10 * * * *'
get_usps_proofing_results_job_reprocess_delay_minutes: 5
get_usps_proofing_results_job_request_delay_milliseconds: 1000
@@ -373,8 +371,6 @@ development:
hmac_fingerprinter_key_queue: '["11111111111111111111111111111111", "22222222222222222222222222222222"]'
identity_pki_local_dev: true
in_person_proofing_enabled: true
- inherited_proofing_enabled: true
- va_inherited_proofing_mock_enabled: true
irs_attempt_api_public_key: MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyut9Uio5XxsIUVrXARqCoHvcMVYT0p6WyU1BnbhxLRW4Q60p+4Bn32vVOt9nzeih7qvauYM5M0PZdKEmwOHflqPP+ABfKhL+6jxBhykN5P5UY375wTFBJZ20Fx8jOJbRhJD02oUQ49YKlDu3MG5Y0ApyD4ER4WKgxuB2OdyQKd9vg2ZZa+P2pw1HkFPEin0h8KBUFBeLGDZni8PIJdHBP6dA+xbayGBxSM/8xQC0JIg6KlGTcLql37QJIhP2oSv0nAJNb6idFPAz0uMCQDQWKKWV5FUDCsFVH7VuQz8xUCwnPn/SdaratB+29bwUpVhgHXrHdJ0i8vjBEX7smD7pI8CcFHuVgACt86NMlBnNCVkwumQgZNAAxe2mJoYcotEWOnhCuMc6MwSj985bj8XEdFlbf4ny9QO9rETd5aYcwXBiV/T6vd637uvHb0KenghNmlb1Tv9LMj2b9ZwNc9C6oeCnbN2YAfxSDrb8Ik+yq4hRewOvIK7f0CcpZYDXK25aHXnHm306Uu53KIwMGf1mha5T5LWTNaYy5XFoMWHJ9E+AnU/MUJSrwCAITH/S0JFcna5Oatn70aTE9pISATsqB5Iz1c46MvdrxD8hPoDjT7x6/EO316DZrxQfJhjbWsCB+R0QxYLkXPHczhB2Z0HPna9xB6RbJHzph7ifDizhZoMCAwEAAQ==
irs_attempt_api_public_key_id: key1
irs_attempt_api_enabled: true
@@ -404,6 +400,7 @@ development:
state_tracking_enabled: true
telephony_adapter: test
use_dashboard_service_providers: true
+ usps_ipp_transliteration_enabled: true
usps_upload_sftp_directory: "/gsa_order"
usps_upload_sftp_host: localhost
usps_upload_sftp_password: test
@@ -523,8 +520,6 @@ test:
hmac_fingerprinter_key: a2c813d4dca919340866ba58063e4072adc459b767a74cf2666d5c1eef3861db26708e7437abde1755eb24f4034386b0fea1850a1cb7e56bff8fae3cc6ade96c
hmac_fingerprinter_key_queue: '["old-key-one", "old-key-two"]'
identity_pki_disabled: true
- inherited_proofing_enabled: true
- va_inherited_proofing_mock_enabled: false
irs_attempt_api_auth_tokens: 'test-token-1,test-token-2'
irs_attempt_api_public_key: MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyut9Uio5XxsIUVrXARqCoHvcMVYT0p6WyU1BnbhxLRW4Q60p+4Bn32vVOt9nzeih7qvauYM5M0PZdKEmwOHflqPP+ABfKhL+6jxBhykN5P5UY375wTFBJZ20Fx8jOJbRhJD02oUQ49YKlDu3MG5Y0ApyD4ER4WKgxuB2OdyQKd9vg2ZZa+P2pw1HkFPEin0h8KBUFBeLGDZni8PIJdHBP6dA+xbayGBxSM/8xQC0JIg6KlGTcLql37QJIhP2oSv0nAJNb6idFPAz0uMCQDQWKKWV5FUDCsFVH7VuQz8xUCwnPn/SdaratB+29bwUpVhgHXrHdJ0i8vjBEX7smD7pI8CcFHuVgACt86NMlBnNCVkwumQgZNAAxe2mJoYcotEWOnhCuMc6MwSj985bj8XEdFlbf4ny9QO9rETd5aYcwXBiV/T6vd637uvHb0KenghNmlb1Tv9LMj2b9ZwNc9C6oeCnbN2YAfxSDrb8Ik+yq4hRewOvIK7f0CcpZYDXK25aHXnHm306Uu53KIwMGf1mha5T5LWTNaYy5XFoMWHJ9E+AnU/MUJSrwCAITH/S0JFcna5Oatn70aTE9pISATsqB5Iz1c46MvdrxD8hPoDjT7x6/EO316DZrxQfJhjbWsCB+R0QxYLkXPHczhB2Z0HPna9xB6RbJHzph7ifDizhZoMCAwEAAQ==
irs_attempt_api_public_key_id: key1
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index 7a0c2bee4c8..e1fce56b1e7 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -113,7 +113,8 @@ ignore_unused:
# - common.brand
## Ignore these keys completely:
-# ignore:
+ignore:
+ - 'i18n.transliterate.rule.*'
# - kaminari.*
## Sometimes, it isn't possible for i18n-tasks to match the key correctly,
diff --git a/config/locales/errors/en.yml b/config/locales/errors/en.yml
index 83688ef42fd..cb1d6c92a8a 100644
--- a/config/locales/errors/en.yml
+++ b/config/locales/errors/en.yml
@@ -34,9 +34,6 @@ en:
security, we limit the number of times you can attempt to verify a
document online.'
general: Oops, something went wrong. Please try again.
- inherited_proofing:
- consent_form: Before you can continue, you must give us permission. Please check
- the box below and then click continue.blah
invalid_totp: Invalid code. Please try again.
max_password_attempts_reached: You’ve entered too many incorrect passwords. You
can reset your password using the “Forgot your password?” link.
diff --git a/config/locales/errors/es.yml b/config/locales/errors/es.yml
index bf923b3355f..eb5aa277e49 100644
--- a/config/locales/errors/es.yml
+++ b/config/locales/errors/es.yml
@@ -35,8 +35,6 @@ es:
%{timeout}. Por su seguridad, limitamos el número de veces que
puede intentar verificar un documento en línea.'
general: '¡Oops! Algo salió mal. Inténtelo de nuevo.'
- inherited_proofing:
- consent_form: to be implemented
invalid_totp: El código es inválido. Vuelva a intentarlo.
max_password_attempts_reached: Ha ingresado demasiadas contraseñas incorrectas.
Puede restablecer su contraseña usando el enlace “¿Olvidó su contraseña?”.
diff --git a/config/locales/errors/fr.yml b/config/locales/errors/fr.yml
index d2b4a55b0f0..b1649a805d0 100644
--- a/config/locales/errors/fr.yml
+++ b/config/locales/errors/fr.yml
@@ -39,8 +39,6 @@ fr:
votre sécurité, nous limitons le nombre de fois où vous pouvez tenter de
vérifier un document en ligne.'
general: Oups, une erreur s’est produite. Veuillez essayer de nouveau.
- inherited_proofing:
- consent_form: to be implemented
invalid_totp: Code non valide. Veuillez essayer de nouveau.
max_password_attempts_reached: Vous avez inscrit des mots de passe incorrects un
trop grand nombre de fois. Vous pouvez réinitialiser votre mot de passe en
diff --git a/config/locales/help_text/en.yml b/config/locales/help_text/en.yml
index d6ad8eaf5cb..a5169c9caaa 100644
--- a/config/locales/help_text/en.yml
+++ b/config/locales/help_text/en.yml
@@ -18,6 +18,8 @@ en:
information with
%{sp}. We’ll share this information: '
ial2_intro_html: '
%{sp} needs to know who you are to connect your
account. We’ll share this information with %{sp}: '
+ ial2_reverified_consent_info: 'Because you verified your identity again, we need
+ your permission to share this information with %{sp}: '
phone: Phone number
social_security_number: Social Security number
verified_at: Updated on
diff --git a/config/locales/help_text/es.yml b/config/locales/help_text/es.yml
index c4f596f906c..21090ee05a0 100644
--- a/config/locales/help_text/es.yml
+++ b/config/locales/help_text/es.yml
@@ -19,6 +19,8 @@ es:
información:'
ial2_intro_html: '
%{sp} necesita saber quién es para conectar su cuenta.
Compartiremos esta información con el organismo asociado: '
+ ial2_reverified_consent_info: 'Como volvió a verificar su identidad, necesitamos
+ su permiso para compartir esta información con %{sp}: '
phone: Teléfono
social_security_number: Número de Seguro Social
verified_at: Actualizado en
diff --git a/config/locales/help_text/fr.yml b/config/locales/help_text/fr.yml
index e39fae0ced1..3f3d539f854 100644
--- a/config/locales/help_text/fr.yml
+++ b/config/locales/help_text/fr.yml
@@ -21,6 +21,9 @@ fr:
ial2_intro_html: '
%{sp} a besoin de savoir qui vous êtes pour connecter
votre compte. Nous partagerons ces informations avec l’agence
partenaire:'
+ ial2_reverified_consent_info: 'Puisque vous avez à nouveau vérifié votre
+ identité, nous avons besoin de votre autorisation pour partager ces
+ informations avec %{sp}:'
phone: Numéro de téléphone
social_security_number: Numéro de sécurité sociale
verified_at: Mis à jour le
diff --git a/config/locales/idv/en.yml b/config/locales/idv/en.yml
index 061c99904a5..6efa7febe14 100644
--- a/config/locales/idv/en.yml
+++ b/config/locales/idv/en.yml
@@ -13,7 +13,6 @@ en:
mail:
resend: Send another letter
send: Send a letter
- send_confirmation_code: Continue
cancel:
actions:
account_page: Go to account page
@@ -72,6 +71,9 @@ en:
exceptions:
internal_error: There was an internal error processing your request. Please try again.
link: please contact us
+ post_office_search_error: We are having technical difficulties at the moment.
+ Try searching for a Post Office again. If this issue continues, come
+ back later.
text_html: Please try again. If you keep getting these errors, %{link}.
phone:
fail_html: '
Please try again in %{timeout}. For your security,
@@ -152,9 +154,6 @@ en:
timeframe_html: Letters are sent the next business day via USPS First Class Mail
and
typically take 3 to 7 business days to arrive.
mail_sent: Your letter is on its way
- otp_delivery_method:
- phone_number_html: We’ll send a code to
%{phone} to verify that
- the phone number belongs to you.
otp_delivery_method_description: If you entered a landline above, please select “Phone call” below.
personal_key: This is your new personal key. Write it down and keep it in a safe
place. You will need it if you ever lose your password.
@@ -208,7 +207,6 @@ en:
still_having_trouble: Still having trouble?
options:
add_new_photos: Add new photos of your state-issued ID
- change_phone_number: Use a different phone number
contact_support: Contact %{app_name} Support
doc_capture_tips: More tips for adding photos of your ID
get_help_at_sp: Get help at %{sp_name}
diff --git a/config/locales/idv/es.yml b/config/locales/idv/es.yml
index ddb29176298..08d77ffb78d 100644
--- a/config/locales/idv/es.yml
+++ b/config/locales/idv/es.yml
@@ -14,7 +14,6 @@ es:
mail:
resend: Enviar otra carta
send: Enviar una carta
- send_confirmation_code: Continuar
cancel:
actions:
account_page: Ir a la página de la cuenta
@@ -77,6 +76,9 @@ es:
internal_error: Se produjo un error interno al procesar tu solicitud. Por favor,
inténtalo de nuevo.
link: contáctanos
+ post_office_search_error: En este momento, estamos teniendo problemas técnicos.
+ Trate de buscar de nuevo una oficina de correos. Si el problema
+ continúa, regrese más tarde.
text_html: Inténtalo de nuevo. Si sigues recibiendo estos errores, %{link}.
phone:
fail_html: '
Por favor, inténtelo de nuevo en %{timeout}. Por su
@@ -162,9 +164,6 @@ es:
USPS y
suelen tardar entre 3 y 7 días hábiles en
llegar.
mail_sent: Su carta está en camino
- otp_delivery_method:
- phone_number_html: Enviaremos un código a
%{phone} para
- verificar que el número de teléfono le pertenece.
otp_delivery_method_description: Si ha introducido un teléfono fijo más arriba,
seleccione “Llamada telefónica” más abajo.
personal_key: Esta es su nueva clave personal. Escríbala y guárdela en un lugar
@@ -222,7 +221,6 @@ es:
still_having_trouble: '¿Sigue teniendo dificultades?'
options:
add_new_photos: Añada nuevas fotos de su ID emitido por el estado
- change_phone_number: Utiliza un número de teléfono diferente
contact_support: Póngase en contacto con el servicio de asistencia de %{app_name}
doc_capture_tips: Más consejos para agregar fotos de su identificación
get_help_at_sp: Obtenga ayuda en %{sp_name}
diff --git a/config/locales/idv/fr.yml b/config/locales/idv/fr.yml
index d10f8582cd3..409b423caa6 100644
--- a/config/locales/idv/fr.yml
+++ b/config/locales/idv/fr.yml
@@ -14,7 +14,6 @@ fr:
mail:
resend: Envoyer une autre lettre
send: Envoyer une lettre
- send_confirmation_code: Continuer
cancel:
actions:
account_page: Accéder à la page de votre compte
@@ -81,6 +80,9 @@ fr:
internal_error: Une erreur interne s’est produite lors du traitement de votre
demande. Veuillez réessayer.
link: contactez-nous
+ post_office_search_error: Nous connaissons des difficultés techniques en ce
+ moment. Essayez de chercher à nouveau un bureau de poste. Si le
+ problème persiste, revenez plus tard.
text_html: Veuillez réessayer. Si vous continuez à recevoir ces erreurs, %{link}
phone:
fail_html: '
Veuillez réessayer dans %{timeout}. Pour votre
@@ -171,9 +173,6 @@ fr:
première classe de USPS et
prennent généralement entre trois à
sept jours ouvrables pour être reçues.
mail_sent: Votre lettre est en route
- otp_delivery_method:
- phone_number_html: Nous enverrons un code à
%{phone} pour
- vérifier que le numéro de téléphone vous appartient.
otp_delivery_method_description: Si vous avez saisi une ligne fixe ci-dessus,
veuillez sélectionner « Appel téléphonique » ci-dessous.
personal_key: Il s’agit de votre nouvelle clé personnelle. Notez-la et
@@ -238,7 +237,6 @@ fr:
options:
add_new_photos: Ajoutez de nouvelles photos de votre carte d’identité délivrée
par l’État.
- change_phone_number: Utiliser un autre numéro de téléphone
contact_support: Contacter le service d’assistance de %{app_name}
doc_capture_tips: Plus de conseils pour ajouter des photos de votre carte d’identité
get_help_at_sp: Demandez de l’aide à %{sp_name}
diff --git a/config/locales/inherited_proofing/en.yml b/config/locales/inherited_proofing/en.yml
deleted file mode 100644
index 38da46a43ab..00000000000
--- a/config/locales/inherited_proofing/en.yml
+++ /dev/null
@@ -1,71 +0,0 @@
----
-en:
- inherited_proofing:
- buttons:
- continue: Continue
- try_again: Try again
- cancel:
- actions:
- keep_going: No, keep going
- start_over: Start over
- description:
- start_over: If you start over, you will restart this process from the beginning
- and the information you entered will not be saved.
- headings:
- confirmation:
- hybrid: You have cancelled uploading photos of your ID on this phone
- prompt:
- standard: Cancel verifying your identity?
- start_over: Start over verifying your identity
- instructions:
- switch_back: Switch back to your computer to finish verifying your identity.
- switch_back_image: Arrow pointing from phone to computer
- errors:
- cannot_retrieve:
- failure_info: Please check back later.
- heading: We could not retrieve your information from your Partner Agency
- info: We are temporarily having trouble retrieving your information. Please try
- again.
- title: Couldn’t retrieve information
- service_provider:
- communication: 'communication was unsuccessful'
- headings:
- lets_go: How verifying your identity works
- retrieval: We are retrieving your information from your Partner Agency
- secure_account: Secure your account
- verify_identity: Verify your identity
- verify_information: Verify your information
- welcome: Get started verifying your identity
- info:
- lets_go: 'Identity verification happens in two parts:'
- no_sp_name: VA needs to make sure you are you
- privacy_html: '%{app_name} is a secure, government website that adheres to the
- highest standards in data protection. We only use your data to verify
- your identity. %{link} about our privacy and security measures.'
- retrieval_thanks: Thanks for your patience!
- retrieval_time: This might take up to a minute. We’ll load the next step
- automatically when it’s done.
- secure_account: We’ll encrypt your account with your password. Encryption means
- your data is protected and only you will be able to access or change
- your information.
- verify_identity: We’ll retrieve your personal information from %{sp_name} and
- ask you to verify it.
- welcome_html: '%{sp_name} needs to make sure you are you - not someone
- pretending to be you.'
- instructions:
- consent: By checking this box, you are letting login.gov ask for, use, keep, and
- share your personal information. We will only use it to verify your
- identity.
- learn_more: Learn more
- privacy: Our privacy and security standards
- verify_requirements: We’ll call or text your phone number to verify your
- identity. If we can’t verify your phone number, you can verify by mail
- instead.
- troubleshooting:
- headings:
- missing_required_items: Don’t have a phone number? Here’s how to get help
- need_assistance: 'Need immediate assistance? Here’s how to get help:'
- need_help_updating: Need to update your information? Here’s how to get help
- options:
- get_help: Get help at the %{sp_name} web site
- learn_more_phone_or_mail: Learn more about verifying by phone or mail
diff --git a/config/locales/inherited_proofing/es.yml b/config/locales/inherited_proofing/es.yml
deleted file mode 100644
index d79cfd9ead4..00000000000
--- a/config/locales/inherited_proofing/es.yml
+++ /dev/null
@@ -1,76 +0,0 @@
----
-es:
- inherited_proofing:
- buttons:
- continue: Continuar
- try_again: Inténtelo de nuevo
- cancel:
- actions:
- keep_going: No, continuar
- start_over: Empezar de nuevo
- description:
- start_over: Si empieza de nuevo, el proceso se reiniciará y la información que
- haya ingresado se perderá.
- headings:
- confirmation:
- hybrid: Ha cancelado la carga de fotos de su identificación en este teléfono
- prompt:
- standard: '¿Cancelar la verificación de su identidad?'
- start_over: Empezar de nuevo a verificar su identidad
- instructions:
- 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
- errors:
- cannot_retrieve:
- failure_info: to be implemented
- heading: No hemos podido obtener su información de su agencia colaboradora
- info: Estamos teniendo problemas temporalmente para obtener su información.
- Inténtelo de nuevo.
- title: to be implemented
- service_provider:
- communication: 'la comunicacion no tuvo exito'
- headings:
- lets_go: Cómo funciona la verificación de su identidad
- retrieval: Estamos recuperando su información de su agencia colaboradora
- secure_account: Asegure su cuenta
- verify_identity: Verifique su identidad
- verify_information: Verifique su información
- welcome: Empiece con la verificación de su identidad
- info:
- lets_go: 'La verificación de la identidad se realiza en dos partes:'
- no_sp_name: La agencia a la que está intentando acceder
- privacy_html: '%{app_name} es un sitio web gubernamental seguro que cumple con
- las normas más estrictas de protección de datos. Solo utilizamos sus
- datos para verificar su identidad. %{link} sobre nuestras medidas de
- privacidad y seguridad.'
- retrieval_thanks: '¡Gracias por su paciencia!'
- retrieval_time: Esto puede tardar hasta un minuto. Cargaremos el siguiente paso
- automáticamente cuando haya terminado.
- secure_account: Cifraremos su cuenta con su contraseña. La encriptación
- significa que sus datos están protegidos y solo usted podrá acceder o
- modificar su información.
- verify_identity: Obtendremos su información personal de %{sp_name} y le
- pediremos que la verifique.
- welcome_html: '%{sp_name} necesita asegurarse de que sea usted y no alguien que
- se haga pasar por usted.'
- instructions:
- consent: Al marcar esta casilla, usted permite que login.gov solicite, utilice,
- conserve y comparta su información personal. Solo la utilizaremos para
- verificar su identidad.
- learn_more: Obtenga más información
- privacy: Nuestras normas de privacidad y seguridad
- verify_requirements: Te llamaremos o te enviaremos un mensaje de texto a tu
- número de teléfono para verificar tu identidad. Si no podemos verificar
- tu número de teléfono, puedes realizar la verificación por correo
- postal.
- troubleshooting:
- headings:
- missing_required_items: ¿No tienes número de teléfono? A continuación, te
- indicamos cómo obtener ayuda
- need_assistance: to be implemented
- need_help_updating: ¿Necesita actualizar su información? A continuación le
- indicamos cómo obtener ayuda
- options:
- get_help: Obtenga ayuda en %{sp_name}
- learn_more_phone_or_mail: Más información sobre la verificación por teléfono o correo postal.
diff --git a/config/locales/inherited_proofing/fr.yml b/config/locales/inherited_proofing/fr.yml
deleted file mode 100644
index 140a6dc8650..00000000000
--- a/config/locales/inherited_proofing/fr.yml
+++ /dev/null
@@ -1,76 +0,0 @@
----
-fr:
- inherited_proofing:
- buttons:
- continue: Continuer
- try_again: Réessayez
- cancel:
- actions:
- keep_going: Non, continuer
- start_over: Recommencer
- description:
- start_over: Si vous recommencez, vous reprendrez ce processus depuis le début et
- les informations que vous avez saisies ne seront pas enregistrées.
- headings:
- confirmation:
- hybrid: Vous avez annulé le téléchargement de vos photos d’identité sur ce
- téléphone
- prompt:
- standard: Annuler la vérification de votre identité?
- start_over: Recommencez la vérification de votre identité
- instructions:
- 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
- errors:
- cannot_retrieve:
- failure_info: to be implemented
- heading: Nous n’avons pas pu récupérer vos informations dans votre agence
- partenaire
- info: Nous avons temporairement des difficultés à récupérer vos informations.
- Veuillez réessayer.
- title: to be implemented
- service_provider:
- communication: 'la communication a échoué'
- headings:
- lets_go: Comment fonctionne la vérification de votre identité
- retrieval: Nous récupérons vos informations depuis votre agence partenaire.
- secure_account: Sécuriser votre compte
- verify_identity: Vérifier votre identité
- verify_information: Vérifier votre information
- welcome: Commencez à vérifier votre identité
- info:
- lets_go: 'La vérification de l’identité se fait en deux temps :'
- no_sp_name: L’agence à laquelle vous essayez d’accéder
- privacy_html: '%{app_name} est un site gouvernemental sécurisé qui respecte les
- normes les plus strictes en matière de protection des données. Nous
- n’utilisons vos données uniquement pour vérifier votre identité. %{link}
- sur nos mesures de confidentialité et de sécurité.'
- retrieval_thanks: Merci de votre patience!
- retrieval_time: Cette opération peut prendre jusqu’à une minute. Nous chargerons
- automatiquement l’étape suivante lorsque ce sera fait.
- secure_account: Votre compte sera crypté avec votre mot de passe. Le cryptage
- signifie que vos données sont protégées et que vous seul pourrez accéder
- à vos informations ou les modifier.
- verify_identity: Nous récupérerons vos informations personnelles sur %{sp_name}
- et vous demanderons de les vérifier.
- welcome_html: '%{sp_name} doit s’assurer que vous êtes bien vous, et non
- quelqu’un qui se fait passer pour vous'
- instructions:
- consent: En cochant cette case, vous autorisez login.gov à demander, utiliser,
- conserver et partager vos renseignements personnels. Nous ne les
- utiliserons que pour vérifier votre identité.
- learn_more: En savoir plus
- privacy: Nos normes de confidentialité et de sécurité
- verify_requirements: Nous allons vous appeler ou vous envoyer un SMS à partir de
- votre contact pour vérifier votre identité. Si nous ne pouvons pas
- vérifier votre numéro de téléphone, vous pouvez le faire par courriel.
- troubleshooting:
- headings:
- missing_required_items: Vous n’avez pas de numéro de téléphone? Voici comment obtenir de l’aide
- need_assistance: to be implemented
- need_help_updating: Vous devez mettre à jour vos informations? Voici comment
- obtenir de l’aide
- options:
- get_help: Obtenez de l’aide sur %{sp_name}
- learn_more_phone_or_mail: En savoir plus sur la vérification par téléphone ou par courriel.
diff --git a/config/locales/titles/en.yml b/config/locales/titles/en.yml
index 783638a1ef9..2d898e0715e 100644
--- a/config/locales/titles/en.yml
+++ b/config/locales/titles/en.yml
@@ -13,7 +13,6 @@ en:
address: Update your mailing address
doc_capture: Add your ID
link_sent: Link sent
- otp_delivery: Receive a one-time code
processing_images: Processing your images
ssn: Enter your Social Security number
switch_back: Switch back to your computer
@@ -42,9 +41,6 @@ en:
reset_password: Reset Password
review: Re-enter your password
verify_info: Verify your information
- inherited_proofing:
- cancellation_prompt: Cancel identity verification
- cancelled: Identity verification is cancelled
mfa_setup:
suggest_second_mfa: You’ve added your first authentication method! Add a second
method as a backup.
@@ -58,7 +54,7 @@ en:
confirm: Confirm the password for your account
forgot: Reset password
personal_key: Just in case
- phone_setup: Send your one-time code via text message (SMS) or phone call
+ phone_setup: Get your one-time code
piv_cac_login:
add: Add your PIV or CAC
new: Use your PIV/CAC to sign in to your account
@@ -79,6 +75,7 @@ en:
completion_ial2: Connect your verified information to %{sp}
completion_new_attributes: '%{sp} is requesting new information'
completion_new_sp: You are now signing in for the first time
+ completion_reverified_consent: Update your verified information with %{sp}
confirmation: Continue to sign in
spam_protection: Protecting against spam
totp_setup:
diff --git a/config/locales/titles/es.yml b/config/locales/titles/es.yml
index 458620a62ee..27a3c09aa19 100644
--- a/config/locales/titles/es.yml
+++ b/config/locales/titles/es.yml
@@ -13,7 +13,6 @@ es:
address: Actualice su dirección postal
doc_capture: Agrega tu identificación
link_sent: Enlace enviado
- otp_delivery: Reciba un código de un solo uso
processing_images: Procesando tus imágenes
ssn: Ingresa tu número del seguro social
switch_back: Regresar a tu computadora
@@ -42,9 +41,6 @@ es:
reset_password: Restablecer la contraseña
review: Vuelve a ingresar tu contraseña
verify_info: Verifica tu información
- inherited_proofing:
- cancellation_prompt: Cancela la verificación de identidad
- cancelled: Se canceló la verificación de identidad
mfa_setup:
suggest_second_mfa: '¡Has agregado tu primer método de autenticación! Agrega un
segundo método como respaldo.'
@@ -58,8 +54,7 @@ es:
confirm: Confirme la contraseña de su cuenta
forgot: Restablecer la contraseña
personal_key: Por si acaso
- phone_setup: Envíe su código de un solo uso a través de un mensaje de texto
- (SMS) o una llamada telefónica
+ phone_setup: Obtenga su código único
piv_cac_login:
add: Agregue su PIV o CAC
new: Use su PIV / CAC para iniciar sesión en su cuenta
@@ -81,6 +76,7 @@ es:
completion_ial2: Conecte su información verificada a %{sp}
completion_new_attributes: '%{sp} está solicitando nueva información'
completion_new_sp: Acabas de iniciar sesión por primera vez
+ completion_reverified_consent: Actualice su información verificados con %{sp}
confirmation: Continuar para iniciar sesión
spam_protection: Protección contra el correo no deseado
totp_setup:
diff --git a/config/locales/titles/fr.yml b/config/locales/titles/fr.yml
index 5175de061b2..0718e36a78d 100644
--- a/config/locales/titles/fr.yml
+++ b/config/locales/titles/fr.yml
@@ -13,7 +13,6 @@ fr:
address: Mettez à jour votre adresse postale
doc_capture: Ajoutez votre pièce d’identité
link_sent: Lien envoyé
- otp_delivery: Recevez un code à usage unique
processing_images: Traitement de vos images
ssn: Entrez votre numéro de sécurité sociale
switch_back: Retournez sur votre ordinateur
@@ -42,9 +41,6 @@ fr:
reset_password: Réinitialisez le mot de passe
review: Saisissez à nouveau votre mot de passe
verify_info: Vérifiez vos informations
- inherited_proofing:
- cancellation_prompt: Annulez la vérification d’identité
- cancelled: La vérification d’identité est annulée
mfa_setup:
suggest_second_mfa: Vous avez ajouté votre première méthode d’authentification !
Ajoutez-en une deuxième en guise de sauvegarde.
@@ -58,8 +54,7 @@ fr:
confirm: Confirmez le mot de passe de votre compte
forgot: Réinitialisez le mot de passe
personal_key: Juste au cas
- phone_setup: Envoyez votre code à usage unique par message texte (SMS) ou par
- appel téléphonique.
+ phone_setup: Obtenez votre code à usage unique
piv_cac_login:
add: Ajoutez votre PIV ou CAC
new: Utilisez votre PIV / CAC pour vous connecter à votre compte
@@ -81,6 +76,7 @@ fr:
completion_ial2: Connectez vos informations vérifiées à %{sp}
completion_new_attributes: '%{sp} demande de nouvelles informations'
completion_new_sp: Vous vous connectez pour la première fois
+ completion_reverified_consent: Mettez à jour vos informations vérifiées avec %{sp}
confirmation: Continuer à vous connecter
spam_protection: Protection contre les pourriels
totp_setup:
diff --git a/config/locales/transliterate/en.yml b/config/locales/transliterate/en.yml
new file mode 100644
index 00000000000..ff055805825
--- /dev/null
+++ b/config/locales/transliterate/en.yml
@@ -0,0 +1,23 @@
+en:
+ i18n:
+ transliterate:
+ rule:
+ # Convert okina to apostrophe
+ ʻ: "'"
+ # Convert quotation marks
+ ’: "'"
+ ‘: "'"
+ ‛: "'"
+ “: '"'
+ ‟: '"'
+ ”: '"'
+ # Convert hyphens
+ ‐: '-'
+ ‑: '-'
+ ‒: '-'
+ –: '-'
+ —: '-'
+ ﹘: '-'
+ # Convert number signs
+ ﹟: '#'
+ #: '#'
diff --git a/config/locales/two_factor_authentication/en.yml b/config/locales/two_factor_authentication/en.yml
index a9eba3bc0a2..cefa57a0e6d 100644
--- a/config/locales/two_factor_authentication/en.yml
+++ b/config/locales/two_factor_authentication/en.yml
@@ -81,20 +81,19 @@ en:
wait_30d_opt_in: After 30 days, you can opt in and receive a security code to
that phone number.
otp_delivery_preference:
- instruction: You can change this selection the next time you sign in. If you
- entered a landline, please select “Phone call” below.
+ instruction: You can change this anytime. If you use a landline number, select
+ “Phone call.”
landline_warning_html: The phone number entered appears to be a
landline
phone. Request a one-time code by %{phone_setup_path} instead.
no_supported_options: We are unable to verify phone numbers from %{location}
phone_call: phone call
sms: Text message (SMS)
sms_unsupported: We are unable to send text messages to phone numbers in %{location}.
- title: How should we send you a code?
+ title: How you’ll get your code
voice: Phone call
voice_unsupported: We are unable to call phone numbers in %{location}.
otp_make_default_number:
- instruction: Make this phone number the default number where you receive text
- message or phone calls.
+ instruction: Send text messages and calls to this number by default.
label: Default phone number
one_number_instruction: You must have more than one phone number added to select
a default phone number.
@@ -112,7 +111,7 @@ en:
phone_fallback:
question: Can’t use your phone?
phone_fee_disclosure: Message and data rates may apply.
- phone_info_html: We’ll send you a one-time code
each time you sign in.
+ phone_info: We’ll send you a one-time code each time you sign in.
phone_label: Phone number
phone_verification:
troubleshooting:
@@ -158,12 +157,10 @@ en:
piv_cac: Government employee ID
piv_cac_info: PIV/CAC cards for government and military employees. Desktop only.
sms: Text message / SMS
- sms_info: Get your one-time code via text message / SMS.
unused_backup_code:
one: '(%{count} unused code)'
other: '(%{count} unused codes)'
voice: Phone call
- voice_info: Get your one-time code via phone call.
webauthn: Security key
webauthn_info: A physical device, often shaped like a USB drive, that you plug
in to your device.
diff --git a/config/locales/two_factor_authentication/es.yml b/config/locales/two_factor_authentication/es.yml
index ac1492c149a..1edd7c183eb 100644
--- a/config/locales/two_factor_authentication/es.yml
+++ b/config/locales/two_factor_authentication/es.yml
@@ -89,7 +89,7 @@ es:
wait_30d_opt_in: Después de 30 días, podrá inscribirse y recibir un código de
seguridad para ese número de teléfono.
otp_delivery_preference:
- instruction: Puede cambiar esta selección la próxima vez que inicie sesión.
+ instruction: Envíe mensajes de texto y llamadas a este número por defecto.
landline_warning_html: Al parecer el número ingresado pertenece a un
teléfono
fijo. Mejor solicita un código de un solo uso por
%{phone_setup_path}.
@@ -97,7 +97,7 @@ es:
phone_call: llamada telefónica
sms: Mensaje de texto (SMS, sigla en inglés)
sms_unsupported: No podemos enviar mensajes de texto a números de teléfono de %{location}.
- title: '¿Cómo deberíamos enviarle un código?'
+ title: Cómo obtendrá su código
voice: Llamada telefónica
voice_unsupported: No podemos llamar a números de teléfono en %{location}.
otp_make_default_number:
@@ -120,8 +120,7 @@ es:
phone_fallback:
question: '¿No puede utilizar su teléfono?'
phone_fee_disclosure: Se pueden aplicar tarifas por mensajes y datos.
- phone_info_html: Le enviaremos un código de un solo uso
cada vez que
- ingrese.
+ phone_info: Le enviaremos un código de un solo uso cada vez que ingrese.
phone_label: Número de teléfono
phone_verification:
troubleshooting:
@@ -171,12 +170,10 @@ es:
piv_cac_info: Credenciales PIV/CAC para empleados gubernamentales y del
ejército. Únicamente versión de escritorio.
sms: Mensaje de texto / SMS
- sms_info: Obtenga su código de un solo uso a través de un mensaje de texto/SMS.
unused_backup_code:
one: '(%{count} código sin usar)'
other: '(%{count} códigos sin usar)'
voice: Llamada telefónica
- voice_info: Obtenga su código de un solo uso a través de una llamada telefónica.
webauthn: Clave de seguridad
webauthn_info: Un dispositivo físico que suele tener la forma de una unidad USB
y se conecta a su dispositivo.
diff --git a/config/locales/two_factor_authentication/fr.yml b/config/locales/two_factor_authentication/fr.yml
index 733257f448a..41de2c0ecb1 100644
--- a/config/locales/two_factor_authentication/fr.yml
+++ b/config/locales/two_factor_authentication/fr.yml
@@ -91,7 +91,7 @@ fr:
wait_30d_opt_in: Après 30 jours, vous pouvez vous inscrire et recevoir un code
de sécurité à ce numéro de téléphone.
otp_delivery_preference:
- instruction: Vous pouvez modifier cette sélection lors de votre prochaine connexion.
+ instruction: Envoyez des messages texte ainsi que des appels par défaut à ce numéro
landline_warning_html: Le numéro de téléphone saisi semble être un
téléphone
fixe. Demandez plutôt un code à usage unique par
%{phone_setup_path}.
@@ -101,7 +101,7 @@ fr:
sms: Message texte (SMS)
sms_unsupported: Il est impossible d’envoyer des messages texte à des numéros de
téléphone dans %{location}.
- title: Comment devrions-nous vous envoyer un code?
+ title: Comment vous obtiendrez votre code
voice: Appel téléphonique
voice_unsupported: Il nous est impossible d’appeler des numéros de téléphone
dans le %{location}.
@@ -125,8 +125,8 @@ fr:
phone_fallback:
question: Vous ne pouvez pas utiliser votre téléphone?
phone_fee_disclosure: Des messages et débits de données peuvent être appliqués.
- phone_info_html: Nous vous enverrons un code à usage unique
à chaque
- fois que vous vous connecterez.
+ phone_info: Nous vous enverrons un code à usage unique à chaque fois que vous
+ vous connecterez.
phone_label: Numéro de téléphone
phone_verification:
troubleshooting:
@@ -175,12 +175,10 @@ fr:
piv_cac_info: Cartes PIV/CAC pour les fonctionnaires et les militaires. Bureau
uniquement.
sms: SMS
- sms_info: Recevez votre code à usage unique par message texte/SMS.
unused_backup_code:
one: '(%{count} code non utilisé)'
other: '(%{count} codes non utilisés)'
voice: Appel téléphonique
- voice_info: Obtenez votre code à usage unique par appel téléphonique.
webauthn: Clef de sécurité
webauthn_info: Un appareil physique, souvent en forme de clé USB, que vous
branchez sur votre appareil.
diff --git a/config/routes.rb b/config/routes.rb
index 20fb8449910..c79649eaadd 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -307,8 +307,7 @@
post '/personal_key' => 'personal_key#update'
get '/forgot_password' => 'forgot_password#new'
post '/forgot_password' => 'forgot_password#update'
- get '/otp_delivery_method' => 'otp_delivery_method#new'
- put '/otp_delivery_method' => 'otp_delivery_method#create'
+ get '/document_capture' => 'document_capture#show'
get '/ssn' => 'ssn#show'
put '/ssn' => 'ssn#update'
get '/verify_info' => 'verify_info#show'
@@ -366,22 +365,6 @@
post '/confirmations' => 'personal_key#update'
end
- # Inherited Proofing (IP)-specific routes.
- scope '/verify/inherited_proofing', module: 'idv', as: 'idv_inherited_proofing' do
- # NOTE: cancellation routes need to be before any other IP
- # routes in this scope.
- delete '/session' => 'sessions#destroy'
- get '/cancel' => 'inherited_proofing_cancellations#new', as: :cancel
- put '/cancel' => 'inherited_proofing_cancellations#update'
- delete '/cancel' => 'inherited_proofing_cancellations#destroy'
- get '/' => 'inherited_proofing#index'
- get '/:step' => 'inherited_proofing#show', as: :step
- put '/:step' => 'inherited_proofing#update'
- get '/return_to_sp' => 'inherited_proofing#return_to_sp'
- get '/errors/no_information' => 'inherited_proofing_errors#warning'
- get '/errors/failure' => 'inherited_proofing_errors#failure'
- end
-
namespace :api do
post '/verify/v2/document_capture' => 'verify/document_capture#create'
delete '/verify/v2/document_capture_errors' => 'verify/document_capture_errors#delete'
diff --git a/docs/FixingOpenSSLVersionProblem.md b/docs/FixingOpenSSLVersionProblem.md
new file mode 100644
index 00000000000..b0184a4eda4
--- /dev/null
+++ b/docs/FixingOpenSSLVersionProblem.md
@@ -0,0 +1,82 @@
+# How to fix a recurrent problem with OpenSSL and some of our tests
+This problem has happened when Ruby was built and linked against the
+wrong version of OpenSSL.
+
+The procedure we have found that fixes the problem is to rebuild Ruby,
+linked against the correct version of OpenSSL, then remove and
+reinstall all of your gems.
+
+These instructions have been used successfully for environments
+managed using `asdf`, `chruby` and `rbenv`. Details for each are
+below.
+
+If you are using another Ruby version manager, the section on
+`ruby-build` is likely your best starting point. Please add your
+experience and any useful information to this document.
+
+# Details
+- These instructions assume you're on a Mac; if not, you will have to
+ work out the equivalent directions based on these.
+
+- As of this writing, the correct Ruby version for login.gov is 3.2.0.
+ Use whatever the current version is.
+
+## One spec which shows the problem:
+
+`spec/features/openid_connect/openid_connect_spec.rb`
+
+The problem looks like:
+```
+1) OpenID Connect receives an ID token with a kid that matches the certs endpoint
+ Failure/Error: JWT::JWK.import(certs_response[:keys].first).public_key
+ OpenSSL::PKey::PKeyError:
+ rsa#set_key= is incompatible with OpenSSL 3.0
+```
+
+## Finding out where you have openssl 1.1 installed
+
+`brew --prefix openssl@1.1`
+
+If not present, run `brew install openssl@1.1`
+
+## Version manager specifics
+Most version managers simply require that the correct version of Ruby
+be installed, usually using `ruby-build`.
+
+### Rebuilding Ruby using `asdf`
+`asdf` uses `ruby-build` under the covers, but supplies some
+configuration of its own, so we must use `asdf` to (re-)install Ruby.
+
+Remove the existing Ruby version, if present:
+
+`asdf uninstall ruby 3.2.0`
+
+And re-install, using the correct OpenSSL installation:
+
+`RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1)" asdf install ruby 3.2.0`
+
+### Rebuilding Ruby using `chruby`
+Use the `ruby-build` instructions; `chruby` doesn't require anything special.
+
+### Rebuilding Ruby using `rbenv`
+Use the `ruby-build` instructions; `rbenv` doesn't require anything special.
+
+### Rebuilding Ruby using `ruby-build`
+Make sure ruby-build is up to date
+
+`brew upgrade ruby-build`
+
+And then rebuild Ruby (this assumes your Rubies are in ~/.rubies)
+
+`RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1)" ruby-build 3.2.0 ~/.rubies/3.2.0`
+
+## Exiting your shell
+After your Ruby is built, exit your shell and open a new one, to clear caches.
+
+## Removing all of your gems
+
+`gem uninstall -aIx`
+
+## Reinstalling your gems
+
+`bundle install`
diff --git a/lib/identity_config.rb b/lib/identity_config.rb
index e5982dfcfc6..714cf08c821 100644
--- a/lib/identity_config.rb
+++ b/lib/identity_config.rb
@@ -157,6 +157,7 @@ def self.build_store(config_map)
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)
config.add(:doc_auth_error_glare_threshold, type: :integer)
@@ -167,7 +168,6 @@ def self.build_store(config_map)
config.add(:doc_auth_max_submission_attempts_before_native_camera, type: :integer)
config.add(:doc_auth_max_capture_attempts_before_tips, type: :integer)
config.add(:doc_auth_s3_request_timeout, type: :integer)
- config.add(:doc_auth_ssn_controller_enabled, type: :boolean)
config.add(:doc_auth_vendor, type: :string)
config.add(:doc_auth_vendor_randomize, type: :boolean)
config.add(:doc_auth_vendor_randomize_percent, type: :integer)
@@ -211,6 +211,7 @@ def self.build_store(config_map)
config.add(:idv_send_link_max_attempts, type: :integer)
config.add(:idv_sp_required, type: :boolean)
config.add(:ie11_support_end_date, type: :timestamp)
+ config.add(:in_person_capture_secondary_id_enabled, type: :boolean)
config.add(:in_person_cta_variant_testing_enabled, type: :boolean)
config.add(:in_person_cta_variant_testing_percents, type: :json)
config.add(:in_person_email_reminder_early_benchmark_in_days, type: :integer)
@@ -222,11 +223,6 @@ def self.build_store(config_map)
config.add(:in_person_completion_survey_url, type: :string)
config.add(:in_person_verify_info_controller_enabled, type: :boolean)
config.add(:include_slo_in_saml_metadata, type: :boolean)
- config.add(:inherited_proofing_enabled, type: :boolean)
- config.add(:inherited_proofing_va_base_url, type: :string)
- config.add(:inherited_proofing_max_attempts, type: :integer)
- config.add(:inherited_proofing_max_attempt_window_in_minutes, type: :integer)
- config.add(:va_inherited_proofing_mock_enabled, type: :boolean)
config.add(:irs_attempt_api_audience)
config.add(:irs_attempt_api_auth_tokens, type: :comma_separated_string_list)
config.add(:irs_attempt_api_bucket_name, type: :string, allow_nil: true)
@@ -239,6 +235,7 @@ def self.build_store(config_map)
config.add(:irs_attempt_api_event_count_default, type: :integer)
config.add(:irs_attempt_api_event_count_max, type: :integer)
config.add(:irs_attempt_api_payload_size_logging_enabled, type: :boolean)
+ config.add(:irs_attempt_api_track_tmx_fraud_check_event, type: :boolean)
config.add(:irs_attempt_api_public_key)
config.add(:irs_attempt_api_public_key_id)
config.add(:lexisnexis_base_url, type: :string)
@@ -431,6 +428,7 @@ def self.build_store(config_map)
config.add(:usps_ipp_username, type: :string)
config.add(:usps_ipp_request_timeout, type: :integer)
config.add(:usps_upload_enabled, type: :boolean)
+ config.add(:usps_ipp_transliteration_enabled, type: :boolean)
config.add(:get_usps_proofing_results_job_cron, type: :string)
config.add(:get_usps_proofing_results_job_reprocess_delay_minutes, type: :integer)
config.add(:get_usps_proofing_results_job_request_delay_milliseconds, type: :integer)
diff --git a/lib/session_encryptor.rb b/lib/session_encryptor.rb
index 113a1b496b1..2ac918f8f7d 100644
--- a/lib/session_encryptor.rb
+++ b/lib/session_encryptor.rb
@@ -20,7 +20,6 @@ class SensitiveValueError < StandardError; end
# personal keys are generated and stored in the session between requests, but are used
# to decrypt PII bundles, so we treat them similarly to the PII itself.
SENSITIVE_PATHS = [
- ['warden.user.user.session', 'idv/inherited_proofing'],
['warden.user.user.session', 'idv/doc_auth'],
['warden.user.user.session', 'idv/in_person'],
['warden.user.user.session', 'idv'],
diff --git a/package.json b/package.json
index e2df37ddbaa..4333a229151 100644
--- a/package.json
+++ b/package.json
@@ -14,9 +14,10 @@
"lint:css": "stylelint 'app/assets/stylesheets/**/*.scss' 'app/javascript/**/*.scss'",
"test": "mocha 'spec/javascripts/**/**spec.+(j|t)s?(x)' 'app/javascript/packages/**/*.spec.+(j|t)s?(x)'",
"normalize-yaml": "normalize-yaml",
+ "generate-browsers-json": "./scripts/generate-browsers-json.js",
"clean": "rm -rf public/packs/*",
"prebuild": "yarn run clean",
- "build": "webpack",
+ "build": "webpack && yarn generate-browsers-json",
"build:css": "build-sass app/assets/stylesheets/*.css.scss --out-dir=app/assets/builds"
},
"dependencies": {
@@ -27,6 +28,7 @@
"@babel/register": "^7.15.3",
"babel-loader": "^9.1.0",
"babel-plugin-polyfill-corejs3": "^0.5.2",
+ "browserslist": "^4.21.5",
"cleave.js": "^1.6.0",
"core-js": "^3.21.1",
"fast-glob": "^3.2.7",
diff --git a/scripts/generate-browsers-json.js b/scripts/generate-browsers-json.js
new file mode 100755
index 00000000000..f0d044a0ce1
--- /dev/null
+++ b/scripts/generate-browsers-json.js
@@ -0,0 +1,6 @@
+#!/usr/bin/env node
+
+const { writeFileSync } = require('fs');
+const browserslist = require('browserslist');
+
+writeFileSync('./browsers.json', JSON.stringify(browserslist()));
diff --git a/scripts/inherited_proofing/errorable.rb b/scripts/inherited_proofing/errorable.rb
deleted file mode 100644
index 2c4bd406de6..00000000000
--- a/scripts/inherited_proofing/errorable.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-module Scripts
- module InheritedProofing
- module Errorable
- module_function
-
- def puts_message(message)
- puts message
- end
-
- def puts_success(message)
- puts_message "Success: #{message}"
- end
-
- def puts_warning(message)
- puts_message "Warning: #{message}"
- end
-
- def puts_error(message)
- puts_message "Oops! An error occurred: #{message}"
- end
- end
- end
-end
diff --git a/scripts/inherited_proofing/va/lexis_nexis/phone_finder.rb b/scripts/inherited_proofing/va/lexis_nexis/phone_finder.rb
deleted file mode 100644
index 4f32e37e5f1..00000000000
--- a/scripts/inherited_proofing/va/lexis_nexis/phone_finder.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module Scripts
- module InheritedProofing
- module Va
- module LexisNexis
- module PhoneFinder
- class << self
- def call(user_pii)
- proofer = if IdentityConfig.store.proofer_mock_fallback
- Proofing::Mock::AddressMockClient.new
- else
- Proofing::LexisNexis::PhoneFinder::Proofer.new(
- phone_finder_workflow: IdentityConfig.store.lexisnexis_phone_finder_workflow,
- account_id: IdentityConfig.store.lexisnexis_account_id,
- base_url: IdentityConfig.store.lexisnexis_base_url,
- username: IdentityConfig.store.lexisnexis_username,
- password: IdentityConfig.store.lexisnexis_password,
- request_mode: IdentityConfig.store.lexisnexis_request_mode,
- )
- end
-
- proofer.proof user_pii
- end
- end
- end
- end
- end
- end
-end
diff --git a/scripts/inherited_proofing/va/lexis_nexis/test_script.rb b/scripts/inherited_proofing/va/lexis_nexis/test_script.rb
deleted file mode 100644
index 7a3d17c5262..00000000000
--- a/scripts/inherited_proofing/va/lexis_nexis/test_script.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env ruby
-
-# rubocop:disable Layout/LineLength
-
-# Usage
-#
-# 1) Run with no ARGV and BASE_URI in the Idv::InheritedProofing::Va::Service
-# will default to a base uri of: IdentityConfig.store.inherited_proofing_va_base_url
-# and a private key using: AppArtifacts.store.oidc_private_key
-#
-# $ bin/rails r scripts/inherited_proofing/va/lexis_nexis/test_script.rb
-#
-# 2) To override BASE_URI in the Idv::InheritedProofing::Va::Service class
-# and/or use a private key file, and/or force an error return.
-# Where -u|-t|-f forces proofing to fail
-#
-# NOTE: Private key files are forced to be located at "#{Rails.root}/tmp".
-# $ bin/rails r scripts/inherited_proofing/va/lexis_nexis/test_script.rb https://staging-api.va.gov private.key -u|-t|-f
-
-require_relative '../user_attributes/test_server'
-require_relative './phone_finder'
-require_relative '../../errorable'
-
-def error_phone_or_default(fail_option:, default_phone:)
- return case fail_option
- when '-u'
- Scripts::InheritedProofing::Errorable.puts_message "Forcing unverifiable phone number failure (#{fail_option})"
- Proofing::Mock::AddressMockClient::UNVERIFIABLE_PHONE_NUMBER
- when '-t'
- Scripts::InheritedProofing::Errorable.puts_message "Forcing proofer timeout failure (#{fail_option})"
- Proofing::Mock::AddressMockClient::PROOFER_TIMEOUT_PHONE_NUMBER
- when '-f'
- Scripts::InheritedProofing::Errorable.puts_message "Forcing failed to contact phone number (#{fail_option})"
- Proofing::Mock::AddressMockClient::FAILED_TO_CONTACT_PHONE_NUMBER
- else
- default_phone
- end
-end
-
-raise 'You must run this from the command-line!' unless $PROGRAM_NAME == __FILE__
-
-Scripts::InheritedProofing::Errorable.puts_message "\nTesting call to Lexis Nexis Phone Finder - START"
-
-form, form_response = Scripts::InheritedProofing::Va::UserAttributes::TestServer.new(
- auth_code: 'mocked-auth-code-for-testing',
- base_uri: ARGV[0],
- private_key_file: ARGV[1],
-).run
-
-Scripts::InheritedProofing::Errorable.puts_message "Form response:\n\t#{form_response.to_h}"
-
-user_pii = form.payload_hash
-user_pii[:uuid] = SecureRandom.uuid
-# Lexis Nexis Phone Finder expects dob (as opposed to birth_date).
-user_pii[:dob] = user_pii.delete(:birth_date)
-user_pii[:phone] = error_phone_or_default fail_option: ARGV[2], default_phone: user_pii[:phone]
-user_pii.delete(:address)
-user_pii.delete(:mhv_data)
-
-Scripts::InheritedProofing::Errorable.puts_message "Calling Lexis Nexis Phone Finder using:\n\t#{user_pii}}"
-
-# Verify the user's pii.
-address_proofer_results = Scripts::InheritedProofing::Va::LexisNexis::PhoneFinder.call(user_pii)
-
-Scripts::InheritedProofing::Errorable.puts_message "Call to Lexis Nexis Phone Finder complete. Results:\n\t#{address_proofer_results.to_h}"
-
-Scripts::InheritedProofing::Errorable.puts_message "\nTesting call to Lexis Nexis Phone Finder - END"
-
-Scripts::InheritedProofing::Errorable.puts_message "\nDone."
-# rubocop:enable Layout/LineLength
diff --git a/scripts/inherited_proofing/va/user_attributes/test_script.rb b/scripts/inherited_proofing/va/user_attributes/test_script.rb
deleted file mode 100644
index 7586c86ee2e..00000000000
--- a/scripts/inherited_proofing/va/user_attributes/test_script.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env ruby
-
-# Usage
-#
-# 1) Run with no ARGV and BASE_URI in the Idv::InheritedProofing::Va::Service
-# will default to a base uri of: IdentityConfig.store.inherited_proofing_va_base_url
-# and a private key using: AppArtifacts.store.oidc_private_key
-#
-# $ bin/rails r scripts/inherited_proofing/va/user_attributes/test_script.rb
-#
-# 2) To override BASE_URI in the Idv::InheritedProofing::Va::Service class
-# and/or use a private key file:
-#
-# rubocop:disable Layout/LineLength
-# NOTE: Private key files are forced to be located at "#{Rails.root}/tmp".
-# $ bin/rails r scripts/inherited_proofing/va/user_attributes/test_script.rb https://staging-api.va.gov private.key
-# rubocop:enable Layout/LineLength
-
-require_relative '../../../../app/services/idv/inherited_proofing/va/service'
-require_relative '../../../../app/forms/idv/inherited_proofing/va/form'
-require_relative '../../errorable'
-require_relative './test_server'
-
-raise 'You must run this from the command-line!' unless $PROGRAM_NAME == __FILE__
-
-Scripts::InheritedProofing::Errorable.puts_message "\nTesting call to VA API - START\n\n"
-
-_form, form_response = Scripts::InheritedProofing::Va::UserAttributes::TestServer.new(
- auth_code: 'mocked-auth-code-for-testing',
- base_uri: ARGV[0],
- private_key_file: ARGV[1],
-).run
-
-Scripts::InheritedProofing::Errorable.puts_message "Form response:\n\t#{form_response.to_h}"
-
-Scripts::InheritedProofing::Errorable.puts_message "\nTesting call to VA API - END"
-
-Scripts::InheritedProofing::Errorable.puts_message "\nDone."
diff --git a/scripts/inherited_proofing/va/user_attributes/test_server.rb b/scripts/inherited_proofing/va/user_attributes/test_server.rb
deleted file mode 100644
index ce5a65b2e9b..00000000000
--- a/scripts/inherited_proofing/va/user_attributes/test_server.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-require_relative '../../errorable'
-
-module Scripts
- module InheritedProofing
- module Va
- module UserAttributes
- class TestServer < Idv::InheritedProofing::Va::Service
- include Errorable
-
- attr_reader :base_uri
-
- def initialize(auth_code:, private_key_file: nil, base_uri: nil)
- super({ auth_code: auth_code })
-
- if private_key_file.present?
- @private_key_file = force_tmp_private_key_file_name(private_key_file)
- end
- @base_uri = base_uri || BASE_URI
- end
-
- def run
- begin
- # rubocop:disable Layout/LineLength
- puts_message "Retrieving the user's PII from the VA using auth code: '#{auth_code}' at #{request_uri}..."
- puts_message "Retrieved payload containing the user's PII from the VA:\n\tRetrieved user PII: #{user_pii}"
- # rubocop:enable Layout/LineLength
-
- puts_message "Validating payload containing the user's PII from the VA..."
- if form_response.success?
- puts_success "Retrieved user PII is valid:\n\t#{user_pii}"
- else
- puts_error "Payload returned from the VA is invalid:" \
- "\n\t#{form.errors.full_messages}"
- end
- rescue => e
- puts_error e.message
- end
-
- [form, form_response]
- end
-
- private
-
- attr_reader :private_key_file
-
- # Override
- def request_uri
- @request_uri ||= "#{ URI(@base_uri) }/inherited_proofing/user_attributes"
- end
-
- def user_pii
- @user_pii ||= execute
- end
-
- def form
- @form ||= Idv::InheritedProofing::Va::Form.new(payload_hash: user_pii)
- end
-
- def form_response
- @form_response ||= form.submit
- end
-
- def private_key
- if private_key_file?
- if File.exist?(private_key_file)
- return OpenSSL::PKey::RSA.new(File.read(private_key_file))
- else
- puts_warning "private key file does not exist, using artifacts store: " \
- "#{private_key_file}"
- end
- end
-
- AppArtifacts.store.oidc_private_key
- end
-
- def private_key_file?
- @private_key_file.present?
- end
-
- # Always ensure we're referencing files in the /tmp/ folder!
- def force_tmp_private_key_file_name(private_key_file)
- "#{Rails.root}/tmp/#{File.basename(private_key_file)}"
- end
- end
- end
- end
- end
-end
diff --git a/scripts/va-api-test.rb b/scripts/va-api-test.rb
deleted file mode 100755
index f99e9b6e97d..00000000000
--- a/scripts/va-api-test.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'jwt'
-require 'jwe'
-require 'net/http'
-
-# Script to test connection to VA API, can be removed once we create code inside the IDV flow
-class VaApiTest
- def run
- uri = URI 'https://staging-api.va.gov/inherited_proofing/user_attributes'
- headers = { Authorization: "Bearer #{jwt_token}" }
-
- response = Net::HTTP.get_response(uri, headers)
- decrypt_payload(response)
- end
-
- private
-
- def jwt_token
- payload = { inherited_proofing_auth: 'mocked-auth-code-for-testing', exp: 1.day.from_now.to_i }
- JWT.encode(payload, private_key, 'RS256')
- end
-
- def decrypt_payload(response)
- payload = JSON.parse(response.body)['data']
- JWE.decrypt(payload, private_key) if payload
- end
-
- def private_key
- return AppArtifacts.store.oidc_private_key if private_key_store?
-
- OpenSSL::PKey::RSA.new(File.read(private_key_file))
- end
-
- # Returns true if a private key store should be used
- # (as opposed to the private key file).
- def private_key_store?
- Identity::Hostdata.in_datacenter? || !private_key_file?
- end
-
- def private_key_file?
- File.exist?(private_key_file)
- end
-
- def private_key_file
- @private_key_file ||= 'tmp/va_ip.key'
- end
-end
-
-puts(VaApiTest.new.run || 'VaApiTest#run returned no output') if $PROGRAM_NAME == __FILE__
diff --git a/spec/browsers_json_spec.rb b/spec/browsers_json_spec.rb
new file mode 100644
index 00000000000..6f4d69508cf
--- /dev/null
+++ b/spec/browsers_json_spec.rb
@@ -0,0 +1,14 @@
+require 'rails_helper'
+
+RSpec.describe 'browsers.json' do
+ before(:all) { system 'make browsers.json' }
+
+ subject(:browsers_json) { JSON.parse(File.read(Rails.root.join('browsers.json'))) }
+
+ it 'includes only keys known to BrowserSupport' do
+ actual_keys = browsers_json.map { |entry| entry.split(' ', 2).first }
+ known_keys = BrowserSupport::BROWSERSLIST_TO_BROWSER_MAP.keys.map(&:to_s)
+
+ expect(actual_keys - known_keys).to be_empty
+ end
+end
diff --git a/spec/controllers/concerns/idv_step_concern_spec.rb b/spec/controllers/concerns/idv_step_concern_spec.rb
index 1ddf2d87459..e60cc8692e9 100644
--- a/spec/controllers/concerns/idv_step_concern_spec.rb
+++ b/spec/controllers/concerns/idv_step_concern_spec.rb
@@ -9,16 +9,16 @@
module Idv
class StepController < ApplicationController
include IdvStepConcern
+
+ def show
+ render plain: 'Hello'
+ end
end
end
describe '#confirm_idv_needed' do
controller Idv::StepController do
before_action :confirm_idv_needed
-
- def show
- render plain: 'Hello'
- end
end
before(:each) do
@@ -55,4 +55,115 @@ def show
end
end
end
+
+ describe '#confirm_address_step_complete' do
+ controller Idv::StepController do
+ before_action :confirm_address_step_complete
+ end
+
+ before(:each) do
+ sign_in(user)
+ routes.draw do
+ get 'show' => 'idv/step#show'
+ end
+ end
+
+ context 'the user has completed phone confirmation' do
+ it 'does not redirect' do
+ idv_session.vendor_phone_confirmation = true
+ idv_session.user_phone_confirmation = true
+
+ get :show
+
+ expect(response.body).to eq('Hello')
+ expect(response.status).to eq(200)
+ end
+ end
+
+ context 'the user has not confirmed their phone OTP' do
+ it 'redirects to OTP confirmation' do
+ idv_session.vendor_phone_confirmation = true
+ idv_session.user_phone_confirmation = false
+
+ get :show
+
+ expect(response).to redirect_to(idv_otp_verification_url)
+ end
+ end
+
+ context 'the user has not confirmed their phone with the vendor' do
+ it 'redirects to phone confirmation' do
+ idv_session.vendor_phone_confirmation = false
+ idv_session.user_phone_confirmation = false
+
+ get :show
+
+ expect(response).to redirect_to(idv_otp_verification_url)
+ end
+ end
+
+ context 'the user has selected GPO for address confirmation' do
+ it 'does not redirect' do
+ idv_session.address_verification_mechanism = 'gpo'
+
+ get :show
+
+ expect(response.body).to eq('Hello')
+ expect(response.status).to eq(200)
+ end
+ end
+ end
+
+ describe '#confirm_verify_info_step_complete' do
+ controller Idv::StepController do
+ before_action :confirm_verify_info_step_complete
+ end
+
+ before(:each) do
+ sign_in(user)
+ routes.draw do
+ get 'show' => 'idv/step#show'
+ end
+ end
+
+ context 'the user has completed the verify info step' do
+ it 'does not redirect and renders the view' do
+ idv_session.profile_confirmation = true
+ idv_session.resolution_successful = 'phone'
+
+ get :show
+
+ expect(response.body).to eq('Hello')
+ expect(response.status).to eq(200)
+ end
+ end
+
+ context 'the user has not completed the verify info step' do
+ it 'redirects to the remote verify info step' do
+ idv_session.profile_confirmation = nil
+ idv_session.resolution_successful = nil
+
+ get :show
+
+ expect(response).to redirect_to(idv_verify_info_url)
+ end
+ end
+
+ context 'the user has not completed the verify info step with an in-person enrollment' do
+ it 'redirects to the in-person verify info step' do
+ idv_session.profile_confirmation = nil
+ idv_session.resolution_successful = nil
+
+ ProofingComponent.find_or_create_by(
+ user: user,
+ ).update!(
+ document_check: Idp::Constants::Vendors::USPS,
+ )
+
+ get :show
+
+ expect(response).to redirect_to(idv_in_person_verify_info_url)
+ end
+ end
+ end
end
diff --git a/spec/controllers/concerns/inherited_proofing_concern_spec.rb b/spec/controllers/concerns/inherited_proofing_concern_spec.rb
deleted file mode 100644
index 5796827f075..00000000000
--- a/spec/controllers/concerns/inherited_proofing_concern_spec.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe InheritedProofingConcern do
- subject do
- Class.new do
- include InheritedProofingConcern
- end.new
- end
-
- before do
- allow(IdentityConfig.store).to receive(:inherited_proofing_enabled).and_return(true)
- allow(subject).to receive(:va_inherited_proofing_auth_code).and_return auth_code
- end
-
- let(:auth_code) { Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE }
- let(:payload_hash) { Idv::InheritedProofing::Va::Mocks::Service::PAYLOAD_HASH }
-
- describe '#inherited_proofing?' do
- context 'when inherited proofing proofing is not effect' do
- let(:auth_code) { nil }
-
- it 'returns false' do
- expect(subject.inherited_proofing?).to eq false
- end
- end
-
- context 'when inherited proofing proofing is effect' do
- it 'returns true' do
- expect(subject.inherited_proofing?).to eq true
- end
- end
- end
-
- describe '#inherited_proofing_service_provider' do
- context 'when a service provider cannot be identified' do
- before do
- allow(subject).to receive(:va_inherited_proofing_auth_code).and_return nil
- end
-
- it 'returns nil' do
- expect(subject.inherited_proofing_service_provider).to eq nil
- end
- end
-
- context 'when a service provider can be identified' do
- let(:va) { :va }
-
- it 'returns the service provider' do
- expect(subject.inherited_proofing_service_provider).to eq va
- end
- end
- end
-
- describe '#va_inherited_proofing?' do
- context 'when the va auth code is present' do
- it 'returns true' do
- expect(subject.va_inherited_proofing?).to eq true
- end
- end
-
- context 'when the va auth code is not present' do
- let(:auth_code) { nil }
-
- it 'returns false' do
- expect(subject.va_inherited_proofing?).to eq false
- end
- end
- end
-
- describe '#va_inherited_proofing_auth_code_params_key' do
- it 'returns the correct va auth code url query param key' do
- expect(subject.va_inherited_proofing_auth_code_params_key).to eq 'inherited_proofing_auth'
- end
- end
-
- describe '#inherited_proofing_service_provider_data' do
- context 'when there is a va inherited proofing request' do
- it 'returns the correct service provider-specific data' do
- expect(subject.inherited_proofing_service_provider_data).to \
- eq({ auth_code: auth_code })
- end
- end
-
- context 'when the inherited proofing request cannot be identified' do
- let(:auth_code) { nil }
-
- it 'returns an empty hash' do
- expect(subject.inherited_proofing_service_provider_data).to eq({})
- end
- end
- end
-end
diff --git a/spec/controllers/concerns/verify_sp_attributes_concern_spec.rb b/spec/controllers/concerns/verify_sp_attributes_concern_spec.rb
index d6be336fdfa..1d6977ecd62 100644
--- a/spec/controllers/concerns/verify_sp_attributes_concern_spec.rb
+++ b/spec/controllers/concerns/verify_sp_attributes_concern_spec.rb
@@ -80,30 +80,6 @@
expect(consent_has_expired?).to eq(false)
end
end
-
- context 'when there is an active profile' do
- let(:sp_session_identity) do
- create(:service_provider_identity, last_consented_at: 15.days.ago, user: user)
- end
-
- before do
- create(:profile, :active, verified_at: verified_at, user: user)
- end
-
- context 'when the active profile was verified after last_consented_at' do
- let(:verified_at) { 5.days.ago }
- it 'is true because the new verified data needs to be consented to sharing' do
- expect(consent_has_expired?).to eq(true)
- end
- end
-
- context 'when the active profile was verified before last_consented_at' do
- let(:verified_at) { 20.days.ago }
- it 'is false' do
- expect(consent_has_expired?).to eq(false)
- end
- end
- end
end
describe '#consent_was_revoked?' do
@@ -199,6 +175,23 @@
expect(needs_completion_screen_reason).to be_nil
end
end
+
+ context 'when user is reverified' do
+ let(:verified_at) { 5.days.ago }
+ let(:sp_session_identity) do
+ build(
+ :service_provider_identity,
+ user: user,
+ last_consented_at: 15.days.ago,
+ )
+ end
+ before do
+ create(:profile, :active, verified_at: verified_at, user: user)
+ end
+ it 'is reverified_after_consent' do
+ expect(needs_completion_screen_reason).to eq(:reverified_after_consent)
+ end
+ end
end
end
@@ -208,4 +201,107 @@
end
end
end
+
+ describe '#reverified_after_consent?' do
+ let(:sp_session_identity) { build(:service_provider_identity, user: user) }
+ let(:user) { build(:user) }
+
+ before do
+ allow(controller).to receive(:current_user).and_return(user)
+ allow(controller).to receive(:sp_session_identity).and_return(sp_session_identity)
+ end
+
+ subject(:reverified_after_consent?) do
+ controller.reverified_after_consent?(sp_session_identity)
+ end
+
+ context 'when there is no sp_session_identity' do
+ let(:sp_session_identity) { nil }
+ it 'is false' do
+ expect(reverified_after_consent?).to eq(false)
+ end
+ end
+
+ context 'when there is no last_consented_at' do
+ it 'is false' do
+ expect(reverified_after_consent?).to eq(false)
+ end
+ end
+
+ context 'when last_consented_at within one year' do
+ let(:sp_session_identity) { build(:service_provider_identity, last_consented_at: 5.days.ago) }
+
+ it 'is false' do
+ expect(reverified_after_consent?).to eq(false)
+ end
+ end
+
+ context 'when the last_consented_at is older than a year ago' do
+ let(:sp_session_identity) do
+ build(:service_provider_identity, last_consented_at: 2.years.ago)
+ end
+
+ it 'is false' do
+ expect(reverified_after_consent?).to eq(false)
+ end
+ end
+
+ context 'when last_consented_at is nil but created_at is within a year' do
+ let(:sp_session_identity) do
+ build(:service_provider_identity, last_consented_at: nil, created_at: 4.days.ago)
+ end
+
+ it 'is false' do
+ expect(reverified_after_consent?).to eq(false)
+ end
+ end
+
+ context 'when last_consented_at is nil and created_at is older than a year' do
+ let(:sp_session_identity) do
+ build(:service_provider_identity, last_consented_at: nil, created_at: 4.years.ago)
+ end
+
+ it 'is false' do
+ expect(reverified_after_consent?).to eq(false)
+ end
+ end
+
+ context 'when the identity has been soft-deleted (consent has been revoked)' do
+ let(:sp_session_identity) do
+ build(
+ :service_provider_identity,
+ deleted_at: 1.day.ago,
+ last_consented_at: 2.years.ago,
+ )
+ end
+
+ it 'is false' do
+ expect(reverified_after_consent?).to eq(false)
+ end
+ end
+
+ context 'when there is an active profile' do
+ let(:sp_session_identity) do
+ create(:service_provider_identity, last_consented_at: 15.days.ago, user: user)
+ end
+
+ before do
+ create(:profile, :active, verified_at: verified_at, user: user)
+ end
+
+ context 'when the active profile was verified after last_consented_at' do
+ let(:verified_at) { 5.days.ago }
+ it 'is true because the new verified data needs to be consented to sharing' do
+ expect(reverified_after_consent?).to eq(true)
+ end
+ end
+
+ context 'when the active profile was verified before last_consented_at' do
+ let(:verified_at) { 20.days.ago }
+ it 'is false' do
+ expect(reverified_after_consent?).to eq(false)
+ end
+ end
+ end
+ end
end
diff --git a/spec/controllers/idv/doc_auth_controller_spec.rb b/spec/controllers/idv/doc_auth_controller_spec.rb
index 3aadf2c879a..7170c1abfd5 100644
--- a/spec/controllers/idv/doc_auth_controller_spec.rb
+++ b/spec/controllers/idv/doc_auth_controller_spec.rb
@@ -142,7 +142,7 @@
it 'finishes the flow' do
get :show, params: { step: 'welcome' }
- expect(response).to redirect_to idv_review_url
+ expect(response).to redirect_to idv_ssn_url
end
end
end
@@ -155,19 +155,18 @@
result = {
success: true,
errors: {},
- step: 'ssn',
+ step: 'agreement',
flow_path: 'standard',
step_count: 1,
- pii_like_keypaths: [[:errors, :ssn], [:error_details, :ssn]],
irs_reproofing: false,
analytics_id: 'Doc Auth',
acuant_sdk_upgrade_ab_test_bucket: :default,
}
- put :update, params: { step: 'ssn', doc_auth: { step: 'ssn', ssn: '111-11-1111' } }
+ put :update, params: { step: 'agreement', doc_auth: { ial2_consent_given: '1' } }
expect(@analytics).to have_received(:track_event).with(
- 'IdV: doc auth ssn submitted', result
+ 'IdV: doc auth agreement submitted', result
)
end
@@ -176,20 +175,20 @@
allow_any_instance_of(Flow::BaseFlow).to \
receive(:flow_session).and_return(pii_from_doc: {})
- put :update, params: { step: 'ssn', doc_auth: { step: 'ssn', ssn: '666-66-6666' } }
- put :update, params: { step: 'ssn', doc_auth: { step: 'ssn', ssn: '111-11-1111' } }
+ put :update, params: { step: 'agreement', doc_auth: { ial2_consent_given: '1' } }
+ put :update, params: { step: 'agreement', doc_auth: { ial2_consent_given: '1' } }
expect(@analytics).to have_received(:track_event).with(
- 'IdV: doc auth ssn submitted',
+ 'IdV: doc auth agreement submitted',
hash_including(
- step: 'ssn',
+ step: 'agreement',
step_count: 1,
acuant_sdk_upgrade_ab_test_bucket: :default,
),
)
expect(@analytics).to have_received(:track_event).with(
- 'IdV: doc auth ssn submitted',
- hash_including(step: 'ssn', step_count: 2),
+ 'IdV: doc auth agreement submitted',
+ hash_including(step: 'agreement', step_count: 2),
)
end
@@ -233,7 +232,7 @@
it 'finishes the flow' do
put :update, params: { step: 'ssn' }
- expect(response).to redirect_to idv_review_url
+ expect(response).to redirect_to idv_ssn_url
end
end
end
diff --git a/spec/controllers/idv/document_capture_controller_spec.rb b/spec/controllers/idv/document_capture_controller_spec.rb
new file mode 100644
index 00000000000..71f3d831ee0
--- /dev/null
+++ b/spec/controllers/idv/document_capture_controller_spec.rb
@@ -0,0 +1,103 @@
+require 'rails_helper'
+
+describe Idv::DocumentCaptureController do
+ include IdvHelper
+
+ let(:flow_session) do
+ { 'document_capture_session_uuid' => 'fd14e181-6fb1-4cdc-92e0-ef66dad0df4e',
+ 'pii_from_doc' => Idp::Constants::MOCK_IDV_APPLICANT.dup,
+ :threatmetrix_session_id => 'c90ae7a5-6629-4e77-b97c-f1987c2df7d0',
+ :flow_path => 'standard' }
+ end
+
+ let(:user) { build(:user) }
+ let(:service_provider) do
+ create(
+ :service_provider,
+ issuer: 'http://sp.example.com',
+ app_id: '123',
+ )
+ end
+
+ let(:default_sdk_version) { IdentityConfig.store.idv_acuant_sdk_version_default }
+ let(:alternate_sdk_version) { IdentityConfig.store.idv_acuant_sdk_version_alternate }
+
+ before do
+ allow(subject).to receive(:flow_session).and_return(flow_session)
+ stub_sign_in(user)
+ end
+
+ describe 'before_actions' do
+ it 'checks that feature flag is enabled' do
+ expect(subject).to have_actions(
+ :before,
+ :render_404_if_document_capture_controller_disabled,
+ )
+ end
+
+ it 'includes authentication before_action' do
+ expect(subject).to have_actions(
+ :before,
+ :confirm_two_factor_authenticated,
+ )
+ end
+ end
+
+ context 'when doc_auth_document_capture_controller_enabled' do
+ before do
+ allow(IdentityConfig.store).to receive(:doc_auth_document_capture_controller_enabled).
+ and_return(true)
+ stub_analytics
+ stub_attempts_tracker
+ allow(@analytics).to receive(:track_event)
+ end
+
+ describe '#show' do
+ let(:analytics_name) { 'IdV: doc auth document_capture visited' }
+ let(:analytics_args) do
+ {
+ analytics_id: 'Doc Auth',
+ flow_path: 'standard',
+ irs_reproofing: false,
+ step: 'document capture',
+ step_count: 1,
+ }
+ end
+
+ context '#show' do
+ it 'renders the show template' do
+ get :show
+
+ expect(response).to render_template :show
+ end
+
+ it 'sends analytics_visited event' do
+ get :show
+
+ expect(@analytics).to have_received(:track_event).with(analytics_name, analytics_args)
+ end
+
+ it 'sends correct step count to analytics' do
+ get :show
+ get :show
+ analytics_args[:step_count] = 2
+
+ expect(@analytics).to have_received(:track_event).with(analytics_name, analytics_args)
+ end
+ end
+ end
+ end
+
+ context 'when doc_auth_document_capture_controller_enabled is false' do
+ before do
+ allow(IdentityConfig.store).to receive(:doc_auth_document_capture_controller_enabled).
+ and_return(false)
+ end
+
+ it 'returns 404' do
+ get :show
+
+ expect(response.status).to eq(404)
+ end
+ end
+end
diff --git a/spec/controllers/idv/image_uploads_controller_spec.rb b/spec/controllers/idv/image_uploads_controller_spec.rb
index 56946a2834c..adc7a82cfae 100644
--- a/spec/controllers/idv/image_uploads_controller_spec.rb
+++ b/spec/controllers/idv/image_uploads_controller_spec.rb
@@ -73,7 +73,7 @@
any_args,
)
- expect(@irs_attempts_api_tracker).not_to receive(:track_event).with(
+ expect(@irs_attempts_api_tracker).to receive(:track_event).with(
:idv_document_upload_submitted,
any_args,
)
@@ -129,9 +129,21 @@
flow_path: 'standard',
)
- expect(@irs_attempts_api_tracker).not_to receive(:track_event).with(
+ expect(@irs_attempts_api_tracker).to receive(:track_event).with(
:idv_document_upload_submitted,
- any_args,
+ { address: nil,
+ date_of_birth: nil,
+ document_back_image_filename: nil,
+ document_expiration: nil,
+ document_front_image_filename: nil,
+ document_image_encryption_key: nil,
+ document_issued: nil,
+ document_number: nil,
+ document_state: nil,
+ failure_reason: { front: ['The selection was not a valid file.'] },
+ first_name: nil,
+ last_name: nil,
+ success: false },
)
expect(@analytics).not_to receive(:track_event).with(
@@ -229,9 +241,27 @@
flow_path: 'standard',
)
- expect(@irs_attempts_api_tracker).not_to receive(:track_event).with(
+ expect(@irs_attempts_api_tracker).to receive(:track_event).with(
+ :idv_document_upload_rate_limited,
+ )
+
+ # This is the last upload which triggers the rate limit, apparently.
+ # I do find this moderately confusing.
+ expect(@irs_attempts_api_tracker).to receive(:track_event).with(
:idv_document_upload_submitted,
- any_args,
+ { address: nil,
+ date_of_birth: nil,
+ document_back_image_filename: nil,
+ document_expiration: nil,
+ document_front_image_filename: nil,
+ document_image_encryption_key: nil,
+ document_issued: nil,
+ document_number: nil,
+ document_state: nil,
+ failure_reason: { limit: ['We could not verify your ID'] },
+ first_name: nil,
+ last_name: nil,
+ success: false },
)
expect(@analytics).not_to receive(:track_event).with(
diff --git a/spec/controllers/idv/inherited_proofing_cancellations_controller_spec.rb b/spec/controllers/idv/inherited_proofing_cancellations_controller_spec.rb
deleted file mode 100644
index 86451d87906..00000000000
--- a/spec/controllers/idv/inherited_proofing_cancellations_controller_spec.rb
+++ /dev/null
@@ -1,245 +0,0 @@
-require 'rails_helper'
-
-shared_examples 'an HTML 404 not found' do
- it 'returns a 404 not found' do
- expect(response).to have_http_status(:not_found)
- end
-end
-
-describe Idv::InheritedProofingCancellationsController do
- let(:step) { Idv::Flows::InheritedProofingFlow::STEPS.keys.first }
-
- describe 'before_actions' do
- it 'includes before_actions from IdvSession' do
- expect(subject).to have_actions(:before, :redirect_if_sp_context_needed)
- end
-
- it 'includes before_actions from InheritedProofing404Concern' do
- expect(subject).to have_actions(:before, :render_404_if_disabled)
- end
-
- it 'includes before_actions from AllowlistedFlowStepConcern' do
- expect(subject).to have_actions(:before, :flow_step!)
- end
- end
-
- describe '#new' do
- let(:go_back_path) { '/path/to/return' }
-
- before do
- allow(controller).to receive(:go_back_path).and_return(go_back_path)
- end
-
- context 'when the inherited proofing feature flipper is turned off' do
- before do
- allow(IdentityConfig.store).to receive(:inherited_proofing_enabled).and_return(false)
- stub_sign_in
- end
-
- describe '#new' do
- before do
- get :new, params: { step: step }
- end
-
- it_behaves_like 'an HTML 404 not found'
- end
-
- describe '#update' do
- before do
- get :update, params: { step: step }
- end
-
- it_behaves_like 'an HTML 404 not found'
- end
-
- describe '#destroy' do
- before do
- get :destroy, params: { step: step }
- end
-
- it_behaves_like 'an HTML 404 not found'
- end
- end
-
- context 'when the flow step is not in the allowed list' do
- before do
- stub_sign_in
- end
-
- let(:step) { :not_found_step }
- let(:expected_logger_warning) { "Flow step param \"#{step})\" was not whitelisted!" }
-
- describe '#new' do
- before do
- expect(Rails.logger).to receive(:warn).with(expected_logger_warning)
- get :new, params: { step: step }
- end
-
- it_behaves_like 'an HTML 404 not found'
- end
-
- describe '#update' do
- before do
- expect(Rails.logger).to receive(:warn).with(expected_logger_warning)
- get :update, params: { step: step }
- end
-
- it_behaves_like 'an HTML 404 not found'
- end
-
- describe '#destroy' do
- before do
- expect(Rails.logger).to receive(:warn).with(expected_logger_warning)
- get :destroy, params: { step: step }
- end
-
- it_behaves_like 'an HTML 404 not found'
- end
- end
-
- context 'when there is no session' do
- it 'redirects to root' do
- get :new
-
- expect(response).to redirect_to(root_url)
- end
- end
-
- context 'when there is a session' do
- subject(:action) do
- get :new, params: { step: step }
- end
-
- before do
- stub_sign_in
- end
-
- it 'renders template' do
- action
-
- expect(response).to render_template(:new)
- end
-
- it 'stores go back path' do
- action
-
- expect(controller.user_session[:idv][:go_back_path]).to eq(go_back_path)
- end
-
- it 'tracks the event in analytics' do
- stub_analytics
- request.env['HTTP_REFERER'] = 'https://example.com/'
-
- expect(@analytics).to receive(:track_event).with(
- 'IdV: cancellation visited',
- request_came_from: 'users/sessions#new',
- step: step.to_s,
- proofing_components: nil,
- analytics_id: nil,
- )
-
- action
- end
- end
- end
-
- describe '#update' do
- subject(:action) do
- put :update, params: { step: step, cancel: 'true' }
- end
-
- before do
- stub_sign_in
- end
-
- it 'redirects to idv_inherited_proofing_path' do
- action
-
- expect(response).to redirect_to idv_inherited_proofing_url
- end
-
- context 'when a go back path is stored in session' do
- let(:go_back_path) { '/path/to/return' }
-
- before do
- allow(controller).to receive(:user_session).and_return(
- idv: { go_back_path: go_back_path },
- )
- end
-
- it 'redirects to go back path' do
- action
-
- expect(response).to redirect_to go_back_path
- end
- end
-
- it 'tracks the event in analytics' do
- stub_analytics
- request.env['HTTP_REFERER'] = 'https://example.com/'
-
- expect(@analytics).to receive(:track_event).with(
- 'IdV: cancellation go back',
- request_came_from: 'users/sessions#new',
- step: step.to_s,
- proofing_components: nil,
- analytics_id: nil,
- )
-
- action
- end
- end
-
- describe '#destroy' do
- subject(:action) do
- delete :destroy, params: { step: step }
- end
-
- context 'when there is no session' do
- it 'redirects to root' do
- action
-
- expect(response).to redirect_to(root_url)
- end
- end
-
- context 'when there is a session' do
- let(:user) { create(:user) }
-
- before do
- stub_sign_in user
- allow(controller).to receive(:user_session).
- and_return(idv: { go_back_path: '/path/to/return' })
- end
-
- it 'destroys session' do
- expect(controller).to receive(:cancel_session).once
-
- action
- end
-
- it 'renders a json response with the redirect path set to account_path' do
- action
-
- parsed_body = JSON.parse(response.body, symbolize_names: true)
- expect(response).not_to render_template(:destroy)
- expect(parsed_body).to eq({ redirect_url: account_path })
- end
-
- it 'tracks the event in analytics' do
- stub_analytics
- request.env['HTTP_REFERER'] = 'https://example.com/'
-
- expect(@analytics).to receive(:track_event).with(
- 'IdV: cancellation confirmed',
- request_came_from: 'users/sessions#new',
- step: step.to_s,
- proofing_components: nil,
- analytics_id: nil,
- )
-
- action
- end
- end
- end
-end
diff --git a/spec/controllers/idv/inherited_proofing_controller_spec.rb b/spec/controllers/idv/inherited_proofing_controller_spec.rb
deleted file mode 100644
index 2fc7541ff39..00000000000
--- a/spec/controllers/idv/inherited_proofing_controller_spec.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-require 'rails_helper'
-
-shared_examples 'the flow steps work correctly' do
- describe '#index' do
- it 'redirects to the first step' do
- get :index
-
- expect(response).to redirect_to idv_inherited_proofing_step_url(step: :get_started)
- end
-
- context 'when the inherited proofing feature flag is disabled' do
- it 'returns 404 not found' do
- allow(IdentityConfig.store).to receive(:inherited_proofing_enabled).and_return(false)
-
- get :index
-
- expect(response).to have_http_status(:not_found)
- end
- end
- end
-
- describe '#show' do
- it 'renders the correct template' do
- expect(subject).to receive(:render).with(
- template: 'layouts/flow_step',
- locals: hash_including(
- :flow_session,
- flow_namespace: 'idv',
- step_template: 'idv/inherited_proofing/get_started',
- step_indicator: hash_including(
- :steps,
- current_step: :getting_started,
- ),
- ),
- ).and_call_original
-
- get :show, params: { step: 'get_started' }
- end
-
- it 'redirects to the configured next step' do
- mock_next_step(:some_next_step)
- get :show, params: { step: 'getting_started' }
-
- expect(response).to redirect_to idv_inherited_proofing_step_url(:some_next_step)
- end
-
- it 'redirects to the first step if a non-existent step is given' do
- get :show, params: { step: 'non_existent_step' }
-
- expect(response).to redirect_to idv_inherited_proofing_step_url(step: :get_started)
- end
- end
-end
-
-def mock_next_step(step)
- allow_any_instance_of(Idv::Flows::InheritedProofingFlow).to receive(:next_step).and_return(step)
-end
-
-describe Idv::InheritedProofingController do
- let(:sp) { nil }
- let(:user) { build(:user) }
-
- before do
- allow(controller).to receive(:current_sp).and_return(sp)
- stub_sign_in(user)
- end
-
- context 'when VA inherited proofing mock is enabled' do
- before do
- allow(IdentityConfig.store).to receive(:va_inherited_proofing_mock_enabled).and_return(true)
- end
-
- it_behaves_like 'the flow steps work correctly'
- end
-
- context 'when VA inherited proofing mock is not enabled' do
- before do
- allow(IdentityConfig.store).to receive(:va_inherited_proofing_mock_enabled).and_return(false)
- end
-
- it_behaves_like 'the flow steps work correctly'
- end
-end
diff --git a/spec/controllers/idv/otp_verification_controller_spec.rb b/spec/controllers/idv/otp_verification_controller_spec.rb
index 8f7cbcd326a..e1dec31b047 100644
--- a/spec/controllers/idv/otp_verification_controller_spec.rb
+++ b/spec/controllers/idv/otp_verification_controller_spec.rb
@@ -46,7 +46,7 @@
it 'redirects to the delivery method path' do
get :show
- expect(response).to redirect_to(idv_otp_delivery_method_path)
+ expect(response).to redirect_to(idv_phone_url)
end
end
@@ -76,7 +76,7 @@
it 'redirects to otp delivery method selection' do
put :update, params: otp_code_param
- expect(response).to redirect_to(idv_otp_delivery_method_path)
+ expect(response).to redirect_to(idv_phone_url)
end
end
diff --git a/spec/controllers/idv/phone_controller_spec.rb b/spec/controllers/idv/phone_controller_spec.rb
index c91fc19a7da..8c60e77ca28 100644
--- a/spec/controllers/idv/phone_controller_spec.rb
+++ b/spec/controllers/idv/phone_controller_spec.rb
@@ -17,7 +17,7 @@
expect(subject).to have_actions(
:before,
:confirm_two_factor_authenticated,
- :confirm_idv_applicant_created,
+ :confirm_verify_info_step_complete,
)
end
end
diff --git a/spec/controllers/idv/review_controller_spec.rb b/spec/controllers/idv/review_controller_spec.rb
index a5782b567bc..80e1b1a203a 100644
--- a/spec/controllers/idv/review_controller_spec.rb
+++ b/spec/controllers/idv/review_controller_spec.rb
@@ -19,7 +19,9 @@
service_provider: nil,
)
idv_session.profile_confirmation = true
+ idv_session.resolution_successful = 'phone'
idv_session.vendor_phone_confirmation = true
+ idv_session.user_phone_confirmation = true
idv_session.applicant = applicant.with_indifferent_access
idv_session
end
@@ -34,8 +36,8 @@
expect(subject).to have_actions(
:before,
:confirm_two_factor_authenticated,
- :confirm_idv_applicant_created,
- :confirm_idv_steps_complete,
+ :confirm_verify_info_step_complete,
+ :confirm_address_step_complete,
)
end
@@ -68,63 +70,7 @@ def show
it 'redirects to address step' do
get :show
- expect(response).to redirect_to idv_phone_path
- end
- end
- end
-
- describe '#confirm_idv_phone_confirmed' do
- controller do
- before_action :confirm_idv_phone_confirmed
-
- def show
- render plain: 'Hello'
- end
- end
-
- before(:each) do
- stub_sign_in(user)
- allow(subject).to receive(:idv_session).and_return(idv_session)
- routes.draw do
- get 'show' => 'idv/review#show'
- end
- end
-
- context 'user is verifying by mail' do
- before do
- allow(idv_session).to receive(:address_verification_mechanism).and_return('gpo')
- end
-
- it 'does not redirect' do
- get :show
-
- expect(response.body).to eq 'Hello'
- end
- end
-
- context 'user phone is confirmed' do
- before do
- allow(idv_session).to receive(:address_verification_mechanism).and_return('phone')
- allow(idv_session).to receive(:phone_confirmed?).and_return(true)
- end
-
- it 'does not redirect' do
- get :show
-
- expect(response.body).to eq 'Hello'
- end
- end
-
- context 'user phone is not confirmed' do
- before do
- allow(idv_session).to receive(:address_verification_mechanism).and_return('phone')
- allow(idv_session).to receive(:phone_confirmed?).and_return(false)
- end
-
- it 'redirects to phone confirmation' do
- get :show
-
- expect(response).to redirect_to idv_otp_verification_path
+ expect(response).to redirect_to idv_otp_verification_url
end
end
end
diff --git a/spec/controllers/idv/sessions_controller_spec.rb b/spec/controllers/idv/sessions_controller_spec.rb
index faa34fca6b7..4b9bf2396e1 100644
--- a/spec/controllers/idv/sessions_controller_spec.rb
+++ b/spec/controllers/idv/sessions_controller_spec.rb
@@ -15,7 +15,6 @@
allow(subject).to receive(:idv_session).and_return(idv_session)
controller.user_session['idv/doc_auth'] = flow_session
controller.user_session['idv/in_person'] = flow_session
- controller.user_session['idv/inherited_proofing'] = flow_session
controller.user_session[:decrypted_pii] = pii
end
@@ -37,10 +36,6 @@
expect(controller.user_session['idv/in_person']).to be_blank
end
- it 'clears the idv/inherited_proofing session' do
- expect(controller.user_session['idv/inherited_proofing']).to be_blank
- end
-
it 'clears the decrypted_pii session' do
expect(controller.user_session[:decrypted_pii]).to be_blank
end
diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb
index 5a4509a1571..ef51bd651bd 100644
--- a/spec/controllers/idv/verify_info_controller_spec.rb
+++ b/spec/controllers/idv/verify_info_controller_spec.rb
@@ -60,6 +60,7 @@
stub_analytics
stub_attempts_tracker
allow(@analytics).to receive(:track_event)
+ allow(@irs_attempts_api_tracker).to receive(:track_event)
end
it 'renders the show template' do
@@ -119,6 +120,14 @@
end
end
+ it 'redirects to ssn controller when ssn info is missing' do
+ flow_session[:pii_from_doc][:ssn] = nil
+
+ get :show
+
+ expect(response).to redirect_to(idv_ssn_url)
+ end
+
context 'when the user is ssn throttled' do
before do
Throttle.new(
@@ -129,21 +138,6 @@
).increment_to_throttled!
end
- context 'when using new ssn controller' do
- before do
- allow(IdentityConfig.store).to receive(:doc_auth_ssn_controller_enabled).
- and_return(true)
- end
-
- it 'redirects to ssn controller when ssn info is missing' do
- flow_session[:pii_from_doc][:ssn] = nil
-
- get :show
-
- expect(response).to redirect_to(idv_ssn_url)
- end
- end
-
it 'redirects to ssn failure url' do
get :show
@@ -179,6 +173,92 @@
get :show
end
end
+
+ context 'when proofing_device_profiling is enabled' do
+ let(:idv_result) do
+ {
+ context: {
+ stages: {
+ threatmetrix: {
+ transaction_id: 1,
+ review_status: review_status,
+ response_body: {
+ tmx_summary_reason_code: ['Identity_Negative_History'],
+ },
+ },
+ },
+ },
+ errors: {},
+ exception: nil,
+ success: true,
+ }
+ end
+
+ let(:document_capture_session) do
+ document_capture_session = DocumentCaptureSession.create!(user: user)
+ document_capture_session.create_proofing_session
+ document_capture_session.store_proofing_result(idv_result)
+ document_capture_session
+ end
+
+ let(:expected_failure_reason) { DocAuthHelper::SAMPLE_TMX_SUMMARY_REASON_CODE }
+
+ before do
+ controller.
+ idv_session.verify_info_step_document_capture_session_uuid = document_capture_session.uuid
+ allow(IdentityConfig.store).to receive(:proofing_device_profiling).and_return(:enabled)
+ allow(IdentityConfig.store).to receive(:irs_attempt_api_track_tmx_fraud_check_event).
+ and_return(true)
+ end
+
+ context 'when threatmetrix response is Pass' do
+ let(:review_status) { 'pass' }
+
+ it 'it logs IRS idv_tmx_fraud_check event' do
+ expect(@irs_attempts_api_tracker).to receive(:idv_tmx_fraud_check).with(
+ success: true,
+ failure_reason: nil,
+ )
+ get :show
+ end
+ end
+
+ context 'when threatmetrix response is No Result' do
+ let(:review_status) { 'no_result' }
+
+ it 'it logs IRS idv_tmx_fraud_check event' do
+ expect(@irs_attempts_api_tracker).to receive(:idv_tmx_fraud_check).with(
+ success: false,
+ failure_reason: expected_failure_reason,
+ )
+ get :show
+ end
+ end
+
+ context 'when threatmetrix response is Reject' do
+ let(:review_status) { 'reject' }
+
+ it 'it logs IRS idv_tmx_fraud_check event' do
+ expect(@irs_attempts_api_tracker).to receive(:idv_tmx_fraud_check).with(
+ success: false,
+ failure_reason: expected_failure_reason,
+ )
+ get :show
+ end
+ end
+
+ context 'when threatmetrix response is Review' do
+ let(:review_status) { 'review' }
+
+ it 'it logs IRS idv_tmx_fraud_check event' do
+ expect(@irs_attempts_api_tracker).to receive(:idv_tmx_fraud_check).with(
+ success: false,
+ failure_reason: expected_failure_reason,
+ )
+ get :show
+ end
+ end
+ end
end
describe '#update' do
diff --git a/spec/controllers/idv_controller_spec.rb b/spec/controllers/idv_controller_spec.rb
index 8775f2e6003..d7f379b73a9 100644
--- a/spec/controllers/idv_controller_spec.rb
+++ b/spec/controllers/idv_controller_spec.rb
@@ -70,13 +70,6 @@
expect(response).to redirect_to idv_doc_auth_path
end
- it 'redirects to inherited proofing with a VA inherited proofing session' do
- allow(controller).to receive(:va_inherited_proofing?).and_return(true)
-
- get :index
- expect(response).to redirect_to idv_inherited_proofing_path
- end
-
context 'no SP context' do
let(:user) { build(:user, password: ControllerHelper::VALID_PASSWORD) }
@@ -131,7 +124,6 @@
get :activated
expect(response).to render_template(:activated)
- expect(subject.idv_session.alive?).to eq false
end
end
diff --git a/spec/controllers/openid_connect/authorization_controller_spec.rb b/spec/controllers/openid_connect/authorization_controller_spec.rb
index 169aa997467..d0156405b7d 100644
--- a/spec/controllers/openid_connect/authorization_controller_spec.rb
+++ b/spec/controllers/openid_connect/authorization_controller_spec.rb
@@ -421,28 +421,6 @@
end
end
- context 'with an inherited_proofing_auth code' do
- before do
- params[inherited_proofing_auth_key] = inherited_proofing_auth_value
- action
- end
-
- let(:inherited_proofing_auth_key) { 'inherited_proofing_auth' }
- let(:inherited_proofing_auth_value) { SecureRandom.hex }
- let(:decorated_session) { controller.view_context.decorated_session }
-
- it 'persists the inherited_proofing_auth value' do
- expect(decorated_session.request_url_params[inherited_proofing_auth_key]).to \
- eq inherited_proofing_auth_value
- end
-
- it 'redirects to SP landing page with the request_id in the params' do
- sp_request_id = ServiceProviderRequestProxy.last.uuid
-
- expect(response).to redirect_to new_user_session_url(request_id: sp_request_id)
- end
- end
-
it 'redirects to SP landing page with the request_id in the params' do
action
sp_request_id = ServiceProviderRequestProxy.last.uuid
diff --git a/spec/features/idv/actions/redo_document_capture_action_spec.rb b/spec/features/idv/actions/redo_document_capture_action_spec.rb
index 19dd5d685cd..55dde9e3f43 100644
--- a/spec/features/idv/actions/redo_document_capture_action_spec.rb
+++ b/spec/features/idv/actions/redo_document_capture_action_spec.rb
@@ -29,6 +29,9 @@
DocAuth::Mock::DocAuthMockClient.reset!
attach_and_submit_images
+ expect(current_path).to eq(idv_ssn_path)
+ fill_out_ssn_form_with_ssn_that_fails_resolution
+ click_on t('forms.buttons.submit.update')
expect(current_path).to eq(idv_verify_info_path)
check t('forms.ssn.show')
expect(page).to have_content(DocAuthHelper::SSN_THAT_FAILS_RESOLUTION)
@@ -62,6 +65,9 @@
DocAuth::Mock::DocAuthMockClient.reset!
attach_and_submit_images
+ expect(current_path).to eq(idv_ssn_path)
+ fill_out_ssn_form_with_ssn_that_fails_resolution
+ click_on t('forms.buttons.submit.update')
expect(current_path).to eq(idv_verify_info_path)
check t('forms.ssn.show')
expect(page).to have_content(DocAuthHelper::SSN_THAT_FAILS_RESOLUTION)
diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb
index 1eb36c17a9b..ba1a8c83be5 100644
--- a/spec/features/idv/analytics_spec.rb
+++ b/spec/features/idv/analytics_spec.rb
@@ -26,7 +26,7 @@
'IdV: doc auth ssn submitted' => { success: true, errors: {}, flow_path: 'standard', step: 'ssn', step_count: 1, acuant_sdk_upgrade_ab_test_bucket: :default, analytics_id: 'Doc Auth', irs_reproofing: false },
'IdV: doc auth verify visited' => { flow_path: 'standard', step: 'verify', step_count: 1, acuant_sdk_upgrade_ab_test_bucket: :default, analytics_id: 'Doc Auth', irs_reproofing: false },
'IdV: doc auth verify submitted' => { flow_path: 'standard', step: 'verify', step_count: 1, acuant_sdk_upgrade_ab_test_bucket: :default, analytics_id: 'Doc Auth', irs_reproofing: false },
- 'IdV: doc auth verify proofing results' => { success: true, errors: {}, address_edited: false, ssn_is_unique: true, proofing_results: { exception: nil, timed_out: false, context: { adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil, drivers_license_check_info: nil }, state_id: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' } } } } },
+ 'IdV: doc auth verify proofing results' => { success: true, errors: {}, address_edited: false, address_line2_present: false, ssn_is_unique: true, proofing_results: { exception: nil, timed_out: false, context: { adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil, drivers_license_check_info: nil }, state_id: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' } } } } },
'IdV: phone of record visited' => { proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis' } },
'IdV: phone confirmation form' => { success: true, errors: {}, phone_type: :mobile, types: [:fixed_or_mobile], carrier: 'Test Mobile Carrier', country_code: 'US', area_code: '202', proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis' }, otp_delivery_preference: 'sms' },
'IdV: phone confirmation vendor' => { success: true, errors: {}, vendor: { exception: nil, vendor_name: 'AddressMock', transaction_id: 'address-mock-transaction-id-123', timed_out: false, reference: '' }, new_phone_added: false, proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', address_check: 'lexis_nexis_address' }, area_code: '202', country_code: 'US', phone_fingerprint: anything },
@@ -61,7 +61,7 @@
'IdV: doc auth ssn submitted' => { success: true, errors: {}, flow_path: 'standard', step: 'ssn', step_count: 1, acuant_sdk_upgrade_ab_test_bucket: :default, analytics_id: 'Doc Auth', irs_reproofing: false },
'IdV: doc auth verify visited' => { flow_path: 'standard', step: 'verify', step_count: 1, acuant_sdk_upgrade_ab_test_bucket: :default, analytics_id: 'Doc Auth', irs_reproofing: false },
'IdV: doc auth verify submitted' => { flow_path: 'standard', step: 'verify', step_count: 1, acuant_sdk_upgrade_ab_test_bucket: :default, analytics_id: 'Doc Auth', irs_reproofing: false },
- 'IdV: doc auth verify proofing results' => { success: true, errors: {}, address_edited: false, ssn_is_unique: true, proofing_results: { exception: nil, timed_out: false, context: { adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil, drivers_license_check_info: nil }, state_id: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' } } } } },
+ 'IdV: doc auth verify proofing results' => { success: true, errors: {}, address_edited: false, address_line2_present: false, ssn_is_unique: true, proofing_results: { exception: nil, timed_out: false, context: { adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil, drivers_license_check_info: nil }, state_id: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' } } } } },
'IdV: phone of record visited' => { proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis' } },
'IdV: USPS address letter requested' => { resend: false, proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis' } },
'IdV: review info visited' => { address_verification_method: 'gpo', proofing_components: { document_check: 'mock', document_type: 'state_id', source_check: 'aamva', resolution_check: 'lexis_nexis', address_check: 'gpo_letter' } },
diff --git a/spec/features/idv/cancel_spec.rb b/spec/features/idv/cancel_spec.rb
index 793b2e734c2..25695e60558 100644
--- a/spec/features/idv/cancel_spec.rb
+++ b/spec/features/idv/cancel_spec.rb
@@ -92,7 +92,7 @@
expect(fake_analytics).to have_logged_event(
'IdV: cancellation visited',
proofing_components: { document_check: 'mock', document_type: 'state_id' },
- request_came_from: 'idv/doc_auth#show',
+ request_came_from: 'idv/ssn#show',
step: 'ssn',
)
diff --git a/spec/features/idv/doc_auth/document_capture_spec.rb b/spec/features/idv/doc_auth/document_capture_spec.rb
new file mode 100644
index 00000000000..40b20635272
--- /dev/null
+++ b/spec/features/idv/doc_auth/document_capture_spec.rb
@@ -0,0 +1,46 @@
+require 'rails_helper'
+
+feature 'doc auth document capture step', :js do
+ include IdvStepHelper
+ include DocAuthHelper
+ include ActionView::Helpers::DateHelper
+
+ let(:max_attempts) { IdentityConfig.store.doc_auth_max_attempts }
+ let(:user) { user_with_2fa }
+ let(:doc_auth_enable_presigned_s3_urls) { false }
+ let(:fake_analytics) { FakeAnalytics.new }
+ let(:sp_name) { 'Test SP' }
+ before do
+ allow(IdentityConfig.store).to receive(:doc_auth_document_capture_controller_enabled).
+ and_return(true)
+ allow(IdentityConfig.store).to receive(:doc_auth_enable_presigned_s3_urls).
+ and_return(doc_auth_enable_presigned_s3_urls)
+ allow(Identity::Hostdata::EC2).to receive(:load).
+ and_return(OpenStruct.new(region: 'us-west-2', account_id: '123456789'))
+ allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics)
+ allow_any_instance_of(ServiceProviderSessionDecorator).to receive(:sp_name).and_return(sp_name)
+
+ visit_idp_from_oidc_sp_with_ial2
+
+ sign_in_and_2fa_user(user)
+ complete_doc_auth_steps_before_document_capture_step
+ end
+
+ it 'shows the new DocumentCapture page for desktop standard flow' do
+ visit(idv_document_capture_url)
+ expect(page).to have_current_path(idv_document_capture_url)
+
+ expect(page).to have_content(t('doc_auth.headings.document_capture'))
+ expect(page).to have_content(t('step_indicator.flows.idv.verify_id'))
+
+ expect(fake_analytics).to have_logged_event(
+ 'IdV: doc auth document_capture visited',
+ flow_path: 'standard',
+ step: 'document_capture',
+ step_count: 1,
+ analytics_id: 'Doc Auth',
+ irs_reproofing: false,
+ acuant_sdk_upgrade_ab_test_bucket: :default,
+ )
+ end
+end
diff --git a/spec/features/idv/doc_auth/document_capture_step_spec.rb b/spec/features/idv/doc_auth/document_capture_step_spec.rb
index a630d6094c0..a59ea8dece3 100644
--- a/spec/features/idv/doc_auth/document_capture_step_spec.rb
+++ b/spec/features/idv/doc_auth/document_capture_step_spec.rb
@@ -207,22 +207,8 @@
end
end
- context 'when new ssn controller is enabled' do
- before do
- allow(IdentityConfig.store).to receive(:doc_auth_ssn_controller_enabled).
- and_return(true)
- end
- it 'redirects to ssn controller' do
- expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id'))
-
- attach_and_submit_images
-
- expect(page).to have_current_path(idv_ssn_url)
- end
- end
-
def next_step
- idv_doc_auth_ssn_step
+ idv_ssn_url
end
def expect_costing_for_document
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 e3d5281e940..157a3ef8fe1 100644
--- a/spec/features/idv/doc_auth/link_sent_step_spec.rb
+++ b/spec/features/idv/doc_auth/link_sent_step_spec.rb
@@ -22,7 +22,7 @@
mock_doc_captured(user.id)
click_idv_continue
- expect(page).to have_current_path(idv_doc_auth_ssn_step)
+ 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
@@ -32,7 +32,7 @@
mock_doc_captured(user.id)
click_idv_continue
- expect(page).to have_current_path(idv_doc_auth_ssn_step)
+ 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
@@ -80,7 +80,7 @@
mock_doc_captured(user.id)
expect(page).to have_content(t('doc_auth.headings.ssn'), wait: 6)
- expect(page).to have_current_path(idv_doc_auth_ssn_step)
+ expect(page).to have_current_path(idv_ssn_path)
end
end
diff --git a/spec/features/idv/doc_auth/ssn_spec.rb b/spec/features/idv/doc_auth/ssn_spec.rb
deleted file mode 100644
index d1d7c6b373d..00000000000
--- a/spec/features/idv/doc_auth/ssn_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require 'rails_helper'
-
-feature 'doc auth ssn step', :js do
- include IdvStepHelper
- include DocAuthHelper
- include DocCaptureHelper
-
- before do
- allow(IdentityConfig.store).to receive(:proofing_device_profiling).and_return(:enabled)
- allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_org_id).and_return('test_org')
- allow(IdentityConfig.store).to receive(:doc_auth_ssn_controller_enabled).and_return(true)
-
- sign_in_and_2fa_user
- complete_doc_auth_steps_before_ssn_step
- end
-
- it 'proceeds to the next page with valid info' do
- expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_info'))
-
- fill_out_ssn_form_ok
-
- match = page.body.match(/session_id=(?
[^"&]+)/)
- session_id = match && match[:session_id]
- expect(session_id).to be_present
-
- select 'Review', from: 'mock_profiling_result'
-
- expect(page.find_field(t('idv.form.ssn_label_html'))['aria-invalid']).to eq('false')
- click_idv_continue
-
- expect(page).to have_current_path(idv_verify_info_url)
-
- profiling_result = Proofing::Mock::DeviceProfilingBackend.new.profiling_result(session_id)
- expect(profiling_result).to eq('review')
- end
-
- it 'does not proceed to the next page with invalid info' do
- fill_out_ssn_form_fail
- click_idv_continue
-
- expect(page.find_field(t('idv.form.ssn_label_html'))['aria-invalid']).to eq('true')
-
- expect(page).to have_current_path(idv_ssn_url)
- end
-end
diff --git a/spec/features/idv/doc_auth/ssn_step_spec.rb b/spec/features/idv/doc_auth/ssn_step_spec.rb
index b7c1269bf56..6bb05ad4506 100644
--- a/spec/features/idv/doc_auth/ssn_step_spec.rb
+++ b/spec/features/idv/doc_auth/ssn_step_spec.rb
@@ -27,7 +27,7 @@
expect(page.find_field(t('idv.form.ssn_label_html'))['aria-invalid']).to eq('false')
click_idv_continue
- expect(page).to have_current_path(idv_verify_info_path)
+ expect(page).to have_current_path(idv_verify_info_url)
profiling_result = Proofing::Mock::DeviceProfilingBackend.new.profiling_result(session_id)
expect(profiling_result).to eq('review')
@@ -39,6 +39,6 @@
expect(page.find_field(t('idv.form.ssn_label_html'))['aria-invalid']).to eq('true')
- expect(page).to have_current_path(idv_doc_auth_ssn_step)
+ expect(page).to have_current_path(idv_ssn_url)
end
end
diff --git a/spec/features/idv/doc_auth/test_credentials_spec.rb b/spec/features/idv/doc_auth/test_credentials_spec.rb
index a7c57d8818b..2117b529bdf 100644
--- a/spec/features/idv/doc_auth/test_credentials_spec.rb
+++ b/spec/features/idv/doc_auth/test_credentials_spec.rb
@@ -23,7 +23,7 @@
attach_file 'Back of your ID', File.expand_path('spec/fixtures/ial2_test_credential.yml')
click_on 'Submit'
- expect(page).to have_current_path(idv_doc_auth_ssn_step)
+ expect(page).to have_current_path(idv_ssn_path)
fill_out_ssn_form_ok
click_idv_continue
diff --git a/spec/features/idv/doc_auth/verify_info_step_spec.rb b/spec/features/idv/doc_auth/verify_info_step_spec.rb
index d4df7d5ca15..b344d7b5268 100644
--- a/spec/features/idv/doc_auth/verify_info_step_spec.rb
+++ b/spec/features/idv/doc_auth/verify_info_step_spec.rb
@@ -42,6 +42,9 @@
expect(page).to have_content(t('headings.verify'))
expect(page).to have_content(t('step_indicator.flows.idv.verify_info'))
+ # DOB is in full month format (October)
+ expect(page).to have_text(t('date.month_names')[10])
+
# SSN is masked until revealed
expect(page).to have_text(DocAuthHelper::GOOD_SSN_MASKED)
expect(page).not_to have_text(DocAuthHelper::GOOD_SSN)
@@ -53,18 +56,33 @@
it 'allows the user to enter in a new address and displays updated info' do
click_button t('idv.buttons.change_address_label')
fill_in 'idv_form_zipcode', with: '12345'
+ fill_in 'idv_form_address2', with: 'Apt 3E'
+
click_button t('forms.buttons.submit.update')
expect(page).to have_current_path(idv_verify_info_path)
expect(page).to have_content('12345')
+ expect(page).to have_content('Apt 3E')
+
+ click_idv_continue
+
+ expect(fake_analytics).to have_logged_event(
+ 'IdV: doc auth verify proofing results',
+ hash_including(address_edited: true, address_line2_present: true),
+ )
end
it 'allows the user to enter in a new ssn and displays updated info' do
- click_button t('idv.buttons.change_ssn_label')
+ click_link t('idv.buttons.change_ssn_label')
+ expect(page).to have_current_path(idv_ssn_path)
fill_in t('idv.form.ssn_label_html'), with: '900456789'
click_button t('forms.buttons.submit.update')
+ expect(fake_analytics).to have_logged_event(
+ 'IdV: doc auth redo_ssn submitted',
+ )
+
expect(page).to have_current_path(idv_verify_info_path)
expect(page).to have_text('9**-**-***9')
@@ -91,7 +109,7 @@
expect(DocAuthLog.find_by(user_id: user.id).aamva).to eq(true)
expect(fake_analytics).to have_logged_event(
'IdV: doc auth verify proofing results',
- hash_including(address_edited: false),
+ hash_including(address_edited: false, address_line2_present: false),
)
end
@@ -372,31 +390,4 @@
expect(page).to have_current_path(idv_phone_path)
end
end
-
- context 'with ssn_controller enabled' do
- before do
- allow(IdentityConfig.store).to receive(:doc_auth_ssn_controller_enabled).
- and_return(true)
- sign_in_and_2fa_user
- complete_doc_auth_steps_before_verify_step
- end
-
- it 'uses ssn controller to enter a new ssn and displays updated info' do
- click_link t('idv.buttons.change_ssn_label')
- expect(page).to have_current_path(idv_ssn_path)
-
- fill_in t('idv.form.ssn_label_html'), with: '900456789'
- click_button t('forms.buttons.submit.update')
-
- expect(fake_analytics).to have_logged_event(
- 'IdV: doc auth redo_ssn submitted',
- )
-
- expect(page).to have_current_path(idv_verify_info_path)
-
- expect(page).to have_text('9**-**-***9')
- check t('forms.ssn.show')
- expect(page).to have_text('900-45-6789')
- end
- end
end
diff --git a/spec/features/idv/doc_capture/document_capture_step_spec.rb b/spec/features/idv/doc_capture/document_capture_step_spec.rb
index 515e70a4f34..96b44e0990c 100644
--- a/spec/features/idv/doc_capture/document_capture_step_spec.rb
+++ b/spec/features/idv/doc_capture/document_capture_step_spec.rb
@@ -62,7 +62,7 @@
using_doc_capture_session { attach_and_submit_images }
click_idv_continue
- expect(page).to have_current_path(idv_doc_auth_ssn_step)
+ expect(page).to have_current_path(idv_ssn_path)
expect(fake_analytics).to have_logged_event(
'IdV: doc auth document_capture submitted',
hash_including(
@@ -98,7 +98,7 @@
click_button t('forms.buttons.continue')
end
- expect(page).to have_current_path(idv_doc_auth_ssn_step, wait: 10)
+ expect(page).to have_current_path(idv_ssn_path, wait: 10)
end
end
@@ -119,7 +119,7 @@
end
click_idv_continue
- expect(page).to have_current_path(idv_doc_auth_ssn_step)
+ expect(page).to have_current_path(idv_ssn_path)
end
it 'does not advance original session with errors' do
@@ -156,7 +156,7 @@
click_button t('forms.buttons.continue')
end
- expect(page).to have_current_path(idv_doc_auth_ssn_step, wait: 10)
+ expect(page).to have_current_path(idv_ssn_path, wait: 10)
end
end
end
diff --git a/spec/features/idv/hybrid_flow_spec.rb b/spec/features/idv/hybrid_flow_spec.rb
index 867f9552699..a1e2049191c 100644
--- a/spec/features/idv/hybrid_flow_spec.rb
+++ b/spec/features/idv/hybrid_flow_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-describe 'Hybrid Flow' do
+describe 'Hybrid Flow', :allow_net_connect_on_start do
include IdvHelper
include DocAuthHelper
@@ -40,6 +40,7 @@
perform_in_browser(:desktop) do
expect(page).to_not have_content(t('doc_auth.headings.text_message'), wait: 10)
+ expect(page).to have_current_path(idv_ssn_path)
fill_out_ssn_form_ok
click_idv_continue
@@ -60,55 +61,6 @@
end
end
- context 'with ssn controller enabled' do
- before do
- allow(IdentityConfig.store).to receive(:doc_auth_ssn_controller_enabled).and_return(true)
- end
-
- it 'proofs and hands off to mobile', js: true do
- user = nil
-
- 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
-
- expect(page).to have_content(t('doc_auth.headings.text_message'))
- end
-
- expect(@sms_link).to be_present
-
- perform_in_browser(:mobile) do
- visit @sms_link
- attach_and_submit_images
- expect(page).to have_text(t('doc_auth.instructions.switch_back'))
- end
-
- perform_in_browser(:desktop) do
- expect(page).to_not have_content(t('doc_auth.headings.text_message'), wait: 10)
- expect(page).to have_current_path(idv_ssn_path)
-
- fill_out_ssn_form_ok
- click_idv_continue
-
- expect(page).to have_content(t('headings.verify'))
- click_idv_continue
-
- fill_out_phone_form_ok
- verify_phone_otp
-
- fill_in t('idv.form.password'), with: Features::SessionHelper::VALID_PASSWORD
- click_idv_continue
-
- acknowledge_and_confirm_personal_key
-
- expect(page).to have_current_path(account_path)
- expect(page).to have_content(t('headings.account.verified_account'))
- end
- end
- end
-
it 'shows the waiting screen correctly after cancelling from mobile and restarting', js: true do
user = nil
diff --git a/spec/features/idv/inherited_proofing/agreement_step_spec.rb b/spec/features/idv/inherited_proofing/agreement_step_spec.rb
deleted file mode 100644
index 47e05fb191d..00000000000
--- a/spec/features/idv/inherited_proofing/agreement_step_spec.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-require 'rails_helper'
-
-feature 'inherited proofing agreement' do
- include InheritedProofingHelper
-
- before do
- allow(IdentityConfig.store).to receive(:va_inherited_proofing_mock_enabled).and_return true
- allow_any_instance_of(Idv::InheritedProofingController).to \
- receive(:va_inherited_proofing?).and_return true
- allow_any_instance_of(Idv::InheritedProofingController).to \
- receive(:va_inherited_proofing_auth_code).and_return auth_code
- end
-
- let(:auth_code) { Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE }
-
- def expect_ip_verify_info_step
- expect(page).to have_current_path(idv_ip_verify_info_step)
- end
-
- def expect_inherited_proofing_first_step
- expect(page).to have_current_path(idv_inherited_proofing_agreement_step)
- end
-
- context 'when JS is enabled', :js do
- before do
- sign_in_and_2fa_user
- complete_inherited_proofing_steps_before_agreement_step
- end
-
- it 'shows an inline error if the user clicks continue without giving consent' do
- click_continue
- expect_inherited_proofing_first_step
- expect(page).to have_content(t('forms.validation.required_checkbox'))
- end
-
- it 'allows the user to continue after checking the checkbox' do
- check t('inherited_proofing.instructions.consent', app_name: APP_NAME)
- click_continue
-
- expect_ip_verify_info_step
- end
-
- context 'when clicking on the Cancel link' do
- it 'redirects to the Cancellation UI' do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :agreement))
- end
- end
- end
-
- context 'when JS is disabled' do
- before do
- sign_in_and_2fa_user
- complete_inherited_proofing_steps_before_agreement_step
- end
-
- it 'shows the notice if the user clicks continue without giving consent' do
- click_continue
-
- expect_inherited_proofing_first_step
- expect(page).to have_content(t('errors.doc_auth.consent_form'))
- end
-
- it 'allows the user to continue after checking the checkbox' do
- check t('inherited_proofing.instructions.consent', app_name: APP_NAME)
- click_continue
-
- expect_ip_verify_info_step
- end
-
- context 'when clicking on the Cancel link' do
- it 'redirects to the Cancellation UI' do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :agreement))
- end
- end
- end
-end
diff --git a/spec/features/idv/inherited_proofing/analytics_spec.rb b/spec/features/idv/inherited_proofing/analytics_spec.rb
deleted file mode 100644
index 43462bb74e0..00000000000
--- a/spec/features/idv/inherited_proofing/analytics_spec.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'rails_helper'
-
-feature 'Inherited Proofing Analytics Regression', js: true do
- include InheritedProofingHelper
-
- let(:user) { user_with_2fa }
- let(:fake_analytics) { FakeAnalytics.new }
- let(:auth_code) { Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE }
- # rubocop:disable Layout/LineLength
- let(:happy_path_events) do
- {
- 'IdV: inherited proofing get started visited' => { flow_path: 'standard', step: 'get_started', step_count: 1, analytics_id: 'Inherited Proofing', irs_reproofing: false },
- 'IdV: inherited proofing get started submitted' => { success: true, errors: {}, flow_path: 'standard', step: 'get_started', step_count: 1, analytics_id: 'Inherited Proofing', irs_reproofing: false },
- 'IdV: inherited proofing agreement visited' => { flow_path: 'standard', step: 'agreement', step_count: 1, analytics_id: 'Inherited Proofing', irs_reproofing: false },
- 'IdV: inherited proofing agreement submitted' => { success: true, errors: {}, flow_path: 'standard', step: 'agreement', step_count: 1, analytics_id: 'Inherited Proofing', irs_reproofing: false },
- 'IdV: doc auth verify_wait visited' => { flow_path: 'standard', step: 'verify_wait', step_count: 1, analytics_id: 'Inherited Proofing', irs_reproofing: false },
- 'IdV: doc auth optional verify_wait submitted' => { success: true, errors: {}, step: 'verify_wait_step_show', analytics_id: 'Inherited Proofing' },
- 'IdV: doc auth verify visited' => { flow_path: 'standard', step: 'verify_info', step_count: 1, analytics_id: 'Inherited Proofing', irs_reproofing: false },
- 'IdV: doc auth verify submitted' => { success: true, errors: {}, flow_path: 'standard', step: 'verify_info', step_count: 1, analytics_id: 'Inherited Proofing', irs_reproofing: false },
- }
- end
- # rubocop:enable Layout/LineLength
-
- before do
- allow_any_instance_of(ApplicationController).to receive(:analytics) do |controller|
- fake_analytics.user = controller.analytics_user
- fake_analytics
- end
-
- allow(IdentityConfig.store).to receive(:va_inherited_proofing_mock_enabled).and_return true
- allow_any_instance_of(Idv::InheritedProofingController).to \
- receive(:va_inherited_proofing?).and_return true
- allow_any_instance_of(Idv::InheritedProofingController).to \
- receive(:va_inherited_proofing_auth_code).and_return auth_code
- end
-
- context 'Happy path' do
- before do
- sign_in_and_2fa_user
- complete_all_inherited_proofing_steps_to_handoff
- end
-
- it 'records all of the events' do
- happy_path_events.each do |event, attributes|
- expect(fake_analytics).to have_logged_event(event, attributes)
- end
- end
- end
-end
diff --git a/spec/features/idv/inherited_proofing/get_started_step_spec.rb b/spec/features/idv/inherited_proofing/get_started_step_spec.rb
deleted file mode 100644
index 35222000f68..00000000000
--- a/spec/features/idv/inherited_proofing/get_started_step_spec.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-require 'rails_helper'
-
-feature 'inherited proofing get started' do
- include InheritedProofingHelper
-
- before do
- allow(IdentityConfig.store).to receive(:va_inherited_proofing_mock_enabled).and_return true
- allow_any_instance_of(Idv::InheritedProofingController).to \
- receive(:va_inherited_proofing?).and_return true
- allow_any_instance_of(Idv::InheritedProofingController).to \
- receive(:va_inherited_proofing_auth_code).and_return auth_code
- end
-
- let(:auth_code) { Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE }
-
- def expect_ip_get_started_step
- expect(page).to have_current_path(idv_ip_get_started_step)
- end
-
- def expect_inherited_proofing_get_started_step
- expect(page).to have_current_path(idv_ip_get_started_step)
- end
-
- context 'when JS is enabled', :js do
- before do
- sign_in_and_2fa_user
- complete_inherited_proofing_steps_before_get_started_step
- end
-
- context 'when clicking on the Cancel link' do
- it 'redirects to the Cancellation UI' do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :get_started))
- end
- end
- end
-
- context 'when JS is disabled' do
- before do
- sign_in_and_2fa_user
- complete_inherited_proofing_steps_before_get_started_step
- end
-
- context 'when clicking on the Cancel link' do
- it 'redirects to the Cancellation UI' do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :get_started))
- end
- end
- end
-end
diff --git a/spec/features/idv/inherited_proofing/inherited_proofing_cancel_spec.rb b/spec/features/idv/inherited_proofing/inherited_proofing_cancel_spec.rb
deleted file mode 100644
index cf594bd0c6c..00000000000
--- a/spec/features/idv/inherited_proofing/inherited_proofing_cancel_spec.rb
+++ /dev/null
@@ -1,151 +0,0 @@
-require 'rails_helper'
-
-feature 'inherited proofing cancel process', :js do
- include InheritedProofingWithServiceProviderHelper
-
- before do
- allow(IdentityConfig.store).to receive(:va_inherited_proofing_mock_enabled).and_return true
- send_user_from_service_provider_to_login_gov_openid_connect user, inherited_proofing_auth
- end
-
- let!(:user) { user_with_2fa }
- let(:inherited_proofing_auth) { Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE }
-
- context 'from the "Get started verifying your identity" view, and clicking the "Cancel" link' do
- before do
- complete_steps_up_to_inherited_proofing_get_started_step user
- end
-
- it 'should have current path equal to the Getting Started page' do
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :get_started))
- end
-
- context 'when clicking the "Start Over" button from the "Cancel" view' do
- before do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :get_started))
- end
-
- it 'redirects the user back to the start of the Inherited Proofing process' do
- click_button t('inherited_proofing.cancel.actions.start_over')
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :get_started))
- end
- end
-
- context 'when clicking the "No, keep going" button from the "Cancel" view' do
- before do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :get_started))
- end
-
- it 'redirects the user back to where the user left off in the Inherited Proofing process' do
- click_button t('inherited_proofing.cancel.actions.keep_going')
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :get_started))
- end
- end
-
- context 'when clicking the "Exit Login.gov" button from the "Cancel" view' do
- before do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :get_started))
- end
-
- it 'redirects the user back to the service provider website' do
- click_button t('idv.cancel.actions.exit', app_name: APP_NAME)
- expect(page).to have_current_path(/\/auth\/result\?/)
- end
- end
- end
-
- context 'from the "How verifying your identify works" view, and clicking the "Cancel" link' do
- before do
- complete_steps_up_to_inherited_proofing_how_verifying_step user
- end
-
- it 'should have current path equal to the How Verifying (agreement step) page' do
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :agreement))
- end
-
- context 'when clicking the "Start Over" button from the "Cancel" view' do
- before do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :agreement))
- end
-
- it 'redirects the user back to the start of the Inherited Proofing process' do
- click_button t('inherited_proofing.cancel.actions.start_over')
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :get_started))
- end
- end
-
- context 'when clicking the "No, keep going" button from the "Cancel" view' do
- before do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :agreement))
- end
-
- it 'redirects the user back to where the user left off in the Inherited Proofing process' do
- click_button t('inherited_proofing.cancel.actions.keep_going')
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :agreement))
- end
- end
-
- context 'when clicking the "Exit Login.gov" button from the "Cancel" view' do
- before do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :agreement))
- end
-
- it 'redirects the user back to the service provider website' do
- click_button t('idv.cancel.actions.exit', app_name: APP_NAME)
- expect(page).to have_current_path(/\/auth\/result\?/)
- end
- end
- end
-
- context 'from the "Verify your information..." view, and clicking the "Cancel" link' do
- before do
- complete_steps_up_to_inherited_proofing_verify_your_info_step user
- end
-
- it 'should have current path equal to the Verify your information (verify_info step) page' do
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :verify_info))
- end
-
- context 'when clicking the "Start Over" button from the "Cancel" view' do
- before do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :verify_info))
- end
-
- it 'redirects the user back to the start of the Inherited Proofing process' do
- click_button t('inherited_proofing.cancel.actions.start_over')
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :get_started))
- end
- end
-
- context 'when clicking the "No, keep going" button from the "Cancel" view' do
- before do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :verify_info))
- end
-
- it 'redirects the user back to where the user left off in the Inherited Proofing process' do
- click_button t('inherited_proofing.cancel.actions.keep_going')
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :verify_info))
- end
- end
-
- context 'when clicking the "Exit Login.gov" button from the "Cancel" view' do
- before do
- click_link t('links.cancel')
- expect(page).to have_current_path(idv_inherited_proofing_cancel_path(step: :verify_info))
- end
-
- it 'redirects the user back to the service provider website' do
- click_button t('idv.cancel.actions.exit', app_name: APP_NAME)
- expect(page).to have_current_path(/\/auth\/result\?/)
- end
- end
- end
-end
diff --git a/spec/features/idv/inherited_proofing/verify_info_step_spec.rb b/spec/features/idv/inherited_proofing/verify_info_step_spec.rb
deleted file mode 100644
index fe1a14ea848..00000000000
--- a/spec/features/idv/inherited_proofing/verify_info_step_spec.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-require 'rails_helper'
-
-feature 'inherited proofing verify info' do
- include InheritedProofingHelper
- include_context 'va_user_context'
-
- before do
- allow(IdentityConfig.store).to receive(:va_inherited_proofing_mock_enabled).and_return true
- allow_any_instance_of(Idv::InheritedProofingController).to \
- receive(:va_inherited_proofing?).and_return true
- allow_any_instance_of(Idv::InheritedProofingController).to \
- receive(:va_inherited_proofing_auth_code).and_return auth_code
- @decorated_session = instance_double(ServiceProviderSessionDecorator)
- allow(@decorated_session).to receive(:sp_name).and_return(sp_name)
- allow(@decorated_session).to receive(:sp_logo_url).and_return('')
- allow_any_instance_of(Idv::InheritedProofingController).to \
- receive(:decorated_session).and_return(@decorated_session)
- sign_in_and_2fa_user
- complete_inherited_proofing_steps_before_verify_step
- end
-
- let(:sp_name) { 'VA.gov' }
- let(:auth_code) { Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE }
-
- describe 'page content' do
- it 'renders the Continue button' do
- expect(page).to have_button(t('inherited_proofing.buttons.continue'))
- end
-
- it 'renders content' do
- expect(page).to have_content(t('titles.idv.verify_info'))
- expect(page).to have_link(
- t(
- 'inherited_proofing.troubleshooting.options.get_help',
- sp_name: sp_name,
- ),
- )
- end
- end
-
- describe 'user info' do
- it "displays the user's personal information" do
- expect(page).to have_text user_attributes[:first_name]
- expect(page).to have_text user_attributes[:last_name]
- expect(page).to have_text user_attributes[:birth_date]
- end
-
- it "displays the user's address" do
- expect(page).to have_text user_attributes[:address][:street]
- expect(page).to have_text user_attributes[:address][:city]
- expect(page).to have_text user_attributes[:address][:state]
- expect(page).to have_text user_attributes[:address][:zip]
- end
-
- it "obfuscates the user's ssn" do
- expect(page).to have_text '1**-**-***9'
- end
-
- it "can display the user's ssn when selected" do
- check 'Show Social Security number'
- expect(page).to have_text '123-45-6789'
- end
- end
-end
diff --git a/spec/features/idv/inherited_proofing/verify_wait_step_spec.rb b/spec/features/idv/inherited_proofing/verify_wait_step_spec.rb
deleted file mode 100644
index 3c17b33d889..00000000000
--- a/spec/features/idv/inherited_proofing/verify_wait_step_spec.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-require 'rails_helper'
-
-feature 'inherited proofing verify wait', :js do
- include InheritedProofingWithServiceProviderHelper
-
- before do
- allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics)
- allow(IdentityConfig.store).to receive(:va_inherited_proofing_mock_enabled).and_return(true)
- send_user_from_service_provider_to_login_gov_openid_connect(user, inherited_proofing_auth)
- end
-
- let!(:user) { user_with_2fa }
- let(:inherited_proofing_auth) { Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE }
- let(:fake_analytics) { FakeAnalytics.new }
-
- context 'when on the "How verifying your identify works" page, ' \
- 'and the user clicks the "Continue" button' do
- before do
- complete_steps_up_to_inherited_proofing_we_are_retrieving_step user
- end
-
- context 'when there are no service-related errors' do
- it 'displays the "Verify your information" page' do
- expect(page).to have_current_path(
- idv_inherited_proofing_step_path(step: :verify_info),
- )
- end
- end
-
- context 'when there are service-related errors on the first attempt' do
- let(:inherited_proofing_auth) { 'invalid-auth-code' }
-
- it 'displays the warning page and allows retries' do
- expect(page).to have_current_path(
- idv_inherited_proofing_errors_no_information_path(flow: :inherited_proofing),
- )
- expect(page).to have_selector(:link_or_button, t('inherited_proofing.buttons.try_again'))
- end
- end
-
- context 'when there are service-related errors on the second attempt' do
- let(:inherited_proofing_auth) { 'invalid-auth-code' }
-
- it 'redirects to the error page, prohibits retries and logs the event' do
- click_button t('inherited_proofing.buttons.try_again')
- expect(page).to have_current_path(
- idv_inherited_proofing_errors_failure_url(flow: :inherited_proofing),
- )
- expect(fake_analytics).to have_logged_event(
- 'Throttler Rate Limit Triggered',
- throttle_type: :inherited_proofing,
- step_name: Idv::Actions::InheritedProofing::RedoRetrieveUserInfoAction.name,
- )
- end
- end
- end
-
- context 'when the async state is missing during polling' do
- before do
- allow_any_instance_of(ProofingSessionAsyncResult).to receive(:missing?).and_return(true)
- complete_steps_up_to_inherited_proofing_we_are_retrieving_step user
- end
-
- it 'redirects back to the agreement step and logs the event' do
- expect(page).to have_current_path(
- idv_inherited_proofing_step_path(step: :agreement),
- )
- expect(fake_analytics).to have_logged_event(
- 'Proofing Resolution Result Missing',
- )
- end
- end
-end
diff --git a/spec/features/idv/steps/in_person/verify_info_spec.rb b/spec/features/idv/steps/in_person/verify_info_spec.rb
index fd0e1858d05..6f408fb9760 100644
--- a/spec/features/idv/steps/in_person/verify_info_spec.rb
+++ b/spec/features/idv/steps/in_person/verify_info_spec.rb
@@ -28,7 +28,11 @@
expect(page).to have_content(t('headings.verify'))
expect(page).to have_text(InPersonHelper::GOOD_FIRST_NAME)
expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME)
- expect(page).to have_text(InPersonHelper::GOOD_DOB)
+ i18n_dob = I18n.l(
+ Date.parse(InPersonHelper::GOOD_DOB),
+ format: I18n.t('time.formats.event_date'),
+ )
+ expect(page).to have_text(i18n_dob)
expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER)
expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1)
expect(page).to have_text(InPersonHelper::GOOD_CITY)
diff --git a/spec/features/idv/threatmetrix_pending_spec.rb b/spec/features/idv/threatmetrix_pending_spec.rb
index 0201fd47ffd..ad042d4fbd7 100644
--- a/spec/features/idv/threatmetrix_pending_spec.rb
+++ b/spec/features/idv/threatmetrix_pending_spec.rb
@@ -2,10 +2,27 @@
RSpec.feature 'Users pending threatmetrix review', :js do
include IdvStepHelper
+ include OidcAuthHelper
+ include IrsAttemptsApiTrackingHelper
+ include DocAuthHelper
before do
allow(IdentityConfig.store).to receive(:proofing_device_profiling).and_return(:enabled)
allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_org_id).and_return('test_org')
+ allow(IdentityConfig.store).to receive(:irs_attempt_api_enabled).and_return(true)
+ allow(IdentityConfig.store).to receive(:irs_attempt_api_track_tmx_fraud_check_event).
+ and_return(true)
+ mock_irs_attempts_api_encryption_key
+ end
+
+ let(:service_provider) do
+ create(
+ :service_provider,
+ active: true,
+ redirect_uris: ['http://localhost:7654/auth/result'],
+ ial: 2,
+ irs_attempts_api_enabled: true,
+ )
end
scenario 'users pending threatmetrix see sad face screen and cannot perform idv' do
@@ -49,4 +66,53 @@
expect(current_path).to eq('/auth/result')
end
+
+ scenario 'users threatmetrix Pass, it logs idv_tmx_fraud_check event', :js do
+ freeze_time do
+ complete_all_idv_steps_with(threatmetrix: 'Pass')
+ expect_irs_event(expected_success: true, expected_failure_reason: nil)
+ end
+ end
+
+ scenario 'users pending threatmetrix Reject, it logs idv_tmx_fraud_check event', :js do
+ freeze_time do
+ expect_pending_failure_reason(threatmetrix: 'Reject')
+ end
+ end
+
+ scenario 'users pending threatmetrix Review, it logs idv_tmx_fraud_check event', :js do
+ freeze_time do
+ expect_pending_failure_reason(threatmetrix: 'Review')
+ end
+ end
+
+ scenario 'users pending threatmetrix No Result, it logs idv_tmx_fraud_check event', :js do
+ freeze_time do
+ expect_pending_failure_reason(threatmetrix: 'No Result')
+ end
+ end
+
+ def expect_pending_failure_reason(threatmetrix:)
+ complete_all_idv_steps_with(threatmetrix: threatmetrix)
+ expect(page).to have_content(t('idv.failure.setup.heading'))
+ expect(page).to have_current_path(idv_setup_errors_path)
+ expect_irs_event(
+ expected_success: false,
+ expected_failure_reason: DocAuthHelper::SAMPLE_TMX_SUMMARY_REASON_CODE,
+ )
+ end
+
+ def expect_irs_event(expected_success:, expected_failure_reason:)
+ event_name = 'idv-tmx-fraud-check'
+ events = irs_attempts_api_tracked_events(timestamp: Time.zone.now)
+ received_event_types = events.map(&:event_type)
+
+ idv_tmx_fraud_check_event = events.find { |x| x.event_type == event_name }
+ failure_reason = idv_tmx_fraud_check_event.event_metadata[:failure_reason]
+ success = idv_tmx_fraud_check_event.event_metadata[:success]
+
+ expect(received_event_types).to include event_name
+ expect(failure_reason).to eq expected_failure_reason.as_json
+ expect(success).to eq expected_success
+ end
end
diff --git a/spec/features/services/idv/inherited_proofing/va/mocks/service_spec.rb b/spec/features/services/idv/inherited_proofing/va/mocks/service_spec.rb
deleted file mode 100644
index 88d8c7d429f..00000000000
--- a/spec/features/services/idv/inherited_proofing/va/mocks/service_spec.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe 'Inherited Proofing VA API Proofer Service' do
- subject(:form) { Idv::InheritedProofing::Va::Form.new(payload_hash: proofer_results) }
-
- let(:proofer_results) do
- Idv::InheritedProofing::Va::Mocks::Service.new({ auth_code: auth_code }).execute
- end
- let(:auth_code) { Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE }
-
- context 'when used with the VA Inherited Proofing Response Form' do
- it 'works as expected' do
- expect(form.submit.success?).to eq true
- end
- end
-end
diff --git a/spec/fixtures/proofing/lexis_nexis/ddp/error_response.json b/spec/fixtures/proofing/lexis_nexis/ddp/error_response.json
index d36ca4063bf..0de8a11bf99 100644
--- a/spec/fixtures/proofing/lexis_nexis/ddp/error_response.json
+++ b/spec/fixtures/proofing/lexis_nexis/ddp/error_response.json
@@ -2,5 +2,6 @@
"error_detail": "service_type",
"request_id":"1234-abcd",
"request_result":"fail_invalid_parameter",
- "review_status":"REVIEW_STATUS"
+ "review_status":"REVIEW_STATUS",
+ "tmx_summary_reason_code": ["Identity_Negative_History"]
}
diff --git a/spec/fixtures/proofing/lexis_nexis/ddp/successful_redacted_response.json b/spec/fixtures/proofing/lexis_nexis/ddp/successful_redacted_response.json
index 85b43947a59..add352a3a54 100644
--- a/spec/fixtures/proofing/lexis_nexis/ddp/successful_redacted_response.json
+++ b/spec/fixtures/proofing/lexis_nexis/ddp/successful_redacted_response.json
@@ -6,5 +6,6 @@
"summary_risk_score": "-6",
"tmx_risk_rating": "neutral",
"fraudpoint.score": "500",
- "first_name": "[redacted]"
+ "first_name": "[redacted]",
+ "tmx_summary_reason_code": ["Identity_Negative_History"]
}
diff --git a/spec/fixtures/proofing/lexis_nexis/ddp/successful_response.json b/spec/fixtures/proofing/lexis_nexis/ddp/successful_response.json
index 4f63de45a75..a408987796b 100644
--- a/spec/fixtures/proofing/lexis_nexis/ddp/successful_response.json
+++ b/spec/fixtures/proofing/lexis_nexis/ddp/successful_response.json
@@ -6,5 +6,6 @@
"summary_risk_score": "-6",
"tmx_risk_rating": "neutral",
"fraudpoint.score": "500",
- "first_name": "WARNING! YOU SHOULD NEVER SEE THIS PII FIELD IN THE LOGS"
+ "first_name": "WARNING! YOU SHOULD NEVER SEE THIS PII FIELD IN THE LOGS",
+ "tmx_summary_reason_code": ["Identity_Negative_History"]
}
diff --git a/spec/forms/idv/inherited_proofing/base_form_spec.rb b/spec/forms/idv/inherited_proofing/base_form_spec.rb
deleted file mode 100644
index 871142de3eb..00000000000
--- a/spec/forms/idv/inherited_proofing/base_form_spec.rb
+++ /dev/null
@@ -1,182 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Idv::InheritedProofing::BaseForm do
- subject { form_object }
-
- let(:form_class) do
- Class.new(Idv::InheritedProofing::BaseForm) do
- class << self
- def required_fields; [] end
-
- def optional_fields; [] end
- end
-
- def user_pii; {} end
- end
- end
-
- let(:form_object) do
- form_class.new(payload_hash: payload_hash)
- end
-
- let(:payload_hash) do
- {
- first_name: 'Henry',
- last_name: 'Ford',
- phone: '12222222222',
- birth_date: '2000-01-01',
- ssn: '111223333',
- address: {
- street: '1234 Model Street',
- street2: 'Suite A',
- city: 'Detroit',
- state: 'MI',
- country: 'United States',
- zip: '12345',
- },
- }
- end
-
- describe '#initialize' do
- subject { form_class }
-
- context 'when .user_pii is not overridden' do
- subject do
- Class.new(Idv::InheritedProofing::BaseForm) do
- class << self
- def required_fields; [] end
-
- def optional_fields; [] end
- end
- end
- end
-
- it 'raises an error' do
- expected_error = 'Override this method and return a user PII Hash'
- expect { subject.new(payload_hash: payload_hash).user_pii }.to raise_error(expected_error)
- end
- end
- end
-
- describe 'class methods' do
- describe '.model_name' do
- it 'returns the right model name' do
- expect(described_class.model_name).to eq 'IdvInheritedProofingBaseForm'
- end
- end
- end
-
- describe '#initialize' do
- context 'when passing an invalid payload hash' do
- context 'when not a Hash' do
- let(:payload_hash) { :x }
-
- it 'raises an error' do
- expect { subject }.to raise_error 'payload_hash is not a Hash'
- end
- end
-
- context 'when nil?' do
- let(:payload_hash) { nil }
-
- it_behaves_like 'the hash is blank?'
- end
-
- context 'when empty?' do
- let(:payload_hash) { {} }
-
- it_behaves_like 'the hash is blank?'
- end
- end
-
- context 'when passing a valid payload hash' do
- it 'raises no errors' do
- expect { subject }.to_not raise_error
- end
- end
- end
-
- describe '#validate' do
- subject do
- Class.new(Idv::InheritedProofing::BaseForm) do
- class << self
- def required_fields; %i[required] end
-
- def optional_fields; %i[optional] end
- end
-
- def user_pii; {} end
- end.new(payload_hash: payload_hash)
- end
-
- let(:payload_hash) do
- {
- required: 'Required',
- optional: 'Optional',
- }
- end
-
- context 'with valid payload data' do
- it 'returns true' do
- expect(subject.validate).to eq true
- end
- end
-
- context 'with invalid payload data' do
- context 'when the payload has unrecognized fields' do
- let(:payload_hash) do
- {
- xrequired: 'xRequired',
- xoptional: 'xOptional',
- }
- end
-
- let(:expected_error_messages) do
- [
- # Required field presence
- 'Required field is missing',
- 'Optional field is missing',
- ]
- end
-
- it 'returns true' do
- expect(subject.validate).to eq true
- end
- end
-
- context 'when the payload has missing required field data' do
- let(:payload_hash) do
- {
- required: nil,
- optional: '',
- }
- end
-
- it 'returns true' do
- expect(subject.validate).to eq true
- end
-
- it 'returns no errors because no data validations take place by default' do
- subject.validate
- expect(subject.errors.full_messages).to eq []
- end
- end
- end
- end
-
- describe '#submit' do
- it 'returns a FormResponse object' do
- expect(subject.submit).to be_kind_of FormResponse
- end
-
- describe 'before returning' do
- after do
- subject.submit
- end
-
- it 'calls #valid?' do
- expect(subject).to receive(:valid?).once
- end
- end
- end
-end
diff --git a/spec/forms/idv/inherited_proofing/va/form_spec.rb b/spec/forms/idv/inherited_proofing/va/form_spec.rb
deleted file mode 100644
index ad734ab37c1..00000000000
--- a/spec/forms/idv/inherited_proofing/va/form_spec.rb
+++ /dev/null
@@ -1,317 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Idv::InheritedProofing::Va::Form do
- subject(:form) { described_class.new payload_hash: payload_hash }
-
- let(:required_fields) { %i[first_name last_name birth_date ssn address_street address_zip] }
- let(:optional_fields) do
- %i[phone address_street2 address_city address_state address_country service_error]
- end
-
- let(:payload_hash) do
- {
- first_name: 'Henry',
- last_name: 'Ford',
- phone: '12222222222',
- birth_date: '2000-01-01',
- ssn: '111223333',
- address: {
- street: '1234 Model Street',
- street2: 'Suite A',
- city: 'Detroit',
- state: 'MI',
- country: 'United States',
- zip: '12345',
- },
- }
- end
-
- describe 'constants' do
- describe 'FIELDS' do
- it 'returns all the fields' do
- expect(described_class::FIELDS).to match_array required_fields + optional_fields
- end
- end
-
- describe 'REQUIRED_FIELDS' do
- it 'returns the required fields' do
- expect(described_class::REQUIRED_FIELDS).to match_array required_fields
- end
- end
-
- describe 'OPTIONAL_FIELDS' do
- it 'returns the optional fields' do
- expect(described_class::OPTIONAL_FIELDS).to match_array optional_fields
- end
- end
- end
-
- describe 'class methods' do
- describe '.model_name' do
- it 'returns the right model name' do
- expect(described_class.model_name).to eq 'IdvInheritedProofingVaForm'
- end
- end
- end
-
- describe '#initialize' do
- context 'when passing an invalid payload hash' do
- context 'when not a Hash' do
- let(:payload_hash) { :x }
-
- it 'raises an error' do
- expect { form }.to raise_error 'payload_hash is not a Hash'
- end
- end
-
- context 'when nil?' do
- let(:payload_hash) { nil }
-
- it_behaves_like 'the hash is blank?'
- end
-
- context 'when empty?' do
- let(:payload_hash) { {} }
-
- it_behaves_like 'the hash is blank?'
- end
- end
-
- context 'when passing a valid payload hash' do
- it 'raises no errors' do
- expect { form }.to_not raise_error
- end
- end
- end
-
- describe '#validate' do
- context 'with valid payload data' do
- it 'returns true' do
- expect(form.validate).to be true
- end
- end
-
- context 'with invalid payload data' do
- context 'when the payload has missing fields' do
- let(:payload_hash) do
- {
- xfirst_name: 'Henry',
- xlast_name: 'Ford',
- xphone: '12222222222',
- xbirth_date: '2000-01-01',
- xssn: '111223333',
- xaddress: {
- xstreet: '1234 Model Street',
- xstreet2: 'Suite A',
- xcity: 'Detroit',
- xstate: 'MI',
- xcountry: 'United States',
- xzip: '12345',
- },
- }
- end
-
- let(:expected_error_messages) do
- [
- 'First name Please fill in this field.',
- 'Last name Please fill in this field.',
- 'Birth date Please fill in this field.',
- 'Ssn Please fill in this field.',
- 'Address street Please fill in this field.',
- 'Address zip Please fill in this field.',
- ]
- end
-
- it 'returns false' do
- expect(form.validate).to be false
- end
-
- it 'adds the correct error messages for missing fields' do
- subject.validate
- expect(form.errors.full_messages).to match_array expected_error_messages
- end
- end
-
- context 'when the payload has missing required field data' do
- let(:payload_hash) do
- {
- first_name: nil,
- last_name: '',
- phone: nil,
- birth_date: '',
- ssn: nil,
- address: {
- street: '',
- street2: nil,
- city: '',
- state: nil,
- country: '',
- zip: nil,
- },
- }
- end
-
- let(:expected_error_messages) do
- [
- # Required field data presence
- 'First name Please fill in this field.',
- 'Last name Please fill in this field.',
- 'Birth date Please fill in this field.',
- 'Ssn Please fill in this field.',
- 'Address street Please fill in this field.',
- 'Address zip Please fill in this field.',
- ]
- end
-
- it 'returns false' do
- expect(form.validate).to be false
- end
-
- it 'adds the correct error messages for required fields that are missing data' do
- subject.validate
- expect(form.errors.full_messages).to match_array expected_error_messages
- end
- end
-
- context 'when the payload has missing optional field data' do
- let(:payload_hash) do
- {
- first_name: 'x',
- last_name: 'x',
- phone: nil,
- birth_date: '01/01/2022',
- ssn: '123456789',
- address: {
- street: 'x',
- street2: nil,
- city: '',
- state: nil,
- country: '',
- zip: '12345',
- },
- }
- end
-
- it 'returns true' do
- expect(form.validate).to be true
- end
- end
-
- context 'when there is a service-related error' do
- before do
- subject.validate
- end
-
- let(:payload_hash) { { service_error: 'service error' } }
-
- it 'returns false' do
- expect(form.valid?).to be false
- end
-
- it 'adds a user-friendly model error' do
- expect(form.errors.full_messages).to \
- match_array ['Service provider communication was unsuccessful']
- end
- end
- end
- end
-
- describe '#submit' do
- context 'with an invalid payload' do
- context 'when the payload has invalid field data' do
- let(:payload_hash) do
- {
- first_name: nil,
- last_name: '',
- phone: nil,
- birth_date: '',
- ssn: nil,
- address: {
- street: '',
- street2: nil,
- city: '',
- state: nil,
- country: '',
- zip: nil,
- },
- }
- end
-
- let(:expected_errors) do
- {
- # Required field data presence
- first_name: ['Please fill in this field.'],
- last_name: ['Please fill in this field.'],
- birth_date: ['Please fill in this field.'],
- ssn: ['Please fill in this field.'],
- address_street: ['Please fill in this field.'],
- address_zip: ['Please fill in this field.'],
- }
- end
-
- it 'returns a FormResponse indicating the correct errors and status' do
- form_response = subject.submit
- expect(form_response.success?).to be false
- expect(form_response.errors).to match_array expected_errors
- expect(form_response.extra).to eq({})
- end
- end
- end
-
- context 'with a valid payload' do
- it 'returns a FormResponse indicating the no errors and successful status' do
- form_response = subject.submit
- expect(form_response.success?).to be true
- expect(form_response.errors).to eq({})
- expect(form_response.extra).to eq({})
- end
- end
-
- context 'when there is a service-related error' do
- let(:payload_hash) { { service_error: 'service error' } }
-
- it 'adds the unfiltered error to the FormResponse :extra Hash' do
- form_response = subject.submit
- expect(form_response.success?).to be false
- expect(form_response.errors).to \
- eq({ service_provider: ['communication was unsuccessful'] })
- expect(form_response.extra).to eq({ service_error: 'service error' })
- end
- end
- end
-
- describe '#user_pii' do
- let(:expected_user_pii) do
- {
- first_name: subject.first_name,
- last_name: subject.last_name,
- dob: subject.birth_date,
- ssn: subject.ssn,
- phone: subject.phone,
- address1: subject.address_street,
- city: subject.address_city,
- state: subject.address_state,
- zipcode: subject.address_zip,
- }
- end
- it 'returns the correct user pii' do
- expect(form.user_pii).to eq expected_user_pii
- end
- end
-
- describe '#service_error?' do
- context 'when there is a service-related error' do
- let(:payload_hash) { { service_error: 'service error' } }
-
- it 'returns true' do
- expect(form.service_error?).to be true
- end
- end
-
- context 'when there is not a service-related error' do
- it 'returns false' do
- expect(form.service_error?).to be false
- end
- end
- end
-end
diff --git a/spec/i18n_spec.rb b/spec/i18n_spec.rb
index fe11f2cec91..ef3f2601abe 100644
--- a/spec/i18n_spec.rb
+++ b/spec/i18n_spec.rb
@@ -16,6 +16,7 @@ class BaseTask
{ key: 'account.navigation.menu', locales: %i[fr] }, # "Menu" is "Menu" in French
{ key: 'doc_auth.headings.photo', locales: %i[fr] }, # "Photo" is "Photo" in French
{ key: /^i18n\.locale\./ }, # Show locale options translated as that language
+ { key: /^i18n\.transliterate\./ }, # Approximate non-ASCII characters in ASCII
{ key: /^countries/ }, # Some countries have the same name across languages
{ key: 'links.contact', locales: %i[fr] }, # "Contact" is "Contact" in French
{ key: 'simple_form.no', locales: %i[es] }, # "No" is "No" in Spanish
@@ -89,7 +90,9 @@ def allowed_untranslated_key?(locale, key)
missing_interpolation_argument_keys = []
i18n.data[i18n.base_locale].select_keys do |key, _node|
- next if i18n.t(key).is_a?(Array) || i18n.t(key).nil?
+ if key.start_with?('i18n.transliterate.rule.') || i18n.t(key).is_a?(Array) || i18n.t(key).nil?
+ next
+ end
interpolation_arguments = i18n.locales.map do |locale|
extract_interpolation_arguments i18n.t(key, locale)
@@ -109,20 +112,23 @@ def allowed_untranslated_key?(locale, key)
i18n_file = full_path.sub("#{root_dir}/", '')
describe i18n_file do
- it 'has only lower_snake_case keys' do
- keys = flatten_hash(YAML.load_file(full_path)).keys
+ # Transliteration includes special characters by definition, so it could fail the below checks
+ if !full_path.match?(%(/config/locales/transliterate/))
+ it 'has only lower_snake_case keys' do
+ keys = flatten_hash(YAML.load_file(full_path)).keys
- bad_keys = keys.reject { |key| key =~ /^[a-z0-9_.]+$/ }
+ bad_keys = keys.reject { |key| key =~ /^[a-z0-9_.]+$/ }
- expect(bad_keys).to be_empty
- end
+ expect(bad_keys).to be_empty
+ end
- it 'has only has XML-safe identifiers (keys start with a letter)' do
- keys = flatten_hash(YAML.load_file(full_path)).keys
+ it 'has only has XML-safe identifiers (keys start with a letter)' do
+ keys = flatten_hash(YAML.load_file(full_path)).keys
- bad_keys = keys.select { |key| key.split('.').any? { |part| part =~ /^[0-9]/ } }
+ bad_keys = keys.select { |key| key.split('.').any? { |part| part =~ /^[0-9]/ } }
- expect(bad_keys).to be_empty
+ expect(bad_keys).to be_empty
+ end
end
it 'has correctly-formatted interpolation values' do
diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb
index a39addc7f90..bd17b08c838 100644
--- a/spec/jobs/get_usps_proofing_results_job_spec.rb
+++ b/spec/jobs/get_usps_proofing_results_job_spec.rb
@@ -166,9 +166,10 @@
allow(job).to receive(:analytics).and_return(job_analytics)
allow(IdentityConfig.store).to receive(:get_usps_proofing_results_job_reprocess_delay_minutes).
and_return(reprocess_delay_minutes)
- allow(IdentityConfig.store).
- to receive(:get_usps_proofing_results_job_request_delay_milliseconds).
- and_return(request_delay_ms)
+ stub_const(
+ 'GetUspsProofingResultsJob::REQUEST_DELAY_IN_SECONDS',
+ request_delay_ms / GetUspsProofingResultsJob::MILLISECONDS_PER_SECOND,
+ )
stub_request_token
if respond_to?(:pending_enrollment)
pending_enrollment.update(enrollment_established_at: 3.days.ago)
diff --git a/spec/jobs/inherited_proofing_job_spec.rb b/spec/jobs/inherited_proofing_job_spec.rb
deleted file mode 100644
index 839d292cd33..00000000000
--- a/spec/jobs/inherited_proofing_job_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe InheritedProofingJob, type: :job do
- include Idv::InheritedProofing::ServiceProviderServices
- include Idv::InheritedProofing::ServiceProviderForms
- include_context 'va_api_context'
-
- let(:document_capture_session) { DocumentCaptureSession.new(result_id: SecureRandom.hex) }
- let(:service_provider_data) { { auth_code: 'mocked-auth-code-for-testing' } }
- let(:service_provider) { Idv::InheritedProofing::ServiceProviders::VA }
-
- before do
- allow(IdentityConfig.store).to receive(:va_inherited_proofing_mock_enabled).and_return true
- allow_any_instance_of(Idv::InheritedProofing::ServiceProviderServices).to \
- receive(:inherited_proofing?).and_return true
- end
-
- describe '#perform' do
- it 'calls api for user data and stores in document capture session' do
- document_capture_session.create_doc_auth_session
-
- InheritedProofingJob.perform_now(
- service_provider,
- service_provider_data,
- document_capture_session.uuid,
- )
-
- result = document_capture_session.load_proofing_result[:result]
-
- expect(result).to be_present
- expect(result).to include(last_name: 'Fakerson')
- end
- end
-end
diff --git a/spec/presenters/completions_presenter_spec.rb b/spec/presenters/completions_presenter_spec.rb
index 48e75c79b70..2265157fbbe 100644
--- a/spec/presenters/completions_presenter_spec.rb
+++ b/spec/presenters/completions_presenter_spec.rb
@@ -224,6 +224,27 @@
end
end
+ context 'user has reverified since last consent for sp' do
+ let(:identities) do
+ [
+ build(
+ :service_provider_identity,
+ service_provider: current_sp.issuer,
+ last_consented_at: 2.months.ago,
+ ),
+ ]
+ end
+ let(:completion_context) { :reverified_after_consent }
+ it 'renders the reverified IAL2 consent intro message' do
+ expect(presenter.intro).to eq(
+ I18n.t(
+ 'help_text.requested_attributes.ial2_reverified_consent_info',
+ sp: current_sp.friendly_name,
+ ),
+ )
+ end
+ end
+
context 'when consent has not expired' do
it 'renders the standard intro message' do
expect(presenter.intro).to eq(
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index c0d8fc9e9c1..2aec91ab96f 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -155,4 +155,18 @@ class Analytics
# Consider any browser console logging as a failure.
raise BrowserConsoleLogError.new(javascript_errors) if javascript_errors.present?
end
+
+ config.around(:each, allow_net_connect_on_start: true) do |example|
+ # Avoid "Too many open files - socket(2)" error on some local machines
+ WebMock.allow_net_connect!(net_http_connect_on_start: true)
+ example.run
+ WebMock.disable_net_connect!(
+ allow: [
+ /localhost/,
+ /127\.0\.0\.1/,
+ /codeclimate.com/, # For uploading coverage reports
+ /chromedriver\.storage\.googleapis\.com/, # For fetching a chromedriver binary
+ ],
+ )
+ end
end
diff --git a/spec/services/browser_support_spec.rb b/spec/services/browser_support_spec.rb
new file mode 100644
index 00000000000..d545eb22b14
--- /dev/null
+++ b/spec/services/browser_support_spec.rb
@@ -0,0 +1,127 @@
+require 'rails_helper'
+
+RSpec.describe BrowserSupport do
+ before { BrowserSupport.clear_cache! }
+
+ describe '.supported?' do
+ let(:user_agent) do
+ # Chrome v110
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like ' \
+ 'Gecko) Chrome/110.0.0.0 Safari/537.36'
+ end
+
+ subject(:supported) { BrowserSupport.supported?(user_agent) }
+
+ context 'with browser support config file missing' do
+ before do
+ expect(File).to receive(:read).once.with(Rails.root.join('browsers.json')).
+ and_raise(Errno::ENOENT.new)
+ end
+
+ it { expect(supported).to eq(true) }
+
+ it 'memoizes result of parsing browser config' do
+ BrowserSupport.supported?('a')
+ BrowserSupport.supported?('b')
+ end
+ end
+
+ context 'with invalid support config' do
+ before do
+ expect(File).to receive(:read).once.with(Rails.root.join('browsers.json')).
+ and_return('invalid')
+ end
+
+ it { expect(supported).to eq(true) }
+
+ it 'memoizes result of parsing browser config' do
+ BrowserSupport.supported?('a')
+ BrowserSupport.supported?('b')
+ end
+ end
+
+ context 'with valid browser support config' do
+ before do
+ allow(BrowserSupport).to receive(:browser_support_config).
+ and_return(['chrome 109', 'and_chr 108', 'ios_saf 14.5-14.8', 'op_mini all'])
+ end
+
+ context 'with nil user agent' do
+ let(:user_agent) { nil }
+
+ it { expect(supported).to eq(false) }
+ end
+
+ context 'with supported user agent' do
+ let(:user_agent) do
+ # Chrome v110
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like ' \
+ 'Gecko) Chrome/110.0.0.0 Safari/537.36'
+ end
+
+ it { expect(supported).to eq(true) }
+ end
+
+ context 'with unsupported user agent' do
+ let(:user_agent) do
+ # Chrome v108
+ 'Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 (KHTML, like Gecko) ' \
+ 'Chrome/108.0.2704.64 Safari/537.36'
+ end
+
+ it { expect(supported).to eq(false) }
+ end
+
+ context 'with user agent for non-numeric version test' do
+ let(:user_agent) do
+ # Opera v12
+ 'Opera/9.80 (Android; Opera Mini/36.2.2254/119.132; U; id) Presto/2.12.423 Version/12.16)'
+ end
+
+ it { expect(supported).to eq(true) }
+ end
+
+ context 'with user agent for version range test' do
+ context 'below version range' do
+ let(:user_agent) do
+ # Safari v11.2
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, ' \
+ 'like Gecko) Version/11.2 Mobile/15E148 Safari/604.1'
+ end
+
+ it { expect(supported).to eq(false) }
+ end
+
+ context 'within version range' do
+ let(:user_agent) do
+ # Safari v14.6
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, ' \
+ 'like Gecko) Mobile/15E148 Version/14.6 Safari/605.1.15 AlohaBrowser/3.1.5'
+ end
+
+ it { expect(supported).to eq(true) }
+ end
+
+ context 'above version range' do
+ let(:user_agent) do
+ # Safari v16.3
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML' \
+ ', like Gecko) Version/16.3 Mobile/15E148 Safari/604.1'
+ end
+
+ it { expect(supported).to eq(true) }
+ end
+ end
+ end
+
+ context 'with user agent for platform-specific version support' do
+ let(:user_agent) do
+ # Android Chrome v108
+ 'Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) ' \
+ 'Chrome/108.0.5481.153 Mobile Safari/537.36'
+ end
+
+ it { expect(supported).to eq(true) }
+ end
+ end
+end
diff --git a/spec/services/idv/inherited_proofing/service_provider_forms_spec.rb b/spec/services/idv/inherited_proofing/service_provider_forms_spec.rb
deleted file mode 100644
index bbad02b360e..00000000000
--- a/spec/services/idv/inherited_proofing/service_provider_forms_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Idv::InheritedProofing::ServiceProviderForms do
- subject do
- Class.new do
- include Idv::InheritedProofing::ServiceProviderForms
- end.new
- end
-
- let(:service_provider) { :va }
- let(:payload_hash) { Idv::InheritedProofing::Va::Mocks::Service::PAYLOAD_HASH }
-
- describe '#inherited_proofing_form_for' do
- context 'when there is a va inherited proofing request' do
- it 'returns the correct form' do
- expect(
- subject.inherited_proofing_form_for(
- service_provider,
- payload_hash: payload_hash,
- ),
- ).to \
- be_kind_of Idv::InheritedProofing::Va::Form
- end
- end
-
- context 'when the inherited proofing request cannot be identified' do
- let(:service_provider) { :unknown_service_provider }
-
- it 'raises an error' do
- expect do
- subject.inherited_proofing_form_for(service_provider, payload_hash: payload_hash)
- end.to \
- raise_error 'Inherited proofing form could not be identified'
- end
- end
- end
-end
diff --git a/spec/services/idv/inherited_proofing/service_provider_services_spec.rb b/spec/services/idv/inherited_proofing/service_provider_services_spec.rb
deleted file mode 100644
index 76380bf2374..00000000000
--- a/spec/services/idv/inherited_proofing/service_provider_services_spec.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Idv::InheritedProofing::ServiceProviderServices do
- subject do
- Class.new do
- include Idv::InheritedProofing::ServiceProviderServices
- end.new
- end
-
- let(:service_provider) { :va }
- let(:service_provider_data) { { auth_code: auth_code } }
- let(:auth_code) { Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE }
-
- describe '#inherited_proofing_service_class_for' do
- context 'when va inherited proofing is disabled' do
- before do
- allow(IdentityConfig.store).to receive(:inherited_proofing_enabled).and_return(false)
- end
-
- it 'raises an error' do
- expect do
- subject.inherited_proofing_service_class_for(service_provider)
- end.to raise_error 'Inherited Proofing is not enabled'
- end
- end
-
- context 'when there is a va inherited proofing request' do
- context 'when va mock proofing is turned on' do
- before do
- allow(IdentityConfig.store).to \
- receive(:va_inherited_proofing_mock_enabled).and_return(true)
- end
-
- it 'returns the correct service provider service class' do
- expect(subject.inherited_proofing_service_class_for(service_provider)).to \
- eq Idv::InheritedProofing::Va::Mocks::Service
- end
- end
-
- context 'when va mock proofing is turned off' do
- before do
- allow(IdentityConfig.store).to \
- receive(:va_inherited_proofing_mock_enabled).and_return(false)
- end
-
- it 'returns the correct service provider service class' do
- expect(subject.inherited_proofing_service_class_for(service_provider)).to \
- eq Idv::InheritedProofing::Va::Service
- end
- end
- end
-
- context 'when the inherited proofing class cannot be identified' do
- let(:service_provider) { :unknown_service_provider }
-
- it 'raises an error' do
- expect do
- subject.inherited_proofing_service_class_for(service_provider)
- end.to raise_error 'Inherited proofing service class could not be identified'
- end
- end
- end
-
- describe '#inherited_proofing_service_for' do
- context 'when there is a va inherited proofing request' do
- context 'when va mock proofing is turned on' do
- before do
- allow(IdentityConfig.store).to \
- receive(:va_inherited_proofing_mock_enabled).and_return(true)
- end
-
- it 'returns the correct service provider service class' do
- expect(
- subject.inherited_proofing_service_for(
- service_provider,
- service_provider_data: service_provider_data,
- ),
- ).to \
- be_kind_of Idv::InheritedProofing::Va::Mocks::Service
- end
- end
-
- context 'when va mock proofing is turned off' do
- before do
- allow(IdentityConfig.store).to \
- receive(:va_inherited_proofing_mock_enabled).and_return(false)
- end
-
- it 'returns the correct service provider service class' do
- expect(
- subject.inherited_proofing_service_for(
- service_provider,
- service_provider_data: service_provider_data,
- ),
- ).to \
- be_kind_of Idv::InheritedProofing::Va::Service
- end
- end
- end
- end
-end
diff --git a/spec/services/idv/inherited_proofing/va/mocks/service_spec.rb b/spec/services/idv/inherited_proofing/va/mocks/service_spec.rb
deleted file mode 100644
index 865383e874b..00000000000
--- a/spec/services/idv/inherited_proofing/va/mocks/service_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Idv::InheritedProofing::Va::Mocks::Service do
- subject { described_class.new({ auth_code: auth_code }) }
- let(:auth_code) { described_class::VALID_AUTH_CODE }
-
- describe '#initialize' do
- it 'sets #auth_code' do
- expect(subject.auth_code).to eq auth_code
- end
- end
-
- describe '#execute' do
- context 'when auth_code is valid' do
- it 'returns a Hash' do
- expect(subject.execute).to eq(described_class::PAYLOAD_HASH)
- end
- end
-
- context 'with auth code is invalid' do
- let(:auth_code) { "invalid-#{described_class::VALID_AUTH_CODE}" }
-
- it 'returns an error' do
- expect(subject.execute).to eq(described_class::ERROR_HASH)
- end
- end
- end
-end
diff --git a/spec/services/idv/inherited_proofing/va/service_spec.rb b/spec/services/idv/inherited_proofing/va/service_spec.rb
deleted file mode 100644
index 7a5dece157b..00000000000
--- a/spec/services/idv/inherited_proofing/va/service_spec.rb
+++ /dev/null
@@ -1,124 +0,0 @@
-require 'rails_helper'
-
-RSpec.shared_examples 'an invalid auth code error is raised' do
- it 'raises an error' do
- expect { subject.execute }.to raise_error 'The provided auth_code is blank?'
- end
-end
-
-RSpec.describe Idv::InheritedProofing::Va::Service do
- include_context 'va_api_context'
- include_context 'va_user_context'
-
- subject(:service) { described_class.new(auth_code: auth_code) }
-
- before do
- allow(service).to receive(:private_key).and_return(private_key)
- end
-
- it { respond_to :execute }
-
- it do
- expect(service.send(:private_key)).to eq private_key
- end
-
- describe '#execute' do
- context 'when the auth code is valid' do
- let(:auth_code) { 'mocked-auth-code-for-testing' }
-
- it 'makes an authenticated request' do
- freeze_time do
- stub = stub_request(:get, request_uri).
- with(headers: request_headers).
- to_return(status: 200, body: '{}', headers: {})
-
- service.execute
-
- expect(stub).to have_been_requested.once
- end
- end
-
- it 'decrypts the response' do
- freeze_time do
- stub_request(:get, request_uri).
- with(headers: request_headers).
- to_return(status: 200, body: encrypted_user_attributes, headers: {})
-
- expect(service.execute).to eq user_attributes
- end
- end
- end
-
- context 'when the auth code is invalid' do
- context 'when an empty? string' do
- let(:auth_code) { '' }
-
- it_behaves_like 'an invalid auth code error is raised'
- end
-
- context 'when an nil?' do
- let(:auth_code) { nil }
-
- it_behaves_like 'an invalid auth code error is raised'
- end
- end
-
- context 'when a request error is raised' do
- before do
- allow(service).to receive(:request).and_raise('Boom!')
- end
-
- it 'rescues and returns the error' do
- expect(service.execute).to eq({ service_error: 'Boom!' })
- end
- end
-
- context 'when a decryption error is raised' do
- it 'rescues and returns the error' do
- freeze_time do
- stub_request(:get, request_uri).
- with(headers: request_headers).
- to_return(status: 200, body: 'xyz', headers: {})
-
- expect(service.execute[:service_error]).to match(/unexpected token at 'xyz'/)
- end
- end
- end
-
- context 'when a non-200 error is raised' do
- it 'rescues and returns the error' do
- freeze_time do
- stub_request(:get, request_uri).
- with(headers: request_headers).
- to_return(status: 302, body: encrypted_user_attributes, headers: {})
-
- expect(service.execute.to_s).to \
- match(/The service provider API returned an http status other than 200/)
- end
- end
-
- context 'when http status is unavailable (nil)' do
- before do
- allow_any_instance_of(Faraday::Response).to receive(:status).and_return(nil)
- end
-
- let(:expected_error) do
- {
- service_error: 'The service provider API returned an http status other than 200: ' \
- 'unavailable (unavailable)',
- }
- end
-
- it 'rescues and returns the error' do
- freeze_time do
- stub_request(:get, request_uri).
- with(headers: request_headers).
- to_return(status: nil, body: encrypted_user_attributes, headers: {})
-
- expect(service.execute).to eq expected_error
- end
- end
- end
- end
- end
-end
diff --git a/spec/services/idv/steps/in_person/address_step_spec.rb b/spec/services/idv/steps/in_person/address_step_spec.rb
index c4d89ee306e..cfadab1c5c2 100644
--- a/spec/services/idv/steps/in_person/address_step_spec.rb
+++ b/spec/services/idv/steps/in_person/address_step_spec.rb
@@ -2,7 +2,7 @@
describe Idv::Steps::InPerson::AddressStep do
let(:submitted_values) { {} }
- let(:params) { { doc_auth: submitted_values } }
+ let(:params) { ActionController::Parameters.new({ in_person_address: submitted_values }) }
let(:user) { build(:user) }
let(:service_provider) { create(:service_provider) }
let(:controller) do
diff --git a/spec/services/idv/steps/in_person/state_id_step_spec.rb b/spec/services/idv/steps/in_person/state_id_step_spec.rb
index 3d1ea03fd11..f3767209e18 100644
--- a/spec/services/idv/steps/in_person/state_id_step_spec.rb
+++ b/spec/services/idv/steps/in_person/state_id_step_spec.rb
@@ -2,7 +2,7 @@
describe Idv::Steps::InPerson::StateIdStep do
let(:submitted_values) { {} }
- let(:params) { { doc_auth: submitted_values } }
+ let(:params) { ActionController::Parameters.new({ state_id: submitted_values }) }
let(:user) { build(:user) }
let(:service_provider) { create(:service_provider) }
let(:controller) do
@@ -78,6 +78,7 @@
let(:dob) { '1972-02-23' }
let(:first_name) { 'First name' }
let(:pii_from_user) { flow.flow_session[:pii_from_user] }
+ let(:params) { ActionController::Parameters.new }
context 'first name and dob are set' do
it 'returns extra view variables' do
diff --git a/spec/services/idv/steps/ssn_step_spec.rb b/spec/services/idv/steps/ssn_step_spec.rb
deleted file mode 100644
index 75ea852f83d..00000000000
--- a/spec/services/idv/steps/ssn_step_spec.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-require 'rails_helper'
-
-describe Idv::Steps::SsnStep do
- include Rails.application.routes.url_helpers
-
- let(:user) { build(:user) }
- let(:params) { { doc_auth: {} } }
- let(:session) { { sp: { issuer: service_provider.issuer } } }
- let(:attempts_api) { IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new }
- let(:service_provider) do
- create(
- :service_provider,
- issuer: 'http://sp.example.com',
- app_id: '123',
- )
- end
- let(:controller) do
- instance_double(
- 'controller',
- session: session,
- current_user: user,
- params: params,
- analytics: FakeAnalytics.new,
- irs_attempts_api_tracker: attempts_api,
- url_options: {},
- request: double(
- 'request',
- headers: {
- 'X-Amzn-Trace-Id' => amzn_trace_id,
- },
- ),
- )
- end
- let(:amzn_trace_id) { SecureRandom.uuid }
-
- let(:pii_from_doc) do
- {
- first_name: Faker::Name.first_name,
- }
- 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
-
- subject(:step) do
- Idv::Steps::SsnStep.new(flow)
- end
-
- describe '#call' do
- context 'with valid ssn' do
- let(:ssn) { Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn] }
- let(:params) { { doc_auth: { ssn: ssn } } }
-
- it 'merges ssn into pii session value' do
- step.call
-
- expect(flow.flow_session[:pii_from_doc][:ssn]).to eq(ssn)
- end
-
- it 'logs attempts api event' do
- expect(attempts_api).to receive(:idv_ssn_submitted).with(
- ssn: ssn,
- )
- step.call
- end
-
- context 'with existing session applicant' do
- let(:session) { super().merge(idv: { 'applicant' => {} }) }
-
- it 'clears applicant' do
- step.call
-
- expect(session[:idv]['applicant']).to be_blank
- end
- end
-
- it 'adds a threatmetrix session id to flow session' do
- step.extra_view_variables
- expect(flow.flow_session[:threatmetrix_session_id]).to_not eq(nil)
- end
-
- it 'does not change threatmetrix_session_id when updating ssn' do
- step.call
- session_id = flow.flow_session[:threatmetrix_session_id]
- step.extra_view_variables
- expect(flow.flow_session[:threatmetrix_session_id]).to eq(session_id)
- end
- end
-
- context 'when pii_from_doc is not present' do
- let(:flow) do
- Idv::Flows::DocAuthFlow.new(controller, {}, 'idv/doc_auth').tap do |flow|
- flow.flow_session = { 'Idv::Steps::DocumentCaptureStep' => true }
- end
- end
-
- it 'marks previous step as incomplete' do
- expect(flow.flow_session['Idv::Steps::DocumentCaptureStep']).to eq true
- result = step.call
- expect(flow.flow_session['Idv::Steps::DocumentCaptureStep']).to eq nil
- expect(result.success?).to eq false
- end
- end
- end
-end
diff --git a/spec/services/proofing/aamva/response/verification_response_spec.rb b/spec/services/proofing/aamva/response/verification_response_spec.rb
index 5f5aeff4348..39ff9c207ba 100644
--- a/spec/services/proofing/aamva/response/verification_response_spec.rb
+++ b/spec/services/proofing/aamva/response/verification_response_spec.rb
@@ -49,7 +49,7 @@
it 'raises a VerificationError' do
expect { subject }.to raise_error(
Proofing::Aamva::VerificationError,
- 'Unexpected status code in response: 504',
+ /Unexpected status code in response: 504/,
)
end
end
diff --git a/spec/services/proofing/aamva/verification_client_spec.rb b/spec/services/proofing/aamva/verification_client_spec.rb
index 46348a8a73e..1412531714a 100644
--- a/spec/services/proofing/aamva/verification_client_spec.rb
+++ b/spec/services/proofing/aamva/verification_client_spec.rb
@@ -19,11 +19,13 @@
subject(:verification_client) { described_class.new(AamvaFixtures.example_config) }
describe '#send_verification_request' do
- it 'should get the auth token from the auth client' do
+ before do
auth_client = instance_double(Proofing::Aamva::AuthenticationClient)
allow(auth_client).to receive(:fetch_token).and_return('ThisIsTheToken')
allow(Proofing::Aamva::AuthenticationClient).to receive(:new).and_return(auth_client)
+ end
+ it 'gets the auth token from the auth client' do
verification_stub = stub_request(:post, AamvaFixtures.example_config.verification_url).
to_return(body: AamvaFixtures.verification_response, status: 200).
with do |request|
@@ -37,45 +39,149 @@
expect(verification_stub).to have_been_requested
end
+ end
- context 'when verification is successful' do
- it 'should return a successful response' do
- auth_client = instance_double(Proofing::Aamva::AuthenticationClient)
- allow(auth_client).to receive(:fetch_token).and_return('ThisIsTheToken')
- allow(Proofing::Aamva::AuthenticationClient).to receive(:new).and_return(auth_client)
- stub_request(:post, AamvaFixtures.example_config.verification_url).
- to_return(body: AamvaFixtures.verification_response, status: 200)
-
- response = verification_client.send_verification_request(
- applicant: applicant,
- session_id: '1234-abcd-efgh',
- )
+ describe '#send_verification_request' do
+ let(:response_body) { AamvaFixtures.verification_response }
+ let(:response_http_status) { 200 }
+
+ before do
+ auth_client = instance_double(Proofing::Aamva::AuthenticationClient)
+ allow(auth_client).to receive(:fetch_token).and_return('ThisIsTheToken')
+ allow(Proofing::Aamva::AuthenticationClient).to receive(:new).and_return(auth_client)
+
+ stub_request(:post, AamvaFixtures.example_config.verification_url).
+ to_return(body: response_body, status: response_http_status)
+ end
+
+ let(:response) do
+ verification_client.send_verification_request(
+ applicant: applicant,
+ session_id: '1234-abcd-efgh',
+ )
+ end
+ context 'when verification is successful' do
+ it 'returns a successful response' do
expect(response).to be_a Proofing::Aamva::Response::VerificationResponse
expect(response.success?).to eq(true)
end
end
context 'when verification is not successful' do
- it 'should return an unsuccessful response with errors' do
- auth_client = instance_double(Proofing::Aamva::AuthenticationClient)
- allow(auth_client).to receive(:fetch_token).and_return('ThisIsTheToken')
- allow(Proofing::Aamva::AuthenticationClient).to receive(:new).and_return(auth_client)
+ context 'because we have a valid response and a 200 status, but the response says "no"' do
+ let(:response_body) do
+ modify_xml_at_xpath(
+ AamvaFixtures.verification_response,
+ '//PersonBirthDateMatchIndicator',
+ 'false',
+ )
+ end
+
+ it 'returns an unsuccessful response with errors' do
+ expect(response).to be_a Proofing::Aamva::Response::VerificationResponse
+ expect(response.success?).to eq(false)
+ end
+ end
- stub_request(:post, AamvaFixtures.example_config.verification_url).
- to_return(status: 200, body: modify_xml_at_xpath(
+ context 'because we have a valid response and a non-200 status, and the response says "no"' do
+ let(:response_body) do
+ modify_xml_at_xpath(
AamvaFixtures.verification_response,
'//PersonBirthDateMatchIndicator',
'false',
- ))
+ )
+ end
+ let(:response_http_status) { 500 }
+
+ it 'throws an exception about the status code' do
+ expect { response }.to raise_error(
+ Proofing::Aamva::VerificationError,
+ /Unexpected status code in response: 500/,
+ )
+ end
+ end
- response = verification_client.send_verification_request(
- applicant: applicant,
- session_id: '1234-abcd-efgh',
- )
+ context 'because we have an MVA timeout and 500 status' do
+ let(:response_body) { AamvaFixtures.soap_fault_response }
+ let(:response_http_status) { 500 }
- expect(response).to be_a Proofing::Aamva::Response::VerificationResponse
- expect(response.success?).to eq(false)
+ it 'throws an exception about the MVA timeout' do
+ expect { response }.to raise_error(
+ Proofing::Aamva::VerificationError,
+ /#{Proofing::Aamva::Response::VerificationResponse::MVA_TIMEOUT_EXCEPTION}/o,
+ )
+ end
+
+ it 'throws an exception about the status code' do
+ expect { response }.to raise_error(
+ Proofing::Aamva::VerificationError,
+ /Unexpected status code in response: 500/,
+ )
+ end
+ end
+
+ context 'because we have an MVA timeout and 200 status' do
+ let(:response_body) { AamvaFixtures.soap_fault_response }
+ let(:response_http_status) { 200 }
+
+ it 'parses the raw response body' do
+ begin
+ response
+ rescue Proofing::Aamva::VerificationError
+ end
+ end
+
+ it 'throws an exception about the MVA timeout' do
+ expect { response }.to raise_error(
+ Proofing::Aamva::VerificationError,
+ /#{Proofing::Aamva::Response::VerificationResponse::MVA_TIMEOUT_EXCEPTION}/o,
+ )
+ end
+ end
+
+ context 'because we have an invalid response and a 200 status' do
+ let(:response_body) { 'error: computer has no brain.
' }
+
+ it 'tries to parse the raw response body' do
+ begin
+ response
+ rescue Proofing::Aamva::VerificationError
+ end
+ end
+
+ it 'throws a SOAP exception' do
+ expect { response }.to raise_error(
+ Proofing::Aamva::VerificationError,
+ /No close tag for \/br/,
+ )
+ end
+ end
+
+ context 'because we have an invalid response and a non-200 status' do
+ let(:response_body) { 'I\'m a teapot' }
+ let(:response_http_status) { 418 }
+
+ it 'tries to parse the raw response body' do
+ begin
+ response
+ rescue Proofing::Aamva::VerificationError
+ end
+ end
+
+ it 'throws an error which complains about the invalid response' do
+ expect { response }.to raise_error(
+ Proofing::Aamva::VerificationError,
+ /No close tag for \/h1/,
+ )
+ end
+
+ it 'throws an error which complains about the HTTP error code' do
+ expect { response }.to raise_error(
+ Proofing::Aamva::VerificationError,
+ /Unexpected status code in response: 418/,
+ )
+ end
end
end
end
diff --git a/spec/services/proofing/lexis_nexis/instant_verify/proofing_spec.rb b/spec/services/proofing/lexis_nexis/instant_verify/proofing_spec.rb
index fdeb8b9ba9f..ffd2146795e 100644
--- a/spec/services/proofing/lexis_nexis/instant_verify/proofing_spec.rb
+++ b/spec/services/proofing/lexis_nexis/instant_verify/proofing_spec.rb
@@ -44,7 +44,7 @@
result = subject.proof(applicant)
expect(result.success?).to eq(true)
- expect(result.errors).to eq({})
+ expect(result.errors).to include(InstantVerify: include(a_kind_of(Hash)))
expect(result.vendor_workflow).to(
eq(LexisNexisFixtures.example_config.phone_finder_workflow),
)
diff --git a/spec/services/proofing/lexis_nexis/phone_finder/proofing_spec.rb b/spec/services/proofing/lexis_nexis/phone_finder/proofing_spec.rb
index 6ba049bc9a6..074142ab8d7 100644
--- a/spec/services/proofing/lexis_nexis/phone_finder/proofing_spec.rb
+++ b/spec/services/proofing/lexis_nexis/phone_finder/proofing_spec.rb
@@ -48,7 +48,9 @@
result = subject.proof(applicant)
expect(result.success?).to eq(true)
- expect(result.errors).to eq({})
+ expect(result.errors).to include(
+ PhoneFinder: include(a_kind_of(Hash)),
+ )
expect(result.vendor_workflow).to(
eq(LexisNexisFixtures.example_config.phone_finder_workflow),
)
@@ -69,7 +71,6 @@
expect(result.success?).to eq(false)
expect(result.errors).to include(
- base: include(a_kind_of(String)),
PhoneFinder: include(a_kind_of(Hash)),
)
expect(result.transaction_id).to eq('31000000000000')
diff --git a/spec/services/proofing/lexis_nexis/response_spec.rb b/spec/services/proofing/lexis_nexis/response_spec.rb
index f61d77c61c9..cc434136747 100644
--- a/spec/services/proofing/lexis_nexis/response_spec.rb
+++ b/spec/services/proofing/lexis_nexis/response_spec.rb
@@ -38,7 +38,11 @@
end
context 'with a passed verification' do
- it { expect(subject.verification_errors).to eq({}) }
+ it 'returns a hash of error' do
+ errors = subject.verification_errors
+
+ expect(errors).to have_key(:InstantVerify)
+ end
end
end
diff --git a/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb b/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb
index 5ca6594595d..6386f38098f 100644
--- a/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb
+++ b/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb
@@ -11,15 +11,24 @@
merge(same_address_as_id: current_address_matches_id).
transform_keys(&:to_s)
end
- let(:subject) { described_class }
+ subject(:subject) { described_class }
let(:subject_analytics) { FakeAnalytics.new }
+ let(:transliterator) { UspsInPersonProofing::Transliterator.new }
let(:service_provider) { nil }
+ let(:usps_ipp_transliteration_enabled) { true }
before(:each) do
stub_request_token
stub_request_enroll
allow(IdentityConfig.store).to receive(:usps_mock_fallback).and_return(usps_mock_fallback)
+ allow(subject).to receive(:transliterator).and_return(transliterator)
+ allow(transliterator).to receive(:transliterate).
+ with(anything) do |val|
+ transliterated_without_change(val)
+ end
allow(subject).to receive(:analytics).and_return(subject_analytics)
+ allow(IdentityConfig.store).to receive(:usps_ipp_transliteration_enabled).
+ and_return(usps_ipp_transliteration_enabled)
end
describe '#schedule_in_person_enrollment' do
@@ -58,38 +67,79 @@
expect(enrollment.current_address_matches_id).to eq(current_address_matches_id)
end
- it 'creates usps enrollment' do
- proofer = UspsInPersonProofing::Mock::Proofer.new
- mock = double
-
- expect(UspsInPersonProofing::Proofer).to receive(:new).and_return(mock)
- expect(mock).to receive(:request_enroll) do |applicant|
- expect(applicant.first_name).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:first_name])
- expect(applicant.last_name).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:last_name])
- expect(applicant.address).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:address1])
- expect(applicant.city).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:city])
- expect(applicant.state).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:state])
- expect(applicant.zip_code).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:zipcode])
- expect(applicant.email).to eq('no-reply@login.gov')
- expect(applicant.unique_id).to eq(enrollment.unique_id)
-
- proofer.request_enroll(applicant)
+ context 'transliteration disabled' do
+ let(:usps_ipp_transliteration_enabled) { false }
+
+ it 'creates usps enrollment without using transliteration' do
+ mock_proofer = double(UspsInPersonProofing::Mock::Proofer)
+ expect(subject).to receive(:usps_proofer).and_return(mock_proofer)
+
+ expect(transliterator).not_to receive(:transliterate)
+ expect(mock_proofer).to receive(:request_enroll) do |applicant|
+ expect(applicant.first_name).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:first_name])
+ expect(applicant.last_name).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:last_name])
+ expect(applicant.address).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:address1])
+ expect(applicant.city).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:city])
+ expect(applicant.state).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:state])
+ expect(applicant.zip_code).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:zipcode])
+ expect(applicant.email).to eq('no-reply@login.gov')
+ expect(applicant.unique_id).to eq(enrollment.unique_id)
+
+ UspsInPersonProofing::Mock::Proofer.new.request_enroll(applicant)
+ end
+
+ subject.schedule_in_person_enrollment(user, pii)
end
+ end
- subject.schedule_in_person_enrollment(user, pii)
+ context 'transliteration enabled' do
+ let(:usps_ipp_transliteration_enabled) { true }
+
+ it 'creates usps enrollment while using transliteration' do
+ mock_proofer = double(UspsInPersonProofing::Mock::Proofer)
+ expect(subject).to receive(:usps_proofer).and_return(mock_proofer)
+
+ first_name = Idp::Constants::MOCK_IDV_APPLICANT[:first_name]
+ last_name = Idp::Constants::MOCK_IDV_APPLICANT[:last_name]
+ address = Idp::Constants::MOCK_IDV_APPLICANT[:address1]
+ city = Idp::Constants::MOCK_IDV_APPLICANT[:city]
+
+ expect(transliterator).to receive(:transliterate).
+ with(first_name).and_return(transliterated_without_change(first_name))
+ expect(transliterator).to receive(:transliterate).
+ with(last_name).and_return(transliterated(last_name))
+ expect(transliterator).to receive(:transliterate).
+ with(address).and_return(transliterated_with_failure(address))
+ expect(transliterator).to receive(:transliterate).
+ with(city).and_return(transliterated(city))
+
+ expect(mock_proofer).to receive(:request_enroll) do |applicant|
+ expect(applicant.first_name).to eq(first_name)
+ expect(applicant.last_name).to eq("transliterated_#{last_name}")
+ expect(applicant.address).to eq(address)
+ expect(applicant.city).to eq("transliterated_#{city}")
+ expect(applicant.state).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:state])
+ expect(applicant.zip_code).to eq(Idp::Constants::MOCK_IDV_APPLICANT[:zipcode])
+ expect(applicant.email).to eq('no-reply@login.gov')
+ expect(applicant.unique_id).to eq(enrollment.unique_id)
+
+ UspsInPersonProofing::Mock::Proofer.new.request_enroll(applicant)
+ end
+
+ subject.schedule_in_person_enrollment(user, pii)
+ end
end
context 'when the enrollment does not have a unique ID' do
it 'uses the deprecated InPersonEnrollment#usps_unique_id value to create the enrollment' do
enrollment.update(unique_id: nil)
- proofer = UspsInPersonProofing::Mock::Proofer.new
- mock = double
+ mock_proofer = double(UspsInPersonProofing::Mock::Proofer)
+ expect(subject).to receive(:usps_proofer).and_return(mock_proofer)
- expect(UspsInPersonProofing::Proofer).to receive(:new).and_return(mock)
- expect(mock).to receive(:request_enroll) do |applicant|
+ expect(mock_proofer).to receive(:request_enroll) do |applicant|
expect(applicant.unique_id).to eq(enrollment.usps_unique_id)
- proofer.request_enroll(applicant)
+ UspsInPersonProofing::Mock::Proofer.new.request_enroll(applicant)
end
subject.schedule_in_person_enrollment(user, pii)
@@ -146,4 +196,31 @@
end
end
end
+
+ def transliterated_without_change(value)
+ UspsInPersonProofing::Transliterator::TransliterationResult.new(
+ changed?: false,
+ original: value,
+ transliterated: value,
+ unsupported_chars: [],
+ )
+ end
+
+ def transliterated(value)
+ UspsInPersonProofing::Transliterator::TransliterationResult.new(
+ changed?: true,
+ original: value,
+ transliterated: "transliterated_#{value}",
+ unsupported_chars: [],
+ )
+ end
+
+ def transliterated_with_failure(value)
+ UspsInPersonProofing::Transliterator::TransliterationResult.new(
+ changed?: true,
+ original: value,
+ transliterated: "transliterated_failed_#{value}",
+ unsupported_chars: [':'],
+ )
+ end
end
diff --git a/spec/services/usps_in_person_proofing/transliterator_spec.rb b/spec/services/usps_in_person_proofing/transliterator_spec.rb
new file mode 100644
index 00000000000..bbc0ac03dff
--- /dev/null
+++ b/spec/services/usps_in_person_proofing/transliterator_spec.rb
@@ -0,0 +1,93 @@
+require 'rails_helper'
+
+RSpec.describe UspsInPersonProofing::Transliterator do
+ describe '#transliterate' do
+ subject(:transliterator) { UspsInPersonProofing::Transliterator.new }
+ context 'baseline functionality' do
+ context 'with an input that requires transliteration' do
+ let(:input_value) { "\t\n BobИy \t TЉble?s\r\n" }
+ let(:result) { transliterator.transliterate(input_value) }
+ let(:transliterated_result) { 'Bob?y T?ble?s' }
+
+ it 'returns the original value that was requested to be transliterated' do
+ expect(result.original).to eq(input_value)
+ end
+ it 'includes a "changed?" key indicating that transliteration did change the value' do
+ expect(result.changed?).to be(true)
+ end
+ it 'strips whitespace from the ends' do
+ expect(result.transliterated).not_to match(/^\s+/)
+ expect(result.transliterated).not_to match(/\s+^/)
+ end
+ it 'replaces consecutive whitespaces with regular spaces' do
+ expect(result.transliterated).not_to match(/\s\s/)
+ expect(result.transliterated).not_to match(/[^\S ]+/)
+ end
+ it 'returns a list of the characters that transliteration does not support' do
+ expect(result.unsupported_chars).to include('И', 'Љ')
+ end
+ it 'transliterates using English locale when default does not match' do
+ expect(I18n).to receive(:transliterate).
+ with(duck_type(:to_s), locale: :en).
+ and_call_original
+ result
+ end
+ it 'does not count question marks as unsupported characters by default' do
+ expect(result.unsupported_chars).not_to include('?')
+ expect(result.transliterated).to include('?')
+ end
+ it 'returns the transliterated value' do
+ expect(result.transliterated).to eq(transliterated_result)
+ end
+ end
+ context 'with an input that does not require transliteration' do
+ let(:input_value) { 'Abc Is My Fav Number' }
+ let(:result) { transliterator.transliterate(input_value) }
+
+ it 'returns the original value that was requested to be transliterated' do
+ expect(result.original).to eq(input_value)
+ end
+ it 'includes a "changed?" key indicating that transliteration did not change the value' do
+ expect(result.changed?).to be(false)
+ end
+
+ it 'transliterated value is identical to the original value' do
+ expect(result.transliterated).to eq(input_value)
+ end
+ end
+ end
+
+ context 'for additional values not supported for transliteration by default' do
+ {
+ # Convert okina to apostrophe
+ "ʻ": "'",
+ # Convert quotation marks
+ "’": "'",
+ "‘": "'",
+ "‛": "'",
+ "“": '"',
+ "‟": '"',
+ "”": '"',
+ # Convert hyphens
+ "‐": '-',
+ "‑": '-',
+ "‒": '-',
+ "–": '-',
+ "—": '-',
+ "﹘": '-',
+ # Convert number signs
+ "﹟": '#',
+ "#": '#',
+ }.each do |key, value|
+ it "converts \"\\u#{key.to_s.ord.to_s(16).rjust(
+ 4,
+ '0',
+ )}\" to \"\\u#{value.ord.to_s(16).rjust(
+ 4, '0'
+ )}\"" do
+ expect(transliterator.transliterate(key).transliterated).to eq(value)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/controller_helper.rb b/spec/support/controller_helper.rb
index d607be3fd3c..61db17ce642 100644
--- a/spec/support/controller_helper.rb
+++ b/spec/support/controller_helper.rb
@@ -67,6 +67,7 @@ def stub_verify_steps_one_and_two(user)
ssn: '666-12-1234',
}.with_indifferent_access
idv_session.profile_confirmation = true
+ idv_session.resolution_successful = 'phone'
allow(subject).to receive(:confirm_idv_applicant_created).and_return(true)
allow(subject).to receive(:idv_session).and_return(idv_session)
allow(subject).to receive(:user_session).and_return(user_session)
diff --git a/spec/support/features/doc_auth_helper.rb b/spec/support/features/doc_auth_helper.rb
index cb3ec0ddc96..0a52a1708f9 100644
--- a/spec/support/features/doc_auth_helper.rb
+++ b/spec/support/features/doc_auth_helper.rb
@@ -5,6 +5,7 @@ module DocAuthHelper
GOOD_SSN = Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn]
GOOD_SSN_MASKED = '9**-**-***4'
+ SAMPLE_TMX_SUMMARY_REASON_CODE = { tmx_summary_reason_code: ['Identity_Negative_History'] }
SSN_THAT_FAILS_RESOLUTION = '123-45-6666'
SSN_THAT_RAISES_EXCEPTION = '000-00-0000'
@@ -57,10 +58,6 @@ def idv_doc_auth_upload_step
idv_doc_auth_step_path(step: :upload)
end
- def idv_doc_auth_ssn_step
- idv_doc_auth_step_path(step: :ssn)
- end
-
def idv_doc_auth_document_capture_step
idv_doc_auth_step_path(step: :document_capture)
end
@@ -303,4 +300,22 @@ def fill_out_address_form_fail
def fill_out_doc_auth_phone_form_ok(phone = '415-555-0199')
fill_in :doc_auth_phone, with: phone
end
+
+ def complete_all_idv_steps_with(threatmetrix:)
+ allow(IdentityConfig.store).to receive(:otp_delivery_blocklist_maxretry).and_return(300)
+ user = create(:user, :signed_up)
+ visit_idp_from_ial1_oidc_sp(
+ client_id: service_provider.issuer,
+ irs_attempts_api_session_id: 'test-session-id',
+ )
+ visit root_path
+ sign_in_and_2fa_user(user)
+ complete_doc_auth_steps_before_ssn_step
+ select threatmetrix, from: :mock_profiling_result
+ complete_ssn_step
+ click_idv_continue
+ complete_phone_step(user)
+ complete_review_step(user)
+ acknowledge_and_confirm_personal_key
+ end
end
diff --git a/spec/support/features/idv_helper.rb b/spec/support/features/idv_helper.rb
index 13cf08e2199..2deaaf63487 100644
--- a/spec/support/features/idv_helper.rb
+++ b/spec/support/features/idv_helper.rb
@@ -152,30 +152,6 @@ def visit_idp_from_oidc_sp_with_ial2(
)
end
- def visit_idp_from_oidc_va_with_ial2(
- client_id: sp_oidc_issuer,
- state: SecureRandom.hex,
- nonce: SecureRandom.hex,
- verified_within: nil,
- inherited_proofing_auth: Idv::InheritedProofing::Va::Mocks::Service::VALID_AUTH_CODE
- )
- @state = state
- @client_id = sp_oidc_issuer
- @nonce = nonce
- visit openid_connect_authorize_path(
- client_id: client_id,
- response_type: 'code',
- acr_values: Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF,
- scope: 'openid email profile:name phone social_security_number',
- redirect_uri: sp_oidc_redirect_uri,
- state: state,
- prompt: 'select_account',
- nonce: nonce,
- verified_within: verified_within,
- inherited_proofing_auth: inherited_proofing_auth,
- )
- end
-
def visit_idp_from_oidc_sp_with_loa3
visit openid_connect_authorize_path(
client_id: sp_oidc_issuer,
diff --git a/spec/support/features/inherited_proofing_helper.rb b/spec/support/features/inherited_proofing_helper.rb
deleted file mode 100644
index 90e397d0ce6..00000000000
--- a/spec/support/features/inherited_proofing_helper.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require_relative 'idv_step_helper'
-require_relative 'doc_auth_helper'
-
-module InheritedProofingHelper
- include IdvStepHelper
- include DocAuthHelper
-
- # Steps
- def idv_ip_get_started_step
- idv_inherited_proofing_step_path(step: :get_started)
- end
-
- def idv_inherited_proofing_agreement_step
- idv_inherited_proofing_step_path(step: :agreement)
- end
-
- def idv_ip_verify_info_step
- idv_inherited_proofing_step_path(step: :verify_info)
- end
-
- # Traverse Steps
-
- # create account
- def complete_inherited_proofing_steps_before_get_started_step(expect_accessible: false)
- visit idv_ip_get_started_step unless current_path == idv_ip_get_started_step
- expect(page).to be_axe_clean.according_to :section508, :"best-practice" if expect_accessible
- end
-
- # get started
- def complete_get_started_step
- click_on t('inherited_proofing.buttons.continue')
- end
-
- def complete_inherited_proofing_steps_before_agreement_step(expect_accessible: false)
- complete_inherited_proofing_steps_before_get_started_step(expect_accessible: expect_accessible)
- complete_get_started_step
- expect(page).to be_axe_clean.according_to :section508, :"best-practice" if expect_accessible
- end
-
- # get started > agreement > verify_wait > please verify
- def complete_agreement_step
- find('label', text: t('inherited_proofing.instructions.consent', app_name: APP_NAME)).click
- click_on t('inherited_proofing.buttons.continue')
- end
-
- def complete_inherited_proofing_steps_before_verify_step(expect_accessible: false)
- complete_inherited_proofing_steps_before_agreement_step(expect_accessible: expect_accessible)
- complete_agreement_step
- expect(page).to be_axe_clean.according_to :section508, :"best-practice" if expect_accessible
- end
-
- def complete_inherited_proofing_verify_step
- click_on t('inherited_proofing.buttons.continue')
- end
-
- # get_started > agreement > verify_wait > please verify > complete
- def complete_all_inherited_proofing_steps_to_handoff(expect_accessible: false)
- complete_inherited_proofing_steps_before_verify_step(expect_accessible: expect_accessible)
- complete_inherited_proofing_verify_step
- expect(page).to be_axe_clean.according_to :section508, :"best-practice" if expect_accessible
- end
-end
diff --git a/spec/support/features/inherited_proofing_with_service_provider_helper.rb b/spec/support/features/inherited_proofing_with_service_provider_helper.rb
deleted file mode 100644
index f899b293d2c..00000000000
--- a/spec/support/features/inherited_proofing_with_service_provider_helper.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-require_relative 'idv_step_helper'
-require_relative 'doc_auth_helper'
-
-module InheritedProofingWithServiceProviderHelper
- include IdvStepHelper
- include DocAuthHelper
-
- # Simulates a user (in this case, a VA inherited proofing-authorized user)
- # coming over to login.gov from a service provider, and hitting the
- # OpenidConnect::AuthorizationController#index action.
- def send_user_from_service_provider_to_login_gov_openid_connect(user, inherited_proofing_auth)
- expect(user).to_not be_nil
- # NOTE: VA user.
- visit_idp_from_oidc_va_with_ial2 inherited_proofing_auth: inherited_proofing_auth
- end
-
- def complete_steps_up_to_inherited_proofing_get_started_step(user, expect_accessible: false)
- unless current_path == idv_inherited_proofing_step_path(step: :get_started)
- complete_idv_steps_before_phone_step(user)
- click_link t('links.cancel')
- click_button t('idv.cancel.actions.start_over')
- expect(page).to have_current_path(idv_inherited_proofing_step_path(step: :get_started))
- end
- expect(page).to be_axe_clean.according_to :section508, :"best-practice" if expect_accessible
- end
-
- def complete_steps_up_to_inherited_proofing_how_verifying_step(user, expect_accessible: false)
- complete_steps_up_to_inherited_proofing_get_started_step user,
- expect_accessible: expect_accessible
- unless current_path == idv_inherited_proofing_step_path(step: :agreement)
- click_on t('inherited_proofing.buttons.continue')
- end
- end
-
- def complete_steps_up_to_inherited_proofing_we_are_retrieving_step(user,
- expect_accessible: false)
- complete_steps_up_to_inherited_proofing_how_verifying_step(
- user,
- expect_accessible: expect_accessible,
- )
- unless current_path == idv_inherited_proofing_step_path(step: :verify_wait)
- check t('inherited_proofing.instructions.consent', app_name: APP_NAME),
- allow_label_click: true
- click_on t('inherited_proofing.buttons.continue')
- end
- end
-
- def complete_steps_up_to_inherited_proofing_verify_your_info_step(user,
- expect_accessible: false)
- complete_steps_up_to_inherited_proofing_we_are_retrieving_step(
- user,
- expect_accessible: expect_accessible,
- )
- end
-end
diff --git a/spec/support/idv_examples/fail_to_verify.rb b/spec/support/idv_examples/fail_to_verify.rb
deleted file mode 100644
index 2ce9e8650d9..00000000000
--- a/spec/support/idv_examples/fail_to_verify.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-shared_examples 'fail to verify idv info' do |step|
- let(:locale) { LinkLocaleResolver.locale }
- let(:step_locale_key) do
- return :sessions if step == :profile
- step
- end
-
- before do
- start_idv_from_sp
- complete_idv_steps_before_step(step)
- fill_out_idv_form_fail if step == :profile
- fill_out_phone_form_fail if step == :phone
- click_continue
- click_continue
- end
-
- it 'renders a warning failure screen and lets the user try again' do
- expect(page).to have_current_path(session_failure_path) if step == :profile
- expect(page).to have_current_path(phone_failure_path) if step == :phone
- expect(page).to have_content t("idv.failure.#{step_locale_key}.heading")
- expect(page).to have_content t("idv.failure.#{step_locale_key}.warning")
-
- click_on t('idv.failure.button.warning')
-
- if step == :profile
- fill_out_idv_form_ok
- click_idv_continue
- end
- fill_out_phone_form_ok if step == :phone
- click_idv_continue
-
- expect(page).to have_current_path(idv_phone_path) if step == :profile
- expect(page).to have_current_path(idv_otp_delivery_method_path) if step == :phone
- expect(page).to have_content(t('idv.titles.session.phone')) if step == :profile
- expect(page).to have_content(t('idv.titles.otp_delivery_method')) if step == :phone
- end
-
- def session_failure_path
- idv_session_errors_warning_path(local: locale)
- end
-
- def phone_failure_path
- idv_phone_errors_warning_path(locale: locale)
- end
-end
diff --git a/spec/support/shared_contexts/inherited_proofing/encrypted_user_attributes.json b/spec/support/shared_contexts/inherited_proofing/encrypted_user_attributes.json
deleted file mode 100644
index af29a512873..00000000000
--- a/spec/support/shared_contexts/inherited_proofing/encrypted_user_attributes.json
+++ /dev/null
@@ -1 +0,0 @@
-{"data":"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.IL_uTLpwR3ZoDQKuRY_clxK1AmrEnf3rCREIj8XGQ-iA7NxCiYfZ2CxuXFOTIzFbKXjcNYT1F56bCUuPwSmHNt88AGumB3RcskR6POfBu8EcjK2CI6myycGuQwm_1Dp9Vi55TQpSFRy5Bld7IR0gbk4ju0qTVSeH59-AyBGr0w07vojdHcPe-SDWEC1pG0_4iyVg0x2wOFAh6kIjMJ04sJYB4e7uW8hEI7lSwDLpiW-8KsjGhwCVIkUGPw7XKtLiWo1U_nXSragpG-E6XRx0Hn3YckSwEAMTATeZZPJr0TAAMO_jtukL0e7_ApwsCI-sEdI035_4befLlDnuz1QFJg.oLmsRlZKFlL_3Th4.YumiTPq6y8jyCpVwuSpqsd8iWQ_AqEN81v8pV9lB2dPb6po03aj05K361IWmWfB3gXir--L3nPpUdlFFkxF1X12QVkpfmH03kj01Zoaq9hZcQvY7d4QoOkMNkdONNFZ3_sp-4-11m5ki2TpD1AidkLe7AIaSvBvhYOq0TC-0veLwRvp5234-XyDq9o5hLogzUa3G1BxcZO_TxpS5IhV4CzJ2a-o_ymSgUULDjrAty23XMiqXxTMFbVCpMDrvgGTX2TYOYx0PngjySlir6Zf4WjKhvFBOd34hvx2MUYTEGPw.UcPA0owzraT7ckc1cRDzeg"}
diff --git a/spec/support/shared_contexts/inherited_proofing/va_api_context.rb b/spec/support/shared_contexts/inherited_proofing/va_api_context.rb
deleted file mode 100644
index bec50c6a17c..00000000000
--- a/spec/support/shared_contexts/inherited_proofing/va_api_context.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-RSpec.shared_context 'va_api_context' do
- # Sample mocked API call:
- # stub_request(:get, request_uri).
- # with(headers: request_headers).
- # to_return(status: 200, body: '{}', headers: {})
-
- let(:auth_code) { 'mocked-auth-code-for-testing' }
- let(:private_key) { private_key_from_store_or(file_name: 'empty.key') }
- let(:payload) { { inherited_proofing_auth: auth_code, exp: 1.day.from_now.to_i } }
- let(:jwt_token) { JWT.encode(payload, private_key, 'RS256') }
- let(:request_uri) do
- "#{Idv::InheritedProofing::Va::Service::BASE_URI}/inherited_proofing/user_attributes"
- end
- let(:request_headers) { { Authorization: "Bearer #{jwt_token}" } }
-end
diff --git a/spec/support/shared_contexts/inherited_proofing/va_user_context.rb b/spec/support/shared_contexts/inherited_proofing/va_user_context.rb
deleted file mode 100644
index 81ac0b82545..00000000000
--- a/spec/support/shared_contexts/inherited_proofing/va_user_context.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-RSpec.shared_context 'va_user_context' do
- # As given to us from VA
- let(:user_attributes) do
- { first_name: 'Fakey',
- last_name: 'Fakerson',
- address: { street: '123 Fake St',
- street2: 'Apt 235',
- city: 'Faketown',
- state: 'WA',
- country: nil,
- zip: '98037' },
- phone: '2063119187',
- birth_date: '2022-1-31',
- ssn: '123456789' }
- end
- # Encrypted with AppArtifacts.store.oidc_private_key for testing
- let(:encrypted_user_attributes) { File.read("#{__dir__}/encrypted_user_attributes.json") }
-end
diff --git a/spec/views/idv/inherited_proofing/agreement.html.erb_spec.rb b/spec/views/idv/inherited_proofing/agreement.html.erb_spec.rb
deleted file mode 100644
index d8f6ac9c379..00000000000
--- a/spec/views/idv/inherited_proofing/agreement.html.erb_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require 'rails_helper'
-
-describe 'idv/inherited_proofing/agreement.html.erb' do
- include Devise::Test::ControllerHelpers
-
- let(:flow_session) { {} }
- let(:sp_name) { 'test' }
-
- before do
- allow(view).to receive(:decorated_session).and_return(@decorated_session)
- allow(view).to receive(:flow_session).and_return(flow_session)
- allow(view).to receive(:url_for).and_return('https://www.example.com/')
- allow(view).to receive(:user_signing_up?).and_return(true)
- end
-
- it 'renders the Continue button' do
- render template: 'idv/inherited_proofing/agreement'
-
- expect(rendered).to have_button(t('inherited_proofing.buttons.continue'))
- end
-
- it 'renders the Cancel link' do
- render template: 'idv/inherited_proofing/agreement'
-
- expect(rendered).to have_link(t('links.cancel_account_creation'))
- end
-
- context 'with or without service provider' do
- it 'renders content' do
- render template: 'idv/inherited_proofing/agreement'
-
- expect(rendered).to have_content(t('inherited_proofing.info.lets_go'))
- expect(rendered).to have_content(
- t('inherited_proofing.headings.verify_identity'),
- )
- expect(rendered).to have_content(t('inherited_proofing.info.verify_identity'))
- expect(rendered).to have_content(
- t('inherited_proofing.headings.secure_account'),
- )
- expect(rendered).to have_content(
- t('inherited_proofing.info.secure_account', sp_name: sp_name),
- )
- end
- end
-end
diff --git a/spec/views/idv/inherited_proofing/get_started.html.erb_spec.rb b/spec/views/idv/inherited_proofing/get_started.html.erb_spec.rb
deleted file mode 100644
index 76d27eef061..00000000000
--- a/spec/views/idv/inherited_proofing/get_started.html.erb_spec.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-require 'rails_helper'
-
-describe 'idv/inherited_proofing/get_started.html.erb' do
- include Devise::Test::ControllerHelpers
-
- let(:flow_session) { {} }
- let(:sp_name) { 'test' }
-
- before do
- @decorated_session = instance_double(ServiceProviderSessionDecorator)
- allow(@decorated_session).to receive(:sp_name).and_return(sp_name)
- allow(view).to receive(:decorated_session).and_return(@decorated_session)
- allow(view).to receive(:flow_session).and_return(flow_session)
- allow(view).to receive(:url_for).and_return('https://www.example.com/')
- allow(view).to receive(:user_fully_authenticated?).and_return(true)
- allow(view).to receive(:user_signing_up?).and_return(true)
-
- @presenter = instance_double(Idv::InheritedProofing::InheritedProofingPresenter)
- allow(@presenter).to receive(:learn_more_phone_or_mail_url).and_return('https://www.va.gov/resources/managing-your-vagov-profile/')
- allow(@presenter).to receive(:get_help_url).and_return('https://www.va.gov/resources/managing-your-vagov-profile/')
- allow(view).to receive(:presenter).and_return(@presenter)
- end
-
- it 'renders the Continue button' do
- render template: 'idv/inherited_proofing/get_started'
-
- expect(rendered).to have_button(t('inherited_proofing.buttons.continue'))
- end
-
- it 'renders the Cancel link' do
- render template: 'idv/inherited_proofing/get_started'
-
- expect(rendered).to have_link(t('links.cancel_account_creation'))
- end
-
- context 'with or without service provider' do
- it 'renders troubleshooting options' do
- render template: 'idv/inherited_proofing/get_started'
-
- expect(rendered).to have_link(
- t('inherited_proofing.troubleshooting.options.learn_more_phone_or_mail'),
- )
- expect(rendered).not_to have_link(nil, href: idv_inherited_proofing_return_to_sp_path)
- expect(rendered).to have_link(
- t(
- 'inherited_proofing.troubleshooting.options.get_help',
- sp_name: sp_name,
- ),
- )
- expect(rendered).to have_link(
- t('inherited_proofing.troubleshooting.options.learn_more_phone_or_mail'),
- )
- end
- end
-end
diff --git a/spec/views/idv/inherited_proofing/retrieval.html.erb_spec.rb b/spec/views/idv/inherited_proofing/retrieval.html.erb_spec.rb
deleted file mode 100644
index 7db2ed40eb1..00000000000
--- a/spec/views/idv/inherited_proofing/retrieval.html.erb_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require 'rails_helper'
-
-describe 'idv/inherited_proofing/verify_wait.html.erb' do
- include Devise::Test::ControllerHelpers
-
- it 'renders' do
- render template: 'idv/inherited_proofing/verify_wait'
-
- # Appropriate header
- expect(rendered).to have_text(t('inherited_proofing.headings.retrieval'))
-
- # Spinner
- expect(rendered).to have_css("img[src*='shield-spinner']")
-
- # Appropriate text
- expect(rendered).to have_text(t('inherited_proofing.info.retrieval_time'))
- expect(rendered).to have_text(t('inherited_proofing.info.retrieval_thanks'))
- end
-end
diff --git a/spec/views/idv/otp_delivery_method/new.html.erb_spec.rb b/spec/views/idv/otp_delivery_method/new.html.erb_spec.rb
deleted file mode 100644
index 46d4585739d..00000000000
--- a/spec/views/idv/otp_delivery_method/new.html.erb_spec.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-require 'rails_helper'
-
-describe 'idv/otp_delivery_method/new.html.erb' do
- let(:gpo_letter_available) { false }
- let(:step_indicator_steps) { Idv::Flows::DocAuthFlow::STEP_INDICATOR_STEPS }
- let(:supports_sms) { true }
- let(:supports_voice) { true }
-
- before do
- phone_number_capabilities = instance_double(
- PhoneNumberCapabilities,
- supports_sms?: supports_sms,
- supports_voice?: supports_voice,
- )
-
- allow(view).to receive(:phone_number_capabilities).and_return(phone_number_capabilities)
- allow(view).to receive(:user_signing_up?).and_return(false)
- allow(view).to receive(:user_fully_authenticated?).and_return(true)
- allow(view).to receive(:gpo_letter_available).and_return(gpo_letter_available)
- allow(view).to receive(:step_indicator_steps).and_return(step_indicator_steps)
- end
-
- subject(:rendered) { render template: 'idv/otp_delivery_method/new' }
-
- context 'gpo letter available' do
- let(:gpo_letter_available) { true }
-
- it 'renders troubleshooting options' do
- expect(rendered).to have_link(t('idv.troubleshooting.options.change_phone_number'))
- expect(rendered).to have_link(t('idv.troubleshooting.options.verify_by_mail'))
- end
- end
-
- context 'gpo letter not available' do
- let(:gpo_letter_available) { false }
-
- it 'renders troubleshooting options' do
- expect(rendered).to have_link(t('idv.troubleshooting.options.change_phone_number'))
- expect(rendered).not_to have_link(t('idv.troubleshooting.options.verify_by_mail'))
- end
- end
-
- context 'phone vendor outage' do
- before do
- allow_any_instance_of(VendorStatus).to receive(:vendor_outage?).and_return(false)
- allow_any_instance_of(VendorStatus).to receive(:vendor_outage?).with(:sms).and_return(true)
- end
-
- it 'renders alert banner' do
- expect(rendered).to have_selector('.usa-alert.usa-alert--error')
- end
-
- it 'disables problematic vendor option' do
- expect(rendered).to have_field('otp_delivery_preference', with: :voice, disabled: false)
- expect(rendered).to have_field('otp_delivery_preference', with: :sms, disabled: true)
- end
- end
-
- it 'renders sms and voice options' do
- expect(rendered).to have_field('otp_delivery_preference', with: :voice)
- expect(rendered).to have_field('otp_delivery_preference', with: :sms)
- end
-
- context 'without sms support' do
- let(:supports_sms) { false }
-
- it 'renders voice option' do
- expect(rendered).to have_field('otp_delivery_preference', with: :voice)
- expect(rendered).not_to have_field('otp_delivery_preference', with: :sms)
- end
- end
-
- context 'without voice support' do
- let(:supports_voice) { false }
-
- it 'renders sms option' do
- expect(rendered).not_to have_field('otp_delivery_preference', with: :voice)
- expect(rendered).to have_field('otp_delivery_preference', with: :sms)
- end
- end
-end
diff --git a/yarn.lock b/yarn.lock
index fc21062e5bc..0d867c73df7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2232,15 +2232,15 @@ browser-stdout@1.3.1:
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
-browserslist@^4.14.5, browserslist@^4.19.1, browserslist@^4.21.3, browserslist@^4.21.4:
- version "4.21.4"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987"
- integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==
+browserslist@^4.14.5, browserslist@^4.19.1, browserslist@^4.21.3, browserslist@^4.21.5:
+ version "4.21.5"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7"
+ integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==
dependencies:
- caniuse-lite "^1.0.30001400"
- electron-to-chromium "^1.4.251"
- node-releases "^2.0.6"
- update-browserslist-db "^1.0.9"
+ caniuse-lite "^1.0.30001449"
+ electron-to-chromium "^1.4.284"
+ node-releases "^2.0.8"
+ update-browserslist-db "^1.0.10"
buffer-builder@^0.2.0:
version "0.2.0"
@@ -2302,10 +2302,10 @@ camelcase@^6.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
-caniuse-lite@^1.0.30001400:
- version "1.0.30001441"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz#987437b266260b640a23cd18fbddb509d7f69f3e"
- integrity sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==
+caniuse-lite@^1.0.30001449:
+ version "1.0.30001458"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz#871e35866b4654a7d25eccca86864f411825540c"
+ integrity sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w==
chai-as-promised@^7.1.1:
version "7.1.1"
@@ -2907,10 +2907,10 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
-electron-to-chromium@^1.4.251:
- version "1.4.284"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592"
- integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==
+electron-to-chromium@^1.4.284:
+ version "1.4.314"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.314.tgz#33e4ad7a2ca2ddbe2e113874cc0c0e2a00cb46bf"
+ integrity sha512-+3RmNVx9hZLlc0gW//4yep0K5SYKmIvB5DXg1Yg6varsuAHlHwTeqeygfS8DWwLCsNOWrgj+p9qgM5WYjw1lXQ==
element-closest@^2.0.1:
version "2.0.2"
@@ -4897,10 +4897,10 @@ node-modules-regexp@^1.0.0:
resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=
-node-releases@^2.0.6:
- version "2.0.8"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.8.tgz#0f349cdc8fcfa39a92ac0be9bc48b7706292b9ae"
- integrity sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==
+node-releases@^2.0.8:
+ version "2.0.10"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f"
+ integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==
normalize-package-data@^2.5.0:
version "2.5.0"
@@ -6567,7 +6567,7 @@ unpipe@1.0.0, unpipe@~1.0.0:
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
-update-browserslist-db@^1.0.9:
+update-browserslist-db@^1.0.10:
version "1.0.10"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3"
integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==