From a5a3e17ca9d0e0718c67d00748457be635ba966b Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Fri, 14 Jul 2023 11:39:50 -0700 Subject: [PATCH 01/27] New GettingStartedController copied from WelcomeController changelog: User-facing Improvements, Identity Verification, New Getting Started experience behind A/B test Co-authored-by: John Maxwell --- .../idv/getting_started_controller.rb | 63 ++++++++++ app/views/idv/getting_started/show.html.erb | 117 ++++++++++++++++++ config/routes.rb | 2 + .../idv/getting_started_controller_spec.rb | 114 +++++++++++++++++ 4 files changed, 296 insertions(+) create mode 100644 app/controllers/idv/getting_started_controller.rb create mode 100644 app/views/idv/getting_started/show.html.erb create mode 100644 spec/controllers/idv/getting_started_controller_spec.rb diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb new file mode 100644 index 00000000000..cd9695bd183 --- /dev/null +++ b/app/controllers/idv/getting_started_controller.rb @@ -0,0 +1,63 @@ +module Idv + class GettingStartedController < ApplicationController + include IdvStepConcern + include StepIndicatorConcern + include StepUtilitiesConcern + + before_action :confirm_welcome_needed + + def show + analytics.idv_doc_auth_welcome_visited(**analytics_arguments) + + Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( + 'welcome', :view, + true + ) + + render :show, locals: { flow_session: flow_session } + end + + def update + flow_session[:skip_upload_step] = true unless FeatureManagement.idv_allow_hybrid_flow? + + analytics.idv_doc_auth_welcome_submitted(**analytics_arguments) + + create_document_capture_session + cancel_previous_in_person_enrollments + + idv_session.welcome_visited = true + + redirect_to idv_agreement_url + end + + private + + def analytics_arguments + { + step: 'welcome', + analytics_id: 'Doc Auth', + irs_reproofing: irs_reproofing?, + } + end + + def create_document_capture_session + document_capture_session = DocumentCaptureSession.create( + user_id: current_user.id, + issuer: sp_session[:issuer], + ) + flow_session[:document_capture_session_uuid] = document_capture_session.uuid + end + + def cancel_previous_in_person_enrollments + return unless IdentityConfig.store.in_person_proofing_enabled + UspsInPersonProofing::EnrollmentHelper. + cancel_stale_establishing_enrollments_for_user(current_user) + end + + def confirm_welcome_needed + return unless idv_session.welcome_visited + + redirect_to idv_agreement_url + end + end +end diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb new file mode 100644 index 00000000000..6a852e68406 --- /dev/null +++ b/app/views/idv/getting_started/show.html.erb @@ -0,0 +1,117 @@ +<% title t('doc_auth.headings.welcome') %> + +<% content_for(:pre_flash_content) do %> + <%= render StepIndicatorComponent.new( + steps: Idv::StepIndicatorConcern::STEP_INDICATOR_STEPS, + current_step: :getting_started, + locale_scope: 'idv', + class: 'margin-x-neg-2 margin-top-neg-4 tablet:margin-x-neg-6 tablet:margin-top-neg-4', + ) %> +<% end %> + +<%= render 'shared/maintenance_window_alert' do %> + <%= render JavascriptRequiredComponent.new( + header: t('idv.welcome.no_js_header'), + intro: t('idv.welcome.no_js_intro', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')), + ) do %> + + <% if @current_user&.reproof_for_irs?(service_provider: @current_sp) %> + <%= render AlertComponent.new( + type: :info, + message: t('doc_auth.info.irs_reproofing_explanation'), + class: ['margin-bottom-2', 'usa-alert--info-important'], + ) + %> + <% end %> + + <%= render PageHeadingComponent.new.with_content(t('doc_auth.headings.welcome')) %> +

+ <%= t('doc_auth.info.welcome', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')) %> +

+ +

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

+ + <%= render ProcessListComponent.new(heading_level: :h3, class: 'margin-y-3') do |c| %> + <%= c.with_item(heading: t('doc_auth.instructions.bullet1')) do %> +

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

+ <% end %> + <%= c.with_item(heading: t('doc_auth.instructions.bullet2')) do %> +

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

+ <% end %> + <%= c.with_item(heading: t('doc_auth.instructions.bullet3')) do %> + + <%= new_tab_link_to( + t('idv.troubleshooting.options.learn_more_address_verification_options'), + help_center_redirect_path( + category: 'verify-your-identity', + article: 'phone-number', + flow: :idv, + step: :welcome, + location: 'you_will_need', + ), + ) %> + <% end %> + <% end %> + + <%= simple_form_for :doc_auth, + url: url_for, + method: 'put', + html: { autocomplete: 'off', class: 'margin-y-5 js-consent-continue-form' } do |f| %> + <%= f.submit t('doc_auth.buttons.continue') %> + <% end %> + + <%= render( + 'shared/troubleshooting_options', + heading_tag: :h3, + heading: t('idv.troubleshooting.headings.missing_required_items'), + options: [ + { + url: help_center_redirect_path( + category: 'verify-your-identity', + article: 'accepted-state-issued-identification', + flow: :idv, + step: :welcome, + location: 'missing_items', + ), + text: t('idv.troubleshooting.options.supported_documents'), + new_tab: true, + }, + { + url: help_center_redirect_path( + category: 'verify-your-identity', + article: 'phone-number', + flow: :idv, + step: :welcome, + location: 'missing_items', + ), + text: t('idv.troubleshooting.options.learn_more_address_verification_options'), + new_tab: true, + }, + decorated_session.sp_name && { + url: return_to_sp_failure_to_proof_url(step: 'welcome', location: 'missing_items'), + text: t('idv.troubleshooting.options.get_help_at_sp', sp_name: decorated_session.sp_name), + new_tab: true, + }, + ].select(&:present?), + ) %> + +

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

+

+ <%= t('doc_auth.info.privacy', app_name: APP_NAME) %> +

+

+ <%= new_tab_link_to( + t('doc_auth.instructions.learn_more'), + policy_redirect_url(flow: :idv, step: :welcome, location: :footer), + ) %> +

+ + <%= render 'shared/cancel', link: idv_cancel_path(step: 'welcome') %> + <% end %> +<% end %> + +<%= javascript_packs_tag_once('document-capture-welcome') %> diff --git a/config/routes.rb b/config/routes.rb index ce8c475685a..f18e0d159b7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -334,6 +334,8 @@ # This route is included in SMS messages sent to users who start the IdV hybrid flow. It # should be kept short, and should not include underscores ("_"). get '/documents' => 'hybrid_mobile/entry#show', as: :hybrid_mobile_entry + get '/getting_started' => 'getting_started#show' + put '/getting_started' => 'getting_started#update' get '/hybrid_mobile/document_capture' => 'hybrid_mobile/document_capture#show' put '/hybrid_mobile/document_capture' => 'hybrid_mobile/document_capture#update' get '/hybrid_mobile/capture_complete' => 'hybrid_mobile/capture_complete#show' diff --git a/spec/controllers/idv/getting_started_controller_spec.rb b/spec/controllers/idv/getting_started_controller_spec.rb new file mode 100644 index 00000000000..cd2088e9cb8 --- /dev/null +++ b/spec/controllers/idv/getting_started_controller_spec.rb @@ -0,0 +1,114 @@ +require 'rails_helper' + +RSpec.describe Idv::GettingStartedController do + include IdvHelper + + let(:user) { create(:user) } + + before do + stub_sign_in(user) + stub_analytics + subject.user_session['idv/doc_auth'] = {} + end + + describe 'before_actions' do + it 'includes authentication before_action' do + expect(subject).to have_actions( + :before, + :confirm_two_factor_authenticated, + ) + end + + it 'includes outage before_action' do + expect(subject).to have_actions( + :before, + :check_for_outage, + ) + end + end + + describe '#show' do + let(:analytics_name) { 'IdV: doc auth welcome visited' } + let(:analytics_args) do + { step: 'welcome', + analytics_id: 'Doc Auth', + irs_reproofing: false } + end + + 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_logged_event(analytics_name, analytics_args) + end + + it 'updates DocAuthLog welcome_view_count' do + doc_auth_log = DocAuthLog.create(user_id: user.id) + + expect { get :show }.to( + change { doc_auth_log.reload.welcome_view_count }.from(0).to(1), + ) + end + + context 'welcome already visited' do + it 'redirects to agreement' do + subject.idv_session.welcome_visited = true + + get :show + + expect(response).to redirect_to(idv_agreement_url) + end + end + + it 'redirects to please call page if fraud review is pending' do + profile = create(:profile, :fraud_review_pending) + + stub_sign_in(profile.user) + + get :show + + expect(response).to redirect_to(idv_please_call_url) + end + end + + describe '#update' do + let(:analytics_name) { 'IdV: doc auth welcome submitted' } + + let(:analytics_args) do + { step: 'welcome', + analytics_id: 'Doc Auth', + irs_reproofing: false } + end + + it 'sends analytics_submitted event' do + put :update + + expect(@analytics).to have_logged_event(analytics_name, analytics_args) + end + + it 'creates a document capture session' do + expect { put :update }. + to change { subject.user_session['idv/doc_auth'][:document_capture_session_uuid] }.from(nil) + end + + context 'with previous establishing in-person enrollments' do + let!(:enrollment) { create(:in_person_enrollment, :establishing, user: user, profile: nil) } + + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) + end + + it 'cancels all previous establishing enrollments' do + put :update + + expect(enrollment.reload.status).to eq('cancelled') + expect(user.establishing_in_person_enrollment).to be_blank + end + end + end +end From 1d36aad201cb9fb64e64f134af910d6231421c74 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Fri, 14 Jul 2023 12:16:43 -0700 Subject: [PATCH 02/27] Remove StepIndicator from GettingStartedController --- .../idv/getting_started_controller.rb | 1 - app/views/idv/getting_started/show.html.erb | 9 -- .../idv/doc_auth/getting_started_spec.rb | 99 +++++++++++++++++++ 3 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 spec/features/idv/doc_auth/getting_started_spec.rb diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb index cd9695bd183..25bf825b480 100644 --- a/app/controllers/idv/getting_started_controller.rb +++ b/app/controllers/idv/getting_started_controller.rb @@ -1,7 +1,6 @@ module Idv class GettingStartedController < ApplicationController include IdvStepConcern - include StepIndicatorConcern include StepUtilitiesConcern before_action :confirm_welcome_needed diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb index 6a852e68406..a84ae7ca361 100644 --- a/app/views/idv/getting_started/show.html.erb +++ b/app/views/idv/getting_started/show.html.erb @@ -1,14 +1,5 @@ <% title t('doc_auth.headings.welcome') %> -<% content_for(:pre_flash_content) do %> - <%= render StepIndicatorComponent.new( - steps: Idv::StepIndicatorConcern::STEP_INDICATOR_STEPS, - current_step: :getting_started, - locale_scope: 'idv', - class: 'margin-x-neg-2 margin-top-neg-4 tablet:margin-x-neg-6 tablet:margin-top-neg-4', - ) %> -<% end %> - <%= render 'shared/maintenance_window_alert' do %> <%= render JavascriptRequiredComponent.new( header: t('idv.welcome.no_js_header'), diff --git a/spec/features/idv/doc_auth/getting_started_spec.rb b/spec/features/idv/doc_auth/getting_started_spec.rb new file mode 100644 index 00000000000..d495b95ef9f --- /dev/null +++ b/spec/features/idv/doc_auth/getting_started_spec.rb @@ -0,0 +1,99 @@ +require 'rails_helper' + +RSpec.feature 'getting started step' do + include IdvHelper + include DocAuthHelper + + let(:fake_analytics) { FakeAnalytics.new } + let(:maintenance_window) { [] } + let(:sp_name) { 'Test SP' } + + before do + 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) + start, finish = maintenance_window + allow(IdentityConfig.store).to receive(:acuant_maintenance_window_start).and_return(start) + allow(IdentityConfig.store).to receive(:acuant_maintenance_window_finish).and_return(finish) + + visit_idp_from_sp_with_ial2(:oidc) + sign_in_and_2fa_user + complete_doc_auth_steps_before_welcome_step + end + + it 'logs return to sp link click' do + click_on t('idv.troubleshooting.options.get_help_at_sp', sp_name: sp_name) + + expect(fake_analytics).to have_logged_event( + 'Return to SP: Failed to proof', + flow: nil, + location: 'missing_items', + redirect_url: instance_of(String), + step: 'welcome', + ) + end + + it 'logs supported documents troubleshooting link click' do + click_on t('idv.troubleshooting.options.supported_documents') + + expect(fake_analytics).to have_logged_event( + 'External Redirect', + step: 'welcome', + location: 'missing_items', + flow: 'idv', + redirect_url: MarketingSite.help_center_article_url( + category: 'verify-your-identity', + article: 'accepted-state-issued-identification', + ), + ) + end + + it 'logs missing items troubleshooting link click' do + within '.troubleshooting-options' do + click_on t('idv.troubleshooting.options.learn_more_address_verification_options') + end + + expect(fake_analytics).to have_logged_event( + 'External Redirect', + step: 'welcome', + location: 'missing_items', + flow: 'idv', + redirect_url: MarketingSite.help_center_article_url( + category: 'verify-your-identity', + article: 'phone-number', + ), + ) + end + + it 'logs "you will need" learn more link click' do + within '.usa-process-list' do + click_on t('idv.troubleshooting.options.learn_more_address_verification_options') + end + + expect(fake_analytics).to have_logged_event( + 'External Redirect', + step: 'welcome', + location: 'you_will_need', + flow: 'idv', + redirect_url: MarketingSite.help_center_article_url( + category: 'verify-your-identity', + article: 'phone-number', + ), + ) + end + + context 'during the acuant maintenance window' do + let(:maintenance_window) do + [Time.zone.parse('2020-01-01T00:00:00Z'), Time.zone.parse('2020-01-01T23:59:59Z')] + end + let(:now) { Time.zone.parse('2020-01-01T12:00:00Z') } + + around do |ex| + travel_to(now) { ex.run } + end + + it 'renders the warning banner but no other content' do + expect(page).to have_content('We are currently under maintenance') + expect(page).to_not have_content(t('doc_auth.headings.welcome')) + end + end +end From d06a4f109a37e0f05e19c2c1e5bf5c8e2ffaa469 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Fri, 14 Jul 2023 12:26:42 -0700 Subject: [PATCH 03/27] Add GettingStartedAbTestConcern and before action in WelcomeController --- .../idv/getting_started_ab_test_concern.rb | 6 ++++++ app/controllers/idv/welcome_controller.rb | 2 ++ .../getting_started_ab_test_concern_spec.rb | 20 +++++++++++++++++++ .../idv/welcome_controller_spec.rb | 7 +++++++ 4 files changed, 35 insertions(+) create mode 100644 app/controllers/concerns/idv/getting_started_ab_test_concern.rb create mode 100644 spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb diff --git a/app/controllers/concerns/idv/getting_started_ab_test_concern.rb b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb new file mode 100644 index 00000000000..ef1cdf196c3 --- /dev/null +++ b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb @@ -0,0 +1,6 @@ +module Idv + module GettingStartedAbTestConcern + def maybe_redirect_for_getting_started_ab_test + end + end +end diff --git a/app/controllers/idv/welcome_controller.rb b/app/controllers/idv/welcome_controller.rb index d4913074e27..4019aac00ef 100644 --- a/app/controllers/idv/welcome_controller.rb +++ b/app/controllers/idv/welcome_controller.rb @@ -3,8 +3,10 @@ class WelcomeController < ApplicationController include IdvStepConcern include StepIndicatorConcern include StepUtilitiesConcern + include GettingStartedAbTestConcern before_action :confirm_welcome_needed + before_action :maybe_redirect_for_getting_started_ab_test def show analytics.idv_doc_auth_welcome_visited(**analytics_arguments) diff --git a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb new file mode 100644 index 00000000000..e89a03b99ee --- /dev/null +++ b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +RSpec.describe 'GettingStartedAbTestConcern' do + let(:user) { create(:user, :fully_registered, email: 'old_email@example.com') } + let(:idv_session) do + Idv::Session.new(user_session: subject.user_session, current_user: user, service_provider: nil) + end + + module Idv + class StepController < ApplicationController + include IdvStepConcern + + def show + render plain: 'Hello' + end + end + end + + context "#maybe_redirect_for_getting_started_ab_test" +end diff --git a/spec/controllers/idv/welcome_controller_spec.rb b/spec/controllers/idv/welcome_controller_spec.rb index f8da3e66d5f..ca531e9414b 100644 --- a/spec/controllers/idv/welcome_controller_spec.rb +++ b/spec/controllers/idv/welcome_controller_spec.rb @@ -25,6 +25,13 @@ :check_for_outage, ) end + + it 'includes getting started ab test before_action' do + expect(subject).to have_actions( + :before, + :maybe_redirect_for_getting_started_ab_test, + ) + end end describe '#show' do From 8b0d1dce8ab72840e337bd6708d30ee5cd508969 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Fri, 14 Jul 2023 12:42:02 -0700 Subject: [PATCH 04/27] Specs for ABTest behavior --- .../getting_started_ab_test_concern_spec.rb | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb index e89a03b99ee..82b070fbdd5 100644 --- a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb +++ b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb @@ -8,7 +8,7 @@ module Idv class StepController < ApplicationController - include IdvStepConcern + include GettingStartedAbTestConcern def show render plain: 'Hello' @@ -16,5 +16,31 @@ def show end end - context "#maybe_redirect_for_getting_started_ab_test" + context '#maybe_redirect_for_getting_started_ab_test' do + controller Idv::StepController do + before_action :maybe_redirect_for_getting_started_ab_test + end + + before do + sign_in(user) + routes.draw do + get 'show' => 'idv/step#show' + end + end + + it 'does not redirect users getting existing experience' do + # user goes in bucket A + get :show + + expect(response.body).to eq('Hello') + expect(response.status).to eq(200) + end + + it 'redirects to idv_getting_started_url for users getting the new experience' do + # user goes in bucket B + get :show + + expect(response).to redirect_to(idv_getting_started_url) + end + end end From 8e72759d79b63929e7e0ad0447ec57c4d5d4ba36 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Fri, 14 Jul 2023 12:58:56 -0700 Subject: [PATCH 05/27] Add config flag and ABTestBucket. Co-authored-by: Jessica Dembe --- .../idv/getting_started_ab_test_concern.rb | 7 ++ config/application.yml.default | 1 + config/initializers/ab_tests.rb | 5 ++ lib/identity_config.rb | 1 + .../getting_started_ab_test_concern_spec.rb | 68 ++++++++++++++++--- 5 files changed, 73 insertions(+), 9 deletions(-) diff --git a/app/controllers/concerns/idv/getting_started_ab_test_concern.rb b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb index ef1cdf196c3..86d98230258 100644 --- a/app/controllers/concerns/idv/getting_started_ab_test_concern.rb +++ b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb @@ -1,6 +1,13 @@ module Idv module GettingStartedAbTestConcern + def getting_started_a_b_test_bucket + AbTests::IDV_GETTING_STARTED.bucket(sp_session[:request_id] || session.id) + end + def maybe_redirect_for_getting_started_ab_test + return if getting_started_a_b_test_bucket == 'default' + + redirect_to idv_getting_started_url end end end diff --git a/config/application.yml.default b/config/application.yml.default index 6be71c0d196..22d254cdfcd 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -130,6 +130,7 @@ idv_acuant_sdk_version_default: '11.8.2' idv_acuant_sdk_version_alternate: '11.8.1' idv_acuant_sdk_upgrade_a_b_testing_enabled: false idv_acuant_sdk_upgrade_a_b_testing_percent: 50 +idv_getting_started_a_b_testing: '{"default":100,"new":0}' idv_send_link_attempt_window_in_minutes: 10 idv_send_link_max_attempts: 5 idv_tmx_test_csp_disabled_emails: '[]' diff --git a/config/initializers/ab_tests.rb b/config/initializers/ab_tests.rb index 4df55b07756..2d37e294cc4 100644 --- a/config/initializers/ab_tests.rb +++ b/config/initializers/ab_tests.rb @@ -18,4 +18,9 @@ module AbTests 0, }, ) + + IDV_GETTING_STARTED = AbTestBucket.new( + experiment_name: 'Idv: Getting Started Experience', + buckets: IdentityConfig.store.idv_getting_started_a_b_testing, + ) end diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 4f7ee430a3c..85f4a343524 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -221,6 +221,7 @@ def self.build_store(config_map) config.add(:idv_acuant_sdk_version_alternate, type: :string) config.add(:idv_acuant_sdk_upgrade_a_b_testing_enabled, type: :boolean) config.add(:idv_acuant_sdk_upgrade_a_b_testing_percent, type: :integer) + config.add(:idv_getting_started_a_b_testing, type: :json, options: { symbolize_names: true }) config.add(:idv_send_link_attempt_window_in_minutes, type: :integer) config.add(:idv_send_link_max_attempts, type: :integer) config.add(:idv_sp_required, type: :boolean) diff --git a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb index 82b070fbdd5..5ace2ed2c69 100644 --- a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb +++ b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb @@ -16,6 +16,38 @@ def show end end + describe '#getting_started_a_b_test_bucket' do + let(:sp_session) { {} } + + controller Idv::StepController do + end + + before do + allow(session).to receive(:id).and_return('session-id') + allow(controller).to receive(:sp_session).and_return(sp_session) + allow(AbTests::IDV_GETTING_STARTED).to receive(:bucket) do |discriminator| + case discriminator + when 'session-id' + :default + when 'request-id' + :new + end + end + end + + it 'returns the bucket based on session id' do + expect(controller.getting_started_a_b_test_bucket).to eq(:default) + end + + context 'with associated sp session request id' do + let(:sp_session) { { request_id: 'request-id' } } + + it 'returns the bucket based on request id' do + expect(controller.getting_started_a_b_test_bucket).to eq(:new) + end + end + end + context '#maybe_redirect_for_getting_started_ab_test' do controller Idv::StepController do before_action :maybe_redirect_for_getting_started_ab_test @@ -28,19 +60,37 @@ def show end end - it 'does not redirect users getting existing experience' do - # user goes in bucket A - get :show + let(:session_uuid) { SecureRandom.uuid } + + context 'A/B test specifies getting started page' do + before do + stub_const( + 'AbTests::IDV_GETTING_STARTED', + FakeAbTestBucket.new.tap { |ab| ab.assign(session_uuid => :new) }, + ) + end - expect(response.body).to eq('Hello') - expect(response.status).to eq(200) + it 'redirects to idv_getting_started_url' do + get :show + + expect(response).to redirect_to(idv_getting_started_url) + end end - it 'redirects to idv_getting_started_url for users getting the new experience' do - # user goes in bucket B - get :show + context 'A/B test specifies welcome page' do + before do + stub_const( + 'AbTests::IDV_GETTING_STARTED', + FakeAbTestBucket.new.tap { |ab| ab.assign(session_uuid => :default) }, + ) + end - expect(response).to redirect_to(idv_getting_started_url) + it 'does not redirect users away from welcome page' do + get :show + + expect(response.body).to eq('Hello') + expect(response.status).to eq(200) + end end end end From 21020aa2341d1acfde4b7dcb04413b09f3899b72 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Fri, 14 Jul 2023 15:23:17 -0700 Subject: [PATCH 06/27] Update getting_started_controller_spec and analytics --- .../idv/getting_started_controller.rb | 14 +++++++------- app/services/analytics_events.rb | 8 ++++++++ .../idv/getting_started_controller_spec.rb | 16 ++++++++-------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb index 25bf825b480..27ec9f4875b 100644 --- a/app/controllers/idv/getting_started_controller.rb +++ b/app/controllers/idv/getting_started_controller.rb @@ -3,10 +3,10 @@ class GettingStartedController < ApplicationController include IdvStepConcern include StepUtilitiesConcern - before_action :confirm_welcome_needed + before_action :confirm_agreement_needed def show - analytics.idv_doc_auth_welcome_visited(**analytics_arguments) + analytics.idv_doc_auth_getting_started_visited(**analytics_arguments) Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( 'welcome', :view, @@ -19,7 +19,7 @@ def show def update flow_session[:skip_upload_step] = true unless FeatureManagement.idv_allow_hybrid_flow? - analytics.idv_doc_auth_welcome_submitted(**analytics_arguments) + analytics.idv_doc_auth_getting_started_submitted(**analytics_arguments) create_document_capture_session cancel_previous_in_person_enrollments @@ -33,7 +33,7 @@ def update def analytics_arguments { - step: 'welcome', + step: 'getting_started', analytics_id: 'Doc Auth', irs_reproofing: irs_reproofing?, } @@ -53,10 +53,10 @@ def cancel_previous_in_person_enrollments cancel_stale_establishing_enrollments_for_user(current_user) end - def confirm_welcome_needed - return unless idv_session.welcome_visited + def confirm_agreement_needed + return unless idv_session.idv_consent_given - redirect_to idv_agreement_url + redirect_to idv_hybrid_handoff_url end end end diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 9c833412003..dd0d6519121 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -682,6 +682,14 @@ def idv_doc_auth_exception_visited(step_name:, remaining_attempts:, **extra) ) end + def idv_doc_auth_getting_started_submitted(**extra) + track_event('IdV: doc auth getting_started submitted', **extra) + end + + def idv_doc_auth_getting_started_visited(**extra) + track_event('IdV: doc auth getting_started visited', **extra) + end + # @identity.idp.previous_event_name IdV: doc auth send_link submitted def idv_doc_auth_link_sent_submitted(**extra) track_event('IdV: doc auth link_sent submitted', **extra) diff --git a/spec/controllers/idv/getting_started_controller_spec.rb b/spec/controllers/idv/getting_started_controller_spec.rb index cd2088e9cb8..ddc16ef061e 100644 --- a/spec/controllers/idv/getting_started_controller_spec.rb +++ b/spec/controllers/idv/getting_started_controller_spec.rb @@ -28,9 +28,9 @@ end describe '#show' do - let(:analytics_name) { 'IdV: doc auth welcome visited' } + let(:analytics_name) { 'IdV: doc auth getting_started visited' } let(:analytics_args) do - { step: 'welcome', + { step: 'getting_started', analytics_id: 'Doc Auth', irs_reproofing: false } end @@ -55,13 +55,13 @@ ) end - context 'welcome already visited' do - it 'redirects to agreement' do - subject.idv_session.welcome_visited = true + context 'getting_started already visited' do + it 'redirects to hybrid_handoff' do + subject.idv_session.idv_consent_given = true get :show - expect(response).to redirect_to(idv_agreement_url) + expect(response).to redirect_to(idv_hybrid_handoff_url) end end @@ -77,10 +77,10 @@ end describe '#update' do - let(:analytics_name) { 'IdV: doc auth welcome submitted' } + let(:analytics_name) { 'IdV: doc auth getting_started submitted' } let(:analytics_args) do - { step: 'welcome', + { step: 'getting_started', analytics_id: 'Doc Auth', irs_reproofing: false } end From ca77d16ea8372bf60f42b36abf78b911afb2d638 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Fri, 14 Jul 2023 15:52:25 -0700 Subject: [PATCH 07/27] Add agreement checkbox and specs --- .../idv/getting_started_controller.rb | 28 +++++++++++++++---- app/views/idv/getting_started/show.html.erb | 19 +++++++++---- .../idv/getting_started_controller_spec.rb | 12 ++++---- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb index 27ec9f4875b..e7bf3c6897c 100644 --- a/app/controllers/idv/getting_started_controller.rb +++ b/app/controllers/idv/getting_started_controller.rb @@ -18,15 +18,24 @@ def show def update flow_session[:skip_upload_step] = true unless FeatureManagement.idv_allow_hybrid_flow? + skip_to_capture if params[:skip_upload] - analytics.idv_doc_auth_getting_started_submitted(**analytics_arguments) + result = Idv::ConsentForm.new.submit(consent_form_params) - create_document_capture_session - cancel_previous_in_person_enrollments + analytics.idv_doc_auth_getting_started_submitted( + **analytics_arguments.merge(result.to_h), + ) + + if result.success? + idv_session.idv_consent_given = true - idv_session.welcome_visited = true + create_document_capture_session + cancel_previous_in_person_enrollments - redirect_to idv_agreement_url + redirect_to idv_hybrid_handoff_url + else + redirect_to idv_getting_started_url + end end private @@ -53,6 +62,15 @@ def cancel_previous_in_person_enrollments cancel_stale_establishing_enrollments_for_user(current_user) end + def skip_to_capture + flow_session[:skip_upload_step] = true + idv_session.flow_path = 'standard' + end + + def consent_form_params + params.require(:doc_auth).permit(:ial2_consent_given) + end + def confirm_agreement_needed return unless idv_session.idv_consent_given diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb index a84ae7ca361..c1beee0b31c 100644 --- a/app/views/idv/getting_started/show.html.erb +++ b/app/views/idv/getting_started/show.html.erb @@ -48,11 +48,20 @@ <% end %> <% end %> - <%= simple_form_for :doc_auth, - url: url_for, - method: 'put', - html: { autocomplete: 'off', class: 'margin-y-5 js-consent-continue-form' } do |f| %> - <%= f.submit t('doc_auth.buttons.continue') %> + <%= simple_form_for( + :doc_auth, + url: url_for, + method: 'put', + html: { autocomplete: 'off', class: 'margin-top-2 margin-bottom-5 js-consent-continue-form' }, + ) do |f| %> + <%= render ClickObserverComponent.new(event_name: 'IdV: consent checkbox toggled') do %> + <%= render ValidatedFieldComponent.new( + form: f, + name: :ial2_consent_given, + as: :boolean, + label: t('doc_auth.instructions.consent', app_name: APP_NAME), + required: true, + ) %> <% end %> <%= render( diff --git a/spec/controllers/idv/getting_started_controller_spec.rb b/spec/controllers/idv/getting_started_controller_spec.rb index ddc16ef061e..2f6ea79fc7c 100644 --- a/spec/controllers/idv/getting_started_controller_spec.rb +++ b/spec/controllers/idv/getting_started_controller_spec.rb @@ -80,19 +80,21 @@ let(:analytics_name) { 'IdV: doc auth getting_started submitted' } let(:analytics_args) do - { step: 'getting_started', + { success: true, + errors: {}, + step: 'getting_started', analytics_id: 'Doc Auth', irs_reproofing: false } end - it 'sends analytics_submitted event' do - put :update + it 'sends analytics_submitted event with consent given' do + put :update, params: { doc_auth: { ial2_consent_given: 1 } } expect(@analytics).to have_logged_event(analytics_name, analytics_args) end it 'creates a document capture session' do - expect { put :update }. + expect { put :update, params: { doc_auth: { ial2_consent_given: 1 } } }. to change { subject.user_session['idv/doc_auth'][:document_capture_session_uuid] }.from(nil) end @@ -104,7 +106,7 @@ end it 'cancels all previous establishing enrollments' do - put :update + put :update, params: { doc_auth: { ial2_consent_given: 1 } } expect(enrollment.reload.status).to eq('cancelled') expect(user.establishing_in_person_enrollment).to be_blank From 35e5a838ad85753efbb682b091cf3f350ce6aa23 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Mon, 17 Jul 2023 08:33:30 -0700 Subject: [PATCH 08/27] Change the setup in getting_started_ab_test_concern_spec --- .../concerns/idv/getting_started_ab_test_concern.rb | 2 +- .../idv/getting_started_ab_test_concern_spec.rb | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/controllers/concerns/idv/getting_started_ab_test_concern.rb b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb index 86d98230258..2681d0011f0 100644 --- a/app/controllers/concerns/idv/getting_started_ab_test_concern.rb +++ b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb @@ -5,7 +5,7 @@ def getting_started_a_b_test_bucket end def maybe_redirect_for_getting_started_ab_test - return if getting_started_a_b_test_bucket == 'default' + return if getting_started_a_b_test_bucket == :default redirect_to idv_getting_started_url end diff --git a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb index 5ace2ed2c69..e8654eab979 100644 --- a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb +++ b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb @@ -64,10 +64,8 @@ def show context 'A/B test specifies getting started page' do before do - stub_const( - 'AbTests::IDV_GETTING_STARTED', - FakeAbTestBucket.new.tap { |ab| ab.assign(session_uuid => :new) }, - ) + allow(controller).to receive(:getting_started_a_b_test_bucket). + and_return(:new) end it 'redirects to idv_getting_started_url' do @@ -79,10 +77,8 @@ def show context 'A/B test specifies welcome page' do before do - stub_const( - 'AbTests::IDV_GETTING_STARTED', - FakeAbTestBucket.new.tap { |ab| ab.assign(session_uuid => :default) }, - ) + allow(controller).to receive(:getting_started_a_b_test_bucket). + and_return(:default) end it 'does not redirect users away from welcome page' do From 9ef73083f0026e3eb86cf9fe252c17114a8c0d20 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Mon, 17 Jul 2023 09:06:12 -0700 Subject: [PATCH 09/27] Remove unneeded components from Getting Started template and add feature spec --- app/views/idv/getting_started/show.html.erb | 55 ++++------------ .../idv/doc_auth/getting_started_spec.rb | 62 +------------------ 2 files changed, 16 insertions(+), 101 deletions(-) diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb index c1beee0b31c..1baa8d8da0a 100644 --- a/app/views/idv/getting_started/show.html.erb +++ b/app/views/idv/getting_started/show.html.erb @@ -63,52 +63,23 @@ required: true, ) %> <% end %> - - <%= render( - 'shared/troubleshooting_options', - heading_tag: :h3, - heading: t('idv.troubleshooting.headings.missing_required_items'), - options: [ - { - url: help_center_redirect_path( - category: 'verify-your-identity', - article: 'accepted-state-issued-identification', - flow: :idv, - step: :welcome, - location: 'missing_items', - ), - text: t('idv.troubleshooting.options.supported_documents'), - new_tab: true, - }, - { - url: help_center_redirect_path( - category: 'verify-your-identity', - article: 'phone-number', - flow: :idv, - step: :welcome, - location: 'missing_items', - ), - text: t('idv.troubleshooting.options.learn_more_address_verification_options'), - new_tab: true, - }, - decorated_session.sp_name && { - url: return_to_sp_failure_to_proof_url(step: 'welcome', location: 'missing_items'), - text: t('idv.troubleshooting.options.get_help_at_sp', sp_name: decorated_session.sp_name), - new_tab: true, - }, - ].select(&:present?), - ) %> - -

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

-

- <%= t('doc_auth.info.privacy', app_name: APP_NAME) %> -

-

+

<%= new_tab_link_to( t('doc_auth.instructions.learn_more'), - policy_redirect_url(flow: :idv, step: :welcome, location: :footer), + policy_redirect_url(flow: :idv, step: :agreement, location: :consent), ) %>

+
+ <%= render( + SpinnerButtonComponent.new( + type: :submit, + big: true, + wide: true, + spin_on_click: false, + ).with_content(t('doc_auth.buttons.continue')), + ) %> +
+ <% end %> <%= render 'shared/cancel', link: idv_cancel_path(step: 'welcome') %> <% end %> diff --git a/spec/features/idv/doc_auth/getting_started_spec.rb b/spec/features/idv/doc_auth/getting_started_spec.rb index d495b95ef9f..c0ac081c97d 100644 --- a/spec/features/idv/doc_auth/getting_started_spec.rb +++ b/spec/features/idv/doc_auth/getting_started_spec.rb @@ -18,67 +18,11 @@ visit_idp_from_sp_with_ial2(:oidc) sign_in_and_2fa_user complete_doc_auth_steps_before_welcome_step + visit(idv_getting_started_url) end - it 'logs return to sp link click' do - click_on t('idv.troubleshooting.options.get_help_at_sp', sp_name: sp_name) - - expect(fake_analytics).to have_logged_event( - 'Return to SP: Failed to proof', - flow: nil, - location: 'missing_items', - redirect_url: instance_of(String), - step: 'welcome', - ) - end - - it 'logs supported documents troubleshooting link click' do - click_on t('idv.troubleshooting.options.supported_documents') - - expect(fake_analytics).to have_logged_event( - 'External Redirect', - step: 'welcome', - location: 'missing_items', - flow: 'idv', - redirect_url: MarketingSite.help_center_article_url( - category: 'verify-your-identity', - article: 'accepted-state-issued-identification', - ), - ) - end - - it 'logs missing items troubleshooting link click' do - within '.troubleshooting-options' do - click_on t('idv.troubleshooting.options.learn_more_address_verification_options') - end - - expect(fake_analytics).to have_logged_event( - 'External Redirect', - step: 'welcome', - location: 'missing_items', - flow: 'idv', - redirect_url: MarketingSite.help_center_article_url( - category: 'verify-your-identity', - article: 'phone-number', - ), - ) - end - - it 'logs "you will need" learn more link click' do - within '.usa-process-list' do - click_on t('idv.troubleshooting.options.learn_more_address_verification_options') - end - - expect(fake_analytics).to have_logged_event( - 'External Redirect', - step: 'welcome', - location: 'you_will_need', - flow: 'idv', - redirect_url: MarketingSite.help_center_article_url( - category: 'verify-your-identity', - article: 'phone-number', - ), - ) + it 'displays expected content', :js do + expect(page).to have_current_path(idv_getting_started_path) end context 'during the acuant maintenance window' do From ed8f9f9783e6bd28c5fbb41b874ef3e746613425 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Mon, 17 Jul 2023 09:19:17 -0700 Subject: [PATCH 10/27] Add new translation keys --- app/views/idv/getting_started/show.html.erb | 30 ++++++++++----------- config/locales/doc_auth/en.yml | 26 ++++++++++++++++++ config/locales/doc_auth/es.yml | 27 +++++++++++++++++++ config/locales/doc_auth/fr.yml | 29 ++++++++++++++++++++ config/locales/idv/en.yml | 4 +++ config/locales/idv/es.yml | 4 +++ config/locales/idv/fr.yml | 4 +++ 7 files changed, 109 insertions(+), 15 deletions(-) diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb index 1baa8d8da0a..c17afb4ee37 100644 --- a/app/views/idv/getting_started/show.html.erb +++ b/app/views/idv/getting_started/show.html.erb @@ -1,9 +1,9 @@ -<% title t('doc_auth.headings.welcome') %> +<% title t('doc_auth.headings.getting_started') %> <%= render 'shared/maintenance_window_alert' do %> <%= render JavascriptRequiredComponent.new( - header: t('idv.welcome.no_js_header'), - intro: t('idv.welcome.no_js_intro', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')), + header: t('idv.getting_started.no_js_header'), + intro: t('idv.getting_started.no_js_intro', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')), ) do %> <% if @current_user&.reproof_for_irs?(service_provider: @current_sp) %> @@ -15,23 +15,23 @@ %> <% end %> - <%= render PageHeadingComponent.new.with_content(t('doc_auth.headings.welcome')) %> + <%= render PageHeadingComponent.new.with_content(t('doc_auth.headings.getting_started')) %>

- <%= t('doc_auth.info.welcome', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')) %> + <%= t('doc_auth.info.getting_started', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')) %>

-

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

+

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

<%= render ProcessListComponent.new(heading_level: :h3, class: 'margin-y-3') do |c| %> - <%= c.with_item(heading: t('doc_auth.instructions.bullet1')) do %> -

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

+ <%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet1')) do %> +

<%= t('doc_auth.getting_started.instructions.text1') %>

<% end %> - <%= c.with_item(heading: t('doc_auth.instructions.bullet2')) do %> -

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

+ <%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet2')) do %> +

<%= t('doc_auth.getting_started.instructions.text2') %>

<% end %> - <%= c.with_item(heading: t('doc_auth.instructions.bullet3')) do %> + <%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet3')) do %>
    - <% t('doc_auth.instructions.text3_html').each do |bullet_item| %> + <% t('doc_auth.getting_started.instructions.text3_html').each do |bullet_item| %>
  • <%= bullet_item %>
  • <% end %>
@@ -59,13 +59,13 @@ form: f, name: :ial2_consent_given, as: :boolean, - label: t('doc_auth.instructions.consent', app_name: APP_NAME), + label: t('doc_auth.getting_started.instructions.consent', app_name: APP_NAME), required: true, ) %> <% end %>

<%= new_tab_link_to( - t('doc_auth.instructions.learn_more'), + t('doc_auth.getting_started.instructions.learn_more'), policy_redirect_url(flow: :idv, step: :agreement, location: :consent), ) %>

@@ -81,7 +81,7 @@ <% end %> - <%= render 'shared/cancel', link: idv_cancel_path(step: 'welcome') %> + <%= render 'shared/cancel', link: idv_cancel_path(step: 'getting_started') %> <% end %> <% end %> diff --git a/config/locales/doc_auth/en.yml b/config/locales/doc_auth/en.yml index c91745ff7db..382426d8284 100644 --- a/config/locales/doc_auth/en.yml +++ b/config/locales/doc_auth/en.yml @@ -112,6 +112,7 @@ en: document_capture_back: Back of your ID document_capture_front: Front of your ID front: Front + getting_started: Get started verifying your identity hybrid_handoff: How would you like to add your ID? interstitial: We are processing your images lets_go: How verifying your identity works @@ -134,6 +135,28 @@ en: only_add_phone_verify: You asked %{app_name} to verify your ID using your phone only_add_sp_services_html: You are trying to access %{service_provider_name} services + getting_started: + instructions: + bullet1: State‑issued ID + bullet2: Social Security number + bullet3: Phone number OR home address + consent: By checking this box, you are letting %{app_name} ask for, use, keep, + and share your personal information. We will use it to verify your + identity. + getting_started: 'You will need your:' + learn_more: Learn more about our privacy and security measures + privacy: Our privacy and security standards + switch_back: Switch back to your computer to finish verifying your identity. + switch_back_image: Arrow pointing from phone to computer + test_ssn: In the test environment only SSNs that begin with “900-” or “666-” are + considered valid. Do not enter real PII in this field. + text1: Your ID cannot be expired. + text2: You will not need the card with you. + text3_html: + - 'Verify by phone: We’ll call or text your phone + number. This takes a few minutes.' + - 'Verify by mail: We’ll mail a letter to your home + address. This takes about 3 to 7 business days.' info: address_guidance_puerto_rico_html: Puerto Rico residents:

Edit your address to list your urbanization or condominium on address line 2. @@ -145,6 +168,8 @@ en: document_capture_intro_acknowledgment: We’ll collect information about you by reading your state‑issued ID. We use this information to verify your identity. + getting_started: '%{sp_name} needs to make sure you are you — not someone + pretending to be you.' hybrid_handoff: We’ll collect information about you by reading your state‑issued ID. image_loaded: Image loaded image_loading: Image loading @@ -186,6 +211,7 @@ en: consent: By checking this box, you are letting %{app_name} ask for, use, keep, and share your personal information. We will use it to verify your identity. + getting_started: 'You will need your:' learn_more: Learn more about our privacy and security measures privacy: Our privacy and security standards switch_back: Switch back to your computer to finish verifying your identity. diff --git a/config/locales/doc_auth/es.yml b/config/locales/doc_auth/es.yml index c741fd81ca6..5a60ba657e7 100644 --- a/config/locales/doc_auth/es.yml +++ b/config/locales/doc_auth/es.yml @@ -136,6 +136,7 @@ es: document_capture_back: Parte trasera de su documento de identidad document_capture_front: Parte delantera de su documento de identidad front: Parte Delantera + getting_started: Comience a verificar su identidad hybrid_handoff: '¿Cómo desea añadir su documento de identidad?' interstitial: Estamos procesando sus imágenes lets_go: Cómo funciona la verificación de su identidad @@ -160,6 +161,29 @@ es: a través de su teléfono only_add_sp_services_html: Está tratando de acceder a los servicios %{service_provider_name} + getting_started: + instructions: + bullet1: Documento de identidad emitido por el estado. + bullet2: Número de seguro social + bullet3: Número de teléfono O domicilio + consent: Al marcar esta casilla, usted permite que %{app_name} solicite, + utilice, conserve y comparta su información personal. Los utilizamos + para verificar su identidad. + getting_started: 'Necesitará su:' + learn_more: Obtenga más información sobre nuestras medidas de privacidad y seguridad + privacy: Nuestras normas de privacidad y seguridad + 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 + test_ssn: En el entorno de prueba solo los SSN que comienzan con “900-” o “666-” + se consideran válidos. No ingrese PII real en este campo. + text1: Su documento de identidad no puede estar caducado. + text2: No necesitará la tarjeta con usted. + text3_html: + - 'Verificar por teléfono: Le llamaremos o enviaremos + un mensaje de texto a su número de teléfono. Esto lleva unos minutos' + - 'Verificar por correo: Le enviaremos una carta a su + domicilio. Esto tarda entre 3 y 7 días laborables.' info: address_guidance_puerto_rico_html: Residentes en Puerto Rico:

Edite su dirección para que figure su urbanización o condominio en la línea de @@ -172,6 +196,8 @@ es: document_capture_intro_acknowledgment: Recopilaremos información sobre usted leyendo su documento de identidad expedido por el Estado. Usamos esta información para verificar su identidad. + getting_started: '%{sp_name} necesita asegurarse de que es usted y no es alguien + que se hace pasar por usted.' hybrid_handoff: Recopilaremos información sobre usted leyendo su documento de identidad expedido por el estado. image_loaded: Imagen cargada @@ -218,6 +244,7 @@ es: consent: Al marcar esta casilla, usted permite que %{app_name} solicite, utilice, conserve y comparta su información personal. Los utilizamos para verificar su identidad. + getting_started: 'Necesitará su:' learn_more: Obtenga más información sobre nuestras medidas de privacidad y seguridad privacy: Nuestras normas de privacidad y seguridad switch_back: Regrese a su computadora para continuar con la verificación de su diff --git a/config/locales/doc_auth/fr.yml b/config/locales/doc_auth/fr.yml index 24ff5d1f60a..a3baade1ef7 100644 --- a/config/locales/doc_auth/fr.yml +++ b/config/locales/doc_auth/fr.yml @@ -142,6 +142,7 @@ fr: document_capture_back: Verso de votre carte d’identité document_capture_front: Recto de votre carte d’identité front: Recto + getting_started: Commencez à vérifier votre identité hybrid_handoff: Comment voulez-vous ajouter votre identifiant ? interstitial: Nous traitons vos images lets_go: Comment fonctionne la vérification de votre identité @@ -165,6 +166,31 @@ fr: identité en utilisant votre téléphone only_add_sp_services_html: Vous essayez d’accéder aux services de %{service_provider_name} + getting_started: + instructions: + bullet1: Carte d’identité délivrée par l’État + bullet2: Numéro de sécurité sociale + bullet3: Numéro de téléphone OU adresse du domicile + consent: En cochant cette case, vous autorisez %{app_name} à demander, utiliser, + conserver et partager vos renseignements personnels. Nous les utilisons + pour vérifier votre identité. + getting_started: 'Vous aurez besoin de votre:' + learn_more: En savoir plus sur nos mesures de confidentialité et de sécurité + privacy: Nos normes de confidentialité et de sécurité + switch_back: Retournez sur votre ordinateur pour continuer à vérifier votre identité. + switch_back_image: Flèche pointant du téléphone vers l’ordinateur + test_ssn: Dans l’environnement de test seuls les SSN commençant par “900-” ou + “900-” sont considérés comme valides. N’entrez pas de vrais PII dans ce + champ. + text1: Votre carte d’identité ne doit pas être expirée. + text2: Vous n’aurez pas besoin de la carte sur vous. + text3_html: + - 'Vérification par téléphone : Nous appellerons ou + enverrons un SMS à votre numéro de téléphone. Cela prend quelques + minutes.' + - 'Vérification par courrier : Nous vous enverrons une + lettre à votre adresse personnelle. Cela prend de 3 à 7 jours + ouvrables.' info: address_guidance_puerto_rico_html: Résidents de Porto Rico:

Modifiez votre adresse pour indiquer votre lotissement ou votre condominium à la @@ -177,6 +203,8 @@ fr: document_capture_intro_acknowledgment: Nous recueillons des informations sur vous en lisant votre pièce d’identité délivrée par l’État. Nous utilisons ces informations pour vérifier votre identité. + getting_started: '%{sp_name} doit s’assurer que vous êtes bien vous, et non + quelqu’un qui se fait passer pour vous.' hybrid_handoff: Nous recueillons des informations sur vous en lisant votre carte d’identité délivrée par l’État. image_loaded: Image chargée @@ -225,6 +253,7 @@ fr: consent: En cochant cette case, vous autorisez %{app_name} à demander, utiliser, conserver et partager vos renseignements personnels. Nous les utilisons pour vérifier votre identité. + getting_started: 'Vous aurez besoin de votre:' learn_more: En savoir plus sur nos mesures de confidentialité et de sécurité privacy: Nos normes de confidentialité et de sécurité switch_back: Retournez sur votre ordinateur pour continuer à vérifier votre identité. diff --git a/config/locales/idv/en.yml b/config/locales/idv/en.yml index 31a9a32e45f..0c2fe8e310d 100644 --- a/config/locales/idv/en.yml +++ b/config/locales/idv/en.yml @@ -166,6 +166,10 @@ en: ssn_label: Social Security number state: State zipcode: ZIP Code + getting_started: + no_js_header: You must enable JavaScript to verify your identity. + no_js_intro: '%{sp_name} needs you to verify your identity. You need to enable + JavaScript to continue this process.' images: come_back_later: Letter with a check mark index: diff --git a/config/locales/idv/es.yml b/config/locales/idv/es.yml index 54626089440..dd8a0e31292 100644 --- a/config/locales/idv/es.yml +++ b/config/locales/idv/es.yml @@ -174,6 +174,10 @@ es: ssn_label: Número de Seguro Social state: Estado zipcode: Código postal + getting_started: + no_js_header: Debe habilitar JavaScript para verificar su identidad. + no_js_intro: '%{sp_name} requiere que usted verifique su identidad. Debe + habilitar JavaScript para continuar con este proceso.' images: come_back_later: Carta con una marca de verificación index: diff --git a/config/locales/idv/fr.yml b/config/locales/idv/fr.yml index 5e7d2fa128e..adc95adb52f 100644 --- a/config/locales/idv/fr.yml +++ b/config/locales/idv/fr.yml @@ -181,6 +181,10 @@ fr: ssn_label: Numéro de sécurité sociale state: État zipcode: Code postal + getting_started: + no_js_header: Vous devez activer JavaScript pour vérifier votre identité. + no_js_intro: '%{sp_name} a besoin de vous pour vérifier votre identité. Vous + devez activer JavaScript pour poursuivre ce processus.' images: come_back_later: Lettre avec un crochet index: From 394c55d0312543b930275aed7db27d7497f60ac4 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Mon, 17 Jul 2023 15:34:53 -0700 Subject: [PATCH 11/27] Add new translation text and page formatting --- .../idv/getting_started_controller.rb | 2 + app/views/idv/getting_started/show.html.erb | 40 +++++++++---------- config/locales/doc_auth/en.yml | 32 ++++++--------- config/locales/doc_auth/es.yml | 28 +++++-------- config/locales/doc_auth/fr.yml | 34 ++++++---------- .../idv/doc_auth/getting_started_spec.rb | 22 +--------- 6 files changed, 59 insertions(+), 99 deletions(-) diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb index e7bf3c6897c..412cc82d572 100644 --- a/app/controllers/idv/getting_started_controller.rb +++ b/app/controllers/idv/getting_started_controller.rb @@ -12,6 +12,8 @@ def show 'welcome', :view, true ) + @sp_name = decorated_session.sp_name || t('doc_auth.info.no_sp_name') + @title = t('doc_auth.headings.getting_started', sp_name: @sp_name.downcase) render :show, locals: { flow_session: flow_session } end diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb index c17afb4ee37..2d8df367af0 100644 --- a/app/views/idv/getting_started/show.html.erb +++ b/app/views/idv/getting_started/show.html.erb @@ -1,9 +1,9 @@ -<% title t('doc_auth.headings.getting_started') %> +<% title @title %> <%= render 'shared/maintenance_window_alert' do %> <%= render JavascriptRequiredComponent.new( header: t('idv.getting_started.no_js_header'), - intro: t('idv.getting_started.no_js_intro', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')), + intro: t('idv.getting_started.no_js_intro', sp_name: @sp_name), ) do %> <% if @current_user&.reproof_for_irs?(service_provider: @current_sp) %> @@ -15,9 +15,20 @@ %> <% end %> - <%= render PageHeadingComponent.new.with_content(t('doc_auth.headings.getting_started')) %> + <%= render PageHeadingComponent.new.with_content(@title) %>

- <%= t('doc_auth.info.getting_started', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')) %> + <%= t('doc_auth.info.getting_started_html', + sp_name: @sp_name, + link_html: new_tab_link_to( + t('doc_auth.info.getting_started_learn_more'), + help_center_redirect_path( + category: 'verify-your-identity', + article: 'how-to-verify-your-identity', + flow: :idv, + step: :getting_started, + location: 'you_will_need', + ), + )) %>

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

@@ -30,21 +41,10 @@

<%= t('doc_auth.getting_started.instructions.text2') %>

<% end %> <%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet3')) do %> -
    - <% t('doc_auth.getting_started.instructions.text3_html').each do |bullet_item| %> -
  • <%= bullet_item %>
  • - <% end %> -
- <%= new_tab_link_to( - t('idv.troubleshooting.options.learn_more_address_verification_options'), - help_center_redirect_path( - category: 'verify-your-identity', - article: 'phone-number', - flow: :idv, - step: :welcome, - location: 'you_will_need', - ), - ) %> +

<%= t('doc_auth.getting_started.instructions.text3') %>

+ <% end %> + <%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet4')) do %> +

<%= t('doc_auth.getting_started.instructions.text4') %>

<% end %> <% end %> @@ -66,7 +66,7 @@

<%= new_tab_link_to( t('doc_auth.getting_started.instructions.learn_more'), - policy_redirect_url(flow: :idv, step: :agreement, location: :consent), + policy_redirect_url(flow: :idv, step: :getting_started, location: :consent), ) %>

diff --git a/config/locales/doc_auth/en.yml b/config/locales/doc_auth/en.yml index 382426d8284..c42051b2511 100644 --- a/config/locales/doc_auth/en.yml +++ b/config/locales/doc_auth/en.yml @@ -112,7 +112,7 @@ en: document_capture_back: Back of your ID document_capture_front: Front of your ID front: Front - getting_started: Get started verifying your identity + getting_started: Let’s verify your identity for %{sp_name} hybrid_handoff: How would you like to add your ID? interstitial: We are processing your images lets_go: How verifying your identity works @@ -137,26 +137,20 @@ en: %{service_provider_name} services getting_started: instructions: - bullet1: State‑issued ID - bullet2: Social Security number - bullet3: Phone number OR home address + bullet1: Add photos of your ID + bullet2: Enter your Social Security number + bullet3: Match to your phone number + bullet4: Re-enter your Login.gov password consent: By checking this box, you are letting %{app_name} ask for, use, keep, and share your personal information. We will use it to verify your identity. - getting_started: 'You will need your:' + getting_started: 'You’ll need to:' learn_more: Learn more about our privacy and security measures privacy: Our privacy and security standards - switch_back: Switch back to your computer to finish verifying your identity. - switch_back_image: Arrow pointing from phone to computer - test_ssn: In the test environment only SSNs that begin with “900-” or “666-” are - considered valid. Do not enter real PII in this field. - text1: Your ID cannot be expired. - text2: You will not need the card with you. - text3_html: - - 'Verify by phone: We’ll call or text your phone - number. This takes a few minutes.' - - 'Verify by mail: We’ll mail a letter to your home - address. This takes about 3 to 7 business days.' + text1: Use your driver’s license or state ID card. Other forms of ID are not accepted. + text2: You will not need your physical SSN card. + text3: Your phone number matches you to your personal information. After you match, we’ll send you a code. + text4: Your password saves and encrypts your personal information. info: address_guidance_puerto_rico_html: Puerto Rico residents:

Edit your address to list your urbanization or condominium on address line 2. @@ -168,8 +162,9 @@ en: document_capture_intro_acknowledgment: We’ll collect information about you by reading your state‑issued ID. We use this information to verify your identity. - getting_started: '%{sp_name} needs to make sure you are you — not someone - pretending to be you.' + getting_started_html: '%{sp_name} needs to make sure you are you — not someone + pretending to be you. %{link_html}' + getting_started_learn_more: Learn more about what you need to verify your identity hybrid_handoff: We’ll collect information about you by reading your state‑issued ID. image_loaded: Image loaded image_loading: Image loading @@ -211,7 +206,6 @@ en: consent: By checking this box, you are letting %{app_name} ask for, use, keep, and share your personal information. We will use it to verify your identity. - getting_started: 'You will need your:' learn_more: Learn more about our privacy and security measures privacy: Our privacy and security standards switch_back: Switch back to your computer to finish verifying your identity. diff --git a/config/locales/doc_auth/es.yml b/config/locales/doc_auth/es.yml index 5a60ba657e7..6aaa265024b 100644 --- a/config/locales/doc_auth/es.yml +++ b/config/locales/doc_auth/es.yml @@ -136,7 +136,7 @@ es: document_capture_back: Parte trasera de su documento de identidad document_capture_front: Parte delantera de su documento de identidad front: Parte Delantera - getting_started: Comience a verificar su identidad + getting_started: Vamos a verificar su identidad para %{sp_name} hybrid_handoff: '¿Cómo desea añadir su documento de identidad?' interstitial: Estamos procesando sus imágenes lets_go: Cómo funciona la verificación de su identidad @@ -163,27 +163,20 @@ es: %{service_provider_name} getting_started: instructions: - bullet1: Documento de identidad emitido por el estado. - bullet2: Número de seguro social - bullet3: Número de teléfono O domicilio + bullet1: Incluir fotos de su identificación + bullet2: Introducir su número de Seguro Social + bullet3: Vincular su número de teléfono + bullet4: Volver a introducir su contraseña de Login.gov consent: Al marcar esta casilla, usted permite que %{app_name} solicite, utilice, conserve y comparta su información personal. Los utilizamos para verificar su identidad. - getting_started: 'Necesitará su:' + getting_started: 'Deberá:' learn_more: Obtenga más información sobre nuestras medidas de privacidad y seguridad privacy: Nuestras normas de privacidad y seguridad - 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 - test_ssn: En el entorno de prueba solo los SSN que comienzan con “900-” o “666-” - se consideran válidos. No ingrese PII real en este campo. text1: Su documento de identidad no puede estar caducado. text2: No necesitará la tarjeta con usted. - text3_html: - - 'Verificar por teléfono: Le llamaremos o enviaremos - un mensaje de texto a su número de teléfono. Esto lleva unos minutos' - - 'Verificar por correo: Le enviaremos una carta a su - domicilio. Esto tarda entre 3 y 7 días laborables.' + text3: Su número de teléfono se asocia a su información personal. Después de que lo haya asociado, le enviaremos un código. + text4: Su contraseña guarda y encripta su información personal. info: address_guidance_puerto_rico_html: Residentes en Puerto Rico:

Edite su dirección para que figure su urbanización o condominio en la línea de @@ -196,8 +189,8 @@ es: document_capture_intro_acknowledgment: Recopilaremos información sobre usted leyendo su documento de identidad expedido por el Estado. Usamos esta información para verificar su identidad. - getting_started: '%{sp_name} necesita asegurarse de que es usted y no es alguien - que se hace pasar por usted.' + getting_started_html: '%{sp_name} necesita asegurarse de que es usted realmente y no alguien que se hace pasar por usted. %{link_html}' + getting_started_learn_more: Obtenga más información sobre lo que necesita para verificar su identidad hybrid_handoff: Recopilaremos información sobre usted leyendo su documento de identidad expedido por el estado. image_loaded: Imagen cargada @@ -244,7 +237,6 @@ es: consent: Al marcar esta casilla, usted permite que %{app_name} solicite, utilice, conserve y comparta su información personal. Los utilizamos para verificar su identidad. - getting_started: 'Necesitará su:' learn_more: Obtenga más información sobre nuestras medidas de privacidad y seguridad privacy: Nuestras normas de privacidad y seguridad switch_back: Regrese a su computadora para continuar con la verificación de su diff --git a/config/locales/doc_auth/fr.yml b/config/locales/doc_auth/fr.yml index a3baade1ef7..1d9a071a3f9 100644 --- a/config/locales/doc_auth/fr.yml +++ b/config/locales/doc_auth/fr.yml @@ -142,7 +142,7 @@ fr: document_capture_back: Verso de votre carte d’identité document_capture_front: Recto de votre carte d’identité front: Recto - getting_started: Commencez à vérifier votre identité + getting_started: Vérifions votre identité pour %{sp_name} hybrid_handoff: Comment voulez-vous ajouter votre identifiant ? interstitial: Nous traitons vos images lets_go: Comment fonctionne la vérification de votre identité @@ -168,29 +168,20 @@ fr: %{service_provider_name} getting_started: instructions: - bullet1: Carte d’identité délivrée par l’État - bullet2: Numéro de sécurité sociale - bullet3: Numéro de téléphone OU adresse du domicile + bullet1: Ajoutez des photos de votre pièce d’identité + bullet2: Saisissez votre numéro de sécurité sociale + bullet3: Faire correspondre à votre numéro de téléphone + bullet4: Saisissez à nouveau votre mot de passe Login.gov consent: En cochant cette case, vous autorisez %{app_name} à demander, utiliser, conserver et partager vos renseignements personnels. Nous les utilisons pour vérifier votre identité. - getting_started: 'Vous aurez besoin de votre:' + getting_started: 'Vous aurez besoin de :' learn_more: En savoir plus sur nos mesures de confidentialité et de sécurité privacy: Nos normes de confidentialité et de sécurité - switch_back: Retournez sur votre ordinateur pour continuer à vérifier votre identité. - switch_back_image: Flèche pointant du téléphone vers l’ordinateur - test_ssn: Dans l’environnement de test seuls les SSN commençant par “900-” ou - “900-” sont considérés comme valides. N’entrez pas de vrais PII dans ce - champ. - text1: Votre carte d’identité ne doit pas être expirée. - text2: Vous n’aurez pas besoin de la carte sur vous. - text3_html: - - 'Vérification par téléphone : Nous appellerons ou - enverrons un SMS à votre numéro de téléphone. Cela prend quelques - minutes.' - - 'Vérification par courrier : Nous vous enverrons une - lettre à votre adresse personnelle. Cela prend de 3 à 7 jours - ouvrables.' + text1: Utilisez votre permis de conduire ou votre carte d'identité de l'État. Les autres pièces d’identité ne sont pas acceptées. + text2: Vous n’aurez pas besoin de votre carte SSN physique. + text3: Votre numéro de téléphone correspond à vos informations personnelles. Une fois la correspondance établie, nous vous enverrons un code. + text4: Votre mot de passe sauvegarde et crypte vos informations personnelles. info: address_guidance_puerto_rico_html: Résidents de Porto Rico:

Modifiez votre adresse pour indiquer votre lotissement ou votre condominium à la @@ -203,8 +194,8 @@ fr: document_capture_intro_acknowledgment: Nous recueillons des informations sur vous en lisant votre pièce d’identité délivrée par l’État. Nous utilisons ces informations pour vérifier votre identité. - getting_started: '%{sp_name} doit s’assurer que vous êtes bien vous, et non - quelqu’un qui se fait passer pour vous.' + getting_started_html: '%{sp_name} doit s’assurer que c’est bien vous — et non quelqu’un qui se fait passer pour vous. %{link_html}' + getting_started_learn_more: En savoir plus sur ce dont vous avez besoin pour vérifier votre identité hybrid_handoff: Nous recueillons des informations sur vous en lisant votre carte d’identité délivrée par l’État. image_loaded: Image chargée @@ -253,7 +244,6 @@ fr: consent: En cochant cette case, vous autorisez %{app_name} à demander, utiliser, conserver et partager vos renseignements personnels. Nous les utilisons pour vérifier votre identité. - getting_started: 'Vous aurez besoin de votre:' learn_more: En savoir plus sur nos mesures de confidentialité et de sécurité privacy: Nos normes de confidentialité et de sécurité switch_back: Retournez sur votre ordinateur pour continuer à vérifier votre identité. diff --git a/spec/features/idv/doc_auth/getting_started_spec.rb b/spec/features/idv/doc_auth/getting_started_spec.rb index c0ac081c97d..829bce0dac3 100644 --- a/spec/features/idv/doc_auth/getting_started_spec.rb +++ b/spec/features/idv/doc_auth/getting_started_spec.rb @@ -11,33 +11,15 @@ before do 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) - start, finish = maintenance_window - allow(IdentityConfig.store).to receive(:acuant_maintenance_window_start).and_return(start) - allow(IdentityConfig.store).to receive(:acuant_maintenance_window_finish).and_return(finish) + allow_any_instance_of(Idv::WelcomeController).to receive(:getting_started_a_b_test_bucket). + and_return(:new) visit_idp_from_sp_with_ial2(:oidc) sign_in_and_2fa_user complete_doc_auth_steps_before_welcome_step - visit(idv_getting_started_url) end it 'displays expected content', :js do expect(page).to have_current_path(idv_getting_started_path) end - - context 'during the acuant maintenance window' do - let(:maintenance_window) do - [Time.zone.parse('2020-01-01T00:00:00Z'), Time.zone.parse('2020-01-01T23:59:59Z')] - end - let(:now) { Time.zone.parse('2020-01-01T12:00:00Z') } - - around do |ex| - travel_to(now) { ex.run } - end - - it 'renders the warning banner but no other content' do - expect(page).to have_content('We are currently under maintenance') - expect(page).to_not have_content(t('doc_auth.headings.welcome')) - end - end end From c2e549b3dabcc887debefe2820b833e31194b74d Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Mon, 17 Jul 2023 15:39:21 -0700 Subject: [PATCH 12/27] Register both welcome and agreement steps in DocAuthLog --- app/controllers/idv/getting_started_controller.rb | 6 ++++++ spec/controllers/idv/getting_started_controller_spec.rb | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb index 412cc82d572..778c774aa40 100644 --- a/app/controllers/idv/getting_started_controller.rb +++ b/app/controllers/idv/getting_started_controller.rb @@ -8,10 +8,16 @@ class GettingStartedController < ApplicationController def show analytics.idv_doc_auth_getting_started_visited(**analytics_arguments) + # Register both Welcome and Agreement steps in DocAuthLog Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( 'welcome', :view, true ) + Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( + 'agreement', :view, + true + ) + @sp_name = decorated_session.sp_name || t('doc_auth.info.no_sp_name') @title = t('doc_auth.headings.getting_started', sp_name: @sp_name.downcase) diff --git a/spec/controllers/idv/getting_started_controller_spec.rb b/spec/controllers/idv/getting_started_controller_spec.rb index 2f6ea79fc7c..0eaaa0ac9c0 100644 --- a/spec/controllers/idv/getting_started_controller_spec.rb +++ b/spec/controllers/idv/getting_started_controller_spec.rb @@ -55,6 +55,14 @@ ) end + it 'updates DocAuthLog agreement_view_count' do + doc_auth_log = DocAuthLog.create(user_id: user.id) + + expect { get :show }.to( + change { doc_auth_log.reload.agreement_view_count }.from(0).to(1), + ) + end + context 'getting_started already visited' do it 'redirects to hybrid_handoff' do subject.idv_session.idv_consent_given = true From 06e52863b06176a158a0c4533a50fb6813767086 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Mon, 17 Jul 2023 15:45:25 -0700 Subject: [PATCH 13/27] Lint --- app/views/idv/getting_started/show.html.erb | 10 +++--- config/locales/doc_auth/en.yml | 34 ++++++++++--------- config/locales/doc_auth/es.yml | 37 +++++++++++---------- config/locales/doc_auth/fr.yml | 37 +++++++++++---------- 4 files changed, 64 insertions(+), 54 deletions(-) diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb index 2d8df367af0..20cbff40140 100644 --- a/app/views/idv/getting_started/show.html.erb +++ b/app/views/idv/getting_started/show.html.erb @@ -17,9 +17,10 @@ <%= render PageHeadingComponent.new.with_content(@title) %>

- <%= t('doc_auth.info.getting_started_html', - sp_name: @sp_name, - link_html: new_tab_link_to( + <%= t( + 'doc_auth.info.getting_started_html', + sp_name: @sp_name, + link_html: new_tab_link_to( t('doc_auth.info.getting_started_learn_more'), help_center_redirect_path( category: 'verify-your-identity', @@ -28,7 +29,8 @@ step: :getting_started, location: 'you_will_need', ), - )) %> + ), + ) %>

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

diff --git a/config/locales/doc_auth/en.yml b/config/locales/doc_auth/en.yml index c42051b2511..18d4e9b2af1 100644 --- a/config/locales/doc_auth/en.yml +++ b/config/locales/doc_auth/en.yml @@ -99,6 +99,24 @@ en: choose_file_html: Drag file here or choose from folder doc_success: We verified your information selected_file: Selected file + getting_started: + instructions: + bullet1: Add photos of your ID + bullet2: Enter your Social Security number + bullet3: Match to your phone number + bullet4: Re-enter your Login.gov password + consent: By checking this box, you are letting %{app_name} ask for, use, keep, + and share your personal information. We will use it to verify your + identity. + getting_started: 'You’ll need to:' + learn_more: Learn more about our privacy and security measures + privacy: Our privacy and security standards + text1: Use your driver’s license or state ID card. Other forms of ID are not + accepted. + text2: You will not need your physical SSN card. + text3: Your phone number matches you to your personal information. After you + match, we’ll send you a code. + text4: Your password saves and encrypts your personal information. headings: address: Update your mailing address back: Back @@ -135,22 +153,6 @@ en: only_add_phone_verify: You asked %{app_name} to verify your ID using your phone only_add_sp_services_html: You are trying to access %{service_provider_name} services - getting_started: - instructions: - bullet1: Add photos of your ID - bullet2: Enter your Social Security number - bullet3: Match to your phone number - bullet4: Re-enter your Login.gov password - consent: By checking this box, you are letting %{app_name} ask for, use, keep, - and share your personal information. We will use it to verify your - identity. - getting_started: 'You’ll need to:' - learn_more: Learn more about our privacy and security measures - privacy: Our privacy and security standards - text1: Use your driver’s license or state ID card. Other forms of ID are not accepted. - text2: You will not need your physical SSN card. - text3: Your phone number matches you to your personal information. After you match, we’ll send you a code. - text4: Your password saves and encrypts your personal information. info: address_guidance_puerto_rico_html: Puerto Rico residents:

Edit your address to list your urbanization or condominium on address line 2. diff --git a/config/locales/doc_auth/es.yml b/config/locales/doc_auth/es.yml index 6aaa265024b..2bdaafe76c8 100644 --- a/config/locales/doc_auth/es.yml +++ b/config/locales/doc_auth/es.yml @@ -123,6 +123,24 @@ es: carpeta doc_success: Verificamos sus datos selected_file: Archivo seleccionado + getting_started: + instructions: + bullet1: Incluir fotos de su identificación + bullet2: Introducir su número de Seguro Social + bullet3: Vincular su número de teléfono + bullet4: Volver a introducir su contraseña de Login.gov + consent: Al marcar esta casilla, usted permite que %{app_name} solicite, + utilice, conserve y comparta su información personal. Los utilizamos + para verificar su identidad. + getting_started: 'Deberá:' + learn_more: Obtenga más información sobre nuestras medidas de privacidad y + seguridad + privacy: Nuestras normas de privacidad y seguridad + text1: Su documento de identidad no puede estar caducado. + text2: No necesitará la tarjeta con usted. + text3: Su número de teléfono se asocia a su información personal. Después de que + lo haya asociado, le enviaremos un código. + text4: Su contraseña guarda y encripta su información personal. headings: address: Actualice su dirección postal back: Parte Trasera @@ -161,22 +179,6 @@ es: a través de su teléfono only_add_sp_services_html: Está tratando de acceder a los servicios %{service_provider_name} - getting_started: - instructions: - bullet1: Incluir fotos de su identificación - bullet2: Introducir su número de Seguro Social - bullet3: Vincular su número de teléfono - bullet4: Volver a introducir su contraseña de Login.gov - consent: Al marcar esta casilla, usted permite que %{app_name} solicite, - utilice, conserve y comparta su información personal. Los utilizamos - para verificar su identidad. - getting_started: 'Deberá:' - learn_more: Obtenga más información sobre nuestras medidas de privacidad y seguridad - privacy: Nuestras normas de privacidad y seguridad - text1: Su documento de identidad no puede estar caducado. - text2: No necesitará la tarjeta con usted. - text3: Su número de teléfono se asocia a su información personal. Después de que lo haya asociado, le enviaremos un código. - text4: Su contraseña guarda y encripta su información personal. info: address_guidance_puerto_rico_html: Residentes en Puerto Rico:

Edite su dirección para que figure su urbanización o condominio en la línea de @@ -189,7 +191,8 @@ es: document_capture_intro_acknowledgment: Recopilaremos información sobre usted leyendo su documento de identidad expedido por el Estado. Usamos esta información para verificar su identidad. - getting_started_html: '%{sp_name} necesita asegurarse de que es usted realmente y no alguien que se hace pasar por usted. %{link_html}' + getting_started_html: '%{sp_name} necesita asegurarse de que es usted realmente + y no alguien que se hace pasar por usted. %{link_html}' getting_started_learn_more: Obtenga más información sobre lo que necesita para verificar su identidad hybrid_handoff: Recopilaremos información sobre usted leyendo su documento de identidad expedido por el estado. diff --git a/config/locales/doc_auth/fr.yml b/config/locales/doc_auth/fr.yml index 1d9a071a3f9..523293127ff 100644 --- a/config/locales/doc_auth/fr.yml +++ b/config/locales/doc_auth/fr.yml @@ -129,6 +129,24 @@ fr: dossier doc_success: Nous avons vérifié vos informations selected_file: Fichier sélectionné + getting_started: + instructions: + bullet1: Ajoutez des photos de votre pièce d’identité + bullet2: Saisissez votre numéro de sécurité sociale + bullet3: Faire correspondre à votre numéro de téléphone + bullet4: Saisissez à nouveau votre mot de passe Login.gov + consent: En cochant cette case, vous autorisez %{app_name} à demander, utiliser, + conserver et partager vos renseignements personnels. Nous les + utilisons pour vérifier votre identité. + getting_started: 'Vous aurez besoin de :' + learn_more: En savoir plus sur nos mesures de confidentialité et de sécurité + privacy: Nos normes de confidentialité et de sécurité + text1: Utilisez votre permis de conduire ou votre carte d’identité de l’État. + Les autres pièces d’identité ne sont pas acceptées. + text2: Vous n’aurez pas besoin de votre carte SSN physique. + text3: Votre numéro de téléphone correspond à vos informations personnelles. Une + fois la correspondance établie, nous vous enverrons un code. + text4: Votre mot de passe sauvegarde et crypte vos informations personnelles. headings: address: Mettre à jour votre adresse postale back: Verso @@ -166,22 +184,6 @@ fr: identité en utilisant votre téléphone only_add_sp_services_html: Vous essayez d’accéder aux services de %{service_provider_name} - getting_started: - instructions: - bullet1: Ajoutez des photos de votre pièce d’identité - bullet2: Saisissez votre numéro de sécurité sociale - bullet3: Faire correspondre à votre numéro de téléphone - bullet4: Saisissez à nouveau votre mot de passe Login.gov - consent: En cochant cette case, vous autorisez %{app_name} à demander, utiliser, - conserver et partager vos renseignements personnels. Nous les utilisons - pour vérifier votre identité. - getting_started: 'Vous aurez besoin de :' - learn_more: En savoir plus sur nos mesures de confidentialité et de sécurité - privacy: Nos normes de confidentialité et de sécurité - text1: Utilisez votre permis de conduire ou votre carte d'identité de l'État. Les autres pièces d’identité ne sont pas acceptées. - text2: Vous n’aurez pas besoin de votre carte SSN physique. - text3: Votre numéro de téléphone correspond à vos informations personnelles. Une fois la correspondance établie, nous vous enverrons un code. - text4: Votre mot de passe sauvegarde et crypte vos informations personnelles. info: address_guidance_puerto_rico_html: Résidents de Porto Rico:

Modifiez votre adresse pour indiquer votre lotissement ou votre condominium à la @@ -194,7 +196,8 @@ fr: document_capture_intro_acknowledgment: Nous recueillons des informations sur vous en lisant votre pièce d’identité délivrée par l’État. Nous utilisons ces informations pour vérifier votre identité. - getting_started_html: '%{sp_name} doit s’assurer que c’est bien vous — et non quelqu’un qui se fait passer pour vous. %{link_html}' + getting_started_html: '%{sp_name} doit s’assurer que c’est bien vous — et non + quelqu’un qui se fait passer pour vous. %{link_html}' getting_started_learn_more: En savoir plus sur ce dont vous avez besoin pour vérifier votre identité hybrid_handoff: Nous recueillons des informations sur vous en lisant votre carte d’identité délivrée par l’État. From a3b3289c1579e31f2ef639563a887ed0d6a20cf7 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Mon, 17 Jul 2023 15:58:10 -0700 Subject: [PATCH 14/27] Test agreement checkbox in getting started feature spec --- spec/features/idv/doc_auth/getting_started_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/features/idv/doc_auth/getting_started_spec.rb b/spec/features/idv/doc_auth/getting_started_spec.rb index 829bce0dac3..4a8bb0eed5b 100644 --- a/spec/features/idv/doc_auth/getting_started_spec.rb +++ b/spec/features/idv/doc_auth/getting_started_spec.rb @@ -21,5 +21,17 @@ it 'displays expected content', :js do expect(page).to have_current_path(idv_getting_started_path) + + # Try to continue with unchecked checkbox + click_continue + expect(page).to have_current_path(idv_getting_started_path) + expect(page).to have_content(t('forms.validation.required_checkbox')) + + complete_getting_started_step + expect(page).to have_current_path(idv_hybrid_handoff_path) + end + + def complete_getting_started_step + complete_agreement_step # it does the right thing end end From f5dc4cec132ae7e9d72f22f194902d18524800e8 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Mon, 17 Jul 2023 15:58:39 -0700 Subject: [PATCH 15/27] Remove unneeded locals when rendering show in WelcomeController --- app/controllers/idv/welcome_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/idv/welcome_controller.rb b/app/controllers/idv/welcome_controller.rb index 4019aac00ef..3e9e25416bd 100644 --- a/app/controllers/idv/welcome_controller.rb +++ b/app/controllers/idv/welcome_controller.rb @@ -16,7 +16,7 @@ def show true ) - render :show, locals: { flow_session: flow_session } + render :show end def update From 05dd0ca16290aaaebe2131228764139c2489be9e Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Mon, 17 Jul 2023 16:12:15 -0700 Subject: [PATCH 16/27] Add Agreement feature specs and make them pass --- app/views/idv/getting_started/show.html.erb | 10 +++++++ .../idv/doc_auth/getting_started_spec.rb | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb index 20cbff40140..361fe76ebbd 100644 --- a/app/views/idv/getting_started/show.html.erb +++ b/app/views/idv/getting_started/show.html.erb @@ -15,6 +15,16 @@ %> <% end %> + <%= render AlertComponent.new( + type: :error, + class: [ + 'js-consent-form-alert', + 'margin-bottom-4', + flow_session[:error_message].blank? && 'display-none', + ].select(&:present?), + message: flow_session[:error_message].presence || t('errors.doc_auth.consent_form'), + ) %> + <%= render PageHeadingComponent.new.with_content(@title) %>

<%= t( diff --git a/spec/features/idv/doc_auth/getting_started_spec.rb b/spec/features/idv/doc_auth/getting_started_spec.rb index 4a8bb0eed5b..456183b06c2 100644 --- a/spec/features/idv/doc_auth/getting_started_spec.rb +++ b/spec/features/idv/doc_auth/getting_started_spec.rb @@ -31,6 +31,32 @@ expect(page).to have_current_path(idv_hybrid_handoff_path) end + context 'when JS is disabled' do + it 'shows the notice if the user clicks continue without giving consent' do + click_continue + + expect(page).to have_current_path(idv_getting_started_url) + 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('doc_auth.instructions.consent', app_name: APP_NAME) + click_continue + + expect(page).to have_current_path(idv_hybrid_handoff_path) + end + end + + context 'skipping hybrid_handoff step', :js, driver: :headless_chrome_mobile do + before do + complete_getting_started_step + end + + it 'progresses to document capture' do + expect(page).to have_current_path(idv_document_capture_url) + end + end + def complete_getting_started_step complete_agreement_step # it does the right thing end From bdf5e638825a267d67c981276b326070973d0d6c Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Tue, 18 Jul 2023 08:56:32 -0700 Subject: [PATCH 17/27] I18n lint --- app/views/idv/getting_started/show.html.erb | 2 +- config/locales/doc_auth/en.yml | 3 +-- config/locales/doc_auth/es.yml | 3 +-- config/locales/doc_auth/fr.yml | 3 +-- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb index 361fe76ebbd..f786d08c898 100644 --- a/app/views/idv/getting_started/show.html.erb +++ b/app/views/idv/getting_started/show.html.erb @@ -55,7 +55,7 @@ <%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet3')) do %>

<%= t('doc_auth.getting_started.instructions.text3') %>

<% end %> - <%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet4')) do %> + <%= c.with_item(heading: t('doc_auth.getting_started.instructions.bullet4', app_name: APP_NAME)) do %>

<%= t('doc_auth.getting_started.instructions.text4') %>

<% end %> <% end %> diff --git a/config/locales/doc_auth/en.yml b/config/locales/doc_auth/en.yml index 18d4e9b2af1..baadbdb5fbb 100644 --- a/config/locales/doc_auth/en.yml +++ b/config/locales/doc_auth/en.yml @@ -104,13 +104,12 @@ en: bullet1: Add photos of your ID bullet2: Enter your Social Security number bullet3: Match to your phone number - bullet4: Re-enter your Login.gov password + bullet4: Re-enter your %{app_name} password consent: By checking this box, you are letting %{app_name} ask for, use, keep, and share your personal information. We will use it to verify your identity. getting_started: 'You’ll need to:' learn_more: Learn more about our privacy and security measures - privacy: Our privacy and security standards text1: Use your driver’s license or state ID card. Other forms of ID are not accepted. text2: You will not need your physical SSN card. diff --git a/config/locales/doc_auth/es.yml b/config/locales/doc_auth/es.yml index 2bdaafe76c8..23371e23cdc 100644 --- a/config/locales/doc_auth/es.yml +++ b/config/locales/doc_auth/es.yml @@ -128,14 +128,13 @@ es: bullet1: Incluir fotos de su identificación bullet2: Introducir su número de Seguro Social bullet3: Vincular su número de teléfono - bullet4: Volver a introducir su contraseña de Login.gov + bullet4: Volver a introducir su contraseña de %{app_name} consent: Al marcar esta casilla, usted permite que %{app_name} solicite, utilice, conserve y comparta su información personal. Los utilizamos para verificar su identidad. getting_started: 'Deberá:' learn_more: Obtenga más información sobre nuestras medidas de privacidad y seguridad - privacy: Nuestras normas de privacidad y seguridad text1: Su documento de identidad no puede estar caducado. text2: No necesitará la tarjeta con usted. text3: Su número de teléfono se asocia a su información personal. Después de que diff --git a/config/locales/doc_auth/fr.yml b/config/locales/doc_auth/fr.yml index 523293127ff..af538d152be 100644 --- a/config/locales/doc_auth/fr.yml +++ b/config/locales/doc_auth/fr.yml @@ -134,13 +134,12 @@ fr: bullet1: Ajoutez des photos de votre pièce d’identité bullet2: Saisissez votre numéro de sécurité sociale bullet3: Faire correspondre à votre numéro de téléphone - bullet4: Saisissez à nouveau votre mot de passe Login.gov + bullet4: Saisissez à nouveau votre mot de passe %{app_name} consent: En cochant cette case, vous autorisez %{app_name} à demander, utiliser, conserver et partager vos renseignements personnels. Nous les utilisons pour vérifier votre identité. getting_started: 'Vous aurez besoin de :' learn_more: En savoir plus sur nos mesures de confidentialité et de sécurité - privacy: Nos normes de confidentialité et de sécurité text1: Utilisez votre permis de conduire ou votre carte d’identité de l’État. Les autres pièces d’identité ne sont pas acceptées. text2: Vous n’aurez pas besoin de votre carte SSN physique. From 6545ddb869a297164eb6628ce2102ac144c254d2 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Tue, 18 Jul 2023 08:57:48 -0700 Subject: [PATCH 18/27] Put parameters on own line, fix downcase of SP name --- app/controllers/idv/getting_started_controller.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb index 778c774aa40..a99b1ae6d7a 100644 --- a/app/controllers/idv/getting_started_controller.rb +++ b/app/controllers/idv/getting_started_controller.rb @@ -10,16 +10,21 @@ def show # Register both Welcome and Agreement steps in DocAuthLog Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( - 'welcome', :view, - true + 'welcome', + :view, + true, ) Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( - 'agreement', :view, - true + 'agreement', + :view, + true, ) @sp_name = decorated_session.sp_name || t('doc_auth.info.no_sp_name') - @title = t('doc_auth.headings.getting_started', sp_name: @sp_name.downcase) + @title = t( + 'doc_auth.headings.getting_started', + sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name').downcase, + ) render :show, locals: { flow_session: flow_session } end From 9ef31de29b7bac0a0e34c371276b75a0c6cdc093 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Tue, 18 Jul 2023 13:01:36 -0700 Subject: [PATCH 19/27] Fix bad merge in analytics_events --- app/services/analytics_events.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 348c9c99005..cb522455b77 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -688,6 +688,8 @@ def idv_doc_auth_getting_started_submitted(**extra) def idv_doc_auth_getting_started_visited(**extra) track_event('IdV: doc auth getting_started visited', **extra) + end + # The "hybrid handoff" step: Desktop user has submitted their choice to # either continue via desktop ("document_capture" destination) or switch # to mobile phone ("send_link" destination) to perform document upload. From f42300f5962aa3600f1c52b7d66531ec6ff8a744 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Tue, 18 Jul 2023 13:19:17 -0700 Subject: [PATCH 20/27] Clean up Funnel::DocAuth::RegisterStep code layout --- app/controllers/idv/getting_started_controller.rb | 14 ++++---------- app/controllers/idv/welcome_controller.rb | 6 ++---- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb index a99b1ae6d7a..6500ae79492 100644 --- a/app/controllers/idv/getting_started_controller.rb +++ b/app/controllers/idv/getting_started_controller.rb @@ -9,16 +9,10 @@ def show analytics.idv_doc_auth_getting_started_visited(**analytics_arguments) # Register both Welcome and Agreement steps in DocAuthLog - Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( - 'welcome', - :view, - true, - ) - Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( - 'agreement', - :view, - true, - ) + Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]). + call('welcome', :view, true) + Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]). + call('agreement', :view, true) @sp_name = decorated_session.sp_name || t('doc_auth.info.no_sp_name') @title = t( diff --git a/app/controllers/idv/welcome_controller.rb b/app/controllers/idv/welcome_controller.rb index 3e9e25416bd..f352e6ca4ec 100644 --- a/app/controllers/idv/welcome_controller.rb +++ b/app/controllers/idv/welcome_controller.rb @@ -11,10 +11,8 @@ class WelcomeController < ApplicationController def show analytics.idv_doc_auth_welcome_visited(**analytics_arguments) - Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).call( - 'welcome', :view, - true - ) + Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]). + call('welcome', :view, true) render :show end From 72c9834fb4c0ee63a5d54e5c83080d93a0a559ac Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Tue, 18 Jul 2023 14:54:09 -0700 Subject: [PATCH 21/27] Replace no_sp_name with APP_NAME when there's no SP --- app/controllers/idv/getting_started_controller.rb | 7 ++----- app/views/idv/welcome/show.html.erb | 4 ++-- config/locales/doc_auth/en.yml | 1 - config/locales/doc_auth/es.yml | 1 - config/locales/doc_auth/fr.yml | 1 - 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/app/controllers/idv/getting_started_controller.rb b/app/controllers/idv/getting_started_controller.rb index 6500ae79492..e0a38117053 100644 --- a/app/controllers/idv/getting_started_controller.rb +++ b/app/controllers/idv/getting_started_controller.rb @@ -14,11 +14,8 @@ def show Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]). call('agreement', :view, true) - @sp_name = decorated_session.sp_name || t('doc_auth.info.no_sp_name') - @title = t( - 'doc_auth.headings.getting_started', - sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name').downcase, - ) + @sp_name = decorated_session.sp_name || APP_NAME + @title = t('doc_auth.headings.getting_started', sp_name: @sp_name) render :show, locals: { flow_session: flow_session } end diff --git a/app/views/idv/welcome/show.html.erb b/app/views/idv/welcome/show.html.erb index 6a852e68406..63025fafef5 100644 --- a/app/views/idv/welcome/show.html.erb +++ b/app/views/idv/welcome/show.html.erb @@ -12,7 +12,7 @@ <%= render 'shared/maintenance_window_alert' do %> <%= render JavascriptRequiredComponent.new( header: t('idv.welcome.no_js_header'), - intro: t('idv.welcome.no_js_intro', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')), + intro: t('idv.welcome.no_js_intro', sp_name: decorated_session.sp_name || APP_Name), ) do %> <% if @current_user&.reproof_for_irs?(service_provider: @current_sp) %> @@ -26,7 +26,7 @@ <%= render PageHeadingComponent.new.with_content(t('doc_auth.headings.welcome')) %>

- <%= t('doc_auth.info.welcome', sp_name: decorated_session.sp_name || t('doc_auth.info.no_sp_name')) %> + <%= t('doc_auth.info.welcome', sp_name: decorated_session.sp_name || APP_NAME) %>

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

diff --git a/config/locales/doc_auth/en.yml b/config/locales/doc_auth/en.yml index baadbdb5fbb..5347946f7a8 100644 --- a/config/locales/doc_auth/en.yml +++ b/config/locales/doc_auth/en.yml @@ -181,7 +181,6 @@ en: your state‑issued ID. link_sent_complete_no_polling: When you are done, click Continue here to finish verifying your identity. link_sent_complete_polling: The next step will load automatically. - no_sp_name: The agency that you are trying to access privacy: '%{app_name} is a secure, government website that adheres to the highest standards in data protection. We use your data to verify your identity.' diff --git a/config/locales/doc_auth/es.yml b/config/locales/doc_auth/es.yml index 23371e23cdc..10df5315445 100644 --- a/config/locales/doc_auth/es.yml +++ b/config/locales/doc_auth/es.yml @@ -212,7 +212,6 @@ es: completar la verificación de tu identidad. link_sent_complete_polling: El siguiente paso se cargará automáticamente una vez que verifiques tu identidad a través de tu teléfono. - no_sp_name: La agencia a la que está intentando acceder privacy: '%{app_name} es un sitio web gubernamental seguro que cumple con las normas más estrictas de protección de datos. Utilizamos sus datos para verificar su identidad.' diff --git a/config/locales/doc_auth/fr.yml b/config/locales/doc_auth/fr.yml index af538d152be..f59c1c5a5ac 100644 --- a/config/locales/doc_auth/fr.yml +++ b/config/locales/doc_auth/fr.yml @@ -219,7 +219,6 @@ fr: link_sent_complete_polling: L’étape suivante se chargera automatiquement une fois que vous aurez confirmé votre identifiant à l’aide de votre téléphone. - no_sp_name: L’agence à laquelle vous essayez d’accéder privacy: '%{app_name} est un site gouvernemental sécurisé qui respecte les normes les plus strictes en matière de protection des données. Nous utilisons vos données pour vérifier votre identité.' From b44e98b19315274d437c34245783bb71ff0868e9 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Tue, 18 Jul 2023 16:36:05 -0700 Subject: [PATCH 22/27] Fix capitalization of APP_NAME in Welcome show template --- app/views/idv/welcome/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/idv/welcome/show.html.erb b/app/views/idv/welcome/show.html.erb index 63025fafef5..c5db6c7538a 100644 --- a/app/views/idv/welcome/show.html.erb +++ b/app/views/idv/welcome/show.html.erb @@ -12,7 +12,7 @@ <%= render 'shared/maintenance_window_alert' do %> <%= render JavascriptRequiredComponent.new( header: t('idv.welcome.no_js_header'), - intro: t('idv.welcome.no_js_intro', sp_name: decorated_session.sp_name || APP_Name), + intro: t('idv.welcome.no_js_intro', sp_name: decorated_session.sp_name || APP_NAME), ) do %> <% if @current_user&.reproof_for_irs?(service_provider: @current_sp) %> From f014e8b16e1903114270bc1db77448bd4f3348f4 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Wed, 19 Jul 2023 09:51:20 -0700 Subject: [PATCH 23/27] Add show template spec and external_redirect analytics spec Fix help center link by adding entry to MarketingSite Co-authored-by: Alexander Bradley --- app/services/marketing_site.rb | 1 + app/views/idv/getting_started/show.html.erb | 2 +- .../idv/doc_auth/getting_started_spec.rb | 17 ++- .../idv/getting_started/show.html.erb_spec.rb | 103 ++++++++++++++++++ 4 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 spec/views/idv/getting_started/show.html.erb_spec.rb diff --git a/app/services/marketing_site.rb b/app/services/marketing_site.rb index d18eba07056..02748dd4f5f 100644 --- a/app/services/marketing_site.rb +++ b/app/services/marketing_site.rb @@ -15,6 +15,7 @@ class MarketingSite verify-your-identity/verify-your-identity-in-person verify-your-identity/phone-number verify-your-identity/verify-your-address-by-mail + verify-your-identity/how-to-verify-your-identity ].to_set.freeze def self.locale_segment diff --git a/app/views/idv/getting_started/show.html.erb b/app/views/idv/getting_started/show.html.erb index f786d08c898..99d27e1b30e 100644 --- a/app/views/idv/getting_started/show.html.erb +++ b/app/views/idv/getting_started/show.html.erb @@ -37,7 +37,7 @@ article: 'how-to-verify-your-identity', flow: :idv, step: :getting_started, - location: 'you_will_need', + location: 'intro_paragraph', ), ), ) %> diff --git a/spec/features/idv/doc_auth/getting_started_spec.rb b/spec/features/idv/doc_auth/getting_started_spec.rb index 456183b06c2..28ecc9cfbf7 100644 --- a/spec/features/idv/doc_auth/getting_started_spec.rb +++ b/spec/features/idv/doc_auth/getting_started_spec.rb @@ -19,7 +19,7 @@ complete_doc_auth_steps_before_welcome_step end - it 'displays expected content', :js do + it 'displays expected content with javascript enabled', :js do expect(page).to have_current_path(idv_getting_started_path) # Try to continue with unchecked checkbox @@ -31,6 +31,21 @@ expect(page).to have_current_path(idv_hybrid_handoff_path) end + it 'logs "intro_paragraph" learn more link click' do + click_on t('doc_auth.info.getting_started_learn_more') + + expect(fake_analytics).to have_logged_event( + 'External Redirect', + step: 'getting_started', + location: 'intro_paragraph', + flow: 'idv', + redirect_url: MarketingSite.help_center_article_url( + category: 'verify-your-identity', + article: 'how-to-verify-your-identity', + ), + ) + end + context 'when JS is disabled' do it 'shows the notice if the user clicks continue without giving consent' do click_continue diff --git a/spec/views/idv/getting_started/show.html.erb_spec.rb b/spec/views/idv/getting_started/show.html.erb_spec.rb new file mode 100644 index 00000000000..ce936ad5262 --- /dev/null +++ b/spec/views/idv/getting_started/show.html.erb_spec.rb @@ -0,0 +1,103 @@ +require 'rails_helper' + +RSpec.describe 'idv/getting_started/show' do + let(:flow_session) { {} } + let(:user_fully_authenticated) { true } + let(:sp_name) { nil } + let(:user) { create(:user) } + + before do + @decorated_session = instance_double(ServiceProviderSessionDecorator) + @sp_name = 'Login.gov' + @title = t('doc_auth.headings.getting_started', sp_name: @sp_name) + 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(:user_fully_authenticated?).and_return(user_fully_authenticated) + allow(view).to receive(:user_signing_up?).and_return(false) + allow(view).to receive(:url_for).and_wrap_original do |method, *args, &block| + method.call(*args, &block) + rescue + '' + end + render + end + + context 'in doc auth with an authenticated user' do + let(:need_irs_reproofing) { false } + + before do + allow(user).to receive(:reproof_for_irs?).and_return(need_irs_reproofing) + assign(:current_user, user) + + render + end + + it 'does not render the IRS reproofing explanation' do + expect(rendered).not_to have_text(t('doc_auth.info.irs_reproofing_explanation')) + end + + it 'renders a link to return to the SP' do + expect(rendered).to have_link(t('links.cancel')) + end + + context 'when trying to log in to the IRS' do + let(:need_irs_reproofing) { true } + + it 'renders the IRS reproofing explanation' do + expect(rendered).to have_text(t('doc_auth.info.irs_reproofing_explanation')) + end + end + end + + context 'during the acuant maintenance window' do + let(:start) { Time.zone.parse('2020-01-01T00:00:00Z') } + let(:now) { Time.zone.parse('2020-01-01T12:00:00Z') } + let(:finish) { Time.zone.parse('2020-01-01T23:59:59Z') } + + before do + allow(IdentityConfig.store).to receive(:acuant_maintenance_window_start).and_return(start) + allow(IdentityConfig.store).to receive(:acuant_maintenance_window_finish).and_return(finish) + end + + around do |ex| + travel_to(now) { ex.run } + end + + it 'renders the warning banner but no other content' do + render + + expect(rendered).to have_content('We are currently under maintenance') + expect(rendered).to_not have_content(t('doc_auth.headings.welcome')) + end + end + + it 'includes code to track clicks on the consent checkbox' do + selector = [ + 'lg-click-observer[event-name="IdV: consent checkbox toggled"]', + '[name="doc_auth[ial2_consent_given]"]', + ].join ' ' + + expect(rendered).to have_css(selector) + end + + it 'renders a link to help center article' do + expect(rendered).to have_link( + t('doc_auth.info.getting_started_learn_more'), + href: help_center_redirect_path( + category: 'verify-your-identity', + article: 'how-to-verify-your-identity', + flow: :idv, + step: :getting_started, + location: 'you_will_need', + ), + ) + end + + it 'renders a link to the privacy & security page' do + expect(rendered).to have_link( + t('doc_auth.getting_started.instructions.learn_more'), + href: policy_redirect_url(flow: :idv, step: :getting_started, location: :consent), + ) + end +end From b20e2b8d9e89dab93f4a441c0cc114dc0c05549d Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Wed, 19 Jul 2023 11:31:58 -0700 Subject: [PATCH 24/27] Update spec to match analytics arg change --- spec/views/idv/getting_started/show.html.erb_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/views/idv/getting_started/show.html.erb_spec.rb b/spec/views/idv/getting_started/show.html.erb_spec.rb index ce936ad5262..769e4e3fb31 100644 --- a/spec/views/idv/getting_started/show.html.erb_spec.rb +++ b/spec/views/idv/getting_started/show.html.erb_spec.rb @@ -89,7 +89,7 @@ article: 'how-to-verify-your-identity', flow: :idv, step: :getting_started, - location: 'you_will_need', + location: 'intro_paragraph', ), ) end From 5fc58f2e5b4d1434abb76dbcc486b129c1033e15 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Wed, 19 Jul 2023 12:21:39 -0700 Subject: [PATCH 25/27] Change A/B test buckets to :welcome and :getting_started instead of :default and :new --- .../concerns/idv/getting_started_ab_test_concern.rb | 2 +- config/application.yml.default | 2 +- .../idv/getting_started_ab_test_concern_spec.rb | 12 ++++++------ spec/features/idv/doc_auth/getting_started_spec.rb | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/concerns/idv/getting_started_ab_test_concern.rb b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb index 2681d0011f0..fe7188ae48b 100644 --- a/app/controllers/concerns/idv/getting_started_ab_test_concern.rb +++ b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb @@ -5,7 +5,7 @@ def getting_started_a_b_test_bucket end def maybe_redirect_for_getting_started_ab_test - return if getting_started_a_b_test_bucket == :default + return if getting_started_a_b_test_bucket == :welcome redirect_to idv_getting_started_url end diff --git a/config/application.yml.default b/config/application.yml.default index 2e1be5272b3..e8f25192247 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -130,7 +130,7 @@ idv_acuant_sdk_version_default: '11.8.2' idv_acuant_sdk_version_alternate: '11.8.1' idv_acuant_sdk_upgrade_a_b_testing_enabled: false idv_acuant_sdk_upgrade_a_b_testing_percent: 50 -idv_getting_started_a_b_testing: '{"default":100,"new":0}' +idv_getting_started_a_b_testing: '{"welcome":100,"getting_started":0}' idv_send_link_attempt_window_in_minutes: 10 idv_send_link_max_attempts: 5 idv_tmx_test_csp_disabled_emails: '[]' diff --git a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb index e8654eab979..94e5f142eb8 100644 --- a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb +++ b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb @@ -28,22 +28,22 @@ def show allow(AbTests::IDV_GETTING_STARTED).to receive(:bucket) do |discriminator| case discriminator when 'session-id' - :default + :welcome when 'request-id' - :new + :getting_started end end end it 'returns the bucket based on session id' do - expect(controller.getting_started_a_b_test_bucket).to eq(:default) + expect(controller.getting_started_a_b_test_bucket).to eq(:welcome) end context 'with associated sp session request id' do let(:sp_session) { { request_id: 'request-id' } } it 'returns the bucket based on request id' do - expect(controller.getting_started_a_b_test_bucket).to eq(:new) + expect(controller.getting_started_a_b_test_bucket).to eq(:getting_started) end end end @@ -65,7 +65,7 @@ def show context 'A/B test specifies getting started page' do before do allow(controller).to receive(:getting_started_a_b_test_bucket). - and_return(:new) + and_return(:getting_started) end it 'redirects to idv_getting_started_url' do @@ -78,7 +78,7 @@ def show context 'A/B test specifies welcome page' do before do allow(controller).to receive(:getting_started_a_b_test_bucket). - and_return(:default) + and_return(:welcome) end it 'does not redirect users away from welcome page' do diff --git a/spec/features/idv/doc_auth/getting_started_spec.rb b/spec/features/idv/doc_auth/getting_started_spec.rb index 28ecc9cfbf7..58f1589a77e 100644 --- a/spec/features/idv/doc_auth/getting_started_spec.rb +++ b/spec/features/idv/doc_auth/getting_started_spec.rb @@ -12,7 +12,7 @@ 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) allow_any_instance_of(Idv::WelcomeController).to receive(:getting_started_a_b_test_bucket). - and_return(:new) + and_return(:getting_started) visit_idp_from_sp_with_ial2(:oidc) sign_in_and_2fa_user From 2d232238a18a947dc3fd9daf656403152d150554 Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Wed, 19 Jul 2023 12:37:37 -0700 Subject: [PATCH 26/27] Use FakeABTestBucket to avoid any_instance stub --- spec/features/idv/doc_auth/getting_started_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/idv/doc_auth/getting_started_spec.rb b/spec/features/idv/doc_auth/getting_started_spec.rb index 58f1589a77e..661ce15beeb 100644 --- a/spec/features/idv/doc_auth/getting_started_spec.rb +++ b/spec/features/idv/doc_auth/getting_started_spec.rb @@ -11,8 +11,8 @@ before do 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) - allow_any_instance_of(Idv::WelcomeController).to receive(:getting_started_a_b_test_bucket). - and_return(:getting_started) + stub_const('AbTests::IDV_GETTING_STARTED', FakeAbTestBucket.new) + AbTests::IDV_GETTING_STARTED.assign_all(:getting_started) visit_idp_from_sp_with_ial2(:oidc) sign_in_and_2fa_user From d1a4723ebe58aab963c9e8df44eb10804dfe38fe Mon Sep 17 00:00:00 2001 From: Sonia Connolly Date: Wed, 19 Jul 2023 13:53:09 -0700 Subject: [PATCH 27/27] Only redirect if bucket is :getting_started, stay on Welcome for all other values --- .../idv/getting_started_ab_test_concern.rb | 2 +- .../idv/getting_started_ab_test_concern_spec.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/controllers/concerns/idv/getting_started_ab_test_concern.rb b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb index fe7188ae48b..212404a699c 100644 --- a/app/controllers/concerns/idv/getting_started_ab_test_concern.rb +++ b/app/controllers/concerns/idv/getting_started_ab_test_concern.rb @@ -5,7 +5,7 @@ def getting_started_a_b_test_bucket end def maybe_redirect_for_getting_started_ab_test - return if getting_started_a_b_test_bucket == :welcome + return if getting_started_a_b_test_bucket != :getting_started redirect_to idv_getting_started_url end diff --git a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb index 94e5f142eb8..464e40ddf96 100644 --- a/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb +++ b/spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb @@ -88,5 +88,19 @@ def show expect(response.status).to eq(200) end end + + context 'A/B test specifies some other value' do + before do + allow(controller).to receive(:getting_started_a_b_test_bucket). + and_return(:something_else) + end + + it 'does not redirect users away from welcome page' do + get :show + + expect(response.body).to eq('Hello') + expect(response.status).to eq(200) + end + end end end