Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions app/jobs/resolution_proofing_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
144 changes: 65 additions & 79 deletions app/services/proofing/resolution/progressive_proofer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -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

Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
31 changes: 14 additions & 17 deletions spec/services/proofing/resolution/progressive_proofer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down