Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
0dc6768
doc auth pass if transaction status passes
amirbey Apr 12, 2024
4a56d57
update spec response transaction status
amirbey Apr 13, 2024
34db71f
update true id response spec
amirbey Apr 13, 2024
4bdd889
update fixtures product status for failed transactions
amirbey Apr 13, 2024
d7f9faa
update product status
amirbey Apr 16, 2024
0369a1a
selfie must past
amirbey May 14, 2024
69c0131
revert fixture changes
amirbey May 14, 2024
28cad5b
update trueID response specs for transaction status
amirbey May 14, 2024
e59dbac
attention barcode does not have to be only error
amirbey May 14, 2024
6db9df1
update doc_auth_success to remove selfie in mock result response
amirbey May 14, 2024
a8b2b5f
happy linting
amirbey May 14, 2024
b6c3450
allow mock proofer to have multiple errors with barcode attn
amirbey May 14, 2024
addd7e3
remove dup test
amirbey May 14, 2024
c52b29b
add an error barcode fixture to barcode error trueid response
amirbey May 14, 2024
8531cee
ensure attention_with_barcode? returns a boolean
amirbey May 14, 2024
6828d0f
update spec attention with barcode
amirbey May 15, 2024
a740b59
error generator use transaction status to determine if doc auth passe…
amirbey May 15, 2024
b0c4609
consolidate checking if doc auth passed in error generator
amirbey May 15, 2024
a50a47a
doc_auth_passed not in scope for DocAuthErrorHandler
amirbey May 15, 2024
92b5c8c
update mock to include transaction_status
amirbey May 15, 2024
a3518c0
rename error generator tests from 'DocAuthResult is ...' to 'Transact…
amirbey May 15, 2024
5932f0b
fetch transaction_status from yml image files
amirbey May 15, 2024
394df62
update analytics expectation with transaction_status value
amirbey May 15, 2024
203b224
update analytics expectation with transaction_status value
amirbey May 15, 2024
ba169cf
update analytics expectation with transaction_status value
amirbey May 15, 2024
a117959
update transaction_stauts in mock to reflect doc auth only
amirbey May 15, 2024
ad8de35
check transaction status to determine if doc auth is sucess for mock
amirbey May 15, 2024
60980a5
assist with correcting case for transaction status and doc auth resul…
amirbey May 15, 2024
b471df6
do not correct case
amirbey May 15, 2024
98d0d53
add transaction status to yml
amirbey May 16, 2024
bbfb249
add transaction status to yml
amirbey May 16, 2024
d207dce
add transaction status to yml
amirbey May 16, 2024
5be254f
add transaction result to inline yaml files
amirbey May 16, 2024
99cf19e
update yml fixtures to have transaction_status
amirbey May 16, 2024
b71e01b
update image upload presenter to use transaction status
amirbey May 16, 2024
fc067af
upate image upload presenter spec to receive transaction status
amirbey May 16, 2024
bf691c9
remove stale comment
amirbey May 21, 2024
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 @@ -51,7 +51,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 @@ -73,8 +73,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] == 'failed'
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 @@ -127,7 +127,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] != 'passed'
response_info[:processed_alerts][:failed]&.each do |alert|
alert_msg_hash = ErrorGenerator::ALERT_MESSAGES[alert[:name].to_sym]

Expand Down Expand Up @@ -370,28 +370,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] == 'passed'

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
44 changes: 35 additions & 9 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: transaction_status,
doc_auth_result: doc_auth_result,
portrait_match_results: portrait_match_results,
billed: true,
Expand All @@ -39,6 +40,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 @@ -47,6 +49,7 @@ def errors
classification_info = file_data.dig('classification_info')
# Pass and doc type is ok
has_fields = [
transaction_status,
doc_auth_result,
image_metrics,
failed,
Expand All @@ -59,10 +62,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 @@ -91,7 +95,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 @@ -105,10 +110,14 @@ 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 == 'failed'
return true if transaction_status_from_uploaded_file == 'passed'
return false if doc_auth_result_from_uploaded_file == 'Failed'
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 line in case there are yml files out there that haven't implemented transaction_status?

If so, it does seem like it could be worthwhile enforcing folks to include that, rather than keeping this method for old code.

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.

good point .. currently we do not force folks to include doc_auth_result ... so replicating this behavior with transaction_status


doc_auth_result_from_uploaded_file == 'Passed' ||
errors.blank? ||
attention_with_barcode?
) && id_type_supported?
(attention_with_barcode? && parsed_alerts.length == 1)
end

def selfie_status
Expand Down Expand Up @@ -154,6 +163,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 @@ -166,15 +183,23 @@ def classification_info
end

def doc_auth_result_from_success
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 wonder if we still need this method? It seems possible that we could refactor this away if we aren't using the doc_auth_result for any logic.

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

def all_doc_capture_values_passing?(doc_auth_result, id_type_supported)
doc_auth_result == 'Passed' &&
def transaction_status_from_success
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.

this name is confusing to me - I'm not sure I understand the from_success piece.

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.

continuing the pattern used in doc_auth_result_from_success this is if the document is authenticated successfully

if doc_auth_success?
'passed'
else
'failed'
end
end

def all_doc_capture_values_passing?(transaction_status, id_type_supported)
transaction_status == 'passed' &&
id_type_supported &&
(selfie_check_performed? ? selfie_passed? : true)
end
Expand All @@ -194,7 +219,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 @@ -212,6 +236,7 @@ def parse_uri
}.freeze

def create_response_info(
transaction_status: 'failed',
doc_auth_result: 'Failed',
passed: [],
failed: DEFAULT_FAILED_ALERTS,
Expand All @@ -222,6 +247,7 @@ def create_response_info(
merged_image_metrics = DEFAULT_IMAGE_METRICS.deep_merge(image_metrics)
{
vendor: 'Mock',
transaction_status: transaction_status,
doc_auth_result: doc_auth_result,
processed_alerts: {
passed: passed,
Expand Down
4 changes: 2 additions & 2 deletions spec/controllers/idv/image_uploads_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@
product_status: nil,
reference: nil,
transaction_reason_code: nil,
transaction_status: nil,
transaction_status: 'passed',
vendor: nil,
workflow: an_instance_of(String),
birth_year: 1938,
Expand Down Expand Up @@ -1190,7 +1190,7 @@
product_status: nil,
reference: nil,
transaction_reason_code: nil,
transaction_status: nil,
transaction_status: 'failed',
vendor: nil,
workflow: an_instance_of(String),
birth_year: nil,
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",
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.

Can you say more about these changes (also in some of the other fixtures)? I could be mistaken but I thought these were direct responses from TrueID and this PR is to change what field we rely on from TrueID, and not that the TrueID response itself has changed.

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.

@night-jellyfish - yes, you are correct ... this change is about relying on a different field (transaction_status)! 👍🏿
while we will not be evaluating product_status ... in our prod events.log, it is consistent that product status and transaction status either both pass or both fail. however, it seems there is a discrepancy in many of our fixtures.

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.

Interesting! I guess I was worrying a little that I thought our fixtures were taken directly from requests to the API (and then anonymized). So that would imply to me that maybe the values could be opposing. But maybe I'm wrong about how they were created and this isn't a concern.

"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
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
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
4 changes: 2 additions & 2 deletions spec/forms/idv/api_image_upload_form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@
doc_auth_success: boolean,
selfie_status: anything,
vendor: nil,
transaction_status: nil,
transaction_status: 'passed',
transaction_reason_code: nil,
workflow: 'test_non_liveness_workflow',
birth_year: 1938,
Expand Down Expand Up @@ -373,7 +373,7 @@
doc_auth_success: boolean,
selfie_status: :success,
vendor: nil,
transaction_status: nil,
transaction_status: 'passed',
transaction_reason_code: nil,
workflow: 'test_liveness_workflow',
birth_year: 1938,
Expand Down
2 changes: 1 addition & 1 deletion spec/presenters/image_upload_response_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@
front: t('doc_auth.errors.not_a_file'),
hints: true,
},
extra: { doc_auth_result: 'Failed', remaining_submit_attempts: 3 },
extra: { transaction_status: 'failed', remaining_submit_attempts: 3 },
)
end

Expand Down
Loading