Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
93bd8a3
Rename spec file to match the file under test
Mar 30, 2023
1574aed
Proof state ID address against AAMVA and LN
Apr 3, 2023
6680284
Use string instead of boolean
Apr 5, 2023
d007ee2
Fix lint and spec failures
Apr 5, 2023
140c4ea
Pull resolution proofing into a new module
Apr 11, 2023
2291ba1
Reduce resolution logic to only one address
Apr 11, 2023
f40be44
Fix merge conflicts
Apr 11, 2023
fadddc0
Fix lint failures
Apr 11, 2023
2526e6c
Revert unnecessary change
Apr 11, 2023
71ac679
Begin using state_id_state field
Apr 11, 2023
73078cd
Pass DAV flag into resolution proofing job
Apr 11, 2023
8703a04
Rename proofer to indicate its progressive nature
Apr 11, 2023
4f3a44a
Correctly calculate DAV flag for IPP
Apr 11, 2023
299a3d0
Fix indentation
Apr 11, 2023
c2c82ef
Merge remote-tracking branch 'origin/main' into sbachstein/lg-8934-co…
Apr 12, 2023
5367240
Fix merge conflicts
Apr 12, 2023
7f6ddfe
Fix lint failures
Apr 12, 2023
9206f4b
Fix spec failure
Apr 12, 2023
6fe706d
Pull logging and proofing component into job
Apr 12, 2023
ac6eadd
Make ProgressiveProofer stateless
Apr 12, 2023
16a7ca7
Simplify PR changes
Apr 12, 2023
e84e576
Add progressive proofer spec skeleton
Apr 12, 2023
34aea45
Begin fleshing out progressive proofer specs
Apr 12, 2023
305eb9c
Fix analytics feature spec
Apr 12, 2023
b3c371b
test progressive proofer
eileen-nava Apr 18, 2023
6fc01c8
update specs for verify_info_controller
eileen-nava Apr 18, 2023
b9417f4
update specs
eileen-nava Apr 18, 2023
3d616ba
Merge branch 'main' into sbachstein/lg-8934-composition-exploration
eileen-nava Apr 18, 2023
aaef68b
respond to feedback
eileen-nava Apr 18, 2023
8a0c508
fix errors related to drivers_license_info_matches
eileen-nava Apr 18, 2023
4e9c8c5
begin responding to feedback
eileen-nava Apr 19, 2023
4550d59
fix broken analytics specs
eileen-nava Apr 20, 2023
18f4a57
fix lint
eileen-nava Apr 20, 2023
96629bd
expand progressive proofer tests, particularly threatmetrix tests
eileen-nava Apr 20, 2023
c06fa9a
add tests to progressive proofer spec
eileen-nava Apr 21, 2023
d85d355
Merge branch 'main' into sbachstein/lg-8934-composition-exploration
eileen-nava Apr 21, 2023
146516e
fix specs and identity_doc variables
eileen-nava Apr 21, 2023
e178cdb
fix tests
eileen-nava Apr 24, 2023
31c3fb6
Apply residential address only
allthesignals Apr 24, 2023
be39fa8
fix tests to match dav expectations
eileen-nava Apr 24, 2023
1c5f370
remove nil check for pii in progressive proofer
eileen-nava Apr 24, 2023
17fbf3a
Setup same address spec context
allthesignals Apr 24, 2023
5153e00
Merge branch 'sbachstein/lg-8934-composition-exploration' into wmg/lg…
allthesignals Apr 24, 2023
be64854
Remove residential code for now
allthesignals Apr 24, 2023
27f90a2
Merge branch 'sbachstein/lg-8934-composition-exploration' into wmg/lg…
allthesignals Apr 25, 2023
973477c
Merge branch 'main' into wmg/lg-8693-verify-current-address
allthesignals Apr 25, 2023
9fe958f
Add residential checks; todo: update result adjudicator
allthesignals May 1, 2023
662860c
ProgressiveProofer residential check included
allthesignals May 1, 2023
20b9948
move IV proof of res address before IV proof of id address
eileen-nava May 1, 2023
ce5966d
WIP naming refactor and logic for lexisnexis failing res address
eileen-nava May 1, 2023
2e1177c
share tests for rubber duck
eileen-nava May 2, 2023
e38d320
Fix syntax error
allthesignals May 2, 2023
054fe80
work to support residential and id addresses
eileen-nava May 4, 2023
c505183
support double address verification when id and residential address a…
eileen-nava May 4, 2023
13e7c2e
update resolution proofing job
eileen-nava May 4, 2023
4d066ca
changelog: Upcoming Features, In-person proofing, verify res address …
eileen-nava May 4, 2023
8ecfa2b
refactor out_of_aamva_jurisdiction_result guard statement
eileen-nava May 5, 2023
9f7a465
Merge branch 'main' into wmg/lg-8693-verify-current-address
eileen-nava May 5, 2023
1f3a799
refactor progressive proofer conditional check and naming
eileen-nava May 8, 2023
54795ea
fix bug for pre-DAV users w same id & res address
eileen-nava May 8, 2023
fc3279a
clarify vendor names and comments
eileen-nava May 8, 2023
5c70b8a
revert changes to vendor name
eileen-nava May 8, 2023
2c52f9c
improve specs for same_address_as_id non-dav bug
eileen-nava May 9, 2023
4e5387c
decrease coupling of result adjudicator & progressive proofer
eileen-nava May 9, 2023
914aa6f
tweak pii transformation
eileen-nava May 10, 2023
80fc53d
Merge branch 'main' into wmg/lg-8693-verify-current-address
eileen-nava May 10, 2023
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
96 changes: 80 additions & 16 deletions app/services/proofing/resolution/progressive_proofer.rb
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that progressive_proofer.rb retains too much of the complexity of this process & needs some of the logic extracted into modules. One clear point of separation would be using a separate module as a results factory that could contain all of the customized calls to Proofing::AddressResult.new.

Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,41 @@ def proof(
user_email: user_email,
)

# todo(LG-8693): Begin verifying both the user's residential address and identity document
# address
applicant_pii = with_state_id_address(applicant_pii) if double_address_verification

resolution_result = proof_resolution(
residential_instant_verify_result = proof_residential_address_if_needed(
applicant_pii: applicant_pii,
timer: timer,
double_address_verification: double_address_verification,
)
state_id_result = proof_state_id_if_needed(
applicant_pii: applicant_pii,

applicant_pii_transformed = applicant_pii.clone
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,
resolution_result: resolution_result,
residential_instant_verify_result: residential_instant_verify_result,
double_address_verification: double_address_verification,
)

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,
double_address_verification: double_address_verification,
)

ResultAdjudicator.new(
device_profiling_result: device_profiling_result,
double_address_verification: double_address_verification,
resolution_result: resolution_result,
resolution_result: instant_verify_result,
should_proof_state_id: should_proof_state_id,
state_id_result: state_id_result,
residential_resolution_result: residential_instant_verify_result,
same_address_as_id: applicant_pii[:same_address_as_id],
)
end

Expand Down Expand Up @@ -86,20 +100,70 @@ def proof_with_threatmetrix_if_needed(
end
end

def proof_resolution(applicant_pii:, timer:)
def proof_residential_address_if_needed(
applicant_pii:,
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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this for the case where a user has not been presented DAV and so they only have their state id address?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct this is for the case where a user is not going through the double address verification flow and only one address is verified. Relevant code here.

I wouldn't say that "they only have their state id address," because before DAV, someone could enter their address on the pre-DAV address page and check that their current address does not appear on their state-issued id. Link to figma here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it might be helpful to include a short comment above each of these functions that briefly describes the use case

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',
)
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
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)
end
end

def proof_state_id_if_needed(
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 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?
end
end

def proof_id_with_aamva_if_needed(
applicant_pii:, timer:,
resolution_result:,
should_proof_state_id:
residential_instant_verify_result:,
instant_verify_result:,
should_proof_state_id:,
double_address_verification:
)
unless should_proof_state_id && user_can_pass_after_state_id_check?(resolution_result)
return out_of_aamva_jurisdiction_result
end
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:,
residential_instant_verify_result:,
)
return out_of_aamva_jurisdiction_result unless should_proof_state_id_with_aamva

timer.time('state_id') do
state_id_proofer.proof(applicant_pii)
Expand Down
17 changes: 12 additions & 5 deletions app/services/proofing/resolution/result_adjudicator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,24 @@ module Proofing
module Resolution
class ResultAdjudicator
attr_reader :resolution_result, :state_id_result, :device_profiling_result,
:double_address_verification
:double_address_verification, :residential_resolution_result, :same_address_as_id

def initialize(
resolution_result:,
state_id_result:,
resolution_result:, # InstantVerify
state_id_result:, # AAMVA
residential_resolution_result:, # InstantVerify Residential
should_proof_state_id:,
double_address_verification:,
device_profiling_result:
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"
end

def adjudicated_result
Expand Down Expand Up @@ -78,7 +82,10 @@ def device_profiling_result_and_reason
end

def resolution_result_and_reason
if resolution_result.success? && state_id_result.success?
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]
elsif !state_id_result.success?
[false, :fail_state_id]
Expand Down
10 changes: 10 additions & 0 deletions lib/idp/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ module Vendors
identity_doc_city: 'Best City',
identity_doc_zipcode: '12345',
identity_doc_address_state: 'VA',
same_address_as_id: 'false',
).freeze

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],
identity_doc_city: MOCK_IDV_APPLICANT_WITH_SSN[:city],
identity_doc_zipcode: MOCK_IDV_APPLICANT_WITH_SSN[:zipcode],
identity_doc_address_state: MOCK_IDV_APPLICANT_WITH_SSN[:state],
same_address_as_id: 'true',
).freeze

MOCK_IDV_APPLICANT_WITH_PHONE = MOCK_IDV_APPLICANT_WITH_SSN.merge(phone: '12025551212').freeze
Expand Down
17 changes: 16 additions & 1 deletion spec/jobs/resolution_proofing_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,17 @@
context "when the user's state ID address does not match their residential address" do
let(:pii) { Idp::Constants::MOCK_IDV_APPLICANT_STATE_ID_ADDRESS }

let(:residential_address) do
{
address1: pii[:address1],
address2: pii[:address2],
city: pii[:city],
state: pii[:state],
state_id_jurisdiction: pii[:state_id_jurisdiction],
zipcode: pii[:zipcode],
}
end

let(:identity_doc_address) do
{
address1: pii[:identity_doc_address1],
Expand All @@ -324,11 +335,15 @@
)
end

it 'verifies the state ID address with AAMVA and LexisNexis' do
it 'verifies ID address with AAMVA & LexisNexis & residential address with LexisNexis' do
stub_vendor_requests

expect_any_instance_of(Proofing::LexisNexis::InstantVerify::Proofer).to receive(:proof).
with(hash_including(residential_address)).and_call_original

expect_any_instance_of(Proofing::LexisNexis::InstantVerify::Proofer).to receive(:proof).
with(hash_including(identity_doc_address)).and_call_original

expect_any_instance_of(Proofing::Aamva::Proofer).to receive(:proof).with(
hash_including(identity_doc_address),
).and_call_original
Expand Down
Loading