LG-7275 Expand metrics for USPS proofing attempts#6967
Conversation
ccf6192 to
ea826da
Compare
changelog: Internal, In-person proofing, expand metrics for proofing attempts
ea826da to
dc29936
Compare
|
can you link the ticket in the summary? |
Thanks for noting that. I linked the ticket in the summary. |
| 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'], |
There was a problem hiding this comment.
Could we move this all to the 'enrollment with a status update' shared example by doing this?
before do
stub_request_passed_proofing_results
end
it_behaves_like(
'enrollment with a status update',
passed: true,
response_json: UspsInPersonProofing::Mock::Fixtures.request_passed_proofing_results_response,
status: 'passed',
)
And then in the shared example we could do this:
RSpec.shared_examples 'enrollment with a status update' do |passed:, status:, response_json:|
it 'logs a message with common attributes' do
<...omitted code...>
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
And we could then use that shared example for most the test cases where you've added these checks. I like this approach because the shared examples already check for logged attributes and this would reduce a lot of similar looking lines of test code. And then we could revert the changes to usps_ipp_helper.rb
| 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'], |
There was a problem hiding this comment.
IMO I think all this switching of cases might be a good hint to move the processing of the response to the USPS proofer client class, have it return a Struct or equivalent object that has snake_case keys already (similar to https://cm-jira.usa.gov/browse/LG-7025)
There was a problem hiding this comment.
Thanks for raising this point! I will make another ticket to address it.
|
Heads-up: This PR is not ready for re-review. I will post when it is. Almost there! |
| 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'], |
There was a problem hiding this comment.
Thanks for raising this point! I will make another ticket to address it.
| end | ||
|
|
||
| def self.request_passed_proofing_unsupported_status_results_response | ||
| def self.request_passed_proofing_unsupported_status_response |
There was a problem hiding this comment.
I shortened this method name because it set off rubocop's "line too long" check. I realize that the method name is no longer consistent with the many self.foo_results_response methods in this file. I thought about renaming those methods to self.foo_response, but decided to prioritize making the smallest change possible.
If other folks think it's worth it to refactor the self.foo_results_response methods to self.foo_response, please give a shout.
There was a problem hiding this comment.
There's a lot of ways we can work around the Rubocop restriction, and I'd personally prefer to pursue those before choosing renaming the method, or at least when we'd be introducing inconsistency by doing so (like you mentioned).
Example:
it_behaves_like(
'enrollment encountering an exception',
reason: 'Bad response structure',
response_json: UspsInPersonProofing::Mock::Fixtures.
request_passed_proofing_unsupported_status_result_response,
)There was a problem hiding this comment.
Agreed. I'll take the approach you suggest.
| "transactionEndDateTime": "12/17/2020 034055", | ||
| "secondaryIdType": "Deed of Trust", | ||
| "responseMessage": "More than 30 days have passed since opt-in to IPP", | ||
| "fraudSuspected": null, |
There was a problem hiding this comment.
I changed this value because I don't think we'd suspect fraud for an expired id. Also, the related method, handle_expired_status_update, has the parameter fraud_suspected: nil for the method idv_in_person_usps_proofing_results_job_enrollment_updated.
There was a problem hiding this comment.
The USPS API documentation specifies that this field would only ever be true or false, so I think the fixtures should reflect the values we'd actually expect.
(Aside: Curious if these fixtures were provided to us by USPS directly. Their documentation claims the type of this field is a String of true or false, so I'm curious if that means true and false, or if it means "true" and "false". The previous fixture code would imply the former.)
There was a problem hiding this comment.
I just checked in dev where we have some expired enrollments -- the USPS response body is this:
{"responseMessage"=>"More than 30 days have passed since opt-in to IPP"}
There was a problem hiding this comment.
While I'm there I checked on the value of fraud_suspected for a passed enrollment. Looks like it returns the value as a boolean:
"fraudSuspected"=>false,
There was a problem hiding this comment.
Can we update the expired mock response json value to match that actual response I got back @eileen-nava?
There was a problem hiding this comment.
Absolutely! I'll update the expired mock response json value to match that actual response. Thanks for pointing this out, @aduth and @sheldon-b.
|
This PR is ready for re-review. Thanks for everyone who provided feedback so far. |
|
Update: I responded to the most recent round of feedback. |
sheldon-b
left a comment
There was a problem hiding this comment.
Nice! Looking good. I have a few more comments, mostly minor styling things that would be nice to enforce with a linter (separate PR/ticket, not asking you to do that)
| "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" | ||
| } |
There was a problem hiding this comment.
Per this comment I suggest deleting most of these fields because USPS doesn't actually return them for expired enrollments
| "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" | |
| } |
| reason: 'Request exception'| | ||
| reason: 'Request exception', | ||
| response_json: {}| |
There was a problem hiding this comment.
Doesn't look like response_json is used in these shared examples. Should we revert this change?
| it_behaves_like( | ||
| 'enrollment with a status update', passed: true, status: 'passed', | ||
| response_json: UspsInPersonProofing::Mock::Fixtures. | ||
| request_passed_proofing_results_response | ||
| ) |
There was a problem hiding this comment.
I believe this style is more consistent with the rest of the codebase (and a little easier to read imo). I think I'll see if there's a rubocop rule to enforce this better in a separate PR
Similar comment for the other places below with the same styling
| it_behaves_like( | |
| 'enrollment with a status update', passed: true, status: 'passed', | |
| response_json: UspsInPersonProofing::Mock::Fixtures. | |
| request_passed_proofing_results_response | |
| ) | |
| it_behaves_like( | |
| 'enrollment with a status update', | |
| passed: true, | |
| status: 'passed', | |
| response_json: UspsInPersonProofing::Mock::Fixtures. | |
| request_passed_proofing_results_response | |
| ) |
| 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', |
Resolves jira ticket #7275: Collect consistent USPS proofing attempt metrics
Summary
This PR increases the metrics that are collected during USPS proofing attempts. It includes a new method,
response_analytics_attributes, which logs the below attributes during both successful and unsuccessful proofing attempts:The above attributes will not be logged for all USPS proofing attempts that raise exceptions. For example, if there is an exception where the response is not in hash format, then these attributes won't be logged.