Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
e0b73d3
wip
jmhooper Sep 1, 2022
84071b0
Replace context object with vendor name
kbighorse Sep 1, 2022
9b800c1
Test verified phone finder result
kbighorse Sep 2, 2022
6960f26
Rename response body parameter
kbighorse Sep 2, 2022
b738171
Test for failed result
kbighorse Sep 2, 2022
8c360f3
Revert jonathan's nonsense (he told me to say that)
kbighorse Sep 2, 2022
85eda2f
Add new result proofing class
kbighorse Sep 2, 2022
ed1d140
Add new TimedOut result
kbighorse Sep 2, 2022
5ae8e93
Test for reference and transaction_id on result
kbighorse Sep 2, 2022
c47683d
Implement reference and transaction_id
kbighorse Sep 2, 2022
c5548b5
Test no errors on success; pending text for error response
kbighorse Sep 2, 2022
68ab5ad
Replace result with new implementation
kbighorse Sep 2, 2022
03759c1
Delete response.rb
kbighorse Sep 6, 2022
7c50b68
Remove debug statement
kbighorse Sep 6, 2022
4415daa
Return nil for exception
kbighorse Sep 6, 2022
54df75d
Remove `context` from spec expected result
kbighorse Sep 6, 2022
dda1c95
Check for `vendor_name` in result in spec
kbighorse Sep 6, 2022
b1a2e0d
Test result elements separately
kbighorse Sep 6, 2022
8c08cf8
Implement errors
kbighorse Sep 6, 2022
8be1ada
Test expects values as arrays
kbighorse Sep 6, 2022
c36d511
Test result error fields in turn
kbighorse Sep 7, 2022
d960281
Merge branch 'main' into jmhooper-pf-refactor
kbighorse Sep 7, 2022
3056cf9
Merge branch 'main' into jmhooper-pf-refactor
kbighorse Sep 8, 2022
64c590f
Merge branch 'main' into jmhooper-pf-refactor
kbighorse Sep 8, 2022
546a1be
[skip changelog]
kbighorse Sep 8, 2022
cb370d0
Some subtle changes to make the result align with the result for inst…
jmhooper Sep 8, 2022
3550d1f
Merge branch 'main' into jmhooper-pf-refactor
kbighorse Sep 9, 2022
574fc8c
Test for timeout and correct request on send
kbighorse Sep 9, 2022
fcf1fe7
Add empty line
kbighorse Sep 9, 2022
a1fecca
Test for errors
kbighorse Sep 10, 2022
820f3aa
Move transaction_id and reference checks
kbighorse Sep 12, 2022
f62021c
Add error handling to the proofer
jmhooper Sep 12, 2022
ef712af
cleanup this some comments
jmhooper Sep 12, 2022
feef71d
cleanup more comments
jmhooper Sep 12, 2022
a5919ce
add tests for the results objects
jmhooper Sep 12, 2022
980d7eb
cleanup the address mock proofer
jmhooper Sep 12, 2022
90339ed
delint
jmhooper Sep 12, 2022
ff87596
delint
jmhooper Sep 12, 2022
48bc53e
fix a typo
jmhooper Sep 12, 2022
6c1608e
get all but a few specs passing
jmhooper Sep 13, 2022
afa57de
delete unused file
jmhooper Sep 13, 2022
fb9dcb3
clean up address mock to look like the actual client
jmhooper Sep 13, 2022
83303b4
one last cleanup
jmhooper Sep 13, 2022
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
9 changes: 1 addition & 8 deletions app/jobs/address_proofing_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,8 @@ def perform(user_id:, issuer:, result_id:, encrypted_arguments:, trace_id:)
)
Db::ProofingCost::AddUserProofingCost.call(user_id, :lexis_nexis_address)

result = proofer_result.to_h
result[:context] = { stages: [address: address_proofer.class.vendor_name] }
result[:transaction_id] = proofer_result.transaction_id

result[:timed_out] = proofer_result.timed_out?
result[:exception] = proofer_result.exception.inspect if proofer_result.exception

document_capture_session = DocumentCaptureSession.new(result_id: result_id)
document_capture_session.store_proofing_result(result)
document_capture_session.store_proofing_result(proofer_result.to_h)
ensure
logger.info(
{
Expand Down
27 changes: 10 additions & 17 deletions app/services/proofing/lexis_nexis/phone_finder/proofer.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
module Proofing
module LexisNexis
module PhoneFinder
class Proofer < LexisNexis::Proofer
vendor_name 'lexisnexis:phone_finder'
class Proofer
attr_reader :config

required_attributes :uuid,
:first_name,
:last_name,
:dob,
:ssn,
:phone

optional_attributes :uuid_prefix

stage :address

proof do |applicant, result|
proof_applicant(applicant, result)
def initialize(config)
@config = LexisNexis::Proofer::Config.new(config)
end

def send_verification_request(applicant)
VerificationRequest.new(config: config, applicant: applicant).send
def proof(applicant)
response = VerificationRequest.new(config: config, applicant: applicant).send
return Proofing::LexisNexis::PhoneFinder::Result.new(response)
rescue => exception
NewRelic::Agent.notice_error(exception)
ResultWithException.new(exception)
end
end
end
Expand Down
58 changes: 58 additions & 0 deletions app/services/proofing/lexis_nexis/phone_finder/result.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module Proofing
module LexisNexis
module PhoneFinder
class Result
attr_reader :verification_response

delegate(
:reference,
:verification_status,
:verification_errors,
to: :verification_response,
)

def initialize(verification_response)
@verification_response = verification_response
end

def errors
return @errors if defined?(@errors)

@errors = {}
verification_errors.each do |key, value|
@errors[key] ||= []
@errors[key].push(value)
end
@errors
end

def exception
nil
end

def success?
verification_response.verification_status == 'passed'
end

def timed_out?
false
end

def transaction_id
verification_response.conversation_id
end

def to_h
{
exception: exception,
errors: errors,
success: success?,
timed_out: timed_out?,
transaction_id: transaction_id,
vendor_name: 'lexisnexis:phone_finder',
}
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Proofing
module LexisNexis
module PhoneFinder
class ResultWithException
attr_reader :exception

def initialize(exception)
@exception = exception
end

def success?
false
end

def errors
{}
end

def timed_out?
exception.is_a?(Proofing::TimeoutError)
end

def to_h
{
success: success?,
errors: errors,
exception: exception,
timed_out: timed_out?,
vendor_name: 'lexisnexis:phone_finder',
}
end
end
end
end
end
74 changes: 54 additions & 20 deletions app/services/proofing/mock/address_mock_client.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,69 @@
module Proofing
module Mock
class AddressMockClient < Proofing::Base
vendor_name 'AddressMock'

required_attributes :uuid,
:first_name,
:last_name,
:dob,
:ssn,
:phone

optional_attributes :uuid_prefix

stage :address

class AddressMockClient
UNVERIFIABLE_PHONE_NUMBER = '7035555555'
PROOFER_TIMEOUT_PHONE_NUMBER = '7035555888'
FAILED_TO_CONTACT_PHONE_NUMBER = '7035555999'
TRANSACTION_ID = 'address-mock-transaction-id-123'

proof do |applicant, result|
AddressMockClientResult = Struct.new(:success, :errors, :exception, keyword_init: true) do
def success?
success
end

def transaction_id
TRANSACTION_ID
end

def to_h
{
exception: exception,
errors: errors,
success: success,
timed_out: exception.is_a?(Proofing::TimeoutError),
transaction_id: transaction_id,
vendor_name: 'AddressMock',
}
end
end

def proof(applicant)
plain_phone = applicant[:phone].gsub(/\D/, '').delete_prefix('1')
if plain_phone == UNVERIFIABLE_PHONE_NUMBER
result.add_error(:phone, 'The phone number could not be verified.')
unverifiable_phone_result
elsif plain_phone == FAILED_TO_CONTACT_PHONE_NUMBER
raise 'Failed to contact proofing vendor'
failed_to_contact_vendor_result
elsif plain_phone == PROOFER_TIMEOUT_PHONE_NUMBER
raise Proofing::TimeoutError, 'address mock timeout'
timeout_result
else
AddressMockClientResult.new(success: true, errors: {}, exception: nil)
end
result.transaction_id = TRANSACTION_ID
result.context[:message] = 'some context for the mock address proofer'
end

private

def unverifiable_phone_result
AddressMockClientResult.new(
success: false,
errors: { phone: ['The phone number could not be verified.'] },
exception: nil,
)
end

def failed_to_contact_vendor_result
AddressMockClientResult.new(
success: false,
errors: {},
exception: RuntimeError.new('Failed to contact proofing vendor'),
)
end

def timeout_result
AddressMockClientResult.new(
success: false,
errors: {},
exception: Proofing::TimeoutError.new('address mock timeout'),
)
end
end
end
Expand Down
6 changes: 2 additions & 4 deletions spec/controllers/idv/phone_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -320,14 +320,13 @@
stub_analytics
allow(@analytics).to receive(:track_event)

context = { stages: [{ address: 'AddressMock' }] }
result = {
success: true,
new_phone_added: true,
errors: {},
pii_like_keypaths: [[:errors, :phone], [:context, :stages, :address]],
vendor: {
context: context,
vendor_name: 'AddressMock',
exception: nil,
timed_out: false,
transaction_id: 'address-mock-transaction-id-123',
Expand Down Expand Up @@ -369,7 +368,6 @@
stub_analytics
allow(@analytics).to receive(:track_event)

context = { stages: [{ address: 'AddressMock' }] }
result = {
success: false,
new_phone_added: true,
Expand All @@ -378,7 +376,7 @@
},
pii_like_keypaths: [[:errors, :phone], [:context, :stages, :address]],
vendor: {
context: context,
vendor_name: 'AddressMock',
exception: nil,
timed_out: false,
transaction_id: 'address-mock-transaction-id-123',
Expand Down
4 changes: 2 additions & 2 deletions spec/features/idv/analytics_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
'IdV: doc auth optional verify_wait submitted' => { success: true, errors: {}, address_edited: false, proofing_results: { exception: nil, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', timed_out: false, context: { should_proof_state_id: true, stages: { resolution: { client: 'ResolutionMock', errors: {}, exception: nil, success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc' }, state_id: { client: 'StateIdMock', errors: {}, success: true, timed_out: false, exception: nil, transaction_id: 'state-id-mock-transaction-id-456', state: 'MT', state_id_jurisdiction: 'ND' } } } }, ssn_is_unique: true, step: 'verify_wait_step_show' },
'IdV: phone of record visited' => {},
'IdV: phone confirmation form' => { success: true, errors: {}, phone_type: :mobile, types: [:fixed_or_mobile], carrier: 'Test Mobile Carrier', country_code: 'US', area_code: '202' },
'IdV: phone confirmation vendor' => { success: true, errors: {}, vendor: { exception: nil, context: { stages: [{ address: 'AddressMock' }] }, transaction_id: 'address-mock-transaction-id-123', timed_out: false }, new_phone_added: false },
'IdV: phone confirmation vendor' => { success: true, errors: {}, vendor: { exception: nil, vendor_name: 'AddressMock', transaction_id: 'address-mock-transaction-id-123', timed_out: false }, new_phone_added: false },
'IdV: final resolution' => { success: true },
'IdV: personal key visited' => {},
'IdV: personal key submitted' => {},
Expand Down Expand Up @@ -113,7 +113,7 @@
'IdV: in person proofing optional verify_wait submitted' => { success: true, step: 'verify_wait_step_show', address_edited: false, ssn_is_unique: true },
'IdV: phone of record visited' => {},
'IdV: phone confirmation form' => { success: true, errors: {}, phone_type: :mobile, types: [:fixed_or_mobile], carrier: 'Test Mobile Carrier', country_code: 'US', area_code: '202' },
'IdV: phone confirmation vendor' => { success: true, errors: {}, vendor: { exception: nil, context: { stages: [{ address: 'AddressMock' }] }, transaction_id: 'address-mock-transaction-id-123', timed_out: false }, new_phone_added: false },
'IdV: phone confirmation vendor' => { success: true, errors: {}, vendor: { exception: nil, vendor_name: 'AddressMock', transaction_id: 'address-mock-transaction-id-123', timed_out: false }, new_phone_added: false },
'IdV: Phone OTP delivery Selection Visited' => {},
'IdV: Phone OTP Delivery Selection Submitted' => { success: true, otp_delivery_preference: 'sms' },
'IdV: phone confirmation otp sent' => { success: true, otp_delivery_preference: :sms, country_code: 'US', area_code: '202' },
Expand Down
15 changes: 5 additions & 10 deletions spec/jobs/address_proofing_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,11 @@

result = document_capture_session.load_proofing_result[:result]

expect(result).to eq(
exception: nil,
errors: {},
success: true,
timed_out: false,
transaction_id: conversation_id,
context: { stages: [
{ address: 'lexisnexis:phone_finder' },
] },
)
expect(result[:exception]).to be_nil
expect(result[:errors]).to eq({})
expect(result[:success]).to be true
expect(result[:timed_out]).to be false
expect(result[:vendor_name]).to eq('lexisnexis:phone_finder')
end

it 'adds cost data' do
Expand Down
4 changes: 2 additions & 2 deletions spec/services/idv/agent_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
issuer: issuer,
)
result = document_capture_session.load_proofing_result[:result]
expect(result[:context][:stages]).to include({ address: 'AddressMock' })
expect(result[:vendor_name]).to eq('AddressMock')
expect(result[:success]).to eq true
end

Expand All @@ -189,7 +189,7 @@
document_capture_session, trace_id: trace_id, user_id: user_id, issuer: issuer
)
result = document_capture_session.load_proofing_result[:result]
expect(result[:context][:stages]).to include({ address: 'AddressMock' })
expect(result[:vendor_name]).to eq('AddressMock')
expect(result[:success]).to eq false
end
end
Expand Down
6 changes: 2 additions & 4 deletions spec/services/idv/phone_step_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,9 @@
let(:throttle) { Throttle.new(throttle_type: :proof_address, user: user) }

it 'succeeds with good params' do
context = { stages: [{ address: 'AddressMock' }] }
extra = {
vendor: {
context: context,
vendor_name: 'AddressMock',
exception: nil,
timed_out: false,
transaction_id: 'address-mock-transaction-id-123',
Expand All @@ -79,10 +78,9 @@
end

it 'fails with bad params' do
context = { stages: [{ address: 'AddressMock' }] }
extra = {
vendor: {
context: context,
vendor_name: 'AddressMock',
exception: nil,
timed_out: false,
transaction_id: 'address-mock-transaction-id-123',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
zipcode: '70802-12345',
}
end

let(:verification_request) do
Proofing::LexisNexis::InstantVerify::VerificationRequest.new(
applicant: applicant,
Expand Down
Loading