Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e71101b
doc auth pass if transaction status passes
amirbey Apr 12, 2024
6f76bdb
update spec response transaction status
amirbey Apr 13, 2024
642aa69
update true id response spec
amirbey Apr 13, 2024
8926e55
update fixtures product status for failed transactions
amirbey Apr 13, 2024
ffaa2f8
update product status
amirbey Apr 16, 2024
e617c1f
selfie must past
amirbey May 14, 2024
382e04e
revert fixture changes
amirbey May 14, 2024
85b7062
resolve rebase conflict
amirbey May 14, 2025
a7d1f31
attention barcode does not have to be only error
amirbey May 14, 2024
117c976
update doc_auth_success to remove selfie in mock result response
amirbey May 14, 2024
f3da3df
happy linting
amirbey May 14, 2024
32a38c8
allow mock proofer to have multiple errors with barcode attn
amirbey May 14, 2024
e4326c3
remove dup test
amirbey May 14, 2024
32bab43
add an error barcode fixture to barcode error trueid response
amirbey May 14, 2024
5c0d47e
ensure attention_with_barcode? returns a boolean
amirbey May 14, 2024
3a31f62
update spec attention with barcode
amirbey May 15, 2024
8cb3f8f
error generator use transaction status to determine if doc auth passe…
amirbey May 15, 2024
e806f64
consolidate checking if doc auth passed in error generator
amirbey May 15, 2024
5ea7c9a
doc_auth_passed not in scope for DocAuthErrorHandler
amirbey May 15, 2024
5fa76fd
update mock to include transaction_status
amirbey May 15, 2024
211caca
rename error generator tests from 'DocAuthResult is ...' to 'Transact…
amirbey May 15, 2024
d5e6a45
resolve rebase conflict
amirbey May 14, 2025
911c681
resolve rebase conflict
amirbey May 14, 2025
f7d3071
resolve rebase conflict
amirbey May 14, 2025
c86968c
resolve rebase conflict
amirbey May 14, 2025
917ca4d
update transaction_stauts in mock to reflect doc auth only
amirbey May 15, 2024
696279e
check transaction status to determine if doc auth is sucess for mock
amirbey May 15, 2024
582af18
assist with correcting case for transaction status and doc auth resul…
amirbey May 15, 2024
3303664
do not correct case
amirbey May 15, 2024
95ea9c1
add transaction status to yml
amirbey May 16, 2024
98528ad
add transaction status to yml
amirbey May 16, 2024
f87920f
add transaction status to yml
amirbey May 16, 2024
9843a2d
add transaction result to inline yaml files
amirbey May 16, 2024
b4e1da1
update yml fixtures to have transaction_status
amirbey May 16, 2024
5d9352a
update image upload presenter to use transaction status
amirbey May 16, 2024
7977128
resolve rebase conflict
amirbey May 14, 2025
1228112
remove stale comment
amirbey May 21, 2024
d391dab
remove props as per PR #10987
amirbey May 14, 2025
a353924
happy linting
amirbey May 14, 2025
a15a83e
TransactionCodes
amirbey May 14, 2025
158c5c3
happy linting
amirbey May 14, 2025
fafe216
fix namespacing
amirbey May 14, 2025
92192f9
remove billed attribute from transactin status
amirbey May 14, 2025
f635047
fix typo
amirbey May 14, 2025
36f95be
Merge branch 'main' into amirbey/LG-13005-transaction-status
amirbey May 19, 2025
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/presenters/image_upload_response_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def as_json(*)
end
json[:hints] = true if show_hints?
json[:ocr_pii] = ocr_pii
json[:result_failed] = doc_auth_result_failed?
json[:result_failed] = doc_auth_failed?
json[:result_code_invalid] = result_code_invalid?
json[:doc_type_supported] = doc_type_supported?
json[:selfie_status] = selfie_status if show_selfie_failures?
Expand All @@ -78,8 +78,8 @@ def result_code_invalid?
!attention_with_barcode?
end

def doc_auth_result_failed?
@form_response.to_h[:doc_auth_result] == DocAuth::LexisNexis::ResultCodes::FAILED.name
def doc_auth_failed?
@form_response.to_h[:transaction_status] == DocAuth::LexisNexis::TransactionCodes::FAILED.name
end

def show_hints?
Expand Down
26 changes: 4 additions & 22 deletions app/services/doc_auth/error_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def get_doc_auth_errors(response_info, known_error_count)
def get_doc_auth_error_messages(response_info)
errors = Hash.new { |hash, key| hash[key] = Set.new }

if response_info[:doc_auth_result] != LexisNexis::ResultCodes::PASSED.name
if response_info[:transaction_status] != LexisNexis::TransactionCodes::PASSED.name
response_info[:processed_alerts][:failed]&.each do |alert|
alert_msg_hash = ErrorGenerator::ALERT_MESSAGES[alert[:name].to_sym]

Expand Down Expand Up @@ -373,28 +373,10 @@ def scan_for_unknown_alerts(response_info)
unknown_fail_count
end

# This method replicates TrueIdResponse::attention_with_barcode? and
# should be removed/updated when that is.
def attention_with_barcode_result(doc_auth_result, processed_alerts)
attention_result_name = LexisNexis::ResultCodes::ATTENTION.name
barcode_alerts = processed_alerts[:failed]&.count.to_i == 1 &&
processed_alerts.dig(:failed, 0, :name) == '2D Barcode Read' &&
processed_alerts.dig(:failed, 0, :result) == 'Attention'

doc_auth_result == attention_result_name && barcode_alerts
end

def doc_auth_passed_or_attn_with_barcode(response_info)
doc_auth_result = response_info[:doc_auth_result]
processed_alerts = response_info[:processed_alerts]

doc_auth_result_passed = doc_auth_result == LexisNexis::ResultCodes::PASSED.name
doc_auth_result_passed || attention_with_barcode_result(doc_auth_result, processed_alerts)
end

def doc_auth_error_count(response_info)
doc_auth_passed_or_attn_with_barcode(response_info) ?
0 : response_info[:alert_failure_count]
return 0 if response_info[:transaction_status] == LexisNexis::TransactionCodes::PASSED.name

response_info[:alert_failure_count]
end
end
end
16 changes: 3 additions & 13 deletions app/services/doc_auth/lexis_nexis/responses/true_id_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ def initialize(http_response, config, liveness_checking_enabled = false,

## returns full check success status, considering all checks:
# vendor (document and selfie if requested)
# document type
# bar code attention
def successful_result?
doc_auth_success? &&
(@liveness_checking_enabled ? selfie_passed? : true)
Expand All @@ -49,16 +47,9 @@ def successful_result?
# all checks from document perspectives, without considering selfie:
# vendor (document only)
# document_type
# bar code attention
def doc_auth_success?
# really it's everything else excluding selfie
((transaction_status_passed? &&
true_id_product.present? &&
product_status_passed? &&
doc_auth_result_passed?
) ||
attention_with_barcode?
) && id_type_supported?
transaction_status_passed? && id_type_supported?
end

def error_messages
Expand Down Expand Up @@ -93,9 +84,8 @@ def extra_attributes
def attention_with_barcode?
return false unless doc_auth_result_attention?

parsed_alerts[:failed]&.count.to_i == 1 &&
parsed_alerts.dig(:failed, 0, :name) == '2D Barcode Read' &&
parsed_alerts.dig(:failed, 0, :result) == 'Attention'
!!parsed_alerts[:failed]
&.any? { |alert| alert[:name] == '2D Barcode Read' && alert[:result] == 'Attention' }
end

def billed?
Expand Down
30 changes: 30 additions & 0 deletions app/services/doc_auth/lexis_nexis/transaction_codes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

module DocAuth
module LexisNexis
module TransactionCodes
TransactionCode = Struct.new(:code, :name) do
end

# The authentication test errored (ie: network error)
ERROR = TransactionCode.new(0, 'error').freeze
# The authentication test passed.
PASSED = TransactionCode.new(1, 'passed').freeze
# The authentication test failed.
FAILED = TransactionCode.new(2, 'failed').freeze

ALL = [
ERROR,
PASSED,
FAILED,
].freeze

BY_CODE = ALL.index_by(&:code).freeze

# @return [TransactionCode]
def self.from_int(code)
BY_CODE[code]
end
end
end
end
58 changes: 43 additions & 15 deletions app/services/doc_auth/mock/result_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def initialize(uploaded_file, config, selfie_required = false)
selfie_quality_good: selfie_quality_good?,
selfie_status: selfie_status,
extra: {
transaction_status:,
doc_auth_result:,
passport_check_result:,
portrait_match_results:,
Expand All @@ -41,6 +42,7 @@ def errors
if file_data.blank?
{}
else
transaction_status = file_data.dig('transaction_status')
doc_auth_result = file_data.dig('doc_auth_result')
image_metrics = file_data.dig('image_metrics')
failed = file_data.dig('failed_alerts')&.dup
Expand All @@ -50,6 +52,7 @@ def errors
passport_check_result = file_data.dig('passport_check_result', 'PassportCheckResult')
# Pass and doc type is ok
has_fields = [
transaction_status,
doc_auth_result,
image_metrics,
failed,
Expand All @@ -63,10 +66,11 @@ def errors
# Error generator is not to be called when it's not failure
# allows us to test successful results
return {} if all_doc_capture_values_passing?(
doc_auth_result, id_type_supported?
transaction_status, id_type_supported?
)

mock_args = {}
mock_args[:transaction_status] = transaction_status if transaction_status.present?
mock_args[:doc_auth_result] = doc_auth_result if doc_auth_result.present?
mock_args[:image_metrics] = image_metrics.symbolize_keys if image_metrics.present?
mock_args[:failed] = failed.map!(&:symbolize_keys) unless failed.nil?
Expand Down Expand Up @@ -99,7 +103,8 @@ def success?
end

def attention_with_barcode?
parsed_alerts == [ATTENTION_WITH_BARCODE_ALERT]
!!parsed_alerts
&.any? { |alert| alert['name'] == '2D Barcode Read' && alert['result'] == 'Attention' }
end

def self.create_network_error_response
Expand All @@ -113,10 +118,16 @@ def self.create_network_error_response
end

def doc_auth_success?
(doc_auth_result_from_uploaded_file == 'Passed' ||
return false unless id_type_supported?
return false if transaction_status_from_uploaded_file ==
LexisNexis::TransactionCodes::FAILED.name
return true if transaction_status_from_uploaded_file ==
LexisNexis::TransactionCodes::PASSED.name
return false if doc_auth_result_from_uploaded_file == LexisNexis::ResultCodes::FAILED.name

doc_auth_result_from_uploaded_file == LexisNexis::ResultCodes::PASSED.name ||
errors.blank? ||
attention_with_barcode?
) && id_type_supported?
(attention_with_barcode? && parsed_alerts.length == 1)
end

def selfie_status
Expand Down Expand Up @@ -178,6 +189,14 @@ def doc_auth_result_from_uploaded_file
parsed_data_from_uploaded_file&.[]('doc_auth_result')
end

def transaction_status
transaction_status_from_uploaded_file || transaction_status_from_success
end

def transaction_status_from_uploaded_file
parsed_data_from_uploaded_file&.[]('transaction_status')
end

def portrait_match_results
parsed_data_from_uploaded_file.dig('portrait_match_results')
&.transform_keys! { |key| key.to_s.camelize }
Expand All @@ -190,15 +209,23 @@ def classification_info
end

def doc_auth_result_from_success
if success?
DocAuth::LexisNexis::ResultCodes::PASSED.name
if doc_auth_success?
LexisNexis::ResultCodes::PASSED.name
else
LexisNexis::ResultCodes::CAUTION.name
end
end

def transaction_status_from_success
if doc_auth_success?
LexisNexis::TransactionCodes::PASSED.name
else
DocAuth::LexisNexis::ResultCodes::CAUTION.name
LexisNexis::TransactionCodes::FAILED.name
end
end

def all_doc_capture_values_passing?(doc_auth_result, id_type_supported)
doc_auth_result == 'Passed' &&
def all_doc_capture_values_passing?(transaction_status, id_type_supported)
transaction_status == LexisNexis::TransactionCodes::PASSED.name &&
id_type_supported &&
(selfie_check_performed? ? selfie_passed? : true)
end
Expand All @@ -219,7 +246,6 @@ def parse_uri
# no-op, allows falling through to YAML parsing
end

ATTENTION_WITH_BARCODE_ALERT = { 'name' => '2D Barcode Read', 'result' => 'Attention' }.freeze
DEFAULT_FAILED_ALERTS = [{ name: '2D Barcode Read', result: 'Failed' }].freeze
DEFAULT_IMAGE_METRICS = {
front: {
Expand All @@ -237,7 +263,8 @@ def parse_uri
}.freeze

def create_response_info(
doc_auth_result: 'Failed',
transaction_status: LexisNexis::TransactionCodes::FAILED.name,
doc_auth_result: LexisNexis::ResultCodes::FAILED.name,
passed: [],
failed: DEFAULT_FAILED_ALERTS,
liveness_enabled: false,
Expand All @@ -248,15 +275,16 @@ def create_response_info(
merged_image_metrics = DEFAULT_IMAGE_METRICS.deep_merge(image_metrics)
{
vendor: 'Mock',
doc_auth_result: doc_auth_result,
transaction_status:,
doc_auth_result:,
processed_alerts: {
passed: passed,
failed: failed,
},
alert_failure_count: failed&.count.to_i,
image_metrics: merged_image_metrics,
liveness_enabled: liveness_enabled,
classification_info: classification_info,
liveness_enabled:,
classification_info:,
portrait_match_results: selfie_check_performed? ? portrait_match_results : nil,
passport_check_result:,
}
Expand Down
2 changes: 2 additions & 0 deletions spec/controllers/idv/image_uploads_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@
liveness_checking_required: boolean,
selfie_live: boolean,
selfie_quality_good: boolean,
transaction_status: 'passed',
workflow: an_instance_of(String),
birth_year: 1938,
zip_code: '59010',
Expand Down Expand Up @@ -1185,6 +1186,7 @@
liveness_checking_required: boolean,
selfie_live: boolean,
selfie_quality_good: boolean,
transaction_status: 'failed',
workflow: an_instance_of(String),
alert_failure_count: 1,
liveness_enabled: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: failed
portrait_match_results:
FaceMatchResult: Fail
FaceErrorMessage: 'Successful. Liveness: Live'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: failed
portrait_match_results:
FaceMatchResult: Fail
FaceErrorMessage: 'Liveness: NotLive'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: passed
portrait_match_results:
# returns the portrait match result
FaceMatchResult: Fail
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: passed
document:
address1: 1800 F Street
address2: Apt 3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: failed
failed_alerts:
- name: unexpected attention alert
result: Attention
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: failed
portrait_match_results:
# returns the portrait match result
FaceMatchResult: Fail
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: failed
failed_alerts: []
portrait_match_results:
FaceMatchResult: Fail
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: failed
failed_alerts: []
portrait_match_results:
FaceMatchResult: Pass
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: passed
document:
first_name: Jane
last_name: Doe
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: passed
document:
first_name: Jane
last_name: Doe
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: passed
document:
first_name: 'John'
last_name: 'Doe'
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/ial2_test_credential_no_liveness.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: passed
portrait_match_results:
# returns the portrait match result
FaceMatchResult: Fail
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/ial2_test_credential_poor_quality.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: passed
portrait_match_results:
# returns the portrait match result
FaceMatchResult: Fail
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/ial2_test_portrait_match_success.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
transaction_status: passed
document:
address1: '1 FAKE RD'
city: 'GREAT FALLS'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@
"Name": "Alert_1_AuthenticationResult",
"Values": [
{
"Value": "Passed",
"Value": "Failed",
"Detail": "Verified the presence of a pattern on the visible image."
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"ProductType": "TrueID",
"ExecutedStepName": "True_ID_Step",
"ProductConfigurationName": "AndreV3_TrueID_Flow",
"ProductStatus": "pass",
"ProductStatus": "fail",
"ParameterDetails": [
{
"Group": "AUTHENTICATION_RESULT",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"ProductType": "TrueID",
"ExecutedStepName": "True_ID_Step",
"ProductConfigurationName": "AndreV3_TrueID_Flow",
"ProductStatus": "pass",
"ProductStatus": "fail",
"ParameterDetails": [
{
"Group": "AUTHENTICATION_RESULT",
Expand Down
Loading