Skip to content

Commit

Permalink
ProgressiveProofer refactor 3/N: Instant Verify residential address (#…
Browse files Browse the repository at this point in the history
…11433)

* Extract residential address InstantVerify plugin

Add separate spec for the residential address verification only.

[skip changelog]

* Remove duplicative test from ResolutionProofingJob spec

This test is essentially doing what the ProgressiveProofer spec is doing.
  • Loading branch information
matthinz authored Nov 4, 2024
1 parent 257f49e commit 92165a1
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# frozen_string_literal: true

module Proofing
module Resolution
module Plugins
class InstantVerifyResidentialAddressPlugin
def call(
applicant_pii:,
current_sp:,
ipp_enrollment_in_progress:,
timer:
)
return residential_address_unnecessary_result unless ipp_enrollment_in_progress

timer.time('residential address') do
proofer.proof(applicant_pii)
end.tap do |result|
Db::SpCost::AddSpCost.call(
current_sp,
:lexis_nexis_resolution,
transaction_id: result.transaction_id,
)
end
end

def proofer
@proofer ||=
if IdentityConfig.store.proofer_mock_fallback
Proofing::Mock::ResolutionMockClient.new
else
Proofing::LexisNexis::InstantVerify::Proofer.new(
instant_verify_workflow: IdentityConfig.store.lexisnexis_instant_verify_workflow,
account_id: IdentityConfig.store.lexisnexis_account_id,
base_url: IdentityConfig.store.lexisnexis_base_url,
username: IdentityConfig.store.lexisnexis_username,
password: IdentityConfig.store.lexisnexis_password,
hmac_key_id: IdentityConfig.store.lexisnexis_hmac_key_id,
hmac_secret_key: IdentityConfig.store.lexisnexis_hmac_secret_key,
request_mode: IdentityConfig.store.lexisnexis_request_mode,
)
end
end

def residential_address_unnecessary_result
Proofing::Resolution::Result.new(
success: true, errors: {}, exception: nil, vendor_name: 'ResidentialAddressNotRequired',
)
end
end
end
end
end
34 changes: 12 additions & 22 deletions app/services/proofing/resolution/progressive_proofer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ module Resolution
# address or separate residential and identity document addresses
class ProgressiveProofer
attr_reader :applicant_pii, :timer, :current_sp
attr_reader :aamva_plugin, :threatmetrix_plugin
attr_reader :aamva_plugin,
:instant_verify_residential_address_plugin,
:threatmetrix_plugin

def initialize
@aamva_plugin = Plugins::AamvaPlugin.new
@instant_verify_residential_address_plugin =
Plugins::InstantVerifyResidentialAddressPlugin.new
@threatmetrix_plugin = Plugins::ThreatMetrixPlugin.new
end

Expand Down Expand Up @@ -47,7 +51,13 @@ def proof(
user_email:,
)

@residential_instant_verify_result = proof_residential_address_if_needed
@residential_instant_verify_result = instant_verify_residential_address_plugin.call(
applicant_pii:,
current_sp:,
ipp_enrollment_in_progress:,
timer:,
)

@instant_verify_result = proof_id_address_with_lexis_nexis_if_needed

state_id_result = aamva_plugin.call(
Expand Down Expand Up @@ -76,22 +86,6 @@ def proof(
:residential_instant_verify_result,
:instant_verify_result

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_with_residential_address)
end.tap do |result|
add_sp_cost(:lexis_nexis_resolution, result.transaction_id)
end
end

def residential_address_unnecessary_result
Proofing::Resolution::Result.new(
success: true, errors: {}, exception: nil, vendor_name: 'ResidentialAddressNotRequired',
)
end

def resolution_cannot_pass
Proofing::Resolution::Result.new(
success: false, errors: {}, exception: nil, vendor_name: 'ResolutionCannotPass',
Expand Down Expand Up @@ -145,10 +139,6 @@ def applicant_pii_with_state_id_address
end
end

def applicant_pii_with_residential_address
applicant_pii
end

def add_sp_cost(token, transaction_id)
Db::SpCost::AddSpCost.call(current_sp, token, transaction_id: transaction_id)
end
Expand Down
16 changes: 0 additions & 16 deletions spec/jobs/resolution_proofing_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -383,22 +383,6 @@
)
end

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

perform
end

it 'stores a successful result' do
stub_vendor_requests

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
require 'rails_helper'

RSpec.describe Proofing::Resolution::Plugins::InstantVerifyResidentialAddressPlugin do
let(:current_sp) { build(:service_provider) }

let(:ipp_enrollment_in_progress) { false }

let(:proofer_transaction_id) { 'residential-123' }

let(:proofer_result) do
Proofing::Resolution::Result.new(
success: true,
transaction_id: proofer_transaction_id,
vendor_name: 'lexisnexis:instant_verify',
)
end

subject(:plugin) do
described_class.new
end

before do
allow(plugin.proofer).to receive(:proof).and_return(proofer_result)
end

describe '#call' do
def sp_cost_count_for_issuer
SpCost.where(cost_type: :lexis_nexis_resolution, issuer: current_sp.issuer).count
end

def sp_cost_count_with_transaction_id
SpCost.where(
cost_type: :lexis_nexis_resolution,
issuer: current_sp.issuer,
transaction_id: proofer_transaction_id,
).count
end

subject(:call) do
plugin.call(
applicant_pii:,
current_sp:,
ipp_enrollment_in_progress:,
timer: JobHelpers::Timer.new,
)
end

context 'remote unsupervised proofing' do
let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN }
let(:ipp_enrollment_in_progress) { false }

it 'returns a ResidentialAddressNotRequired result' do
call.tap do |result|
expect(result.success?).to eql(true)
expect(result.vendor_name).to eql('ResidentialAddressNotRequired')
end
end

it 'does not record a LexisNexis SP cost' do
expect { call }.not_to change { sp_cost_count_for_issuer }
end
end

context 'in-person proofing' do
let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID }
let(:ipp_enrollment_in_progress) { true }
let(:proofer_result) do
Proofing::Resolution::Result.new(
success: true,
transaction_id: proofer_transaction_id,
vendor_name: 'lexisnexis:instant_verify',
)
end

it 'calls proofer with pii' do
expect(plugin.proofer).to receive(:proof).with(applicant_pii)
call
end

context 'when InstantVerify call succeeds' do
it 'returns the proofer result' do
expect(call).to eql(proofer_result)
end

it 'records a LexisNexis SP cost' do
expect { call }.to change { sp_cost_count_with_transaction_id }.to(1)
end
end

context 'when InstantVerify call fails' do
let(:proofer_result) do
Proofing::Resolution::Result.new(
success: false,
errors: {},
exception: nil,
transaction_id: proofer_transaction_id,
vendor_name: 'lexisnexis:instant_verify',
)
end

it 'returns the proofer result' do
expect(call).to eql(proofer_result)
end

it 'records a LexisNexis SP cost' do
expect { call }.to change { sp_cost_count_with_transaction_id }.to(1)
end
end

context 'when InstantVerify call results in exception' do
let(:proofer_result) do
Proofing::Resolution::Result.new(
success: false,
errors: {},
exception: RuntimeError.new(':ohno:'),
transaction_id: proofer_transaction_id,
vendor_name: 'lexisnexis:instant_verify',
)
end

it 'returns the proofer result' do
expect(call).to eql(proofer_result)
end

it 'records a LexisNexis SP cost' do
expect { call }.to change { sp_cost_count_with_transaction_id }.to(1)
end
end
end
end
end
45 changes: 45 additions & 0 deletions spec/services/proofing/resolution/progressive_proofer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
let(:user_email) { Faker::Internet.email }
let(:current_sp) { build(:service_provider) }

let(:instant_verify_residential_address_plugin) do
Proofing::Resolution::Plugins::InstantVerifyResidentialAddressPlugin.new
end

let(:instant_verify_result) do
Proofing::Resolution::Result.new(
success: true,
Expand Down Expand Up @@ -107,6 +111,11 @@ def block_real_instant_verify_requests
allow(progressive_proofer).to receive(:aamva_plugin).and_return(aamva_plugin)
allow(aamva_plugin).to receive(:proofer).and_return(aamva_proofer)

allow(progressive_proofer).to receive(:instant_verify_residential_address_plugin).
and_return(instant_verify_residential_address_plugin)
allow(instant_verify_residential_address_plugin).to receive(:proofer).
and_return(instant_verify_proofer)

allow(progressive_proofer).to receive(:resolution_proofer).and_return(instant_verify_proofer)

block_real_instant_verify_requests
Expand All @@ -118,6 +127,12 @@ def block_real_instant_verify_requests
)
end

it 'assigns instant_verify_residential_address_plugin' do
expect(described_class.new.instant_verify_residential_address_plugin).to be_a(
Proofing::Resolution::Plugins::InstantVerifyResidentialAddressPlugin,
)
end

it 'assigns threatmetrix_plugin' do
expect(described_class.new.threatmetrix_plugin).to be_a(
Proofing::Resolution::Plugins::ThreatMetrixPlugin,
Expand Down Expand Up @@ -153,6 +168,16 @@ def block_real_instant_verify_requests
proof
end

it 'calls InstantVerifyResidentialAddressPlugin' do
expect(instant_verify_residential_address_plugin).to receive(:call).with(
applicant_pii:,
current_sp:,
ipp_enrollment_in_progress: false,
timer: an_instance_of(JobHelpers::Timer),
).and_call_original
proof
end

it 'calls ThreatMetrixPlugin' do
expect(threatmetrix_plugin).to receive(:call).with(
applicant_pii:,
Expand Down Expand Up @@ -200,6 +225,16 @@ def block_real_instant_verify_requests
proof
end

it 'calls InstantVerifyResidentialAddressPlugin' do
expect(instant_verify_residential_address_plugin).to receive(:call).with(
applicant_pii:,
current_sp:,
ipp_enrollment_in_progress: true,
timer: an_instance_of(JobHelpers::Timer),
).and_call_original
proof
end

it 'calls ThreatMetrixPlugin' do
expect(threatmetrix_plugin).to receive(:call).with(
applicant_pii:,
Expand Down Expand Up @@ -253,6 +288,16 @@ def block_real_instant_verify_requests
proof
end

it 'calls InstantVerifyResidentialAddressPlugin' do
expect(instant_verify_residential_address_plugin).to receive(:call).with(
applicant_pii:,
current_sp:,
ipp_enrollment_in_progress: true,
timer: an_instance_of(JobHelpers::Timer),
).and_call_original
proof
end

it 'calls AamvaPlugin' do
expect(aamva_plugin).to receive(:call).with(
applicant_pii:,
Expand Down

0 comments on commit 92165a1

Please sign in to comment.