From 31af3f841558ba05dc74b2925a56757c7d93ea47 Mon Sep 17 00:00:00 2001 From: Peri McLaren <141954992+pmclaren19@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:47:48 -0700 Subject: [PATCH] updated update_documents_status_service, tests and moved test file to the correct folder --- db/schema.rb | 31 +-- .../update_documents_status_service.rb | 7 +- .../update_documents_status_service_spec.rb | 216 ------------------ .../update_documents_status_service_spec.rb | 61 +++++ 4 files changed, 82 insertions(+), 233 deletions(-) delete mode 100644 spec/lib/lighthouse/benefits_documents/spec/lib/lighthouse/benefits_documents/form526/update_documents_status_service_spec.rb create mode 100644 spec/lib/lighthouse/benefits_documents/update_documents_status_service_spec.rb diff --git a/db/schema.rb b/db/schema.rb index 6f6e1c3d013..2a4826a90d6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_10_29_143650) do +ActiveRecord::Schema[7.1].define(version: 2024_11_19_134025) do # These are extensions that must be enabled in order to support this database enable_extension "btree_gin" enable_extension "fuzzystrmatch" @@ -351,9 +351,9 @@ t.string "form_type" t.bigint "saved_claim_id", null: false t.boolean "email_sent" - t.integer "email_template_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "email_template_id" t.index ["saved_claim_id"], name: "index_claim_va_notifications_on_saved_claim_id" end @@ -628,7 +628,7 @@ t.string "job_class" t.string "request_id" t.string "claim_id" - t.string "user_account_id" + t.uuid "user_account_id", null: false t.json "template_metadata_ciphertext" t.text "encrypted_kms_key" t.string "upload_status" @@ -641,6 +641,7 @@ t.string "tracked_item_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["user_account_id"], name: "index_evidence_submissions_on_user_account_id" end create_table "evss_claims", id: :serial, force: :cascade do |t| @@ -678,6 +679,7 @@ t.datetime "updated_at", null: false t.datetime "flagged_value_updated_at" t.index ["ip_address", "representative_id", "flag_type", "flagged_value_updated_at"], name: "index_unique_constraint_fields", unique: true + t.index ["ip_address", "representative_id", "flag_type"], name: "index_unique_flagged_veteran_representative", unique: true end create_table "flipper_features", force: :cascade do |t| @@ -760,6 +762,7 @@ t.string "aasm_state", default: "unprocessed" t.integer "submit_endpoint" t.integer "backup_submitted_claim_status" + t.index ["backup_submitted_claim_id"], name: "index_form526_submissions_on_backup_submitted_claim_id" t.index ["saved_claim_id"], name: "index_form526_submissions_on_saved_claim_id", unique: true t.index ["submitted_claim_id"], name: "index_form526_submissions_on_submitted_claim_id", unique: true t.index ["user_account_id"], name: "index_form526_submissions_on_user_account_id" @@ -793,6 +796,14 @@ t.index ["id", "type"], name: "index_form_attachments_on_id_and_type" end + create_table "form_email_matches_profile_logs", force: :cascade do |t| + t.string "user_uuid", null: false + t.integer "in_progress_form_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_uuid", "in_progress_form_id"], name: "idx_on_user_uuid_in_progress_form_id_f21f47b9c8", unique: true + end + create_table "form_submission_attempts", force: :cascade do |t| t.bigint "form_submission_id", null: false t.jsonb "response" @@ -810,14 +821,12 @@ create_table "form_submissions", force: :cascade do |t| t.string "form_type", null: false - t.uuid "benefits_intake_uuid" t.uuid "user_account_id" t.bigint "saved_claim_id" t.text "encrypted_kms_key" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.jsonb "form_data_ciphertext" - t.index ["benefits_intake_uuid"], name: "index_form_submissions_on_benefits_intake_uuid" t.index ["saved_claim_id"], name: "index_form_submissions_on_saved_claim_id" t.index ["user_account_id"], name: "index_form_submissions_on_user_account_id" end @@ -1023,13 +1032,6 @@ t.index ["va_profile_id", "dismissed"], name: "show_onsite_notifications_index" end - create_table "pension_ipf_notifications", force: :cascade do |t| - t.text "payload_ciphertext" - t.text "encrypted_kms_key" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - create_table "persistent_attachments", id: :serial, force: :cascade do |t| t.uuid "guid" t.string "type" @@ -1095,7 +1097,6 @@ t.text "form_ciphertext" t.text "encrypted_kms_key" t.string "uploaded_forms", default: [], array: true - t.datetime "itf_datetime" t.datetime "form_start_date" t.datetime "delete_date" t.text "metadata" @@ -1403,6 +1404,9 @@ t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "metadata" + t.jsonb "callback_metadata" + t.text "callback_klass" + t.uuid "template_id" end create_table "vba_documents_monthly_stats", force: :cascade do |t| @@ -1722,6 +1726,7 @@ add_foreign_key "deprecated_user_accounts", "user_accounts" add_foreign_key "deprecated_user_accounts", "user_verifications" add_foreign_key "education_stem_automated_decisions", "user_accounts" + add_foreign_key "evidence_submissions", "user_accounts" add_foreign_key "evss_claims", "user_accounts" add_foreign_key "form526_submission_remediations", "form526_submissions" add_foreign_key "form526_submissions", "user_accounts" diff --git a/lib/lighthouse/benefits_documents/update_documents_status_service.rb b/lib/lighthouse/benefits_documents/update_documents_status_service.rb index ea07a94e194..75068a34a8a 100644 --- a/lib/lighthouse/benefits_documents/update_documents_status_service.rb +++ b/lib/lighthouse/benefits_documents/update_documents_status_service.rb @@ -47,7 +47,6 @@ def initialize(benefits_document_uploads, lighthouse_status_response) def process_status_updates update_documents_status - unknown_ids = @lighthouse_status_response.dig('data', 'requestIdsNotFound') return { success: true } if unknown_ids.blank? @@ -82,9 +81,9 @@ def update_document_status(status_response) # end end - def statsd_document_base_key(statsd_document_type_key) - @statsd_document_base_key ||= "#{STATSD_BASE_KEY}.#{statsd_document_type_key}" - end + # def statsd_document_base_key(statsd_document_type_key) + # @statsd_document_base_key ||= "#{STATSD_BASE_KEY}.#{statsd_document_type_key}" + # end # def log_failure(status_updater, document_upload) # # Because Lighthouse's processing steps are subject to change, these metrics must be dynamic. diff --git a/spec/lib/lighthouse/benefits_documents/spec/lib/lighthouse/benefits_documents/form526/update_documents_status_service_spec.rb b/spec/lib/lighthouse/benefits_documents/spec/lib/lighthouse/benefits_documents/form526/update_documents_status_service_spec.rb deleted file mode 100644 index 88779676eed..00000000000 --- a/spec/lib/lighthouse/benefits_documents/spec/lib/lighthouse/benefits_documents/form526/update_documents_status_service_spec.rb +++ /dev/null @@ -1,216 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' -require 'lighthouse/benefits_documents/update_documents_status_service' -require 'lighthouse/benefits_documents/documents_status_polling_service' - -RSpec.describe BenefitsDocuments::UpdateDocumentsStatusService do - let(:start_time) { Time.new(1985, 10, 26).utc } - - # NOTE: The Lighthouse Benefits Documents API returns UNIX timestamps in milliseconds - let(:start_time_in_unix_milliseconds) { start_time.to_i * 1000 } - - # Simulate Lighthouse processing time offset - let(:end_time_in_unix_milliseconds) { (start_time + 30.seconds).to_i * 1000 } - - describe '#call' do - let(:pending_document_upload) { create(:lighthouse_document_upload, document_type: 'Veteran Upload') } - let(:uploads) { EvidenceSubmission.where(id: pending_document_upload.id) } - let(:status_response) do - { - 'data' => { - 'statuses' => [ - { - 'requestId' => pending_document_upload.lighthouse_document_request_id, - 'status' => status, - 'time' => { 'startTime' => start_time_in_unix_milliseconds, 'endTime' => end_time }, - 'steps' => steps, - 'error' => error - } - ] - } - } - end - - shared_examples 'document status updater' do |expected_state, metrics_key| - it "transitions the document to #{expected_state}" do - described_class.call(uploads, status_response) - expect(pending_document_upload.reload.aasm_state).to eq(expected_state) - end - - it "logs the #{expected_state} document to DataDog" do - expect { described_class.call(uploads, status_response) }.to trigger_statsd_increment(metrics_key) - end - end - - context 'when a Lighthouse526DocumentUpload has completed all steps in Lighthouse' do - let(:status) { 'SUCCESS' } - let(:steps) do - [ - { 'name' => 'CLAIMS_EVIDENCE', 'status' => 'SUCCESS' }, - { 'name' => 'BENEFITS_GATEWAY_SERVICE', 'status' => 'SUCCESS' } - ] - end - let(:error) { nil } - let(:end_time) { end_time_in_unix_milliseconds } - - it_behaves_like 'document status updater', 'completed', - 'api.form526.lighthouse_document_upload_processing_status.veteran_upload.complete' - end - - context 'when a Lighthouse526DocumentUpload fails in Lighthouse processing' do - let(:status) { 'FAILED' } - let(:steps) do - [ - { 'name' => 'CLAIMS_EVIDENCE', 'status' => 'FAILED' }, - { 'name' => 'BENEFITS_GATEWAY_SERVICE', 'status' => 'NOT_STARTED' } - ] - end - let(:error) { { 'detail' => 'VBMS System Outage', 'step' => 'CLAIMS_EVIDENCE' } } - let(:end_time) { end_time_in_unix_milliseconds } - - it_behaves_like 'document status updater', 'failed', - 'api.form526.lighthouse_document_upload_processing_status.veteran_upload.failed.claims_evidence' - end - - context 'when a Lighthouse526DocumentUpload is still in progress at Lighthouse' do - let(:status) { 'IN_PROGRESS' } - let(:steps) do - [ - { 'name' => 'CLAIMS_EVIDENCE', 'status' => 'IN_PROGRESS' }, - { 'name' => 'BENEFITS_GATEWAY_SERVICE', 'status' => 'NOT_STARTED' } - ] - end - let(:error) { nil } - let(:end_time) { nil } - - context 'when it has been more than 24 hours since Lighthouse started processing a Lighthouse526DocumentUpload' do - it 'logs a processing timeout metric to statsd' do - Timecop.freeze(start_time + 2.days) do - expect { described_class.call(uploads, status_response) }.to trigger_statsd_increment( - 'api.form526.lighthouse_document_upload_processing_status.veteran_upload.processing_timeout' - ) - end - end - end - - context 'when it has been less than 24 hours since Lighthouse started processing a Lighthouse526DocumentUpload' do - it 'does not log a processing timeout metric to statsd' do - Timecop.freeze(start_time + 2.hours) do - expect { described_class.call(uploads, status_response) }.not_to trigger_statsd_increment( - 'api.form526.lighthouse_document_upload_processing_status.veteran_upload.processing_timeout' - ) - end - end - end - - context 'when updating multiple records' do - let!(:first_pending_polling_document) { create(:lighthouse_document_upload, aasm_state: 'pending') } - let!(:second_pending_polling_document) { create(:lighthouse_document_upload, aasm_state: 'pending') } - - let(:status_response) do - { - 'data' => { - 'statuses' => [ - { - 'requestId' => first_pending_polling_document.lighthouse_document_request_id, - 'time' => { - 'startTime' => start_time_in_unix_milliseconds, - 'endTime' => end_time_in_unix_milliseconds - }, - 'status' => 'SUCCESS' - }, { - 'requestId' => second_pending_polling_document.lighthouse_document_request_id, - 'time' => { - 'startTime' => start_time_in_unix_milliseconds, - 'endTime' => end_time_in_unix_milliseconds - }, - 'status' => 'FAILED', - 'error' => { - 'detail' => 'Something went wrong', - 'step' => 'BENEFITS_GATEWAY_SERVICE' - } - } - ], - 'requestIdsNotFound' => [ - 0 - ] - } - } - end - - it 'updates each record status properly' do - described_class.call(Lighthouse526DocumentUpload.all, status_response) - - expect(first_pending_polling_document.reload.aasm_state).to eq('completed') - expect(second_pending_polling_document.reload.aasm_state).to eq('failed') - end - end - end - - describe 'document type in statsd metrics' do - # Helper method to generate identical responses that vary only in document request id - def mock_success_response(request_id) - { - 'data' => { - 'statuses' => [ - { - 'requestId' => request_id, - 'status' => 'SUCCESS', - 'time' => { 'startTime' => start_time_in_unix_milliseconds, 'endTime' => end_time_in_unix_milliseconds } - } - ] - } - } - end - - before do - # Stub update behavior; tests metrics keys include the correct document type - allow_any_instance_of(BenefitsDocuments::Form526::UploadStatusUpdater).to receive(:update_status) - allow_any_instance_of(Lighthouse526DocumentUpload).to receive(:completed?).and_return(true) - end - - shared_examples 'correct statsd metric' do |document_type, metrics_key| - let(:document_upload) { create(:lighthouse_document_upload, document_type:) } - let(:uploads) { Lighthouse526DocumentUpload.where(id: document_upload.id) } - let(:status_response) { mock_success_response(document_upload.lighthouse_document_request_id) } - - it "increments the correct statsd metric for #{document_type}" do - expect { described_class.call(uploads, status_response) }.to trigger_statsd_increment(metrics_key) - end - end - - it_behaves_like 'correct statsd metric', 'BDD Instructions', - 'api.form526.lighthouse_document_upload_processing_status.bdd_instructions.complete' - it_behaves_like 'correct statsd metric', 'Form 0781', - 'api.form526.lighthouse_document_upload_processing_status.form_0781.complete' - it_behaves_like 'correct statsd metric', 'Form 0781a', - 'api.form526.lighthouse_document_upload_processing_status.form_0781a.complete' - it_behaves_like 'correct statsd metric', 'Veteran Upload', - 'api.form526.lighthouse_document_upload_processing_status.veteran_upload.complete' - end - end - - let(:submission) { form0781_document_upload.form526_submission } - - before do - allow_any_instance_of(BenefitsDocuments::Form526::UploadStatusUpdater).to receive(:update_status) - allow_any_instance_of(Lighthouse526DocumentUpload).to receive(:failed?).and_return(true) - allow(Rails.logger).to receive(:warn) - end - - it 'logs the latest_status_response to the Rails logger' do - described_class.call(uploads, status_response) - - expect(Rails.logger).to have_received(:warn).with( - 'Benefits Documents API responded with a failed document upload status', { - form526_submission_id: submission.id, - document_type: form0781_document_upload.document_type, - failure_step: 'CLAIMS_EVIDENCE', - lighthouse_document_request_id: form0781_document_upload.lighthouse_document_request_id, - user_uuid: submission.user_uuid - } - ) - end - end -end diff --git a/spec/lib/lighthouse/benefits_documents/update_documents_status_service_spec.rb b/spec/lib/lighthouse/benefits_documents/update_documents_status_service_spec.rb new file mode 100644 index 00000000000..055f4d76de4 --- /dev/null +++ b/spec/lib/lighthouse/benefits_documents/update_documents_status_service_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'lighthouse/benefits_documents/update_documents_status_service' +require 'lighthouse/benefits_documents/documents_status_polling_service' + +RSpec.describe BenefitsDocuments::UpdateDocumentsStatusService do + describe '#call' do + let(:lighthouse_document_upload1) { create(:bd_evidence_submission, request_id: 1) } + let(:lighthouse_document_upload2) { create(:bd_evidence_submission, request_id: 2) } + let(:lighthouse_document_upload3) { create(:bd_evidence_submission, request_id: 3) } + + let :document_batch_ids do + [ + lighthouse_document_upload1.request_id, + lighthouse_document_upload2.request_id, + lighthouse_document_upload3.request_id + ] + end + let(:document_batch) do + EvidenceSubmission.where(request_id: document_batch_ids) + end + + describe 'process_status_updates' do + let(:lighthouse_status_response) do + { + 'data' => { + 'statuses' => [ + { + 'requestId' => lighthouse_document_upload1.request_id, + 'status' => BenefitsDocuments::Constants::UPLOAD_STATUS[:SUCCESS], + 'error' => nil + }, + { + 'requestId' => lighthouse_document_upload2.request_id, + 'status' => BenefitsDocuments::Constants::UPLOAD_STATUS[:FAILED], + 'error' => 'ERROR' + }, + { + 'requestId' => lighthouse_document_upload3.request_id, + 'status' => BenefitsDocuments::Constants::UPLOAD_STATUS[:PENDING], + 'error' => nil + } + ] + } + } + end + + it 'updates 2 records and leaves one in pending status' do + described_class.call(document_batch, lighthouse_status_response) + es1 = EvidenceSubmission.find_by(request_id: lighthouse_document_upload1.request_id) + es2 = EvidenceSubmission.find_by(request_id: lighthouse_document_upload2.request_id) + es3 = EvidenceSubmission.find_by(request_id: lighthouse_document_upload3.request_id) + + expect(es1.upload_status).to eq(BenefitsDocuments::Constants::UPLOAD_STATUS[:SUCCESS]) + expect(es2.upload_status).to eq(BenefitsDocuments::Constants::UPLOAD_STATUS[:FAILED]) + expect(es3.upload_status).to eq(BenefitsDocuments::Constants::UPLOAD_STATUS[:PENDING]) + end + end + end +end