From 416001256b3c597941ba72f9d59e85a4ab27091b Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 13 Sep 2023 17:03:53 -0400 Subject: [PATCH 01/37] remove including dav from proof_resolution in agent --- app/controllers/concerns/idv/verify_info_concern.rb | 6 ------ app/services/idv/agent.rb | 6 ++---- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb index 9169af3cf40..5700a7b0be8 100644 --- a/app/controllers/concerns/idv/verify_info_concern.rb +++ b/app/controllers/concerns/idv/verify_info_concern.rb @@ -33,7 +33,6 @@ def shared_update user_id: current_user.id, threatmetrix_session_id: idv_session.threatmetrix_session_id, request_ip: request.remote_ip, - double_address_verification: capture_secondary_id_enabled, ) return true @@ -41,11 +40,6 @@ def shared_update private - def capture_secondary_id_enabled - current_user.establishing_in_person_enrollment&. - capture_secondary_id_enabled || false - end - def should_use_aamva?(pii) aamva_state?(pii) && !aamva_disallowed_for_service_provider? end diff --git a/app/services/idv/agent.rb b/app/services/idv/agent.rb index f606ea173f0..5d4ca4647c9 100644 --- a/app/services/idv/agent.rb +++ b/app/services/idv/agent.rb @@ -10,8 +10,7 @@ def proof_resolution( trace_id:, user_id:, threatmetrix_session_id:, - request_ip:, - double_address_verification: false + request_ip: ) document_capture_session.create_proofing_session @@ -26,8 +25,7 @@ def proof_resolution( result_id: document_capture_session.result_id, user_id: user_id, threatmetrix_session_id: threatmetrix_session_id, - request_ip: request_ip, - double_address_verification: double_address_verification, + request_ip: request_ip } if IdentityConfig.store.ruby_workers_idv_enabled From f4c4e2593bda7f7670056ac34d450328fa6ed9fa Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 13 Sep 2023 17:50:26 -0400 Subject: [PATCH 02/37] remove capture_secondary_id_enabled from address form, validator and step --- app/forms/idv/in_person/address_form.rb | 6 +-- .../idv/steps/in_person/address_step.rb | 16 ++----- .../idv/in_person/form_address_validator.rb | 3 -- app/views/idv/in_person/address.html.erb | 46 +------------------ spec/forms/idv/in_person/address_form_spec.rb | 31 ++++--------- 5 files changed, 15 insertions(+), 87 deletions(-) diff --git a/app/forms/idv/in_person/address_form.rb b/app/forms/idv/in_person/address_form.rb index 43d5b422cca..92849ae230c 100644 --- a/app/forms/idv/in_person/address_form.rb +++ b/app/forms/idv/in_person/address_form.rb @@ -8,8 +8,7 @@ class AddressForm attr_accessor(*ATTRIBUTES) - def initialize(capture_secondary_id_enabled:) - @capture_secondary_id_enabled = capture_secondary_id_enabled + def initialize end def self.model_name @@ -33,9 +32,6 @@ def submit(params) private - attr_reader :capture_secondary_id_enabled - alias_method :capture_secondary_id_enabled?, :capture_secondary_id_enabled - def consume_params(params) params.each do |key, value| raise_invalid_address_parameter_error(key) unless ATTRIBUTES.include?(key.to_sym) diff --git a/app/services/idv/steps/in_person/address_step.rb b/app/services/idv/steps/in_person/address_step.rb index 7b53f4943f7..7a28e11137b 100644 --- a/app/services/idv/steps/in_person/address_step.rb +++ b/app/services/idv/steps/in_person/address_step.rb @@ -9,20 +9,14 @@ def self.analytics_visited_event end def analytics_submitted_event - if capture_secondary_id_enabled? - :idv_in_person_proofing_residential_address_submitted - else - :idv_in_person_proofing_address_submitted - end + :idv_in_person_proofing_residential_address_submitted end def call attrs = Idv::InPerson::AddressForm::ATTRIBUTES - if capture_secondary_id_enabled? - attrs = attrs.difference([:same_address_as_id]) - flow_session[:pii_from_user][:same_address_as_id] = 'false' if updating_address? - end + attrs = attrs.difference([:same_address_as_id]) + flow_session[:pii_from_user][:same_address_as_id] = 'false' if updating_address? attrs.each do |attr| flow_session[:pii_from_user][attr] = flow_params[attr] @@ -35,7 +29,6 @@ def call def extra_view_variables { - capture_secondary_id_enabled: capture_secondary_id_enabled?, form:, pii:, updating_address: updating_address?, @@ -61,8 +54,7 @@ def flow_params end def form - @form ||= Idv::InPerson::AddressForm. - new(capture_secondary_id_enabled: capture_secondary_id_enabled?) + @form ||= Idv::InPerson::AddressForm.new end def form_submit diff --git a/app/validators/idv/in_person/form_address_validator.rb b/app/validators/idv/in_person/form_address_validator.rb index 928b377caff..d8072a0d6ca 100644 --- a/app/validators/idv/in_person/form_address_validator.rb +++ b/app/validators/idv/in_person/form_address_validator.rb @@ -5,9 +5,6 @@ module FormAddressValidator include Idv::FormAddressValidator included do - validates :same_address_as_id, - presence: true, - unless: :capture_secondary_id_enabled? validates_with UspsInPersonProofing::TransliterableValidator, fields: [:city], diff --git a/app/views/idv/in_person/address.html.erb b/app/views/idv/in_person/address.html.erb index f2b02c809a8..27760560c4b 100644 --- a/app/views/idv/in_person/address.html.erb +++ b/app/views/idv/in_person/address.html.erb @@ -6,24 +6,10 @@ <%= render PageHeadingComponent.new.with_content(t('in_person_proofing.headings.address')) %> <% end %> -<% unless capture_secondary_id_enabled %> -

- <%= t('in_person_proofing.body.address.info') %> - <%= new_tab_link_to( - t('in_person_proofing.body.address.learn_more'), - MarketingSite.help_center_article_url( - category: 'verify-your-identity', - article: 'verify-your-identity-in-person', - ), - ) %> -

-<% end %> - <%= simple_form_for( form, url: url_for, method: 'PUT', html: { autocomplete: 'off' } ) do |f| %> - <% if capture_secondary_id_enabled %> <%= render ValidatedFieldComponent.new( collection: us_states_territories, form: f, @@ -35,7 +21,6 @@ required: true, selected: pii[:state], ) %> - <% end %> <%= render ValidatedFieldComponent.new( form: f, hint: t('in_person_proofing.form.state_id.address1_hint'), @@ -52,7 +37,7 @@ hint: t('in_person_proofing.form.state_id.address2_hint'), hint_html: { class: ['display-none', 'puerto-rico-extras'] }, input_html: { value: pii[:address2] }, - label: capture_secondary_id_enabled ? t('idv.form.address2') : t('idv.form.address2_optional'), + label: t('idv.form.address2'), label_html: { class: 'usa-label' }, maxlength: 255, name: :address2, @@ -68,19 +53,6 @@ required: true, ) %> - <% unless capture_secondary_id_enabled %> - <%= render ValidatedFieldComponent.new( - collection: us_states_territories, - form: f, - label: t('idv.form.state'), - label_html: { class: 'usa-label' }, - name: :state, - prompt: t('in_person_proofing.form.address.state_prompt'), - required: true, - selected: pii[:state], - ) %> - <% end %> -
<%# using :tel for mobile numeric keypad %> <%= render ValidatedFieldComponent.new( @@ -96,22 +68,6 @@ ) %>
- <% unless capture_secondary_id_enabled %> - <%= render ValidatedFieldComponent.new( - as: :radio_buttons, - checked: pii[:same_address_as_id], - collection: [ - [t('in_person_proofing.form.address.same_address_choice_yes'), true], - [t('in_person_proofing.form.address.same_address_choice_no'), false], - ], - form: f, - label: t('in_person_proofing.form.address.same_address'), - name: :same_address_as_id, - required: true, - wrapper: :uswds_radio_buttons, - ) %> - <% end %> - <%= f.submit class: 'margin-top-1' do %> <% if updating_address %> <%= t('forms.buttons.submit.update') %> diff --git a/spec/forms/idv/in_person/address_form_spec.rb b/spec/forms/idv/in_person/address_form_spec.rb index f51daf033e3..fc6d284c5df 100644 --- a/spec/forms/idv/in_person/address_form_spec.rb +++ b/spec/forms/idv/in_person/address_form_spec.rb @@ -23,7 +23,7 @@ } end context 'when usps_ipp_transliteration_enabled is false' do - let(:subject) { described_class.new(capture_secondary_id_enabled: true) } + let(:subject) { described_class.new } before(:each) do allow(IdentityConfig.store).to receive(:usps_ipp_transliteration_enabled).and_return(false) end @@ -52,7 +52,7 @@ end end context 'when usps_ipp_transliteration_enabled is enabled ' do - let(:subject) { described_class.new(capture_secondary_id_enabled: true) } + let(:subject) { described_class.new } before(:each) do allow(IdentityConfig.store).to receive(:usps_ipp_transliteration_enabled).and_return(true) end @@ -77,26 +77,13 @@ before(:each) do allow(IdentityConfig.store).to receive(:usps_ipp_transliteration_enabled).and_return(true) end - context 'when capture_secondary_id_enabled is true' do - let(:subject) { described_class.new(capture_secondary_id_enabled: true) } - it 'submit with missing same_address_as_id should be successful' do - missing_required_params = good_params.except(:same_address_as_id) - result = subject.submit(missing_required_params) - expect(subject.errors.empty?).to be(true) - expect(result).to be_kind_of(FormResponse) - expect(result.success?).to be(true) - end - end - context 'when capture_secondary_id_enabled is false' do - let(:subject) { described_class.new(capture_secondary_id_enabled: false) } - it 'submit with missing same_address_as_id will fail' do - missing_required_params = good_params.except(:same_address_as_id) - result = subject.submit(missing_required_params) - expect(subject.errors.empty?).to be(false) - expect(result).to be_kind_of(FormResponse) - expect(result.success?).to be(false) - expect(result.errors.keys).to include(:same_address_as_id) - end + let(:subject) { described_class.new } + it 'submit with missing same_address_as_id should be successful' do + missing_required_params = good_params.except(:same_address_as_id) + result = subject.submit(missing_required_params) + expect(subject.errors.empty?).to be(true) + expect(result).to be_kind_of(FormResponse) + expect(result.success?).to be(true) end end end From 64d01c5a10c8073f73ff392e504135dfe665584b Mon Sep 17 00:00:00 2001 From: svalexander Date: Thu, 14 Sep 2023 17:04:31 -0400 Subject: [PATCH 03/37] remove dav and capture secondary id from verify info --- .../idv/in_person/verify_info_controller.rb | 1 - .../idv/in_person/verify_info/show.html.erb | 10 -- .../in_person/verify_info_controller_spec.rb | 136 ++---------------- 3 files changed, 11 insertions(+), 136 deletions(-) diff --git a/app/controllers/idv/in_person/verify_info_controller.rb b/app/controllers/idv/in_person/verify_info_controller.rb index 6ce2fc38a91..473aeaff6ac 100644 --- a/app/controllers/idv/in_person/verify_info_controller.rb +++ b/app/controllers/idv/in_person/verify_info_controller.rb @@ -13,7 +13,6 @@ class VerifyInfoController < ApplicationController def show @step_indicator_steps = step_indicator_steps @ssn = idv_session.ssn - @capture_secondary_id_enabled = capture_secondary_id_enabled analytics.idv_doc_auth_verify_visited(**analytics_arguments) Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]). diff --git a/app/views/idv/in_person/verify_info/show.html.erb b/app/views/idv/in_person/verify_info/show.html.erb index 25ea23ca778..016422cf450 100644 --- a/app/views/idv/in_person/verify_info/show.html.erb +++ b/app/views/idv/in_person/verify_info/show.html.erb @@ -25,11 +25,9 @@ locals:
- <% if @capture_secondary_id_enabled %>

<%= t('headings.state_id') %>

- <% end %>
<%= t('idv.form.first_name') %>:
<%= @pii[:first_name] %>
@@ -44,17 +42,14 @@ locals: <%= I18n.l(Date.parse(@pii[:dob]), format: I18n.t('time.formats.event_date')) %>
- <% if @capture_secondary_id_enabled %>
<%= t('idv.form.issuing_state') %>:
<%= @pii[:state_id_jurisdiction] %>
- <% end %>
<%= t('idv.form.id_number') %>:
<%= @pii[:state_id_number] %>
- <% if @capture_secondary_id_enabled %>
<%= t('idv.form.address1') %>:
<%= @pii[:identity_doc_address1] %>
@@ -75,7 +70,6 @@ locals:
<%= t('idv.form.zipcode') %>:
<%= @pii[:identity_doc_zipcode] %>
- <% end %>
<%= button_to( @@ -88,11 +82,9 @@ locals:
- <% if @capture_secondary_id_enabled %>

<%= t('headings.residential_address') %>

- <% end %>
<%= t('idv.form.address1') %>:
<%= @pii[:address1] %>
@@ -125,11 +117,9 @@ locals:
- <% if @capture_secondary_id_enabled %>

<%= t('headings.ssn') %>

- <% end %> <%= t('idv.form.ssn') %>: <%= render( 'shared/masked_text', diff --git a/spec/controllers/idv/in_person/verify_info_controller_spec.rb b/spec/controllers/idv/in_person/verify_info_controller_spec.rb index eeaca608221..f464766090d 100644 --- a/spec/controllers/idv/in_person/verify_info_controller_spec.rb +++ b/spec/controllers/idv/in_person/verify_info_controller_spec.rb @@ -123,137 +123,23 @@ end describe '#update' do + let(:pii_from_user) { Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS.dup } + let(:enrollment) { InPersonEnrollment.new } + before do + allow(user).to receive(:establishing_in_person_enrollment).and_return(enrollment) + end + it 'redirects to the expected page' do put :update expect(response).to redirect_to idv_in_person_verify_info_url end - context 'double address verification is not enabled' do - let(:capture_secondary_id_enabled) { false } - let(:enrollment) { InPersonEnrollment.new(capture_secondary_id_enabled:) } - before do - allow(user).to receive(:establishing_in_person_enrollment).and_return(enrollment) - end - - it 'sets uuid_prefix and state_id_type on pii_from_user' do - expect(Idv::Agent).to receive(:new). - with(hash_including(uuid_prefix: service_provider.app_id)).and_call_original - # our test data already has the expected value by default - flow_session[:pii_from_user].delete(:state_id_type) - - put :update - - expect(flow_session[:pii_from_user][:state_id_type]).to eq 'drivers_license' - expect(flow_session[:pii_from_user][:uuid_prefix]).to eq service_provider.app_id - end - - context 'a user does not have an establishing in person enrollment associated with them' do - before do - allow(user).to receive(:establishing_in_person_enrollment).and_return(nil) - end - - it 'disables double address verification for the user' do - expect_any_instance_of(Idv::Agent).to receive(:proof_resolution). - with( - kind_of(DocumentCaptureSession), - should_proof_state_id: anything, - trace_id: subject.send(:amzn_trace_id), - threatmetrix_session_id: nil, - user_id: anything, - request_ip: request.remote_ip, - double_address_verification: false, - ) - - put :update - end - end - - it 'passes the X-Amzn-Trace-Id to the proofer' do - expect_any_instance_of(Idv::Agent).to receive(:proof_resolution). - with( - kind_of(DocumentCaptureSession), - should_proof_state_id: anything, - trace_id: subject.send(:amzn_trace_id), - threatmetrix_session_id: nil, - user_id: anything, - request_ip: request.remote_ip, - double_address_verification: false, - ) - - put :update - end - - it 'only enqueues a job once' do - put :update - expect_any_instance_of(Idv::Agent).to_not receive(:proof_resolution) - - put :update - end - - context 'when pii_from_user is blank' do - it 'redirects' do - flow_session[:pii_from_user] = {} - put :update - expect(response.status).to eq 302 - end - end - - context 'when different users use the same SSN within the same timeframe' do - let(:user2) { create(:user) } - - before do - allow(IdentityConfig.store).to receive(:proof_ssn_max_attempts).and_return(3) - allow(IdentityConfig.store).to receive(:proof_ssn_max_attempt_window_in_minutes). - and_return(10) - end - - it 'rate limits them all' do - put :update - subject.idv_session.verify_info_step_document_capture_session_uuid = nil - put :update - subject.idv_session.verify_info_step_document_capture_session_uuid = nil - put :update - put :update - expect_any_instance_of(Idv::Agent).to_not receive(:proof_resolution) - expect(response).to redirect_to(idv_session_errors_ssn_failure_url) - subject.idv_session.verify_info_step_document_capture_session_uuid = nil - - stub_sign_in(user2) - put :update - expect_any_instance_of(Idv::Agent).to_not receive(:proof_resolution) - expect(response).to redirect_to(idv_session_errors_ssn_failure_url) - end - end - end - - context 'double address verification is enabled' do - let(:pii_from_user) { Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS.dup } - let(:capture_secondary_id_enabled) { true } - let(:enrollment) { InPersonEnrollment.new(capture_secondary_id_enabled:) } - before do - allow(user).to receive(:establishing_in_person_enrollment).and_return(enrollment) - end - it 'captures state id address fields in the pii' do - expect(Idv::Agent).to receive(:new). - with(Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS.merge(uuid_prefix: nil)). - and_call_original - put :update - end - - it 'indicates to the IDV agent that double_address_verification is enabled' do - expect_any_instance_of(Idv::Agent).to receive(:proof_resolution).with( - kind_of(DocumentCaptureSession), - should_proof_state_id: anything, - trace_id: anything, - threatmetrix_session_id: anything, - user_id: anything, - request_ip: anything, - double_address_verification: true, - ) - - put :update - end + it 'captures state id address fields in the pii' do + expect(Idv::Agent).to receive(:new). + with(Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS.merge(uuid_prefix: nil)). + and_call_original + put :update end end end From 1375409e77e441c236bfb4894e1693043798ddc1 Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 15 Sep 2023 09:48:38 -0400 Subject: [PATCH 04/37] lint fixes --- app/forms/idv/in_person/address_form.rb | 3 --- app/services/idv/agent.rb | 2 +- app/validators/idv/in_person/form_address_validator.rb | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/app/forms/idv/in_person/address_form.rb b/app/forms/idv/in_person/address_form.rb index 92849ae230c..6bfd7493462 100644 --- a/app/forms/idv/in_person/address_form.rb +++ b/app/forms/idv/in_person/address_form.rb @@ -8,9 +8,6 @@ class AddressForm attr_accessor(*ATTRIBUTES) - def initialize - end - def self.model_name ActiveModel::Name.new(self, nil, 'InPersonAddress') end diff --git a/app/services/idv/agent.rb b/app/services/idv/agent.rb index 5d4ca4647c9..4dde23c1c32 100644 --- a/app/services/idv/agent.rb +++ b/app/services/idv/agent.rb @@ -25,7 +25,7 @@ def proof_resolution( result_id: document_capture_session.result_id, user_id: user_id, threatmetrix_session_id: threatmetrix_session_id, - request_ip: request_ip + request_ip: request_ip, } if IdentityConfig.store.ruby_workers_idv_enabled diff --git a/app/validators/idv/in_person/form_address_validator.rb b/app/validators/idv/in_person/form_address_validator.rb index d8072a0d6ca..00a44ca4d36 100644 --- a/app/validators/idv/in_person/form_address_validator.rb +++ b/app/validators/idv/in_person/form_address_validator.rb @@ -5,7 +5,6 @@ module FormAddressValidator include Idv::FormAddressValidator included do - validates_with UspsInPersonProofing::TransliterableValidator, fields: [:city], reject_chars: /[^A-Za-z\-' ]/, From d9b5b12e5fe30f54fa1797a2bba8fc14e71fbd4a Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 15 Sep 2023 10:20:29 -0400 Subject: [PATCH 05/37] remove capture_secondary_id from state id step --- app/forms/idv/state_id_form.rb | 6 +-- .../idv/steps/in_person/state_id_step.rb | 28 ++++------ app/validators/idv/form_state_id_validator.rb | 7 +-- app/views/idv/in_person/state_id.html.erb | 21 -------- .../idv/steps/in_person/state_id_step_spec.rb | 52 ++++++++----------- spec/forms/idv/state_id_form_spec.rb | 3 +- spec/support/features/in_person_helper.rb | 26 +++++----- 7 files changed, 49 insertions(+), 94 deletions(-) diff --git a/app/forms/idv/state_id_form.rb b/app/forms/idv/state_id_form.rb index 3f80e517ca3..2225225344a 100644 --- a/app/forms/idv/state_id_form.rb +++ b/app/forms/idv/state_id_form.rb @@ -13,9 +13,8 @@ def self.model_name ActiveModel::Name.new(self, nil, 'StateId') end - def initialize(pii, capture_secondary_id_enabled:) + def initialize(pii) @pii = pii - @capture_secondary_id_enabled = capture_secondary_id_enabled end def submit(params) @@ -36,9 +35,6 @@ def submit(params) private - attr_reader :capture_secondary_id_enabled - alias_method :capture_secondary_id_enabled?, :capture_secondary_id_enabled - def consume_params(params) params.each do |key, value| raise_invalid_state_id_parameter_error(key) unless ATTRIBUTES.include?(key.to_sym) diff --git a/app/services/idv/steps/in_person/state_id_step.rb b/app/services/idv/steps/in_person/state_id_step.rb index 872387abe32..c3079c55468 100644 --- a/app/services/idv/steps/in_person/state_id_step.rb +++ b/app/services/idv/steps/in_person/state_id_step.rb @@ -23,20 +23,18 @@ def call formatted_dob = MemorableDateComponent.extract_date_param flow_params&.[](:dob) pii_from_user[:dob] = formatted_dob if formatted_dob - if capture_secondary_id_enabled? - if pii_from_user[:same_address_as_id] == 'true' - copy_state_id_address_to_residential_address(pii_from_user) - mark_step_complete(:address) - redirect_to idv_in_person_ssn_url - end - - if initial_state_of_same_address_as_id == 'true' && - pii_from_user[:same_address_as_id] == 'false' - clear_residential_address(pii_from_user) - mark_step_incomplete(:address) - end + if pii_from_user[:same_address_as_id] == 'true' + copy_state_id_address_to_residential_address(pii_from_user) + mark_step_complete(:address) + redirect_to idv_in_person_ssn_url end + if initial_state_of_same_address_as_id == 'true' && + pii_from_user[:same_address_as_id] == 'false' + clear_residential_address(pii_from_user) + mark_step_incomplete(:address) + end + if flow_session['Idv::Steps::InPerson::AddressStep'] redirect_to idv_in_person_verify_info_url end @@ -44,7 +42,6 @@ def call def extra_view_variables { - capture_secondary_id_enabled: capture_secondary_id_enabled?, form:, pii:, parsed_dob:, @@ -104,10 +101,7 @@ def flow_params end def form - @form ||= Idv::StateIdForm.new( - current_user, - capture_secondary_id_enabled: capture_secondary_id_enabled?, - ) + @form ||= Idv::StateIdForm.new(current_user) end def form_submit diff --git a/app/validators/idv/form_state_id_validator.rb b/app/validators/idv/form_state_id_validator.rb index cb993bae471..62dbe02e3e1 100644 --- a/app/validators/idv/form_state_id_validator.rb +++ b/app/validators/idv/form_state_id_validator.rb @@ -7,15 +7,12 @@ module FormStateIdValidator validates :first_name, :last_name, :dob, + :identity_doc_address1, + :identity_doc_city, :state_id_jurisdiction, :state_id_number, presence: true - validates :identity_doc_address1, - :identity_doc_city, - presence: true, - if: :capture_secondary_id_enabled? - validates_with UspsInPersonProofing::TransliterableValidator, fields: [:first_name, :last_name, :identity_doc_city], reject_chars: /[^A-Za-z\-' ]/, diff --git a/app/views/idv/in_person/state_id.html.erb b/app/views/idv/in_person/state_id.html.erb index fed60a92539..3112f918ce9 100644 --- a/app/views/idv/in_person/state_id.html.erb +++ b/app/views/idv/in_person/state_id.html.erb @@ -96,7 +96,6 @@ %>
- <% if capture_secondary_id_enabled %>
<%= render ValidatedFieldComponent.new( name: :state_id_jurisdiction, @@ -110,7 +109,6 @@ selected: pii[:state_id_jurisdiction], ) %>
- <% end %>
<%= render ValidatedFieldComponent.new( name: :state_id_number, @@ -125,7 +123,6 @@ ) %>
- <% if capture_secondary_id_enabled %>

<%= t('in_person_proofing.headings.id_address') %>

<%= render ValidatedFieldComponent.new( name: :identity_doc_address_state, @@ -171,23 +168,6 @@ maxlength: 255, required: true, ) %> - <% end %> - <% unless capture_secondary_id_enabled %> -
- <%= render ValidatedFieldComponent.new( - name: :state_id_jurisdiction, - collection: us_states_territories, - form: f, - hint: t('in_person_proofing.form.state_id.identity_doc_address_state_hint'), - label: t('in_person_proofing.form.state_id.state_id_jurisdiction'), - label_html: { class: 'usa-label' }, - prompt: t('in_person_proofing.form.state_id.state_id_jurisdiction_prompt'), - required: true, - selected: pii[:state_id_jurisdiction], - ) %> -
- <% end %> - <% if capture_secondary_id_enabled %>
<%# using :tel for mobile numeric keypad %> <%= render ValidatedFieldComponent.new( @@ -216,7 +196,6 @@ required: true, wrapper: :uswds_radio_buttons, ) %> - <% end %> <%= f.submit do %> <% if updating_state_id %> diff --git a/spec/features/idv/steps/in_person/state_id_step_spec.rb b/spec/features/idv/steps/in_person/state_id_step_spec.rb index a265174d37f..aa774a0477a 100644 --- a/spec/features/idv/steps/in_person/state_id_step_spec.rb +++ b/spec/features/idv/steps/in_person/state_id_step_spec.rb @@ -8,36 +8,28 @@ allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) end - context 'capture secondary id is enabled' do - before do - allow(IdentityConfig.store). - to(receive(:in_person_capture_secondary_id_enabled)). - and_return(true) - end + it 'validates zip code input', allow_browser_log: true do + user = user_with_2fa - it 'validates zip code input', allow_browser_log: true do - user = user_with_2fa - - sign_in_and_2fa_user(user) - begin_in_person_proofing(user) - complete_prepare_step(user) - complete_location_step(user) - expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) - fill_out_state_id_form_ok(same_address_as_id: true, capture_secondary_id_enabled: true) - # blank out the zip code field - fill_in t('in_person_proofing.form.state_id.zipcode'), with: '' - # try to enter invalid input into the zip code field - fill_in t('in_person_proofing.form.state_id.zipcode'), with: 'invalid input' - expect(page).to have_field(t('in_person_proofing.form.state_id.zipcode'), with: '') - # enter valid characters, but invalid length - fill_in t('in_person_proofing.form.state_id.zipcode'), with: '123' - click_idv_continue - expect(page).to have_css('.usa-error-message', text: t('idv.errors.pattern_mismatch.zipcode')) - # enter a valid zip and make sure we can continue - fill_in t('in_person_proofing.form.state_id.zipcode'), with: '123456789' - expect(page).to have_field(t('in_person_proofing.form.state_id.zipcode'), with: '12345-6789') - click_idv_continue - expect(page).to have_current_path(idv_in_person_ssn_url) - end + sign_in_and_2fa_user(user) + begin_in_person_proofing(user) + complete_prepare_step(user) + complete_location_step(user) + expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) + fill_out_state_id_form_ok(same_address_as_id: true) + # blank out the zip code field + fill_in t('in_person_proofing.form.state_id.zipcode'), with: '' + # try to enter invalid input into the zip code field + fill_in t('in_person_proofing.form.state_id.zipcode'), with: 'invalid input' + expect(page).to have_field(t('in_person_proofing.form.state_id.zipcode'), with: '') + # enter valid characters, but invalid length + fill_in t('in_person_proofing.form.state_id.zipcode'), with: '123' + click_idv_continue + expect(page).to have_css('.usa-error-message', text: t('idv.errors.pattern_mismatch.zipcode')) + # enter a valid zip and make sure we can continue + fill_in t('in_person_proofing.form.state_id.zipcode'), with: '123456789' + expect(page).to have_field(t('in_person_proofing.form.state_id.zipcode'), with: '12345-6789') + click_idv_continue + expect(page).to have_current_path(idv_in_person_ssn_url) end end diff --git a/spec/forms/idv/state_id_form_spec.rb b/spec/forms/idv/state_id_form_spec.rb index a2d371c481d..7e2fadb21a5 100644 --- a/spec/forms/idv/state_id_form_spec.rb +++ b/spec/forms/idv/state_id_form_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' RSpec.describe Idv::StateIdForm do - let(:subject) { Idv::StateIdForm.new(pii, capture_secondary_id_enabled:) } + let(:subject) { Idv::StateIdForm.new(pii) } let(:valid_dob) do valid_d = Time.zone.today - IdentityConfig.store.idv_min_age_years.years - 1.day ActionController::Parameters.new( @@ -62,7 +62,6 @@ } end let(:pii) { nil } - let(:capture_secondary_id_enabled) { true } describe '#submit' do context 'when the form is valid' do it 'returns a successful form response' do diff --git a/spec/support/features/in_person_helper.rb b/spec/support/features/in_person_helper.rb index 8f856af732e..65cee16e857 100644 --- a/spec/support/features/in_person_helper.rb +++ b/spec/support/features/in_person_helper.rb @@ -31,7 +31,7 @@ module InPersonHelper GOOD_IDENTITY_DOC_ZIPCODE = Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_zipcode] - def fill_out_state_id_form_ok(same_address_as_id: false, capture_secondary_id_enabled: false) + def fill_out_state_id_form_ok(same_address_as_id: false) fill_in t('in_person_proofing.form.state_id.first_name'), with: GOOD_FIRST_NAME fill_in t('in_person_proofing.form.state_id.last_name'), with: GOOD_LAST_NAME year, month, day = GOOD_DOB.split('-') @@ -42,19 +42,17 @@ def fill_out_state_id_form_ok(same_address_as_id: false, capture_secondary_id_en from: t('in_person_proofing.form.state_id.state_id_jurisdiction') fill_in t('in_person_proofing.form.state_id.state_id_number'), with: GOOD_STATE_ID_NUMBER - if capture_secondary_id_enabled - fill_in t('in_person_proofing.form.state_id.address1'), with: GOOD_IDENTITY_DOC_ADDRESS1 - fill_in t('in_person_proofing.form.state_id.address2'), with: GOOD_IDENTITY_DOC_ADDRESS2 - fill_in t('in_person_proofing.form.state_id.city'), with: GOOD_IDENTITY_DOC_CITY - fill_in t('in_person_proofing.form.state_id.zipcode'), with: GOOD_IDENTITY_DOC_ZIPCODE - if same_address_as_id - select GOOD_IDENTITY_DOC_ADDRESS_STATE, - from: t('in_person_proofing.form.state_id.identity_doc_address_state') - choose t('in_person_proofing.form.state_id.same_address_as_id_yes') - else - select GOOD_STATE, from: t('in_person_proofing.form.state_id.identity_doc_address_state') - choose t('in_person_proofing.form.state_id.same_address_as_id_no') - end + fill_in t('in_person_proofing.form.state_id.address1'), with: GOOD_IDENTITY_DOC_ADDRESS1 + fill_in t('in_person_proofing.form.state_id.address2'), with: GOOD_IDENTITY_DOC_ADDRESS2 + fill_in t('in_person_proofing.form.state_id.city'), with: GOOD_IDENTITY_DOC_CITY + fill_in t('in_person_proofing.form.state_id.zipcode'), with: GOOD_IDENTITY_DOC_ZIPCODE + if same_address_as_id + select GOOD_IDENTITY_DOC_ADDRESS_STATE, + from: t('in_person_proofing.form.state_id.identity_doc_address_state') + choose t('in_person_proofing.form.state_id.same_address_as_id_yes') + else + select GOOD_STATE, from: t('in_person_proofing.form.state_id.identity_doc_address_state') + choose t('in_person_proofing.form.state_id.same_address_as_id_no') end end From 594883b3f98f4b3da346d02961d7fd04faa69d2b Mon Sep 17 00:00:00 2001 From: svalexander Date: Mon, 18 Sep 2023 10:48:27 -0400 Subject: [PATCH 06/37] update in person spec and helper --- spec/features/idv/in_person_spec.rb | 819 +++++++++------------- spec/support/features/in_person_helper.rb | 69 +- 2 files changed, 386 insertions(+), 502 deletions(-) diff --git a/spec/features/idv/in_person_spec.rb b/spec/features/idv/in_person_spec.rb index 14fe80b0713..d73385ebc91 100644 --- a/spec/features/idv/in_person_spec.rb +++ b/spec/features/idv/in_person_spec.rb @@ -8,8 +8,6 @@ before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(false) end context 'ThreatMetrix review pending' do @@ -32,9 +30,6 @@ # state ID page complete_state_id_step(user) - # address page - complete_address_step(user) - # ssn page select 'Reject', from: :mock_profiling_result complete_ssn_step(user) @@ -47,10 +42,14 @@ expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME) expect(page).to have_text(InPersonHelper::GOOD_DOB_FORMATTED_EVENT) expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER) - expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1) - expect(page).to have_text(InPersonHelper::GOOD_CITY) - expect(page).to have_text(InPersonHelper::GOOD_ZIPCODE) - expect(page).to have_text(Idp::Constants::MOCK_IDV_APPLICANT[:state]) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS1).twice + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS2).twice + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_CITY).twice + expect(page).to have_text( + Idp::Constants::MOCK_IDV_APPLICANT[:state_id_jurisdiction], + count: 3, + ) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ZIPCODE).twice expect(page).to have_text(DocAuthHelper::GOOD_SSN_MASKED) complete_verify_step(user) @@ -138,12 +137,6 @@ ) complete_state_id_step(user) - # address page - expect_in_person_step_indicator_current_step(t('step_indicator.flows.idv.verify_info')) - expect(page).to have_content(t('in_person_proofing.headings.address')) - expect(page).to have_content(t('in_person_proofing.form.address.same_address').tr(' ', ' ')) - complete_address_step(user) - # ssn page expect_in_person_step_indicator_current_step(t('step_indicator.flows.idv.verify_info')) expect(page).to have_content(t('doc_auth.headings.ssn')) @@ -157,15 +150,17 @@ expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME) expect(page).to have_text(InPersonHelper::GOOD_DOB_FORMATTED_EVENT) expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER) - expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1) - expect(page).to have_text(InPersonHelper::GOOD_CITY) - expect(page).to have_text(InPersonHelper::GOOD_ZIPCODE) - expect(page).to have_text(Idp::Constants::MOCK_IDV_APPLICANT[:state]) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS1).twice + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS2).twice + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_CITY).twice + expect(page).to have_text(Idp::Constants::MOCK_IDV_APPLICANT[:state_id_jurisdiction], count: 3) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ZIPCODE).twice expect(page).to have_text(DocAuthHelper::GOOD_SSN_MASKED) # click update state ID button click_button t('idv.buttons.change_state_id_label') expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + choose t('in_person_proofing.form.state_id.same_address_as_id_yes') click_button t('forms.buttons.submit.update') expect(page).to have_content(t('headings.verify')) expect(page).to have_current_path(idv_in_person_verify_info_path) @@ -173,7 +168,6 @@ # click update address button click_button t('idv.buttons.change_address_label') expect(page).to have_content(t('in_person_proofing.headings.update_address')) - choose t('in_person_proofing.form.address.same_address_choice_yes') click_button t('forms.buttons.submit.update') expect(page).to have_content(t('headings.verify')) expect(page).to have_current_path(idv_in_person_verify_info_path) @@ -324,7 +318,8 @@ end end - it 'resumes desktop session with in-person proofing', allow_browser_log: true do + it 'resumes desktop session with in-person proofing when same_address_as_id is true', + allow_browser_log: true do user = nil perform_in_browser(:desktop) do @@ -338,38 +333,27 @@ expect(@sms_link).to be_present - perform_in_browser(:mobile) do - # doc auth page - visit @sms_link - mock_doc_auth_attention_with_barcode - attach_and_submit_images - - # error page - click_button t('in_person_proofing.body.cta.button') - # prepare page - expect(page).to(have_content(t('in_person_proofing.body.prepare.verify_step_about'))) - click_idv_continue - # location page - expect(page).to have_content(t('in_person_proofing.headings.po_search.location')) - complete_location_step - - # switch back page - expect(page).to have_content(t('in_person_proofing.headings.switch_back')) - end + perform_mobile_hybrid_steps + perform_desktop_hybrid_steps(user) + end + + it 'resumes desktop session with in-person proofing when same_address_as_id is false', + allow_browser_log: true do + user = nil perform_in_browser(:desktop) do - expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) - - complete_state_id_step(user) - complete_address_step(user) - complete_ssn_step(user) - complete_verify_step(user) - complete_phone_step(user) - complete_review_step(user) - acknowledge_and_confirm_personal_key + user = sign_in_and_2fa_user + complete_doc_auth_steps_before_hybrid_handoff_step + clear_and_fill_in(:doc_auth_phone, '415-555-0199') + click_send_link - expect(page).to have_content('MILWAUKEE') + expect(page).to have_content(t('doc_auth.headings.text_message')) end + + expect(@sms_link).to be_present + + perform_mobile_hybrid_steps + perform_desktop_hybrid_steps(user, same_address_as_id: false) end end @@ -435,333 +419,213 @@ and_return(true) end - context 'with double address verification' do - let(:capture_secondary_id_enabled) { true } - let(:double_address_verification) { true } - let(:user) { user_with_2fa } - let(:enrollment) { InPersonEnrollment.new(capture_secondary_id_enabled:) } - - before do - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(true) - allow(user).to receive(:establishing_in_person_enrollment). - and_return(enrollment) - end - - it 'shows validation errors when double address verification is true', - allow_browser_log: true do - sign_in_and_2fa_user - begin_in_person_proofing - complete_prepare_step - complete_location_step - expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) - - fill_out_state_id_form_ok(capture_secondary_id_enabled: capture_secondary_id_enabled) - fill_in t('in_person_proofing.form.state_id.first_name'), with: 'T0mmy "Lee"' - fill_in t('in_person_proofing.form.state_id.last_name'), with: 'Джейкоб' - fill_in t('in_person_proofing.form.state_id.address1'), with: '#1 $treet' - fill_in t('in_person_proofing.form.state_id.address2'), with: 'Gr@nd Lañe^' - fill_in t('in_person_proofing.form.state_id.city'), with: 'B3st C!ty' - click_idv_continue - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.state_id.errors.unsupported_chars', - char_list: '", 0', - ), - ) - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.state_id.errors.unsupported_chars', - char_list: 'Д, б, е, ж, й, к, о', - ), - ) - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.state_id.errors.unsupported_chars', - char_list: '$', - ), - ) - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.state_id.errors.unsupported_chars', - char_list: '@, ^', - ), - ) - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.state_id.errors.unsupported_chars', - char_list: '!, 3', - ), - ) - - # re-fill state id form with good inputs - fill_in t('in_person_proofing.form.state_id.first_name'), - with: InPersonHelper::GOOD_FIRST_NAME - fill_in t('in_person_proofing.form.state_id.last_name'), - with: InPersonHelper::GOOD_LAST_NAME - fill_in t('in_person_proofing.form.state_id.address1'), - with: InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS1 - fill_in t('in_person_proofing.form.state_id.address2'), - with: InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS2 - fill_in t('in_person_proofing.form.state_id.city'), - with: InPersonHelper::GOOD_IDENTITY_DOC_CITY - click_idv_continue - - expect(page).to have_current_path(idv_in_person_step_path(step: :address), wait: 10) - end + let(:user) { user_with_2fa } + let(:enrollment) { InPersonEnrollment.new } - it 'shows hints when user selects Puerto Rico as state', - allow_browser_log: true do - sign_in_and_2fa_user - begin_in_person_proofing - complete_prepare_step - complete_location_step - expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) - - # state id page - select 'Puerto Rico', - from: t('in_person_proofing.form.state_id.identity_doc_address_state') - - expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) - expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) - - # change state selection - fill_out_state_id_form_ok(capture_secondary_id_enabled: true) - expect(page).not_to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) - expect(page).not_to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) - - # re-select puerto rico - select 'Puerto Rico', - from: t('in_person_proofing.form.state_id.identity_doc_address_state') - click_idv_continue - - expect(page).to have_current_path(idv_in_person_step_path(step: :address)) - - # address form - select 'Puerto Rico', - from: t('idv.form.state') - expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) - expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) - - # change selection - fill_out_address_form_ok(double_address_verification: true) - expect(page).not_to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) - expect(page).not_to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) - - # re-select puerto rico - select 'Puerto Rico', - from: t('idv.form.state') - click_idv_continue - - # ssn page - expect(page).to have_current_path(idv_in_person_ssn_url) - complete_ssn_step - - # verify page - expect(page).to have_current_path(idv_in_person_verify_info_path) - expect(page).to have_text('PR').twice - - # update state ID - click_button t('idv.buttons.change_state_id_label') - - expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) - expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) - expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) - click_button t('forms.buttons.submit.update') - - # update address - click_button t('idv.buttons.change_address_label') - - expect(page).to have_content(t('in_person_proofing.headings.update_address')) - expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) - expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) - end + before do + allow(user).to receive(:establishing_in_person_enrollment). + and_return(enrollment) end - context 'without double address verification' do - it 'shows validation errors when double address verification is false', - allow_browser_log: true do - sign_in_and_2fa_user - begin_in_person_proofing - complete_prepare_step - complete_location_step - expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) - - fill_out_state_id_form_ok - fill_in t('in_person_proofing.form.state_id.first_name'), with: 'T0mmy "Lee"' - fill_in t('in_person_proofing.form.state_id.last_name'), with: 'Джейкоб' - click_idv_continue - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.state_id.errors.unsupported_chars', - char_list: '", 0', - ), - ) - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.state_id.errors.unsupported_chars', - char_list: 'Д, б, е, ж, й, к, о', - ), - ) - - # re-fill form with good inputs - fill_in t('in_person_proofing.form.state_id.first_name'), - with: InPersonHelper::GOOD_FIRST_NAME - fill_in t('in_person_proofing.form.state_id.last_name'), - with: InPersonHelper::GOOD_LAST_NAME - click_idv_continue - - expect(page).to have_current_path(idv_in_person_step_path(step: :address), wait: 10) - fill_out_address_form_ok - - fill_in t('idv.form.address1'), with: 'Джордж' - fill_in t('idv.form.address2_optional'), with: '(Nope) = %' - fill_in t('idv.form.city'), with: 'Елена' - click_idv_continue - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.address.errors.unsupported_chars', - char_list: 'Д, д, ж, о, р', - ), - ) - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.address.errors.unsupported_chars', - char_list: '%, (, ), =', - ), - ) - - expect(page).to have_content( - I18n.t( - 'in_person_proofing.form.address.errors.unsupported_chars', - char_list: 'Е, а, е, л, н', - ), - ) - - # re-fill form with good inputs - fill_in t('idv.form.address1'), with: InPersonHelper::GOOD_ADDRESS1 - fill_in t('idv.form.address2_optional'), with: InPersonHelper::GOOD_ADDRESS2 - fill_in t('idv.form.city'), with: InPersonHelper::GOOD_CITY - click_idv_continue - expect(page).to have_current_path(idv_in_person_ssn_url, wait: 10) - end - end - end + it 'shows validation errors', + allow_browser_log: true do + sign_in_and_2fa_user + begin_in_person_proofing + complete_prepare_step + complete_location_step + expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) + + fill_out_state_id_form_ok + fill_in t('in_person_proofing.form.state_id.first_name'), with: 'T0mmy "Lee"' + fill_in t('in_person_proofing.form.state_id.last_name'), with: 'Джейкоб' + fill_in t('in_person_proofing.form.state_id.address1'), with: '#1 $treet' + fill_in t('in_person_proofing.form.state_id.address2'), with: 'Gr@nd Lañe^' + fill_in t('in_person_proofing.form.state_id.city'), with: 'B3st C!ty' + click_idv_continue - context 'in_person_capture_secondary_id_enabled feature flag disabled, then enabled during flow', - allow_browser_log: true do - let(:user) { user_with_2fa } + expect(page).to have_content( + I18n.t( + 'in_person_proofing.form.state_id.errors.unsupported_chars', + char_list: '", 0', + ), + ) - before(:each) do - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(false) + expect(page).to have_content( + I18n.t( + 'in_person_proofing.form.state_id.errors.unsupported_chars', + char_list: 'Д, б, е, ж, й, к, о', + ), + ) - sign_in_and_2fa_user(user) - begin_in_person_proofing(user) - complete_prepare_step(user) - complete_location_step(user) + expect(page).to have_content( + I18n.t( + 'in_person_proofing.form.state_id.errors.unsupported_chars', + char_list: '$', + ), + ) + + expect(page).to have_content( + I18n.t( + 'in_person_proofing.form.state_id.errors.unsupported_chars', + char_list: '@, ^', + ), + ) + + expect(page).to have_content( + I18n.t( + 'in_person_proofing.form.state_id.errors.unsupported_chars', + char_list: '!, 3', + ), + ) + + # re-fill state id form with good inputs + fill_in t('in_person_proofing.form.state_id.first_name'), + with: InPersonHelper::GOOD_FIRST_NAME + fill_in t('in_person_proofing.form.state_id.last_name'), + with: InPersonHelper::GOOD_LAST_NAME + fill_in t('in_person_proofing.form.state_id.address1'), + with: InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS1 + fill_in t('in_person_proofing.form.state_id.address2'), + with: InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS2 + fill_in t('in_person_proofing.form.state_id.city'), + with: InPersonHelper::GOOD_IDENTITY_DOC_CITY + click_idv_continue + + expect(page).to have_current_path(idv_in_person_step_path(step: :address), wait: 10) end - it 'does not capture separate state id address from residential address' do - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(true) - complete_state_id_step(user) - complete_address_step(user) - complete_ssn_step(user) + it 'shows hints when user selects Puerto Rico as state', + allow_browser_log: true do + sign_in_and_2fa_user + begin_in_person_proofing + complete_prepare_step + complete_location_step + expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) + + # state id page + select 'Puerto Rico', + from: t('in_person_proofing.form.state_id.identity_doc_address_state') + + expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) + expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) + + # change state selection + fill_out_state_id_form_ok + expect(page).not_to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) + expect(page).not_to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) + + # re-select puerto rico + select 'Puerto Rico', + from: t('in_person_proofing.form.state_id.identity_doc_address_state') + click_idv_continue + + expect(page).to have_current_path(idv_in_person_step_path(step: :address)) + + # address form + select 'Puerto Rico', + from: t('idv.form.state') + expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) + expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) + + # change selection + fill_out_address_form_ok + expect(page).not_to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) + expect(page).not_to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) + + # re-select puerto rico + select 'Puerto Rico', + from: t('idv.form.state') + click_idv_continue + + # ssn page + expect(page).to have_current_path(idv_in_person_ssn_url) + complete_ssn_step + + # verify page + expect(page).to have_current_path(idv_in_person_verify_info_path) + expect(page).to have_text('PR').twice + + # update state ID + click_button t('idv.buttons.change_state_id_label') + + expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) + expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) + click_button t('forms.buttons.submit.update') + + # update address + click_button t('idv.buttons.change_address_label') + + expect(page).to have_content(t('in_person_proofing.headings.update_address')) + expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address1_hint')) + expect(page).to have_content(I18n.t('in_person_proofing.form.state_id.address2_hint')) end end - shared_examples 'captures address with state id' do + context 'same address as id is false', + allow_browser_log: true do let(:user) { user_with_2fa } before(:each) do - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(true) - sign_in_and_2fa_user(user) begin_in_person_proofing(user) complete_prepare_step(user) complete_location_step(user) end - it 'successfully proceeds through the flow' do - complete_state_id_step( - user, same_address_as_id: false, capture_secondary_id_enabled: true - ) - complete_address_step(user, double_address_verification: true) + it 'shows the address page' do + complete_state_id_step(user, same_address_as_id: false) + expect_in_person_step_indicator_current_step(t('step_indicator.flows.idv.verify_info')) + expect(page).to have_content(t('in_person_proofing.headings.address')) + + # arrive at address step + complete_address_step(user, same_address_as_id: false) + complete_ssn_step(user) # Ensure the page submitted successfully expect(page).to have_content(t('idv.form.ssn_label')) end - end - - context 'in_person_capture_secondary_id_enabled feature flag enabled', allow_browser_log: true do - context 'flag remains enabled' do - it_behaves_like 'captures address with state id' - end - - context 'flag is then disabled' do - before(:each) do - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(false) - end - it_behaves_like 'captures address with state id' + it 'can update the address page form' do + complete_state_id_step(user, same_address_as_id: false) + complete_address_step(user, same_address_as_id: false) + complete_ssn_step(user) + # click update address button on the verify page + click_button t('idv.buttons.change_address_label') + expect(page).to have_content(t('in_person_proofing.headings.update_address')) + fill_out_address_form_ok(same_address_as_id: true) + click_button t('forms.buttons.submit.update') + expect(page).to have_content(t('headings.verify')) + expect(page).to have_current_path(idv_in_person_verify_info_path) end end - context 'in_person_capture_secondary_id_enabled feature flag enabled and same address as id', + context 'same address as id is true then update is selected on verify info pg', allow_browser_log: true do let(:user) { user_with_2fa } before(:each) do - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(true) - sign_in_and_2fa_user(user) begin_in_person_proofing(user) complete_prepare_step(user) complete_location_step(user) end - it 'skips the address page' do - complete_state_id_step( - user, same_address_as_id: true, capture_secondary_id_enabled: true - ) - # skip address step - complete_ssn_step(user) - # Ensure the page submitted successfully - expect(page).to have_content(t('idv.form.ssn_label')) - end - - it 'can redo the address page form even if that page is skipped' do - complete_state_id_step( - user, same_address_as_id: true, capture_secondary_id_enabled: true - ) + it 'can redo the address page form after it is skipped' do + complete_state_id_step(user, same_address_as_id: true) # skip address step complete_ssn_step(user) # click update address button on the verify page click_button t('idv.buttons.change_address_label') expect(page).to have_content(t('in_person_proofing.headings.update_address')) - fill_out_address_form_ok(double_address_verification: true, same_address_as_id: true) + fill_out_address_form_ok(same_address_as_id: true) click_button t('forms.buttons.submit.update') expect(page).to have_content(t('headings.verify')) expect(page).to have_current_path(idv_in_person_verify_info_path) end it 'allows user to update their residential address as different from their state id' do - complete_state_id_step( - user, same_address_as_id: true, capture_secondary_id_enabled: true - ) + complete_state_id_step(user, same_address_as_id: true) complete_ssn_step(user) # click "update residential address" @@ -788,167 +652,155 @@ end end - context 'in_person_capture_secondary_id_enabled feature flag enabled and' do - context 'when updates are made on state ID page starting from Verify Your Information', - allow_browser_log: true do - let(:user) { user_with_2fa } - - before(:each) do - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(true) + context 'Updates are made on state ID page starting from Verify Your Information', + allow_browser_log: true do + let(:user) { user_with_2fa } - sign_in_and_2fa_user(user) - begin_in_person_proofing(user) - complete_prepare_step(user) - complete_location_step(user) - end + before(:each) do + sign_in_and_2fa_user(user) + begin_in_person_proofing(user) + complete_prepare_step(user) + complete_location_step(user) + end - it 'does not update their previous selection of "Yes, + it 'does not update their previous selection of "Yes, I live at the address on my state-issued ID"' do - complete_state_id_step( - user, same_address_as_id: true, capture_secondary_id_enabled: true - ) - # skip address step - complete_ssn_step(user) - # expect to be on verify page - expect(page).to have_content(t('headings.verify')) - expect(page).to have_current_path(idv_in_person_verify_info_path) - # click update state ID button on the verify page - click_button t('idv.buttons.change_state_id_label') - # expect to be on the state ID page - expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) - # change address - fill_in t('in_person_proofing.form.state_id.address1'), with: '' - fill_in t('in_person_proofing.form.state_id.address1'), with: 'test update address' - click_button t('forms.buttons.submit.update') - # expect to be back on verify page - expect(page).to have_content(t('headings.verify')) - expect(page).to have_current_path(idv_in_person_verify_info_path) - expect(page).to have_content(t('headings.verify')) - # expect to see state ID address update on verify twice - expect(page).to have_text('test update address').twice # for state id addr and addr update - # click update state id address - click_button t('idv.buttons.change_state_id_label') - # expect to be on the state ID page - expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) - # expect "Yes, I live at a different address" is checked" - expect(page).to have_checked_field( - t('in_person_proofing.form.state_id.same_address_as_id_yes'), - visible: false, - ) - end + complete_state_id_step(user, same_address_as_id: true) + # skip address step + complete_ssn_step(user) + # expect to be on verify page + expect(page).to have_content(t('headings.verify')) + expect(page).to have_current_path(idv_in_person_verify_info_path) + # click update state ID button on the verify page + click_button t('idv.buttons.change_state_id_label') + # expect to be on the state ID page + expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + # change address + fill_in t('in_person_proofing.form.state_id.address1'), with: '' + fill_in t('in_person_proofing.form.state_id.address1'), with: 'test update address' + click_button t('forms.buttons.submit.update') + # expect to be back on verify page + expect(page).to have_content(t('headings.verify')) + expect(page).to have_current_path(idv_in_person_verify_info_path) + expect(page).to have_content(t('headings.verify')) + # expect to see state ID address update on verify twice + expect(page).to have_text('test update address').twice # for state id addr and addr update + # click update state id address + click_button t('idv.buttons.change_state_id_label') + # expect to be on the state ID page + expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + # expect "Yes, I live at a different address" is checked" + expect(page).to have_checked_field( + t('in_person_proofing.form.state_id.same_address_as_id_yes'), + visible: false, + ) + end - it 'does not update their previous selection of "No, I live at a different address"' do - complete_state_id_step( - user, same_address_as_id: false, capture_secondary_id_enabled: true - ) - # expect to be on address page - expect(page).to have_content(t('in_person_proofing.headings.address')) - # complete address step - complete_address_step(user, double_address_verification: true) - complete_ssn_step(user) - # expect to be back on verify page - expect(page).to have_content(t('headings.verify')) - expect(page).to have_current_path(idv_in_person_verify_info_path) - # click update state ID button on the verify page - click_button t('idv.buttons.change_state_id_label') - # expect to be on the state ID page - expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) - # change address - fill_in t('in_person_proofing.form.state_id.address1'), with: '' - fill_in t('in_person_proofing.form.state_id.address1'), with: 'test update address' - click_button t('forms.buttons.submit.update') - # expect to be back on verify page - expect(page).to have_content(t('headings.verify')) - expect(page).to have_current_path(idv_in_person_verify_info_path) - expect(page).to have_content(t('headings.verify')) - # expect to see state ID address update on verify - expect(page).to have_text('test update address').once # only state id address update - # click update state id address - click_button t('idv.buttons.change_state_id_label') - # expect to be on the state ID page - expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) - expect(page).to have_checked_field( - t('in_person_proofing.form.state_id.same_address_as_id_no'), - visible: false, - ) - end + it 'does not update their previous selection of "No, I live at a different address"' do + complete_state_id_step(user, same_address_as_id: false) + # expect to be on address page + expect(page).to have_content(t('in_person_proofing.headings.address')) + # complete address step + complete_address_step(user) + complete_ssn_step(user) + # expect to be back on verify page + expect(page).to have_content(t('headings.verify')) + expect(page).to have_current_path(idv_in_person_verify_info_path) + # click update state ID button on the verify page + click_button t('idv.buttons.change_state_id_label') + # expect to be on the state ID page + expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + # change address + fill_in t('in_person_proofing.form.state_id.address1'), with: '' + fill_in t('in_person_proofing.form.state_id.address1'), with: 'test update address' + click_button t('forms.buttons.submit.update') + # expect to be back on verify page + expect(page).to have_content(t('headings.verify')) + expect(page).to have_current_path(idv_in_person_verify_info_path) + expect(page).to have_content(t('headings.verify')) + # expect to see state ID address update on verify + expect(page).to have_text('test update address').once # only state id address update + # click update state id address + click_button t('idv.buttons.change_state_id_label') + # expect to be on the state ID page + expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + expect(page).to have_checked_field( + t('in_person_proofing.form.state_id.same_address_as_id_no'), + visible: false, + ) + end - it 'updates their previous selection from "Yes" TO "No, I live at a different address"' do - complete_state_id_step( - user, same_address_as_id: true, capture_secondary_id_enabled: true - ) - # skip address step - complete_ssn_step(user) - # click update state ID button on the verify page - click_button t('idv.buttons.change_state_id_label') - # expect to be on the state ID page - expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) - # change address - fill_in t('in_person_proofing.form.state_id.address1'), with: '' - fill_in t('in_person_proofing.form.state_id.address1'), with: 'test update address' - # change response to No - choose t('in_person_proofing.form.state_id.same_address_as_id_no') - click_button t('forms.buttons.submit.update') - # expect to be on address page - expect(page).to have_content(t('in_person_proofing.headings.address')) - # complete address step - complete_address_step(user, double_address_verification: true) - # expect to be on verify page - expect(page).to have_content(t('headings.verify')) - expect(page).to have_current_path(idv_in_person_verify_info_path) - # expect to see state ID address update on verify - expect(page).to have_text('test update address').once # only state id address update - # click update state id address - click_button t('idv.buttons.change_state_id_label') - # expect to be on the state ID page - expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) - # check that the "No, I live at a different address" is checked" - expect(page).to have_checked_field( - t('in_person_proofing.form.state_id.same_address_as_id_no'), - visible: false, - ) - end + it 'updates their previous selection from "Yes" TO "No, I live at a different address"' do + complete_state_id_step(user, same_address_as_id: true) + # skip address step + complete_ssn_step(user) + # click update state ID button on the verify page + click_button t('idv.buttons.change_state_id_label') + # expect to be on the state ID page + expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + # change address + fill_in t('in_person_proofing.form.state_id.address1'), with: '' + fill_in t('in_person_proofing.form.state_id.address1'), with: 'test update address' + # change response to No + choose t('in_person_proofing.form.state_id.same_address_as_id_no') + click_button t('forms.buttons.submit.update') + # expect to be on address page + expect(page).to have_content(t('in_person_proofing.headings.address')) + # complete address step + complete_address_step(user) + # expect to be on verify page + expect(page).to have_content(t('headings.verify')) + expect(page).to have_current_path(idv_in_person_verify_info_path) + # expect to see state ID address update on verify + expect(page).to have_text('test update address').once # only state id address update + # click update state id address + click_button t('idv.buttons.change_state_id_label') + # expect to be on the state ID page + expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + # check that the "No, I live at a different address" is checked" + expect(page).to have_checked_field( + t('in_person_proofing.form.state_id.same_address_as_id_no'), + visible: false, + ) + end - it 'updates their previous selection from "No" TO "Yes, + it 'updates their previous selection from "No" TO "Yes, I live at the address on my state-issued ID"' do - complete_state_id_step( - user, same_address_as_id: false, capture_secondary_id_enabled: true - ) - # expect to be on address page - expect(page).to have_content(t('in_person_proofing.headings.address')) - # complete address step - complete_address_step(user, double_address_verification: true) - complete_ssn_step(user) - # expect to be on verify page - expect(page).to have_content(t('headings.verify')) - expect(page).to have_current_path(idv_in_person_verify_info_path) - # click update state ID button on the verify page - click_button t('idv.buttons.change_state_id_label') - # expect to be on the state ID page - expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) - # change address - fill_in t('in_person_proofing.form.state_id.address1'), with: '' - fill_in t('in_person_proofing.form.state_id.address1'), with: 'test update address' - # change response to Yes - choose t('in_person_proofing.form.state_id.same_address_as_id_yes') - click_button t('forms.buttons.submit.update') - # expect to be back on verify page - expect(page).to have_content(t('headings.verify')) - expect(page).to have_current_path(idv_in_person_verify_info_path) - # expect to see state ID address update on verify twice - expect(page).to have_text('test update address').twice # for state id addr and addr update - # click update state ID button on the verify page - click_button t('idv.buttons.change_state_id_label') - # expect to be on the state ID page - expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) - expect(page).to have_checked_field( - t('in_person_proofing.form.state_id.same_address_as_id_yes'), - visible: false, - ) - end + complete_state_id_step(user, same_address_as_id: false) + # expect to be on address page + expect(page).to have_content(t('in_person_proofing.headings.address')) + # complete address step + complete_address_step(user) + complete_ssn_step(user) + # expect to be on verify page + expect(page).to have_content(t('headings.verify')) + expect(page).to have_current_path(idv_in_person_verify_info_path) + # click update state ID button on the verify page + click_button t('idv.buttons.change_state_id_label') + # expect to be on the state ID page + expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + # change address + fill_in t('in_person_proofing.form.state_id.address1'), with: '' + fill_in t('in_person_proofing.form.state_id.address1'), with: 'test update address' + # change response to Yes + choose t('in_person_proofing.form.state_id.same_address_as_id_yes') + click_button t('forms.buttons.submit.update') + # expect to be back on verify page + expect(page).to have_content(t('headings.verify')) + expect(page).to have_current_path(idv_in_person_verify_info_path) + # expect to see state ID address update on verify twice + expect(page).to have_text('test update address').twice # for state id addr and addr update + # click update state ID button on the verify page + click_button t('idv.buttons.change_state_id_label') + # expect to be on the state ID page + expect(page).to have_content(t('in_person_proofing.headings.update_state_id')) + expect(page).to have_checked_field( + t('in_person_proofing.form.state_id.same_address_as_id_yes'), + visible: false, + ) end end + context 'when manual address entry is enabled for post office search' do let(:user) { user_with_2fa } @@ -966,10 +818,10 @@ complete_location_step # state ID page - complete_state_id_step(user) + complete_state_id_step(user, same_address_as_id: false) # address page - complete_address_step(user) + complete_address_step(user, same_address_as_id: false) # ssn page select 'Reject', from: :mock_profiling_result @@ -983,6 +835,11 @@ expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME) expect(page).to have_text(InPersonHelper::GOOD_DOB_FORMATTED_EVENT) expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS1) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS2) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_CITY) + expect(page).to have_text(Idp::Constants::MOCK_IDV_APPLICANT[:state_id_jurisdiction]).twice + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ZIPCODE) expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1) expect(page).to have_text(InPersonHelper::GOOD_CITY) expect(page).to have_text(InPersonHelper::GOOD_ZIPCODE) diff --git a/spec/support/features/in_person_helper.rb b/spec/support/features/in_person_helper.rb index 65cee16e857..b0fffbabeba 100644 --- a/spec/support/features/in_person_helper.rb +++ b/spec/support/features/in_person_helper.rb @@ -46,34 +46,28 @@ def fill_out_state_id_form_ok(same_address_as_id: false) fill_in t('in_person_proofing.form.state_id.address2'), with: GOOD_IDENTITY_DOC_ADDRESS2 fill_in t('in_person_proofing.form.state_id.city'), with: GOOD_IDENTITY_DOC_CITY fill_in t('in_person_proofing.form.state_id.zipcode'), with: GOOD_IDENTITY_DOC_ZIPCODE + select GOOD_STATE_ID_JURISDICTION, + from: t('in_person_proofing.form.state_id.identity_doc_address_state') if same_address_as_id - select GOOD_IDENTITY_DOC_ADDRESS_STATE, - from: t('in_person_proofing.form.state_id.identity_doc_address_state') choose t('in_person_proofing.form.state_id.same_address_as_id_yes') else - select GOOD_STATE, from: t('in_person_proofing.form.state_id.identity_doc_address_state') choose t('in_person_proofing.form.state_id.same_address_as_id_no') end end - def fill_out_address_form_ok(double_address_verification: false, same_address_as_id: false) + def fill_out_address_form_ok(same_address_as_id: false) fill_in t('idv.form.address1'), with: same_address_as_id ? GOOD_IDENTITY_DOC_ADDRESS1 : GOOD_ADDRESS1 - fill_in t('idv.form.address2_optional'), with: GOOD_ADDRESS2 unless double_address_verification fill_in t('idv.form.address2'), with: same_address_as_id ? GOOD_IDENTITY_DOC_ADDRESS2 : GOOD_ADDRESS2 fill_in t('idv.form.city'), with: same_address_as_id ? GOOD_IDENTITY_DOC_CITY : GOOD_CITY fill_in t('idv.form.zipcode'), with: same_address_as_id ? GOOD_IDENTITY_DOC_ZIPCODE : GOOD_ZIPCODE if same_address_as_id - select GOOD_IDENTITY_DOC_ADDRESS_STATE, from: t('idv.form.state') + select GOOD_STATE_ID_JURISDICTION, from: t('idv.form.state') else select GOOD_STATE, from: t('idv.form.state') end - - unless double_address_verification - choose t('in_person_proofing.form.address.same_address_choice_yes') - end end def begin_in_person_proofing(_user = nil) @@ -120,23 +114,19 @@ def complete_prepare_step(_user = nil) click_on t('forms.buttons.continue') end - def complete_state_id_step(_user = nil, same_address_as_id: true, - capture_secondary_id_enabled: false) + def complete_state_id_step(_user = nil, same_address_as_id: true) # Wait for page to load before attempting to fill out form expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) - fill_out_state_id_form_ok( - same_address_as_id: same_address_as_id, - capture_secondary_id_enabled: capture_secondary_id_enabled, - ) + fill_out_state_id_form_ok(same_address_as_id: same_address_as_id) click_idv_continue - unless capture_secondary_id_enabled && same_address_as_id + unless same_address_as_id expect(page).to have_current_path(idv_in_person_step_path(step: :address), wait: 10) expect_in_person_step_indicator_current_step(t('step_indicator.flows.idv.verify_info')) end end - def complete_address_step(_user = nil, double_address_verification: false) - fill_out_address_form_ok(double_address_verification: double_address_verification) + def complete_address_step(_user = nil, same_address_as_id: true) + fill_out_address_form_ok(same_address_as_id: same_address_as_id) click_idv_continue end @@ -149,11 +139,11 @@ def complete_verify_step(_user = nil) click_idv_continue end - def complete_all_in_person_proofing_steps(user = user_with_2fa) + def complete_all_in_person_proofing_steps(user = user_with_2fa, same_address_as_id: true) complete_prepare_step(user) complete_location_step(user) complete_state_id_step(user) - complete_address_step(user) + complete_address_step(user) unless same_address_as_id complete_ssn_step(user) complete_verify_step(user) end @@ -200,4 +190,41 @@ def mark_in_person_enrollment_passed(user) enrollment.profile.activate_after_passing_in_person enrollment.update(status: :passed) end + + def perform_mobile_hybrid_steps + perform_in_browser(:mobile) do + # doc auth page + visit @sms_link + mock_doc_auth_attention_with_barcode + attach_and_submit_images + + # error page + click_button t('in_person_proofing.body.cta.button') + # prepare page + expect(page).to(have_content(t('in_person_proofing.body.prepare.verify_step_about'))) + click_idv_continue + # location page + expect(page).to have_content(t('in_person_proofing.headings.po_search.location')) + complete_location_step + + # switch back page + expect(page).to have_content(t('in_person_proofing.headings.switch_back')) + end + end + + def perform_desktop_hybrid_steps(user = user_with_2fa, same_address_as_id: true) + perform_in_browser(:desktop) do + expect(page).to have_current_path(idv_in_person_step_path(step: :state_id), wait: 10) + + complete_state_id_step(user, same_address_as_id: same_address_as_id) + complete_address_step(user, same_address_as_id: same_address_as_id) unless same_address_as_id + complete_ssn_step(user) + complete_verify_step(user) + complete_phone_step(user) + complete_review_step(user) + acknowledge_and_confirm_personal_key + + expect(page).to have_content('MILWAUKEE') + end + end end From 068e892dadb4754f3d27297ca82169b5b1a54bd5 Mon Sep 17 00:00:00 2001 From: svalexander Date: Mon, 18 Sep 2023 10:56:54 -0400 Subject: [PATCH 07/37] update idv step helper --- spec/support/features/idv_step_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/features/idv_step_helper.rb b/spec/support/features/idv_step_helper.rb index 86b3b700e40..f6150c1ba6d 100644 --- a/spec/support/features/idv_step_helper.rb +++ b/spec/support/features/idv_step_helper.rb @@ -134,7 +134,7 @@ def complete_idv_steps_before_ssn(user = user_with_2fa) # location page complete_location_step(user) # state ID page - fill_out_state_id_form_ok(same_address_as_id: true, capture_secondary_id_enabled: true) + fill_out_state_id_form_ok(same_address_as_id: true) click_idv_continue end From 9948b1c8553f7e9b999948348fd8eb5e4a558350 Mon Sep 17 00:00:00 2001 From: svalexander Date: Mon, 18 Sep 2023 13:14:52 -0400 Subject: [PATCH 08/37] remove unused strings --- config/locales/in_person_proofing/en.yml | 9 --------- config/locales/in_person_proofing/es.yml | 10 ---------- config/locales/in_person_proofing/fr.yml | 10 ---------- 3 files changed, 29 deletions(-) diff --git a/config/locales/in_person_proofing/en.yml b/config/locales/in_person_proofing/en.yml index 35f2574846d..0427a5290f8 100644 --- a/config/locales/in_person_proofing/en.yml +++ b/config/locales/in_person_proofing/en.yml @@ -2,10 +2,6 @@ en: in_person_proofing: body: - address: - info: If your current address does not match the address on your ID, you will - need to bring proof of your current address to the Post Office. - learn_more: Learn more barcode: cancel_link_text: Cancel your barcode close_window: You may now close this window. @@ -93,10 +89,6 @@ en: unsupported_chars: 'Our system cannot read the following characters: %{char_list}. Please try again using substitutes for those characters.' - same_address: Is this address displayed on the state‑issued ID that you are - bringing to the Post Office? - same_address_choice_no: I have a different address on my ID - same_address_choice_yes: This address is on my state‑issued ID state_prompt: '- Select -' state_id: address1: Address line 1 @@ -115,7 +107,6 @@ en: %{char_list}. Please try again using the characters on your ID.' first_name: First name identity_doc_address_state: State - identity_doc_address_state_hint: Select the state shown on your ID identity_doc_address_state_prompt: '- Select -' last_name: Last name memorable_date: diff --git a/config/locales/in_person_proofing/es.yml b/config/locales/in_person_proofing/es.yml index 52c592f0445..b43c5782d88 100644 --- a/config/locales/in_person_proofing/es.yml +++ b/config/locales/in_person_proofing/es.yml @@ -2,11 +2,6 @@ es: in_person_proofing: body: - address: - info: Si su dirección actual no coincide con la que figura en su cédula de - identidad, deberá llevar a la oficina de correos un comprobante de su - dirección actual. - learn_more: Aprende más barcode: cancel_link_text: Cancelar su código de barras close_window: Ya puede cerrar esta ventana @@ -105,10 +100,6 @@ es: unsupported_chars: 'Los siguientes caracteres no pueden ser leídos por nuestro sistema: %{char_list}. Inténtelo nuevamente usando sustitutos para estos caracteres.' - same_address: '¿Aparece esta dirección en la cédula de identidad emitido por el - Estado que va a llevar a la oficina de Correos?' - same_address_choice_no: Tengo una dirección diferente en mi cédula de identidad - same_address_choice_yes: Esta dirección aparece en mi cédula de identidad emitida por el estado state_prompt: '- Seleccione -' state_id: address1: Línea de dirección 1 @@ -128,7 +119,6 @@ es: su documento de identidad.' first_name: Nombre identity_doc_address_state: Estado emisor - identity_doc_address_state_hint: Este es el estado que emitió su identificación identity_doc_address_state_prompt: '- Seleccione -' last_name: Apellido memorable_date: diff --git a/config/locales/in_person_proofing/fr.yml b/config/locales/in_person_proofing/fr.yml index 4e0468bd9f6..69b9d8b1c09 100644 --- a/config/locales/in_person_proofing/fr.yml +++ b/config/locales/in_person_proofing/fr.yml @@ -2,11 +2,6 @@ fr: in_person_proofing: body: - address: - info: Si votre adresse actuelle ne correspond pas à l’adresse figurant sur votre - document d’identité, vous devrez apporter une preuve de votre adresse - actuelle au bureau de poste. - learn_more: Apprendre encore plus barcode: cancel_link_text: Annulez votre code-barres close_window: Vous pouvez maintenant fermer cette fenêtre @@ -104,10 +99,6 @@ fr: unsupported_chars: 'Notre système ne parvient pas à lire les caractères suivants : %{char_list}. Veuillez réessayer en utilisant d’autres caractères alternatifs.' - same_address: Cette adresse figure-t-elle sur la pièce d’identité délivrée par - l’État que vous apportez au bureau de poste? - same_address_choice_no: J’ai une adresse différente sur mon document d’identité - same_address_choice_yes: Cette adresse figure sur mon document d’identité nationale state_prompt: '- Sélectionnez -' state_id: address1: Adresse ligne 1 @@ -127,7 +118,6 @@ fr: votre carte d’identité.' first_name: Prénom identity_doc_address_state: État émetteur - identity_doc_address_state_hint: Il s’agit de l’État qui a émis votre pièce d’identité identity_doc_address_state_prompt: '- Sélectionnez -' last_name: Nom de famille memorable_date: From b4fca4e1652796d576774c2a3780cb06764f3c85 Mon Sep 17 00:00:00 2001 From: svalexander Date: Mon, 18 Sep 2023 13:20:17 -0400 Subject: [PATCH 09/37] update step specs --- .../idv/doc_auth/verify_info_step_spec.rb | 1 - .../idv/steps/in_person/address_step_spec.rb | 99 ++++++------------- .../idv/steps/in_person/state_id_step_spec.rb | 94 ++---------------- 3 files changed, 35 insertions(+), 159 deletions(-) diff --git a/spec/features/idv/doc_auth/verify_info_step_spec.rb b/spec/features/idv/doc_auth/verify_info_step_spec.rb index 164b2b05952..cdd7423dc80 100644 --- a/spec/features/idv/doc_auth/verify_info_step_spec.rb +++ b/spec/features/idv/doc_auth/verify_info_step_spec.rb @@ -272,7 +272,6 @@ trace_id: anything, threatmetrix_session_id: anything, request_ip: kind_of(String), - double_address_verification: false, } end diff --git a/spec/services/idv/steps/in_person/address_step_spec.rb b/spec/services/idv/steps/in_person/address_step_spec.rb index d635d33b526..7a3cf969a1f 100644 --- a/spec/services/idv/steps/in_person/address_step_spec.rb +++ b/spec/services/idv/steps/in_person/address_step_spec.rb @@ -5,8 +5,7 @@ let(:submitted_values) { {} } let(:pii_from_user) { flow.flow_session[:pii_from_user] } let(:params) { ActionController::Parameters.new({ in_person_address: submitted_values }) } - let(:capture_secondary_id_enabled) { false } - let(:enrollment) { InPersonEnrollment.new(capture_secondary_id_enabled:) } + let(:enrollment) { InPersonEnrollment.new } let(:user) { build(:user) } let(:service_provider) { create(:service_provider) } let(:controller) do @@ -35,10 +34,6 @@ end describe '#call' do - before do - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(false) - end context 'with values submitted' do let(:address1) { '1 FAKE RD' } let(:address2) { 'APT 1B' } @@ -63,67 +58,51 @@ end end - it 'sets values in flow session' do + it 'sets the values in flow session' do step.call + expect(flow.flow_session[:pii_from_user]).to include( address1:, address2:, city:, zipcode:, state:, - same_address_as_id:, ) end - context 'with secondary capture enabled' do - let(:capture_secondary_id_enabled) { true } - - it 'sets the values in flow session' do + context 'when initially entering the residential address' do + it 'leaves the "same_address_as_id" attr as false' do + flow.flow_session[:pii_from_user][:same_address_as_id] = 'false' step.call - expect(flow.flow_session[:pii_from_user]).to include( - address1:, - address2:, - city:, - zipcode:, - state:, - ) + expect(flow.flow_session[:pii_from_user][:same_address_as_id]).to eq('false') end + end - context 'when initially entering the residential address' do - it 'leaves the "same_address_as_id" attr as false' do - flow.flow_session[:pii_from_user][:same_address_as_id] = 'false' - step.call - - expect(flow.flow_session[:pii_from_user][:same_address_as_id]).to eq('false') - end + context 'when updating the residential address' do + before(:each) do + flow.flow_session[:pii_from_user][:address1] = '123 New Residential Ave' end - context 'when updating the residential address' do + context 'user previously selected that the residential address matched state ID' do before(:each) do - flow.flow_session[:pii_from_user][:address1] = '123 New Residential Ave' + flow.flow_session[:pii_from_user][:same_address_as_id] = 'true' end - context 'user previously selected that the residential address matched state ID' do - before(:each) do - flow.flow_session[:pii_from_user][:same_address_as_id] = 'true' - end - - it 'infers and sets the "same_address_as_id" in the flow session to false' do - step.call - expect(flow.flow_session[:pii_from_user][:same_address_as_id]).to eq('false') - end + it 'infers and sets the "same_address_as_id" in the flow session to false' do + step.call + expect(flow.flow_session[:pii_from_user][:same_address_as_id]).to eq('false') end + end - context 'user previously selected that the residential address did not match state ID' do - before(:each) do - flow.flow_session[:pii_from_user][:same_address_as_id] = 'false' - end + context 'user previously selected that the residential address did not match state ID' do + before(:each) do + flow.flow_session[:pii_from_user][:same_address_as_id] = 'false' + end - it 'leaves the "same_address_as_id" in the flow session as false' do - step.call - expect(flow.flow_session[:pii_from_user][:same_address_as_id]).to eq('false') - end + it 'leaves the "same_address_as_id" in the flow session as false' do + step.call + expect(flow.flow_session[:pii_from_user][:same_address_as_id]).to eq('false') end end end @@ -131,17 +110,10 @@ end describe '#analytics_submitted_event' do - it 'logs idv_in_person_proofing_address_submitted' do - expect(step.analytics_submitted_event).to be(:idv_in_person_proofing_address_submitted) - end - - context 'with secondary capture enabled' do - let(:capture_secondary_id_enabled) { true } - it 'logs idv_in_person_proofing_residential_address_submitted' do - expect(step.analytics_submitted_event).to be( - :idv_in_person_proofing_residential_address_submitted, - ) - end + it 'logs idv_in_person_proofing_residential_address_submitted' do + expect(step.analytics_submitted_event).to be( + :idv_in_person_proofing_residential_address_submitted, + ) end end @@ -173,20 +145,5 @@ ) end end - - it 'returns capture enabled = false' do - expect(step.extra_view_variables).to include( - capture_secondary_id_enabled: false, - ) - end - - context 'with secondary capture enabled' do - let(:capture_secondary_id_enabled) { true } - it 'returns capture enabled = true' do - expect(step.extra_view_variables).to include( - capture_secondary_id_enabled: true, - ) - end - end end end diff --git a/spec/services/idv/steps/in_person/state_id_step_spec.rb b/spec/services/idv/steps/in_person/state_id_step_spec.rb index c9a279529b1..59083836b15 100644 --- a/spec/services/idv/steps/in_person/state_id_step_spec.rb +++ b/spec/services/idv/steps/in_person/state_id_step_spec.rb @@ -5,8 +5,7 @@ let(:submitted_values) { {} } let(:params) { ActionController::Parameters.new({ state_id: submitted_values }) } let(:user) { build(:user) } - let(:capture_secondary_id_enabled) { false } - let(:enrollment) { InPersonEnrollment.new(capture_secondary_id_enabled:) } + let(:enrollment) { InPersonEnrollment.new } let(:service_provider) { create(:service_provider) } let(:controller) do instance_double( @@ -44,8 +43,6 @@ end before do - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(false) allow(user).to receive(:establishing_in_person_enrollment). and_return(enrollment) end @@ -87,7 +84,6 @@ context 'when capture_secondary_id_enabled is...' do let(:pii_from_user) { flow.flow_session[:pii_from_user] } let(:params) { ActionController::Parameters.new({ state_id: submitted_values }) } - let(:capture_secondary_id_enabled) { true } let(:dob) { InPersonHelper::GOOD_DOB } # residential let(:address1) { InPersonHelper::GOOD_ADDRESS1 } @@ -107,8 +103,7 @@ and_return(enrollment) end - context 'enabled, and - same_address_as_id changed from "true" to "false"' do + context 'same_address_as_id changed from "true" to "false"' do let(:submitted_values) do { dob:, @@ -125,6 +120,7 @@ identity_doc_zipcode:, } end + it 'marks address step as incomplete, retains identity_doc_ attrs/value but removes addr attr in flow session' do Idv::StateIdForm::ATTRIBUTES.each do |attr| @@ -161,8 +157,7 @@ end end - context 'enabled, and - same_address_as_id changed from "false" to "true"' do + context 'same_address_as_id changed from "false" to "true"' do let(:submitted_values) do { dob:, @@ -200,8 +195,7 @@ end end - context 'enabled, and - same_address_as_id does not change from from "false"' do + context 'same_address_as_id does not change from from "false"' do let(:submitted_values) do { dob:, @@ -252,47 +246,6 @@ expect(pii_from_user[:zipcode]).to_not eq identity_doc_zipcode end end - - context 'not enabled' do - let(:capture_secondary_id_enabled) { false } - let(:submitted_values) do - { - dob:, - address1:, - address2:, - city:, - state:, - zipcode:, - identity_doc_address1:, - identity_doc_address2:, - identity_doc_city:, - identity_doc_address_state:, - identity_doc_zipcode:, - } - end - - it 'retains identity_doc_ attr/values in flow session' do - Idv::StateIdForm::ATTRIBUTES.each do |attr| - expect(flow.flow_session[:pii_from_user]).to_not have_key attr - end - - pii_from_user[:identity_doc_address1] = identity_doc_address1 - pii_from_user[:identity_doc_address2] = identity_doc_address2 - pii_from_user[:identity_doc_city] = identity_doc_city - pii_from_user[:identity_doc_address_state] = identity_doc_address_state - pii_from_user[:identity_doc_zipcode] = identity_doc_zipcode - - step.call - - expect(flow.flow_session[:pii_from_user]).to include( - identity_doc_address1:, - identity_doc_address2:, - identity_doc_city:, - identity_doc_address_state:, - identity_doc_zipcode:, - ) - end - end end end @@ -301,8 +254,7 @@ let(:first_name) { 'First name' } let(:pii_from_user) { flow.flow_session[:pii_from_user] } let(:params) { ActionController::Parameters.new } - let(:capture_secondary_id_enabled) { true } - let(:enrollment) { InPersonEnrollment.new(capture_secondary_id_enabled:) } + let(:enrollment) { InPersonEnrollment.new } before(:each) do allow(step).to receive(:current_user). @@ -354,30 +306,12 @@ ) end end - - context 'with secondary capture enabled' do - it 'returns capture enabled = true' do - expect(step.extra_view_variables).to include( - capture_secondary_id_enabled: true, - ) - end - end - - context 'with secondary capture disabled' do - let(:capture_secondary_id_enabled) { false } - it 'returns capture enabled = false' do - expect(step.extra_view_variables).to include( - capture_secondary_id_enabled: false, - ) - end - end end describe 'skip address step?' do let(:pii_from_user) { flow.flow_session[:pii_from_user] } let(:params) { ActionController::Parameters.new({ state_id: submitted_values }) } - let(:capture_secondary_id_enabled) { true } - let(:enrollment) { InPersonEnrollment.new(capture_secondary_id_enabled:) } + let(:enrollment) { InPersonEnrollment.new } let(:dob) { '1980-01-01' } let(:identity_doc_address_state) { 'Nevada' } let(:identity_doc_city) { 'Twin Peaks' } @@ -437,19 +371,5 @@ expect(pii_from_user[:zipcode]).to_not eq identity_doc_zipcode end end - - context 'capture secondary id is disabled' do - let(:capture_secondary_id_enabled) { false } - it 'does not add state id values to address values in pii' do - step.call - - pii_from_user = flow.flow_session[:pii_from_user] - expect(pii_from_user[:address1]).to_not eq identity_doc_address1 - expect(pii_from_user[:address2]).to_not eq identity_doc_address2 - expect(pii_from_user[:city]).to_not eq identity_doc_city - expect(pii_from_user[:state]).to_not eq identity_doc_address_state - expect(pii_from_user[:zipcode]).to_not eq identity_doc_zipcode - end - end end end From 4a44a51d16ffa0d47e0c246d53d516021b5e01a9 Mon Sep 17 00:00:00 2001 From: svalexander Date: Mon, 18 Sep 2023 15:50:22 -0400 Subject: [PATCH 10/37] update ssn and verify info specs --- spec/features/idv/steps/in_person/ssn_spec.rb | 27 +++++++++--------- .../idv/steps/in_person/verify_info_spec.rb | 28 ++++++++----------- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/spec/features/idv/steps/in_person/ssn_spec.rb b/spec/features/idv/steps/in_person/ssn_spec.rb index 011f4ed029e..31e35137481 100644 --- a/spec/features/idv/steps/in_person/ssn_spec.rb +++ b/spec/features/idv/steps/in_person/ssn_spec.rb @@ -6,7 +6,6 @@ before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled).and_return(true) end context 'when visiting ssn for the first time' do @@ -101,7 +100,7 @@ end end - context 'when in_person_capture_secondary_id_enabled is true, ssn step is accessible from' do + context 'when same_address_as_id is false, ssn step is accessible from' do it 'address step', allow_browser_log: true do user = user_with_2fa sign_in_and_2fa_user(user) @@ -111,25 +110,27 @@ # location page complete_location_step(user) # state ID page - fill_out_state_id_form_ok(same_address_as_id: false, capture_secondary_id_enabled: true) + fill_out_state_id_form_ok(same_address_as_id: false) click_idv_continue - fill_out_address_form_ok(double_address_verification: true, same_address_as_id: false) + fill_out_address_form_ok(same_address_as_id: false) click_idv_continue # ssn page expect(page).to have_content(t('doc_auth.headings.ssn')) end - it 'state_id step (when state id address matches residential address)', - allow_browser_log: true do - user = user_with_2fa - complete_idv_steps_before_ssn(user) - # ssn page - expect(page).to have_content(t('doc_auth.headings.ssn')) - end - it 'verify info step', allow_browser_log: true do user = user_with_2fa - complete_idv_steps_before_ssn(user) + sign_in_and_2fa_user(user) + begin_in_person_proofing(user) + # prepare page + complete_prepare_step(user) + # location page + complete_location_step(user) + # state ID page + fill_out_state_id_form_ok(same_address_as_id: false) + click_idv_continue + fill_out_address_form_ok(same_address_as_id: false) + click_idv_continue # ssn page (first visit) complete_ssn_step(user) # verify page (next page) diff --git a/spec/features/idv/steps/in_person/verify_info_spec.rb b/spec/features/idv/steps/in_person/verify_info_spec.rb index c4a4be66b56..f7172c6a70a 100644 --- a/spec/features/idv/steps/in_person/verify_info_spec.rb +++ b/spec/features/idv/steps/in_person/verify_info_spec.rb @@ -7,8 +7,7 @@ let(:user) { user_with_2fa } let(:fake_analytics) { FakeAnalytics.new(user: user) } - let(:capture_secondary_id_enabled) { false } - let(:enrollment) { InPersonEnrollment.new(capture_secondary_id_enabled:) } + let(:enrollment) { InPersonEnrollment.new } before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) @@ -24,7 +23,6 @@ complete_prepare_step(user) complete_location_step(user) complete_state_id_step(user) - complete_address_step(user) complete_ssn_step(user) # verify page @@ -35,10 +33,11 @@ expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME) expect(page).to have_text(InPersonHelper::GOOD_DOB_FORMATTED_EVENT) expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER) - expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1) - expect(page).to have_text(InPersonHelper::GOOD_CITY) - expect(page).to have_text(InPersonHelper::GOOD_ZIPCODE) - expect(page).to have_text(Idp::Constants::MOCK_IDV_APPLICANT[:state]) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS1).twice + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS2).twice + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_CITY).twice + expect(page).to have_text(Idp::Constants::MOCK_IDV_APPLICANT[:state_id_jurisdiction], count: 3) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ZIPCODE).twice expect(page).to have_text(DocAuthHelper::GOOD_SSN_MASKED) # click update state ID button @@ -58,7 +57,7 @@ click_doc_auth_back_link expect(page).to have_content(t('headings.verify')) expect(page).to have_current_path(idv_in_person_verify_info_path) - expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS1) expect(page).not_to have_text('bad address') # click update ssn button @@ -83,7 +82,6 @@ complete_prepare_step(user) complete_location_step(user) complete_state_id_step(user) - complete_address_step(user) complete_ssn_step(user) # verify page @@ -95,10 +93,11 @@ expect(page).to have_text(InPersonHelper::GOOD_LAST_NAME) expect(page).to have_text(InPersonHelper::GOOD_DOB_FORMATTED_EVENT) expect(page).to have_text(InPersonHelper::GOOD_STATE_ID_NUMBER) - expect(page).to have_text(InPersonHelper::GOOD_ADDRESS1) - expect(page).to have_text(InPersonHelper::GOOD_CITY) - expect(page).to have_text(InPersonHelper::GOOD_ZIPCODE) - expect(page).to have_text(Idp::Constants::MOCK_IDV_APPLICANT[:state]) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS1).twice + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ADDRESS2).twice + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_CITY).twice + expect(page).to have_text(Idp::Constants::MOCK_IDV_APPLICANT[:state_id_jurisdiction], count: 3) + expect(page).to have_text(InPersonHelper::GOOD_IDENTITY_DOC_ZIPCODE).twice expect(page).to have_text(DocAuthHelper::GOOD_SSN_MASKED) # click update state ID button @@ -115,7 +114,6 @@ click_button t('idv.buttons.change_address_label') expect(page).to have_content(t('in_person_proofing.headings.update_address')) fill_in t('idv.form.address1'), with: '987 Fake St.' - choose t('in_person_proofing.form.address.same_address_choice_yes') click_button t('forms.buttons.submit.update') expect(page).to have_content(t('headings.verify')) expect(page).to have_current_path(idv_in_person_verify_info_path) @@ -145,7 +143,6 @@ complete_prepare_step(user) complete_location_step(user) complete_state_id_step(user) - complete_address_step(user) fill_out_ssn_form_with_ssn_that_fails_resolution click_idv_continue click_idv_continue @@ -163,7 +160,6 @@ complete_prepare_step(user) complete_location_step(user) complete_state_id_step(user) - complete_address_step(user) complete_ssn_step(user) click_idv_continue From 1b7971556f2b75b5cffe7346b4c62d0748919fec Mon Sep 17 00:00:00 2001 From: svalexander Date: Mon, 18 Sep 2023 17:20:49 -0400 Subject: [PATCH 11/37] fix spacing for view files --- app/views/idv/in_person/address.html.erb | 22 +-- app/views/idv/in_person/state_id.html.erb | 162 +++++++++--------- .../idv/in_person/verify_info/show.html.erb | 66 +++---- 3 files changed, 125 insertions(+), 125 deletions(-) diff --git a/app/views/idv/in_person/address.html.erb b/app/views/idv/in_person/address.html.erb index 27760560c4b..bf5a5799ff0 100644 --- a/app/views/idv/in_person/address.html.erb +++ b/app/views/idv/in_person/address.html.erb @@ -10,17 +10,17 @@ form, url: url_for, method: 'PUT', html: { autocomplete: 'off' } ) do |f| %> - <%= render ValidatedFieldComponent.new( - collection: us_states_territories, - form: f, - input_html: { class: 'address-state-selector' }, - label: t('idv.form.state'), - label_html: { class: 'usa-label' }, - name: :state, - prompt: t('in_person_proofing.form.address.state_prompt'), - required: true, - selected: pii[:state], - ) %> + <%= render ValidatedFieldComponent.new( + collection: us_states_territories, + form: f, + input_html: { class: 'address-state-selector' }, + label: t('idv.form.state'), + label_html: { class: 'usa-label' }, + name: :state, + prompt: t('in_person_proofing.form.address.state_prompt'), + required: true, + selected: pii[:state], + ) %> <%= render ValidatedFieldComponent.new( form: f, hint: t('in_person_proofing.form.state_id.address1_hint'), diff --git a/app/views/idv/in_person/state_id.html.erb b/app/views/idv/in_person/state_id.html.erb index 3112f918ce9..4f1f255aafc 100644 --- a/app/views/idv/in_person/state_id.html.erb +++ b/app/views/idv/in_person/state_id.html.erb @@ -96,19 +96,19 @@ %>
-
- <%= render ValidatedFieldComponent.new( - name: :state_id_jurisdiction, - collection: us_states_territories, - form: f, - hint: t('in_person_proofing.form.state_id.state_id_jurisdiction_hint'), - label: t('in_person_proofing.form.state_id.state_id_jurisdiction'), - label_html: { class: 'usa-label' }, - prompt: t('in_person_proofing.form.state_id.state_id_jurisdiction_prompt'), - required: true, - selected: pii[:state_id_jurisdiction], - ) %> -
+
+ <%= render ValidatedFieldComponent.new( + name: :state_id_jurisdiction, + collection: us_states_territories, + form: f, + hint: t('in_person_proofing.form.state_id.state_id_jurisdiction_hint'), + label: t('in_person_proofing.form.state_id.state_id_jurisdiction'), + label_html: { class: 'usa-label' }, + prompt: t('in_person_proofing.form.state_id.state_id_jurisdiction_prompt'), + required: true, + selected: pii[:state_id_jurisdiction], + ) %> +
<%= render ValidatedFieldComponent.new( name: :state_id_number, @@ -123,79 +123,79 @@ ) %>
-

<%= t('in_person_proofing.headings.id_address') %>

- <%= render ValidatedFieldComponent.new( - name: :identity_doc_address_state, - collection: us_states_territories, - form: f, - input_html: { class: 'address-state-selector' }, - label: t('in_person_proofing.form.state_id.identity_doc_address_state'), - label_html: { class: 'usa-label' }, - prompt: t('in_person_proofing.form.state_id.identity_doc_address_state_prompt'), - required: true, - selected: pii[:identity_doc_address_state], - ) %> - <%= render ValidatedFieldComponent.new( - name: :identity_doc_address1, - form: f, - hint_html: { class: ['display-none', 'puerto-rico-extras'] }, - hint: t('in_person_proofing.form.state_id.address1_hint'), - input_html: { value: pii[:identity_doc_address1] }, - label: t('in_person_proofing.form.state_id.address1'), - label_html: { class: 'usa-label' }, - maxlength: 255, - required: true, - ) %> +

<%= t('in_person_proofing.headings.id_address') %>

+ <%= render ValidatedFieldComponent.new( + name: :identity_doc_address_state, + collection: us_states_territories, + form: f, + input_html: { class: 'address-state-selector' }, + label: t('in_person_proofing.form.state_id.identity_doc_address_state'), + label_html: { class: 'usa-label' }, + prompt: t('in_person_proofing.form.state_id.identity_doc_address_state_prompt'), + required: true, + selected: pii[:identity_doc_address_state], + ) %> + <%= render ValidatedFieldComponent.new( + name: :identity_doc_address1, + form: f, + hint_html: { class: ['display-none', 'puerto-rico-extras'] }, + hint: t('in_person_proofing.form.state_id.address1_hint'), + input_html: { value: pii[:identity_doc_address1] }, + label: t('in_person_proofing.form.state_id.address1'), + label_html: { class: 'usa-label' }, + maxlength: 255, + required: true, + ) %> - <%= render ValidatedFieldComponent.new( - name: :identity_doc_address2, - form: f, - hint: t('in_person_proofing.form.state_id.address2_hint'), - hint_html: { class: ['display-none', 'puerto-rico-extras'] }, - input_html: { value: pii[:identity_doc_address2] }, - label: t('in_person_proofing.form.state_id.address2'), - label_html: { class: 'usa-label' }, - maxlength: 255, - required: false, - ) %> - - <%= render ValidatedFieldComponent.new( - name: :identity_doc_city, - form: f, - input_html: { value: pii[:identity_doc_city] }, - label: t('in_person_proofing.form.state_id.city'), - label_html: { class: 'usa-label' }, - maxlength: 255, - required: true, - ) %> -
- <%# using :tel for mobile numeric keypad %> - <%= render ValidatedFieldComponent.new( - as: :tel, - error_messages: { patternMismatch: t('idv.errors.pattern_mismatch.zipcode') }, - form: f, - input_html: { value: pii[:identity_doc_zipcode], class: 'zipcode' }, - label: t('in_person_proofing.form.state_id.zipcode'), - label_html: { class: 'usa-label' }, - name: :identity_doc_zipcode, - pattern: '\d{5}([\-]\d{4})?', - required: true, - ) %> -
<%= render ValidatedFieldComponent.new( - as: :radio_buttons, - checked: pii[:same_address_as_id], - collection: [ - [t('in_person_proofing.form.state_id.same_address_as_id_yes'), true], - [t('in_person_proofing.form.state_id.same_address_as_id_no'), false], - ], + name: :identity_doc_address2, form: f, - label: t('in_person_proofing.form.state_id.same_address_as_id'), - legend_html: { class: 'h2' }, - name: :same_address_as_id, + hint: t('in_person_proofing.form.state_id.address2_hint'), + hint_html: { class: ['display-none', 'puerto-rico-extras'] }, + input_html: { value: pii[:identity_doc_address2] }, + label: t('in_person_proofing.form.state_id.address2'), + label_html: { class: 'usa-label' }, + maxlength: 255, + required: false, + ) %> + + <%= render ValidatedFieldComponent.new( + name: :identity_doc_city, + form: f, + input_html: { value: pii[:identity_doc_city] }, + label: t('in_person_proofing.form.state_id.city'), + label_html: { class: 'usa-label' }, + maxlength: 255, required: true, - wrapper: :uswds_radio_buttons, ) %> +
+ <%# using :tel for mobile numeric keypad %> + <%= render ValidatedFieldComponent.new( + as: :tel, + error_messages: { patternMismatch: t('idv.errors.pattern_mismatch.zipcode') }, + form: f, + input_html: { value: pii[:identity_doc_zipcode], class: 'zipcode' }, + label: t('in_person_proofing.form.state_id.zipcode'), + label_html: { class: 'usa-label' }, + name: :identity_doc_zipcode, + pattern: '\d{5}([\-]\d{4})?', + required: true, + ) %> +
+ <%= render ValidatedFieldComponent.new( + as: :radio_buttons, + checked: pii[:same_address_as_id], + collection: [ + [t('in_person_proofing.form.state_id.same_address_as_id_yes'), true], + [t('in_person_proofing.form.state_id.same_address_as_id_no'), false], + ], + form: f, + label: t('in_person_proofing.form.state_id.same_address_as_id'), + legend_html: { class: 'h2' }, + name: :same_address_as_id, + required: true, + wrapper: :uswds_radio_buttons, + ) %> <%= f.submit do %> <% if updating_state_id %> diff --git a/app/views/idv/in_person/verify_info/show.html.erb b/app/views/idv/in_person/verify_info/show.html.erb index 016422cf450..8dbb5d8573b 100644 --- a/app/views/idv/in_person/verify_info/show.html.erb +++ b/app/views/idv/in_person/verify_info/show.html.erb @@ -25,9 +25,9 @@ locals:
-
-

<%= t('headings.state_id') %>

-
+
+

<%= t('headings.state_id') %>

+
<%= t('idv.form.first_name') %>:
<%= @pii[:first_name] %>
@@ -42,34 +42,34 @@ locals: <%= I18n.l(Date.parse(@pii[:dob]), format: I18n.t('time.formats.event_date')) %>
-
-
<%= t('idv.form.issuing_state') %>:
-
<%= @pii[:state_id_jurisdiction] %>
-
+
+
<%= t('idv.form.issuing_state') %>:
+
<%= @pii[:state_id_jurisdiction] %>
+
<%= t('idv.form.id_number') %>:
<%= @pii[:state_id_number] %>
-
-
<%= t('idv.form.address1') %>:
-
<%= @pii[:identity_doc_address1] %>
-
-
-
<%= t('idv.form.address2') %>:
-
<%= @pii[:identity_doc_address2].presence %>
-
-
-
<%= t('idv.form.city') %>:
-
<%= @pii[:identity_doc_city] %>
-
-
-
<%= t('idv.form.state') %>:
-
<%= @pii[:identity_doc_address_state] %>
-
-
-
<%= t('idv.form.zipcode') %>:
-
<%= @pii[:identity_doc_zipcode] %>
-
+
+
<%= t('idv.form.address1') %>:
+
<%= @pii[:identity_doc_address1] %>
+
+
+
<%= t('idv.form.address2') %>:
+
<%= @pii[:identity_doc_address2].presence %>
+
+
+
<%= t('idv.form.city') %>:
+
<%= @pii[:identity_doc_city] %>
+
+
+
<%= t('idv.form.state') %>:
+
<%= @pii[:identity_doc_address_state] %>
+
+
+
<%= t('idv.form.zipcode') %>:
+
<%= @pii[:identity_doc_zipcode] %>
+
<%= button_to( @@ -82,9 +82,9 @@ locals:
-
-

<%= t('headings.residential_address') %>

-
+
+

<%= t('headings.residential_address') %>

+
<%= t('idv.form.address1') %>:
<%= @pii[:address1] %>
@@ -117,9 +117,9 @@ locals:
-
-

<%= t('headings.ssn') %>

-
+
+

<%= t('headings.ssn') %>

+
<%= t('idv.form.ssn') %>: <%= render( 'shared/masked_text', From c7184c84e4dc7a088571b2d7e56b835eb4b3ecdc Mon Sep 17 00:00:00 2001 From: svalexander Date: Mon, 18 Sep 2023 17:45:59 -0400 Subject: [PATCH 12/37] update test names in state id step spec --- spec/services/idv/steps/in_person/state_id_step_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/services/idv/steps/in_person/state_id_step_spec.rb b/spec/services/idv/steps/in_person/state_id_step_spec.rb index 59083836b15..270a32b6117 100644 --- a/spec/services/idv/steps/in_person/state_id_step_spec.rb +++ b/spec/services/idv/steps/in_person/state_id_step_spec.rb @@ -81,7 +81,7 @@ end end - context 'when capture_secondary_id_enabled is...' do + context 'when same_address_as_id is...' do let(:pii_from_user) { flow.flow_session[:pii_from_user] } let(:params) { ActionController::Parameters.new({ state_id: submitted_values }) } let(:dob) { InPersonHelper::GOOD_DOB } @@ -103,7 +103,7 @@ and_return(enrollment) end - context 'same_address_as_id changed from "true" to "false"' do + context 'changed from "true" to "false"' do let(:submitted_values) do { dob:, @@ -157,7 +157,7 @@ end end - context 'same_address_as_id changed from "false" to "true"' do + context 'changed from "false" to "true"' do let(:submitted_values) do { dob:, @@ -195,7 +195,7 @@ end end - context 'same_address_as_id does not change from from "false"' do + context 'not changed from "false"' do let(:submitted_values) do { dob:, From 4f6e353828ea51847a828bc1609b7f73735d6450 Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 20 Sep 2023 12:24:48 -0400 Subject: [PATCH 13/37] update proofers, jobs and analytics spec --- app/jobs/resolution_proofing_job.rb | 6 +-- app/services/idv/steps/doc_auth_base_step.rb | 4 -- .../resolution/progressive_proofer.rb | 41 +++++-------------- .../proofing/resolution/result_adjudicator.rb | 8 +--- .../idv/verify_info_controller_spec.rb | 1 - spec/features/idv/analytics_spec.rb | 26 ++++++------ spec/jobs/resolution_proofing_job_spec.rb | 1 - spec/support/features/in_person_helper.rb | 4 +- 8 files changed, 27 insertions(+), 64 deletions(-) diff --git a/app/jobs/resolution_proofing_job.rb b/app/jobs/resolution_proofing_job.rb index 650e1ef1a85..a4fe1cd7e1d 100644 --- a/app/jobs/resolution_proofing_job.rb +++ b/app/jobs/resolution_proofing_job.rb @@ -19,7 +19,6 @@ def perform( encrypted_arguments:, trace_id:, should_proof_state_id:, - double_address_verification: false, user_id: nil, threatmetrix_session_id: nil, request_ip: nil @@ -44,7 +43,6 @@ def perform( threatmetrix_session_id: threatmetrix_session_id, request_ip: request_ip, should_proof_state_id: should_proof_state_id, - double_address_verification: double_address_verification, ) document_capture_session = DocumentCaptureSession.new(result_id: result_id) @@ -70,8 +68,7 @@ def make_vendor_proofing_requests( applicant_pii:, threatmetrix_session_id:, request_ip:, - should_proof_state_id:, - double_address_verification: + should_proof_state_id: ) result = resolution_proofer.proof( applicant_pii: applicant_pii, @@ -79,7 +76,6 @@ def make_vendor_proofing_requests( threatmetrix_session_id: threatmetrix_session_id, request_ip: request_ip, should_proof_state_id: should_proof_state_id, - double_address_verification: double_address_verification, timer: timer, ) diff --git a/app/services/idv/steps/doc_auth_base_step.rb b/app/services/idv/steps/doc_auth_base_step.rb index 593bb51d77a..64679881331 100644 --- a/app/services/idv/steps/doc_auth_base_step.rb +++ b/app/services/idv/steps/doc_auth_base_step.rb @@ -7,10 +7,6 @@ def initialize(flow) private - def capture_secondary_id_enabled? - current_user.establishing_in_person_enrollment.capture_secondary_id_enabled - end - def save_proofing_components return unless current_user diff --git a/app/services/proofing/resolution/progressive_proofer.rb b/app/services/proofing/resolution/progressive_proofer.rb index aae6cac3a24..34d9289c92d 100644 --- a/app/services/proofing/resolution/progressive_proofer.rb +++ b/app/services/proofing/resolution/progressive_proofer.rb @@ -7,8 +7,6 @@ module Resolution # address or separate residential and identity document addresses class ProgressiveProofer # @param [Hash] applicant_pii keys are symbols and values are strings, confidential user info - # @param [Boolean] double_address_verification flag that indicates if user will have - # both state id address and current residential address verified # @param [String] request_ip IP address for request # @param [Boolean] should_proof_state_id based on state id jurisdiction, indicates if # there should be a state id proofing request made to aamva @@ -18,7 +16,6 @@ class ProgressiveProofer # @return [ResultAdjudicator] object which contains the logic to determine proofing's result def proof( applicant_pii:, - double_address_verification:, request_ip:, should_proof_state_id:, threatmetrix_session_id:, @@ -33,22 +30,18 @@ def proof( user_email: user_email, ) - residential_instant_verify_result = proof_residential_address_if_needed( + residential_instant_verify_result = proof_residential_address( applicant_pii: applicant_pii, timer: timer, - double_address_verification: double_address_verification, ) applicant_pii_transformed = applicant_pii.clone - if double_address_verification - applicant_pii_transformed = with_state_id_address(applicant_pii_transformed) - end + applicant_pii_transformed = with_state_id_address(applicant_pii_transformed) instant_verify_result = proof_id_address_with_lexis_nexis_if_needed( applicant_pii: applicant_pii_transformed, timer: timer, residential_instant_verify_result: residential_instant_verify_result, - double_address_verification: double_address_verification, ) state_id_result = proof_id_with_aamva_if_needed( @@ -57,12 +50,10 @@ def proof( residential_instant_verify_result: residential_instant_verify_result, instant_verify_result: instant_verify_result, should_proof_state_id: should_proof_state_id, - double_address_verification: double_address_verification, ) ResultAdjudicator.new( device_profiling_result: device_profiling_result, - double_address_verification: double_address_verification, resolution_result: instant_verify_result, should_proof_state_id: should_proof_state_id, state_id_result: state_id_result, @@ -100,24 +91,16 @@ def proof_with_threatmetrix_if_needed( end end - def proof_residential_address_if_needed( + def proof_residential_address( applicant_pii:, - timer:, - double_address_verification: + timer: ) - return residential_address_unnecessary_result unless double_address_verification timer.time('residential address') do resolution_proofer.proof(applicant_pii) end end - def residential_address_unnecessary_result - Proofing::AddressResult.new( - success: true, errors: {}, exception: nil, vendor_name: 'ResidentialAddressNotRequired', - ) - end - def resolution_cannot_pass Proofing::AddressResult.new( success: false, errors: {}, exception: nil, vendor_name: 'ResolutionCannotPass', @@ -125,9 +108,8 @@ def resolution_cannot_pass end def proof_id_address_with_lexis_nexis_if_needed(applicant_pii:, timer:, - residential_instant_verify_result:, - double_address_verification:) - if applicant_pii[:same_address_as_id] == 'true' && double_address_verification == true + residential_instant_verify_result:) + if applicant_pii[:same_address_as_id] == 'true' return residential_instant_verify_result end return resolution_cannot_pass unless residential_instant_verify_result.success? @@ -137,11 +119,10 @@ def proof_id_address_with_lexis_nexis_if_needed(applicant_pii:, timer:, end end - def should_proof_state_id_with_aamva?(double_address_verification:, same_address_as_id:, - should_proof_state_id:, instant_verify_result:, - residential_instant_verify_result:) + def should_proof_state_id_with_aamva?(same_address_as_id:, should_proof_state_id:, + instant_verify_result:, residential_instant_verify_result:) return false unless should_proof_state_id - if double_address_verification == false || same_address_as_id == 'true' + if same_address_as_id == 'true' user_can_pass_after_state_id_check?(instant_verify_result) else residential_instant_verify_result.success? @@ -152,12 +133,10 @@ def proof_id_with_aamva_if_needed( applicant_pii:, timer:, residential_instant_verify_result:, instant_verify_result:, - should_proof_state_id:, - double_address_verification: + should_proof_state_id: ) same_address_as_id = applicant_pii[:same_address_as_id] should_proof_state_id_with_aamva = should_proof_state_id_with_aamva?( - double_address_verification:, same_address_as_id:, should_proof_state_id:, instant_verify_result:, diff --git a/app/services/proofing/resolution/result_adjudicator.rb b/app/services/proofing/resolution/result_adjudicator.rb index 3951b6beb29..ce11ae74609 100644 --- a/app/services/proofing/resolution/result_adjudicator.rb +++ b/app/services/proofing/resolution/result_adjudicator.rb @@ -2,21 +2,19 @@ module Proofing module Resolution class ResultAdjudicator attr_reader :resolution_result, :state_id_result, :device_profiling_result, - :double_address_verification, :residential_resolution_result, :same_address_as_id + :residential_resolution_result, :same_address_as_id def initialize( resolution_result:, # InstantVerify state_id_result:, # AAMVA residential_resolution_result:, # InstantVerify Residential should_proof_state_id:, - double_address_verification:, device_profiling_result:, same_address_as_id: ) @resolution_result = resolution_result @state_id_result = state_id_result @should_proof_state_id = should_proof_state_id - @double_address_verification = double_address_verification @device_profiling_result = device_profiling_result @residential_resolution_result = residential_resolution_result @same_address_as_id = same_address_as_id # this is a string, "true" or "false" @@ -37,7 +35,6 @@ def adjudicated_result device_profiling_adjudication_reason: device_profiling_reason, resolution_adjudication_reason: resolution_reason, should_proof_state_id: should_proof_state_id?, - double_address_verification: double_address_verification, stages: { resolution: resolution_result.to_h, residential_address: residential_resolution_result.to_h, @@ -87,8 +84,7 @@ def device_profiling_result_and_reason end def resolution_result_and_reason - if !residential_resolution_result.success? && - same_address_as_id == 'false' && double_address_verification == true + if !residential_resolution_result.success? && same_address_as_id == 'false' [false, :fail_resolution_skip_state_id] elsif resolution_result.success? && state_id_result.success? [true, :pass_resolution_and_state_id] diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb index 97cd1a4f177..e79c6e40430 100644 --- a/spec/controllers/idv/verify_info_controller_spec.rb +++ b/spec/controllers/idv/verify_info_controller_spec.rb @@ -299,7 +299,6 @@ verified_attributes: [], ), device_profiling_result: Proofing::DdpResult.new(success: true), - double_address_verification: false, residential_resolution_result: Proofing::Resolution::Result.new(success: true), resolution_result: Proofing::Resolution::Result.new(success: true), same_address_as_id: true, diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb index 3851f80b57e..d50f2d0e914 100644 --- a/spec/features/idv/analytics_spec.rb +++ b/spec/features/idv/analytics_spec.rb @@ -91,7 +91,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'Doc Auth', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, irs_reproofing: false, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', double_address_verification: false, resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired' }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: 'aaa-bbb-ccc', success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone of record visited' => { acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, skip_hybrid_handoff: nil, @@ -196,7 +196,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'Doc Auth', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, irs_reproofing: false, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', double_address_verification: false, resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired' }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: 'aaa-bbb-ccc', success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone of record visited' => { acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, skip_hybrid_handoff: nil, @@ -283,29 +283,29 @@ step: 'state_id', flow_path: 'standard', step_count: 1, analytics_id: 'In Person Proofing', irs_reproofing: false }, 'IdV: in person proofing state_id submitted' => { - success: true, flow_path: 'standard', step: 'state_id', step_count: 1, analytics_id: 'In Person Proofing', irs_reproofing: false, errors: {}, same_address_as_id: nil + success: true, flow_path: 'standard', step: 'state_id', step_count: 1, analytics_id: 'In Person Proofing', irs_reproofing: false, errors: {}, same_address_as_id: false }, 'IdV: in person proofing address visited' => { - step: 'address', flow_path: 'standard', step_count: 1, analytics_id: 'In Person Proofing', irs_reproofing: false + step: 'address', flow_path: 'standard', step_count: 1, analytics_id: 'In Person Proofing', irs_reproofing: false, same_address_as_id: false }, - 'IdV: in person proofing address submitted' => { - success: true, step: 'address', flow_path: 'standard', step_count: 1, analytics_id: 'In Person Proofing', irs_reproofing: false, errors: {}, same_address_as_id: true + 'IdV: in person proofing residential address submitted' => { + success: true, step: 'address', flow_path: 'standard', step_count: 1, analytics_id: 'In Person Proofing', irs_reproofing: false, errors: {}, same_address_as_id: false }, 'IdV: doc auth ssn visited' => { - analytics_id: 'In Person Proofing', step: 'ssn', flow_path: 'standard', irs_reproofing: false, getting_started_ab_test_bucket: :welcome_default, acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, same_address_as_id: true + analytics_id: 'In Person Proofing', step: 'ssn', flow_path: 'standard', irs_reproofing: false, getting_started_ab_test_bucket: :welcome_default, acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, same_address_as_id: false }, 'IdV: doc auth ssn submitted' => { - analytics_id: 'In Person Proofing', success: true, step: 'ssn', flow_path: 'standard', irs_reproofing: false, errors: {}, getting_started_ab_test_bucket: :welcome_default, acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, same_address_as_id: true + analytics_id: 'In Person Proofing', success: true, step: 'ssn', flow_path: 'standard', irs_reproofing: false, errors: {}, getting_started_ab_test_bucket: :welcome_default, acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, same_address_as_id: false }, 'IdV: doc auth verify visited' => { - analytics_id: 'In Person Proofing', step: 'verify', flow_path: 'standard', irs_reproofing: false, same_address_as_id: true, getting_started_ab_test_bucket: :welcome_default, acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil + analytics_id: 'In Person Proofing', step: 'verify', flow_path: 'standard', irs_reproofing: false, same_address_as_id: false, getting_started_ab_test_bucket: :welcome_default, acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil }, 'IdV: doc auth verify submitted' => { - analytics_id: 'In Person Proofing', step: 'verify', flow_path: 'standard', irs_reproofing: false, same_address_as_id: true, getting_started_ab_test_bucket: :welcome_default, acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil + analytics_id: 'In Person Proofing', step: 'verify', flow_path: 'standard', irs_reproofing: false, same_address_as_id: false, getting_started_ab_test_bucket: :welcome_default, acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'In Person Proofing', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, irs_reproofing: false, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', double_address_verification: false, resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired' }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: 'aaa-bbb-ccc', success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone confirmation form' => { success: true, errors: {}, phone_type: :mobile, types: [:fixed_or_mobile], carrier: 'Test Mobile Carrier', country_code: 'US', area_code: '202', acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, skip_hybrid_handoff: nil, otp_delivery_preference: 'sms', @@ -482,8 +482,6 @@ before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(false) allow(Idv::InPersonConfig).to receive(:enabled_for_issuer?).and_return(true) allow_any_instance_of(Idv::InPerson::ReadyToVerifyPresenter). to receive(:service_provider_homepage_url).and_return(return_sp_url) @@ -493,7 +491,7 @@ start_idv_from_sp(:saml) sign_in_and_2fa_user(user) begin_in_person_proofing(user) - complete_all_in_person_proofing_steps(user) + complete_all_in_person_proofing_steps(user, same_address_as_id: false) complete_phone_step(user) complete_review_step(user) acknowledge_and_confirm_personal_key diff --git a/spec/jobs/resolution_proofing_job_spec.rb b/spec/jobs/resolution_proofing_job_spec.rb index 84fc0c97232..6de6e15d875 100644 --- a/spec/jobs/resolution_proofing_job_spec.rb +++ b/spec/jobs/resolution_proofing_job_spec.rb @@ -331,7 +331,6 @@ user_id: user.id, threatmetrix_session_id: threatmetrix_session_id, request_ip: request_ip, - double_address_verification: true, ) end diff --git a/spec/support/features/in_person_helper.rb b/spec/support/features/in_person_helper.rb index b0fffbabeba..9ae6de8b41e 100644 --- a/spec/support/features/in_person_helper.rb +++ b/spec/support/features/in_person_helper.rb @@ -142,8 +142,8 @@ def complete_verify_step(_user = nil) def complete_all_in_person_proofing_steps(user = user_with_2fa, same_address_as_id: true) complete_prepare_step(user) complete_location_step(user) - complete_state_id_step(user) - complete_address_step(user) unless same_address_as_id + complete_state_id_step(user, same_address_as_id: same_address_as_id) + complete_address_step(user, same_address_as_id: same_address_as_id) unless same_address_as_id complete_ssn_step(user) complete_verify_step(user) end From 72363697b13dd1a21e72216737ac9f051efc7365 Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 20 Sep 2023 13:46:26 -0400 Subject: [PATCH 14/37] update progressive proofer spec --- .../resolution/progressive_proofer_spec.rb | 556 ++++++++---------- 1 file changed, 258 insertions(+), 298 deletions(-) diff --git a/spec/services/proofing/resolution/progressive_proofer_spec.rb b/spec/services/proofing/resolution/progressive_proofer_spec.rb index 58e9624c7e1..0e54d6b232a 100644 --- a/spec/services/proofing/resolution/progressive_proofer_spec.rb +++ b/spec/services/proofing/resolution/progressive_proofer_spec.rb @@ -3,7 +3,6 @@ RSpec.describe Proofing::Resolution::ProgressiveProofer do let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS } let(:should_proof_state_id) { true } - let(:double_address_verification) { false } let(:request_ip) { Faker::Internet.ip_v4_address } let(:threatmetrix_session_id) { SecureRandom.uuid } let(:timer) { JobHelpers::Timer.new } @@ -39,7 +38,6 @@ subject(:proof) do instance.proof( applicant_pii: applicant_pii, - double_address_verification: double_address_verification, request_ip: request_ip, should_proof_state_id: should_proof_state_id, threatmetrix_session_id: threatmetrix_session_id, @@ -47,6 +45,9 @@ user_email: user.confirmed_email_addresses.first.email, ) end + let(:resolution_result) do + instance_double(Proofing::Resolution::Result) + end it 'returns a ResultAdjudicator' do proofing_result = proof @@ -55,57 +56,30 @@ expect(proofing_result.same_address_as_id).to eq(applicant_pii[:same_address_as_id]) end - context 'when double address verification is enabled' do - let(:double_address_verification) { true } - let(:resolution_result) do - instance_double(Proofing::Resolution::Result) - end - context 'ThreatMetrix is enabled' do - let(:threatmetrix_proofer) { instance_double(Proofing::LexisNexis::Ddp::Proofer) } - - before do - allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). - and_return(true) - allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_mock_enabled). - and_return(false) - allow(instance).to receive(:lexisnexis_ddp_proofer).and_return(threatmetrix_proofer) - - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(resolution_result) - allow(resolution_result).to receive(:success?).and_return(true) - allow(instant_verify_proofer).to receive(:proof) - end - - it 'makes a request to the ThreatMetrix proofer' do - expect(threatmetrix_proofer).to receive(:proof) + context 'ThreatMetrix is enabled' do + let(:threatmetrix_proofer) { instance_double(Proofing::LexisNexis::Ddp::Proofer) } - subject - end + before do + allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). + and_return(true) + allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_mock_enabled). + and_return(false) + allow(instance).to receive(:lexisnexis_ddp_proofer).and_return(threatmetrix_proofer) - context 'it lacks a session id' do - let(:threatmetrix_session_id) { nil } - it 'returns a disabled result' do - result = subject + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(resolution_result) + allow(resolution_result).to receive(:success?).and_return(true) + allow(instant_verify_proofer).to receive(:proof) + end - device_profiling_result = result.device_profiling_result + it 'makes a request to the ThreatMetrix proofer' do + expect(threatmetrix_proofer).to receive(:proof) - expect(device_profiling_result.success).to be(true) - expect(device_profiling_result.client).to eq('tmx_disabled') - expect(device_profiling_result.review_status).to eq('pass') - end - end + subject end - context 'ThreatMetrix is disabled' do - before do - allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). - and_return(false) - - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(resolution_result) - allow(resolution_result).to receive(:success?).and_return(true) - allow(instant_verify_proofer).to receive(:proof) - end + context 'it lacks a session id' do + let(:threatmetrix_session_id) { nil } it 'returns a disabled result' do result = subject @@ -116,155 +90,175 @@ expect(device_profiling_result.review_status).to eq('pass') end end + end - context 'residential address and id address are the same' do - let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID } - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - let(:residential_instant_verify_proof) do + context 'ThreatMetrix is disabled' do + before do + allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). + and_return(false) + + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(resolution_result) + allow(resolution_result).to receive(:success?).and_return(true) + allow(instant_verify_proofer).to receive(:proof) + end + it 'returns a disabled result' do + result = subject + + device_profiling_result = result.device_profiling_result + + expect(device_profiling_result.success).to be(true) + expect(device_profiling_result.client).to eq('tmx_disabled') + expect(device_profiling_result.review_status).to eq('pass') + end + end + + context 'residential address and id address are the same' do + let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID } + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + let(:residential_instant_verify_proof) do + instance_double(Proofing::Resolution::Result) + end + before do + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof). + and_return(residential_instant_verify_proof) + allow(residential_instant_verify_proof).to receive(:success?).and_return(true) + end + + it 'only makes one request to LexisNexis InstantVerify' do + expect(instant_verify_proofer).to receive(:proof).exactly(:once) + expect(aamva_proofer).to receive(:proof) + + subject + end + + it 'produces a result adjudicator with correct information' do + expect(aamva_proofer).to receive(:proof) + + result = subject + + expect(result.same_address_as_id).to eq('true') + expect(result.resolution_result).to eq(result.residential_resolution_result) + end + + context 'LexisNexis InstantVerify fails' do + let(:result_that_failed_instant_verify) do instance_double(Proofing::Resolution::Result) end before do - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof). - and_return(residential_instant_verify_proof) - allow(residential_instant_verify_proof).to receive(:success?).and_return(true) + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(result_that_failed_instant_verify) + allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). + and_return(result_that_failed_instant_verify) + allow(instance).to receive(:user_can_pass_after_state_id_check?). + with(result_that_failed_instant_verify). + and_return(true) + allow(result_that_failed_instant_verify).to receive(:success?). + and_return(false) end - it 'only makes one request to LexisNexis InstantVerify' do - expect(instant_verify_proofer).to receive(:proof).exactly(:once) - expect(aamva_proofer).to receive(:proof) + context 'the failure can be covered by AAMVA' do + before do + allow(result_that_failed_instant_verify). + to receive(:attributes_requiring_additional_verification). + and_return([:address]) + end - subject - end + context 'it is not covered by AAMVA' do + let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } + before do + allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) + allow(failed_aamva_proof).to receive(:verified_attributes).and_return([]) + allow(failed_aamva_proof).to receive(:success?).and_return(false) + end + it 'indicates the aamva check did not pass' do + result = subject - it 'produces a result adjudicator with correct information' do - expect(aamva_proofer).to receive(:proof) + expect(result.state_id_result.success?).to eq(false) + end + end - result = subject + context 'it is covered by AAMVA' do + let(:successful_aamva_proof) { instance_double(Proofing::StateIdResult) } + before do + allow(aamva_proofer).to receive(:proof).and_return(successful_aamva_proof) + allow(successful_aamva_proof).to receive(:verified_attributes). + and_return([:address]) + allow(successful_aamva_proof).to receive(:success?).and_return(true) + end + it 'indicates aamva did pass' do + result = subject - expect(result.same_address_as_id).to eq('true') - expect(result.double_address_verification).to eq(true) - expect(result.resolution_result).to eq(result.residential_resolution_result) + expect(result.state_id_result.success?).to eq(true) + end + end end + end - context 'LexisNexis InstantVerify fails' do - let(:result_that_failed_instant_verify) do + context 'LexisNexis InstantVerify passes for residential address and id address' do + context 'should proof with AAMVA' do + let(:id_resolution_that_passed_instant_verify) do + instance_double(Proofing::Resolution::Result) + end + let(:residential_resolution_that_passed_instant_verify) do instance_double(Proofing::Resolution::Result) end + before do + allow(instance).to receive(:proof_residential_address). + and_return(residential_resolution_that_passed_instant_verify) allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(result_that_failed_instant_verify) - allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). - and_return(result_that_failed_instant_verify) + and_return(id_resolution_that_passed_instant_verify) + allow(instant_verify_proofer).to receive(:proof). + with(hash_including(state_id_address)). + and_return(id_resolution_that_passed_instant_verify) allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(result_that_failed_instant_verify). + with(id_resolution_that_passed_instant_verify). + and_return(true) + allow(id_resolution_that_passed_instant_verify).to receive(:success?). + and_return(true) + allow(residential_resolution_that_passed_instant_verify).to receive(:success?). and_return(true) - allow(result_that_failed_instant_verify).to receive(:success?). - and_return(false) end - context 'the failure can be covered by AAMVA' do - before do - allow(result_that_failed_instant_verify). - to receive(:attributes_requiring_additional_verification). - and_return([:address]) - end - - context 'it is not covered by AAMVA' do - let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } - before do - allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - allow(failed_aamva_proof).to receive(:verified_attributes).and_return([]) - allow(failed_aamva_proof).to receive(:success?).and_return(false) - end - it 'indicates the aamva check did not pass' do - result = subject - - expect(result.state_id_result.success?).to eq(false) - end - end + it 'makes a request to the AAMVA proofer' do + expect(aamva_proofer).to receive(:proof) - context 'it is covered by AAMVA' do - let(:successful_aamva_proof) { instance_double(Proofing::StateIdResult) } - before do - allow(aamva_proofer).to receive(:proof).and_return(successful_aamva_proof) - allow(successful_aamva_proof).to receive(:verified_attributes). - and_return([:address]) - allow(successful_aamva_proof).to receive(:success?).and_return(true) - end - it 'indicates aamva did pass' do - result = subject - - expect(result.state_id_result.success?).to eq(true) - end - end + subject end - end - context 'LexisNexis InstantVerify passes for residential address and id address' do - context 'should proof with AAMVA' do - let(:id_resolution_that_passed_instant_verify) do - instance_double(Proofing::Resolution::Result) - end - let(:residential_resolution_that_passed_instant_verify) do - instance_double(Proofing::Resolution::Result) + context 'AAMVA proofing fails' do + let(:aamva_client) { instance_double(Proofing::Aamva::VerificationClient) } + let(:failed_aamva_proof) do + instance_double(Proofing::StateIdResult) end - before do - allow(instance).to receive(:proof_residential_address_if_needed). - and_return(residential_resolution_that_passed_instant_verify) - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(id_resolution_that_passed_instant_verify) - allow(instant_verify_proofer).to receive(:proof). - with(hash_including(state_id_address)). - and_return(id_resolution_that_passed_instant_verify) - allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(id_resolution_that_passed_instant_verify). - and_return(true) - allow(id_resolution_that_passed_instant_verify).to receive(:success?). - and_return(true) - allow(residential_resolution_that_passed_instant_verify).to receive(:success?). - and_return(true) + allow(Proofing::Aamva::VerificationClient).to receive(:new).and_return(aamva_client) + allow(failed_aamva_proof).to receive(:success?).and_return(false) end + it 'returns a result adjudicator that indicates the aamva proofing failed' do + allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - it 'makes a request to the AAMVA proofer' do - expect(aamva_proofer).to receive(:proof) - - subject - end + result = subject - context 'AAMVA proofing fails' do - let(:aamva_client) { instance_double(Proofing::Aamva::VerificationClient) } - let(:failed_aamva_proof) do - instance_double(Proofing::StateIdResult) - end - before do - allow(Proofing::Aamva::VerificationClient).to receive(:new).and_return(aamva_client) - allow(failed_aamva_proof).to receive(:success?).and_return(false) - end - it 'returns a result adjudicator that indicates the aamva proofing failed' do - allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - - result = subject - - expect(result.state_id_result.success?).to eq(false) - end + expect(result.state_id_result.success?).to eq(false) end end end end + end - context 'residential address and id address are different' do - let(:residential_address_proof) do - instance_double(Proofing::Resolution::Result) - end - let(:resolution_result) do - instance_double(Proofing::Resolution::Result) - end - let(:double_address_verification) { true } - let(:applicant_pii) do - JSON.parse(<<-STR, symbolize_names: true) + context 'residential address and id address are different' do + let(:residential_address_proof) do + instance_double(Proofing::Resolution::Result) + end + let(:resolution_result) do + instance_double(Proofing::Resolution::Result) + end + let(:applicant_pii) do + JSON.parse(<<-STR, symbolize_names: true) { "uuid": "3e8db152-4d35-4207-b828-3eee8c52c50f", "middle_name": "", @@ -291,164 +285,130 @@ "state_id_type": "drivers_license", "uuid_prefix": null } - STR - end - let(:residential_address) do - { - address1: applicant_pii[:address1], - address2: applicant_pii[:address2], - city: applicant_pii[:city], - state: applicant_pii[:state], - state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], - zipcode: applicant_pii[:zipcode], - } - end - let(:state_id_address) do - { - address1: applicant_pii[:identity_doc_address1], - address2: applicant_pii[:identity_doc_address2], - city: applicant_pii[:identity_doc_city], - state: applicant_pii[:identity_doc_address_state], - state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], - zipcode: applicant_pii[:identity_doc_zipcode], - } - end - - context 'LexisNexis InstantVerify passes for residential address' do - before do - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) - allow(residential_address_proof).to receive(:success?).and_return(true) - end - context 'LexisNexis InstantVerify passes for id address' do - it 'makes two requests to the InstantVerify Proofer' do - expect(instant_verify_proofer).to receive(:proof). - with(hash_including(residential_address)). - ordered - expect(instant_verify_proofer).to receive(:proof). - with(hash_including(state_id_address)). - ordered - - subject - end + STR + end + let(:residential_address) do + { + address1: applicant_pii[:address1], + address2: applicant_pii[:address2], + city: applicant_pii[:city], + state: applicant_pii[:state], + state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], + zipcode: applicant_pii[:zipcode], + } + end + let(:state_id_address) do + { + address1: applicant_pii[:identity_doc_address1], + address2: applicant_pii[:identity_doc_address2], + city: applicant_pii[:identity_doc_city], + state: applicant_pii[:identity_doc_address_state], + state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], + zipcode: applicant_pii[:identity_doc_zipcode], + } + end - context 'AAMVA fails' do - let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - before do - allow(instance).to receive(:proof_id_with_aamva_if_needed). - and_return(failed_aamva_proof) - allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - allow(failed_aamva_proof).to receive(:success?).and_return(false) - allow(resolution_result).to receive(:errors) - end - - it 'returns the correct resolution results' do - result_adjudicator = subject - - expect(result_adjudicator.residential_resolution_result.success?).to be(true) - expect(result_adjudicator.resolution_result.success?).to be(true) - expect(result_adjudicator.state_id_result.success?).to be(false) - end - end - end + context 'LexisNexis InstantVerify passes for residential address' do + before do + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) + allow(residential_address_proof).to receive(:success?).and_return(true) end - context 'LexisNexis InstantVerify fails for residential address' do - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - - before do - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - allow(instance).to receive(:proof_residential_address_if_needed). - and_return(residential_address_proof) - allow(instant_verify_proofer).to receive(:proof). + context 'LexisNexis InstantVerify passes for id address' do + it 'makes two requests to the InstantVerify Proofer' do + expect(instant_verify_proofer).to receive(:proof). with(hash_including(residential_address)). - and_return(residential_address_proof) - allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(residential_address_proof). - and_return(false) - allow(residential_address_proof).to receive(:success?). - and_return(false) - end - - it 'does not make unnecessary calls' do - expect(aamva_proofer).to_not receive(:proof) - expect(instant_verify_proofer).to_not receive(:proof). - with(hash_including(state_id_address)) + ordered + expect(instant_verify_proofer).to receive(:proof). + with(hash_including(state_id_address)). + ordered subject end - end - - context 'LexisNexis InstantVerify fails for id address & passes for residential address' do - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - let(:result_that_failed_instant_verify) do - instance_double(Proofing::Resolution::Result) - end - - before do - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(result_that_failed_instant_verify) - allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). - and_return(result_that_failed_instant_verify) - end - context 'the failure can be covered by AAMVA' do + context 'AAMVA fails' do let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } before do - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) - allow(residential_address_proof).to receive(:success?).and_return(true) - - allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(result_that_failed_instant_verify). - and_return(true) - allow(result_that_failed_instant_verify). - to receive(:attributes_requiring_additional_verification). - and_return([:address]) - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:proof_id_with_aamva_if_needed). + and_return(failed_aamva_proof) + allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) + allow(failed_aamva_proof).to receive(:success?).and_return(false) + allow(resolution_result).to receive(:errors) end - it 'calls AAMVA' do - expect(aamva_proofer).to receive(:proof) - subject + it 'returns the correct resolution results' do + result_adjudicator = subject + + expect(result_adjudicator.residential_resolution_result.success?).to be(true) + expect(result_adjudicator.resolution_result.success?).to be(true) + expect(result_adjudicator.state_id_result.success?).to be(false) end end end end - end + context 'LexisNexis InstantVerify fails for residential address' do + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - context 'when double address verification is not enabled' do - let(:double_address_verification) { false } - let(:applicant_pii) do - # test ensures same_address_as_id value has no effect - Idp::Constants::MOCK_IDV_APPLICANT.merge(same_address_as_id: 'true') - end - let(:residential_instant_verify_proof) do - instance_double(Proofing::Resolution::Result) + before do + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:proof_residential_address). + and_return(residential_address_proof) + allow(instant_verify_proofer).to receive(:proof). + with(hash_including(residential_address)). + and_return(residential_address_proof) + allow(instance).to receive(:user_can_pass_after_state_id_check?). + with(residential_address_proof). + and_return(false) + allow(residential_address_proof).to receive(:success?). + and_return(false) + end + + it 'does not make unnecessary calls' do + expect(aamva_proofer).to_not receive(:proof) + expect(instant_verify_proofer).to_not receive(:proof). + with(hash_including(state_id_address)) + + subject + end end - it 'makes one request to LexisNexis InstantVerify' do - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof). - and_return(residential_instant_verify_proof) - allow(residential_instant_verify_proof).to receive(:success?).and_return(true) + context 'LexisNexis InstantVerify fails for id address & passes for residential address' do + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + let(:result_that_failed_instant_verify) do + instance_double(Proofing::Resolution::Result) + end - expect(instant_verify_proofer).to receive(:proof).exactly(:once) + before do + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(result_that_failed_instant_verify) + allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). + and_return(result_that_failed_instant_verify) + end - subject - end + context 'the failure can be covered by AAMVA' do + let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + before do + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) + allow(residential_address_proof).to receive(:success?).and_return(true) - it 'returns distinct objects for the resolution result and residential resolution result' do - result = subject + allow(instance).to receive(:user_can_pass_after_state_id_check?). + with(result_that_failed_instant_verify). + and_return(true) + allow(result_that_failed_instant_verify). + to receive(:attributes_requiring_additional_verification). + and_return([:address]) + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + end + it 'calls AAMVA' do + expect(aamva_proofer).to receive(:proof) - expect(result.residential_resolution_result).to_not eq(result.resolution_result) - expect( - result.residential_resolution_result. - vendor_name, - ).to eq('ResidentialAddressNotRequired') - expect(result.resolution_result.vendor_name).to eq('lexisnexis:instant_verify') + subject + end + end end end end From 77a46d2683066f93db1f5e9fa6857a82b5ceed75 Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 20 Sep 2023 17:18:14 -0400 Subject: [PATCH 15/37] update pii in res proofing job spec --- spec/jobs/resolution_proofing_job_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/jobs/resolution_proofing_job_spec.rb b/spec/jobs/resolution_proofing_job_spec.rb index 6de6e15d875..504de794a04 100644 --- a/spec/jobs/resolution_proofing_job_spec.rb +++ b/spec/jobs/resolution_proofing_job_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' RSpec.describe ResolutionProofingJob, type: :job do - let(:pii) { Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN } + let(:pii) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID } let(:encrypted_arguments) do Encryption::Encryptors::BackgroundProofingArgEncryptor.new.encrypt( { applicant_pii: pii }.to_json, From cab5c212e5f69041230a846922f17626fd2fce7a Mon Sep 17 00:00:00 2001 From: svalexander Date: Thu, 21 Sep 2023 18:37:16 -0400 Subject: [PATCH 16/37] keep dav for proofing --- .../concerns/idv/verify_info_concern.rb | 6 +++ app/jobs/resolution_proofing_job.rb | 6 ++- app/services/idv/agent.rb | 4 +- .../resolution/progressive_proofer.rb | 41 ++++++++++++++----- .../proofing/resolution/result_adjudicator.rb | 10 +++-- .../idv/doc_auth/verify_info_step_spec.rb | 1 + 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb index da526b3decd..cf2acf6ffbe 100644 --- a/app/controllers/concerns/idv/verify_info_concern.rb +++ b/app/controllers/concerns/idv/verify_info_concern.rb @@ -37,6 +37,7 @@ def shared_update user_id: current_user.id, threatmetrix_session_id: idv_session.threatmetrix_session_id, request_ip: request.remote_ip, + double_address_verification: capture_secondary_id_enabled, ) return true @@ -44,6 +45,11 @@ def shared_update private + def capture_secondary_id_enabled + # if in person return true else return false + user_session['idv/doc_auth'].empty? + end + def should_use_aamva?(pii) aamva_state?(pii) && !aamva_disallowed_for_service_provider? end diff --git a/app/jobs/resolution_proofing_job.rb b/app/jobs/resolution_proofing_job.rb index a4fe1cd7e1d..87b597b43f0 100644 --- a/app/jobs/resolution_proofing_job.rb +++ b/app/jobs/resolution_proofing_job.rb @@ -19,6 +19,7 @@ def perform( encrypted_arguments:, trace_id:, should_proof_state_id:, + double_address_verification: false, user_id: nil, threatmetrix_session_id: nil, request_ip: nil @@ -43,6 +44,7 @@ def perform( threatmetrix_session_id: threatmetrix_session_id, request_ip: request_ip, should_proof_state_id: should_proof_state_id, + double_address_verification: double_address_verification, ) document_capture_session = DocumentCaptureSession.new(result_id: result_id) @@ -68,7 +70,8 @@ def make_vendor_proofing_requests( applicant_pii:, threatmetrix_session_id:, request_ip:, - should_proof_state_id: + should_proof_state_id:, + double_address_verification: ) result = resolution_proofer.proof( applicant_pii: applicant_pii, @@ -77,6 +80,7 @@ def make_vendor_proofing_requests( request_ip: request_ip, should_proof_state_id: should_proof_state_id, timer: timer, + double_address_verification: double_address_verification, ) log_threatmetrix_info(result.device_profiling_result, user) diff --git a/app/services/idv/agent.rb b/app/services/idv/agent.rb index 4dde23c1c32..f606ea173f0 100644 --- a/app/services/idv/agent.rb +++ b/app/services/idv/agent.rb @@ -10,7 +10,8 @@ def proof_resolution( trace_id:, user_id:, threatmetrix_session_id:, - request_ip: + request_ip:, + double_address_verification: false ) document_capture_session.create_proofing_session @@ -26,6 +27,7 @@ def proof_resolution( user_id: user_id, threatmetrix_session_id: threatmetrix_session_id, request_ip: request_ip, + double_address_verification: double_address_verification, } if IdentityConfig.store.ruby_workers_idv_enabled diff --git a/app/services/proofing/resolution/progressive_proofer.rb b/app/services/proofing/resolution/progressive_proofer.rb index 34d9289c92d..f6e6ff8b2a7 100644 --- a/app/services/proofing/resolution/progressive_proofer.rb +++ b/app/services/proofing/resolution/progressive_proofer.rb @@ -8,6 +8,8 @@ module Resolution class ProgressiveProofer # @param [Hash] applicant_pii keys are symbols and values are strings, confidential user info # @param [String] request_ip IP address for request + # @param [Boolean] double_address_verification flag that indicates if user will have + # both state id address and current residential address verified # @param [Boolean] should_proof_state_id based on state id jurisdiction, indicates if # there should be a state id proofing request made to aamva # @param [String] threatmetrix_session_id identifies the threatmetrix session @@ -16,6 +18,7 @@ class ProgressiveProofer # @return [ResultAdjudicator] object which contains the logic to determine proofing's result def proof( applicant_pii:, + double_address_verification:, request_ip:, should_proof_state_id:, threatmetrix_session_id:, @@ -30,18 +33,22 @@ def proof( user_email: user_email, ) - residential_instant_verify_result = proof_residential_address( + residential_instant_verify_result = proof_residential_address_if_needed( applicant_pii: applicant_pii, timer: timer, + double_address_verification: double_address_verification, ) applicant_pii_transformed = applicant_pii.clone - applicant_pii_transformed = with_state_id_address(applicant_pii_transformed) + if double_address_verification + applicant_pii_transformed = with_state_id_address(applicant_pii_transformed) + end instant_verify_result = proof_id_address_with_lexis_nexis_if_needed( applicant_pii: applicant_pii_transformed, timer: timer, residential_instant_verify_result: residential_instant_verify_result, + double_address_verification: double_address_verification, ) state_id_result = proof_id_with_aamva_if_needed( @@ -50,10 +57,12 @@ def proof( residential_instant_verify_result: residential_instant_verify_result, instant_verify_result: instant_verify_result, should_proof_state_id: should_proof_state_id, + double_address_verification: double_address_verification, ) ResultAdjudicator.new( device_profiling_result: device_profiling_result, + double_address_verification: double_address_verification, resolution_result: instant_verify_result, should_proof_state_id: should_proof_state_id, state_id_result: state_id_result, @@ -91,16 +100,24 @@ def proof_with_threatmetrix_if_needed( end end - def proof_residential_address( + def proof_residential_address_if_needed( applicant_pii:, - timer: + timer:, + double_address_verification: ) + return residential_address_unnecessary_result unless double_address_verification timer.time('residential address') do resolution_proofer.proof(applicant_pii) end end + def residential_address_unnecessary_result + Proofing::AddressResult.new( + success: true, errors: {}, exception: nil, vendor_name: 'ResidentialAddressNotRequired', + ) + end + def resolution_cannot_pass Proofing::AddressResult.new( success: false, errors: {}, exception: nil, vendor_name: 'ResolutionCannotPass', @@ -108,8 +125,9 @@ def resolution_cannot_pass end def proof_id_address_with_lexis_nexis_if_needed(applicant_pii:, timer:, - residential_instant_verify_result:) - if applicant_pii[:same_address_as_id] == 'true' + residential_instant_verify_result:, + double_address_verification:) + if applicant_pii[:same_address_as_id] == 'true' && double_address_verification == true return residential_instant_verify_result end return resolution_cannot_pass unless residential_instant_verify_result.success? @@ -119,10 +137,11 @@ def proof_id_address_with_lexis_nexis_if_needed(applicant_pii:, timer:, end end - def should_proof_state_id_with_aamva?(same_address_as_id:, should_proof_state_id:, - instant_verify_result:, residential_instant_verify_result:) + def should_proof_state_id_with_aamva?(double_address_verification:, same_address_as_id:, + should_proof_state_id:, instant_verify_result:, + residential_instant_verify_result:) return false unless should_proof_state_id - if same_address_as_id == 'true' + if double_address_verification == false || same_address_as_id == 'true' user_can_pass_after_state_id_check?(instant_verify_result) else residential_instant_verify_result.success? @@ -133,10 +152,12 @@ def proof_id_with_aamva_if_needed( applicant_pii:, timer:, residential_instant_verify_result:, instant_verify_result:, - should_proof_state_id: + should_proof_state_id:, + double_address_verification: ) same_address_as_id = applicant_pii[:same_address_as_id] should_proof_state_id_with_aamva = should_proof_state_id_with_aamva?( + double_address_verification:, same_address_as_id:, should_proof_state_id:, instant_verify_result:, diff --git a/app/services/proofing/resolution/result_adjudicator.rb b/app/services/proofing/resolution/result_adjudicator.rb index ce11ae74609..34aab38046e 100644 --- a/app/services/proofing/resolution/result_adjudicator.rb +++ b/app/services/proofing/resolution/result_adjudicator.rb @@ -2,22 +2,24 @@ module Proofing module Resolution class ResultAdjudicator attr_reader :resolution_result, :state_id_result, :device_profiling_result, - :residential_resolution_result, :same_address_as_id + :double_address_verification, :residential_resolution_result, :same_address_as_id def initialize( resolution_result:, # InstantVerify state_id_result:, # AAMVA residential_resolution_result:, # InstantVerify Residential should_proof_state_id:, + double_address_verification:, device_profiling_result:, same_address_as_id: ) @resolution_result = resolution_result @state_id_result = state_id_result @should_proof_state_id = should_proof_state_id + @double_address_verification = double_address_verification @device_profiling_result = device_profiling_result @residential_resolution_result = residential_resolution_result - @same_address_as_id = same_address_as_id # this is a string, "true" or "false" + @same_address_as_id = same_address_as_id end def adjudicated_result @@ -35,6 +37,7 @@ def adjudicated_result device_profiling_adjudication_reason: device_profiling_reason, resolution_adjudication_reason: resolution_reason, should_proof_state_id: should_proof_state_id?, + double_address_verification: double_address_verification, stages: { resolution: resolution_result.to_h, residential_address: residential_resolution_result.to_h, @@ -84,7 +87,8 @@ def device_profiling_result_and_reason end def resolution_result_and_reason - if !residential_resolution_result.success? && same_address_as_id == 'false' + if !residential_resolution_result.success? && + same_address_as_id == 'false' && double_address_verification == true [false, :fail_resolution_skip_state_id] elsif resolution_result.success? && state_id_result.success? [true, :pass_resolution_and_state_id] diff --git a/spec/features/idv/doc_auth/verify_info_step_spec.rb b/spec/features/idv/doc_auth/verify_info_step_spec.rb index cdd7423dc80..a5763d79e27 100644 --- a/spec/features/idv/doc_auth/verify_info_step_spec.rb +++ b/spec/features/idv/doc_auth/verify_info_step_spec.rb @@ -271,6 +271,7 @@ { trace_id: anything, threatmetrix_session_id: anything, + double_address_verification: false, request_ip: kind_of(String), } end From e60bf1bc83299baf970e0be49ddd7c23fd03a28c Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 22 Sep 2023 09:26:44 -0400 Subject: [PATCH 17/37] revert changes --- app/services/proofing/resolution/progressive_proofer.rb | 2 +- app/services/proofing/resolution/result_adjudicator.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/proofing/resolution/progressive_proofer.rb b/app/services/proofing/resolution/progressive_proofer.rb index f6e6ff8b2a7..aae6cac3a24 100644 --- a/app/services/proofing/resolution/progressive_proofer.rb +++ b/app/services/proofing/resolution/progressive_proofer.rb @@ -7,9 +7,9 @@ module Resolution # address or separate residential and identity document addresses class ProgressiveProofer # @param [Hash] applicant_pii keys are symbols and values are strings, confidential user info - # @param [String] request_ip IP address for request # @param [Boolean] double_address_verification flag that indicates if user will have # both state id address and current residential address verified + # @param [String] request_ip IP address for request # @param [Boolean] should_proof_state_id based on state id jurisdiction, indicates if # there should be a state id proofing request made to aamva # @param [String] threatmetrix_session_id identifies the threatmetrix session diff --git a/app/services/proofing/resolution/result_adjudicator.rb b/app/services/proofing/resolution/result_adjudicator.rb index 34aab38046e..3951b6beb29 100644 --- a/app/services/proofing/resolution/result_adjudicator.rb +++ b/app/services/proofing/resolution/result_adjudicator.rb @@ -19,7 +19,7 @@ def initialize( @double_address_verification = double_address_verification @device_profiling_result = device_profiling_result @residential_resolution_result = residential_resolution_result - @same_address_as_id = same_address_as_id + @same_address_as_id = same_address_as_id # this is a string, "true" or "false" end def adjudicated_result From b2c06ffe23e7ae48bb5325bc3ac5c93cfa75a48d Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 22 Sep 2023 10:25:37 -0400 Subject: [PATCH 18/37] use analytics id for dav value --- app/controllers/concerns/idv/verify_info_concern.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb index cf2acf6ffbe..0f2706ff3aa 100644 --- a/app/controllers/concerns/idv/verify_info_concern.rb +++ b/app/controllers/concerns/idv/verify_info_concern.rb @@ -37,7 +37,7 @@ def shared_update user_id: current_user.id, threatmetrix_session_id: idv_session.threatmetrix_session_id, request_ip: request.remote_ip, - double_address_verification: capture_secondary_id_enabled, + double_address_verification: double_address_verification, ) return true @@ -45,9 +45,9 @@ def shared_update private - def capture_secondary_id_enabled + def double_address_verification # if in person return true else return false - user_session['idv/doc_auth'].empty? + analytics_arguments[:analytics_id] == 'In Person Proofing' end def should_use_aamva?(pii) From 6548a84b3fe6820d4186e05d01f025e23c32d9ee Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 22 Sep 2023 11:12:54 -0400 Subject: [PATCH 19/37] reference dav in specs again --- .../idv/verify_info_controller_spec.rb | 1 + spec/jobs/resolution_proofing_job_spec.rb | 1 + .../resolution/progressive_proofer_spec.rb | 556 ++++++++++-------- 3 files changed, 300 insertions(+), 258 deletions(-) diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb index e79c6e40430..97cd1a4f177 100644 --- a/spec/controllers/idv/verify_info_controller_spec.rb +++ b/spec/controllers/idv/verify_info_controller_spec.rb @@ -299,6 +299,7 @@ verified_attributes: [], ), device_profiling_result: Proofing::DdpResult.new(success: true), + double_address_verification: false, residential_resolution_result: Proofing::Resolution::Result.new(success: true), resolution_result: Proofing::Resolution::Result.new(success: true), same_address_as_id: true, diff --git a/spec/jobs/resolution_proofing_job_spec.rb b/spec/jobs/resolution_proofing_job_spec.rb index 504de794a04..a581637b608 100644 --- a/spec/jobs/resolution_proofing_job_spec.rb +++ b/spec/jobs/resolution_proofing_job_spec.rb @@ -331,6 +331,7 @@ user_id: user.id, threatmetrix_session_id: threatmetrix_session_id, request_ip: request_ip, + double_address_verification: true, ) end diff --git a/spec/services/proofing/resolution/progressive_proofer_spec.rb b/spec/services/proofing/resolution/progressive_proofer_spec.rb index 0e54d6b232a..58e9624c7e1 100644 --- a/spec/services/proofing/resolution/progressive_proofer_spec.rb +++ b/spec/services/proofing/resolution/progressive_proofer_spec.rb @@ -3,6 +3,7 @@ RSpec.describe Proofing::Resolution::ProgressiveProofer do let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS } let(:should_proof_state_id) { true } + let(:double_address_verification) { false } let(:request_ip) { Faker::Internet.ip_v4_address } let(:threatmetrix_session_id) { SecureRandom.uuid } let(:timer) { JobHelpers::Timer.new } @@ -38,6 +39,7 @@ subject(:proof) do instance.proof( applicant_pii: applicant_pii, + double_address_verification: double_address_verification, request_ip: request_ip, should_proof_state_id: should_proof_state_id, threatmetrix_session_id: threatmetrix_session_id, @@ -45,9 +47,6 @@ user_email: user.confirmed_email_addresses.first.email, ) end - let(:resolution_result) do - instance_double(Proofing::Resolution::Result) - end it 'returns a ResultAdjudicator' do proofing_result = proof @@ -56,30 +55,57 @@ expect(proofing_result.same_address_as_id).to eq(applicant_pii[:same_address_as_id]) end - context 'ThreatMetrix is enabled' do - let(:threatmetrix_proofer) { instance_double(Proofing::LexisNexis::Ddp::Proofer) } + context 'when double address verification is enabled' do + let(:double_address_verification) { true } + let(:resolution_result) do + instance_double(Proofing::Resolution::Result) + end + context 'ThreatMetrix is enabled' do + let(:threatmetrix_proofer) { instance_double(Proofing::LexisNexis::Ddp::Proofer) } - before do - allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). - and_return(true) - allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_mock_enabled). - and_return(false) - allow(instance).to receive(:lexisnexis_ddp_proofer).and_return(threatmetrix_proofer) + before do + allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). + and_return(true) + allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_mock_enabled). + and_return(false) + allow(instance).to receive(:lexisnexis_ddp_proofer).and_return(threatmetrix_proofer) - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(resolution_result) - allow(resolution_result).to receive(:success?).and_return(true) - allow(instant_verify_proofer).to receive(:proof) - end + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(resolution_result) + allow(resolution_result).to receive(:success?).and_return(true) + allow(instant_verify_proofer).to receive(:proof) + end - it 'makes a request to the ThreatMetrix proofer' do - expect(threatmetrix_proofer).to receive(:proof) + it 'makes a request to the ThreatMetrix proofer' do + expect(threatmetrix_proofer).to receive(:proof) - subject + subject + end + + context 'it lacks a session id' do + let(:threatmetrix_session_id) { nil } + it 'returns a disabled result' do + result = subject + + device_profiling_result = result.device_profiling_result + + expect(device_profiling_result.success).to be(true) + expect(device_profiling_result.client).to eq('tmx_disabled') + expect(device_profiling_result.review_status).to eq('pass') + end + end end - context 'it lacks a session id' do - let(:threatmetrix_session_id) { nil } + context 'ThreatMetrix is disabled' do + before do + allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). + and_return(false) + + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(resolution_result) + allow(resolution_result).to receive(:success?).and_return(true) + allow(instant_verify_proofer).to receive(:proof) + end it 'returns a disabled result' do result = subject @@ -90,175 +116,155 @@ expect(device_profiling_result.review_status).to eq('pass') end end - end - - context 'ThreatMetrix is disabled' do - before do - allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). - and_return(false) - - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(resolution_result) - allow(resolution_result).to receive(:success?).and_return(true) - allow(instant_verify_proofer).to receive(:proof) - end - it 'returns a disabled result' do - result = subject - - device_profiling_result = result.device_profiling_result - - expect(device_profiling_result.success).to be(true) - expect(device_profiling_result.client).to eq('tmx_disabled') - expect(device_profiling_result.review_status).to eq('pass') - end - end - - context 'residential address and id address are the same' do - let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID } - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - let(:residential_instant_verify_proof) do - instance_double(Proofing::Resolution::Result) - end - before do - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof). - and_return(residential_instant_verify_proof) - allow(residential_instant_verify_proof).to receive(:success?).and_return(true) - end - - it 'only makes one request to LexisNexis InstantVerify' do - expect(instant_verify_proofer).to receive(:proof).exactly(:once) - expect(aamva_proofer).to receive(:proof) - - subject - end - - it 'produces a result adjudicator with correct information' do - expect(aamva_proofer).to receive(:proof) - result = subject - - expect(result.same_address_as_id).to eq('true') - expect(result.resolution_result).to eq(result.residential_resolution_result) - end - - context 'LexisNexis InstantVerify fails' do - let(:result_that_failed_instant_verify) do + context 'residential address and id address are the same' do + let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID } + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + let(:residential_instant_verify_proof) do instance_double(Proofing::Resolution::Result) end before do - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(result_that_failed_instant_verify) - allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). - and_return(result_that_failed_instant_verify) - allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(result_that_failed_instant_verify). - and_return(true) - allow(result_that_failed_instant_verify).to receive(:success?). - and_return(false) + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof). + and_return(residential_instant_verify_proof) + allow(residential_instant_verify_proof).to receive(:success?).and_return(true) end - context 'the failure can be covered by AAMVA' do - before do - allow(result_that_failed_instant_verify). - to receive(:attributes_requiring_additional_verification). - and_return([:address]) - end + it 'only makes one request to LexisNexis InstantVerify' do + expect(instant_verify_proofer).to receive(:proof).exactly(:once) + expect(aamva_proofer).to receive(:proof) - context 'it is not covered by AAMVA' do - let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } - before do - allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - allow(failed_aamva_proof).to receive(:verified_attributes).and_return([]) - allow(failed_aamva_proof).to receive(:success?).and_return(false) - end - it 'indicates the aamva check did not pass' do - result = subject + subject + end - expect(result.state_id_result.success?).to eq(false) - end - end + it 'produces a result adjudicator with correct information' do + expect(aamva_proofer).to receive(:proof) - context 'it is covered by AAMVA' do - let(:successful_aamva_proof) { instance_double(Proofing::StateIdResult) } - before do - allow(aamva_proofer).to receive(:proof).and_return(successful_aamva_proof) - allow(successful_aamva_proof).to receive(:verified_attributes). - and_return([:address]) - allow(successful_aamva_proof).to receive(:success?).and_return(true) - end - it 'indicates aamva did pass' do - result = subject + result = subject - expect(result.state_id_result.success?).to eq(true) - end - end + expect(result.same_address_as_id).to eq('true') + expect(result.double_address_verification).to eq(true) + expect(result.resolution_result).to eq(result.residential_resolution_result) end - end - context 'LexisNexis InstantVerify passes for residential address and id address' do - context 'should proof with AAMVA' do - let(:id_resolution_that_passed_instant_verify) do - instance_double(Proofing::Resolution::Result) - end - let(:residential_resolution_that_passed_instant_verify) do + context 'LexisNexis InstantVerify fails' do + let(:result_that_failed_instant_verify) do instance_double(Proofing::Resolution::Result) end - before do - allow(instance).to receive(:proof_residential_address). - and_return(residential_resolution_that_passed_instant_verify) allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(id_resolution_that_passed_instant_verify) - allow(instant_verify_proofer).to receive(:proof). - with(hash_including(state_id_address)). - and_return(id_resolution_that_passed_instant_verify) + and_return(result_that_failed_instant_verify) + allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). + and_return(result_that_failed_instant_verify) allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(id_resolution_that_passed_instant_verify). - and_return(true) - allow(id_resolution_that_passed_instant_verify).to receive(:success?). - and_return(true) - allow(residential_resolution_that_passed_instant_verify).to receive(:success?). + with(result_that_failed_instant_verify). and_return(true) + allow(result_that_failed_instant_verify).to receive(:success?). + and_return(false) end - it 'makes a request to the AAMVA proofer' do - expect(aamva_proofer).to receive(:proof) + context 'the failure can be covered by AAMVA' do + before do + allow(result_that_failed_instant_verify). + to receive(:attributes_requiring_additional_verification). + and_return([:address]) + end - subject + context 'it is not covered by AAMVA' do + let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } + before do + allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) + allow(failed_aamva_proof).to receive(:verified_attributes).and_return([]) + allow(failed_aamva_proof).to receive(:success?).and_return(false) + end + it 'indicates the aamva check did not pass' do + result = subject + + expect(result.state_id_result.success?).to eq(false) + end + end + + context 'it is covered by AAMVA' do + let(:successful_aamva_proof) { instance_double(Proofing::StateIdResult) } + before do + allow(aamva_proofer).to receive(:proof).and_return(successful_aamva_proof) + allow(successful_aamva_proof).to receive(:verified_attributes). + and_return([:address]) + allow(successful_aamva_proof).to receive(:success?).and_return(true) + end + it 'indicates aamva did pass' do + result = subject + + expect(result.state_id_result.success?).to eq(true) + end + end end + end - context 'AAMVA proofing fails' do - let(:aamva_client) { instance_double(Proofing::Aamva::VerificationClient) } - let(:failed_aamva_proof) do - instance_double(Proofing::StateIdResult) + context 'LexisNexis InstantVerify passes for residential address and id address' do + context 'should proof with AAMVA' do + let(:id_resolution_that_passed_instant_verify) do + instance_double(Proofing::Resolution::Result) + end + let(:residential_resolution_that_passed_instant_verify) do + instance_double(Proofing::Resolution::Result) end + before do - allow(Proofing::Aamva::VerificationClient).to receive(:new).and_return(aamva_client) - allow(failed_aamva_proof).to receive(:success?).and_return(false) + allow(instance).to receive(:proof_residential_address_if_needed). + and_return(residential_resolution_that_passed_instant_verify) + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(id_resolution_that_passed_instant_verify) + allow(instant_verify_proofer).to receive(:proof). + with(hash_including(state_id_address)). + and_return(id_resolution_that_passed_instant_verify) + allow(instance).to receive(:user_can_pass_after_state_id_check?). + with(id_resolution_that_passed_instant_verify). + and_return(true) + allow(id_resolution_that_passed_instant_verify).to receive(:success?). + and_return(true) + allow(residential_resolution_that_passed_instant_verify).to receive(:success?). + and_return(true) end - it 'returns a result adjudicator that indicates the aamva proofing failed' do - allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - result = subject + it 'makes a request to the AAMVA proofer' do + expect(aamva_proofer).to receive(:proof) + + subject + end - expect(result.state_id_result.success?).to eq(false) + context 'AAMVA proofing fails' do + let(:aamva_client) { instance_double(Proofing::Aamva::VerificationClient) } + let(:failed_aamva_proof) do + instance_double(Proofing::StateIdResult) + end + before do + allow(Proofing::Aamva::VerificationClient).to receive(:new).and_return(aamva_client) + allow(failed_aamva_proof).to receive(:success?).and_return(false) + end + it 'returns a result adjudicator that indicates the aamva proofing failed' do + allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) + + result = subject + + expect(result.state_id_result.success?).to eq(false) + end end end end end - end - context 'residential address and id address are different' do - let(:residential_address_proof) do - instance_double(Proofing::Resolution::Result) - end - let(:resolution_result) do - instance_double(Proofing::Resolution::Result) - end - let(:applicant_pii) do - JSON.parse(<<-STR, symbolize_names: true) + context 'residential address and id address are different' do + let(:residential_address_proof) do + instance_double(Proofing::Resolution::Result) + end + let(:resolution_result) do + instance_double(Proofing::Resolution::Result) + end + let(:double_address_verification) { true } + let(:applicant_pii) do + JSON.parse(<<-STR, symbolize_names: true) { "uuid": "3e8db152-4d35-4207-b828-3eee8c52c50f", "middle_name": "", @@ -285,130 +291,164 @@ "state_id_type": "drivers_license", "uuid_prefix": null } - STR - end - let(:residential_address) do - { - address1: applicant_pii[:address1], - address2: applicant_pii[:address2], - city: applicant_pii[:city], - state: applicant_pii[:state], - state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], - zipcode: applicant_pii[:zipcode], - } - end - let(:state_id_address) do - { - address1: applicant_pii[:identity_doc_address1], - address2: applicant_pii[:identity_doc_address2], - city: applicant_pii[:identity_doc_city], - state: applicant_pii[:identity_doc_address_state], - state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], - zipcode: applicant_pii[:identity_doc_zipcode], - } - end + STR + end + let(:residential_address) do + { + address1: applicant_pii[:address1], + address2: applicant_pii[:address2], + city: applicant_pii[:city], + state: applicant_pii[:state], + state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], + zipcode: applicant_pii[:zipcode], + } + end + let(:state_id_address) do + { + address1: applicant_pii[:identity_doc_address1], + address2: applicant_pii[:identity_doc_address2], + city: applicant_pii[:identity_doc_city], + state: applicant_pii[:identity_doc_address_state], + state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], + zipcode: applicant_pii[:identity_doc_zipcode], + } + end - context 'LexisNexis InstantVerify passes for residential address' do - before do - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) - allow(residential_address_proof).to receive(:success?).and_return(true) + context 'LexisNexis InstantVerify passes for residential address' do + before do + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) + allow(residential_address_proof).to receive(:success?).and_return(true) + end + context 'LexisNexis InstantVerify passes for id address' do + it 'makes two requests to the InstantVerify Proofer' do + expect(instant_verify_proofer).to receive(:proof). + with(hash_including(residential_address)). + ordered + expect(instant_verify_proofer).to receive(:proof). + with(hash_including(state_id_address)). + ordered + + subject + end + + context 'AAMVA fails' do + let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + before do + allow(instance).to receive(:proof_id_with_aamva_if_needed). + and_return(failed_aamva_proof) + allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) + allow(failed_aamva_proof).to receive(:success?).and_return(false) + allow(resolution_result).to receive(:errors) + end + + it 'returns the correct resolution results' do + result_adjudicator = subject + + expect(result_adjudicator.residential_resolution_result.success?).to be(true) + expect(result_adjudicator.resolution_result.success?).to be(true) + expect(result_adjudicator.state_id_result.success?).to be(false) + end + end + end end - context 'LexisNexis InstantVerify passes for id address' do - it 'makes two requests to the InstantVerify Proofer' do - expect(instant_verify_proofer).to receive(:proof). + context 'LexisNexis InstantVerify fails for residential address' do + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + + before do + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:proof_residential_address_if_needed). + and_return(residential_address_proof) + allow(instant_verify_proofer).to receive(:proof). with(hash_including(residential_address)). - ordered - expect(instant_verify_proofer).to receive(:proof). - with(hash_including(state_id_address)). - ordered + and_return(residential_address_proof) + allow(instance).to receive(:user_can_pass_after_state_id_check?). + with(residential_address_proof). + and_return(false) + allow(residential_address_proof).to receive(:success?). + and_return(false) + end + + it 'does not make unnecessary calls' do + expect(aamva_proofer).to_not receive(:proof) + expect(instant_verify_proofer).to_not receive(:proof). + with(hash_including(state_id_address)) subject end + end + + context 'LexisNexis InstantVerify fails for id address & passes for residential address' do + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + let(:result_that_failed_instant_verify) do + instance_double(Proofing::Resolution::Result) + end + + before do + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(result_that_failed_instant_verify) + allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). + and_return(result_that_failed_instant_verify) + end - context 'AAMVA fails' do + context 'the failure can be covered by AAMVA' do let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } before do - allow(instance).to receive(:proof_id_with_aamva_if_needed). - and_return(failed_aamva_proof) - allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - allow(failed_aamva_proof).to receive(:success?).and_return(false) - allow(resolution_result).to receive(:errors) + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) + allow(residential_address_proof).to receive(:success?).and_return(true) + + allow(instance).to receive(:user_can_pass_after_state_id_check?). + with(result_that_failed_instant_verify). + and_return(true) + allow(result_that_failed_instant_verify). + to receive(:attributes_requiring_additional_verification). + and_return([:address]) + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) end + it 'calls AAMVA' do + expect(aamva_proofer).to receive(:proof) - it 'returns the correct resolution results' do - result_adjudicator = subject - - expect(result_adjudicator.residential_resolution_result.success?).to be(true) - expect(result_adjudicator.resolution_result.success?).to be(true) - expect(result_adjudicator.state_id_result.success?).to be(false) + subject end end end end - context 'LexisNexis InstantVerify fails for residential address' do - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - - before do - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - allow(instance).to receive(:proof_residential_address). - and_return(residential_address_proof) - allow(instant_verify_proofer).to receive(:proof). - with(hash_including(residential_address)). - and_return(residential_address_proof) - allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(residential_address_proof). - and_return(false) - allow(residential_address_proof).to receive(:success?). - and_return(false) - end - - it 'does not make unnecessary calls' do - expect(aamva_proofer).to_not receive(:proof) - expect(instant_verify_proofer).to_not receive(:proof). - with(hash_including(state_id_address)) + end - subject - end + context 'when double address verification is not enabled' do + let(:double_address_verification) { false } + let(:applicant_pii) do + # test ensures same_address_as_id value has no effect + Idp::Constants::MOCK_IDV_APPLICANT.merge(same_address_as_id: 'true') + end + let(:residential_instant_verify_proof) do + instance_double(Proofing::Resolution::Result) end - context 'LexisNexis InstantVerify fails for id address & passes for residential address' do - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - let(:result_that_failed_instant_verify) do - instance_double(Proofing::Resolution::Result) - end + it 'makes one request to LexisNexis InstantVerify' do + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof). + and_return(residential_instant_verify_proof) + allow(residential_instant_verify_proof).to receive(:success?).and_return(true) - before do - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(result_that_failed_instant_verify) - allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). - and_return(result_that_failed_instant_verify) - end + expect(instant_verify_proofer).to receive(:proof).exactly(:once) - context 'the failure can be covered by AAMVA' do - let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - before do - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) - allow(residential_address_proof).to receive(:success?).and_return(true) + subject + end - allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(result_that_failed_instant_verify). - and_return(true) - allow(result_that_failed_instant_verify). - to receive(:attributes_requiring_additional_verification). - and_return([:address]) - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - end - it 'calls AAMVA' do - expect(aamva_proofer).to receive(:proof) + it 'returns distinct objects for the resolution result and residential resolution result' do + result = subject - subject - end - end + expect(result.residential_resolution_result).to_not eq(result.resolution_result) + expect( + result.residential_resolution_result. + vendor_name, + ).to eq('ResidentialAddressNotRequired') + expect(result.resolution_result.vendor_name).to eq('lexisnexis:instant_verify') end end end From abaf344994e829ebb474f82483890e0f036f2eb6 Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 22 Sep 2023 12:43:55 -0400 Subject: [PATCH 20/37] make same_address_id false in analytics_spec so all in person events are triggered --- spec/features/idv/analytics_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb index d50f2d0e914..0007fc3cd1e 100644 --- a/spec/features/idv/analytics_spec.rb +++ b/spec/features/idv/analytics_spec.rb @@ -91,7 +91,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'Doc Auth', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, irs_reproofing: false, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: 'aaa-bbb-ccc', success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', double_address_verification: false, resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired' }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone of record visited' => { acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, skip_hybrid_handoff: nil, @@ -196,7 +196,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'Doc Auth', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, irs_reproofing: false, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: 'aaa-bbb-ccc', success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', double_address_verification: false, resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired' }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone of record visited' => { acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, skip_hybrid_handoff: nil, @@ -305,7 +305,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'In Person Proofing', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, irs_reproofing: false, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: 'aaa-bbb-ccc', success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', double_address_verification: true, resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: 'aaa-bbb-ccc', success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone confirmation form' => { success: true, errors: {}, phone_type: :mobile, types: [:fixed_or_mobile], carrier: 'Test Mobile Carrier', country_code: 'US', area_code: '202', acuant_sdk_upgrade_ab_test_bucket: :default, getting_started_ab_test_bucket: :welcome_default, skip_hybrid_handoff: nil, otp_delivery_preference: 'sms', From 21a4a3dc3d4d4ace5205575cab046a076bb51f8f Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 22 Sep 2023 13:03:54 -0400 Subject: [PATCH 21/37] remove unused address2_optional string --- config/locales/idv/en.yml | 1 - config/locales/idv/es.yml | 1 - config/locales/idv/fr.yml | 1 - 3 files changed, 3 deletions(-) diff --git a/config/locales/idv/en.yml b/config/locales/idv/en.yml index 2d0af4d1d7c..9317aa2c3a1 100644 --- a/config/locales/idv/en.yml +++ b/config/locales/idv/en.yml @@ -156,7 +156,6 @@ en: form: address1: Address line 1 address2: Address line 2 - address2_optional: Address line 2 (optional) city: City dob: Date of birth first_name: First name diff --git a/config/locales/idv/es.yml b/config/locales/idv/es.yml index 7dfebd40c00..a1b9fdeee7d 100644 --- a/config/locales/idv/es.yml +++ b/config/locales/idv/es.yml @@ -163,7 +163,6 @@ es: form: address1: Línea de dirección 1 address2: Línea de dirección 2 - address2_optional: Línea de dirección 2 (opcional) city: Ciudad dob: Fecha de nacimiento first_name: Nombre diff --git a/config/locales/idv/fr.yml b/config/locales/idv/fr.yml index cdb49352b88..4b5b907e64e 100644 --- a/config/locales/idv/fr.yml +++ b/config/locales/idv/fr.yml @@ -171,7 +171,6 @@ fr: form: address1: Adresse ligne 1 address2: Adresse ligne 2 - address2_optional: Adresse ligne 2 (optional) city: Ville dob: Date de naissance first_name: Prénom From 0a90f16b50c8fc0111ac8c1b27c501562467968a Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 22 Sep 2023 18:08:35 -0400 Subject: [PATCH 22/37] remove more instances of capture secondary id enabled --- app/jobs/get_usps_proofing_results_job.rb | 5 ++- app/models/in_person_enrollment.rb | 7 ---- .../in_person/ready_to_verify_presenter.rb | 2 +- .../verification_results_email_presenter.rb | 2 +- .../enrollment_helper.rb | 4 +-- .../ready_to_verify_presenter_spec.rb | 32 ++++------------- ...rification_results_email_presenter_spec.rb | 34 ++++--------------- 7 files changed, 17 insertions(+), 69 deletions(-) diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index 3690d77acdc..862477f2d9e 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -120,9 +120,8 @@ def check_enrollment(enrollment) enrollment.update(status_check_attempted_at: status_check_attempted_at) end - def passed_with_unsupported_secondary_id_type?(enrollment, response) - return enrollment.capture_secondary_id_enabled && - response['secondaryIdType'].present? && + def passed_with_unsupported_secondary_id_type?(_enrollment, response) + return response['secondaryIdType'].present? && SUPPORTED_SECONDARY_ID_TYPES.exclude?(response['secondaryIdType']) end diff --git a/app/models/in_person_enrollment.rb b/app/models/in_person_enrollment.rb index 169b2f16779..313a133d6fa 100644 --- a/app/models/in_person_enrollment.rb +++ b/app/models/in_person_enrollment.rb @@ -32,7 +32,6 @@ class InPersonEnrollment < ApplicationRecord before_save(:on_status_updated, if: :will_save_change_to_status?) before_save(:on_notification_sent_at_updated, if: :will_save_change_to_notification_sent_at?) before_create(:set_unique_id, unless: :unique_id) - before_create(:set_capture_secondary_id) class << self def needs_early_email_reminder(early_benchmark, late_benchmark) @@ -182,10 +181,4 @@ def profile_belongs_to_user type: :in_person_enrollment_user_profile_mismatch end end - - def set_capture_secondary_id - if IdentityConfig.store.in_person_capture_secondary_id_enabled - self.capture_secondary_id_enabled = true - end - end end diff --git a/app/presenters/idv/in_person/ready_to_verify_presenter.rb b/app/presenters/idv/in_person/ready_to_verify_presenter.rb index f52a5184137..ef99c2e3cb2 100644 --- a/app/presenters/idv/in_person/ready_to_verify_presenter.rb +++ b/app/presenters/idv/in_person/ready_to_verify_presenter.rb @@ -31,7 +31,7 @@ def selected_location_hours(prefix) end def needs_proof_of_address? - !(enrollment.current_address_matches_id || enrollment.capture_secondary_id_enabled) + !enrollment.current_address_matches_id end def service_provider diff --git a/app/presenters/idv/in_person/verification_results_email_presenter.rb b/app/presenters/idv/in_person/verification_results_email_presenter.rb index c89838e07c7..f8ed209f725 100644 --- a/app/presenters/idv/in_person/verification_results_email_presenter.rb +++ b/app/presenters/idv/in_person/verification_results_email_presenter.rb @@ -48,7 +48,7 @@ def service_provider_homepage_url end def needs_proof_of_address? - !(enrollment.current_address_matches_id || enrollment.capture_secondary_id_enabled) + !enrollment.current_address_matches_id end private diff --git a/app/services/usps_in_person_proofing/enrollment_helper.rb b/app/services/usps_in_person_proofing/enrollment_helper.rb index b116838f56d..18e5c03b622 100644 --- a/app/services/usps_in_person_proofing/enrollment_helper.rb +++ b/app/services/usps_in_person_proofing/enrollment_helper.rb @@ -8,10 +8,8 @@ def schedule_in_person_enrollment(user, pii) enrollment.current_address_matches_id = pii['same_address_as_id'] enrollment.save! - # If we're using secondary ID capture (aka double address verification), - # then send the state ID address to USPS. Otherwise send the residential address. pii = pii.to_h - if enrollment.capture_secondary_id_enabled? && !enrollment.current_address_matches_id? + if !enrollment.current_address_matches_id? pii = pii.except(*SECONDARY_ID_ADDRESS_MAP.values). transform_keys(SECONDARY_ID_ADDRESS_MAP) end diff --git a/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb b/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb index ee9db5e0668..e85ce6bb68e 100644 --- a/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb +++ b/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb @@ -105,36 +105,16 @@ describe '#needs_proof_of_address?' do subject(:needs_proof_of_address) { presenter.needs_proof_of_address? } - context 'with double address verification disabled' do - let(:capture_secondary_id_enabled) { false } + context 'with current address matching id' do + let(:current_address_matches_id) { true } - context 'with current address matching id' do - let(:current_address_matches_id) { true } - - it { expect(needs_proof_of_address).to eq false } - end - - context 'with current address not matching id' do - let(:current_address_matches_id) { false } - - it { expect(needs_proof_of_address).to eq true } - end + it { expect(needs_proof_of_address).to eq false } end - context 'with double address verification enabled' do - let(:capture_secondary_id_enabled) { true } + context 'with current address not matching id' do + let(:current_address_matches_id) { false } - context 'with current address matching id' do - let(:current_address_matches_id) { true } - - it { expect(needs_proof_of_address).to eq false } - end - - context 'with current address not matching id' do - let(:current_address_matches_id) { false } - - it { expect(needs_proof_of_address).to eq false } - end + it { expect(needs_proof_of_address).to eq true } end end diff --git a/spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb b/spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb index 05f241b5bb5..787dfc459eb 100644 --- a/spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb +++ b/spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb @@ -7,7 +7,6 @@ let(:status_updated_at) { described_class::USPS_SERVER_TIMEZONE.parse('2022-07-14T00:00:00Z') } let(:sp) { nil } let(:current_address_matches_id) { true } - let(:capture_secondary_id_enabled) { false } let(:enrollment) do create( :in_person_enrollment, @@ -15,7 +14,6 @@ service_provider: sp, selected_location_details: { name: location_name }, current_address_matches_id: current_address_matches_id, - capture_secondary_id_enabled: capture_secondary_id_enabled, ) end @@ -189,36 +187,16 @@ describe '#needs_proof_of_address?' do subject(:needs_proof_of_address) { presenter.needs_proof_of_address? } - context 'with double address verification disabled' do - let(:capture_secondary_id_enabled) { false } + context 'with current address matching id' do + let(:current_address_matches_id) { true } - context 'with current address matching id' do - let(:current_address_matches_id) { true } - - it { expect(needs_proof_of_address).to eq false } - end - - context 'with current address not matching id' do - let(:current_address_matches_id) { false } - - it { expect(needs_proof_of_address).to eq true } - end + it { expect(needs_proof_of_address).to eq false } end - context 'with double address verification enabled' do - let(:capture_secondary_id_enabled) { true } + context 'with current address not matching id' do + let(:current_address_matches_id) { false } - context 'with current address matching id' do - let(:current_address_matches_id) { true } - - it { expect(needs_proof_of_address).to eq false } - end - - context 'with current address not matching id' do - let(:current_address_matches_id) { false } - - it { expect(needs_proof_of_address).to eq false } - end + it { expect(needs_proof_of_address).to eq true } end end end From 6fffec0834dbc7f3ed61a13b6b68e1809677bbee Mon Sep 17 00:00:00 2001 From: svalexander Date: Mon, 25 Sep 2023 16:59:04 -0400 Subject: [PATCH 23/37] update email specs --- .../get_usps_proofing_results_job_spec.rb | 121 +++++++++--------- spec/mailers/previews/user_mailer_preview.rb | 1 - spec/mailers/user_mailer_spec.rb | 60 --------- spec/models/in_person_enrollment_spec.rb | 28 ---- .../ready_to_verify_presenter_spec.rb | 2 - 5 files changed, 58 insertions(+), 154 deletions(-) diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb index defb960d05f..9dbe5b94cb7 100644 --- a/spec/jobs/get_usps_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_proofing_results_job_spec.rb @@ -1149,19 +1149,17 @@ end end - describe 'DAV enabled' do - let(:capture_secondary_id_enabled) { true } + describe 'proofed with secondary id' do let(:pending_enrollment) do create( - :in_person_enrollment, :pending, - capture_secondary_id_enabled: capture_secondary_id_enabled + :in_person_enrollment, :pending ) end before do allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) end - context 'when an enrollment passes proofing with an secondary ID and DAV enabled' do + context 'when an enrollment passes proofing with a secondary ID' do before do stub_request_passed_proofing_secondary_id_type_results end @@ -1212,85 +1210,82 @@ ) end end + end - context 'sms notifications enabled' do - let(:pending_enrollment) do - create( - :in_person_enrollment, - :pending, - :with_notification_phone_configuration, - capture_secondary_id_enabled: true, - ) - end - - before do - allow(IdentityConfig.store).to receive(:in_person_send_proofing_notifications_enabled). - and_return(true) - end + describe 'sms notifications enabled' do + let(:pending_enrollment) do + create( + :in_person_enrollment, :pending, :with_notification_phone_configuration + ) + end + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enabled).and_return(true) + allow(IdentityConfig.store).to receive(:in_person_send_proofing_notifications_enabled). + and_return(true) + end - context 'enrollment is expired' do - it 'deletes the notification phone configuration without sending an sms' do - stub_request_expired_proofing_results + context 'enrollment is expired' do + it 'deletes the notification phone configuration without sending an sms' do + stub_request_expired_proofing_results - expect(pending_enrollment.notification_phone_configuration).to_not be_nil + expect(pending_enrollment.notification_phone_configuration).to_not be_nil - job.perform(Time.zone.now) + job.perform(Time.zone.now) - expect(pending_enrollment.reload.notification_phone_configuration).to be_nil - expect(pending_enrollment.notification_sent_at).to be_nil - end + expect(pending_enrollment.reload.notification_phone_configuration).to be_nil + expect(pending_enrollment.notification_sent_at).to be_nil end + end - context 'enrollment has passed proofing' do - it 'invokes the SendProofingNotificationJob for the enrollment' do - stub_request_passed_proofing_results + context 'enrollment has passed proofing' do + it 'invokes the SendProofingNotificationJob for the enrollment' do + stub_request_passed_proofing_results - expect(pending_enrollment.notification_phone_configuration).to_not be_nil - expect(pending_enrollment.notification_sent_at).to be_nil + expect(pending_enrollment.notification_phone_configuration).to_not be_nil + expect(pending_enrollment.notification_sent_at).to be_nil - expect { job.perform(Time.zone.now) }. - to have_enqueued_job(InPerson::SendProofingNotificationJob). - with(pending_enrollment.id) - end + expect { job.perform(Time.zone.now) }. + to have_enqueued_job(InPerson::SendProofingNotificationJob). + with(pending_enrollment.id) end + end - context 'enrollment has failed proofing' do - it 'invokes the SendProofingNotificationJob for the enrollment' do - stub_request_failed_proofing_results + context 'enrollment has failed proofing' do + it 'invokes the SendProofingNotificationJob for the enrollment' do + stub_request_failed_proofing_results - expect(pending_enrollment.notification_phone_configuration).to_not be_nil - expect(pending_enrollment.notification_sent_at).to be_nil + expect(pending_enrollment.notification_phone_configuration).to_not be_nil + expect(pending_enrollment.notification_sent_at).to be_nil - expect { job.perform(Time.zone.now) }. - to have_enqueued_job(InPerson::SendProofingNotificationJob). - with(pending_enrollment.id) - end + expect { job.perform(Time.zone.now) }. + to have_enqueued_job(InPerson::SendProofingNotificationJob). + with(pending_enrollment.id) end + end - context 'enrollment has failed proofing due to unsupported secondary ID' do - it 'invokes the SendProofingNotificationJob for the enrollment' do - stub_request_passed_proofing_secondary_id_type_results + context 'enrollment has failed proofing due to unsupported secondary ID' do + it 'invokes the SendProofingNotificationJob for the enrollment' do + stub_request_passed_proofing_secondary_id_type_results - expect(pending_enrollment.notification_phone_configuration).to_not be_nil - expect(pending_enrollment.notification_sent_at).to be_nil + expect(pending_enrollment.notification_phone_configuration).to_not be_nil + expect(pending_enrollment.notification_sent_at).to be_nil - expect { job.perform(Time.zone.now) }. - to have_enqueued_job(InPerson::SendProofingNotificationJob). - with(pending_enrollment.id) - end + expect { job.perform(Time.zone.now) }. + to have_enqueued_job(InPerson::SendProofingNotificationJob). + with(pending_enrollment.id) end + end - context 'enrollment has failed proofing due to unsupported ID type' do - it 'invokes the SendProofingNotificationJob for the enrollment' do - stub_request_passed_proofing_unsupported_id_results + context 'enrollment has failed proofing due to unsupported ID type' do + it 'invokes the SendProofingNotificationJob for the enrollment' do + stub_request_passed_proofing_unsupported_id_results - expect(pending_enrollment.notification_phone_configuration).to_not be_nil - expect(pending_enrollment.notification_sent_at).to be_nil + expect(pending_enrollment.notification_phone_configuration).to_not be_nil + expect(pending_enrollment.notification_sent_at).to be_nil - expect { job.perform(Time.zone.now) }. - to have_enqueued_job(InPerson::SendProofingNotificationJob). - with(pending_enrollment.id) - end + expect { job.perform(Time.zone.now) }. + to have_enqueued_job(InPerson::SendProofingNotificationJob). + with(pending_enrollment.id) end end end diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb index 2da146b5174..a85d3df8ba1 100644 --- a/spec/mailers/previews/user_mailer_preview.rb +++ b/spec/mailers/previews/user_mailer_preview.rb @@ -234,7 +234,6 @@ def in_person_enrollment ), status_updated_at: Time.zone.now - 1.hour, current_address_matches_id: params['current_address_matches_id'] == 'true', - capture_secondary_id_enabled: IdentityConfig.store.in_person_capture_secondary_id_enabled, selected_location_details: { 'name' => 'BALTIMORE', 'street_address' => '900 E FAYETTE ST RM 118', diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 344f2db5be1..e78a78ef1c9 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -534,7 +534,6 @@ def expect_email_body_to_have_help_and_contact_links end context 'in person emails' do - let(:capture_secondary_id_enabled) { false } let(:current_address_matches_id) { false } let!(:enrollment) do create( @@ -542,7 +541,6 @@ def expect_email_body_to_have_help_and_contact_links :pending, selected_location_details: { name: 'FRIENDSHIP' }, status_updated_at: Time.zone.now - 2.hours, - capture_secondary_id_enabled: capture_secondary_id_enabled, current_address_matches_id: current_address_matches_id, ) end @@ -557,25 +555,6 @@ def expect_email_body_to_have_help_and_contact_links it_behaves_like 'a system email' it_behaves_like 'an email that respects user email locale preference' - context 'double address verification is not enabled' do - it 'renders the body' do - expect(mail.html_part.body). - to have_content( - t('in_person_proofing.process.proof_of_address.heading'), - ) - end - end - - context 'double address verification is enabled' do - let(:capture_secondary_id_enabled) { true } - it 'renders the body' do - expect(mail.html_part.body). - to_not have_content( - t('in_person_proofing.process.proof_of_address.heading'), - ) - end - end - context 'Outage message' do let(:formatted_date) { 'Tuesday, October 31' } let(:in_person_outage_emailed_by_date) { 'November 1, 2023' } @@ -646,25 +625,6 @@ def expect_email_body_to_have_help_and_contact_links it_behaves_like 'a system email' it_behaves_like 'an email that respects user email locale preference' - context 'double address verification is not enabled' do - it 'renders the body' do - expect(mail.html_part.body). - to have_content( - t('in_person_proofing.process.proof_of_address.heading'), - ) - end - end - - context 'double address verification is enabled' do - let(:capture_secondary_id_enabled) { true } - it 'renders the body' do - expect(mail.html_part.body). - to_not have_content( - t('in_person_proofing.process.proof_of_address.heading'), - ) - end - end - it 'renders the body' do expect(mail.html_part.body). to have_content( @@ -699,7 +659,6 @@ def expect_email_body_to_have_help_and_contact_links selected_location_details: { name: 'FRIENDSHIP' }, status_updated_at: Time.zone.now - 2.hours, current_address_matches_id: current_address_matches_id, - capture_secondary_id_enabled: capture_secondary_id_enabled, ) end @@ -711,25 +670,6 @@ def expect_email_body_to_have_help_and_contact_links it_behaves_like 'a system email' it_behaves_like 'an email that respects user email locale preference' - - context 'double address verification is not enabled' do - it 'renders the body' do - expect(mail.html_part.body). - to have_content( - t('user_mailer.in_person_failed.verifying_step_proof_of_address'), - ) - end - end - - context 'double address verification is enabled' do - let(:capture_secondary_id_enabled) { true } - it 'renders the body' do - expect(mail.html_part.body). - to_not have_content( - t('user_mailer.in_person_failed.verifying_step_proof_of_address'), - ) - end - end end describe '#in_person_failed_fraud' do diff --git a/spec/models/in_person_enrollment_spec.rb b/spec/models/in_person_enrollment_spec.rb index 35848e6d5ab..1d2bd5ac76b 100644 --- a/spec/models/in_person_enrollment_spec.rb +++ b/spec/models/in_person_enrollment_spec.rb @@ -144,34 +144,6 @@ expect(enrollment.unique_id).to eq('1234') end - - describe 'setting capture_secondary_id_enabled on creation' do - let(:capture_enabled) { nil } - - before do - allow(IdentityConfig.store). - to( - receive(:in_person_capture_secondary_id_enabled). - and_return(capture_enabled), - ) - end - - context 'feature flag is enabled' do - let(:capture_enabled) { true } - it 'sets capture_secondary_id_enabled to true on the enrollment' do - enrollment = create(:in_person_enrollment, :pending) - expect(enrollment.capture_secondary_id_enabled).to eq(true) - end - end - - context 'feature flag is not enabled' do - let(:capture_enabled) { false } - it 'does not set capture_secondary_id_enabled to true on the enrollment' do - enrollment = create(:in_person_enrollment, :pending) - expect(enrollment.capture_secondary_id_enabled).to eq(false) - end - end - end end describe 'enrollments that need email reminders' do diff --git a/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb b/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb index e85ce6bb68e..1fbabce9e17 100644 --- a/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb +++ b/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb @@ -11,7 +11,6 @@ let(:enrollment_selected_location_details) do JSON.parse(UspsInPersonProofing::Mock::Fixtures.enrollment_selected_location_details) end - let(:capture_secondary_id_enabled) { false } let(:enrollment) do create( :in_person_enrollment, :with_service_provider, :pending, @@ -21,7 +20,6 @@ enrollment_established_at: enrollment_established_at, current_address_matches_id: current_address_matches_id, selected_location_details: enrollment_selected_location_details, - capture_secondary_id_enabled: capture_secondary_id_enabled ) end subject(:presenter) { described_class.new(enrollment: enrollment) } From 63eb9e37a1ab2b4f7c7c20b0d6440a2e24abe821 Mon Sep 17 00:00:00 2001 From: svalexander Date: Tue, 26 Sep 2023 12:24:07 -0400 Subject: [PATCH 24/37] update enrollment helper spec --- lib/idp/constants.rb | 3 + .../enrollment_helper_spec.rb | 110 ++++++------------ 2 files changed, 38 insertions(+), 75 deletions(-) diff --git a/lib/idp/constants.rb b/lib/idp/constants.rb index 478f183b338..98f5ea8d722 100644 --- a/lib/idp/constants.rb +++ b/lib/idp/constants.rb @@ -113,6 +113,7 @@ module Vendors same_address_as_id: 'false', ).freeze + # This should be the default applicant for ipp MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID = MOCK_IDV_APPLICANT_WITH_SSN.merge( identity_doc_address1: MOCK_IDV_APPLICANT_WITH_SSN[:address1], identity_doc_address2: MOCK_IDV_APPLICANT_WITH_SSN[:address2], @@ -133,6 +134,8 @@ module Vendors MOCK_IDV_APPLICANT_WITH_PHONE = MOCK_IDV_APPLICANT_WITH_SSN.merge(phone: '12025551212').freeze + MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID_WITH_PHONE = MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID.merge(phone: '12025551212').freeze + MOCK_IDV_APPLICANT_FULL_STATE_ID_JURISDICTION = 'North Dakota' MOCK_IDV_APPLICANT_FULL_STATE = 'Montana' MOCK_IDV_APPLICANT_FULL_IDENTITY_DOC_ADDRESS_STATE = 'Virginia' diff --git a/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb b/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb index 449e313ede8..c822c491bad 100644 --- a/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb +++ b/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb @@ -8,7 +8,7 @@ let(:current_address_matches_id) { false } let(:pii) do Pii::Attributes.new_from_hash( - Idp::Constants::MOCK_IDV_APPLICANT_WITH_PHONE. + Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID_WITH_PHONE. merge(same_address_as_id: current_address_matches_id ? 'true' : 'false'). transform_keys(&:to_s), ) @@ -18,7 +18,6 @@ let(:transliterator) { UspsInPersonProofing::Transliterator.new } let(:service_provider) { nil } let(:usps_ipp_transliteration_enabled) { true } - let(:in_person_capture_secondary_id_enabled) { false } let(:usps_ipp_enrollment_status_update_email_address) do 'registration@usps.local.identitysandbox.gov' end @@ -38,8 +37,6 @@ allow(subject).to receive(:analytics).and_return(subject_analytics) allow(IdentityConfig.store).to receive(:usps_ipp_transliteration_enabled). and_return(usps_ipp_transliteration_enabled) - allow(IdentityConfig.store).to receive(:in_person_capture_secondary_id_enabled). - and_return(in_person_capture_secondary_id_enabled) end describe '#schedule_in_person_enrollment' do @@ -102,7 +99,7 @@ subject.schedule_in_person_enrollment(user, pii) end - describe 'double address verification' do + context 'same address as id is false' do let(:pii) do Pii::Attributes.new_from_hash( Idp::Constants::MOCK_IDV_APPLICANT_WITH_PHONE. @@ -112,46 +109,24 @@ ) end - context 'feature enabled' do - let(:in_person_capture_secondary_id_enabled) { true } - - it 'maps enrollment address fields' do - expect(proofer).to receive(:request_enroll) do |applicant| - ADDR = Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS - expect(applicant).to have_attributes( - address: Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[ - :identity_doc_address1 - ], - city: Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_city], - state: Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[ - :identity_doc_address_state - ], - zip_code: - Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_zipcode], - ) - UspsInPersonProofing::Mock::Proofer.new.request_enroll(applicant) - end - - subject.schedule_in_person_enrollment(user, pii) + it 'maps enrollment address fields' do + expect(proofer).to receive(:request_enroll) do |applicant| + ADDR = Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS + expect(applicant).to have_attributes( + address: Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[ + :identity_doc_address1 + ], + city: Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_city], + state: Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[ + :identity_doc_address_state + ], + zip_code: + Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS[:identity_doc_zipcode], + ) + UspsInPersonProofing::Mock::Proofer.new.request_enroll(applicant) end - end - - context 'feature disabled' do - let(:in_person_capture_secondary_id_enabled) { false } - - it 'does not map enrollment address fields' do - expect(proofer).to receive(:request_enroll) do |applicant| - expect(applicant).to have_attributes( - address: Idp::Constants::MOCK_IDV_APPLICANT[:address1], - city: Idp::Constants::MOCK_IDV_APPLICANT[:city], - state: Idp::Constants::MOCK_IDV_APPLICANT[:state], - zip_code: Idp::Constants::MOCK_IDV_APPLICANT[:zipcode], - ) - UspsInPersonProofing::Mock::Proofer.new.request_enroll(applicant) - end - subject.schedule_in_person_enrollment(user, pii) - end + subject.schedule_in_person_enrollment(user, pii) end end end @@ -247,29 +222,33 @@ context 'with address line 2 present' do before { pii['address2'] = 'Apartment 227' } - it 'logs the presence of address line 2' do + # this is a pii bundle that adds identity_doc_* values + let(:pii) do + Pii::Attributes.new_from_hash( + Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS.transform_keys(&:to_s), + ) + end + + it 'does not log the presence of address line 2 only in residential address' do + pii['identity_doc_address2'] = nil + subject.schedule_in_person_enrollment(user, pii) expect(subject_analytics).to have_logged_event( 'USPS IPPaaS enrollment created', enrollment_code: user.in_person_enrollments.first.enrollment_code, enrollment_id: user.in_person_enrollments.first.id, - second_address_line_present: true, + second_address_line_present: false, service_provider: nil, ) end - context 'double address verification active' do - let(:in_person_capture_secondary_id_enabled) { true } - # this is a pii bundle that adds identity_doc_* values - let(:pii) do - Pii::Attributes.new_from_hash( - Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS.transform_keys(&:to_s), - ) - end + context 'with address line 2 present in state ID address' do + it 'logs the presence of address line 2' do + expect(pii['identity_doc_address2'].present?).to eq(true) - it 'does not log the presence of address line 2 only in residential address' do - pii['identity_doc_address2'] = nil + pii['same_address_as_id'] = false + pii['address2'] = nil subject.schedule_in_person_enrollment(user, pii) @@ -277,29 +256,10 @@ 'USPS IPPaaS enrollment created', enrollment_code: user.in_person_enrollments.first.enrollment_code, enrollment_id: user.in_person_enrollments.first.id, - second_address_line_present: false, + second_address_line_present: true, service_provider: nil, ) end - - context 'with address line 2 present in state ID address' do - it 'logs the presence of address line 2' do - expect(pii['identity_doc_address2'].present?).to eq(true) - - pii['same_address_as_id'] = false - pii['address2'] = nil - - subject.schedule_in_person_enrollment(user, pii) - - expect(subject_analytics).to have_logged_event( - 'USPS IPPaaS enrollment created', - enrollment_code: user.in_person_enrollments.first.enrollment_code, - enrollment_id: user.in_person_enrollments.first.id, - second_address_line_present: true, - service_provider: nil, - ) - end - end end end end From a9b4f9ccb98d7700f52d5d14546196fdd71594c6 Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 27 Sep 2023 14:23:38 -0400 Subject: [PATCH 25/37] update review spec to use mock ipp applicant and lint fix --- app/services/usps_in_person_proofing/enrollment_helper.rb | 1 + spec/controllers/idv/review_controller_spec.rb | 7 ++++--- .../idv/in_person/ready_to_verify_presenter_spec.rb | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/services/usps_in_person_proofing/enrollment_helper.rb b/app/services/usps_in_person_proofing/enrollment_helper.rb index 18e5c03b622..f2ef64237ec 100644 --- a/app/services/usps_in_person_proofing/enrollment_helper.rb +++ b/app/services/usps_in_person_proofing/enrollment_helper.rb @@ -8,6 +8,7 @@ def schedule_in_person_enrollment(user, pii) enrollment.current_address_matches_id = pii['same_address_as_id'] enrollment.save! + # Send state ID address to USPS pii = pii.to_h if !enrollment.current_address_matches_id? pii = pii.except(*SECONDARY_ID_ADDRESS_MAP.values). diff --git a/spec/controllers/idv/review_controller_spec.rb b/spec/controllers/idv/review_controller_spec.rb index 439112cdba6..8cfb71de2b2 100644 --- a/spec/controllers/idv/review_controller_spec.rb +++ b/spec/controllers/idv/review_controller_spec.rb @@ -364,7 +364,7 @@ def show stub_request_enroll end let(:applicant) do - Idp::Constants::MOCK_IDV_APPLICANT_WITH_PHONE + Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID_WITH_PHONE end before do @@ -560,12 +560,13 @@ def show end context 'when user enters an address2 value' do - let(:applicant) { Idp::Constants::MOCK_IDV_APPLICANT_WITH_PHONE.merge(address2: '3b') } + let(:applicant) do + Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID_WITH_PHONE.merge(address2: '3b') + end it 'does not include address2' do proofer = UspsInPersonProofing::Proofer.new mock = double - expect(UspsInPersonProofing::Proofer).to receive(:new).and_return(mock) expect(mock).to receive(:request_enroll) do |applicant| expect(applicant.address). diff --git a/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb b/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb index 1fbabce9e17..9bda43c0ae4 100644 --- a/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb +++ b/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb @@ -19,7 +19,7 @@ created_at: created_at, enrollment_established_at: enrollment_established_at, current_address_matches_id: current_address_matches_id, - selected_location_details: enrollment_selected_location_details, + selected_location_details: enrollment_selected_location_details ) end subject(:presenter) { described_class.new(enrollment: enrollment) } From 4912fa051d36c961cbad15e3ae0aa90d23e4a880 Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 27 Sep 2023 15:55:17 -0400 Subject: [PATCH 26/37] lint fix to constants files --- lib/idp/constants.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/idp/constants.rb b/lib/idp/constants.rb index 98f5ea8d722..620e7bda419 100644 --- a/lib/idp/constants.rb +++ b/lib/idp/constants.rb @@ -134,7 +134,8 @@ module Vendors MOCK_IDV_APPLICANT_WITH_PHONE = MOCK_IDV_APPLICANT_WITH_SSN.merge(phone: '12025551212').freeze - MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID_WITH_PHONE = MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID.merge(phone: '12025551212').freeze + MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID_WITH_PHONE = + MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID.merge(phone: '12025551212').freeze MOCK_IDV_APPLICANT_FULL_STATE_ID_JURISDICTION = 'North Dakota' MOCK_IDV_APPLICANT_FULL_STATE = 'Montana' From b7969e74eee2acfb272c8fb93e266afe57b61261 Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 27 Sep 2023 17:44:01 -0400 Subject: [PATCH 27/37] remove dav disabled cases from prog proofer and res adjudicator specs --- .../resolution/progressive_proofer_spec.rb | 560 ++++++++---------- .../resolution/result_adjudicator_spec.rb | 96 +-- 2 files changed, 265 insertions(+), 391 deletions(-) diff --git a/spec/services/proofing/resolution/progressive_proofer_spec.rb b/spec/services/proofing/resolution/progressive_proofer_spec.rb index 58e9624c7e1..374292918b8 100644 --- a/spec/services/proofing/resolution/progressive_proofer_spec.rb +++ b/spec/services/proofing/resolution/progressive_proofer_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Proofing::Resolution::ProgressiveProofer do let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS } let(:should_proof_state_id) { true } - let(:double_address_verification) { false } + let(:double_address_verification) { true } let(:request_ip) { Faker::Internet.ip_v4_address } let(:threatmetrix_session_id) { SecureRandom.uuid } let(:timer) { JobHelpers::Timer.new } @@ -55,57 +55,33 @@ expect(proofing_result.same_address_as_id).to eq(applicant_pii[:same_address_as_id]) end - context 'when double address verification is enabled' do - let(:double_address_verification) { true } - let(:resolution_result) do - instance_double(Proofing::Resolution::Result) + let(:resolution_result) do + instance_double(Proofing::Resolution::Result) + end + context 'ThreatMetrix is enabled' do + let(:threatmetrix_proofer) { instance_double(Proofing::LexisNexis::Ddp::Proofer) } + + before do + allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). + and_return(true) + allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_mock_enabled). + and_return(false) + allow(instance).to receive(:lexisnexis_ddp_proofer).and_return(threatmetrix_proofer) + + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(resolution_result) + allow(resolution_result).to receive(:success?).and_return(true) + allow(instant_verify_proofer).to receive(:proof) end - context 'ThreatMetrix is enabled' do - let(:threatmetrix_proofer) { instance_double(Proofing::LexisNexis::Ddp::Proofer) } - - before do - allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). - and_return(true) - allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_mock_enabled). - and_return(false) - allow(instance).to receive(:lexisnexis_ddp_proofer).and_return(threatmetrix_proofer) - - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(resolution_result) - allow(resolution_result).to receive(:success?).and_return(true) - allow(instant_verify_proofer).to receive(:proof) - end - - it 'makes a request to the ThreatMetrix proofer' do - expect(threatmetrix_proofer).to receive(:proof) - subject - end - - context 'it lacks a session id' do - let(:threatmetrix_session_id) { nil } - it 'returns a disabled result' do - result = subject + it 'makes a request to the ThreatMetrix proofer' do + expect(threatmetrix_proofer).to receive(:proof) - device_profiling_result = result.device_profiling_result - - expect(device_profiling_result.success).to be(true) - expect(device_profiling_result.client).to eq('tmx_disabled') - expect(device_profiling_result.review_status).to eq('pass') - end - end + subject end - context 'ThreatMetrix is disabled' do - before do - allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). - and_return(false) - - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(resolution_result) - allow(resolution_result).to receive(:success?).and_return(true) - allow(instant_verify_proofer).to receive(:proof) - end + context 'it lacks a session id' do + let(:threatmetrix_session_id) { nil } it 'returns a disabled result' do result = subject @@ -116,155 +92,177 @@ expect(device_profiling_result.review_status).to eq('pass') end end + end - context 'residential address and id address are the same' do - let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID } - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - let(:residential_instant_verify_proof) do + context 'ThreatMetrix is disabled' do + before do + allow(FeatureManagement).to receive(:proofing_device_profiling_collecting_enabled?). + and_return(false) + + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(resolution_result) + allow(resolution_result).to receive(:success?).and_return(true) + allow(instant_verify_proofer).to receive(:proof) + end + it 'returns a disabled result' do + result = subject + + device_profiling_result = result.device_profiling_result + + expect(device_profiling_result.success).to be(true) + expect(device_profiling_result.client).to eq('tmx_disabled') + expect(device_profiling_result.review_status).to eq('pass') + end + end + + context 'residential address and id address are the same' do + let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID } + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + let(:residential_instant_verify_proof) do + instance_double(Proofing::Resolution::Result) + end + before do + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof). + and_return(residential_instant_verify_proof) + allow(residential_instant_verify_proof).to receive(:success?).and_return(true) + end + + it 'only makes one request to LexisNexis InstantVerify' do + expect(instant_verify_proofer).to receive(:proof).exactly(:once) + expect(aamva_proofer).to receive(:proof) + + subject + end + + it 'produces a result adjudicator with correct information' do + expect(aamva_proofer).to receive(:proof) + + result = subject + + expect(result.same_address_as_id).to eq('true') + expect(result.double_address_verification).to eq(true) + expect(result.resolution_result).to eq(result.residential_resolution_result) + end + + context 'LexisNexis InstantVerify fails' do + let(:result_that_failed_instant_verify) do instance_double(Proofing::Resolution::Result) end before do - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof). - and_return(residential_instant_verify_proof) - allow(residential_instant_verify_proof).to receive(:success?).and_return(true) + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(result_that_failed_instant_verify) + allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). + and_return(result_that_failed_instant_verify) + allow(instance).to receive(:user_can_pass_after_state_id_check?). + with(result_that_failed_instant_verify). + and_return(true) + allow(result_that_failed_instant_verify).to receive(:success?). + and_return(false) end - it 'only makes one request to LexisNexis InstantVerify' do - expect(instant_verify_proofer).to receive(:proof).exactly(:once) - expect(aamva_proofer).to receive(:proof) + context 'the failure can be covered by AAMVA' do + before do + allow(result_that_failed_instant_verify). + to receive(:attributes_requiring_additional_verification). + and_return([:address]) + end - subject - end + context 'it is not covered by AAMVA' do + let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } + before do + allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) + allow(failed_aamva_proof).to receive(:verified_attributes).and_return([]) + allow(failed_aamva_proof).to receive(:success?).and_return(false) + end + it 'indicates the aamva check did not pass' do + result = subject - it 'produces a result adjudicator with correct information' do - expect(aamva_proofer).to receive(:proof) + expect(result.state_id_result.success?).to eq(false) + end + end - result = subject + context 'it is covered by AAMVA' do + let(:successful_aamva_proof) { instance_double(Proofing::StateIdResult) } + before do + allow(aamva_proofer).to receive(:proof).and_return(successful_aamva_proof) + allow(successful_aamva_proof).to receive(:verified_attributes). + and_return([:address]) + allow(successful_aamva_proof).to receive(:success?).and_return(true) + end + it 'indicates aamva did pass' do + result = subject - expect(result.same_address_as_id).to eq('true') - expect(result.double_address_verification).to eq(true) - expect(result.resolution_result).to eq(result.residential_resolution_result) + expect(result.state_id_result.success?).to eq(true) + end + end end + end - context 'LexisNexis InstantVerify fails' do - let(:result_that_failed_instant_verify) do + context 'LexisNexis InstantVerify passes for residential address and id address' do + context 'should proof with AAMVA' do + let(:id_resolution_that_passed_instant_verify) do instance_double(Proofing::Resolution::Result) end + let(:residential_resolution_that_passed_instant_verify) do + instance_double(Proofing::Resolution::Result) + end + before do + allow(instance).to receive(:proof_residential_address_if_needed). + and_return(residential_resolution_that_passed_instant_verify) allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(result_that_failed_instant_verify) - allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). - and_return(result_that_failed_instant_verify) + and_return(id_resolution_that_passed_instant_verify) + allow(instant_verify_proofer).to receive(:proof). + with(hash_including(state_id_address)). + and_return(id_resolution_that_passed_instant_verify) allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(result_that_failed_instant_verify). + with(id_resolution_that_passed_instant_verify). + and_return(true) + allow(id_resolution_that_passed_instant_verify).to receive(:success?). + and_return(true) + allow(residential_resolution_that_passed_instant_verify).to receive(:success?). and_return(true) - allow(result_that_failed_instant_verify).to receive(:success?). - and_return(false) end - context 'the failure can be covered by AAMVA' do - before do - allow(result_that_failed_instant_verify). - to receive(:attributes_requiring_additional_verification). - and_return([:address]) - end - - context 'it is not covered by AAMVA' do - let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } - before do - allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - allow(failed_aamva_proof).to receive(:verified_attributes).and_return([]) - allow(failed_aamva_proof).to receive(:success?).and_return(false) - end - it 'indicates the aamva check did not pass' do - result = subject - - expect(result.state_id_result.success?).to eq(false) - end - end + it 'makes a request to the AAMVA proofer' do + expect(aamva_proofer).to receive(:proof) - context 'it is covered by AAMVA' do - let(:successful_aamva_proof) { instance_double(Proofing::StateIdResult) } - before do - allow(aamva_proofer).to receive(:proof).and_return(successful_aamva_proof) - allow(successful_aamva_proof).to receive(:verified_attributes). - and_return([:address]) - allow(successful_aamva_proof).to receive(:success?).and_return(true) - end - it 'indicates aamva did pass' do - result = subject - - expect(result.state_id_result.success?).to eq(true) - end - end + subject end - end - context 'LexisNexis InstantVerify passes for residential address and id address' do - context 'should proof with AAMVA' do - let(:id_resolution_that_passed_instant_verify) do - instance_double(Proofing::Resolution::Result) - end - let(:residential_resolution_that_passed_instant_verify) do - instance_double(Proofing::Resolution::Result) + context 'AAMVA proofing fails' do + let(:aamva_client) { instance_double(Proofing::Aamva::VerificationClient) } + let(:failed_aamva_proof) do + instance_double(Proofing::StateIdResult) end - before do - allow(instance).to receive(:proof_residential_address_if_needed). - and_return(residential_resolution_that_passed_instant_verify) - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(id_resolution_that_passed_instant_verify) - allow(instant_verify_proofer).to receive(:proof). - with(hash_including(state_id_address)). - and_return(id_resolution_that_passed_instant_verify) - allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(id_resolution_that_passed_instant_verify). - and_return(true) - allow(id_resolution_that_passed_instant_verify).to receive(:success?). - and_return(true) - allow(residential_resolution_that_passed_instant_verify).to receive(:success?). - and_return(true) + allow(Proofing::Aamva::VerificationClient).to receive(:new).and_return(aamva_client) + allow(failed_aamva_proof).to receive(:success?).and_return(false) end + it 'returns a result adjudicator that indicates the aamva proofing failed' do + allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - it 'makes a request to the AAMVA proofer' do - expect(aamva_proofer).to receive(:proof) - - subject - end + result = subject - context 'AAMVA proofing fails' do - let(:aamva_client) { instance_double(Proofing::Aamva::VerificationClient) } - let(:failed_aamva_proof) do - instance_double(Proofing::StateIdResult) - end - before do - allow(Proofing::Aamva::VerificationClient).to receive(:new).and_return(aamva_client) - allow(failed_aamva_proof).to receive(:success?).and_return(false) - end - it 'returns a result adjudicator that indicates the aamva proofing failed' do - allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - - result = subject - - expect(result.state_id_result.success?).to eq(false) - end + expect(result.state_id_result.success?).to eq(false) end end end end + end - context 'residential address and id address are different' do - let(:residential_address_proof) do - instance_double(Proofing::Resolution::Result) - end - let(:resolution_result) do - instance_double(Proofing::Resolution::Result) - end - let(:double_address_verification) { true } - let(:applicant_pii) do - JSON.parse(<<-STR, symbolize_names: true) + context 'residential address and id address are different' do + let(:residential_address_proof) do + instance_double(Proofing::Resolution::Result) + end + let(:resolution_result) do + instance_double(Proofing::Resolution::Result) + end + let(:double_address_verification) { true } + let(:applicant_pii) do + JSON.parse(<<-STR, symbolize_names: true) { "uuid": "3e8db152-4d35-4207-b828-3eee8c52c50f", "middle_name": "", @@ -291,164 +289,130 @@ "state_id_type": "drivers_license", "uuid_prefix": null } - STR - end - let(:residential_address) do - { - address1: applicant_pii[:address1], - address2: applicant_pii[:address2], - city: applicant_pii[:city], - state: applicant_pii[:state], - state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], - zipcode: applicant_pii[:zipcode], - } - end - let(:state_id_address) do - { - address1: applicant_pii[:identity_doc_address1], - address2: applicant_pii[:identity_doc_address2], - city: applicant_pii[:identity_doc_city], - state: applicant_pii[:identity_doc_address_state], - state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], - zipcode: applicant_pii[:identity_doc_zipcode], - } - end - - context 'LexisNexis InstantVerify passes for residential address' do - before do - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) - allow(residential_address_proof).to receive(:success?).and_return(true) - end - context 'LexisNexis InstantVerify passes for id address' do - it 'makes two requests to the InstantVerify Proofer' do - expect(instant_verify_proofer).to receive(:proof). - with(hash_including(residential_address)). - ordered - expect(instant_verify_proofer).to receive(:proof). - with(hash_including(state_id_address)). - ordered - - subject - end + STR + end + let(:residential_address) do + { + address1: applicant_pii[:address1], + address2: applicant_pii[:address2], + city: applicant_pii[:city], + state: applicant_pii[:state], + state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], + zipcode: applicant_pii[:zipcode], + } + end + let(:state_id_address) do + { + address1: applicant_pii[:identity_doc_address1], + address2: applicant_pii[:identity_doc_address2], + city: applicant_pii[:identity_doc_city], + state: applicant_pii[:identity_doc_address_state], + state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], + zipcode: applicant_pii[:identity_doc_zipcode], + } + end - context 'AAMVA fails' do - let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - before do - allow(instance).to receive(:proof_id_with_aamva_if_needed). - and_return(failed_aamva_proof) - allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) - allow(failed_aamva_proof).to receive(:success?).and_return(false) - allow(resolution_result).to receive(:errors) - end - - it 'returns the correct resolution results' do - result_adjudicator = subject - - expect(result_adjudicator.residential_resolution_result.success?).to be(true) - expect(result_adjudicator.resolution_result.success?).to be(true) - expect(result_adjudicator.state_id_result.success?).to be(false) - end - end - end + context 'LexisNexis InstantVerify passes for residential address' do + before do + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) + allow(residential_address_proof).to receive(:success?).and_return(true) end - context 'LexisNexis InstantVerify fails for residential address' do - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - - before do - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - allow(instance).to receive(:proof_residential_address_if_needed). - and_return(residential_address_proof) - allow(instant_verify_proofer).to receive(:proof). + context 'LexisNexis InstantVerify passes for id address' do + it 'makes two requests to the InstantVerify Proofer' do + expect(instant_verify_proofer).to receive(:proof). with(hash_including(residential_address)). - and_return(residential_address_proof) - allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(residential_address_proof). - and_return(false) - allow(residential_address_proof).to receive(:success?). - and_return(false) - end - - it 'does not make unnecessary calls' do - expect(aamva_proofer).to_not receive(:proof) - expect(instant_verify_proofer).to_not receive(:proof). - with(hash_including(state_id_address)) + ordered + expect(instant_verify_proofer).to receive(:proof). + with(hash_including(state_id_address)). + ordered subject end - end - - context 'LexisNexis InstantVerify fails for id address & passes for residential address' do - let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - let(:result_that_failed_instant_verify) do - instance_double(Proofing::Resolution::Result) - end - - before do - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) - allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). - and_return(result_that_failed_instant_verify) - allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). - and_return(result_that_failed_instant_verify) - end - context 'the failure can be covered by AAMVA' do + context 'AAMVA fails' do let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } before do - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) - allow(residential_address_proof).to receive(:success?).and_return(true) - - allow(instance).to receive(:user_can_pass_after_state_id_check?). - with(result_that_failed_instant_verify). - and_return(true) - allow(result_that_failed_instant_verify). - to receive(:attributes_requiring_additional_verification). - and_return([:address]) - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:proof_id_with_aamva_if_needed). + and_return(failed_aamva_proof) + allow(aamva_proofer).to receive(:proof).and_return(failed_aamva_proof) + allow(failed_aamva_proof).to receive(:success?).and_return(false) + allow(resolution_result).to receive(:errors) end - it 'calls AAMVA' do - expect(aamva_proofer).to receive(:proof) - subject + it 'returns the correct resolution results' do + result_adjudicator = subject + + expect(result_adjudicator.residential_resolution_result.success?).to be(true) + expect(result_adjudicator.resolution_result.success?).to be(true) + expect(result_adjudicator.state_id_result.success?).to be(false) end end end end - end + context 'LexisNexis InstantVerify fails for residential address' do + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } - context 'when double address verification is not enabled' do - let(:double_address_verification) { false } - let(:applicant_pii) do - # test ensures same_address_as_id value has no effect - Idp::Constants::MOCK_IDV_APPLICANT.merge(same_address_as_id: 'true') - end - let(:residential_instant_verify_proof) do - instance_double(Proofing::Resolution::Result) + before do + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:proof_residential_address_if_needed). + and_return(residential_address_proof) + allow(instant_verify_proofer).to receive(:proof). + with(hash_including(residential_address)). + and_return(residential_address_proof) + allow(instance).to receive(:user_can_pass_after_state_id_check?). + with(residential_address_proof). + and_return(false) + allow(residential_address_proof).to receive(:success?). + and_return(false) + end + + it 'does not make unnecessary calls' do + expect(aamva_proofer).to_not receive(:proof) + expect(instant_verify_proofer).to_not receive(:proof). + with(hash_including(state_id_address)) + + subject + end end - it 'makes one request to LexisNexis InstantVerify' do - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instant_verify_proofer).to receive(:proof). - and_return(residential_instant_verify_proof) - allow(residential_instant_verify_proof).to receive(:success?).and_return(true) + context 'LexisNexis InstantVerify fails for id address & passes for residential address' do + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + let(:result_that_failed_instant_verify) do + instance_double(Proofing::Resolution::Result) + end - expect(instant_verify_proofer).to receive(:proof).exactly(:once) + before do + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(instance).to receive(:proof_id_address_with_lexis_nexis_if_needed). + and_return(result_that_failed_instant_verify) + allow(instant_verify_proofer).to receive(:proof).with(hash_including(state_id_address)). + and_return(result_that_failed_instant_verify) + end - subject - end + context 'the failure can be covered by AAMVA' do + let(:failed_aamva_proof) { instance_double(Proofing::StateIdResult) } + let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer) } + before do + allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(instant_verify_proofer).to receive(:proof).and_return(residential_address_proof) + allow(residential_address_proof).to receive(:success?).and_return(true) - it 'returns distinct objects for the resolution result and residential resolution result' do - result = subject + allow(instance).to receive(:user_can_pass_after_state_id_check?). + with(result_that_failed_instant_verify). + and_return(true) + allow(result_that_failed_instant_verify). + to receive(:attributes_requiring_additional_verification). + and_return([:address]) + allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + end + it 'calls AAMVA' do + expect(aamva_proofer).to receive(:proof) - expect(result.residential_resolution_result).to_not eq(result.resolution_result) - expect( - result.residential_resolution_result. - vendor_name, - ).to eq('ResidentialAddressNotRequired') - expect(result.resolution_result.vendor_name).to eq('lexisnexis:instant_verify') + subject + end + end end end end diff --git a/spec/services/proofing/resolution/result_adjudicator_spec.rb b/spec/services/proofing/resolution/result_adjudicator_spec.rb index f517f735617..bcf167fd98b 100644 --- a/spec/services/proofing/resolution/result_adjudicator_spec.rb +++ b/spec/services/proofing/resolution/result_adjudicator_spec.rb @@ -29,8 +29,8 @@ end let(:should_proof_state_id) { true } - let(:double_address_verification) { false } - let(:same_address_as_id) { 'true' } + let(:double_address_verification) { true } + let(:same_address_as_id) { 'false' } let(:device_profiling_success) { true } let(:device_profiling_exception) { nil } @@ -57,98 +57,8 @@ end describe '#adjudicated_result' do - context 'double address verification is disabled' do - context 'AAMVA and LexisNexis both pass' do - it 'returns a successful response' do - result = subject.adjudicated_result - - expect(result.success?).to eq(true) - end - end - context 'LexisNexis fails with attributes covered by AAMVA response' do - let(:resolution_success) { false } - let(:can_pass_with_additional_verification) { true } - let(:attributes_requiring_additional_verification) { [:dob] } - let(:state_id_verified_attributes) { [:dob, :address] } - - it 'returns a successful response' do - result = subject.adjudicated_result - - expect(result.success?).to eq(true) - end - end - - context 'LexisNexis fails with attributes not covered by AAMVA response' do - let(:resolution_success) { false } - let(:can_pass_with_additional_verification) { true } - let(:attributes_requiring_additional_verification) { [:address] } - let(:state_id_verified_attributes) { [:dob] } - - it 'returns a failed response' do - result = subject.adjudicated_result - - expect(result.success?).to eq(false) - end - end - - context 'LexisNexis fails and AAMVA state is unsupported' do - let(:should_proof_state_id) { false } - let(:resolution_success) { false } - - it 'returns a failed response' do - result = subject.adjudicated_result - - expect(result.success?).to eq(false) - end - end - - context 'LexisNexis passes and AAMVA fails' do - let(:resolution_success) { true } - let(:state_id_success) { false } - - it 'returns a failed response' do - result = subject.adjudicated_result - - expect(result.success?).to eq(false) - end - end - - context 'Device profiling fails and everything else passes' do - let(:device_profiling_success) { false } - let(:device_profiling_review_status) { 'fail' } - - it 'returns a successful response including the review status' do - result = subject.adjudicated_result - - expect(result.success?).to eq(true) - - threatmetrix_context = result.extra[:context][:stages][:threatmetrix] - expect(threatmetrix_context[:success]).to eq(false) - expect(threatmetrix_context[:review_status]).to eq('fail') - end - end - - context 'Device profiling experiences an exception' do - let(:device_profiling_success) { false } - let(:device_profiling_exception) { 'this is a test value' } - - it 'returns a failed response' do - result = subject.adjudicated_result - - expect(result.success?).to eq(false) - - threatmetrix_context = result.extra[:context][:stages][:threatmetrix] - expect(threatmetrix_context[:success]).to eq(false) - expect(threatmetrix_context[:exception]).to eq('this is a test value') - end - end - end - - context 'double address verification is enabled' do - let(:double_address_verification) { true } - let(:should_proof_state_id) { true } + context 'double address verification is enabled' do context 'residential address and id address are different' do - let(:same_address_as_id) { 'false' } context 'LexisNexis fails for the residential address' do let(:resolution_success) { false } let(:residential_resolution_result) do From a452cc01e82c61cf804a86ff06e585bfb18858fb Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 27 Sep 2023 17:54:30 -0400 Subject: [PATCH 28/37] update spec names in get usps proofing job --- spec/jobs/get_usps_proofing_results_job_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb index 9dbe5b94cb7..8b517ec960d 100644 --- a/spec/jobs/get_usps_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_proofing_results_job_spec.rb @@ -218,7 +218,7 @@ describe '#perform' do describe 'IPP enabled' do - describe 'DAV not enabled' do + describe 'Proofed without secondary id' do let!(:pending_enrollments) do ['BALTIMORE', 'FRIENDSHIP', 'WASHINGTON', 'ARLINGTON', 'DEANWOOD'].map do |name| create( @@ -1149,7 +1149,7 @@ end end - describe 'proofed with secondary id' do + describe 'Proofed with secondary id' do let(:pending_enrollment) do create( :in_person_enrollment, :pending From c1bff8a39aef5710071eb99dc2c5e1d6bcda62ec Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 27 Sep 2023 18:01:30 -0400 Subject: [PATCH 29/37] changelog: Internal, Double address verification, make dav default state for ipp From 90510ca099b4ad25a198c2fd9861332a7a98574a Mon Sep 17 00:00:00 2001 From: svalexander Date: Wed, 27 Sep 2023 18:04:02 -0400 Subject: [PATCH 30/37] remove capture secondary id flag from id_config --- lib/identity_config.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/identity_config.rb b/lib/identity_config.rb index efd6d81840e..320cc1468b8 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -235,7 +235,6 @@ def self.build_store(config_map) 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) - config.add(:in_person_capture_secondary_id_enabled, type: :boolean) config.add(:in_person_completion_survey_url, type: :string) config.add(:in_person_doc_auth_button_enabled, type: :boolean) config.add(:in_person_email_reminder_early_benchmark_in_days, type: :integer) From 383c56c9357948ea86396ea7f8ea1ae7ebf5ca04 Mon Sep 17 00:00:00 2001 From: svalexander Date: Thu, 28 Sep 2023 11:27:24 -0400 Subject: [PATCH 31/37] add back in necessary tests and replace analytics_id check --- .../concerns/idv/verify_info_concern.rb | 2 +- app/jobs/resolution_proofing_job.rb | 2 +- .../in_person/verify_info_controller_spec.rb | 118 +++++++++++++++++- .../resolution/result_adjudicator_spec.rb | 2 +- 4 files changed, 115 insertions(+), 9 deletions(-) diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb index 0b671238b93..fbbc4f4b07b 100644 --- a/app/controllers/concerns/idv/verify_info_concern.rb +++ b/app/controllers/concerns/idv/verify_info_concern.rb @@ -44,7 +44,7 @@ def shared_update def double_address_verification # if in person return true else return false - analytics_arguments[:analytics_id] == 'In Person Proofing' + current_user.has_in_person_enrollment? end def should_use_aamva?(pii) diff --git a/app/jobs/resolution_proofing_job.rb b/app/jobs/resolution_proofing_job.rb index 87b597b43f0..650e1ef1a85 100644 --- a/app/jobs/resolution_proofing_job.rb +++ b/app/jobs/resolution_proofing_job.rb @@ -79,8 +79,8 @@ def make_vendor_proofing_requests( threatmetrix_session_id: threatmetrix_session_id, request_ip: request_ip, should_proof_state_id: should_proof_state_id, - timer: timer, double_address_verification: double_address_verification, + timer: timer, ) log_threatmetrix_info(result.device_profiling_result, user) diff --git a/spec/controllers/idv/in_person/verify_info_controller_spec.rb b/spec/controllers/idv/in_person/verify_info_controller_spec.rb index cdf7c01c291..66200e5d465 100644 --- a/spec/controllers/idv/in_person/verify_info_controller_spec.rb +++ b/spec/controllers/idv/in_person/verify_info_controller_spec.rb @@ -122,23 +122,129 @@ end describe '#update' do + it 'redirects to the expected page' do + put :update + + expect(response).to redirect_to idv_in_person_verify_info_url + end + let(:pii_from_user) { Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS.dup } let(:enrollment) { InPersonEnrollment.new } before do allow(user).to receive(:establishing_in_person_enrollment).and_return(enrollment) end - it 'redirects to the expected page' do + it 'sets uuid_prefix and state_id_type on pii_from_user' do + expect(Idv::Agent).to receive(:new). + with(hash_including(uuid_prefix: service_provider.app_id)).and_call_original + # our test data already has the expected value by default + flow_session[:pii_from_user].delete(:state_id_type) + put :update - expect(response).to redirect_to idv_in_person_verify_info_url + expect(flow_session[:pii_from_user][:state_id_type]).to eq 'drivers_license' + expect(flow_session[:pii_from_user][:uuid_prefix]).to eq service_provider.app_id end - it 'captures state id address fields in the pii' do - expect(Idv::Agent).to receive(:new). - with(Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS.merge(uuid_prefix: nil)). - and_call_original + context 'a user does not have an establishing in person enrollment associated with them' do + before do + allow(user).to receive(:establishing_in_person_enrollment).and_return(nil) + end + + it 'disables double address verification for the user' do + expect_any_instance_of(Idv::Agent).to receive(:proof_resolution). + with( + kind_of(DocumentCaptureSession), + should_proof_state_id: anything, + trace_id: subject.send(:amzn_trace_id), + threatmetrix_session_id: nil, + user_id: anything, + request_ip: request.remote_ip, + double_address_verification: false, + ) + + put :update + end + end + + context 'a user does have an establishing in person enrollment associated with them' do + it 'indicates to the IDV agent that double_address_verification is enabled' do + expect_any_instance_of(Idv::Agent).to receive(:proof_resolution).with( + kind_of(DocumentCaptureSession), + should_proof_state_id: anything, + trace_id: anything, + threatmetrix_session_id: anything, + user_id: anything, + request_ip: anything, + double_address_verification: true, + ) + + put :update + end + + it 'captures state id address fields in the pii' do + expect(Idv::Agent).to receive(:new). + with(Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS.merge(uuid_prefix: nil)). + and_call_original + put :update + end + end + + it 'passes the X-Amzn-Trace-Id to the proofer' do + expect_any_instance_of(Idv::Agent).to receive(:proof_resolution). + with( + kind_of(DocumentCaptureSession), + should_proof_state_id: anything, + trace_id: subject.send(:amzn_trace_id), + threatmetrix_session_id: nil, + user_id: anything, + request_ip: request.remote_ip, + double_address_verification: true, + ) + + put :update + end + + it 'only enqueues a job once' do + put :update + expect_any_instance_of(Idv::Agent).to_not receive(:proof_resolution) + put :update end + + context 'when pii_from_user is blank' do + it 'redirects' do + flow_session[:pii_from_user] = {} + put :update + expect(response.status).to eq 302 + end + end + + context 'when different users use the same SSN within the same timeframe' do + let(:user2) { create(:user) } + + before do + allow(IdentityConfig.store).to receive(:proof_ssn_max_attempts).and_return(3) + allow(IdentityConfig.store).to receive(:proof_ssn_max_attempt_window_in_minutes). + and_return(10) + end + + it 'rate limits them all' do + put :update + subject.idv_session.verify_info_step_document_capture_session_uuid = nil + put :update + subject.idv_session.verify_info_step_document_capture_session_uuid = nil + put :update + put :update + expect_any_instance_of(Idv::Agent).to_not receive(:proof_resolution) + expect(response).to redirect_to(idv_session_errors_ssn_failure_url) + subject.idv_session.verify_info_step_document_capture_session_uuid = nil + + stub_sign_in(user2) + put :update + expect_any_instance_of(Idv::Agent).to_not receive(:proof_resolution) + expect(response).to redirect_to(idv_session_errors_ssn_failure_url) + end + end end end diff --git a/spec/services/proofing/resolution/result_adjudicator_spec.rb b/spec/services/proofing/resolution/result_adjudicator_spec.rb index bcf167fd98b..cb4bcb781ee 100644 --- a/spec/services/proofing/resolution/result_adjudicator_spec.rb +++ b/spec/services/proofing/resolution/result_adjudicator_spec.rb @@ -57,7 +57,7 @@ end describe '#adjudicated_result' do - context 'double address verification is enabled' do + context 'double address verification is enabled' do context 'residential address and id address are different' do context 'LexisNexis fails for the residential address' do let(:resolution_success) { false } From ea25867011c252680a7f1a4e283612c6197e2506 Mon Sep 17 00:00:00 2001 From: svalexander Date: Thu, 28 Sep 2023 13:10:33 -0400 Subject: [PATCH 32/37] remove needs_proof_of_address which would always be false --- .../idv/in_person/ready_to_verify_presenter.rb | 4 ---- .../verification_results_email_presenter.rb | 4 ---- .../idv/in_person/ready_to_verify/show.html.erb | 11 ----------- app/views/user_mailer/in_person_failed.html.erb | 3 --- .../shared/_in_person_ready_to_verify.html.erb | 15 --------------- .../in_person/ready_to_verify_presenter_spec.rb | 16 ---------------- .../verification_results_email_presenter_spec.rb | 16 ---------------- 7 files changed, 69 deletions(-) diff --git a/app/presenters/idv/in_person/ready_to_verify_presenter.rb b/app/presenters/idv/in_person/ready_to_verify_presenter.rb index ef99c2e3cb2..3398cb572c9 100644 --- a/app/presenters/idv/in_person/ready_to_verify_presenter.rb +++ b/app/presenters/idv/in_person/ready_to_verify_presenter.rb @@ -30,10 +30,6 @@ def selected_location_hours(prefix) return localized_hours(hours) if hours end - def needs_proof_of_address? - !enrollment.current_address_matches_id - end - def service_provider enrollment.service_provider end diff --git a/app/presenters/idv/in_person/verification_results_email_presenter.rb b/app/presenters/idv/in_person/verification_results_email_presenter.rb index f8ed209f725..98523931bbf 100644 --- a/app/presenters/idv/in_person/verification_results_email_presenter.rb +++ b/app/presenters/idv/in_person/verification_results_email_presenter.rb @@ -47,10 +47,6 @@ def service_provider_homepage_url sp_return_url_resolver.homepage_url if service_provider end - def needs_proof_of_address? - !enrollment.current_address_matches_id - end - private def sp_return_url_resolver diff --git a/app/views/idv/in_person/ready_to_verify/show.html.erb b/app/views/idv/in_person/ready_to_verify/show.html.erb index 917d7b2bf37..ff425592fb5 100644 --- a/app/views/idv/in_person/ready_to_verify/show.html.erb +++ b/app/views/idv/in_person/ready_to_verify/show.html.erb @@ -45,17 +45,6 @@ <% c.with_item(heading: t('in_person_proofing.process.state_id.heading')) do %>

<%= t('in_person_proofing.process.state_id.info') %>

<% end %> - <% if @presenter.needs_proof_of_address? %> - <% c.with_item(heading: t('in_person_proofing.process.proof_of_address.heading')) do %> -

<%= t('in_person_proofing.process.proof_of_address.info') %>

-
    - <% t('in_person_proofing.process.proof_of_address.acceptable_proof').each do |proof| %> -
  • <%= proof %>
  • - <% end %> -
-

<%= t('in_person_proofing.process.proof_of_address.physical_or_digital_copy') %>

- <% end %> - <% end %> <% end %>

<%= t('in_person_proofing.body.barcode.questions') %> diff --git a/app/views/user_mailer/in_person_failed.html.erb b/app/views/user_mailer/in_person_failed.html.erb index bd9117a6f34..4fe54f94d4c 100644 --- a/app/views/user_mailer/in_person_failed.html.erb +++ b/app/views/user_mailer/in_person_failed.html.erb @@ -16,9 +16,6 @@

<%= t('user_mailer.in_person_failed.verifying_identity') %>

  • <%= t('user_mailer.in_person_failed.verifying_step_not_expired') %>
  • - <% if @presenter.needs_proof_of_address? %> -
  • <%= t('user_mailer.in_person_failed.verifying_step_proof_of_address') %>
  • - <% end %>
<%= render 'shared/in-person-verification-results-email-lower' %> diff --git a/app/views/user_mailer/shared/_in_person_ready_to_verify.html.erb b/app/views/user_mailer/shared/_in_person_ready_to_verify.html.erb index ae55ab5aa3b..f033c58e5d7 100644 --- a/app/views/user_mailer/shared/_in_person_ready_to_verify.html.erb +++ b/app/views/user_mailer/shared/_in_person_ready_to_verify.html.erb @@ -62,21 +62,6 @@

<%= t('in_person_proofing.process.state_id.info') %>

- <% if @presenter.needs_proof_of_address? %> - -
4
- -

<%= t('in_person_proofing.process.proof_of_address.heading') %>

-

<%= t('in_person_proofing.process.proof_of_address.info') %>

-
    - <% t('in_person_proofing.process.proof_of_address.acceptable_proof').each do |proof| %> -
  • <%= proof %>
  • - <% end %> -
-

<%= t('in_person_proofing.process.proof_of_address.physical_or_digital_copy') %>

- - - <% end %>

<%= t('in_person_proofing.body.barcode.questions') %> diff --git a/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb b/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb index 9bda43c0ae4..4c66d801dae 100644 --- a/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb +++ b/spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb @@ -100,22 +100,6 @@ end end - describe '#needs_proof_of_address?' do - subject(:needs_proof_of_address) { presenter.needs_proof_of_address? } - - context 'with current address matching id' do - let(:current_address_matches_id) { true } - - it { expect(needs_proof_of_address).to eq false } - end - - context 'with current address not matching id' do - let(:current_address_matches_id) { false } - - it { expect(needs_proof_of_address).to eq true } - end - end - describe '#sp_name' do subject(:sp_name) { presenter.sp_name } diff --git a/spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb b/spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb index 787dfc459eb..4b53c3ae6da 100644 --- a/spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb +++ b/spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb @@ -183,20 +183,4 @@ end end end - - describe '#needs_proof_of_address?' do - subject(:needs_proof_of_address) { presenter.needs_proof_of_address? } - - context 'with current address matching id' do - let(:current_address_matches_id) { true } - - it { expect(needs_proof_of_address).to eq false } - end - - context 'with current address not matching id' do - let(:current_address_matches_id) { false } - - it { expect(needs_proof_of_address).to eq true } - end - end end From 8f351ca94dd1f411a5bf0f9e5e769275643b3cff Mon Sep 17 00:00:00 2001 From: svalexander Date: Thu, 28 Sep 2023 13:27:08 -0400 Subject: [PATCH 33/37] remove unused translations related to needs_proof_of_address --- config/locales/in_person_proofing/en.yml | 12 ------------ config/locales/in_person_proofing/es.yml | 13 ------------- config/locales/in_person_proofing/fr.yml | 13 ------------- config/locales/user_mailer/en.yml | 3 --- config/locales/user_mailer/es.yml | 4 ---- config/locales/user_mailer/fr.yml | 4 ---- 6 files changed, 49 deletions(-) diff --git a/config/locales/in_person_proofing/en.yml b/config/locales/in_person_proofing/en.yml index dac6459c85e..22962daf2ed 100644 --- a/config/locales/in_person_proofing/en.yml +++ b/config/locales/in_person_proofing/en.yml @@ -149,18 +149,6 @@ en: heading: Show your %{app_name} barcode info: The retail associate needs to scan your barcode at the top of this page. You can print this page or show it on your mobile device. - proof_of_address: - acceptable_proof: - - Lease, Mortgage, or Deed of Trust - - Voter Registration - - Vehicle Registration Card - - Home or Vehicle Insurance Policy - heading: Proof of your current address - info: 'You need a proof of address if your current address is different than the - address on your ID. Acceptable forms of proof of address are:' - physical_or_digital_copy: You can bring a physical copy or show a digital copy - of the document. You cannot show a photo or screenshot of the - document. state_id: heading: Show your State Driver’s License or State Non-Driver’s Identification Card diff --git a/config/locales/in_person_proofing/es.yml b/config/locales/in_person_proofing/es.yml index b8f6c3b3648..812b0e144ce 100644 --- a/config/locales/in_person_proofing/es.yml +++ b/config/locales/in_person_proofing/es.yml @@ -164,19 +164,6 @@ es: info: El empleado deberá escanear el código de barras que aparece en la parte superior de esta página. Puede imprimir esta página o mostrarla en su dispositivo móvil. - proof_of_address: - acceptable_proof: - - Arrendamiento, hipoteca o escritura de fideicomiso - - Registro de votantes - - Tarjeta de registro del vehículo - - Póliza de seguro del hogar o del vehículo - heading: Prueba de su dirección actual - info: 'Necesita un justificante de domicilio si su dirección actual es diferente - a la que figura en su cédula de identidad. Los comprobantes de - domicilio aceptables son:' - physical_or_digital_copy: Puede traer una copia física o mostrar una copia - digital del documento. No puede mostrar una foto o una captura de - pantalla del documento. state_id: heading: Muestre su licencia de conducir estatal o su tarjeta de identificación estatal de no conductor diff --git a/config/locales/in_person_proofing/fr.yml b/config/locales/in_person_proofing/fr.yml index 69b9d8b1c09..196b4ac8dc5 100644 --- a/config/locales/in_person_proofing/fr.yml +++ b/config/locales/in_person_proofing/fr.yml @@ -164,19 +164,6 @@ fr: heading: Montrez votre code-barres %{app_name} info: Le vendeur doit scanner votre code-barres en haut de cette page. Vous pouvez imprimer cette page ou la montrer sur votre appareil mobile. - proof_of_address: - acceptable_proof: - - Bail, hypothèque ou acte de fiducie - - Inscription sur les listes électorales - - Carte d’immatriculation du véhicule - - Police d’assurance habitation ou véhicule - heading: Preuve de votre adresse actuelle - info: 'Vous avez besoin d’un justificatif de domicile si votre adresse actuelle - est différente de l’adresse figurant sur votre document d’identité. - Les justificatifs d’adresse acceptés sont les suivants:' - physical_or_digital_copy: Vous pouvez apporter une copie physique ou montrer une - copie numérique du document. Vous ne pouvez pas montrer une photo ou - une capture d’écran du document. state_id: heading: Présentez votre permis de conduire de l’État ou votre carte d’identité de non-conducteur de l’État diff --git a/config/locales/user_mailer/en.yml b/config/locales/user_mailer/en.yml index 07c46f4d308..6fdf667b388 100644 --- a/config/locales/user_mailer/en.yml +++ b/config/locales/user_mailer/en.yml @@ -129,9 +129,6 @@ en: verifying_step_not_expired: Your state‑issued ID or driver’s license must not be expired. We do not currently accept any other forms of identification, such as passports and military IDs. - verifying_step_proof_of_address: If you try to verify your identity in person - again, you need to bring a valid proof of address if your current - address is different than the address on your ID. in_person_failed_suspected_fraud: body: help_center_html: If you need further help, you can Date: Thu, 28 Sep 2023 13:54:04 -0400 Subject: [PATCH 34/37] remove enrollment from passed_with_unsupported_secondary_id_type --- app/jobs/get_usps_proofing_results_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index 862477f2d9e..0368a69232a 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -120,7 +120,7 @@ def check_enrollment(enrollment) enrollment.update(status_check_attempted_at: status_check_attempted_at) end - def passed_with_unsupported_secondary_id_type?(_enrollment, response) + def passed_with_unsupported_secondary_id_type?(response) return response['secondaryIdType'].present? && SUPPORTED_SECONDARY_ID_TYPES.exclude?(response['secondaryIdType']) end @@ -413,7 +413,7 @@ def process_enrollment_response(enrollment, response) case response['status'] when IPP_STATUS_PASSED - if passed_with_unsupported_secondary_id_type?(enrollment, response) + if passed_with_unsupported_secondary_id_type?(response) handle_unsupported_secondary_id(enrollment, response) elsif SUPPORTED_ID_TYPES.include?(response['primaryIdType']) handle_successful_status_update(enrollment, response) From 1bc5dfa233ba2e8821fe670c1daf7b52436ab68b Mon Sep 17 00:00:00 2001 From: svalexander Date: Thu, 28 Sep 2023 16:15:22 -0400 Subject: [PATCH 35/37] remove reference to strings that are removed --- .../ready_to_verify/show.html.erb_spec.rb | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/spec/views/idv/in_person/ready_to_verify/show.html.erb_spec.rb b/spec/views/idv/in_person/ready_to_verify/show.html.erb_spec.rb index 76583e5bacb..ef12a9aa5a8 100644 --- a/spec/views/idv/in_person/ready_to_verify/show.html.erb_spec.rb +++ b/spec/views/idv/in_person/ready_to_verify/show.html.erb_spec.rb @@ -65,26 +65,6 @@ ) end - context 'with enrollment where current address matches id' do - let(:current_address_matches_id) { true } - - it 'renders without proof of address instructions' do - render - - expect(rendered).not_to have_content(t('in_person_proofing.process.proof_of_address.heading')) - end - end - - context 'with enrollment where current address does not match id' do - let(:current_address_matches_id) { false } - - it 'renders with proof of address instructions' do - render - - expect(rendered).to have_content(t('in_person_proofing.process.proof_of_address.heading')) - end - end - context 'with enrollment where selected_location_details is present' do it 'renders a location' do render From 274ce94f5f5522eb2c5505c93388ecb2814d0603 Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 29 Sep 2023 11:18:01 -0400 Subject: [PATCH 36/37] remove config from application.yml.default --- config/application.yml.default | 1 - 1 file changed, 1 deletion(-) diff --git a/config/application.yml.default b/config/application.yml.default index 728986ea5f8..1c8a009f264 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -123,7 +123,6 @@ idv_getting_started_a_b_testing: '{"welcome_default":100, "welcome_new":0, "gett idv_send_link_attempt_window_in_minutes: 10 idv_send_link_max_attempts: 5 idv_sp_required: false -in_person_capture_secondary_id_enabled: false in_person_public_address_search_enabled: false in_person_doc_auth_button_enabled: true in_person_email_reminder_early_benchmark_in_days: 11 From e3fb7728ab8c9ccc49fc4cd4f0f513c4fcb7f38c Mon Sep 17 00:00:00 2001 From: svalexander Date: Fri, 6 Oct 2023 14:53:52 -0400 Subject: [PATCH 37/37] implement feedback --- .../concerns/idv/verify_info_concern.rb | 4 +- lib/idp/constants.rb | 2 +- .../idv/doc_auth/verify_info_step_spec.rb | 2 +- .../resolution/result_adjudicator_spec.rb | 58 +++++++++---------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb index fbbc4f4b07b..647540c3722 100644 --- a/app/controllers/concerns/idv/verify_info_concern.rb +++ b/app/controllers/concerns/idv/verify_info_concern.rb @@ -43,7 +43,9 @@ def shared_update private def double_address_verification - # if in person return true else return false + # If in person return true else return false. This is temporary until we add a feature flag + # to track enrollment was created in the in person flow. + # todo LG-11235 update value based on new feature flag current_user.has_in_person_enrollment? end diff --git a/lib/idp/constants.rb b/lib/idp/constants.rb index 620e7bda419..ea123d5b9e6 100644 --- a/lib/idp/constants.rb +++ b/lib/idp/constants.rb @@ -113,7 +113,7 @@ module Vendors same_address_as_id: 'false', ).freeze - # This should be the default applicant for ipp + # Use this as the default applicant for in person proofing MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID = MOCK_IDV_APPLICANT_WITH_SSN.merge( identity_doc_address1: MOCK_IDV_APPLICANT_WITH_SSN[:address1], identity_doc_address2: MOCK_IDV_APPLICANT_WITH_SSN[:address2], diff --git a/spec/features/idv/doc_auth/verify_info_step_spec.rb b/spec/features/idv/doc_auth/verify_info_step_spec.rb index 5b3fba29796..21c127f564f 100644 --- a/spec/features/idv/doc_auth/verify_info_step_spec.rb +++ b/spec/features/idv/doc_auth/verify_info_step_spec.rb @@ -271,8 +271,8 @@ { trace_id: anything, threatmetrix_session_id: anything, - double_address_verification: false, request_ip: kind_of(String), + double_address_verification: false, } end diff --git a/spec/services/proofing/resolution/result_adjudicator_spec.rb b/spec/services/proofing/resolution/result_adjudicator_spec.rb index cb4bcb781ee..b3bfd220133 100644 --- a/spec/services/proofing/resolution/result_adjudicator_spec.rb +++ b/spec/services/proofing/resolution/result_adjudicator_spec.rb @@ -57,40 +57,38 @@ end describe '#adjudicated_result' do - context 'double address verification is enabled' do - context 'residential address and id address are different' do - context 'LexisNexis fails for the residential address' do - let(:resolution_success) { false } - let(:residential_resolution_result) do - Proofing::Resolution::Result.new( - success: resolution_success, - errors: {}, - exception: nil, - vendor_name: 'test-resolution-vendor', - failed_result_can_pass_with_additional_verification: - can_pass_with_additional_verification, - attributes_requiring_additional_verification: - attributes_requiring_additional_verification, - ) - end - it 'returns a failed response' do - result = subject.adjudicated_result + context 'residential address and id address are different' do + context 'LexisNexis fails for the residential address' do + let(:resolution_success) { false } + let(:residential_resolution_result) do + Proofing::Resolution::Result.new( + success: resolution_success, + errors: {}, + exception: nil, + vendor_name: 'test-resolution-vendor', + failed_result_can_pass_with_additional_verification: + can_pass_with_additional_verification, + attributes_requiring_additional_verification: + attributes_requiring_additional_verification, + ) + end + it 'returns a failed response' do + result = subject.adjudicated_result - expect(result.success?).to eq(false) - resolution_adjudication_reason = result.extra[:context][:resolution_adjudication_reason] - expect(resolution_adjudication_reason).to eq(:fail_resolution_skip_state_id) - end + expect(result.success?).to eq(false) + resolution_adjudication_reason = result.extra[:context][:resolution_adjudication_reason] + expect(resolution_adjudication_reason).to eq(:fail_resolution_skip_state_id) end + end - context 'AAMVA fails for the id address' do - let(:state_id_success) { false } - it 'returns a failed response' do - result = subject.adjudicated_result + context 'AAMVA fails for the id address' do + let(:state_id_success) { false } + it 'returns a failed response' do + result = subject.adjudicated_result - expect(result.success?).to eq(false) - resolution_adjudication_reason = result.extra[:context][:resolution_adjudication_reason] - expect(resolution_adjudication_reason).to eq(:fail_state_id) - end + expect(result.success?).to eq(false) + resolution_adjudication_reason = result.extra[:context][:resolution_adjudication_reason] + expect(resolution_adjudication_reason).to eq(:fail_state_id) end end end