Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#91156 [10-10EZR]: Update submission failure notifications and add user initials to successful submissions #18348

Merged
merged 9 commits into from
Sep 10, 2024
10 changes: 4 additions & 6 deletions app/sidekiq/hca/ezr_submission_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ class EzrSubmissionJob
sidekiq_options retry: 14

sidekiq_retries_exhausted do |msg, _e|
log_submission_failure(decrypt_form(msg['args'][0]))
end

def self.log_submission_failure(parsed_form)
Form1010Ezr::Service.new(nil).log_submission_failure(parsed_form)
Form1010Ezr::Service.new(nil).log_exhausted_submission_failure(
JoshingYou1 marked this conversation as resolved.
Show resolved Hide resolved
decrypt_form(msg['args'][0])
)
end

def self.decrypt_form(encrypted_form)
Expand All @@ -29,7 +27,7 @@ def perform(encrypted_form, user_uuid)

Form1010Ezr::Service.new(user).submit_sync(parsed_form)
rescue VALIDATION_ERROR => e
self.class.log_submission_failure(parsed_form)
Form1010Ezr::Service.new(nil).log_submission_failure(parsed_form)
JoshingYou1 marked this conversation as resolved.
Show resolved Hide resolved
log_exception_to_sentry(e)
rescue
StatsD.increment("#{Form1010Ezr::Service::STATSD_KEY_PREFIX}.async.retries")
Expand Down
39 changes: 33 additions & 6 deletions lib/form1010_ezr/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@
end

# Log the 'formSubmissionId' for successful submissions
Rails.logger.info("SubmissionID=#{res[:formSubmissionId]}")
Rails.logger.info(
'1010EZR successfully submitted',
JoshingYou1 marked this conversation as resolved.
Show resolved Hide resolved
submission_id: res[:formSubmissionId],
veteran_initials: veteran_initials(parsed_form)
)

res
rescue => e
Expand All @@ -61,6 +65,25 @@
end

def log_submission_failure(parsed_form)
StatsD.increment("#{Form1010Ezr::Service::STATSD_KEY_PREFIX}.failed")

if parsed_form.present?
PersonalInformationLog.create!(
data: parsed_form,
Fixed Show fixed Hide fixed

Check failure

Code scanning / CodeQL

Clear-text storage of sensitive information High

This stores sensitive data returned by
a write to veteranDateOfBirth
as clear text.
This stores sensitive data returned by
a write to veteranSocialSecurityNumber
as clear text.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please confirm this is intended and is not a security issue?

error_class: 'Form1010Ezr Failed'
)

log_message_to_sentry(
'1010EZR failure',
:error,
veteran_initials(parsed_form),
ezr: :failure
)
end
end

# When a submission runs out of retry attempts
def log_exhausted_submission_failure(parsed_form)
StatsD.increment("#{Form1010Ezr::Service::STATSD_KEY_PREFIX}.failed_wont_retry")

if parsed_form.present?
Expand All @@ -72,11 +95,7 @@
log_message_to_sentry(
'1010EZR total failure',
:error,
{
first_initial: parsed_form.dig('veteranFullName', 'first')&.chr || 'no initial provided',
middle_initial: parsed_form.dig('veteranFullName', 'middle')&.chr || 'no initial provided',
last_initial: parsed_form.dig('veteranFullName', 'last')&.chr || 'no initial provided'
},
veteran_initials(parsed_form),
ezr: :total_failure
)
end
Expand Down Expand Up @@ -174,5 +193,13 @@
Rails.logger.error "10-10EZR form submission failed: #{error.message}"
raise error
end

def veteran_initials(parsed_form)
JoshingYou1 marked this conversation as resolved.
Show resolved Hide resolved
{
first_initial: parsed_form.dig('veteranFullName', 'first')&.chr || 'no initial provided',
middle_initial: parsed_form.dig('veteranFullName', 'middle')&.chr || 'no initial provided',
last_initial: parsed_form.dig('veteranFullName', 'last')&.chr || 'no initial provided'
}
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DRY'd up this piece of code.

end
end
92 changes: 87 additions & 5 deletions spec/lib/form1010_ezr/service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ def ezr_form_with_attachments
)
end

def expect_personal_info_log(message)
pii_log = PersonalInformationLog.last

expect(pii_log.error_class).to eq(message)
expect(pii_log.data).to eq(form)
end

describe '#add_financial_flag' do
context 'when the form has veteran gross income' do
let(:parsed_form) do
Expand Down Expand Up @@ -91,12 +98,13 @@ def ezr_form_with_attachments
'hca/ee/lookup_user',
VCR::MATCH_EVERYTHING.merge(erb: true)
) do
expect(form['isEssentialAcaCoverage']).to eq(nil)
expect(form['vaMedicalFacility']).to eq(nil)
expect(form.keys).not_to include('isEssentialAcaCoverage', 'vaMedicalFacility')

service.send(:post_fill_required_fields, form)

expect(form.keys).to include('isEssentialAcaCoverage', 'vaMedicalFacility')
expect(form['isEssentialAcaCoverage']).to eq(false)
expect(form['vaMedicalFacility']).to eq('988')
end
end
end
Expand Down Expand Up @@ -156,6 +164,71 @@ def ezr_form_with_attachments
end
end

describe '#log_submission_failure' do
context "when 'parsed_form' is not present" do
it 'only increments StatsD' do
allow(StatsD).to receive(:increment)
expect(StatsD).to receive(:increment).with('api.1010ezr.failed')

described_class.new(nil).log_submission_failure(nil)
end
end

context "when 'parsed_form' is present" do
it "increments StatsD, creates a 'PersonalInformationLog' record, and logs a failure message to sentry" do
allow(StatsD).to receive(:increment)
expect(StatsD).to receive(:increment).with('api.1010ezr.failed')
expect_any_instance_of(SentryLogging).to receive(:log_message_to_sentry).with(
'1010EZR failure',
:error,
{
first_initial: 'F',
middle_initial: 'M',
last_initial: 'Z'
},
ezr: :failure
)

described_class.new(nil).log_submission_failure(form)

expect_personal_info_log('Form1010Ezr Failed')
end
end
end

describe '#log_exhausted_submission_failure' do
context "when 'parsed_form' is not present" do
it 'only increments StatsD' do
allow(StatsD).to receive(:increment)
expect(StatsD).to receive(:increment).with('api.1010ezr.failed_wont_retry')

described_class.new(nil).log_exhausted_submission_failure(nil)
end
end

context "when 'parsed_form' is present" do
it "increments StatsD, creates a 'PersonalInformationLog' record, and logs a failure message to sentry" do
allow(StatsD).to receive(:increment)

expect(StatsD).to receive(:increment).with('api.1010ezr.failed_wont_retry')
expect_any_instance_of(SentryLogging).to receive(:log_message_to_sentry).with(
'1010EZR total failure',
:error,
{
first_initial: 'F',
middle_initial: 'M',
last_initial: 'Z'
},
ezr: :total_failure
)

described_class.new(nil).log_exhausted_submission_failure(form)

expect_personal_info_log('Form1010Ezr FailedWontRetry')
end
end
end

describe '#submit_form' do
it 'submits the ezr with a background job', run_at: 'Tue, 21 Nov 2023 20:42:44 GMT' do
VCR.use_cassette(
Expand Down Expand Up @@ -260,7 +333,7 @@ def ezr_form_with_attachments
it 'increments StatsD as well as logs and raises the error' do
allow(StatsD).to receive(:increment)

expect(StatsD).to receive(:increment).with('api.1010ezr.failed_wont_retry')
expect(StatsD).to receive(:increment).with('api.1010ezr.failed')
expect { submit_form(form) }.to raise_error(
StandardError, 'Uh oh. Some bad error occurred.'
)
Expand Down Expand Up @@ -310,15 +383,24 @@ def ezr_form_with_attachments
end
end

it 'logs the submission id, payload size, and individual attachment sizes in descending order (if applicable)',
it "logs the submission id, user's initials, payload size, and individual attachment sizes in descending " \
'order (if applicable)',
run_at: 'Wed, 17 Jul 2024 18:17:30 GMT' do
VCR.use_cassette(
'form1010_ezr/authorized_submit_with_attachments',
{ match_requests_on: %i[method uri body], erb: true }
) do
submission_response = service.submit_sync(ezr_form_with_attachments)

expect(Rails.logger).to have_received(:info).with("SubmissionID=#{submission_response[:formSubmissionId]}")
expect(Rails.logger).to have_received(:info).with(
'1010EZR successfully submitted',
submission_id: submission_response[:formSubmissionId],
veteran_initials: {
first_initial: 'F',
middle_initial: 'M',
last_initial: 'Z'
}
)
expect(Rails.logger).to have_received(:info).with('Payload for submitted 1010EZR: ' \
'Body size of 362 KB with 2 attachment(s)')
expect(Rails.logger).to have_received(:info).with(
Expand Down
25 changes: 19 additions & 6 deletions spec/sidekiq/hca/ezr_submission_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,31 @@
end
let(:ezr_service) { double }

describe 'when job has failed' do
describe 'when retries are exhausted' do
let(:msg) do
{
'args' => [encrypted_form, nil]
}
end

it 'passes unencrypted form to 1010ezr service' do
expect_any_instance_of(Form1010Ezr::Service).to receive(:log_submission_failure).with(
form
)
described_class.new.sidekiq_retries_exhausted_block.call(msg)
it "increments StatsD, creates a 'PersonalInformationLog' record, and logs a failure message to sentry" do
described_class.within_sidekiq_retries_exhausted_block(msg) do
expect(StatsD).to receive(:increment).with('api.1010ezr.failed_wont_retry')
expect_any_instance_of(SentryLogging).to receive(:log_message_to_sentry).with(
'1010EZR total failure',
:error,
{
first_initial: 'F',
middle_initial: 'M',
last_initial: 'Z'
},
ezr: :total_failure
)
end

pii_log = PersonalInformationLog.last
expect(pii_log.error_class).to eq('Form1010Ezr FailedWontRetry')
expect(pii_log.data).to eq(form)
end
end

Expand Down
Loading