From 31f7acc45beca903971dbc1721e16041952d92f2 Mon Sep 17 00:00:00 2001 From: Jonathan Hooper Date: Wed, 5 Jun 2024 15:01:09 -0400 Subject: [PATCH] LG-13386 Add SP costs in the `ProgressiveProofer` class We are in the process of moving the logic to track SP costs from the IdP into workers. This will let us more accurately track costs by marking costly events where they actually happen (in the worker). It will also give us some flexibility with the result object that is used during resolution since it will not have SP cost tracking as a dependency. In #10743 we stopped writing the costs iin the controller if the result hash indicates that costs were alreay written. This commit does the work of writing costs in the `ProgressiveProofer` and returns that they were written in the result. The next step will be removing the logic to write costs in the controller This commit can only be safely deployed when the changes in #10743 are fully deployed. [skip changelog] --- app/jobs/resolution_proofing_job.rb | 5 +- .../resolution/progressive_proofer.rb | 19 ++++- .../proofing/resolution/result_adjudicator.rb | 1 + .../idv/verify_info_controller_spec.rb | 7 +- spec/features/idv/analytics_spec.rb | 10 +-- spec/features/sp_cost_tracking_spec.rb | 6 +- .../resolution/progressive_proofer_spec.rb | 83 ++++++++++++++++--- 7 files changed, 107 insertions(+), 24 deletions(-) diff --git a/app/jobs/resolution_proofing_job.rb b/app/jobs/resolution_proofing_job.rb index afa1092459b..5c2be8a256e 100644 --- a/app/jobs/resolution_proofing_job.rb +++ b/app/jobs/resolution_proofing_job.rb @@ -51,6 +51,7 @@ def perform( request_ip: request_ip, should_proof_state_id: should_proof_state_id, ipp_enrollment_in_progress: ipp_enrollment_in_progress, + current_sp: current_sp, ) document_capture_session = DocumentCaptureSession.new(result_id: result_id) @@ -77,7 +78,8 @@ def make_vendor_proofing_requests( threatmetrix_session_id:, request_ip:, should_proof_state_id:, - ipp_enrollment_in_progress: + ipp_enrollment_in_progress:, + current_sp: ) result = progressive_proofer.proof( applicant_pii: applicant_pii, @@ -87,6 +89,7 @@ def make_vendor_proofing_requests( should_proof_state_id: should_proof_state_id, ipp_enrollment_in_progress: ipp_enrollment_in_progress, timer: timer, + current_sp: current_sp, ) log_threatmetrix_info(result.device_profiling_result, user) diff --git a/app/services/proofing/resolution/progressive_proofer.rb b/app/services/proofing/resolution/progressive_proofer.rb index 031c445e6ad..e329d07fe7a 100644 --- a/app/services/proofing/resolution/progressive_proofer.rb +++ b/app/services/proofing/resolution/progressive_proofer.rb @@ -13,7 +13,8 @@ class ProgressiveProofer :should_proof_state_id, :threatmetrix_session_id, :timer, - :user_email + :user_email, + :current_sp # @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 @@ -32,7 +33,8 @@ def proof( threatmetrix_session_id:, timer:, user_email:, - ipp_enrollment_in_progress: + ipp_enrollment_in_progress:, + current_sp: ) @applicant_pii = applicant_pii @request_ip = request_ip @@ -41,6 +43,7 @@ def proof( @timer = timer @user_email = user_email @ipp_enrollment_in_progress = ipp_enrollment_in_progress + @current_sp = current_sp @device_profiling_result = proof_with_threatmetrix_if_needed @residential_instant_verify_result = proof_residential_address_if_needed @@ -82,6 +85,8 @@ def proof_with_threatmetrix_if_needed timer.time('threatmetrix') do lexisnexis_ddp_proofer.proof(ddp_pii) + end.tap do |result| + add_sp_cost(:threatmetrix, result.transaction_id) end end @@ -90,6 +95,8 @@ def proof_residential_address_if_needed 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 @@ -113,6 +120,8 @@ def proof_id_address_with_lexis_nexis_if_needed timer.time('resolution') do resolution_proofer.proof(applicant_pii_with_state_id_address) + end.tap do |result| + add_sp_cost(:lexis_nexis_resolution, result.transaction_id) end end @@ -132,6 +141,8 @@ def proof_id_with_aamva_if_needed timer.time('state_id') do state_id_proofer.proof(applicant_pii_with_state_id_address) + end.tap do |result| + add_sp_cost(:aamva, result.transaction_id) end end @@ -254,6 +265,10 @@ 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 + # 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/app/services/proofing/resolution/result_adjudicator.rb b/app/services/proofing/resolution/result_adjudicator.rb index 3fc07cb3483..eda00d80774 100644 --- a/app/services/proofing/resolution/result_adjudicator.rb +++ b/app/services/proofing/resolution/result_adjudicator.rb @@ -39,6 +39,7 @@ def adjudicated_result device_profiling_adjudication_reason: device_profiling_reason, resolution_adjudication_reason: resolution_reason, should_proof_state_id: should_proof_state_id?, + sp_costs_added: true, stages: { resolution: resolution_result.to_h, residential_address: residential_resolution_result.to_h, diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb index 80052b3ae49..98eb9ff05d2 100644 --- a/spec/controllers/idv/verify_info_controller_spec.rb +++ b/spec/controllers/idv/verify_info_controller_spec.rb @@ -257,7 +257,7 @@ let(:async_state) do # Here we're trying to match the store to redis -> read from redis flow this data travels - result = Proofing::Resolution::ResultAdjudicator.new( + adjudicated_result = Proofing::Resolution::ResultAdjudicator.new( state_id_result: Proofing::StateIdResult.new( success: success, errors: errors, @@ -272,11 +272,12 @@ resolution_result: Proofing::Resolution::Result.new(success: true), same_address_as_id: true, should_proof_state_id: true, - ) + ).adjudicated_result.to_h + adjudicated_result[:context].delete(:sp_costs_added) document_capture_session.create_proofing_session - document_capture_session.store_proofing_result(result.adjudicated_result.to_h) + document_capture_session.store_proofing_result(adjudicated_result) document_capture_session.load_proofing_result end diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb index e6652de97cb..270fcf79ce5 100644 --- a/spec/features/idv/analytics_spec.rb +++ b/spec/features/idv/analytics_spec.rb @@ -97,7 +97,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'Doc Auth', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { attributes_requiring_additional_verification: [], can_pass_with_additional_verification: false, errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, sp_costs_added: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { attributes_requiring_additional_verification: [], can_pass_with_additional_verification: false, errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone of record visited' => { acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, @@ -223,7 +223,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'hybrid', address_edited: false, address_line2_present: false, analytics_id: 'Doc Auth', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { attributes_requiring_additional_verification: [], can_pass_with_additional_verification: false, errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, sp_costs_added: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { attributes_requiring_additional_verification: [], can_pass_with_additional_verification: false, errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone of record visited' => { acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, @@ -346,7 +346,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'Doc Auth', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { attributes_requiring_additional_verification: [], can_pass_with_additional_verification: false, errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, sp_costs_added: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { attributes_requiring_additional_verification: [], can_pass_with_additional_verification: false, errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone of record visited' => { acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, @@ -464,7 +464,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'In Person Proofing', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, same_address_as_id: false, skip_hybrid_handoff: nil, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: 'aaa-bbb-ccc', success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, sp_costs_added: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { errors: {}, exception: nil, reference: 'aaa-bbb-ccc', success: true, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone confirmation form' => { success: true, errors: {}, error_details: nil, phone_type: :mobile, types: [:fixed_or_mobile], carrier: 'Test Mobile Carrier', country_code: 'US', area_code: '202', acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: nil, otp_delivery_preference: 'sms', @@ -597,7 +597,7 @@ }, 'IdV: doc auth verify proofing results' => { success: true, errors: {}, flow_path: 'standard', address_edited: false, address_line2_present: false, analytics_id: 'Doc Auth', ssn_is_unique: true, step: 'verify', acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: anything, - proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { attributes_requiring_additional_verification: [], can_pass_with_additional_verification: false, errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } + proofing_results: { exception: nil, timed_out: false, threatmetrix_review_status: 'pass', context: { device_profiling_adjudication_reason: 'device_profiling_result_pass', resolution_adjudication_reason: 'pass_resolution_and_state_id', should_proof_state_id: true, sp_costs_added: true, stages: { resolution: { success: true, errors: {}, exception: nil, timed_out: false, transaction_id: 'resolution-mock-transaction-id-123', reference: 'aaa-bbb-ccc', can_pass_with_additional_verification: false, attributes_requiring_additional_verification: [], vendor_name: 'ResolutionMock', vendor_workflow: nil }, residential_address: { attributes_requiring_additional_verification: [], can_pass_with_additional_verification: false, errors: {}, exception: nil, reference: '', success: true, timed_out: false, transaction_id: '', vendor_name: 'ResidentialAddressNotRequired', vendor_workflow: nil }, state_id: { success: true, errors: {}, exception: nil, mva_exception: nil, requested_attributes: {}, timed_out: false, transaction_id: 'state-id-mock-transaction-id-456', vendor_name: 'StateIdMock', verified_attributes: [], state: 'MT', state_id_jurisdiction: 'ND', state_id_number: '#############' }, threatmetrix: threatmetrix_response } } } }, 'IdV: phone of record visited' => { acuant_sdk_upgrade_ab_test_bucket: :default, skip_hybrid_handoff: anything, diff --git a/spec/features/sp_cost_tracking_spec.rb b/spec/features/sp_cost_tracking_spec.rb index 9f5b0df8cbe..8bf74757b6a 100644 --- a/spec/features/sp_cost_tracking_spec.rb +++ b/spec/features/sp_cost_tracking_spec.rb @@ -23,15 +23,15 @@ expect_sp_cost_type(0, 2, 'acuant_front_image') expect_sp_cost_type(1, 2, 'acuant_back_image') expect_sp_cost_type(2, 2, 'acuant_result') + expect_sp_cost_type(3, 2, 'threatmetrix') expect_sp_cost_type( - 3, 2, 'lexis_nexis_resolution', + 4, 2, 'lexis_nexis_resolution', transaction_id: Proofing::Mock::ResolutionMockClient::TRANSACTION_ID ) expect_sp_cost_type( - 4, 2, 'aamva', + 5, 2, 'aamva', transaction_id: Proofing::Mock::StateIdMockClient::TRANSACTION_ID ) - expect_sp_cost_type(5, 2, 'threatmetrix') expect_sp_cost_type(6, 2, 'lexis_nexis_address') end diff --git a/spec/services/proofing/resolution/progressive_proofer_spec.rb b/spec/services/proofing/resolution/progressive_proofer_spec.rb index 268d30d2dfe..cb289eaab5e 100644 --- a/spec/services/proofing/resolution/progressive_proofer_spec.rb +++ b/spec/services/proofing/resolution/progressive_proofer_spec.rb @@ -4,6 +4,7 @@ let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN } let(:ipp_enrollment_in_progress) { false } let(:threatmetrix_session_id) { SecureRandom.uuid } + let(:current_sp) { build(:service_provider) } let(:instant_verify_proofing_success) { true } let(:instant_verify_proofer_result) do @@ -11,6 +12,7 @@ Proofing::Resolution::Result, success?: instant_verify_proofing_success, attributes_requiring_additional_verification: [:address], + transaction_id: 'ln-123', ) end let(:instant_verify_proofer) do @@ -20,12 +22,24 @@ ) end - let(:aamva_proofer_result) { nil } + let(:aamva_proofer_result) do + instance_double( + Proofing::StateIdResult, + success?: false, + transaction_id: 'aamva-123', + ) + end let(:aamva_proofer) { instance_double(Proofing::Aamva::Proofer, proof: aamva_proofer_result) } - let(:threatmetrix_proofer) { instance_double(Proofing::LexisNexis::Ddp::Proofer, proof: nil) } - - let(:proof_id_address_with_lexis_nexis_if_needed_value) { nil } + let(:threatmetrix_proofer_result) do + instance_double(Proofing::DdpResult, success?: true, transaction_id: 'ddp-123') + end + let(:threatmetrix_proofer) do + instance_double( + Proofing::LexisNexis::Ddp::Proofer, + proof: threatmetrix_proofer_result, + ) + end let(:dcs_uuid) { SecureRandom.uuid } @@ -109,6 +123,7 @@ def block_real_instant_verify_requests threatmetrix_session_id: threatmetrix_session_id, timer: JobHelpers::Timer.new, user_email: Faker::Internet.email, + current_sp: current_sp, ) end @@ -119,8 +134,6 @@ def block_real_instant_verify_requests end context 'ThreatMetrix is enabled' do - let(:proof_id_address_with_lexis_nexis_if_needed_value) { resolution_result } - before do enable_threatmetrix allow(IdentityConfig.store).to receive(:lexisnexis_threatmetrix_mock_enabled). @@ -133,6 +146,11 @@ def block_real_instant_verify_requests expect(threatmetrix_proofer).to have_received(:proof) end + it 'creates a ThreatMetrix associated cost' do + threatmetrix_sp_costs = SpCost.where(cost_type: :threatmetrix, issuer: current_sp.issuer) + expect(threatmetrix_sp_costs.count).to eq(1) + end + context 'session id is missing' do let(:threatmetrix_session_id) { nil } @@ -178,6 +196,11 @@ def block_real_instant_verify_requests expect(device_profiling_result.client).to eq('tmx_disabled') expect(device_profiling_result.review_status).to eq('pass') end + + it 'does not create a ThreatMetrix associated cost' do + threatmetrix_sp_costs = SpCost.where(cost_type: :threatmetrix, issuer: current_sp.issuer) + expect(threatmetrix_sp_costs.count).to eq(0) + end end end @@ -215,6 +238,19 @@ def block_real_instant_verify_requests expect(aamva_proofer).to have_received(:proof).with(transformed_pii) end + it 'records a single LexisNexis SP cost and an AAMVA SP cost' do + proof + + lexis_nexis_sp_costs = SpCost.where( + cost_type: :lexis_nexis_resolution, + issuer: current_sp.issuer, + ) + aamva_sp_costs = SpCost.where(cost_type: :aamva, issuer: current_sp.issuer) + + expect(lexis_nexis_sp_costs.count).to eq(1) + expect(aamva_sp_costs.count).to eq(1) + end + context 'LexisNexis InstantVerify fails' do let(:instant_verify_proofing_success) { false } @@ -242,6 +278,7 @@ def block_real_instant_verify_requests Proofing::StateIdResult, verified_attributes: [], success?: false, + transaction_id: 'aamva-123', ) end @@ -256,6 +293,7 @@ def block_real_instant_verify_requests Proofing::StateIdResult, verified_attributes: [:address], success?: true, + transaction_id: 'aamva-123', ) end @@ -269,7 +307,11 @@ def block_real_instant_verify_requests context 'LexisNexis InstantVerify passes for residential address and id address' do context 'should proof with AAMVA' do let(:residential_resolution_that_passed_instant_verify) do - instance_double(Proofing::Resolution::Result, success?: true) + instance_double( + Proofing::Resolution::Result, + success?: true, + transaction_id: 'aamva-123', + ) end before do @@ -286,7 +328,11 @@ def block_real_instant_verify_requests context 'AAMVA proofing fails' do let(:aamva_client) { instance_double(Proofing::Aamva::VerificationClient) } let(:aamva_proofer_result) do - instance_double(Proofing::StateIdResult, success?: false) + instance_double( + Proofing::StateIdResult, + success?: false, + transaction_id: 'aamva-123', + ) end before do @@ -303,7 +349,7 @@ def block_real_instant_verify_requests context 'residential address and id address are different' do let(:residential_address_proof) do - instance_double(Proofing::Resolution::Result) + instance_double(Proofing::Resolution::Result, transaction_id: 'residential-123') end let(:ipp_enrollment_in_progress) { true } @@ -348,9 +394,26 @@ def block_real_instant_verify_requests ordered end + it 'records 2 LexisNexis SP cost and an AAMVA SP cost' do + proof + + lexis_nexis_sp_costs = SpCost.where( + cost_type: :lexis_nexis_resolution, + issuer: current_sp.issuer, + ) + aamva_sp_costs = SpCost.where(cost_type: :aamva, issuer: current_sp.issuer) + + expect(lexis_nexis_sp_costs.count).to eq(2) + expect(aamva_sp_costs.count).to eq(1) + end + context 'AAMVA fails' do let(:aamva_proofer_result) do - instance_double(Proofing::StateIdResult, success?: false) + instance_double( + Proofing::StateIdResult, + success?: false, + transaction_id: 'aamva-123', + ) end it 'returns the correct resolution results' do