From fba34bfb44dce34576cfbea9386fd7c756c80ebd Mon Sep 17 00:00:00 2001 From: Eileen McFarland Date: Wed, 14 Sep 2022 17:13:00 -0400 Subject: [PATCH 1/7] expand metrics for USPS proofing attempts --- app/jobs/get_usps_proofing_results_job.rb | 42 +++++-- .../get_usps_proofing_results_job_spec.rb | 113 +++++++++++++----- spec/support/usps_ipp_helper.rb | 21 +++- 3 files changed, 132 insertions(+), 44 deletions(-) diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index a43c6a0bf12..b2f6d8d0f89 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -28,6 +28,24 @@ def enrollment_analytics_attributes(enrollment, complete:) } end + def response_analytics_attributes(response) + { + fraud_suspected: response['fraudSuspected'], + primary_id_type: response['primaryIdType'], + secondary_id_type: response['secondaryIdType'], + failure_reason: response['failureReason'], + transaction_end_date_time: response['transactionEndDateTime'], + transaction_start_date_time: response['transactionStartDateTime'], + status: response['status'], + assurance_level: response['assuranceLevel'], + proofing_post_office: response['proofingPostOffice'], + proofing_city: response['proofingCity'], + proofing_state: response['proofingState'], + scan_count: response['scanCount'], + response_message: response['responseMessage'], + } + end + def perform(_now) return true unless IdentityConfig.store.in_person_proofing_enabled @@ -107,10 +125,11 @@ def handle_bad_request_error(err, enrollment) # Customer has not been to post office for IPP enrollment_outcomes[:enrollments_in_progress] += 1 when IPP_EXPIRED_ERROR_MESSAGE - handle_expired_status_update(enrollment) + handle_expired_status_update(enrollment, err.response) else analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_exception( **enrollment_analytics_attributes(enrollment, complete: false), + **response_analytics_attributes(err.response), reason: 'Request exception', exception_class: err.class.to_s, exception_message: err.message, @@ -123,6 +142,7 @@ def handle_standard_error(err, enrollment) enrollment_outcomes[:enrollments_errored] += 1 analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_exception( **enrollment_analytics_attributes(enrollment, complete: false), + **response_analytics_attributes(err.response), reason: 'Request exception', exception_class: err.class.to_s, exception_message: err.message, @@ -137,12 +157,13 @@ def handle_response_is_not_a_hash(enrollment) ) end - def handle_unsupported_status(enrollment, status) + def handle_unsupported_status(enrollment, response) enrollment_outcomes[:enrollments_errored] += 1 analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_exception( **enrollment_analytics_attributes(enrollment, complete: false), + **response_analytics_attributes(response), reason: 'Unsupported status', - status: status, + status: response['status'], ) end @@ -150,6 +171,7 @@ def handle_unsupported_id_type(enrollment, response) enrollment_outcomes[:enrollments_failed] += 1 analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_enrollment_updated( **enrollment_analytics_attributes(enrollment, complete: true), + **response_analytics_attributes(response), fraud_suspected: response['fraudSuspected'], passed: false, primary_id_type: response['primaryIdType'], @@ -158,10 +180,11 @@ def handle_unsupported_id_type(enrollment, response) enrollment.update(status: :failed) end - def handle_expired_status_update(enrollment) + def handle_expired_status_update(enrollment, response) enrollment_outcomes[:enrollments_expired] += 1 analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_enrollment_updated( **enrollment_analytics_attributes(enrollment, complete: true), + **response_analytics_attributes(response[:body]), fraud_suspected: nil, passed: false, reason: 'Enrollment has expired', @@ -173,15 +196,9 @@ def handle_failed_status(enrollment, response) enrollment_outcomes[:enrollments_failed] += 1 analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_enrollment_updated( **enrollment_analytics_attributes(enrollment, complete: true), - failure_reason: response['failureReason'], - fraud_suspected: response['fraudSuspected'], + **response_analytics_attributes(response), passed: false, - primary_id_type: response['primaryIdType'], - proofing_state: response['proofingState'], reason: 'Failed status', - secondary_id_type: response['secondaryIdType'], - transaction_end_date_time: response['transactionEndDateTime'], - transaction_start_date_time: response['transactionStartDateTime'], ) enrollment.update(status: :failed) @@ -192,6 +209,7 @@ def handle_successful_status_update(enrollment, response) enrollment_outcomes[:enrollments_passed] += 1 analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_enrollment_updated( **enrollment_analytics_attributes(enrollment, complete: true), + **response_analytics_attributes(**response), fraud_suspected: response['fraudSuspected'], passed: true, reason: 'Successful status update', @@ -218,7 +236,7 @@ def process_enrollment_response(enrollment, response) when IPP_STATUS_FAILED handle_failed_status(enrollment, response) else - handle_unsupported_status(enrollment, response['status']) + handle_unsupported_status(enrollment, response) end end diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb index 4fba546d105..fdc2332a9b6 100644 --- a/spec/jobs/get_usps_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_proofing_results_job_spec.rb @@ -296,79 +296,117 @@ end context 'when an enrollment passes' do - before(:each) do - stub_request_passed_proofing_results - end + let!(:response) { stub_request_passed_proofing_results } it_behaves_like('enrollment with a status update', passed: true, status: 'passed') it 'logs details about the success' do job.perform(Time.zone.now) + response_as_json = JSON.parse(response[:body]) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Enrollment status updated', - fraud_suspected: false, reason: 'Successful status update', + fraud_suspected: response_as_json['fraudSuspected'], + primary_id_type: response_as_json['primaryIdType'], + secondary_id_type: response_as_json['secondaryIdType'], + failure_reason: response_as_json['failureReason'], + transaction_end_date_time: response_as_json['transactionEndDateTime'], + transaction_start_date_time: response_as_json['transactionStartDateTime'], + status: response_as_json['status'], + assurance_level: response_as_json['assuranceLevel'], + proofing_post_office: response_as_json['proofingPostOffice'], + proofing_city: response_as_json['proofingCity'], + proofing_state: response_as_json['proofingState'], + scan_count: response_as_json['scanCount'], + response_message: response_as_json['responseMessage'], ) end end context 'when an enrollment fails' do - before(:each) do - stub_request_failed_proofing_results - end + let!(:response) { stub_request_failed_proofing_results } it_behaves_like('enrollment with a status update', passed: false, status: 'failed') it 'logs failure details' do job.perform(Time.zone.now) + response_as_json = JSON.parse(response[:body]) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Enrollment status updated', - failure_reason: 'Clerk indicates that ID name or address does not match source data.', - fraud_suspected: false, - primary_id_type: 'Uniformed Services identification card', - proofing_state: 'PA', - reason: 'Failed status', - secondary_id_type: 'Deed of Trust', - transaction_end_date_time: '12/17/2020 034055', - transaction_start_date_time: '12/17/2020 033855', + fraud_suspected: response_as_json['fraudSuspected'], + primary_id_type: response_as_json['primaryIdType'], + secondary_id_type: response_as_json['secondaryIdType'], + failure_reason: response_as_json['failureReason'], + transaction_end_date_time: response_as_json['transactionEndDateTime'], + transaction_start_date_time: response_as_json['transactionStartDateTime'], + status: response_as_json['status'], + assurance_level: response_as_json['assuranceLevel'], + proofing_post_office: response_as_json['proofingPostOffice'], + proofing_city: response_as_json['proofingCity'], + proofing_state: response_as_json['proofingState'], + scan_count: response_as_json['scanCount'], + response_message: response_as_json['responseMessage'], ) end end context 'when an enrollment passes proofing with an unsupported ID' do - before(:each) do - stub_request_passed_proofing_unsupported_id_results - end + let!(:response) { stub_request_passed_proofing_unsupported_id_results } it_behaves_like('enrollment with a status update', passed: false, status: 'failed') it 'logs a message about the unsupported ID' do job.perform Time.zone.now + response_as_json = JSON.parse(response[:body]) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Enrollment status updated', - fraud_suspected: false, - primary_id_type: 'Not supported', reason: 'Unsupported ID type', + fraud_suspected: response_as_json['fraudSuspected'], + primary_id_type: response_as_json['primaryIdType'], + secondary_id_type: response_as_json['secondaryIdType'], + failure_reason: response_as_json['failureReason'], + transaction_end_date_time: response_as_json['transactionEndDateTime'], + transaction_start_date_time: response_as_json['transactionStartDateTime'], + status: response_as_json['status'], + assurance_level: response_as_json['assuranceLevel'], + proofing_post_office: response_as_json['proofingPostOffice'], + proofing_city: response_as_json['proofingCity'], + proofing_state: response_as_json['proofingState'], + scan_count: response_as_json['scanCount'], + response_message: response_as_json['responseMessage'], ) end end context 'when an enrollment expires' do - before(:each) do - stub_request_expired_proofing_results - end + let!(:response) { stub_request_expired_proofing_results } it_behaves_like('enrollment with a status update', passed: false, status: 'expired') it 'logs that the enrollment expired' do job.perform(Time.zone.now) + response_as_json = JSON.parse(response[:body]) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Enrollment status updated', reason: 'Enrollment has expired', + fraud_suspected: nil, + passed: false, + primary_id_type: response_as_json['primaryIdType'], + secondary_id_type: response_as_json['secondaryIdType'], + failure_reason: response_as_json['failureReason'], + transaction_end_date_time: response_as_json['transactionEndDateTime'], + transaction_start_date_time: response_as_json['transactionStartDateTime'], + status: response_as_json['status'], + assurance_level: response_as_json['assuranceLevel'], + proofing_post_office: response_as_json['proofingPostOffice'], + proofing_city: response_as_json['proofingCity'], + proofing_state: response_as_json['proofingState'], + scan_count: response_as_json['scanCount'], + response_message: response_as_json['responseMessage'], ) end end @@ -382,11 +420,32 @@ end context 'when USPS returns an unexpected status' do - before(:each) do - stub_request_passed_proofing_unsupported_status_results - end + let!(:response) { stub_request_passed_proofing_unsupported_status_results } + + it 'logs an error message and leaves the enrollment and profile pending' do + job.perform(Time.zone.now) + pending_enrollment.reload - it_behaves_like('enrollment encountering an exception', reason: 'Unsupported status') + response_as_json = JSON.parse(response[:body]) + expect(job_analytics).to have_logged_event( + 'GetUspsProofingResultsJob: Exception raised', + enrollment_id: pending_enrollment.id, + enrollment_code: pending_enrollment.enrollment_code, + fraud_suspected: response_as_json['fraudSuspected'], + primary_id_type: response_as_json['primaryIdType'], + secondary_id_type: response_as_json['secondaryIdType'], + failure_reason: response_as_json['failureReason'], + transaction_end_date_time: response_as_json['transactionEndDateTime'], + transaction_start_date_time: response_as_json['transactionStartDateTime'], + status: response_as_json['status'], + assurance_level: response_as_json['assuranceLevel'], + proofing_post_office: response_as_json['proofingPostOffice'], + proofing_city: response_as_json['proofingCity'], + proofing_state: response_as_json['proofingState'], + scan_count: response_as_json['scanCount'], + response_message: response_as_json['responseMessage'], + ) + end it 'logs the status received' do job.perform(Time.zone.now) diff --git a/spec/support/usps_ipp_helper.rb b/spec/support/usps_ipp_helper.rb index 2a46b8a17d5..a1416a6b62b 100644 --- a/spec/support/usps_ipp_helper.rb +++ b/spec/support/usps_ipp_helper.rb @@ -40,6 +40,7 @@ def stub_request_expired_proofing_results stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( **request_expired_proofing_results_args, ) + request_expired_proofing_results_args end def request_expired_proofing_results_args @@ -53,6 +54,7 @@ def stub_request_failed_proofing_results stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( **request_failed_proofing_results_args, ) + request_failed_proofing_results_args end def request_failed_proofing_results_args @@ -61,24 +63,33 @@ def request_failed_proofing_results_args end def stub_request_passed_proofing_unsupported_id_results + response = { + status: 200, + body: UspsInPersonProofing::Mock:: + Fixtures.request_passed_proofing_unsupported_id_results_response, + } stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( - status: 200, body: UspsInPersonProofing::Mock::Fixtures. - request_passed_proofing_unsupported_id_results_response + response, ) + response end def stub_request_passed_proofing_unsupported_status_results - stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( + response = { status: 200, - body: UspsInPersonProofing::Mock::Fixtures. - request_passed_proofing_unsupported_status_results_response, + body: UspsInPersonProofing::Mock:: + Fixtures.request_passed_proofing_unsupported_status_results_response } + stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( + response, ) + response end def stub_request_passed_proofing_results stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( **request_passed_proofing_results_args, ) + request_passed_proofing_results_args end def request_passed_proofing_results_args From dc299369fe9f323647d44f85b0d98d3773289546 Mon Sep 17 00:00:00 2001 From: Eileen McFarland Date: Fri, 16 Sep 2022 12:37:42 -0400 Subject: [PATCH 2/7] LG-7275 Expand metrics for USPS proofing attempts changelog: Internal, In-person proofing, expand metrics for proofing attempts --- spec/support/usps_ipp_helper.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/support/usps_ipp_helper.rb b/spec/support/usps_ipp_helper.rb index a1416a6b62b..4030ef947e8 100644 --- a/spec/support/usps_ipp_helper.rb +++ b/spec/support/usps_ipp_helper.rb @@ -78,7 +78,8 @@ def stub_request_passed_proofing_unsupported_status_results response = { status: 200, body: UspsInPersonProofing::Mock:: - Fixtures.request_passed_proofing_unsupported_status_results_response } + Fixtures.request_passed_proofing_unsupported_status_results_response, + } stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( response, ) From 63d66bde5ca1fab4b686c6e6726088c19755268c Mon Sep 17 00:00:00 2001 From: Eileen McFarland Date: Tue, 20 Sep 2022 12:02:37 -0400 Subject: [PATCH 3/7] enumerate params from analytics methods --- app/services/analytics_events.rb | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 64804f71381..b5b79a96b71 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -2521,11 +2521,45 @@ def idv_in_person_usps_proofing_results_job_completed( # @param [String] enrollment_id # @param [String] exception_class # @param [String] exception_message + # @param [String] enrollment_code + # @param [Float] minutes_since_last_status_check + # @param [Float] minutes_since_last_status_update + # @param [Float] minutes_to_completion + # @param [Boolean] fraud_suspected + # @param [String] primary_id_type + # @param [String] secondary_id_type + # @param [String] failure_reason + # @param [String] transaction_end_date_time + # @param [String] transaction_start_date_time + # @param [String] status + # @param [String] assurance_level + # @param [String] proofing_post_office + # @param [String] proofing_city + # @param [String] proofing_state + # @param [String] scan_count + # @param [String] response_message def idv_in_person_usps_proofing_results_job_exception( reason:, enrollment_id:, exception_class: nil, exception_message: nil, + enrollment_code: nil, + minutes_since_last_status_check: nil, + minutes_since_last_status_update: nil, + minutes_to_completion: nil, + fraud_suspected: nil, + primary_id_type: nil, + secondary_id_type: nil, + failure_reason: nil, + transaction_end_date_time: nil, + transaction_start_date_time: nil, + status: nil, + assurance_level: nil, + proofing_post_office: nil, + proofing_city: nil, + proofing_state: nil, + scan_count: nil, + response_message: nil, **extra ) track_event( @@ -2534,6 +2568,23 @@ def idv_in_person_usps_proofing_results_job_exception( enrollment_id: enrollment_id, exception_class: exception_class, exception_message: exception_message, + enrollment_code: enrollment_code, + minutes_since_last_status_check: minutes_since_last_status_check, + minutes_since_last_status_update: minutes_since_last_status_update, + minutes_to_completion: minutes_to_completion, + fraud_suspected: fraud_suspected, + primary_id_type: primary_id_type, + secondary_id_type: secondary_id_type, + failure_reason: failure_reason, + transaction_end_date_time: transaction_end_date_time, + transaction_start_date_time: transaction_start_date_time, + status: status, + assurance_level: assurance_level, + proofing_post_office: proofing_post_office, + proofing_city: proofing_city, + proofing_state: proofing_state, + scan_count: scan_count, + response_message: response_message, **extra, ) end From 689c5bc96313e76a8ebe3b9c3761fd26ba846d1c Mon Sep 17 00:00:00 2001 From: Eileen McFarland Date: Wed, 21 Sep 2022 11:48:19 -0400 Subject: [PATCH 4/7] refactor usps proofing tests to be DRYer --- app/jobs/get_usps_proofing_results_job.rb | 2 + .../usps_in_person_proofing/mock/fixtures.rb | 2 +- ...est_expired_proofing_results_response.json | 28 ++-- .../get_usps_proofing_results_job_spec.rb | 122 +++++++----------- spec/support/usps_ipp_helper.rb | 17 +-- 5 files changed, 64 insertions(+), 107 deletions(-) diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index b2f6d8d0f89..208661bd5cc 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -29,6 +29,7 @@ def enrollment_analytics_attributes(enrollment, complete:) end def response_analytics_attributes(response) + # binding.pry { fraud_suspected: response['fraudSuspected'], primary_id_type: response['primaryIdType'], @@ -181,6 +182,7 @@ def handle_unsupported_id_type(enrollment, response) end def handle_expired_status_update(enrollment, response) + # binding.pry enrollment_outcomes[:enrollments_expired] += 1 analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_enrollment_updated( **enrollment_analytics_attributes(enrollment, complete: true), diff --git a/app/services/usps_in_person_proofing/mock/fixtures.rb b/app/services/usps_in_person_proofing/mock/fixtures.rb index 95d80dacde3..aa52b4866c2 100644 --- a/app/services/usps_in_person_proofing/mock/fixtures.rb +++ b/app/services/usps_in_person_proofing/mock/fixtures.rb @@ -53,7 +53,7 @@ def self.request_passed_proofing_results_response load_response_fixture('request_passed_proofing_results_response.json') end - def self.request_passed_proofing_unsupported_status_results_response + def self.request_passed_proofing_unsupported_status_response load_response_fixture('request_passed_proofing_unsupported_status_results_response.json') end diff --git a/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json b/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json index c2622f1df7e..12b814be6eb 100644 --- a/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json +++ b/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json @@ -1,15 +1,15 @@ { - "status": "In-person expired", - "proofingPostOffice": "WILKES BARRE", - "proofingCity": "WILKES BARRE", - "proofingState": "PA", - "enrollmentCode": "2090002197604352", - "primaryIdType": "Uniformed Services identification card", - "transactionStartDateTime": "12/17/2020 033855", - "transactionEndDateTime": "12/17/2020 034055", - "secondaryIdType": "Deed of Trust", - "responseMessage": "More than 30 days have passed since opt-in to IPP", - "fraudSuspected": false, - "proofingConfirmationNumber": "350040248346707", - "ippAssuranceLevel": "1.5" -} \ No newline at end of file + "status": "In-person expired", + "proofingPostOffice": "WILKES BARRE", + "proofingCity": "WILKES BARRE", + "proofingState": "PA", + "enrollmentCode": "2090002197604352", + "primaryIdType": "Uniformed Services identification card", + "transactionStartDateTime": "12/17/2020 033855", + "transactionEndDateTime": "12/17/2020 034055", + "secondaryIdType": "Deed of Trust", + "responseMessage": "More than 30 days have passed since opt-in to IPP", + "fraudSuspected": null, + "proofingConfirmationNumber": "350040248346707", + "ippAssuranceLevel": "1.5" +} diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb index fdc2332a9b6..84283e7b174 100644 --- a/spec/jobs/get_usps_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_proofing_results_job_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.shared_examples 'enrollment with a status update' do |passed:, status:| +RSpec.shared_examples 'enrollment with a status update' do |passed:, status:, response_json:| it 'logs a message with common attributes' do freeze_time do pending_enrollment.update( @@ -12,14 +12,28 @@ job.perform(Time.zone.now) end + response = JSON.parse(response_json) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Enrollment status updated', + assurance_level: response['assuranceLevel'], enrollment_code: pending_enrollment.enrollment_code, enrollment_id: pending_enrollment.id, + failure_reason: response['failureReason'], + fraud_suspected: response['fraudSuspected'], minutes_since_last_status_check: 15.0, minutes_since_last_status_update: 2.days.in_minutes, minutes_to_completion: 3.days.in_minutes, passed: passed, + primary_id_type: response['primaryIdType'], + proofing_city: response['proofingCity'], + proofing_post_office: response['proofingPostOffice'], + proofing_state: response['proofingState'], + response_message: response['responseMessage'], + scan_count: response['scanCount'], + secondary_id_type: response['secondaryIdType'], + status: response['status'], + transaction_end_date_time: response['transactionEndDateTime'], + transaction_start_date_time: response['transactionStartDateTime'], ) end @@ -44,7 +58,8 @@ RSpec.shared_examples 'enrollment encountering an exception' do |exception_class: nil, exception_message: nil, - reason: 'Request exception'| + reason: 'Request exception', + response_json: {}| it 'logs an error message and leaves the enrollment and profile pending' do job.perform(Time.zone.now) pending_enrollment.reload @@ -298,28 +313,18 @@ context 'when an enrollment passes' do let!(:response) { stub_request_passed_proofing_results } - it_behaves_like('enrollment with a status update', passed: true, status: 'passed') + it_behaves_like( + 'enrollment with a status update', passed: true, status: 'passed', + response_json: UspsInPersonProofing::Mock::Fixtures. + request_passed_proofing_results_response + ) it 'logs details about the success' do job.perform(Time.zone.now) - response_as_json = JSON.parse(response[:body]) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Enrollment status updated', reason: 'Successful status update', - fraud_suspected: response_as_json['fraudSuspected'], - primary_id_type: response_as_json['primaryIdType'], - secondary_id_type: response_as_json['secondaryIdType'], - failure_reason: response_as_json['failureReason'], - transaction_end_date_time: response_as_json['transactionEndDateTime'], - transaction_start_date_time: response_as_json['transactionStartDateTime'], - status: response_as_json['status'], - assurance_level: response_as_json['assuranceLevel'], - proofing_post_office: response_as_json['proofingPostOffice'], - proofing_city: response_as_json['proofingCity'], - proofing_state: response_as_json['proofingState'], - scan_count: response_as_json['scanCount'], - response_message: response_as_json['responseMessage'], ) end end @@ -327,27 +332,17 @@ context 'when an enrollment fails' do let!(:response) { stub_request_failed_proofing_results } - it_behaves_like('enrollment with a status update', passed: false, status: 'failed') + it_behaves_like( + 'enrollment with a status update', passed: false, status: 'failed', + response_json: UspsInPersonProofing::Mock::Fixtures. + request_failed_proofing_results_response + ) it 'logs failure details' do job.perform(Time.zone.now) - response_as_json = JSON.parse(response[:body]) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Enrollment status updated', - fraud_suspected: response_as_json['fraudSuspected'], - primary_id_type: response_as_json['primaryIdType'], - secondary_id_type: response_as_json['secondaryIdType'], - failure_reason: response_as_json['failureReason'], - transaction_end_date_time: response_as_json['transactionEndDateTime'], - transaction_start_date_time: response_as_json['transactionStartDateTime'], - status: response_as_json['status'], - assurance_level: response_as_json['assuranceLevel'], - proofing_post_office: response_as_json['proofingPostOffice'], - proofing_city: response_as_json['proofingCity'], - proofing_state: response_as_json['proofingState'], - scan_count: response_as_json['scanCount'], - response_message: response_as_json['responseMessage'], ) end end @@ -355,28 +350,18 @@ context 'when an enrollment passes proofing with an unsupported ID' do let!(:response) { stub_request_passed_proofing_unsupported_id_results } - it_behaves_like('enrollment with a status update', passed: false, status: 'failed') + it_behaves_like( + 'enrollment with a status update', passed: false, status: 'failed', + response_json: UspsInPersonProofing::Mock::Fixtures. + request_passed_proofing_unsupported_id_results_response + ) it 'logs a message about the unsupported ID' do job.perform Time.zone.now - response_as_json = JSON.parse(response[:body]) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Enrollment status updated', reason: 'Unsupported ID type', - fraud_suspected: response_as_json['fraudSuspected'], - primary_id_type: response_as_json['primaryIdType'], - secondary_id_type: response_as_json['secondaryIdType'], - failure_reason: response_as_json['failureReason'], - transaction_end_date_time: response_as_json['transactionEndDateTime'], - transaction_start_date_time: response_as_json['transactionStartDateTime'], - status: response_as_json['status'], - assurance_level: response_as_json['assuranceLevel'], - proofing_post_office: response_as_json['proofingPostOffice'], - proofing_city: response_as_json['proofingCity'], - proofing_state: response_as_json['proofingState'], - scan_count: response_as_json['scanCount'], - response_message: response_as_json['responseMessage'], ) end end @@ -384,29 +369,18 @@ context 'when an enrollment expires' do let!(:response) { stub_request_expired_proofing_results } - it_behaves_like('enrollment with a status update', passed: false, status: 'expired') + it_behaves_like( + 'enrollment with a status update', passed: false, status: 'expired', + response_json: UspsInPersonProofing::Mock::Fixtures. + request_expired_proofing_results_response + ) it 'logs that the enrollment expired' do job.perform(Time.zone.now) - response_as_json = JSON.parse(response[:body]) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Enrollment status updated', reason: 'Enrollment has expired', - fraud_suspected: nil, - passed: false, - primary_id_type: response_as_json['primaryIdType'], - secondary_id_type: response_as_json['secondaryIdType'], - failure_reason: response_as_json['failureReason'], - transaction_end_date_time: response_as_json['transactionEndDateTime'], - transaction_start_date_time: response_as_json['transactionStartDateTime'], - status: response_as_json['status'], - assurance_level: response_as_json['assuranceLevel'], - proofing_post_office: response_as_json['proofingPostOffice'], - proofing_city: response_as_json['proofingCity'], - proofing_state: response_as_json['proofingState'], - scan_count: response_as_json['scanCount'], - response_message: response_as_json['responseMessage'], ) end end @@ -416,7 +390,13 @@ stub_request_proofing_results_with_responses({}) end - it_behaves_like('enrollment encountering an exception', reason: 'Bad response structure') + it_behaves_like( + 'enrollment encountering an exception', + reason: 'Bad response structure', + response_json: UspsInPersonProofing:: + Mock::Fixtures. + request_passed_proofing_unsupported_status_response, + ) end context 'when USPS returns an unexpected status' do @@ -426,24 +406,10 @@ job.perform(Time.zone.now) pending_enrollment.reload - response_as_json = JSON.parse(response[:body]) expect(job_analytics).to have_logged_event( 'GetUspsProofingResultsJob: Exception raised', enrollment_id: pending_enrollment.id, enrollment_code: pending_enrollment.enrollment_code, - fraud_suspected: response_as_json['fraudSuspected'], - primary_id_type: response_as_json['primaryIdType'], - secondary_id_type: response_as_json['secondaryIdType'], - failure_reason: response_as_json['failureReason'], - transaction_end_date_time: response_as_json['transactionEndDateTime'], - transaction_start_date_time: response_as_json['transactionStartDateTime'], - status: response_as_json['status'], - assurance_level: response_as_json['assuranceLevel'], - proofing_post_office: response_as_json['proofingPostOffice'], - proofing_city: response_as_json['proofingCity'], - proofing_state: response_as_json['proofingState'], - scan_count: response_as_json['scanCount'], - response_message: response_as_json['responseMessage'], ) end diff --git a/spec/support/usps_ipp_helper.rb b/spec/support/usps_ipp_helper.rb index 4030ef947e8..a53da3cd87e 100644 --- a/spec/support/usps_ipp_helper.rb +++ b/spec/support/usps_ipp_helper.rb @@ -40,7 +40,6 @@ def stub_request_expired_proofing_results stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( **request_expired_proofing_results_args, ) - request_expired_proofing_results_args end def request_expired_proofing_results_args @@ -54,7 +53,6 @@ def stub_request_failed_proofing_results stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( **request_failed_proofing_results_args, ) - request_failed_proofing_results_args end def request_failed_proofing_results_args @@ -63,34 +61,25 @@ def request_failed_proofing_results_args end def stub_request_passed_proofing_unsupported_id_results - response = { + stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( status: 200, body: UspsInPersonProofing::Mock:: Fixtures.request_passed_proofing_unsupported_id_results_response, - } - stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( - response, ) - response end def stub_request_passed_proofing_unsupported_status_results - response = { + stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( status: 200, body: UspsInPersonProofing::Mock:: - Fixtures.request_passed_proofing_unsupported_status_results_response, - } - stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( - response, + Fixtures.request_passed_proofing_unsupported_status_response, ) - response end def stub_request_passed_proofing_results stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( **request_passed_proofing_results_args, ) - request_passed_proofing_results_args end def request_passed_proofing_results_args From 25ca8a9282d4df813f39dcab459c6923347fac7d Mon Sep 17 00:00:00 2001 From: Eileen McFarland Date: Wed, 21 Sep 2022 13:47:32 -0400 Subject: [PATCH 5/7] clean up usps proofing job and spec --- app/jobs/get_usps_proofing_results_job.rb | 2 -- .../get_usps_proofing_results_job_spec.rb | 36 +++++++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index 208661bd5cc..b2f6d8d0f89 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -29,7 +29,6 @@ def enrollment_analytics_attributes(enrollment, complete:) end def response_analytics_attributes(response) - # binding.pry { fraud_suspected: response['fraudSuspected'], primary_id_type: response['primaryIdType'], @@ -182,7 +181,6 @@ def handle_unsupported_id_type(enrollment, response) end def handle_expired_status_update(enrollment, response) - # binding.pry enrollment_outcomes[:enrollments_expired] += 1 analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_enrollment_updated( **enrollment_analytics_attributes(enrollment, complete: true), diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb index 84283e7b174..d2e1ecb2aab 100644 --- a/spec/jobs/get_usps_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_proofing_results_job_spec.rb @@ -311,7 +311,9 @@ end context 'when an enrollment passes' do - let!(:response) { stub_request_passed_proofing_results } + before(:each) do + stub_request_passed_proofing_results + end it_behaves_like( 'enrollment with a status update', passed: true, status: 'passed', @@ -330,7 +332,9 @@ end context 'when an enrollment fails' do - let!(:response) { stub_request_failed_proofing_results } + before(:each) do + stub_request_failed_proofing_results + end it_behaves_like( 'enrollment with a status update', passed: false, status: 'failed', @@ -348,7 +352,9 @@ end context 'when an enrollment passes proofing with an unsupported ID' do - let!(:response) { stub_request_passed_proofing_unsupported_id_results } + before(:each) do + stub_request_passed_proofing_unsupported_id_results + end it_behaves_like( 'enrollment with a status update', passed: false, status: 'failed', @@ -367,7 +373,9 @@ end context 'when an enrollment expires' do - let!(:response) { stub_request_expired_proofing_results } + before(:each) do + stub_request_expired_proofing_results + end it_behaves_like( 'enrollment with a status update', passed: false, status: 'expired', @@ -400,19 +408,17 @@ end context 'when USPS returns an unexpected status' do - let!(:response) { stub_request_passed_proofing_unsupported_status_results } - - it 'logs an error message and leaves the enrollment and profile pending' do - job.perform(Time.zone.now) - pending_enrollment.reload - - expect(job_analytics).to have_logged_event( - 'GetUspsProofingResultsJob: Exception raised', - enrollment_id: pending_enrollment.id, - enrollment_code: pending_enrollment.enrollment_code, - ) + before(:each) do + stub_request_passed_proofing_unsupported_status_results end + it_behaves_like( + 'enrollment encountering an exception', + reason: 'Unsupported status', + response_json: UspsInPersonProofing::Mock:: + Fixtures.request_passed_proofing_unsupported_status_response, + ) + it 'logs the status received' do job.perform(Time.zone.now) pending_enrollment.reload From ae8baf4851b27d36284a4c585219f91891b2241a Mon Sep 17 00:00:00 2001 From: Eileen McFarland Date: Thu, 22 Sep 2022 12:14:44 -0400 Subject: [PATCH 6/7] tweak fixtures for expired id & unsupported status --- app/jobs/get_usps_proofing_results_job.rb | 1 - app/services/usps_in_person_proofing/mock/fixtures.rb | 2 +- .../responses/request_expired_proofing_results_response.json | 2 +- spec/jobs/get_usps_proofing_results_job_spec.rb | 4 ++-- spec/support/usps_ipp_helper.rb | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index b2f6d8d0f89..049938d5d0f 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -185,7 +185,6 @@ def handle_expired_status_update(enrollment, response) analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_enrollment_updated( **enrollment_analytics_attributes(enrollment, complete: true), **response_analytics_attributes(response[:body]), - fraud_suspected: nil, passed: false, reason: 'Enrollment has expired', ) diff --git a/app/services/usps_in_person_proofing/mock/fixtures.rb b/app/services/usps_in_person_proofing/mock/fixtures.rb index aa52b4866c2..95d80dacde3 100644 --- a/app/services/usps_in_person_proofing/mock/fixtures.rb +++ b/app/services/usps_in_person_proofing/mock/fixtures.rb @@ -53,7 +53,7 @@ def self.request_passed_proofing_results_response load_response_fixture('request_passed_proofing_results_response.json') end - def self.request_passed_proofing_unsupported_status_response + def self.request_passed_proofing_unsupported_status_results_response load_response_fixture('request_passed_proofing_unsupported_status_results_response.json') end diff --git a/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json b/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json index 12b814be6eb..433f80ca7ac 100644 --- a/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json +++ b/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json @@ -9,7 +9,7 @@ "transactionEndDateTime": "12/17/2020 034055", "secondaryIdType": "Deed of Trust", "responseMessage": "More than 30 days have passed since opt-in to IPP", - "fraudSuspected": null, + "fraudSuspected": false, "proofingConfirmationNumber": "350040248346707", "ippAssuranceLevel": "1.5" } diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb index d2e1ecb2aab..531f0686c32 100644 --- a/spec/jobs/get_usps_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_proofing_results_job_spec.rb @@ -403,7 +403,7 @@ reason: 'Bad response structure', response_json: UspsInPersonProofing:: Mock::Fixtures. - request_passed_proofing_unsupported_status_response, + request_passed_proofing_unsupported_status_results_response, ) end @@ -416,7 +416,7 @@ 'enrollment encountering an exception', reason: 'Unsupported status', response_json: UspsInPersonProofing::Mock:: - Fixtures.request_passed_proofing_unsupported_status_response, + Fixtures.request_passed_proofing_unsupported_status_results_response, ) it 'logs the status received' do diff --git a/spec/support/usps_ipp_helper.rb b/spec/support/usps_ipp_helper.rb index a53da3cd87e..6dd73f8bdf1 100644 --- a/spec/support/usps_ipp_helper.rb +++ b/spec/support/usps_ipp_helper.rb @@ -72,7 +72,7 @@ def stub_request_passed_proofing_unsupported_status_results stub_request(:post, %r{/ivs-ippaas-api/IPPRest/resources/rest/getProofingResults}).to_return( status: 200, body: UspsInPersonProofing::Mock:: - Fixtures.request_passed_proofing_unsupported_status_response, + Fixtures.request_passed_proofing_unsupported_status_results_response, ) end From a94dbd7a47bebe16d78b8b66d043f1878162b2da Mon Sep 17 00:00:00 2001 From: Eileen McFarland Date: Thu, 22 Sep 2022 15:29:08 -0400 Subject: [PATCH 7/7] clean up formatting and fixture --- ...est_expired_proofing_results_response.json | 14 +------ .../get_usps_proofing_results_job_spec.rb | 40 ++++++++++--------- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json b/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json index 433f80ca7ac..7f01924ad96 100644 --- a/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json +++ b/app/services/usps_in_person_proofing/mock/responses/request_expired_proofing_results_response.json @@ -1,15 +1,3 @@ { - "status": "In-person expired", - "proofingPostOffice": "WILKES BARRE", - "proofingCity": "WILKES BARRE", - "proofingState": "PA", - "enrollmentCode": "2090002197604352", - "primaryIdType": "Uniformed Services identification card", - "transactionStartDateTime": "12/17/2020 033855", - "transactionEndDateTime": "12/17/2020 034055", - "secondaryIdType": "Deed of Trust", - "responseMessage": "More than 30 days have passed since opt-in to IPP", - "fraudSuspected": false, - "proofingConfirmationNumber": "350040248346707", - "ippAssuranceLevel": "1.5" + "responseMessage": "More than 30 days have passed since opt-in to IPP" } diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb index 531f0686c32..802df0d0819 100644 --- a/spec/jobs/get_usps_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_proofing_results_job_spec.rb @@ -58,8 +58,7 @@ RSpec.shared_examples 'enrollment encountering an exception' do |exception_class: nil, exception_message: nil, - reason: 'Request exception', - response_json: {}| + reason: 'Request exception'| it 'logs an error message and leaves the enrollment and profile pending' do job.perform(Time.zone.now) pending_enrollment.reload @@ -316,9 +315,11 @@ end it_behaves_like( - 'enrollment with a status update', passed: true, status: 'passed', - response_json: UspsInPersonProofing::Mock::Fixtures. - request_passed_proofing_results_response + 'enrollment with a status update', + passed: true, + status: 'passed', + response_json: UspsInPersonProofing::Mock::Fixtures. + request_passed_proofing_results_response, ) it 'logs details about the success' do @@ -337,9 +338,11 @@ end it_behaves_like( - 'enrollment with a status update', passed: false, status: 'failed', - response_json: UspsInPersonProofing::Mock::Fixtures. - request_failed_proofing_results_response + 'enrollment with a status update', + passed: false, + status: 'failed', + response_json: UspsInPersonProofing::Mock::Fixtures. + request_failed_proofing_results_response, ) it 'logs failure details' do @@ -357,9 +360,11 @@ end it_behaves_like( - 'enrollment with a status update', passed: false, status: 'failed', - response_json: UspsInPersonProofing::Mock::Fixtures. - request_passed_proofing_unsupported_id_results_response + 'enrollment with a status update', + passed: false, + status: 'failed', + response_json: UspsInPersonProofing::Mock::Fixtures. + request_passed_proofing_unsupported_id_results_response, ) it 'logs a message about the unsupported ID' do @@ -378,9 +383,11 @@ end it_behaves_like( - 'enrollment with a status update', passed: false, status: 'expired', - response_json: UspsInPersonProofing::Mock::Fixtures. - request_expired_proofing_results_response + 'enrollment with a status update', + passed: false, + status: 'expired', + response_json: UspsInPersonProofing::Mock::Fixtures. + request_expired_proofing_results_response, ) it 'logs that the enrollment expired' do @@ -401,9 +408,6 @@ it_behaves_like( 'enrollment encountering an exception', reason: 'Bad response structure', - response_json: UspsInPersonProofing:: - Mock::Fixtures. - request_passed_proofing_unsupported_status_results_response, ) end @@ -415,8 +419,6 @@ it_behaves_like( 'enrollment encountering an exception', reason: 'Unsupported status', - response_json: UspsInPersonProofing::Mock:: - Fixtures.request_passed_proofing_unsupported_status_results_response, ) it 'logs the status received' do