diff --git a/app/presenters/image_upload_response_presenter.rb b/app/presenters/image_upload_response_presenter.rb index 5a33c7f4288..a6cbf8565f8 100644 --- a/app/presenters/image_upload_response_presenter.rb +++ b/app/presenters/image_upload_response_presenter.rb @@ -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? @@ -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? diff --git a/app/services/doc_auth/error_generator.rb b/app/services/doc_auth/error_generator.rb index 51b5033c1ac..cd4282330d0 100644 --- a/app/services/doc_auth/error_generator.rb +++ b/app/services/doc_auth/error_generator.rb @@ -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] @@ -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 diff --git a/app/services/doc_auth/lexis_nexis/responses/true_id_response.rb b/app/services/doc_auth/lexis_nexis/responses/true_id_response.rb index a8f22585d94..d9878517127 100644 --- a/app/services/doc_auth/lexis_nexis/responses/true_id_response.rb +++ b/app/services/doc_auth/lexis_nexis/responses/true_id_response.rb @@ -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) @@ -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 @@ -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? diff --git a/app/services/doc_auth/mock/result_response.rb b/app/services/doc_auth/mock/result_response.rb index 3d7784016a6..ab0c3364b1e 100644 --- a/app/services/doc_auth/mock/result_response.rb +++ b/app/services/doc_auth/mock/result_response.rb @@ -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, @@ -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 @@ -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, @@ -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? @@ -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 @@ -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' + + 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 @@ -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 }&. @@ -166,15 +183,23 @@ def classification_info end def doc_auth_result_from_success - 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 + 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 @@ -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: { @@ -212,6 +236,7 @@ def parse_uri }.freeze def create_response_info( + transaction_status: 'failed', doc_auth_result: 'Failed', passed: [], failed: DEFAULT_FAILED_ALERTS, @@ -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, diff --git a/spec/controllers/idv/image_uploads_controller_spec.rb b/spec/controllers/idv/image_uploads_controller_spec.rb index b458af87f1a..dd85b880f53 100644 --- a/spec/controllers/idv/image_uploads_controller_spec.rb +++ b/spec/controllers/idv/image_uploads_controller_spec.rb @@ -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, @@ -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, diff --git a/spec/fixtures/ial2_test_credential_back_fail_doc_auth_face_match_errors.yml b/spec/fixtures/ial2_test_credential_back_fail_doc_auth_face_match_errors.yml index 8d56a635d42..cf2cc7b9cc8 100644 --- a/spec/fixtures/ial2_test_credential_back_fail_doc_auth_face_match_errors.yml +++ b/spec/fixtures/ial2_test_credential_back_fail_doc_auth_face_match_errors.yml @@ -1,3 +1,4 @@ +transaction_status: failed portrait_match_results: FaceMatchResult: Fail FaceErrorMessage: 'Successful. Liveness: Live' diff --git a/spec/fixtures/ial2_test_credential_back_fail_doc_auth_liveness_errors.yml b/spec/fixtures/ial2_test_credential_back_fail_doc_auth_liveness_errors.yml index e570cc2eb61..6aba5a111d7 100644 --- a/spec/fixtures/ial2_test_credential_back_fail_doc_auth_liveness_errors.yml +++ b/spec/fixtures/ial2_test_credential_back_fail_doc_auth_liveness_errors.yml @@ -1,3 +1,4 @@ +transaction_status: failed portrait_match_results: FaceMatchResult: Fail FaceErrorMessage: 'Liveness: NotLive' diff --git a/spec/fixtures/ial2_test_credential_barcode_attention_liveness_fail.yml b/spec/fixtures/ial2_test_credential_barcode_attention_liveness_fail.yml index 132502d887e..f709fdc0a09 100644 --- a/spec/fixtures/ial2_test_credential_barcode_attention_liveness_fail.yml +++ b/spec/fixtures/ial2_test_credential_barcode_attention_liveness_fail.yml @@ -1,3 +1,4 @@ +transaction_status: passed portrait_match_results: # returns the portrait match result FaceMatchResult: Fail diff --git a/spec/fixtures/ial2_test_credential_classification_info_no_name.yml b/spec/fixtures/ial2_test_credential_classification_info_no_name.yml index f3bbd617ef9..1061357d852 100644 --- a/spec/fixtures/ial2_test_credential_classification_info_no_name.yml +++ b/spec/fixtures/ial2_test_credential_classification_info_no_name.yml @@ -1,3 +1,4 @@ +transaction_status: passed document: address1: 1800 F Street address2: Apt 3 diff --git a/spec/fixtures/ial2_test_credential_doc_auth_attention_face_match_fail.yml b/spec/fixtures/ial2_test_credential_doc_auth_attention_face_match_fail.yml index 55effd3d317..fa8ac0e9f82 100644 --- a/spec/fixtures/ial2_test_credential_doc_auth_attention_face_match_fail.yml +++ b/spec/fixtures/ial2_test_credential_doc_auth_attention_face_match_fail.yml @@ -1,3 +1,4 @@ +transaction_status: failed failed_alerts: - name: unexpected attention alert result: Attention diff --git a/spec/fixtures/ial2_test_credential_doc_auth_fail_and_no_liveness.yml b/spec/fixtures/ial2_test_credential_doc_auth_fail_and_no_liveness.yml index 204eed7ad6a..a91a74e2444 100644 --- a/spec/fixtures/ial2_test_credential_doc_auth_fail_and_no_liveness.yml +++ b/spec/fixtures/ial2_test_credential_doc_auth_fail_and_no_liveness.yml @@ -1,3 +1,4 @@ +transaction_status: failed portrait_match_results: # returns the portrait match result FaceMatchResult: Fail diff --git a/spec/fixtures/ial2_test_credential_doc_auth_fail_face_match_fail.yml b/spec/fixtures/ial2_test_credential_doc_auth_fail_face_match_fail.yml index b2e85695378..f2024934dbc 100644 --- a/spec/fixtures/ial2_test_credential_doc_auth_fail_face_match_fail.yml +++ b/spec/fixtures/ial2_test_credential_doc_auth_fail_face_match_fail.yml @@ -1,3 +1,4 @@ +transaction_status: failed failed_alerts: [] portrait_match_results: FaceMatchResult: Fail diff --git a/spec/fixtures/ial2_test_credential_doc_auth_fail_selfie_pass.yml b/spec/fixtures/ial2_test_credential_doc_auth_fail_selfie_pass.yml index 0986801e54a..a3f64e73541 100644 --- a/spec/fixtures/ial2_test_credential_doc_auth_fail_selfie_pass.yml +++ b/spec/fixtures/ial2_test_credential_doc_auth_fail_selfie_pass.yml @@ -1,3 +1,4 @@ +transaction_status: failed failed_alerts: [] portrait_match_results: FaceMatchResult: Pass diff --git a/spec/fixtures/ial2_test_credential_doc_auth_selfie_pass_pii_fail.yml b/spec/fixtures/ial2_test_credential_doc_auth_selfie_pass_pii_fail.yml index e05b4273941..19ae38ce973 100644 --- a/spec/fixtures/ial2_test_credential_doc_auth_selfie_pass_pii_fail.yml +++ b/spec/fixtures/ial2_test_credential_doc_auth_selfie_pass_pii_fail.yml @@ -1,3 +1,4 @@ +transaction_status: passed document: first_name: Jane last_name: Doe diff --git a/spec/fixtures/ial2_test_credential_face_match_fail_and_pii_fail.yml b/spec/fixtures/ial2_test_credential_face_match_fail_and_pii_fail.yml index a108ec84c2a..859be359512 100644 --- a/spec/fixtures/ial2_test_credential_face_match_fail_and_pii_fail.yml +++ b/spec/fixtures/ial2_test_credential_face_match_fail_and_pii_fail.yml @@ -1,3 +1,4 @@ +transaction_status: passed document: first_name: Jane last_name: Doe diff --git a/spec/fixtures/ial2_test_credential_liveness_fail_face_match_fail.yml b/spec/fixtures/ial2_test_credential_liveness_fail_face_match_fail.yml index 7f32eaca941..999a1d3d531 100644 --- a/spec/fixtures/ial2_test_credential_liveness_fail_face_match_fail.yml +++ b/spec/fixtures/ial2_test_credential_liveness_fail_face_match_fail.yml @@ -1,3 +1,4 @@ +transaction_status: passed document: first_name: 'John' last_name: 'Doe' diff --git a/spec/fixtures/ial2_test_credential_no_liveness.yml b/spec/fixtures/ial2_test_credential_no_liveness.yml index 850f6a33ca8..0ac98fe9d51 100644 --- a/spec/fixtures/ial2_test_credential_no_liveness.yml +++ b/spec/fixtures/ial2_test_credential_no_liveness.yml @@ -1,3 +1,4 @@ +transaction_status: passed portrait_match_results: # returns the portrait match result FaceMatchResult: Fail diff --git a/spec/fixtures/ial2_test_credential_poor_quality.yml b/spec/fixtures/ial2_test_credential_poor_quality.yml index 11519ae47b5..240c04292e0 100644 --- a/spec/fixtures/ial2_test_credential_poor_quality.yml +++ b/spec/fixtures/ial2_test_credential_poor_quality.yml @@ -1,3 +1,4 @@ +transaction_status: passed portrait_match_results: # returns the portrait match result FaceMatchResult: Fail diff --git a/spec/fixtures/ial2_test_portrait_match_success.yml b/spec/fixtures/ial2_test_portrait_match_success.yml index decfc65999d..562f43404b4 100644 --- a/spec/fixtures/ial2_test_portrait_match_success.yml +++ b/spec/fixtures/ial2_test_portrait_match_success.yml @@ -1,3 +1,4 @@ +transaction_status: passed document: address1: '1 FAKE RD' city: 'GREAT FALLS' diff --git a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_attention_barcode.json b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_attention_barcode.json index b65a8b12672..6050c5c46d1 100644 --- a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_attention_barcode.json +++ b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_attention_barcode.json @@ -327,7 +327,7 @@ "Name": "Alert_1_AuthenticationResult", "Values": [ { - "Value": "Passed", + "Value": "Failed", "Detail": "Verified the presence of a pattern on the visible image." } ] diff --git a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_no_liveness.json b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_no_liveness.json index d47c7b52a28..bdc254aef5f 100644 --- a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_no_liveness.json +++ b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_no_liveness.json @@ -15,7 +15,7 @@ "ProductType": "TrueID", "ExecutedStepName": "True_ID_Step", "ProductConfigurationName": "AndreV3_TrueID_Flow", - "ProductStatus": "pass", + "ProductStatus": "fail", "ParameterDetails": [ { "Group": "AUTHENTICATION_RESULT", diff --git a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_no_liveness_low_dpi.json b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_no_liveness_low_dpi.json index 040084be529..3c718429ec0 100644 --- a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_no_liveness_low_dpi.json +++ b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_no_liveness_low_dpi.json @@ -15,7 +15,7 @@ "ProductType": "TrueID", "ExecutedStepName": "True_ID_Step", "ProductConfigurationName": "AndreV3_TrueID_Flow", - "ProductStatus": "pass", + "ProductStatus": "fail", "ParameterDetails": [ { "Group": "AUTHENTICATION_RESULT", diff --git a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_all_failures.json b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_all_failures.json index 3d3282e16f2..f7d89e6ae68 100644 --- a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_all_failures.json +++ b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_all_failures.json @@ -15,7 +15,7 @@ "ProductType": "TrueID", "ExecutedStepName": "True_ID_Step", "ProductConfigurationName": "AndreV3_TrueID_Flow", - "ProductStatus": "pass", + "ProductStatus": "fail", "ParameterDetails": [ { "Group": "AUTHENTICATION_RESULT", diff --git a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_face_match_pass.json b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_face_match_pass.json index d82cd53bb5a..aa8b0c08c0a 100644 --- a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_face_match_pass.json +++ b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_face_match_pass.json @@ -15,7 +15,7 @@ "ProductType": "TrueID", "ExecutedStepName": "True_ID_Step", "ProductConfigurationName": "AndreV3_TrueID_Flow", - "ProductStatus": "pass", + "ProductStatus": "fail", "ParameterDetails": [ { "Group": "AUTHENTICATION_RESULT", diff --git a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_liveness.json b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_liveness.json index 9ae6ac15f2c..bf077d15adb 100644 --- a/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_liveness.json +++ b/spec/fixtures/proofing/lexis_nexis/true_id/true_id_response_failure_with_liveness.json @@ -15,7 +15,7 @@ "ProductType": "TrueID", "ExecutedStepName": "True_ID_Step", "ProductConfigurationName": "AndreV3_TrueID_Flow", - "ProductStatus": "pass", + "ProductStatus": "fail", "ParameterDetails": [ { "Group": "AUTHENTICATION_RESULT", diff --git a/spec/forms/idv/api_image_upload_form_spec.rb b/spec/forms/idv/api_image_upload_form_spec.rb index 87b2be2f466..0c2ebd2dc53 100644 --- a/spec/forms/idv/api_image_upload_form_spec.rb +++ b/spec/forms/idv/api_image_upload_form_spec.rb @@ -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, @@ -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, diff --git a/spec/presenters/image_upload_response_presenter_spec.rb b/spec/presenters/image_upload_response_presenter_spec.rb index 19cb7f0decb..813faa4a0b0 100644 --- a/spec/presenters/image_upload_response_presenter_spec.rb +++ b/spec/presenters/image_upload_response_presenter_spec.rb @@ -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 diff --git a/spec/services/doc_auth/error_generator_spec.rb b/spec/services/doc_auth/error_generator_spec.rb index 96b3a344bfa..b2f91e6268d 100644 --- a/spec/services/doc_auth/error_generator_spec.rb +++ b/spec/services/doc_auth/error_generator_spec.rb @@ -47,6 +47,7 @@ let(:result_code_invalid) { false } def build_error_info( + transaction_status: nil, doc_result: nil, passed: [], failed: [], @@ -58,6 +59,7 @@ def build_error_info( reference: 'Reference1', liveness_enabled: liveness_enabled, vendor: 'Test', + transaction_status: transaction_status, transaction_reason_code: 'testing', doc_auth_result: doc_result, processed_alerts: { @@ -83,6 +85,7 @@ def build_error_info( it 'DocAuthResult is Attention of Barcode Read and general selfie error' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Attention', failed: [{ name: '2D Barcode Read', result: 'Attention' }], ) @@ -103,6 +106,7 @@ def build_error_info( it 'DocAuthResult is Attention with unknown alert' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Attention', failed: [{ name: 'Unknown Alert', result: 'Attention' }], ) @@ -121,6 +125,7 @@ def build_error_info( end it 'DocAuthResult is Unknown and general selfie error' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Unknown', failed: [{ name: 'Visible Pattern', result: 'Failed' }], ) @@ -138,8 +143,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed' do + it 'TransactionStatus is Failed' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [{ name: 'Visible Pattern', result: 'Failed' }], ) @@ -153,8 +159,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with single alert with a side' do + it 'TransactionStatus is Failed with single alert with a side' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [{ name: 'Visible Pattern', result: 'Failed', side: 'front' }], ) @@ -167,8 +174,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with multiple different alerts' do + it 'TransactionStatus is Failed with multiple different alerts' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [ { name: '2D Barcode Read', result: 'Attention' }, @@ -185,8 +193,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with multiple id alerts' do + it 'TransactionStatus is Failed with multiple id alerts' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [ { name: 'Expiration Date Valid', result: 'Attention' }, @@ -203,8 +212,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with multiple front alerts' do + it 'TransactionStatus is Failed with multiple front alerts' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [ { name: 'Photo Printing', result: 'Attention' }, @@ -220,8 +230,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with multiple back alerts' do + it 'TransactionStatus is Failed with multiple back alerts' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [ { name: '2D Barcode Read', result: 'Attention' }, @@ -237,8 +248,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with an unknown alert' do + it 'TransactionStatus is Failed with an unknown alert' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [{ name: 'Not a known alert', result: 'Failed' }], ) @@ -255,8 +267,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with multiple alerts including an unknown' do + it 'TransactionStatus is Failed with multiple alerts including an unknown' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [ { name: 'Not a known alert', result: 'Failed' }, @@ -276,8 +289,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with an unknown passed alert' do + it 'TransactionStatus is Failed with an unknown passed alert' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', passed: [{ name: 'Not a known alert', result: 'Passed' }], failed: [{ name: 'Birth Date Crosscheck', result: 'Failed' }], @@ -295,8 +309,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is failed with unsupported doc type' do + it 'TransactionStatus is Failed with unsupported doc type' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', passed: [{ name: 'Not a known alert', result: 'Passed' }], failed: [{ name: 'Birth Date Crosscheck', result: 'Failed' }], @@ -315,8 +330,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with unknown alert and general selfie error' do + it 'TransactionStatus is Failed with unknown alert and general selfie error' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [{ name: 'Unknown alert', result: 'Failed' }], ) @@ -336,8 +352,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is Failed with known alert and specific selfie no liveness error' do + it 'TransactionStatus is Failed with known alert and specific selfie no liveness error' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [{ name: 'Visible Pattern', result: 'Failed' }], ) @@ -355,8 +372,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is success with unsupported doc type' do + it 'TransactionStatus is passed with unsupported doc type' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', passed: [{ name: 'Not a known alert', result: 'Passed' }], failed: [], @@ -375,8 +393,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is success with VHIC' do + it 'TransactionStatus is passed with VHIC' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', passed: [{ name: 'Not a known alert', result: 'Passed' }], failed: [], @@ -396,8 +415,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is failed with unknown doc type' do + it 'TransactionStatus is Failed with unknown doc type' do error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [ { name: 'Not a known alert', result: 'Failed' }, @@ -417,8 +437,9 @@ def build_error_info( expect(output[:hints]).to eq(true) end - it 'DocAuthResult is success with an unknown alert' do + it 'TransactionStatus is passed with an unknown alert' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', failed: [{ name: 'Not a known alert', result: 'Failed' }], ) @@ -434,8 +455,9 @@ def build_error_info( expect(output[:back]).to contain_exactly(DocAuth::Errors::FALLBACK_FIELD_LEVEL) expect(output[:hints]).to eq(true) end - it 'DocAuthResult is success with general selfie error' do + it 'TransactionStatus is passed with general selfie error' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', failed: [], ) @@ -456,8 +478,9 @@ def build_error_info( expect(output[:hints]).to eq(false) end - it 'DocAuthResult is success with specific selfie no liveness error' do + it 'TransactionStatus is passed with specific selfie no liveness error' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', failed: [], ) @@ -476,8 +499,9 @@ def build_error_info( expect(output[:hints]).to eq(false) end - it 'DocAuthResult is success with specific selfie liveness quality error' do + it 'TransactionStatus is passed with specific selfie liveness quality error' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', failed: [], ) @@ -495,8 +519,9 @@ def build_error_info( expect(output[:hints]).to eq(false) end - it 'DocAuthResult is success with alert and general selfie error' do + it 'TransactionStatus is passed with alert and general selfie error' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', failed: [{ name: 'Visible Pattern', result: 'Failed' }], ) @@ -516,8 +541,9 @@ def build_error_info( expect(output[:hints]).to eq(false) end - it 'DocAuthResult is success with unknown alert and general selfie error' do + it 'TransactionStatus is passed with unknown alert and general selfie error' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', failed: [{ name: 'Unknown alert', result: 'Failed' }], ) @@ -538,8 +564,9 @@ def build_error_info( expect(output[:hints]).to eq(false) end - it 'DocAuthResult is success with alert and specific no liveness error' do + it 'TransactionStatus is passed with alert and specific no liveness error' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', failed: [{ name: 'Visible Pattern', result: 'Failed' }], ) @@ -557,8 +584,9 @@ def build_error_info( expect(output[:hints]).to eq(false) end - it 'DocAuthResult is success with alert and specific liveness quality error' do + it 'TransactionStatus is passed with alert and specific liveness quality error' do error_info = build_error_info( + transaction_status: 'passed', doc_result: 'Passed', failed: [{ name: 'Visible Pattern', result: 'Failed' }], ) @@ -785,7 +813,11 @@ def build_error_info( context 'when liveness check passed' do let(:face_match_result) { 'Pass' } it 'returns a metric error with no other error' do - error_info = build_error_info(doc_result: 'Passed', image_metrics: metrics) + error_info = build_error_info( + transaction_status: 'passed', + doc_result: 'Passed', + image_metrics: metrics, + ) errors = described_class.new(config).generate_doc_auth_errors(error_info) expect(errors.keys).to contain_exactly(:front, :back, :general, :hints) end @@ -794,7 +826,11 @@ def build_error_info( context 'when liveness check failed' do let(:face_match_result) { 'Fail' } it 'returns a metric error without a selfie error' do - error_info = build_error_info(doc_result: 'Passed', image_metrics: metrics) + error_info = build_error_info( + transaction_status: 'passed', + doc_result: 'Passed', + image_metrics: metrics, + ) errors = described_class.new(config).generate_doc_auth_errors(error_info) expect(errors.keys).to contain_exactly(:front, :back, :general, :hints) end @@ -822,6 +858,7 @@ def build_error_info( it 'generate doc type error' do metrics[:front]['HorizontalResolution'] = 50 error_info = build_error_info( + transaction_status: 'failed', doc_result: 'Failed', failed: [{ name: '2D Barcode Read', result: 'Attention' }], classification_info: { Back: vhic_classification_details, diff --git a/spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb b/spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb index f527be367d1..0edc6ff037d 100644 --- a/spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb +++ b/spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb @@ -282,12 +282,12 @@ def response_body(include_liveness) def response_body_with_doc_auth_errors(include_liveness) { Status: { - TransactionStatus: 'passed', + TransactionStatus: 'failed', }, Products: [ { ProductType: 'TrueID', - ProductStatus: 'pass', + ProductStatus: 'fail', ParameterDetails: [ { Group: 'AUTHENTICATION_RESULT', diff --git a/spec/services/doc_auth/lexis_nexis/responses/true_id_response_spec.rb b/spec/services/doc_auth/lexis_nexis/responses/true_id_response_spec.rb index 7847a830725..56a6589a439 100644 --- a/spec/services/doc_auth/lexis_nexis/responses/true_id_response_spec.rb +++ b/spec/services/doc_auth/lexis_nexis/responses/true_id_response_spec.rb @@ -15,9 +15,6 @@ let(:success_with_failed_to_ocr_dob) do instance_double(Faraday::Response, status: 200, body: LexisNexisFixtures.true_id_response_failed_to_ocr_dob) end - let(:failure_response_face_match_fail) do - instance_double(Faraday::Response, status: 200, body: LexisNexisFixtures.true_id_response_with_face_match_fail) - end let(:failure_response_no_liveness) do instance_double(Faraday::Response, status: 200, body: LexisNexisFixtures.true_id_response_failure_no_liveness) end @@ -70,6 +67,8 @@ it 'is a successful result' do expect(response.successful_result?).to eq(true) + expect(response.selfie_status).to eq(:not_processed) + expect(response.success?).to eq(true) expect(response.to_h[:vendor]).to eq('TrueID') end @@ -87,16 +86,8 @@ expect(response.success?).to eq(false) expect(response.to_h[:vendor]).to eq('TrueID') end - - context 'when a liveness check was not requested' do - let(:liveness_checking_enabled) { false } - it 'is a successful result' do - expect(response.selfie_status).to eq(:not_processed) - expect(response.success?).to eq(true) - expect(response.to_h[:vendor]).to eq('TrueID') - end - end end + context 'when selfie status passes' do let(:response) do described_class.new( @@ -424,7 +415,7 @@ def get_decision_product(resp) log_alert_results: a_hash_including('2d_barcode_content': { no_side: 'Failed' }), transaction_status: 'failed', transaction_reason_code: 'failed_true_id', - product_status: 'pass', + product_status: 'fail', decision_product_status: 'fail', doc_auth_result: 'Failed', processed_alerts: a_hash_including(:passed, :failed), @@ -597,7 +588,7 @@ def get_decision_product(resp) it { expect(attention_with_barcode).to eq(false) } end - context 'with single barcode attention error' do + context 'with barcode attention error' do let(:response) { described_class.new(attention_barcode_read, config) } it { expect(attention_with_barcode).to eq(true) } @@ -759,7 +750,7 @@ def get_decision_product(resp) end context 'when selfie check is enabled' do - context 'whe missing selfie result in response' do + context 'when missing selfie result in response' do let(:request_context) do { workflow: 'selfie_workflow', @@ -791,7 +782,26 @@ def get_decision_product(resp) end describe '#successful_result?' do - context 'and selfie check is enabled' do + context 'selfie check is disabled' do + liveness_checking_enabled = false + + context 'when document validation is successful' do + let(:response) { described_class.new(success_response, config) } + it 'returns true' do + expect(response.successful_result?).to eq(true) + end + end + + it 'returns true no matter what the value of selfie is' do + response = described_class.new( + doc_auth_success_with_face_match_fail, config, liveness_checking_enabled + ) + + expect(response.successful_result?).to eq(true) + end + end + + context 'selfie check is enabled' do let(:liveness_checking_enabled) { true } it 'returns true with a passing selfie' do @@ -804,7 +814,7 @@ def get_decision_product(resp) context 'when portrait match fails' do it 'returns false with a failing selfie' do response = described_class.new( - failure_response_face_match_fail, config, liveness_checking_enabled + doc_auth_success_with_face_match_fail, config, liveness_checking_enabled ) expect(response.successful_result?).to eq(false) @@ -820,22 +830,11 @@ def get_decision_product(resp) it 'returns false' do expect(response.doc_auth_success?).to eq(true) + expect(response.selfie_passed?).to eq(false) expect(response.successful_result?).to eq(false) end end end - - context 'and selfie check is disabled' do - liveness_checking_enabled = false - - it 'returns true no matter what the value of selfie is' do - response = described_class.new( - failure_response_face_match_fail, config, liveness_checking_enabled - ) - - expect(response.successful_result?).to eq(true) - end - end end end end diff --git a/spec/services/doc_auth/mock/doc_auth_mock_client_spec.rb b/spec/services/doc_auth/mock/doc_auth_mock_client_spec.rb index e4ec9c1487c..36afd74726a 100644 --- a/spec/services/doc_auth/mock/doc_auth_mock_client_spec.rb +++ b/spec/services/doc_auth/mock/doc_auth_mock_client_spec.rb @@ -241,10 +241,12 @@ FaceMatchResult: Pass FaceErrorMessage: 'Successful. Liveness: Live' doc_auth_result: Passed + transaction_status: passed failed_alerts: [] YAML image_no_setting = <<~YAML + transaction_status: passed doc_auth_result: Passed failed_alerts: [] YAML @@ -280,6 +282,7 @@ image = <<~YAML doc_auth_result: Passed + transaction_status: passed failed_alerts: [] YAML @@ -353,6 +356,7 @@ describe 'when sending a selfie image that is successful (both live and a match)' do it 'returns a success response' do image = <<~YAML + transaction_status: passed portrait_match_results: FaceMatchResult: Pass FaceErrorMessage: 'Successful. Liveness: Live' @@ -389,6 +393,7 @@ FaceMatchResult: Fail FaceErrorMessage: 'Liveness: NotLive' doc_auth_result: Passed + transaction_status: passed failed_alerts: [] YAML @@ -421,6 +426,7 @@ FaceMatchResult: Fail FaceErrorMessage: 'Liveness: PoorQuality' doc_auth_result: Passed + transaction_status: passed failed_alerts: [] YAML @@ -453,6 +459,7 @@ FaceMatchResult: Fail FaceErrorMessage: 'Successful. Liveness: Live' doc_auth_result: Passed + transaction_status: passed failed_alerts: [] YAML post_images_response = client.post_images( diff --git a/spec/services/doc_auth/mock/result_response_spec.rb b/spec/services/doc_auth/mock/result_response_spec.rb index 0e247fd97b0..d6cd7a2b1d4 100644 --- a/spec/services/doc_auth/mock/result_response_spec.rb +++ b/spec/services/doc_auth/mock/result_response_spec.rb @@ -124,7 +124,7 @@ ) expect(response.exception).to eq(nil) expect(response.pii_from_doc).to eq(nil) - expect(response.attention_with_barcode?).to eq(false) + expect(response.attention_with_barcode?).to eq(true) end end @@ -318,6 +318,7 @@ ) expect(response.attention_with_barcode?).to eq(false) expect(response.extra).to eq( + transaction_status: 'passed', doc_auth_result: DocAuth::LexisNexis::ResultCodes::PASSED.name, billed: true, classification_info: {}, @@ -392,6 +393,7 @@ expect(response.pii_from_doc).to eq(nil) expect(response.attention_with_barcode?).to eq(false) expect(response.extra).to eq( + transaction_status: 'failed', doc_auth_result: DocAuth::LexisNexis::ResultCodes::CAUTION.name, billed: true, classification_info: {}, @@ -419,6 +421,7 @@ expect(response.pii_from_doc).to eq(nil) expect(response.attention_with_barcode?).to eq(false) expect(response.extra).to eq( + transaction_status: 'failed', doc_auth_result: DocAuth::LexisNexis::ResultCodes::FAILED.name, billed: true, classification_info: {}, @@ -475,6 +478,7 @@ ) expect(response.attention_with_barcode?).to eq(false) expect(response.extra).to eq( + transaction_status: 'passed', doc_auth_result: DocAuth::LexisNexis::ResultCodes::PASSED.name, billed: true, classification_info: {}, @@ -696,6 +700,7 @@ context 'with a yaml file that includes classification info but missing pii' do let(:input) do <<~YAML + transaction_status: passed doc_auth_result: Passed document: city: Bayside @@ -730,6 +735,7 @@ describe 'and it is successful' do let(:input) do <<~YAML + transaction_status: passed portrait_match_results: FaceMatchResult: Pass FaceErrorMessage: 'Successful. Liveness: Live'