diff --git a/app/jobs/resolution_proofing_job.rb b/app/jobs/resolution_proofing_job.rb index ea7110f6d14..afa1092459b 100644 --- a/app/jobs/resolution_proofing_job.rb +++ b/app/jobs/resolution_proofing_job.rb @@ -79,7 +79,7 @@ def make_vendor_proofing_requests( should_proof_state_id:, ipp_enrollment_in_progress: ) - result = resolution_proofer.proof( + result = progressive_proofer.proof( applicant_pii: applicant_pii, user_email: user.confirmed_email_addresses.first.email, threatmetrix_session_id: threatmetrix_session_id, @@ -114,8 +114,8 @@ def logger_info_hash(hash) logger.info(hash.to_json) end - def resolution_proofer - @resolution_proofer ||= Proofing::Resolution::ProgressiveProofer.new + def progressive_proofer + @progressive_proofer ||= Proofing::Resolution::ProgressiveProofer.new end def add_threatmetrix_proofing_component(user_id, threatmetrix_result) diff --git a/app/services/proofing/resolution/progressive_proofer.rb b/app/services/proofing/resolution/progressive_proofer.rb index a2a339bb1f0..031c445e6ad 100644 --- a/app/services/proofing/resolution/progressive_proofer.rb +++ b/app/services/proofing/resolution/progressive_proofer.rb @@ -8,6 +8,13 @@ module Resolution # 2. The user has only provided one address for their residential and identity document # address or separate residential and identity document addresses class ProgressiveProofer + attr_reader :applicant_pii, + :request_ip, + :should_proof_state_id, + :threatmetrix_session_id, + :timer, + :user_email + # @param [Hash] applicant_pii keys are symbols and values are strings, confidential user info # @param [Boolean] ipp_enrollment_in_progress flag that indicates if user will have # both state id address and current residential address verified @@ -27,40 +34,18 @@ def proof( user_email:, ipp_enrollment_in_progress: ) - device_profiling_result = proof_with_threatmetrix_if_needed( - applicant_pii: applicant_pii, - request_ip: request_ip, - threatmetrix_session_id: threatmetrix_session_id, - timer: timer, - user_email: user_email, - ) - - residential_instant_verify_result = proof_residential_address_if_needed( - applicant_pii: applicant_pii, - timer: timer, - ipp_enrollment_in_progress: ipp_enrollment_in_progress, - ) - - applicant_pii_transformed = applicant_pii.clone - if ipp_enrollment_in_progress - 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, - ipp_enrollment_in_progress: ipp_enrollment_in_progress, - ) - - state_id_result = proof_id_with_aamva_if_needed( - applicant_pii: applicant_pii_transformed, - timer: timer, - residential_instant_verify_result: residential_instant_verify_result, - instant_verify_result: instant_verify_result, - should_proof_state_id: should_proof_state_id, - ipp_enrollment_in_progress: ipp_enrollment_in_progress, - ) + @applicant_pii = applicant_pii + @request_ip = request_ip + @should_proof_state_id = should_proof_state_id + @threatmetrix_session_id = threatmetrix_session_id + @timer = timer + @user_email = user_email + @ipp_enrollment_in_progress = ipp_enrollment_in_progress + + @device_profiling_result = proof_with_threatmetrix_if_needed + @residential_instant_verify_result = proof_residential_address_if_needed + @instant_verify_result = proof_id_address_with_lexis_nexis_if_needed + @state_id_result = proof_id_with_aamva_if_needed ResultAdjudicator.new( device_profiling_result: device_profiling_result, @@ -75,13 +60,12 @@ def proof( private - def proof_with_threatmetrix_if_needed( - applicant_pii:, - user_email:, - threatmetrix_session_id:, - request_ip:, - timer: - ) + attr_reader :device_profiling_result, + :residential_instant_verify_result, + :instant_verify_result, + :state_id_result + + def proof_with_threatmetrix_if_needed unless FeatureManagement.proofing_device_profiling_collecting_enabled? return threatmetrix_disabled_result end @@ -101,15 +85,11 @@ def proof_with_threatmetrix_if_needed( end end - def proof_residential_address_if_needed( - applicant_pii:, - timer:, - ipp_enrollment_in_progress: false - ) - return residential_address_unnecessary_result unless ipp_enrollment_in_progress + def proof_residential_address_if_needed + return residential_address_unnecessary_result unless ipp_enrollment_in_progress? timer.time('residential address') do - resolution_proofer.proof(applicant_pii) + resolution_proofer.proof(applicant_pii_with_residential_address) end end @@ -125,68 +105,62 @@ def resolution_cannot_pass ) end - def proof_id_address_with_lexis_nexis_if_needed(applicant_pii:, timer:, - residential_instant_verify_result:, - ipp_enrollment_in_progress:) - if applicant_pii[:same_address_as_id] == 'true' && ipp_enrollment_in_progress + def proof_id_address_with_lexis_nexis_if_needed + if same_address_as_id? && ipp_enrollment_in_progress? return residential_instant_verify_result end return resolution_cannot_pass unless residential_instant_verify_result.success? timer.time('resolution') do - resolution_proofer.proof(applicant_pii) + resolution_proofer.proof(applicant_pii_with_state_id_address) end end - def should_proof_state_id_with_aamva?(ipp_enrollment_in_progress:, same_address_as_id:, - should_proof_state_id:, instant_verify_result:, - residential_instant_verify_result:) + def should_proof_state_id_with_aamva? return false unless should_proof_state_id # If the user is in in-person-proofing and they have changed their address then # they are not eligible for get-to-yes - if !ipp_enrollment_in_progress || same_address_as_id == 'true' - user_can_pass_after_state_id_check?(instant_verify_result) + if !ipp_enrollment_in_progress? || same_address_as_id? + user_can_pass_after_state_id_check? else residential_instant_verify_result.success? end end - def proof_id_with_aamva_if_needed( - applicant_pii:, timer:, - residential_instant_verify_result:, - instant_verify_result:, - should_proof_state_id:, - ipp_enrollment_in_progress: - ) - same_address_as_id = applicant_pii[:same_address_as_id] - should_proof_state_id_with_aamva = should_proof_state_id_with_aamva?( - ipp_enrollment_in_progress:, - same_address_as_id:, - should_proof_state_id:, - instant_verify_result:, - residential_instant_verify_result:, - ) - return out_of_aamva_jurisdiction_result unless should_proof_state_id_with_aamva + def proof_id_with_aamva_if_needed + return out_of_aamva_jurisdiction_result unless should_proof_state_id_with_aamva? timer.time('state_id') do - state_id_proofer.proof(applicant_pii) + state_id_proofer.proof(applicant_pii_with_state_id_address) end end - def user_can_pass_after_state_id_check?(resolution_result) - return true if resolution_result.success? + def user_can_pass_after_state_id_check? + return true if instant_verify_result.success? # For failed IV results, this method validates that the user is eligible to pass if the # failed attributes are covered by the same attributes in a successful AAMVA response # aka the Get-to-Yes w/ AAMVA feature. - return false unless resolution_result.failed_result_can_pass_with_additional_verification? + if !instant_verify_result.failed_result_can_pass_with_additional_verification? + return false + end attributes_aamva_can_pass = [:address, :dob, :state_id_number] + attributes_requiring_additional_verification = + instant_verify_result.attributes_requiring_additional_verification results_that_cannot_pass_aamva = - resolution_result.attributes_requiring_additional_verification - attributes_aamva_can_pass + attributes_requiring_additional_verification - attributes_aamva_can_pass results_that_cannot_pass_aamva.blank? end + def same_address_as_id? + applicant_pii[:same_address_as_id].to_s == 'true' + end + + def ipp_enrollment_in_progress? + @ipp_enrollment_in_progress + end + def threatmetrix_disabled_result Proofing::DdpResult.new( success: true, @@ -268,6 +242,18 @@ def state_id_proofer end end + def applicant_pii_with_state_id_address + if ipp_enrollment_in_progress? + with_state_id_address(applicant_pii) + else + applicant_pii + end + end + + def applicant_pii_with_residential_address + applicant_pii + end + # Make a copy of pii with the user's state ID address overwriting the address keys # Need to first remove the address keys to avoid key/value collision def with_state_id_address(pii) diff --git a/spec/services/proofing/resolution/progressive_proofer_spec.rb b/spec/services/proofing/resolution/progressive_proofer_spec.rb index 88c0778bb60..268d30d2dfe 100644 --- a/spec/services/proofing/resolution/progressive_proofer_spec.rb +++ b/spec/services/proofing/resolution/progressive_proofer_spec.rb @@ -28,11 +28,8 @@ let(:proof_id_address_with_lexis_nexis_if_needed_value) { nil } let(:dcs_uuid) { SecureRandom.uuid } - let(:instance) do - instance = described_class.new - allow(instance).to receive(:user_can_pass_after_state_id_check?).and_call_original - instance - end + + subject(:progressive_proofer) { described_class.new } let(:state_id_address) do { @@ -91,9 +88,9 @@ def block_real_instant_verify_requests end before do - allow(instance).to receive(:resolution_proofer).and_return(instant_verify_proofer) - allow(instance).to receive(:lexisnexis_ddp_proofer).and_return(threatmetrix_proofer) - allow(instance).to receive(:state_id_proofer).and_return(aamva_proofer) + allow(progressive_proofer).to receive(:resolution_proofer).and_return(instant_verify_proofer) + allow(progressive_proofer).to receive(:lexisnexis_ddp_proofer).and_return(threatmetrix_proofer) + allow(progressive_proofer).to receive(:state_id_proofer).and_return(aamva_proofer) block_real_instant_verify_requests end @@ -104,7 +101,7 @@ def block_real_instant_verify_requests end subject(:proof) do - instance.proof( + progressive_proofer.proof( applicant_pii: applicant_pii, ipp_enrollment_in_progress: ipp_enrollment_in_progress, request_ip: Faker::Internet.ip_v4_address, @@ -209,7 +206,7 @@ def block_real_instant_verify_requests end it 'uses the transformed PII' do - allow(instance).to receive(:with_state_id_address).and_return(transformed_pii) + allow(progressive_proofer).to receive(:with_state_id_address).and_return(transformed_pii) expect(proof.same_address_as_id).to eq('true') expect(proof.ipp_enrollment_in_progress).to eq(true) @@ -230,12 +227,12 @@ def block_real_instant_verify_requests end it 'includes the state ID in the InstantVerify call' do - proof - - expect(instance).to have_received(:user_can_pass_after_state_id_check?). - with(instant_verify_proofer_result) - expect(instant_verify_proofer).to have_received(:proof). + expect(progressive_proofer).to receive(:user_can_pass_after_state_id_check?). + and_call_original + expect(instant_verify_proofer).to receive(:proof). with(hash_including(state_id_address)) + + proof end context 'the failure can be covered by AAMVA' do @@ -276,7 +273,7 @@ def block_real_instant_verify_requests end before do - allow(instance).to receive(:proof_residential_address_if_needed). + allow(progressive_proofer).to receive(:proof_residential_address_if_needed). and_return(residential_resolution_that_passed_instant_verify) end @@ -369,7 +366,7 @@ def block_real_instant_verify_requests let(:instant_verify_proofer_result) { residential_address_proof } before do - allow(instance).to receive(:proof_residential_address_if_needed). + allow(progressive_proofer).to receive(:proof_residential_address_if_needed). and_return(residential_address_proof) allow(residential_address_proof).to receive(:success?). and_return(false)