From 8afe93cd32497ea971396888f178699a429b0a99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:26:58 -0400 Subject: [PATCH 01/25] Bump rubocop from 1.63.2 to 1.63.3 (#16452) Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.63.2 to 1.63.3. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.63.2...v1.63.3) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 6971cc5e88e..c378ff0f47d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -890,7 +890,7 @@ GEM rswag-ui (2.13.0) actionpack (>= 3.1, < 7.2) railties (>= 3.1, < 7.2) - rubocop (1.63.2) + rubocop (1.63.3) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From 13bbc4498ae4731e18825b8e6865d585c7dbb250 Mon Sep 17 00:00:00 2001 From: mchristiansonVA <95487885+mchristiansonVA@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:40:46 -0400 Subject: [PATCH 02/25] Api 35333 update document filenames (#16257) * Updates to set file name for BD uploads * Rubocop adjustments * Update to remove filename params, modify calls to BD * Add handling for supporting doc filename * Remove check for blank filename for v1 form 526 uploads * Disable Rubocop method length * Update tests for filename handling * Update test for filename handling --- .../app/sidekiq/claims_api/claim_uploader.rb | 15 +++++----- modules/claims_api/lib/bd/bd.rb | 28 ++++++++++++++++--- .../claims_api/spec/lib/claims_api/bd_spec.rb | 3 +- .../spec/sidekiq/claim_uploader_spec.rb | 10 +++++-- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/modules/claims_api/app/sidekiq/claims_api/claim_uploader.rb b/modules/claims_api/app/sidekiq/claims_api/claim_uploader.rb index bc6bb6cacc0..e0a87d2c5eb 100644 --- a/modules/claims_api/app/sidekiq/claims_api/claim_uploader.rb +++ b/modules/claims_api/app/sidekiq/claims_api/claim_uploader.rb @@ -7,7 +7,7 @@ module ClaimsApi class ClaimUploader < ClaimsApi::ServiceBase sidekiq_options retry: true, unique_until: :success - def perform(uuid) + def perform(uuid) # rubocop:disable Metrics/MethodLength claim_object = ClaimsApi::SupportingDocument.find_by(id: uuid) || ClaimsApi::AutoEstablishedClaim.find_by(id: uuid) @@ -21,11 +21,12 @@ def perform(uuid) else auth_headers = auto_claim.auth_headers uploader = claim_object.uploader - uploader.retrieve_from_store!(claim_object.file_data['filename']) + original_filename = claim_object.file_data['filename'] + uploader.retrieve_from_store!(original_filename) file_body = uploader.read ClaimsApi::Logger.log('lighthouse_claim_uploader', claim_id: auto_claim.id, attachment_id: uuid) if Flipper.enabled? :claims_claim_uploader_use_bd - bd_upload_body(auto_claim:, file_body:, doc_type:) + bd_upload_body(auto_claim:, file_body:, doc_type:, original_filename:) else EVSS::DocumentsService.new(auth_headers).upload(file_body, claim_upload_document(claim_object)) end @@ -34,19 +35,19 @@ def perform(uuid) private - def bd_upload_body(auto_claim:, file_body:, doc_type:) + def bd_upload_body(auto_claim:, file_body:, doc_type:, original_filename:) fh = Tempfile.new(['pdf_path', '.pdf'], binmode: true) begin fh.write(file_body) fh.close - claim_bd_upload_document(auto_claim, doc_type, fh.path) + claim_bd_upload_document(auto_claim, doc_type, fh.path, original_filename) ensure fh.unlink end end - def claim_bd_upload_document(claim, doc_type, pdf_path) # rubocop:disable Metrics/MethodLength - ClaimsApi::BD.new.upload(claim:, doc_type:, pdf_path:) + def claim_bd_upload_document(claim, doc_type, pdf_path, original_filename) # rubocop:disable Metrics/MethodLength + ClaimsApi::BD.new.upload(claim:, doc_type:, pdf_path:, original_filename:) # Temporary errors (returning HTML, connection timeout), retry call rescue Faraday::ParsingError, Faraday::TimeoutError => e message = get_error_message(e) diff --git a/modules/claims_api/lib/bd/bd.rb b/modules/claims_api/lib/bd/bd.rb index a435e1bf067..dc72ecb6625 100644 --- a/modules/claims_api/lib/bd/bd.rb +++ b/modules/claims_api/lib/bd/bd.rb @@ -33,7 +33,7 @@ def search(claim_id, file_number) # Upload document of mapped claim # # @return success or failure - def upload(claim:, pdf_path:, doc_type: 'L122', file_number: nil) + def upload(claim:, pdf_path:, doc_type: 'L122', file_number: nil, original_filename: nil) unless File.exist? pdf_path ClaimsApi::Logger.log('benefits_documents', detail: "Error uploading doc to BD: #{pdf_path} doesn't exist", claim_id: claim&.id) @@ -41,7 +41,7 @@ def upload(claim:, pdf_path:, doc_type: 'L122', file_number: nil) end @multipart = true - body = generate_upload_body(claim:, doc_type:, pdf_path:, file_number:) + body = generate_upload_body(claim:, doc_type:, pdf_path:, file_number:, original_filename:) res = client.post('documents', body)&.body&.deep_symbolize_keys request_id = res&.dig(:data, :requestId) ClaimsApi::Logger.log( @@ -62,10 +62,11 @@ def upload(claim:, pdf_path:, doc_type: 'L122', file_number: nil) # Generate form body to upload a document # # @return {parameters, file} - def generate_upload_body(claim:, doc_type:, pdf_path:, file_number: nil) + def generate_upload_body(claim:, doc_type:, pdf_path:, file_number: nil, original_filename: nil) payload = {} veteran_name = "#{claim.auth_headers['va_eauth_firstName']}_#{claim.auth_headers['va_eauth_lastName']}" - file_name = "526EZ_#{veteran_name}_#{claim.evss_id}.pdf" + file_name = generate_file_name(doc_type:, veteran_name:, claim_id: claim.evss_id, original_filename:) + data = { data: { systemName: 'VA.gov', @@ -83,6 +84,25 @@ def generate_upload_body(claim:, doc_type:, pdf_path:, file_number: nil) payload end + def generate_file_name(doc_type:, veteran_name:, claim_id:, original_filename:) + if doc_type == 'L122' + "#{veteran_name}_#{claim_id}_526EZ.pdf" + else + filename = get_original_supporting_doc_file_name(original_filename) + "#{veteran_name}_#{claim_id}_#{filename}.pdf" + end + end + + ## + # DisabilityCompensationDocuments method create_unique_filename adds a random 11 digit + # hex string to the original filename, so we remove that to yield the user-submitted + # filename to use as part of the filename uploaded to the BD service. + def get_original_supporting_doc_file_name(original_filename) + file_extension = File.extname(original_filename) + base_filename = File.basename(original_filename, file_extension) + base_filename[0...-12] + end + ## # Configure Faraday base class (and do auth) # diff --git a/modules/claims_api/spec/lib/claims_api/bd_spec.rb b/modules/claims_api/spec/lib/claims_api/bd_spec.rb index 67b2cb70d8c..33fa48aaf72 100644 --- a/modules/claims_api/spec/lib/claims_api/bd_spec.rb +++ b/modules/claims_api/spec/lib/claims_api/bd_spec.rb @@ -24,7 +24,8 @@ end it 'uploads an attachment to BD' do - result = subject.send(:generate_upload_body, claim:, doc_type: 'L023', pdf_path:) + result = subject.send(:generate_upload_body, claim:, doc_type: 'L023', original_filename: '21-526EZ.pdf', + pdf_path:) js = JSON.parse(result[:parameters].read) expect(js['data']['docType']).to eq 'L023' end diff --git a/modules/claims_api/spec/sidekiq/claim_uploader_spec.rb b/modules/claims_api/spec/sidekiq/claim_uploader_spec.rb index 099cfb01737..0c2b94d2ef9 100644 --- a/modules/claims_api/spec/sidekiq/claim_uploader_spec.rb +++ b/modules/claims_api/spec/sidekiq/claim_uploader_spec.rb @@ -56,6 +56,8 @@ claim end + let(:original_filename) { 'extras' } + it 'submits successfully' do expect do subject.perform_async(supporting_document.id) @@ -134,7 +136,7 @@ allow(Tempfile).to receive(:new).and_return tf allow(Flipper).to receive(:enabled?).with(:claims_claim_uploader_use_bd).and_return true - args = { claim: auto_claim, doc_type: 'L122', pdf_path: tf.path } + args = { claim: auto_claim, doc_type: 'L122', original_filename: 'extras.pdf', pdf_path: tf.path } expect_any_instance_of(ClaimsApi::BD).to receive(:upload).with(args).and_return true subject.new.perform(auto_claim.id) end @@ -144,7 +146,8 @@ allow(Tempfile).to receive(:new).and_return tf allow(Flipper).to receive(:enabled?).with(:claims_claim_uploader_use_bd).and_return true - args = { claim: supporting_document.auto_established_claim, doc_type: 'L023', pdf_path: tf.path } + args = { claim: supporting_document.auto_established_claim, doc_type: 'L023', + original_filename: 'extras.pdf', pdf_path: tf.path } expect_any_instance_of(ClaimsApi::BD).to receive(:upload).with(args).and_return true subject.new.perform(supporting_document.id) end @@ -161,7 +164,8 @@ text: 'Error calling external service to upload claim document.' } ] } - args = { claim: supporting_document.auto_established_claim, doc_type: 'L023', pdf_path: tf.path } + args = { claim: supporting_document.auto_established_claim, doc_type: 'L023', + original_filename: 'extras.pdf', pdf_path: tf.path } allow_any_instance_of(ClaimsApi::BD).to( receive(:upload).with(args).and_raise(Common::Exceptions::BackendServiceException.new( '', {}, 500, body From 68ed41bd91f089359b098910af3a70f1ed3d1497 Mon Sep 17 00:00:00 2001 From: evansmith Date: Tue, 23 Apr 2024 11:02:34 -0400 Subject: [PATCH 03/25] fix tribal land not appearing (#16461) --- lib/pdf_fill/forms/va21p530v2.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/pdf_fill/forms/va21p530v2.rb b/lib/pdf_fill/forms/va21p530v2.rb index f3ab58cdec1..2dd78c06b2b 100644 --- a/lib/pdf_fill/forms/va21p530v2.rb +++ b/lib/pdf_fill/forms/va21p530v2.rb @@ -619,6 +619,14 @@ def expand_cemetery_location @form_data['stateCemeteryOrTribalTrustZip'] = cemetery_location['zip'] if cemetery_location['zip'].present? end + def expand_tribal_land_location + cemetery_location = @form_data['tribalLandLocation'] + return if cemetery_location.blank? + + @form_data['stateCemeteryOrTribalTrustName'] = cemetery_location['name'] if cemetery_location['name'].present? + @form_data['stateCemeteryOrTribalTrustZip'] = cemetery_location['zip'] if cemetery_location['zip'].present? + end + # VA file number can be up to 10 digits long; An optional leading 'c' or 'C' followed by # 7-9 digits. The file number field on the 4142 form has space for 9 characters so trim the # potential leading 'c' to ensure the file number will fit into the form without overflow. @@ -654,7 +662,7 @@ def expand_confirmation_question def expand_location_question cemetery_location = @form_data['cemetaryLocationQuestion'] @form_data['cemetaryLocationQuestionCemetery'] = select_checkbox(cemetery_location == 'cemetery') - @form_data['cemetaryLocationQuestionTribal'] = select_checkbox(cemetery_location == 'tribal') + @form_data['cemetaryLocationQuestionTribal'] = select_checkbox(cemetery_location == 'tribalLand') @form_data['cemetaryLocationQuestionNone'] = select_checkbox(cemetery_location == 'none') end @@ -718,6 +726,7 @@ def merge_fields(_options = {}) end expand_cemetery_location + expand_tribal_land_location # special case: the UI only has a 'yes' checkbox, so the PDF 'noTransportation' checkbox can never be true. @form_data['hasTransportation'] = @form_data['transportation'] == true ? 'YES' : nil From 5312b9711d061f193eacda7057077a577f7209da Mon Sep 17 00:00:00 2001 From: Eric Tillberg Date: Tue, 23 Apr 2024 11:40:09 -0400 Subject: [PATCH 04/25] Start tracking users in 20-10207 (#16456) --- .../app/models/simple_forms_api/vba_20_10207.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/simple_forms_api/app/models/simple_forms_api/vba_20_10207.rb b/modules/simple_forms_api/app/models/simple_forms_api/vba_20_10207.rb index c0b5c505672..85446b97de0 100644 --- a/modules/simple_forms_api/app/models/simple_forms_api/vba_20_10207.rb +++ b/modules/simple_forms_api/app/models/simple_forms_api/vba_20_10207.rb @@ -3,6 +3,7 @@ module SimpleFormsApi class VBA2010207 include Virtus.model(nullify_blank: true) + STATS_KEY = 'api.simple_forms_api.20_10207' attribute :data @@ -97,7 +98,11 @@ def submission_date_stamps [] end - def track_user_identity(confirmation_number); end + def track_user_identity(confirmation_number) + identity = "#{data['preparer_type']} #{data['third_party_type']}" + StatsD.increment("#{STATS_KEY}.#{identity}") + Rails.logger.info('Simple forms api - 20-10207 submission user identity', identity:, confirmation_number:) + end private From 373a339040fe71b63be33ce90b98a07a7777d73c Mon Sep 17 00:00:00 2001 From: kanchanasuriya <89944361+kanchanasuriya@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:53:54 -0700 Subject: [PATCH 05/25] 71790 CIE facilities payload serializer (#16361) * 71790 CIE facilities payload serializer * Addressing review comments * Fixing rubocop failures --------- Co-authored-by: kanchanasuriya --- .../facilities/facilities_data_serializer.rb | 13 ++ .../facilities_data_serializer_spec.rb | 144 ++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 modules/check_in/app/serializers/check_in/facilities/facilities_data_serializer.rb create mode 100644 modules/check_in/spec/serializers/check_in/facilities/facilities_data_serializer_spec.rb diff --git a/modules/check_in/app/serializers/check_in/facilities/facilities_data_serializer.rb b/modules/check_in/app/serializers/check_in/facilities/facilities_data_serializer.rb new file mode 100644 index 00000000000..6566d04578f --- /dev/null +++ b/modules/check_in/app/serializers/check_in/facilities/facilities_data_serializer.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module CheckIn + module Facilities + class FacilitiesDataSerializer + include JSONAPI::Serializer + + set_id(&:id) + + attribute :name, :type, :classification, :timezone, :phone, :physicalAddress + end + end +end diff --git a/modules/check_in/spec/serializers/check_in/facilities/facilities_data_serializer_spec.rb b/modules/check_in/spec/serializers/check_in/facilities/facilities_data_serializer_spec.rb new file mode 100644 index 00000000000..8dd6b7968a5 --- /dev/null +++ b/modules/check_in/spec/serializers/check_in/facilities/facilities_data_serializer_spec.rb @@ -0,0 +1,144 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe CheckIn::Facilities::FacilitiesDataSerializer do + subject { described_class } + + let(:facilities_data) do + { + id: '442', + facilitiesApiId: 'vha_442', + vistaSite: '442', + vastParent: '442', + type: 'va_health_facility', + name: 'Cheyenne VA Medical Center', + classification: 'VA Medical Center (VAMC)', + timezone: { + timeZoneId: 'America/Denver' + }, + lat: 41.148026, + long: -104.786255, + website: 'https://www.va.gov/cheyenne-health-care/locations/cheyenne-va-medical-center/', + phone: { + main: '307-778-7550', + fax: '307-778-7381', + pharmacy: '866-420-6337', + afterHours: '307-778-7550', + patientAdvocate: '307-778-7550 x7573', + mentalHealthClinic: '307-778-7349', + enrollmentCoordinator: '307-778-7550 x7579' + }, + mailingAddress: { + type: 'postal', + line: [nil, nil, nil] + }, + physicalAddress: { + type: 'physical', + line: ['2360 East Pershing Boulevard', nil, nil], + city: 'Cheyenne', + state: 'WY', + postalCode: '82001-5356' + }, + mobile: false, + healthService: %w[Audiology Cardiology CaregiverSupport Covid19Vaccine DentalServices Dermatology EmergencyCare + Gastroenterology Gynecology MentalHealthCare Nutrition Ophthalmology Optometry Orthopedics + Podiatry PrimaryCare Urology WomensHealth], + operatingStatus: { + code: 'NORMAL' + }, + visn: '19' + } + end + + describe '#serializable_hash' do + context 'when all the necessary fields exist' do + let(:serialized_hash_response) do + { + data: { + id: '442', + type: :facilities_data, + attributes: { + type: 'va_health_facility', + name: 'Cheyenne VA Medical Center', + classification: 'VA Medical Center (VAMC)', + timezone: { + timeZoneId: 'America/Denver' + }, + phone: { + main: '307-778-7550', + fax: '307-778-7381', + pharmacy: '866-420-6337', + afterHours: '307-778-7550', + patientAdvocate: '307-778-7550 x7573', + mentalHealthClinic: '307-778-7349', + enrollmentCoordinator: '307-778-7550 x7579' + }, + physicalAddress: { + type: 'physical', + line: ['2360 East Pershing Boulevard', nil, nil], + city: 'Cheyenne', + state: 'WY', + postalCode: '82001-5356' + } + } + } + } + end + + it 'returns a serialized hash' do + facilities_struct = OpenStruct.new(facilities_data) + facilities_serializer = CheckIn::Facilities::FacilitiesDataSerializer.new(facilities_struct) + + expect(facilities_serializer.serializable_hash).to eq(serialized_hash_response) + end + end + + context 'when name does not exist' do + let(:facilities_data_without_name) do + facilities_data.except!(:name) + facilities_data + end + + let(:serialized_hash_response) do + { + data: { + id: '442', + type: :facilities_data, + attributes: { + name: nil, + type: 'va_health_facility', + classification: 'VA Medical Center (VAMC)', + timezone: { + timeZoneId: 'America/Denver' + }, + phone: { + main: '307-778-7550', + fax: '307-778-7381', + pharmacy: '866-420-6337', + afterHours: '307-778-7550', + patientAdvocate: '307-778-7550 x7573', + mentalHealthClinic: '307-778-7349', + enrollmentCoordinator: '307-778-7550 x7579' + }, + physicalAddress: { + type: 'physical', + line: ['2360 East Pershing Boulevard', nil, nil], + city: 'Cheyenne', + state: 'WY', + postalCode: '82001-5356' + } + } + } + } + end + + it 'returns a serialized hash with nil in name field' do + facilities_struct = OpenStruct.new(facilities_data_without_name) + facilities_serializer = CheckIn::Facilities::FacilitiesDataSerializer.new(facilities_struct) + + expect(facilities_serializer.serializable_hash).to eq(serialized_hash_response) + end + end + end +end From 116d8c762c256410ad5beeaddf6ea0ee38615825 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen <134089461+Khoa-V-Nguyen@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:36:51 -0600 Subject: [PATCH 06/25] Update `Inquiries::Creator` and `InquiriesController` (#16466) - Updated `inquiry_params` - Fix argumet in `Inquiries::Creator` Co-authored-by: khoa-v-nguyen --- .../ask_va_api/v0/inquiries_controller.rb | 12 ++-- .../app/lib/ask_va_api/inquiries/creator.rb | 4 +- .../lib/ask_va_api/inquiries/creator_spec.rb | 28 ++++---- .../spec/requests/v0/inquiries_spec.rb | 68 +++++++++---------- 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/modules/ask_va_api/app/controllers/ask_va_api/v0/inquiries_controller.rb b/modules/ask_va_api/app/controllers/ask_va_api/v0/inquiries_controller.rb index 28b3dbf113f..9cc82b5a60e 100644 --- a/modules/ask_va_api/app/controllers/ask_va_api/v0/inquiries_controller.rb +++ b/modules/ask_va_api/app/controllers/ask_va_api/v0/inquiries_controller.rb @@ -26,12 +26,12 @@ def test_create end def create - response = Inquiries::Creator.new(icn: current_user.icn).call(params: inquiry_params) + response = Inquiries::Creator.new(icn: current_user.icn).call(payload: inquiry_params) render json: response.to_json, status: :created end def unauth_create - response = Inquiries::Creator.new(icn: nil).call(params: inquiry_params) + response = Inquiries::Creator.new(icn: nil).call(payload: inquiry_params) render json: response.to_json, status: :created end @@ -101,7 +101,7 @@ def inquiry_params *dependant_parameters, *submitter_parameters, *veteran_parameters, - school_obj: school_parameters + SchoolObj: school_parameters ).to_h end @@ -112,7 +112,7 @@ def base_parameters InquiryCategory InquirySource InquirySubtopic InquirySummary InquiryTopic InquiryType IsVAEmployee IsVeteran IsVeteranAnEmployee IsVeteranDeceased LevelOfAuthentication MedicalCenter MiddleName PreferredName Pronouns - StreetAddress2 SupervisorFlag VaEmployeeTimeStamp ZipCode + StreetAddress2 SupervisorFlag VaEmployeeTimeStamp ZipCode Suffix ] end @@ -130,7 +130,7 @@ def submitter_parameters Submitter SubmitterDependent SubmitterDOB SubmitterGender SubmitterProvince SubmitterSSN SubmitterState SubmitterStateOfResidency SubmitterStateOfSchool SubmitterStateProperty SubmitterStreetAddress SubmitterVetCenter - SubmitterZipCodeOfResidency SubmitterQuestion + SubmitterZipCodeOfResidency SubmitterQuestion SubmittersDodIdEdipiNumber ] end @@ -143,7 +143,7 @@ def veteran_parameters VeteranRelationship VeteranServiceEndDate VeteranServiceNumber VeteranServiceStartDate VeteranSSN VeteransState VeteranStreetAddress VeteranSuffix VeteranSuiteAptOther VeteranZipCode WhoWasTheirCounselor - YourLastName + YourLastName VeteranDodIdEdipiNumber ] end diff --git a/modules/ask_va_api/app/lib/ask_va_api/inquiries/creator.rb b/modules/ask_va_api/app/lib/ask_va_api/inquiries/creator.rb index dbd8e4e7ef0..5accb20ee13 100644 --- a/modules/ask_va_api/app/lib/ask_va_api/inquiries/creator.rb +++ b/modules/ask_va_api/app/lib/ask_va_api/inquiries/creator.rb @@ -13,8 +13,8 @@ def initialize(icn:, service: nil) @service = service || default_service end - def call(params:) - post_data(payload: { params: }) + def call(payload:) + post_data(payload:) rescue => e ErrorHandler.handle_service_error(e) end diff --git a/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/creator_spec.rb b/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/creator_spec.rb index 6bb4e6d651b..91029a32a3d 100644 --- a/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/creator_spec.rb +++ b/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/creator_spec.rb @@ -6,7 +6,7 @@ let(:icn) { '123456' } let(:service) { instance_double(Crm::Service) } let(:creator) { described_class.new(icn:, service:) } - let(:params) { { FirstName: 'Fake', YourLastName: 'Smith' } } + let(:payload) { { FirstName: 'Fake', YourLastName: 'Smith' } } let(:endpoint) { AskVAApi::Inquiries::Creator::ENDPOINT } before do @@ -17,21 +17,21 @@ context 'when the API call is successful' do before do allow(service).to receive(:call).with(endpoint:, method: :put, - payload: { params: }).and_return({ - Data: { - InquiryNumber: '530d56a8-affd-ee11' \ - '-a1fe-001dd8094ff1' - }, - Message: '', - ExceptionOccurred: false, - ExceptionMessage: '', - MessageId: 'b8ebd8e7-3bbf-49c5' \ - '-aff0-99503e50ee27' - }) + payload:).and_return({ + Data: { + InquiryNumber: '530d56a8-affd-ee11' \ + '-a1fe-001dd8094ff1' + }, + Message: '', + ExceptionOccurred: false, + ExceptionMessage: '', + MessageId: 'b8ebd8e7-3bbf-49c5' \ + '-aff0-99503e50ee27' + }) end it 'posts data to the service and returns the response' do - expect(creator.call(params:)).to eq({ InquiryNumber: '530d56a8-affd-ee11-a1fe-001dd8094ff1' }) + expect(creator.call(payload:)).to eq({ InquiryNumber: '530d56a8-affd-ee11-a1fe-001dd8094ff1' }) end end @@ -45,7 +45,7 @@ end it 'raise InquiriesCreatorError' do - expect { creator.call(params:) }.to raise_error(ErrorHandler::ServiceError) + expect { creator.call(payload:) }.to raise_error(ErrorHandler::ServiceError) end end end diff --git a/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb b/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb index 111e5fe58fb..3d0a6216ddc 100644 --- a/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb +++ b/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb @@ -332,24 +332,24 @@ end describe 'POST #create' do - let(:params) { { FirstName: 'Fake', YourLastName: 'Smith' } } + let(:payload) { { FirstName: 'Fake', YourLastName: 'Smith' } } let(:endpoint) { AskVAApi::Inquiries::Creator::ENDPOINT } context 'when successful' do before do allow_any_instance_of(Crm::Service).to receive(:call) .with(endpoint:, method: :put, - payload: { params: }).and_return({ - Data: { - Id: '530d56a8-affd-ee11-a1fe-001dd8094ff1' - }, - Message: '', - ExceptionOccurred: false, - ExceptionMessage: '', - MessageId: 'b8ebd8e7-3bbf-49c5-aff0-99503e50ee27' - }) + payload:).and_return({ + Data: { + Id: '530d56a8-affd-ee11-a1fe-001dd8094ff1' + }, + Message: '', + ExceptionOccurred: false, + ExceptionMessage: '', + MessageId: 'b8ebd8e7-3bbf-49c5-aff0-99503e50ee27' + }) sign_in(authorized_user) - post '/ask_va_api/v0/inquiries/auth', params: + post '/ask_va_api/v0/inquiries/auth', params: payload end it { expect(response).to have_http_status(:created) } @@ -360,13 +360,13 @@ before do allow_any_instance_of(Crm::Service).to receive(:call) .with(endpoint:, method: :put, - payload: { params: }).and_return({ Data: nil, - Message: 'Data Validation: missing InquiryCategory', - ExceptionOccurred: true, - ExceptionMessage: 'Data Validation: missing InquiryCategory', - MessageId: '13bc59ea-c90a-4d48-8979-fe71e0f7ddeb' }) + payload:).and_return({ Data: nil, + Message: 'Data Validation: missing InquiryCategory', + ExceptionOccurred: true, + ExceptionMessage: 'Data Validation: missing InquiryCategory', + MessageId: '13bc59ea-c90a-4d48-8979-fe71e0f7ddeb' }) sign_in(authorized_user) - post '/ask_va_api/v0/inquiries/auth', params: + post '/ask_va_api/v0/inquiries/auth', params: payload end it 'raise InquiriesCreatorError' do @@ -380,23 +380,23 @@ end describe 'POST #unauth_create' do - let(:params) { { FirstName: 'Fake', YourLastName: 'Smith' } } + let(:payload) { { FirstName: 'Fake', YourLastName: 'Smith' } } let(:endpoint) { AskVAApi::Inquiries::Creator::ENDPOINT } context 'when successful' do before do allow_any_instance_of(Crm::Service).to receive(:call) .with(endpoint:, method: :put, - payload: { params: }).and_return({ - Data: { - Id: '530d56a8-affd-ee11-a1fe-001dd8094ff1' - }, - Message: '', - ExceptionOccurred: false, - ExceptionMessage: '', - MessageId: 'b8ebd8e7-3bbf-49c5-aff0-99503e50ee27' - }) - post inquiry_path, params: + payload:).and_return({ + Data: { + Id: '530d56a8-affd-ee11-a1fe-001dd8094ff1' + }, + Message: '', + ExceptionOccurred: false, + ExceptionMessage: '', + MessageId: 'b8ebd8e7-3bbf-49c5-aff0-99503e50ee27' + }) + post inquiry_path, params: payload end it { expect(response).to have_http_status(:created) } @@ -407,12 +407,12 @@ before do allow_any_instance_of(Crm::Service).to receive(:call) .with(endpoint:, method: :put, - payload: { params: }).and_return({ Data: nil, - Message: 'Data Validation: missing InquiryCategory', - ExceptionOccurred: true, - ExceptionMessage: 'Data Validation: missing InquiryCategory', - MessageId: '13bc59ea-c90a-4d48-8979-fe71e0f7ddeb' }) - post '/ask_va_api/v0/inquiries', params: + payload:).and_return({ Data: nil, + Message: 'Data Validation: missing InquiryCategory', + ExceptionOccurred: true, + ExceptionMessage: 'Data Validation: missing InquiryCategory', + MessageId: '13bc59ea-c90a-4d48-8979-fe71e0f7ddeb' }) + post '/ask_va_api/v0/inquiries', params: payload end it 'raise InquiriesCreatorError' do From 5c0fef3b1430fed8be96458365d4411bc70d482d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:36:49 -0400 Subject: [PATCH 07/25] Bump coverband from 6.1.0 to 6.1.1 (#16451) Bumps [coverband](https://github.com/danmayer/coverband) from 6.1.0 to 6.1.1. - [Release notes](https://github.com/danmayer/coverband/releases) - [Changelog](https://github.com/danmayer/coverband/blob/main/changes.md) - [Commits](https://github.com/danmayer/coverband/compare/v6.1.0...v6.1.1) --- updated-dependencies: - dependency-name: coverband dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c378ff0f47d..fb14fa4d562 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -317,7 +317,7 @@ GEM content_disposition (1.0.0) cork (0.3.0) colored2 (~> 3.1) - coverband (6.1.0) + coverband (6.1.1) redis (>= 3.0) crack (1.0.0) bigdecimal From ab4d44fe29698ec8d63a54388874f0dfc9b9debb Mon Sep 17 00:00:00 2001 From: Gaurav Gupta Date: Tue, 23 Apr 2024 13:21:13 -0700 Subject: [PATCH 08/25] 80854 appts svc using check in UUID (#16432) * 80854 update token service specs * 80854 update base service and specs * 80854 update appointment service specs * 80854 fix specs to get icn from Lorota Redis client --- .../services/check_in/vaos/base_service.rb | 24 ++++++++-- .../check_in/map/token_service_spec.rb | 21 +++++---- .../check_in/vaos/appointment_service_spec.rb | 45 ++++++++++--------- .../check_in/vaos/base_service_spec.rb | 28 +++++++++++- 4 files changed, 81 insertions(+), 37 deletions(-) diff --git a/modules/check_in/app/services/check_in/vaos/base_service.rb b/modules/check_in/app/services/check_in/vaos/base_service.rb index 8cf947ab968..8a906d04d98 100644 --- a/modules/check_in/app/services/check_in/vaos/base_service.rb +++ b/modules/check_in/app/services/check_in/vaos/base_service.rb @@ -9,13 +9,25 @@ class BaseService < Common::Client::Base include SentryLogging include Common::Client::Concerns::Monitoring - attr_reader :patient_icn, :token_service + attr_reader :check_in_session, :patient_icn STATSD_KEY_PREFIX = 'api.check_in.vaos' - def initialize(patient_icn:) - @patient_icn = patient_icn - @token_service = CheckIn::Map::TokenService.build({ patient_icn: }) + ## + # Builds a Service instance + # + # @param opts [Hash] options to create the object + # + # @return [Service] an instance of this class + # + def self.build(opts = {}) + new(opts) + end + + def initialize(opts) + @check_in_session = opts[:check_in_session] + @patient_icn = ::V2::Lorota::RedisClient.build.icn(uuid: check_in_session.uuid) + super() end @@ -35,6 +47,10 @@ def headers } end + def token_service + @token_service ||= Map::TokenService.build(patient_icn:) + end + def referrer if Settings.hostname.ends_with?('.gov') "https://#{Settings.hostname}".gsub('vets', 'va') diff --git a/modules/check_in/spec/services/check_in/map/token_service_spec.rb b/modules/check_in/spec/services/check_in/map/token_service_spec.rb index a87429a51f1..a03e1e7b073 100644 --- a/modules/check_in/spec/services/check_in/map/token_service_spec.rb +++ b/modules/check_in/spec/services/check_in/map/token_service_spec.rb @@ -3,14 +3,10 @@ require 'rails_helper' describe CheckIn::Map::TokenService do - subject { described_class } + subject { described_class.build(opts) } let(:patient_icn) { '123' } - let(:opts) do - { - patient_icn: - } - end + let(:opts) { { patient_icn: } } let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) } before do @@ -21,13 +17,13 @@ describe '.build' do it 'returns an instance of Service' do - expect(subject.build(opts)).to be_an_instance_of(described_class) + expect(subject).to be_an_instance_of(described_class) end end describe '#initialize' do it 'has a redis client' do - expect(subject.build(opts).redis_client).to be_a(CheckIn::Map::RedisClient) + expect(subject.redis_client).to be_a(CheckIn::Map::RedisClient) end end @@ -41,7 +37,7 @@ end it 'returns token from redis' do - expect(subject.build(opts).token).to eq(access_token) + expect(subject.token).to eq(access_token) end end @@ -51,8 +47,11 @@ .and_return({ access_token:, expiration: }) end - it 'returns token by calling client' do - expect(subject.build(opts).token).to eq(access_token) + it 'returns token by calling client and saves it in redis' do + redis_client = subject.redis_client + expect(redis_client).to receive(:save_token) + + expect(subject.token).to eq(access_token) end end end diff --git a/modules/check_in/spec/services/check_in/vaos/appointment_service_spec.rb b/modules/check_in/spec/services/check_in/vaos/appointment_service_spec.rb index ca71d3cb05c..37adf918027 100644 --- a/modules/check_in/spec/services/check_in/vaos/appointment_service_spec.rb +++ b/modules/check_in/spec/services/check_in/vaos/appointment_service_spec.rb @@ -3,17 +3,17 @@ require 'rails_helper' describe CheckIn::VAOS::AppointmentService do - subject { described_class.new(patient_icn:) } + subject { described_class } + let(:uuid) { 'd602d9eb-9a31-484f-9637-13ab0b507e0d' } + let(:check_in_session) { CheckIn::V2::Session.build(data: { uuid: }) } let(:patient_icn) { '123' } let(:token) { 'test_token' } let(:request_id) { SecureRandom.uuid } - describe '#initialize' do - it 'returns an instance of service' do - service_obj = subject - expect(service_obj).to be_an_instance_of(CheckIn::VAOS::AppointmentService) - expect(service_obj.token_service).to be_an_instance_of(CheckIn::Map::TokenService) + describe '.build' do + it 'returns an instance of Service' do + expect(subject.build(check_in_session:)).to be_an_instance_of(described_class) end end @@ -42,21 +42,27 @@ let(:faraday_response) { double('Faraday::Response') } let(:faraday_env) { double('Faraday::Env', status: 200, body: appointments_response.to_json) } + before do + allow_any_instance_of(V2::Lorota::RedisClient).to receive(:icn).with(uuid:) + .and_return(patient_icn) + allow_any_instance_of(CheckIn::Map::TokenService).to receive(:token) + .and_return(token) + end + context 'when vaos returns successful response' do before do - allow_any_instance_of(CheckIn::Map::TokenService).to receive(:token) - .and_return(token) - allow_any_instance_of(Faraday::Connection).to receive(:get).with('/vaos/v1/patients/123/appointments', - { start: start_date, end: end_date, - statuses: }) - .and_return(faraday_response) + allow_any_instance_of(Faraday::Connection).to receive(:get) + .with("/vaos/v1/patients/#{patient_icn}/appointments", + { start: start_date, end: end_date, statuses: }) + .and_return(faraday_response) allow(faraday_response).to receive(:env).and_return(faraday_env) end it 'returns appointments' do - response = subject.get_appointments(DateTime.parse(start_date).in_time_zone, - DateTime.parse(end_date).in_time_zone, - statuses) + svc = subject.build(check_in_session:) + response = svc.get_appointments(DateTime.parse(start_date).in_time_zone, + DateTime.parse(end_date).in_time_zone, + statuses) expect(response).to eq(appointments_response) end end @@ -66,8 +72,6 @@ let(:exception) { Common::Exceptions::BackendServiceException.new(nil, {}, resp.status, resp.body) } before do - allow_any_instance_of(CheckIn::Map::TokenService).to receive(:token) - .and_return(token) allow_any_instance_of(Faraday::Connection).to receive(:get).with('/vaos/v1/patients/123/appointments', { start: start_date, end: end_date, statuses: }) @@ -75,10 +79,11 @@ end it 'throws exception' do + svc = subject.build(check_in_session:) expect do - subject.get_appointments(DateTime.parse(start_date).in_time_zone, - DateTime.parse(end_date).in_time_zone, - statuses) + svc.get_appointments(DateTime.parse(start_date).in_time_zone, + DateTime.parse(end_date).in_time_zone, + statuses) end.to(raise_error do |error| expect(error).to be_a(Common::Exceptions::BackendServiceException) end) diff --git a/modules/check_in/spec/services/check_in/vaos/base_service_spec.rb b/modules/check_in/spec/services/check_in/vaos/base_service_spec.rb index f523aab9fc6..e7733b82363 100644 --- a/modules/check_in/spec/services/check_in/vaos/base_service_spec.rb +++ b/modules/check_in/spec/services/check_in/vaos/base_service_spec.rb @@ -3,12 +3,35 @@ require 'rails_helper' describe CheckIn::VAOS::BaseService do - subject { described_class.new(patient_icn:) } + subject { described_class.build(check_in_session:) } + let(:uuid) { 'd602d9eb-9a31-484f-9637-13ab0b507e0d' } + let(:check_in_session) { CheckIn::V2::Session.build(data: { uuid: }) } let(:patient_icn) { '123' } let(:token) { 'test_token' } let(:request_id) { SecureRandom.uuid } + describe '.build' do + it 'returns an instance of Service' do + expect(subject).to be_an_instance_of(described_class) + end + end + + describe '#initialize' do + before do + allow_any_instance_of(V2::Lorota::RedisClient).to receive(:icn).with(uuid:) + .and_return(patient_icn) + end + + it 'has a check_in_session object' do + expect(subject.check_in_session).to be_a(CheckIn::V2::Session) + end + + it 'has a patient icn' do + expect(subject.patient_icn).to eq(patient_icn) + end + end + describe '#config' do it 'returns an instance of Configuration' do expect(subject.config).to be_an_instance_of(CheckIn::VAOS::Configuration) @@ -17,8 +40,9 @@ describe '#headers' do before do - allow_any_instance_of(CheckIn::Map::TokenService).to receive(:token).and_return(token) RequestStore.store['request_id'] = request_id + + allow_any_instance_of(CheckIn::Map::TokenService).to receive(:token).and_return(token) end it 'returns correct headers' do From 5494d604ca12fa2b09b139b9190d594eebd2a9d8 Mon Sep 17 00:00:00 2001 From: mchristiansonVA <95487885+mchristiansonVA@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:46:04 -0400 Subject: [PATCH 09/25] Api 35334 526 docs max length (#16464) * Add schema updates for max length to match pdf generator * Remove maxLength on states, enforced via pattern * Add generated swagger --- .../swagger/claims_api/v2/dev/swagger.json | 97 ++++++++++++++++--- .../claims_api/v2/production/swagger.json | 97 ++++++++++++++++--- modules/claims_api/config/schemas/v2/526.json | 23 +++++ 3 files changed, 189 insertions(+), 28 deletions(-) diff --git a/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json b/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json index 7094044200c..694ef3f86cd 100644 --- a/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json +++ b/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json @@ -967,7 +967,7 @@ "lighthouseId": null, "maxEstClaimDate": null, "minEstClaimDate": null, - "status": "COMPLETE", + "status": "CANCELED", "submitterApplicationCode": "EBN", "submitterRoleCode": "VET", "supportingDocuments": [ @@ -1625,6 +1625,7 @@ "serviceNumber": { "type": "string", "description": "Service identification number", + "maxLength": 1000, "nullable": true }, "veteranNumber": { @@ -1645,6 +1646,7 @@ "type": "string", "description": "Veteran's international phone number.", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -1687,6 +1689,7 @@ "description": "City for the Veteran's current mailing address.", "type": "string", "pattern": "^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -1698,6 +1701,7 @@ "country": { "description": "Country for the Veteran's current mailing address. Must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -1783,6 +1787,7 @@ "description": "City for the Veteran's new address.", "type": "string", "pattern": "^$|^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -1794,6 +1799,7 @@ "country": { "description": "Country for the Veteran's new address. Value must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -1913,6 +1919,7 @@ "description": "International phone of point of contact.", "type": "string", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -1947,12 +1954,14 @@ "type": "string", "nullable": true, "description": "Approximate begin date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" }, "endDate": { "type": "string", "nullable": true, "description": "Approximate end date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" } } @@ -1978,6 +1987,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Other location(s) where Veteran served." }, "serviceDates": { @@ -2031,6 +2041,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Exposure to asbestos." }, "exposureDates": { @@ -2069,12 +2080,14 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Hazard the Veteran was exposed to." }, "exposureLocation": { "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Location where the exposure happened." }, "exposureDates": { @@ -2126,6 +2139,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -2136,6 +2150,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury. If the disabilityActionType is 'NEW', the serviceRelevance is required.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "approximateDate": { @@ -2198,6 +2213,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -2208,6 +2224,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "disabilityActionType": { @@ -2340,6 +2357,7 @@ "serviceBranch": { "description": "Branch of service during period. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "example": "Air Force" }, "serviceComponent": { @@ -2419,10 +2437,12 @@ "unitName": { "type": "string", "nullable": true, + "maxLength": 1000, "pattern": "^$|([a-zA-Z0-9\\-'.,# ][a-zA-Z0-9\\-'.,# ]?)*$" }, "unitAddress": { "type": "string", + "maxLength": 1000, "pattern": "^$|^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", "nullable": true }, @@ -2532,6 +2552,7 @@ "futureMilitaryRetiredPayExplanation": { "description": "Explains why future pay will be received.", "type": "string", + "maxLength": 1000, "example": "Will be retiring soon.", "nullable": true }, @@ -2543,6 +2564,7 @@ "branchOfService": { "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "nullable": true, "example": "Air Force" }, @@ -2598,6 +2620,7 @@ "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Air Force" }, "preTaxAmountReceived": { @@ -2885,6 +2908,7 @@ "serviceNumber": { "type": "string", "description": "Service identification number", + "maxLength": 1000, "nullable": true }, "veteranNumber": { @@ -2905,6 +2929,7 @@ "type": "string", "description": "Veteran's international phone number.", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -2947,6 +2972,7 @@ "description": "City for the Veteran's current mailing address.", "type": "string", "pattern": "^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -2958,6 +2984,7 @@ "country": { "description": "Country for the Veteran's current mailing address. Must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -3043,6 +3070,7 @@ "description": "City for the Veteran's new address.", "type": "string", "pattern": "^$|^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -3054,6 +3082,7 @@ "country": { "description": "Country for the Veteran's new address. Value must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -3173,6 +3202,7 @@ "description": "International phone of point of contact.", "type": "string", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -3207,12 +3237,14 @@ "type": "string", "nullable": true, "description": "Approximate begin date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" }, "endDate": { "type": "string", "nullable": true, "description": "Approximate end date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" } } @@ -3238,6 +3270,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Other location(s) where Veteran served." }, "serviceDates": { @@ -3291,6 +3324,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Exposure to asbestos." }, "exposureDates": { @@ -3329,12 +3363,14 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Hazard the Veteran was exposed to." }, "exposureLocation": { "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Location where the exposure happened." }, "exposureDates": { @@ -3386,6 +3422,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -3396,6 +3433,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury. If the disabilityActionType is 'NEW', the serviceRelevance is required.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "approximateDate": { @@ -3458,6 +3496,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -3468,6 +3507,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "disabilityActionType": { @@ -3600,6 +3640,7 @@ "serviceBranch": { "description": "Branch of service during period. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "example": "Air Force" }, "serviceComponent": { @@ -3679,10 +3720,12 @@ "unitName": { "type": "string", "nullable": true, + "maxLength": 1000, "pattern": "^$|([a-zA-Z0-9\\-'.,# ][a-zA-Z0-9\\-'.,# ]?)*$" }, "unitAddress": { "type": "string", + "maxLength": 1000, "pattern": "^$|^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", "nullable": true }, @@ -3792,6 +3835,7 @@ "futureMilitaryRetiredPayExplanation": { "description": "Explains why future pay will be received.", "type": "string", + "maxLength": 1000, "example": "Will be retiring soon.", "nullable": true }, @@ -3803,6 +3847,7 @@ "branchOfService": { "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "nullable": true, "example": "Air Force" }, @@ -3858,6 +3903,7 @@ "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Air Force" }, "preTaxAmountReceived": { @@ -4690,6 +4736,7 @@ "serviceNumber": { "type": "string", "description": "Service identification number", + "maxLength": 1000, "nullable": true }, "veteranNumber": { @@ -4710,6 +4757,7 @@ "type": "string", "description": "Veteran's international phone number.", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -4752,6 +4800,7 @@ "description": "City for the Veteran's current mailing address.", "type": "string", "pattern": "^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -4763,6 +4812,7 @@ "country": { "description": "Country for the Veteran's current mailing address. Must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -4848,6 +4898,7 @@ "description": "City for the Veteran's new address.", "type": "string", "pattern": "^$|^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -4859,6 +4910,7 @@ "country": { "description": "Country for the Veteran's new address. Value must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -4978,6 +5030,7 @@ "description": "International phone of point of contact.", "type": "string", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -5012,12 +5065,14 @@ "type": "string", "nullable": true, "description": "Approximate begin date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" }, "endDate": { "type": "string", "nullable": true, "description": "Approximate end date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" } } @@ -5043,6 +5098,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Other location(s) where Veteran served." }, "serviceDates": { @@ -5096,6 +5152,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Exposure to asbestos." }, "exposureDates": { @@ -5134,12 +5191,14 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Hazard the Veteran was exposed to." }, "exposureLocation": { "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Location where the exposure happened." }, "exposureDates": { @@ -5191,6 +5250,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -5201,6 +5261,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury. If the disabilityActionType is 'NEW', the serviceRelevance is required.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "approximateDate": { @@ -5263,6 +5324,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -5273,6 +5335,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "disabilityActionType": { @@ -5405,6 +5468,7 @@ "serviceBranch": { "description": "Branch of service during period. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "example": "Air Force" }, "serviceComponent": { @@ -5484,10 +5548,12 @@ "unitName": { "type": "string", "nullable": true, + "maxLength": 1000, "pattern": "^$|([a-zA-Z0-9\\-'.,# ][a-zA-Z0-9\\-'.,# ]?)*$" }, "unitAddress": { "type": "string", + "maxLength": 1000, "pattern": "^$|^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", "nullable": true }, @@ -5597,6 +5663,7 @@ "futureMilitaryRetiredPayExplanation": { "description": "Explains why future pay will be received.", "type": "string", + "maxLength": 1000, "example": "Will be retiring soon.", "nullable": true }, @@ -5608,6 +5675,7 @@ "branchOfService": { "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "nullable": true, "example": "Air Force" }, @@ -5663,6 +5731,7 @@ "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Air Force" }, "preTaxAmountReceived": { @@ -6003,7 +6072,7 @@ "application/json": { "example": { "data": { - "id": "cf532e4e-e89e-4f9c-aebd-ce8361336a41", + "id": "bcf33b41-f27f-429c-b860-f2b71567d87e", "type": "forms/526", "attributes": { "veteran": { @@ -8087,8 +8156,8 @@ "id": "1", "type": "intent_to_file", "attributes": { - "creationDate": "2024-03-26", - "expirationDate": "2025-03-26", + "creationDate": "2024-04-23", + "expirationDate": "2025-04-23", "type": "compensation", "status": "active" } @@ -8807,7 +8876,7 @@ "status": "422", "detail": "Could not retrieve Power of Attorney due to multiple representatives with code: A1Q", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:112:in `representative'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:130:in `representative'" } } ] @@ -8906,7 +8975,7 @@ "application/json": { "example": { "data": { - "id": "29b16b36-3108-411f-9f5f-2c1c2e147ea3", + "id": "48a79d49-eccd-4a89-adb8-e2c91ed3fab5", "type": "individual", "attributes": { "code": "083", @@ -9108,7 +9177,7 @@ "status": "404", "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/individual_controller.rb:35:in `validate_individual_poa_code!'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } } ] @@ -9602,7 +9671,7 @@ "application/json": { "example": { "data": { - "id": "a7114d11-8ffd-4545-ad99-d70e74991e11", + "id": "7610ed19-baac-46fe-8ba5-5aa3e64a92ff", "type": "organization", "attributes": { "code": "083", @@ -9812,7 +9881,7 @@ "status": "404", "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/organization_controller.rb:35:in `validate_org_poa_code!'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } } ] @@ -10431,7 +10500,7 @@ "status": "404", "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/individual_controller.rb:35:in `validate_individual_poa_code!'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } } ] @@ -11126,7 +11195,7 @@ "status": "404", "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/organization_controller.rb:35:in `validate_org_poa_code!'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } } ] @@ -11562,11 +11631,11 @@ "application/json": { "example": { "data": { - "id": "7b0c58e1-4bf7-413c-a3ab-c8f6b95208b0", + "id": "09a36719-ad88-46b9-97d1-80a746ef9e81", "type": "claimsApiPowerOfAttorneys", "attributes": { "status": "submitted", - "dateRequestAccepted": "2024-03-26", + "dateRequestAccepted": "2024-04-23", "representative": { "serviceOrganization": { "poaCode": "074" @@ -11802,4 +11871,4 @@ } } ] -} +} \ No newline at end of file diff --git a/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json b/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json index 64add52afd5..83308517114 100644 --- a/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json +++ b/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json @@ -684,7 +684,7 @@ "lighthouseId": null, "maxEstClaimDate": null, "minEstClaimDate": null, - "status": "COMPLETE", + "status": "CANCELED", "submitterApplicationCode": "EBN", "submitterRoleCode": "VET", "supportingDocuments": [ @@ -1342,6 +1342,7 @@ "serviceNumber": { "type": "string", "description": "Service identification number", + "maxLength": 1000, "nullable": true }, "veteranNumber": { @@ -1362,6 +1363,7 @@ "type": "string", "description": "Veteran's international phone number.", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -1404,6 +1406,7 @@ "description": "City for the Veteran's current mailing address.", "type": "string", "pattern": "^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -1415,6 +1418,7 @@ "country": { "description": "Country for the Veteran's current mailing address. Must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -1500,6 +1504,7 @@ "description": "City for the Veteran's new address.", "type": "string", "pattern": "^$|^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -1511,6 +1516,7 @@ "country": { "description": "Country for the Veteran's new address. Value must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -1630,6 +1636,7 @@ "description": "International phone of point of contact.", "type": "string", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -1664,12 +1671,14 @@ "type": "string", "nullable": true, "description": "Approximate begin date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" }, "endDate": { "type": "string", "nullable": true, "description": "Approximate end date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" } } @@ -1695,6 +1704,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Other location(s) where Veteran served." }, "serviceDates": { @@ -1748,6 +1758,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Exposure to asbestos." }, "exposureDates": { @@ -1786,12 +1797,14 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Hazard the Veteran was exposed to." }, "exposureLocation": { "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Location where the exposure happened." }, "exposureDates": { @@ -1843,6 +1856,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -1853,6 +1867,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury. If the disabilityActionType is 'NEW', the serviceRelevance is required.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "approximateDate": { @@ -1915,6 +1930,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -1925,6 +1941,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "disabilityActionType": { @@ -2057,6 +2074,7 @@ "serviceBranch": { "description": "Branch of service during period. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "example": "Air Force" }, "serviceComponent": { @@ -2136,10 +2154,12 @@ "unitName": { "type": "string", "nullable": true, + "maxLength": 1000, "pattern": "^$|([a-zA-Z0-9\\-'.,# ][a-zA-Z0-9\\-'.,# ]?)*$" }, "unitAddress": { "type": "string", + "maxLength": 1000, "pattern": "^$|^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", "nullable": true }, @@ -2249,6 +2269,7 @@ "futureMilitaryRetiredPayExplanation": { "description": "Explains why future pay will be received.", "type": "string", + "maxLength": 1000, "example": "Will be retiring soon.", "nullable": true }, @@ -2260,6 +2281,7 @@ "branchOfService": { "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "nullable": true, "example": "Air Force" }, @@ -2315,6 +2337,7 @@ "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Air Force" }, "preTaxAmountReceived": { @@ -2602,6 +2625,7 @@ "serviceNumber": { "type": "string", "description": "Service identification number", + "maxLength": 1000, "nullable": true }, "veteranNumber": { @@ -2622,6 +2646,7 @@ "type": "string", "description": "Veteran's international phone number.", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -2664,6 +2689,7 @@ "description": "City for the Veteran's current mailing address.", "type": "string", "pattern": "^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -2675,6 +2701,7 @@ "country": { "description": "Country for the Veteran's current mailing address. Must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -2760,6 +2787,7 @@ "description": "City for the Veteran's new address.", "type": "string", "pattern": "^$|^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -2771,6 +2799,7 @@ "country": { "description": "Country for the Veteran's new address. Value must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -2890,6 +2919,7 @@ "description": "International phone of point of contact.", "type": "string", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -2924,12 +2954,14 @@ "type": "string", "nullable": true, "description": "Approximate begin date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" }, "endDate": { "type": "string", "nullable": true, "description": "Approximate end date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" } } @@ -2955,6 +2987,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Other location(s) where Veteran served." }, "serviceDates": { @@ -3008,6 +3041,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Exposure to asbestos." }, "exposureDates": { @@ -3046,12 +3080,14 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Hazard the Veteran was exposed to." }, "exposureLocation": { "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Location where the exposure happened." }, "exposureDates": { @@ -3103,6 +3139,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -3113,6 +3150,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury. If the disabilityActionType is 'NEW', the serviceRelevance is required.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "approximateDate": { @@ -3175,6 +3213,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -3185,6 +3224,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "disabilityActionType": { @@ -3317,6 +3357,7 @@ "serviceBranch": { "description": "Branch of service during period. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "example": "Air Force" }, "serviceComponent": { @@ -3396,10 +3437,12 @@ "unitName": { "type": "string", "nullable": true, + "maxLength": 1000, "pattern": "^$|([a-zA-Z0-9\\-'.,# ][a-zA-Z0-9\\-'.,# ]?)*$" }, "unitAddress": { "type": "string", + "maxLength": 1000, "pattern": "^$|^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", "nullable": true }, @@ -3509,6 +3552,7 @@ "futureMilitaryRetiredPayExplanation": { "description": "Explains why future pay will be received.", "type": "string", + "maxLength": 1000, "example": "Will be retiring soon.", "nullable": true }, @@ -3520,6 +3564,7 @@ "branchOfService": { "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "nullable": true, "example": "Air Force" }, @@ -3575,6 +3620,7 @@ "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Air Force" }, "preTaxAmountReceived": { @@ -4407,6 +4453,7 @@ "serviceNumber": { "type": "string", "description": "Service identification number", + "maxLength": 1000, "nullable": true }, "veteranNumber": { @@ -4427,6 +4474,7 @@ "type": "string", "description": "Veteran's international phone number.", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -4469,6 +4517,7 @@ "description": "City for the Veteran's current mailing address.", "type": "string", "pattern": "^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -4480,6 +4529,7 @@ "country": { "description": "Country for the Veteran's current mailing address. Must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -4565,6 +4615,7 @@ "description": "City for the Veteran's new address.", "type": "string", "pattern": "^$|^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -4576,6 +4627,7 @@ "country": { "description": "Country for the Veteran's new address. Value must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -4695,6 +4747,7 @@ "description": "International phone of point of contact.", "type": "string", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -4729,12 +4782,14 @@ "type": "string", "nullable": true, "description": "Approximate begin date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" }, "endDate": { "type": "string", "nullable": true, "description": "Approximate end date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" } } @@ -4760,6 +4815,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Other location(s) where Veteran served." }, "serviceDates": { @@ -4813,6 +4869,7 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Exposure to asbestos." }, "exposureDates": { @@ -4851,12 +4908,14 @@ "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Hazard the Veteran was exposed to." }, "exposureLocation": { "type": "string", "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Location where the exposure happened." }, "exposureDates": { @@ -4908,6 +4967,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -4918,6 +4978,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury. If the disabilityActionType is 'NEW', the serviceRelevance is required.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "approximateDate": { @@ -4980,6 +5041,7 @@ "type": "string", "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": [ "Agent Orange", "radiation", @@ -4990,6 +5052,7 @@ "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "disabilityActionType": { @@ -5122,6 +5185,7 @@ "serviceBranch": { "description": "Branch of service during period. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "example": "Air Force" }, "serviceComponent": { @@ -5201,10 +5265,12 @@ "unitName": { "type": "string", "nullable": true, + "maxLength": 1000, "pattern": "^$|([a-zA-Z0-9\\-'.,# ][a-zA-Z0-9\\-'.,# ]?)*$" }, "unitAddress": { "type": "string", + "maxLength": 1000, "pattern": "^$|^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", "nullable": true }, @@ -5314,6 +5380,7 @@ "futureMilitaryRetiredPayExplanation": { "description": "Explains why future pay will be received.", "type": "string", + "maxLength": 1000, "example": "Will be retiring soon.", "nullable": true }, @@ -5325,6 +5392,7 @@ "branchOfService": { "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "nullable": true, "example": "Air Force" }, @@ -5380,6 +5448,7 @@ "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", "nullable": true, + "maxLength": 1000, "example": "Air Force" }, "preTaxAmountReceived": { @@ -5720,7 +5789,7 @@ "application/json": { "example": { "data": { - "id": "8b3c6607-078b-419b-8549-726da40193df", + "id": "cfe5b467-a176-4987-80a9-4350ba73f350", "type": "forms/526", "attributes": { "veteran": { @@ -7804,8 +7873,8 @@ "id": "1", "type": "intent_to_file", "attributes": { - "creationDate": "2024-03-26", - "expirationDate": "2025-03-26", + "creationDate": "2024-04-23", + "expirationDate": "2025-04-23", "type": "compensation", "status": "active" } @@ -8524,7 +8593,7 @@ "status": "422", "detail": "Could not retrieve Power of Attorney due to multiple representatives with code: A1Q", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:112:in `representative'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:130:in `representative'" } } ] @@ -8623,7 +8692,7 @@ "application/json": { "example": { "data": { - "id": "9a9b6db5-abfc-45f3-ab60-785e3fb052ed", + "id": "74658dd8-0176-4bd4-ac22-beedcef627df", "type": "individual", "attributes": { "code": "083", @@ -8825,7 +8894,7 @@ "status": "404", "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/individual_controller.rb:35:in `validate_individual_poa_code!'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } } ] @@ -9319,7 +9388,7 @@ "application/json": { "example": { "data": { - "id": "618d9ba4-44cf-490a-bd56-8012b59b30e7", + "id": "f8eefcaa-020f-473e-9382-11dbd36f32ff", "type": "organization", "attributes": { "code": "083", @@ -9529,7 +9598,7 @@ "status": "404", "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/organization_controller.rb:35:in `validate_org_poa_code!'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } } ] @@ -10148,7 +10217,7 @@ "status": "404", "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/individual_controller.rb:35:in `validate_individual_poa_code!'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } } ] @@ -10843,7 +10912,7 @@ "status": "404", "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", "source": { - "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/organization_controller.rb:35:in `validate_org_poa_code!'" + "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } } ] @@ -11279,11 +11348,11 @@ "application/json": { "example": { "data": { - "id": "5d78a9f2-fffb-4867-a621-6ddee5bd5e58", + "id": "c08567c4-6f1d-49bb-8416-01b91642b301", "type": "claimsApiPowerOfAttorneys", "attributes": { "status": "submitted", - "dateRequestAccepted": "2024-03-26", + "dateRequestAccepted": "2024-04-23", "representative": { "serviceOrganization": { "poaCode": "074" @@ -11519,4 +11588,4 @@ } } ] -} +} \ No newline at end of file diff --git a/modules/claims_api/config/schemas/v2/526.json b/modules/claims_api/config/schemas/v2/526.json index c498373a404..fe5cc33d1bc 100644 --- a/modules/claims_api/config/schemas/v2/526.json +++ b/modules/claims_api/config/schemas/v2/526.json @@ -27,6 +27,7 @@ "serviceNumber": { "type": ["null", "string"], "description": "Service identification number", + "maxLength": 1000, "nullable": true }, "veteranNumber": { @@ -47,6 +48,7 @@ "type": ["string", "null"], "description": "Veteran's international phone number.", "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -89,6 +91,7 @@ "description": "City for the Veteran's current mailing address.", "type": "string", "pattern": "^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -100,6 +103,7 @@ "country": { "description": "Country for the Veteran's current mailing address. Must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -182,6 +186,7 @@ "description": "City for the Veteran's new address.", "type": "string", "pattern": "^$|^([-a-zA-Z0-9'.#]([-a-zA-Z0-9'.# ])?)+$", + "maxLength": 1000, "example": "Portland" }, "state": { @@ -193,6 +198,7 @@ "country": { "description": "Country for the Veteran's new address. Value must match the values returned by the /countries endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current).", "type": "string", + "maxLength": 1000, "example": "USA" }, "zipFirstFive": { @@ -314,6 +320,7 @@ "description": "International phone of point of contact.", "type": ["string", "null"], "example": "+44 20 1234 5678", + "maxLength": 1000, "nullable": true } } @@ -345,12 +352,14 @@ "type": ["string", "null"], "nullable": true, "description": "Approximate begin date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" }, "endDate": { "type": ["string", "null"], "nullable": true, "description": "Approximate end date for serving in Gulf War hazard location.", + "pattern": "^(?:19|20)[0-9][0-9]$|^(?:19|20)[0-9][0-9]-(0[1-9]|1[0-2])$", "example": "2018-06 or 2018" } } @@ -373,6 +382,7 @@ "type": ["string", "null"], "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Other location(s) where Veteran served." }, "serviceDates": { @@ -427,6 +437,7 @@ "type": ["string", "null"], "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 5000, "description": "Exposure to asbestos." }, "exposureDates": { @@ -465,12 +476,14 @@ "type": ["string", "null"], "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Hazard the Veteran was exposed to." }, "exposureLocation": { "type": ["string", "null"], "nullable": true, "pattern": "^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", + "maxLength": 1000, "description": "Location where the exposure happened." }, "exposureDates": { @@ -519,12 +532,14 @@ "type": ["string", "null"], "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": ["Agent Orange", "radiation", "burn pits"] }, "serviceRelevance": { "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury. If the disabilityActionType is 'NEW', the serviceRelevance is required.", "type": ["string", "null"], "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "approximateDate": { @@ -583,12 +598,14 @@ "type": ["string", "null"], "description": "What caused the disability?", "nullable": true, + "maxLength": 1000, "examples": ["Agent Orange", "radiation", "burn pits"] }, "serviceRelevance": { "description": "Explanation of how the disability(ies) relates to the in-service event/exposure/injury.", "type": ["string", "null"], "nullable": true, + "maxLength": 1000, "example": "Heavy equipment operator in service." }, "disabilityActionType": { @@ -705,6 +722,7 @@ "serviceBranch": { "description": "Branch of service during period. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": "string", + "maxLength": 1000, "example": "Air Force" }, "serviceComponent": { @@ -774,10 +792,12 @@ "unitName": { "type": ["string", "null"], "nullable": true, + "maxLength": 1000, "pattern": "^$|([a-zA-Z0-9\\-'.,# ][a-zA-Z0-9\\-'.,# ]?)*$" }, "unitAddress": { "type": ["string", "null"], + "maxLength": 1000, "pattern": "^$|^([-a-zA-Z0-9'.,&#]([-a-zA-Z0-9'.,&# ])?)+$", "nullable": true }, @@ -878,6 +898,7 @@ "futureMilitaryRetiredPayExplanation": { "description": "Explains why future pay will be received.", "type": ["string", "null"], + "maxLength": 1000, "example": "Will be retiring soon.", "nullable": true }, @@ -889,6 +910,7 @@ "branchOfService": { "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": ["string", "null"], + "maxLength": 1000, "nullable": true, "example": "Air Force" }, @@ -942,6 +964,7 @@ "description": "Branch of service. The /service-branches endpoint on the [Benefits Reference Data API](https://developer.va.gov/explore/benefits/docs/benefits_reference_data?version=current) may be used to retrieve list of possible service branches.", "type": ["string", "null"], "nullable": true, + "maxLength": 1000, "example": "Air Force" }, "preTaxAmountReceived": { From 4995a8a476cdbe4e0d8ab619f56aa3e8a3f35a35 Mon Sep 17 00:00:00 2001 From: Aurora <19178435+aurora-a-k-a-lightning@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:57:32 -0700 Subject: [PATCH 10/25] bdex/80773: Toxic Exposure - [Lighthouse API] generatePdf hook up (#16411) * dbex/80773: enable benefits_claims/service#submit526 to call LH's /generatePDF endpoint * bdex/80773: enable benefits_claims/service#submit526 to call LH's /generatePDF endpoint * bdex/80773: enable benefits_claims/service#submit526 to call LH's /generatePDF endpoint * linting fix * bdex/80773: add removal of unicode carriage return and new line characters * bdex/80773: add generate pdf option unit test --------- Co-authored-by: Seth Darr <92405130+sethdarragile6@users.noreply.github.com> Co-authored-by: Seth Darr --- .../benefits_claims/configuration.rb | 2 +- lib/lighthouse/benefits_claims/service.rb | 42 +++++++-- .../benefits_claims/service_spec.rb | 9 ++ .../submit526/200_response_generate_pdf.yml | 85 +++++++++++++++++++ 4 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 spec/support/vcr_cassettes/lighthouse/benefits_claims/submit526/200_response_generate_pdf.yml diff --git a/lib/lighthouse/benefits_claims/configuration.rb b/lib/lighthouse/benefits_claims/configuration.rb index 394611f02d8..72e714d2f80 100644 --- a/lib/lighthouse/benefits_claims/configuration.rb +++ b/lib/lighthouse/benefits_claims/configuration.rb @@ -13,7 +13,7 @@ module BenefitsClaims class Configuration < Common::Client::Configuration::REST self.read_timeout = Settings.lighthouse.benefits_claims.timeout || 20 - API_SCOPES = %w[system/claim.read system/claim.write].freeze + API_SCOPES = %w[system/claim.read system/claim.write system/526-pdf.override].freeze CLAIMS_PATH = 'services/claims/v2/veterans' TOKEN_PATH = 'oauth2/claims/system/v1/token' diff --git a/lib/lighthouse/benefits_claims/service.rb b/lib/lighthouse/benefits_claims/service.rb index 46f200a43ea..57a8f83f54b 100644 --- a/lib/lighthouse/benefits_claims/service.rb +++ b/lib/lighthouse/benefits_claims/service.rb @@ -102,7 +102,8 @@ def create_intent_to_file(type, claimant_ssn, lighthouse_client_id = nil, lighth handle_error(e, lighthouse_client_id, endpoint) end - # submit form526 to Lighthouse API endpoint: /services/claims/v2/veterans/{veteranId}/526 + # submit form526 to Lighthouse API endpoint: /services/claims/v2/veterans/{veteranId}/526 or + # /services/claims/v2/veterans/{veteranId}/526/generatePdf # @param [hash || Requests::Form526] body: a hash representing the form526 # attributes in the Lighthouse request schema # @param [string] lighthouse_client_id: the lighthouse_client_id requested from Lighthouse @@ -111,28 +112,31 @@ def create_intent_to_file(type, claimant_ssn, lighthouse_client_id = nil, lighth # @option options [hash] :body_only only return the body from the request # @option options [string] :aud_claim_url option to override the aud_claim_url for LH Veteran Verification APIs # @option options [hash] :auth_params a hash to send in auth params to create the access token + # @option options [hash] :generate_pdf call the generatePdf endpoint to receive the 526 pdf def submit526(body, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, options = {}) - endpoint = 'benefits_claims/form/526' + endpoint = '{icn}/526' path = "#{@icn}/526" + if options[:generate_pdf].present? + path += '/generatePDF/minimum-validations' + endpoint += '/generatePDF/minimum-validations' + end + # if we're coming straight from the transformation service without # making this a jsonapi request body first ({data: {type:, attributes}}), # this will put it in the correct format for transmission - body = { - data: { - type: 'form/526', - attributes: body - } - }.as_json.deep_transform_keys { |k| k.camelize(:lower) } + body = build_request_body(body) # Inflection settings force 'current_va_employee' to render as 'currentVAEmployee' in the above camelize() call # Since Lighthouse needs 'currentVaEmployee', the following workaround renames it. fix_current_va_employee(body) + json_body = remove_unicode_characters(body) + response = config.post( path, - body, + json_body, lighthouse_client_id, lighthouse_rsa_key_path, options ) @@ -143,6 +147,26 @@ def submit526(body, lighthouse_client_id = nil, lighthouse_rsa_key_path = nil, o private + def build_request_body(body) + { + data: { + type: 'form/526', + attributes: body + } + }.as_json.deep_transform_keys { |k| k.camelize(:lower) } + end + + # this gsubbing is to fix an issue where the service that generates the 526PDF was failing due to + # unicoded carriage returns: + # i.e.: \n was throwing: "U+000A ('controlLF') is not available in the font Helvetica, encoding: WinAnsiEncoding" + def remove_unicode_characters(body) + body.to_json + .gsub('\\n', ' ') + .gsub('\\r', ' ') + .gsub('\\\\n', ' ') + .gsub('\\\\r', ' ') + end + def fix_current_va_employee(body) if body.dig('data', 'attributes', 'veteranIdentification')&.select do |field| field['currentVAEmployee'] diff --git a/spec/lib/lighthouse/benefits_claims/service_spec.rb b/spec/lib/lighthouse/benefits_claims/service_spec.rb index d5ecd4fe022..05d1fe2e084 100644 --- a/spec/lib/lighthouse/benefits_claims/service_spec.rb +++ b/spec/lib/lighthouse/benefits_claims/service_spec.rb @@ -113,6 +113,15 @@ expect(response.claim_id).to eq(1_234_567_890) end end + + context 'when given the option to use generate pdf' do + it 'calls the generate pdf endpoint' do + VCR.use_cassette('lighthouse/benefits_claims/submit526/200_response_generate_pdf') do + raw_response = @service.submit526({}, '', '', { generate_pdf: true }) + expect(raw_response.body).to eq('No example available') + end + end + end end end end diff --git a/spec/support/vcr_cassettes/lighthouse/benefits_claims/submit526/200_response_generate_pdf.yml b/spec/support/vcr_cassettes/lighthouse/benefits_claims/submit526/200_response_generate_pdf.yml new file mode 100644 index 00000000000..19741d9cff9 --- /dev/null +++ b/spec/support/vcr_cassettes/lighthouse/benefits_claims/submit526/200_response_generate_pdf.yml @@ -0,0 +1,85 @@ +--- +http_interactions: +- request: + method: post + uri: https://sandbox-api.va.gov/services/claims/v2/veterans/123498767V234859/526/generatePDF/minimum-validations + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Authorization: + - Bearer blahblahblah + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 28 Feb 2023 21:02:39 GMT + Content-Type: + - text/html; charset=utf-8 + Connection: + - keep-alive + X-Ratelimit-Remaining-Minute: + - '59' + X-Ratelimit-Limit-Minute: + - '60' + Ratelimit-Remaining: + - '59' + Ratelimit-Limit: + - '60' + Ratelimit-Reset: + - '25' + Etag: + - W/"6571c42e57529000188d704a3cd1f46a" + Referrer-Policy: + - strict-origin-when-cross-origin + Vary: + - Origin + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - SAMEORIGIN + X-Git-Sha: + - b20885293917fd081d24899644d2718d2ab4ccf9 + X-Github-Repository: + - https://github.com/department-of-veterans-affairs/vets-api + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - d687047e-5004-43c1-babb-c2f52f2fda40 + X-Runtime: + - '3.569014' + X-Xss-Protection: + - 1; mode=block + Access-Control-Allow-Origin: + - "*" + X-Kong-Upstream-Latency: + - '3573' + X-Kong-Proxy-Latency: + - '24' + Via: + - kong/3.0.2 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Cache-Control: + - no-cache, no-store + Pragma: + - no-cache + Transfer-Encoding: + - chunked + body: + encoding: ASCII-8BIT + string: 'No example available' + recorded_at: Tue, 28 Feb 2023 21:02:39 GMT +recorded_with: VCR 6.1.0 From 3197afd9afbcf1db0438bb67515e47c83a494794 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Apr 2024 08:29:26 -0400 Subject: [PATCH 11/25] Bump parallel_tests from 4.6.1 to 4.7.0 (#16473) Bumps [parallel_tests](https://github.com/grosser/parallel_tests) from 4.6.1 to 4.7.0. - [Changelog](https://github.com/grosser/parallel_tests/blob/master/CHANGELOG.md) - [Commits](https://github.com/grosser/parallel_tests/compare/v4.6.1...v4.7.0) --- updated-dependencies: - dependency-name: parallel_tests dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index fb14fa4d562..c93cfb9372a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -692,7 +692,7 @@ GEM os (1.1.4) ox (2.14.18) parallel (1.24.0) - parallel_tests (4.6.1) + parallel_tests (4.7.0) parallel parser (3.3.0.5) ast (~> 2.4.1) From 709e36e30fe0068a371caa3c8a60d087a723b237 Mon Sep 17 00:00:00 2001 From: Kevin Suarez Date: Wed, 24 Apr 2024 09:52:16 -0400 Subject: [PATCH 12/25] 80453 pt2 rehydrate 5655 controller (#16459) * 80453 create a method to upsert IPFs based on 5655 metadata * move user verification logic out of UserVerification model at reviewer's request * 80453 add rehydration controller methods * linter or leave 'er am I right? --- .../v0/financial_status_reports_controller.rb | 22 ++++++++++++ modules/debts_api/config/routes.rb | 3 ++ .../debts_api/v0/fsr_rehydration_service.rb | 19 ++++++++++ ...inancial_status_reports_controller_spec.rb | 35 +++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 modules/debts_api/lib/debts_api/v0/fsr_rehydration_service.rb diff --git a/modules/debts_api/app/controllers/debts_api/v0/financial_status_reports_controller.rb b/modules/debts_api/app/controllers/debts_api/v0/financial_status_reports_controller.rb index 76ec33c8869..1cff11148e6 100644 --- a/modules/debts_api/app/controllers/debts_api/v0/financial_status_reports_controller.rb +++ b/modules/debts_api/app/controllers/debts_api/v0/financial_status_reports_controller.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'debts_api/v0/financial_status_report_service' +require 'debts_api/v0/fsr_rehydration_service' module DebtsApi module V0 @@ -23,6 +24,27 @@ def download_pdf ) end + def submissions + submissions = DebtsApi::V0::Form5655Submission.where(user_uuid: current_user.uuid) + render json: { 'submissions' => submissions.map { |sub| { 'id' => sub.id } } } + end + + def rehydrate + submission_id = params[:submission_id] + + DebtsApi::V0::FsrRehydrationService.attempt_rehydration(user_uuid: current_user.uuid, submission_id:) + + render json: { result: 'FSR rehydrated' } + rescue ActiveRecord::RecordNotFound + render json: { error: "Form5655Submission record #{submission_id} not found." }, status: :not_found + rescue DebtsApi::V0::FsrRehydrationService::UserDoesNotOwnsubmission + render json: { error: "User #{current_user.uuid} does not own submission #{submission_id}" }, + status: :unauthorized + rescue DebtsApi::V0::FsrRehydrationService::NoInProgressFormDataStored + render json: { error: "Form5655Submission record #{submission_id} missing InProgressForm data", + status: :not_found } + end + private def render_not_found diff --git a/modules/debts_api/config/routes.rb b/modules/debts_api/config/routes.rb index 6b3ab5c1b7a..5fbb494ba96 100644 --- a/modules/debts_api/config/routes.rb +++ b/modules/debts_api/config/routes.rb @@ -5,9 +5,12 @@ resources :financial_status_reports, only: %i[create] do collection do get :download_pdf + get :submissions end end + get 'financial_status_reports/rehydrate_submission/:submission_id', to: 'financial_status_reports#rehydrate' + post 'calculate_total_assets', to: 'financial_status_reports_calculations#total_assets' post 'calculate_monthly_expenses', to: 'financial_status_reports_calculations#monthly_expenses' post 'calculate_all_expenses', to: 'financial_status_reports_calculations#all_expenses' diff --git a/modules/debts_api/lib/debts_api/v0/fsr_rehydration_service.rb b/modules/debts_api/lib/debts_api/v0/fsr_rehydration_service.rb new file mode 100644 index 00000000000..c66130b30b5 --- /dev/null +++ b/modules/debts_api/lib/debts_api/v0/fsr_rehydration_service.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module DebtsApi + class V0::FsrRehydrationService + include SentryLogging + + class UserDoesNotOwnsubmission < StandardError; end + class NoInProgressFormDataStored < StandardError; end + + def self.attempt_rehydration(user_uuid:, submission_id:) + submission = DebtsApi::V0::Form5655Submission.find(submission_id) + + raise NoInProgressFormDataStored unless submission.ipf_data + raise UserDoesNotOwnsubmission unless submission.user_uuid == user_uuid + + submission.upsert_in_progress_form + end + end +end diff --git a/modules/debts_api/spec/request/debts_api/v0/financial_status_reports_controller_spec.rb b/modules/debts_api/spec/request/debts_api/v0/financial_status_reports_controller_spec.rb index 63be330783b..35f7955f963 100644 --- a/modules/debts_api/spec/request/debts_api/v0/financial_status_reports_controller_spec.rb +++ b/modules/debts_api/spec/request/debts_api/v0/financial_status_reports_controller_spec.rb @@ -59,4 +59,39 @@ def mock_pdf_fill expect(response.body).to eq(content) end end + + describe '#rehydrate' do + context 'on a nonexistent submission' do + it 'renders a 404' do + get '/debts_api/v0/financial_status_reports/rehydrate_submission/1' + expect(response).to have_http_status(:not_found) + end + end + + context 'on a submission you don\'t own' do + let(:form5655_submission) { create(:debts_api_form5655_submission) } + + it 'renders a 404' do + form5655_submission + form5655_submission.update!(user_uuid: 'nottherightguy', ipf_data: '{"its":"me"}') + get "/debts_api/v0/financial_status_reports/rehydrate_submission/#{form5655_submission.id}" + expect(response.code).to eq('401') + body = "{\"error\":\"User #{user.uuid} does not own submission #{form5655_submission.id}\"}" + expect(response.body).to eq(body) + end + end + + context 'on a submission you do own' do + let(:form5655_submission) do + create(:debts_api_form5655_submission, user_uuid: 'b2fab2b56af045e1a9e2394347af91ef') + end + + it 'rehydrates In Progress Form' do + form5655_submission + form5655_submission.update!(user_uuid: user.uuid, ipf_data: '{"its":"me"}') + get "/debts_api/v0/financial_status_reports/rehydrate_submission/#{form5655_submission.id}" + expect(response.code).to eq('200') + end + end + end end From a267cc85a78a10618d62a9ed4fa6d0d3c367ac04 Mon Sep 17 00:00:00 2001 From: Richard Davis Date: Wed, 24 Apr 2024 10:05:48 -0400 Subject: [PATCH 13/25] Adds mhv_landing_page_enable_va_gov_health_tools_links feature toggle (#16398) --- config/features.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/features.yml b/config/features.yml index 49463e5e0e6..79b167cdef5 100644 --- a/config/features.yml +++ b/config/features.yml @@ -730,6 +730,9 @@ features: actor_type: user description: Enables/disables refill-related content for Medications on VA.gov enable_in_development: true + mhv_landing_page_enable_va_gov_health_tools_links: + actor_type: user + description: Enables VA.gov Health Tools links (Appts, SM, Rx, Records) on MHV-on-VA.gov Landing Page mhv_to_logingov_account_transition: actor_type: cookie_id description: Enables/disables MHV to Login.gov account transfer experience (Identity) From da4c68f073ce4de80f2f980a2eea3f0bef57c9ec Mon Sep 17 00:00:00 2001 From: Corey Ferris Date: Wed, 24 Apr 2024 11:05:05 -0400 Subject: [PATCH 14/25] manila timezone info logging (#16468) * manila timezone info logging --- .../services/vaos/v2/appointments_service.rb | 22 +++++++ .../services/v2/appointment_service_spec.rb | 62 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/modules/vaos/app/services/vaos/v2/appointments_service.rb b/modules/vaos/app/services/vaos/v2/appointments_service.rb index 6a3eacbb338..d9bd6d153b3 100644 --- a/modules/vaos/app/services/vaos/v2/appointments_service.rb +++ b/modules/vaos/app/services/vaos/v2/appointments_service.rb @@ -15,6 +15,7 @@ class AppointmentsService < VAOS::SessionService FACILITY_ERROR_MSG = 'Error fetching facility details' AVS_ERROR_MESSAGE = 'Error retrieving AVS link' AVS_APPT_TEST_ID = '192308' + MANILA_PHILIPPINES_FACILITY_ID = '358' AVS_FLIPPER = :va_online_scheduling_after_visit_summary ORACLE_HEALTH_CANCELLATIONS = :va_online_scheduling_enable_OH_cancellations @@ -411,15 +412,36 @@ def convert_appointment_time(appt) if !appt[:start].nil? facility_timezone = get_facility_timezone_memoized(appt[:location_id]) appt[:local_start_time] = convert_utc_to_local_time(appt[:start], facility_timezone) + + if appt[:location_id] == MANILA_PHILIPPINES_FACILITY_ID + log_timezone_info(appt[:location_id], facility_timezone, appt[:start], appt[:local_start_time]) + end + elsif !appt.dig(:requested_periods, 0, :start).nil? appt[:requested_periods].each do |period| facility_timezone = get_facility_timezone_memoized(appt[:location_id]) period[:local_start_time] = convert_utc_to_local_time(period[:start], facility_timezone) + + if appt[:location_id] == MANILA_PHILIPPINES_FACILITY_ID + log_timezone_info(appt[:location_id], facility_timezone, period[:start], period[:local_start_time]) + end end end appt end + def log_timezone_info(appt_location_id, facility_timezone, appt_start_time_utc, appt_start_time_local) + Rails.logger.info( + "Timezone info for Manila Philippines location_id #{appt_location_id}", + { + location_id: appt_location_id, + facility_timezone:, + appt_start_time_utc:, + appt_start_time_local: + }.to_json + ) + end + # Returns a local [DateTime] object converted from UTC using the facility's timezone offset. # We'd like to perform this change only on the appointment responses to offer a consistently # formatted local time to our consumers while not changing how we pass DateTimes to upstream services. diff --git a/modules/vaos/spec/services/v2/appointment_service_spec.rb b/modules/vaos/spec/services/v2/appointment_service_spec.rb index 5ff40013f14..88c2486408c 100644 --- a/modules/vaos/spec/services/v2/appointment_service_spec.rb +++ b/modules/vaos/spec/services/v2/appointment_service_spec.rb @@ -623,6 +623,68 @@ end end + describe '#convert_appointment_time' do + let(:manila_appt) do + { + id: '12345', + location_id: '358', + start: '2024-12-20T00:00:00Z' + } + end + + let(:manila_appt_req) do + { + id: '12345', + location_id: '358', + requested_periods: [{ start: '2024-12-20T00:00:00Z', end: '2024-12-20T11:59:59.999Z' }] + } + end + + context 'when appt location id is 358' do + it 'logs the appt location id, timezone info, utc/local times of appt' do + allow_any_instance_of(VAOS::V2::AppointmentsService) + .to receive(:get_facility_timezone_memoized) + .and_return('Asia/Manila') + allow(Rails.logger).to receive(:info) + + subject.send(:convert_appointment_time, manila_appt) + expect(Rails.logger).to have_received(:info).with('Timezone info for Manila Philippines location_id 358', + { + location_id: '358', + facility_timezone: 'Asia/Manila', + appt_start_time_utc: '2024-12-20T00:00:00Z', + appt_start_time_local: subject.send( + :convert_utc_to_local_time, + manila_appt[:start], + 'Asia/Manila' + ) + }.to_json) + end + + it 'logs the appt location id, timezone info, utc/local times of appt request' do + allow_any_instance_of(VAOS::V2::AppointmentsService) + .to receive(:get_facility_timezone_memoized) + .and_return('Asia/Manila') + allow(Rails.logger).to receive(:info) + + subject.send(:convert_appointment_time, manila_appt_req) + expect(Rails.logger).to have_received(:info).with('Timezone info for Manila Philippines location_id 358', + { + location_id: '358', + facility_timezone: 'Asia/Manila', + appt_start_time_utc: '2024-12-20T00:00:00Z', + appt_start_time_local: subject.send( + :convert_utc_to_local_time, manila_appt_req.dig( + :requested_periods, + 0, + :start + ), 'Asia/Manila' + ) + }.to_json) + end + end + end + describe '#convert_utc_to_local_time' do let(:start_datetime) { '2021-09-02T14:00:00Z'.to_datetime } From 994c71fbc252d294f2818c8149676e29f435ee44 Mon Sep 17 00:00:00 2001 From: Sam Stuckey Date: Wed, 24 Apr 2024 11:19:07 -0400 Subject: [PATCH 15/25] [DBX-80624] add 526 states for remediation audit (#16455) * [DBX-80624] add 526 states for remediation audit * typos --- app/models/form526_submission.rb | 31 ++++++++++++++++++++++++-- spec/models/form526_submission_spec.rb | 4 ++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/models/form526_submission.rb b/app/models/form526_submission.rb index a16f90192a8..86f24ed8151 100644 --- a/app/models/form526_submission.rb +++ b/app/models/form526_submission.rb @@ -18,7 +18,8 @@ class Form526Submission < ApplicationRecord state :unprocessed, initial: true state :delivered_to_primary, :failed_primary_delivery, :rejected_by_primary, :delivered_to_backup, :failed_backup_delivery, :rejected_by_backup, - :in_remediation, :finalized_as_successful, :unprocessable + :in_remediation, :finalized_as_successful, :unprocessable, + :processed_in_batch_remediation, :ignorable_duplicate # - a submission has been delivered to our happy path # - requires polling to finalize @@ -62,7 +63,6 @@ class Form526Submission < ApplicationRecord transitions to: :in_remediation end - # TODO: add this transition when we add 526 completion polling # - The only state that means we no longer own completion of this submission # - There is nothing more to do. E.G. # - VBMS has accepted and returned the applicable status to us via @@ -78,6 +78,33 @@ class Form526Submission < ApplicationRecord event :mark_as_unprocessable do transitions to: :unprocessable end + + # A special state to indicate this was part of our remediation 'batching' + # process in 2023. These were handled manually and are distinct from `in_remediation` + # in that they were not tracked at the time of remediation, but rather later in + # the 2024 526 State audit. + # + # This state is useful to us at the time of creation, but may be something + # to flatten to a simple `finalized_as_successful` in the future. + event :process_in_batch_remediation do + transitions to: :processed_in_batch_remediation + end + + # A special state to indicate this was part of our remediation 'batching' + # process in 2023. These submissions may have been processed or not, but + # we don't care because they have an earlier, successful duplicate. + # + # Duplicates are identified by comparing form_json, using this script: + # https://github.com/department-of-veterans-affairs/va.gov-team-sensitive/blob/master/teams/benefits/scripts/526/submission_deduper.rb + # The result of this script can be evaluated by a qualified stakeholder to make + # a judgement call on whether or not a submission is a 'perfect' duplicate. + # + # IF a submission is found to be an exact duplicate of another + # AND its duplicate was previously submitted / remediated successfully + # THEN we can ignore it as a duplicate + event :ignore_as_duplicate do + transitions to: :ignorable_duplicate + end end wrap_with_logging(:start_evss_submission_job, diff --git a/spec/models/form526_submission_spec.rb b/spec/models/form526_submission_spec.rb index 5084dd9724f..ee207a30ffe 100644 --- a/spec/models/form526_submission_spec.rb +++ b/spec/models/form526_submission_spec.rb @@ -103,6 +103,10 @@ .to(:unprocessable).on_event(:mark_as_unprocessable) expect(submission).to transition_from(:unprocessed) .to(:in_remediation).on_event(:begin_remediation) + expect(submission).to transition_from(:unprocessed) + .to(:processed_in_batch_remediation).on_event(:process_in_batch_remediation) + expect(submission).to transition_from(:unprocessed) + .to(:ignorable_duplicate).on_event(:ignore_as_duplicate) end end From c1787f039475a9057c42162fffa000751d3de090 Mon Sep 17 00:00:00 2001 From: stevenjcumming <134282106+stevenjcumming@users.noreply.github.com> Date: Wed, 24 Apr 2024 13:01:17 -0400 Subject: [PATCH 16/25] Upgrade Debian to Bookworm (master) (#16454) * update debian to bookworm * add test_client.p12 * update ruby version to 2.3.3 * testing with connect_vbms 0.2.0.rc * add back ruby platform to Gemfile.lock * update connect_vbms gem to ad hoc fork * add trailing new line to Dockerfile --- Dockerfile | 17 +++------- Gemfile | 2 +- Gemfile.lock | 31 +++++++++--------- .../claims_api/spec/fixtures/test_client.p12 | Bin 4339 -> 4323 bytes 4 files changed, 22 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index 11836e43a76..96c748bbb5a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ -ARG RELEASE=bullseye -FROM ruby:3.2.3-slim-${RELEASE} as rubyimg +FROM ruby:3.2.3-slim-bookworm as rubyimg # XXX: using stretch here for pdftk dep, which is not availible after # stretch (or in alpine) and is switched automatically to pdftk-java in buster @@ -18,21 +17,15 @@ RUN find modules -type f ! \( -name Gemfile -o -name "*.gemspec" -o -path "*/lib # shared build/settings for all child images, reuse these layers yo ### FROM rubyimg AS base -ARG RELEASE -ENV RELEASE="$RELEASE" ARG userid=993 SHELL ["/bin/bash", "-c"] RUN groupadd -g $userid -r vets-api && \ useradd -u $userid -r -m -d /srv/vets-api -g vets-api vets-api -RUN echo "APT::Default-Release \"${RELEASE}\";" >> /etc/apt/apt.conf.d/99defaultrelease -RUN mv /etc/apt/sources.list /etc/apt/sources.list.d/stable.list -RUN echo "deb http://ftp.debian.org/debian testing main contrib non-free" >> /etc/apt/sources.list.d/testing.list -RUN echo "deb http://deb.debian.org/debian unstable main" >> /etc/apt/sources.list.d/unstable.list -RUN apt-get update -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -t "${RELEASE}" \ - dumb-init imagemagick pdftk poppler-utils curl libpq5 vim libboost-all-dev \ - clamav clamdscan clamav-daemon +RUN apt-get update --fix-missing +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates-java && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y dumb-init imagemagick pdftk poppler-utils curl \ + libpq5 vim libboost-all-dev clamav clamdscan clamav-daemon # The pki work below is for parity with the non-docker BRD deploys to mount certs into # the container, we need to get rid of it and refactor the configuration bits into diff --git a/Gemfile b/Gemfile index 3d0de296b6e..94355520763 100644 --- a/Gemfile +++ b/Gemfile @@ -58,7 +58,7 @@ gem 'carrierwave-aws' gem 'clam_scan' gem 'combine_pdf' gem 'config' -gem 'connect_vbms', git: 'https://github.com/department-of-veterans-affairs/connect_vbms.git', branch: 'master', require: 'vbms' +gem 'connect_vbms', git: 'https://github.com/adhocteam/connect_vbms', tag: 'v2.0.0.rc', require: 'vbms' gem 'date_validator' gem 'ddtrace' gem 'dogstatsd-ruby', '5.6.1' diff --git a/Gemfile.lock b/Gemfile.lock index c93cfb9372a..c97180f9bf7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,17 @@ +GIT + remote: https://github.com/adhocteam/connect_vbms + revision: 6e5dc751afaf0da9c7cbc10c94b909f114f3a156 + tag: v2.0.0.rc + specs: + connect_vbms (2.0.0.rc) + httpclient (~> 2.8.0) + httpi (~> 2.4) + mail + nokogiri (>= 1.8.4) + nori + xmldsig (~> 0.3.1) + xmlenc + GIT remote: https://github.com/department-of-veterans-affairs/apivore revision: f8ccd476f6c5301f5ebe4e2dd5b30ff0e567ffc1 @@ -30,20 +44,6 @@ GIT nokogiri (>= 1.13.6) savon (= 2.12) -GIT - remote: https://github.com/department-of-veterans-affairs/connect_vbms.git - revision: 1834cf61310001c82e2e96d665518407c3bce947 - branch: master - specs: - connect_vbms (1.4.0) - httpclient (~> 2.8.0) - httpi (~> 2.4) - mail - nokogiri (>= 1.8.4) - nori - xmldsig (~> 0.3.1) - xmlenc - GIT remote: https://github.com/department-of-veterans-affairs/fhir_client.git revision: 52e0197dcb1f940a1f0b28bfa983699f0c199696 @@ -663,7 +663,8 @@ GEM nokogiri (1.16.4) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nori (2.6.0) + nori (2.7.0) + bigdecimal notiffany (0.1.3) nenv (~> 0.1) shellany (~> 0.0) diff --git a/modules/claims_api/spec/fixtures/test_client.p12 b/modules/claims_api/spec/fixtures/test_client.p12 index 48fde3d8efab2dbbec58bda1c493cdb90c89613c..b0e862698e9072cd7538cda312593296ed262dcd 100644 GIT binary patch literal 4323 zcmai&S2P?7*M`lQ8H^H1L~o7W5G{H;4AF@mEzw4= zNeDuM5Walt|JON}-^E^g?f1RdS9?A0+HeHr8W2DTM^I)$NciG3}3M!s6Bzz+N~{h?mL5~bR-(9(WPM#rERJu4Rd|M6p;?scz&yXqa#z|#O1N*`rD34=m^Nb zuonh!tt0_Uc~_)3k{EagLT}`>D;3omIwf0MU#lx`$KHFZa#wqAV`*aGAOnV{y0+8ex^w-=EGl}YyEM_ zeFDq!(!;c6j_IW@FeB}uDNuSU+Z+GDjUanfXT4}ID;riDzeFz%9d0mtf@sFj>HDQ_ z>#HVI$XA+yt?q2|2-8p=+joX)Q z`HTW$&_l8M+hb2fzfwIRnKk)ek^o|HPsQ#p6GT`0SZWuS3L)|bNw`7_I$xEe;p(Dx zcHqsK$sXNlKe^fPy0csA`}(Z*>txiW)3ou#W_kIx_-cVEi8A|3iFYkq4d}zQA?7kP=11LIPd!(q%z9|Oe zEshaskW8AEbm{t@VxD#?4NrQ^uS)aom=>>obK8DJ7_j{Y!OS2ZbaYwH_e})lE|G)z zpd_6o9IA+{0yS`*mGb#nmvoemZ4Hr-?aU$~C|)TOl6Rv(oeG2aJC*O|)g1@-saNu$ z#b++B2zmDAj%{mU&=j4=8)0NcZ-VBaM3V~7vgX-cd6-g*MOOEXUsgnJu3m>mAJ-|) zj>DcE9k5oHD{TPyf&>&CLCxpYIg&9c#%91BKZ{^jiHpJtZmuun>icw);g^G1c*AdH z>IBz$n5uC_<`T$HDtRiNp;U>n0cGLrB0)2iVL9v_RKH{rV0af*`&D>rkKir}1z zF9%#P)KrR*s~I$Y{({!F*S}Q-DxHiDn>=XtN3Y#}v=Qd)f`)1Gz%`k|AWT)jaE|sy zWYvwVW{wZPReDy`Ir<|Tp)xft&Ep{A#4*UDRFSQYTE@WQ=c11ia*WDT)~Q?K15EaX zQ%H}ac${h1uYOb6_pGjtw`j?g;<+2v2$m}_BHnSDbAITG$r4hCHTQk(%{X%f5TY=~ z=cSc%=M0OcvR}#&a%QQ%H8-URnqS$1W*qgEm9Qps`8}(sr+wf{8DtjMzw#)YZGp<*}`l|%T2%}rf(fC z<;*o|mr6nqeVvJoF4dNU-uo#Nfm#PABj~^FMsgQEfR>%{-Ru~v3y_O4WSelS%z7y0 z3=A)9uitPEy<3>kmmW96nZKuU9F7J^S3aYef=JqKQTr6JERO3(waAUr!jLjcuT3_x z@S^HuW0b=hj&jLCy0uu90qQ0;FRkyl-gAy3Yp@j_X|_jiS~E5$h;r^_4vk0O-W*n9 zz-QYlQiY|v5Bc6~(;s7dLm&T6+!LS}Ihc9Wk* zXZ>&C2q@?ue*70mBtJk1k`p+B)K}{d0NwhP;m@^!RxLI3Gn)w&no&w-?Fd9ncT)hTG=5>C$!+SdHA3vRt@7fa~d7)QeJe>f9@*sOB!Ys+Mz zsxV>yw{TZE@vVXQ!i>ns^seiuaBN*!zHZ_V_g%Y@@xMAE=ZnAIc`j#6m6NIWOnFOD zmHU@0A(aerWHISP&hw6j?MPILrl?mnt=2B{kOGh3IA=qgQC$OFgr5F&bsI5-KoYUX zh9l>vl4G%M7q|AS(ezI5p7af&PvE2ze(g#mtAZwDcDST6HkUA#w|U9Rsi=?+p9Zqg z_s^&HckYXg9@Og>RvgfCtl)eT=jwt8foouEx!bjbS7BZrwHLYrQV)fgF?bo3ezf}c z{gVfqP1kd2zl~ZrNp@4_EeQ%(PRIK-Q#!^?HWn&q`K& z9QxY+R_3GuQxS~7NDWidxJ_Daa-K|r zY%}LQXDBwm7BmX_n9FMvPg*CP;khW{zti+8)Fpz=9}6ZM=)Q_SELXCjwTu4nkSiij z|8BEg>l zx5&R2tvYgRSY$SRzUaIZKW*tY2^Y;NqYT<6=?ZnoM~1+54#ma{D74brsuD*f{QEjQ zBfOBoU?GauYlS{^ont2qyDge%_xPz`j^k}qgmNYBZeQC*7=s$;$kC*v!AG)R12g0E2OQY z!3ye>TTFf$fN^*E^_gDkd_=IetHo3#Ds7l5bH@FUf1rz_UA&G%`BOlC>v%4iN@&c& zYf(QsBw#h#N#ugh`hH(Lf;I(9&*{T7_BY?ui|Ixk;7B#U&%9?M6TWDd`N;O;#~G^P ze1Zy*^*r@~4fUSLGGFdUIk{J9uJm1~fgc={M+Sb**j^jN`74Jg_99d|q z0N1Zdmrt;y;g^FlZg!O7T`}v5q-T>OVH^-yu+JMn8ETmauv^ z$-~?S@~)-nsYciYFQ{m zL#pfmRwr1)a<~>@l>VcGhz_4bX_2BQVG|PHFP7kb?ia9*zXv5PAD4<{8-yJ;nA@YK z7!g82hC&WbW{U?Xlc)vKM?$3~Li0xO^ARV~j2#BvWD?{>)2AlQWN|f^Sn19bbNER3 z4MpTcK2G<2Kxg95OKW3mH!~yBVh%_nPFZzFn81iy|NV&>*;~3NUI3amY5LtQvad8s zY&z#x$%_-}m_?F3H**>v%O6>#GqwX@u5|14^)H`mL5dyXvzJp*<8LWhB>fU`Ix`Q? znxnM8<*ikGBeMRqJW=lZE%ox=(*0XOpu51nzoDq;LOrK8`9>-Fk+kCNmHtbXluk1-BpT%PL!R>?9xr2e zgGL>3#=&Ee&r1rpla8J`ne=tqEz?E%wenx4TLOVI+FCii=4mp!q3!EpQ)RzKXKocl zM@U5vD&wCJSijS*;;YymoV3mgWgDK?F(xeX-Y|dOh@)*1$Tfa3ANS#@H}kgt$8LhX zo?1pC!eHOlO2KH>?<;PNPuJGI>F#_)A4qh{$n1}Ki%25u?WiYi3%hS3Rj+#4wOs1-d{HHyO|YMrx!{eXV_1=a()auCBiit+)_I^x57RdpH9*(M~WPD-oaq*plf_h2x1Tb;kf+nR%~ z%LW!=#0KG8sm)=`x8x;U2`&sL z|K~jb1b_)ZtnTyTFJ1FG3<$OatI!M2WW<-u*F3uUkqr;J;gEgx9T4$7XsLeesyXz( GQSU!ull7wj literal 4339 zcmai&Ra6uV)5qB*7Zw5OMvxX*8gZpT8YGmI*rh=iX#}K88l-CllwL~0rIB1(LO_@9 z7Nl`s-}8Ovc`o0JIdkU!znHn2-<*MjQXT>U_>fS_5+aa5qVP3ey4gKp&*SAP4f`e`|KOsFDBlBUP{M ztQ*_SC$tZc;VpgFqyk_%i$Y<7Gpxj)d;jxLD`oQ&)W)9n@K%?2?vsi*o#g$dEjuJT&uA84&J&2OfR0?W-WYHP3`>h;>~M(SxtD#csu7*n8Rqhp!HR^`4HJni3n z-guRcK5&(~`QG(MjGT5gHZ4hUn^uMw8&%-B;$YBxX5u(2aWr#@#6BLaUDDs{*Rn7!yU-;<;YO^f(AcacGXzv{pjfP4N^zW69f6zHth z-2at9k*)R3A4U?jsB*POLF87iCJ-&OhkrY_u%_DQ_k)$ zAwbK(qRXHU()_t@T{`~K?xJpIVMpz|QsHi_F|}HU&2kNreRZyI9%T887O9vUCSaNX zu+;^Gy3XL`@7HKs6$dGA-!l-nn_m|u@3Sbdp@e%C(hHhAGsfz5WE4tU-oSt_t=L1r z(v|tHI7M}T%toVu?ZE-Foq}8`gK_fCuBY| zPDKxB45KgNH|6ppGIANcP4^;*NP^d%Q(}C*j0eI!Ct4-3P&<6iu!%)bRl$5Q^#@Fm;4Nw*{CUslT ztlJZMigg*_Q%Dj<0THAlooG_BLqPK!*Wk{>WO;0>s=+_@ zeY^F0GGF;}4l>9Kym#f6cfUNv*=YZlD3I57QTJspkdobG)r6U15X~^8h;Kic=Dvi{ zVLLXwBXb!(IDUXR92=qTuoVnjUaCe{VIJ2oB6bih!YHX zx;FN+A!1^UG+T>69~Lwk&4hCHY%9XHkrVY^h2uTcuXqDlgXHadaIBF2M z#~f;r`KGXd)kYh6YP41+w4LjLW65$CaV5)1;x*HVIjxW(6f zwy~Qru0y?|QBzp&f3m`4xs+iRnj(8SdYnG^&T{qO3o}yWVxB61)@mVQ^HwEuRIAEk zKB)ietaww=OzRkF>fym zM@Qy!5W3H2J%;0_^j~E<^~@~Imc2=0wSZU4A#2YDMvg{BRnz8Ob2@%qj(+b8q!K$6 zy2JWV@8T_5_K1Li#Rn2f3jT*9{{<81mLL>#2?+)L{u{?cWdF}BFew1|*KGMKe*Rw| znix}O1-_QApnX8Yn5e>Z{69g|?e@wbKl!1)#}|7Uo(SoZzZ2-A=Y8C>1s@74c}Q{k z1)CtaOgc6ZX;G5h(e_SXt*?bEgS$uI7h+e((6Rge%5OG|;#i|HH5R0D-coO*f0Sha*ns0vffp%LI~qo0zfCoxFnMB8c&c8yN4Y&4 zJqO-{&PNsKPOBIN;zG` zuE?3JQ->J9sV6?%Ij5oO976E}4JKaE>Lm`SExk{D4>OCkr}~P7Ud!h=s=8p^D#Dv) z?%(@NJsj#ewAwZ$uEoqd1zlg)B?6^e1hG};={wP?nwMTvGwO5~x1?S{jTu5dRAk7g zKM%7L_)QU^3jNxeF9pl&kD;`_RA?ApJvD)j55Q)kBpN(MA4Va002e$ zyTLy(E@B?~($cJTF_cg@FjsucS>a}7Hr z%oa>|*ax?4hYqc`3Rw5$Xvv@TM*My}NT*YgyajX=$z5=qz< zXWG=8F=hm1aW4(*pgn)2lVzq32@dZl?tKdcm|N)fnLu9A*`=uo@AcL+j`HZQov`aJ zL)dlEpZfFDKw?+Gm>;hJW!Ilkb(v-M47{sIX7fOHtE93EyWH2BJ(rW#XW3W4=)qtSA8#%8C7|?l*-~^k&u1j3lOEp`FP>vtNXb#ik~8gHx7@?<>plH*Ollk@Ri( zcan0S`YaS4#iD@DXbh}&wek50qU=cgF??vShSScoL?~$Ssi~PgNP4kO_T(zaM zC-H>K#$w-a)#?JG6|U5Km&KFitlH+=wQ*HS4Oe)d!rCBB;Rt8lj-$^;pznv~t>U>H zWHDEGXJ#*2F~qyP7F$#l0@&xymCM?aHj6&ler^|(6kMy|r*9FbQ>{H4V`ZRb==8(~ z`MOpwE-4hAr<#CwDO2;qRq~c*Uq?}sAJzGU47~wB3dXwcqkp%4Du<~q{XD{xt7wH@ zPS#epJ#^|M+kPeXP0$xdN9*=DqmG*Q{pO~&Djs&P=#2CVZjbD6v6XP6^t8KUy*w&= z$)*-~yIQStA-YV^9jAl*aFF<5%+MRH8k^9b)rS1H|gHL!q?~fA*sqA>2utpkqUnV)vqTtOCJ(2pP?mO7@T!tfVtt5N-nb@MDu!tBj;8&Eh#aKNu zI$X}3J9#XGGmHivueelNY!eV-_bWyoei9f`gxGhNFQXpT0$5Vp$qL)kq~o6FVz_>V zEwIUd#_S1}GnH0vrS{GV=$Ia6x2ivD3t}BD8!5jmUOVB|M&$0eJ1jLJ#pq;DRHNU7 z4e{gJ7xPnvBrHAM_W-rCKM8iMlmXNH8h+Y{fVM#DcU_-7NEI|6#M@N$P_>xe`?Bmj z`y-4)q!ilkHv;CvAQL}Q@yy+?f+a9Od<$({)=1qg;#R;vU1hXM%A#-Ch!IUf*zUMI zU(UgWC$hxOY?+Tlj`Tm$ZblB8KMfA)#B@wFjW}wu70}1fUhtY(d!OVefy{?m7Txvx zgT@afa$N$bWv9>3J1cW<1@eSibYba*d^F=qG%tPo5;*q6CYDi5$m zb~ExUzE;SA&67<|e4G{>D;E#K_@zqd>uDG)S7pge#~;SBH$MI&mPa$ZQxF%+`Y6u&k+t??3m4_G)QL7T4yRtF z*on7%(q88j^rigNpODVGY+XqLw%*^luH6MjXFWs+nEgWTZJk=i0|bpW<5Yw!ODeK9 zmUD}CWv*oE+)KLloA2!2C10(w&vxh;^=MqpW3MtW!dPD?7ZzTqH|^waYvugHz#1Hw zrCcF3I$D^0MaOWCf- z-_|n}T!JltSQ>@2$PD3r720l53WE2rSTSa?BQu@C*^vl5FpnUuF{wo)qhOn;rOuD% z_JgX6l0#sXXO9>|XWzpWt{i0GDltUbaJ>Cw!BHa?mGwqXJ0@}PfYPBb_wa8^!@JQD z6L(v&=U@Qdy7pwgJItHuxZmrJ!(Xf8@svH zIAclSK7ZZi%0+baYfk|ft!}TA5S5f0dzUP;1Ng)^MRb38{2I$O8+G_X2_gwa);{U= zV{#;T;n%`yKt0(b;TXJi*U%tpi*PVRTK+Rgor}O|9KMt0fcx29OBAP+C0-8@pudNpWE3%Eu~pAI+Yhh*DhY}-36&B T{URVi$lEM-Ro=Gz_tg6j5CtT- From 6af92d9ce89bde58eb7a614d716a71062080fd42 Mon Sep 17 00:00:00 2001 From: Bryan Alexander Date: Wed, 24 Apr 2024 13:14:01 -0400 Subject: [PATCH 17/25] 80367: Add form profile for 10-7959F-1 (#16446) * 80367: Add form profile for 10-7959F-1 * 80367: Remove vets-json-schema test * 80367: Add codeowner --- .github/CODEOWNERS | 1 + app/models/form_profile.rb | 6 ++++-- app/models/form_profiles/va_107959f1.rb | 13 ++++++++++++ config/form_profile_mappings/10-7959F-1.yml | 22 +++++++++++++++++++++ config/settings.yml | 3 +++ 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 app/models/form_profiles/va_107959f1.rb create mode 100644 config/form_profile_mappings/10-7959F-1.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 76c7f1639f9..fc639352f37 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -664,6 +664,7 @@ config/form_profile_mappings/0873.yml @department-of-veterans-affairs/vfs-virtua config/form_profile_mappings/1010ez.yml @department-of-veterans-affairs/vfs-10-10 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group config/form_profile_mappings/10-10EZR.yml @department-of-veterans-affairs/vfs-10-10 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group config/form_profile_mappings/10182.yml @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group +config/form_profile_mappings/10-7959F-1.yml @department-of-veterans-affairs/champva-engineering @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group config/form_profile_mappings/20-0995.yml @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group config/form_profile_mappings/20-0996.yml @department-of-veterans-affairs/Benefits-Team-1 @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group config/form_profile_mappings/21-526EZ.yml @department-of-veterans-affairs/Disability-Experience @department-of-veterans-affairs/va-api-engineers @department-of-veterans-affairs/backend-review-group diff --git a/app/models/form_profile.rb b/app/models/form_profile.rb index 17531b9e535..5743ba9e9f3 100644 --- a/app/models/form_profile.rb +++ b/app/models/form_profile.rb @@ -101,7 +101,8 @@ class FormProfile vre_readiness: ['28-1900'], coe: ['26-1880'], adapted_housing: ['26-4555'], - intent_to_file: ['21-0966'] + intent_to_file: ['21-0966'], + ivc_champva: ['10-7959F-1'] }.freeze FORM_ID_TO_CLASS = { @@ -138,7 +139,8 @@ class FormProfile '22-1990EZ' => ::FormProfiles::VA1990ez, '26-1880' => ::FormProfiles::VA261880, '26-4555' => ::FormProfiles::VA264555, - '21-0966' => ::FormProfiles::VA210966 + '21-0966' => ::FormProfiles::VA210966, + '10-7959F-1' => ::FormProfiles::VA107959f1 }.freeze APT_REGEX = /\S\s+((apt|apartment|unit|ste|suite).+)/i diff --git a/app/models/form_profiles/va_107959f1.rb b/app/models/form_profiles/va_107959f1.rb new file mode 100644 index 00000000000..407f42714c6 --- /dev/null +++ b/app/models/form_profiles/va_107959f1.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class FormProfiles::VA107959f1 < FormProfile + FORM_ID = '10-7959F-1' + + def metadata + { + version: 0, + prefill: true, + returnUrl: '/review-and-submit' + } + end +end diff --git a/config/form_profile_mappings/10-7959F-1.yml b/config/form_profile_mappings/10-7959F-1.yml new file mode 100644 index 00000000000..f9846dcb65e --- /dev/null +++ b/config/form_profile_mappings/10-7959F-1.yml @@ -0,0 +1,22 @@ + +veteran: + date_of_birth: [identity_information, date_of_birth] + full_name: [identity_information, full_name] + first: [identity_information, first] + middle: [identity_information, middle] + last: [identity_information, last] +physical_address: + country: [contact_information, country] + street: [contact_information, street] + city: [contact_information, city] + state: [contact_information, state] + postal_code: [contact_information, postal_code] +mailing_address: + country: [contact_information, country] + street: [contact_information, street] + city: [contact_information, city] + state: [contact_information, state] + postal_code: [contact_information, postal_code] +ssn: [identity_information, ssn] +phone_number: [contact_information, us_phone] +email_address: [contact_information, email] \ No newline at end of file diff --git a/config/settings.yml b/config/settings.yml index b069fd69ac7..c1cd8bdb74f 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -404,6 +404,9 @@ adapted_housing: intent_to_file: prefill: true +ivc_champva: + prefill: true + # Settings for Expiry Scanner expiry_scanner: slack: From c06991ecb9f4991bf0ae2614271b8036c68b6c85 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen <134089461+Khoa-V-Nguyen@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:03:33 -0600 Subject: [PATCH 18/25] fix error response for submit inquiry and reply (#16480) Co-authored-by: khoa-v-nguyen --- .../lib/ask_va_api/correspondences/creator.rb | 3 +- .../app/lib/ask_va_api/inquiries/creator.rb | 3 +- .../correspondences/creator_spec.rb | 16 +++- .../lib/ask_va_api/inquiries/creator_spec.rb | 20 +++-- .../spec/requests/v0/inquiries_spec.rb | 90 +++++++++++++++---- 5 files changed, 107 insertions(+), 25 deletions(-) diff --git a/modules/ask_va_api/app/lib/ask_va_api/correspondences/creator.rb b/modules/ask_va_api/app/lib/ask_va_api/correspondences/creator.rb index 9cdf1ad1759..3e57c1fd81a 100644 --- a/modules/ask_va_api/app/lib/ask_va_api/correspondences/creator.rb +++ b/modules/ask_va_api/app/lib/ask_va_api/correspondences/creator.rb @@ -35,7 +35,8 @@ def post_data(payload: {}) def handle_response_data(response) if response[:Data].nil? - raise CorrespondencesCreatorError, response[:Message] + error = JSON.parse(response[:body], symbolize_names: true) + raise CorrespondencesCreatorError, error[:Message] else response[:Data] end diff --git a/modules/ask_va_api/app/lib/ask_va_api/inquiries/creator.rb b/modules/ask_va_api/app/lib/ask_va_api/inquiries/creator.rb index 5accb20ee13..918601ea690 100644 --- a/modules/ask_va_api/app/lib/ask_va_api/inquiries/creator.rb +++ b/modules/ask_va_api/app/lib/ask_va_api/inquiries/creator.rb @@ -32,7 +32,8 @@ def post_data(payload: {}) def handle_response_data(response) if response[:Data].nil? - raise InquiriesCreatorError, response[:Message] + error = JSON.parse(response[:body], symbolize_names: true) + raise InquiriesCreatorError, error[:Message] else response[:Data] end diff --git a/modules/ask_va_api/spec/app/lib/ask_va_api/correspondences/creator_spec.rb b/modules/ask_va_api/spec/app/lib/ask_va_api/correspondences/creator_spec.rb index 6136b5c1609..bea0c25bd50 100644 --- a/modules/ask_va_api/spec/app/lib/ask_va_api/correspondences/creator_spec.rb +++ b/modules/ask_va_api/spec/app/lib/ask_va_api/correspondences/creator_spec.rb @@ -22,9 +22,23 @@ module Correspondences end context 'when not successful' do + let(:body) do + '{"Data":null,"Message":"Data Validation: Missing Reply"' \ + ',"ExceptionOccurred":true,"ExceptionMessage":"Data Validation: ' \ + 'Missing Reply","MessageId":"e2cbe041-df91-41f4-8bd2-8b6d9dbb2e38"}' + end + let(:failure) do + { + status: 400, + body:, + response_headers: nil, + url: nil + } + end + before do allow_any_instance_of(Crm::CrmToken).to receive(:call).and_return('Token') - allow_any_instance_of(Crm::Service).to receive(:call).and_return({ Data: nil, Message: 'Error has occur' }) + allow_any_instance_of(Crm::Service).to receive(:call).and_return(failure) end it 'raise CorrespondenceCreatorError' do diff --git a/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/creator_spec.rb b/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/creator_spec.rb index 91029a32a3d..793ebba7057 100644 --- a/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/creator_spec.rb +++ b/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/creator_spec.rb @@ -36,12 +36,22 @@ end context 'when the API call fails' do + let(:body) do + '{"Data":null,"Message":"Data Validation: missing InquiryCategory"' \ + ',"ExceptionOccurred":true,"ExceptionMessage":"Data Validation: missing' \ + 'InquiryCategory","MessageId":"cb0dd954-ef25-4e56-b0d9-41925e5a190c"}' + end + let(:failure) do + { + status: 400, + body:, + response_headers: nil, + url: nil + } + end + before do - allow(service).to receive(:call).and_return({ Data: nil, - Message: 'Data Validation: missing InquiryCategory', - ExceptionOccurred: true, - ExceptionMessage: 'Data Validation: missing InquiryCategory', - MessageId: '13bc59ea-c90a-4d48-8979-fe71e0f7ddeb' }) + allow(service).to receive(:call).and_return(failure) end it 'raise InquiriesCreatorError' do diff --git a/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb b/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb index 3d0a6216ddc..25ff307fb6f 100644 --- a/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb +++ b/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb @@ -357,14 +357,24 @@ context 'when crm api fail' do context 'when the API call fails' do + let(:body) do + '{"Data":null,"Message":"Data Validation: missing InquiryCategory"' \ + ',"ExceptionOccurred":true,"ExceptionMessage":"Data Validation: missing' \ + 'InquiryCategory","MessageId":"cb0dd954-ef25-4e56-b0d9-41925e5a190c"}' + end + let(:failure) do + { + status: 400, + body:, + response_headers: nil, + url: nil + } + end + before do allow_any_instance_of(Crm::Service).to receive(:call) .with(endpoint:, method: :put, - payload:).and_return({ Data: nil, - Message: 'Data Validation: missing InquiryCategory', - ExceptionOccurred: true, - ExceptionMessage: 'Data Validation: missing InquiryCategory', - MessageId: '13bc59ea-c90a-4d48-8979-fe71e0f7ddeb' }) + payload:).and_return(failure) sign_in(authorized_user) post '/ask_va_api/v0/inquiries/auth', params: payload end @@ -404,14 +414,24 @@ context 'when crm api fail' do context 'when the API call fails' do + let(:body) do + '{"Data":null,"Message":"Data Validation: missing InquiryCategory"' \ + ',"ExceptionOccurred":true,"ExceptionMessage":"Data Validation: missing' \ + 'InquiryCategory","MessageId":"cb0dd954-ef25-4e56-b0d9-41925e5a190c"}' + end + let(:failure) do + { + status: 400, + body:, + response_headers: nil, + url: nil + } + end + before do allow_any_instance_of(Crm::Service).to receive(:call) .with(endpoint:, method: :put, - payload:).and_return({ Data: nil, - Message: 'Data Validation: missing InquiryCategory', - ExceptionOccurred: true, - ExceptionMessage: 'Data Validation: missing InquiryCategory', - MessageId: '13bc59ea-c90a-4d48-8979-fe71e0f7ddeb' }) + payload:).and_return(failure) post '/ask_va_api/v0/inquiries', params: payload end @@ -472,7 +492,7 @@ def json_response describe 'POST #test_create' do before do - allow_any_instance_of(Crm::Service).to receive(:call).and_return({ message: 'success' }) + allow_any_instance_of(Crm::Service).to receive(:call).and_return({ body: { message: 'success' } }) post '/ask_va_api/v0/test_create', params: { 'reply' => 'test', 'endpoint' => 'inquiries/id/reply/new' }, as: :json @@ -486,14 +506,50 @@ def json_response describe 'POST #create_reply' do let(:payload) { { 'reply' => 'this is my reply' } } - before do - allow_any_instance_of(Crm::Service).to receive(:call).and_return({ Data: { Id: '123' } }) - sign_in(authorized_user) - post '/ask_va_api/v0/inquiries/123/reply/new', params: payload + context 'when successful' do + before do + allow_any_instance_of(Crm::Service).to receive(:call).and_return({ Data: { Id: '123' } }) + sign_in(authorized_user) + post '/ask_va_api/v0/inquiries/123/reply/new', params: payload + end + + it 'returns status 200' do + expect(response).to have_http_status(:ok) + end end - it 'returns status 200' do - expect(response).to have_http_status(:ok) + context 'when crm api fail' do + context 'when the API call fails' do + let(:endpoint) { 'inquiries/123/reply/new' } + let(:body) do + '{"Data":null,"Message":"Data Validation: Missing Reply"' \ + ',"ExceptionOccurred":true,"ExceptionMessage":"Data Validation: ' \ + 'Missing Reply","MessageId":"e2cbe041-df91-41f4-8bd2-8b6d9dbb2e38"}' + end + let(:failure) do + { + status: 400, + body:, + response_headers: nil, + url: nil + } + end + + before do + sign_in(authorized_user) + allow_any_instance_of(Crm::Service).to receive(:call) + .with(endpoint:, method: :put, + payload: { Reply: 'this is my reply' }).and_return(failure) + post '/ask_va_api/v0/inquiries/123/reply/new', params: payload + end + + it 'raise InquiriesCreatorError' do + expect(response).to have_http_status(:unprocessable_entity) + end + + it_behaves_like 'common error handling', :unprocessable_entity, 'service_error', + 'AskVAApi::Correspondences::CorrespondencesCreatorError: Data Validation: Missing Reply' + end end end end From 48f16b3a8b612fa9f61b5793d2c9507242e14b52 Mon Sep 17 00:00:00 2001 From: mchristiansonVA <95487885+mchristiansonVA@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:08:24 -0400 Subject: [PATCH 19/25] Api 35595 registration numbers (#16476) * Update json files with new value, add generated swagger * Update tests for rep id and reg number * Fix line lengths * Update test for exampl registration number change * Regenerate swagger and add --- .../swagger/claims_api/v2/dev/swagger.json | 30 +++++++++---------- .../claims_api/v2/production/swagger.json | 30 +++++++++---------- .../power_of_attorney/2122/invalid_poa.json | 2 +- .../power_of_attorney/2122/valid.json | 2 +- .../power_of_attorney/2122a/invalid_poa.json | 2 +- .../power_of_attorney/2122a/valid.json | 2 +- .../power_of_attorney_ind_request_spec.rb | 4 +-- .../power_of_attorney_org_request_spec.rb | 10 ++++--- .../veterans/rswag_power_of_attorney_spec.rb | 9 +++--- 9 files changed, 47 insertions(+), 44 deletions(-) diff --git a/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json b/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json index 694ef3f86cd..bc5b78f3b26 100644 --- a/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json +++ b/modules/claims_api/app/swagger/claims_api/v2/dev/swagger.json @@ -6072,7 +6072,7 @@ "application/json": { "example": { "data": { - "id": "bcf33b41-f27f-429c-b860-f2b71567d87e", + "id": "6be9b240-267c-4c9c-b8d5-af1cd4068308", "type": "forms/526", "attributes": { "veteran": { @@ -8156,8 +8156,8 @@ "id": "1", "type": "intent_to_file", "attributes": { - "creationDate": "2024-04-23", - "expirationDate": "2025-04-23", + "creationDate": "2024-04-24", + "expirationDate": "2025-04-24", "type": "compensation", "status": "active" } @@ -8975,7 +8975,7 @@ "application/json": { "example": { "data": { - "id": "48a79d49-eccd-4a89-adb8-e2c91ed3fab5", + "id": "867b7baa-8dbe-4053-823f-788218fa6984", "type": "individual", "attributes": { "code": "083", @@ -9175,7 +9175,7 @@ { "title": "Resource not found", "status": "404", - "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", + "detail": "Could not find an Accredited Representative with registration number: 999999999999 and poa code: 083", "source": { "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } @@ -9603,7 +9603,7 @@ }, "representative": { "poaCode": "083", - "registrationNumber": "67890", + "registrationNumber": "999999999999", "type": "ATTORNEY", "address": { "addressLine1": "123", @@ -9671,7 +9671,7 @@ "application/json": { "example": { "data": { - "id": "7610ed19-baac-46fe-8ba5-5aa3e64a92ff", + "id": "c54cfb3e-8ec8-48ce-bb19-52847bdd9bde", "type": "organization", "attributes": { "code": "083", @@ -9879,7 +9879,7 @@ { "title": "Resource not found", "status": "404", - "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", + "detail": "Could not find an Accredited Representative with registration number: 999999999999 and poa code: 083", "source": { "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } @@ -10249,7 +10249,7 @@ }, "serviceOrganization": { "poaCode": "083", - "registrationNumber": "67890" + "registrationNumber": "999999999999" } } } @@ -10498,7 +10498,7 @@ { "title": "Resource not found", "status": "404", - "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", + "detail": "Could not find an Accredited Representative with registration number: 999999999999 and poa code: 083", "source": { "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } @@ -10926,7 +10926,7 @@ }, "representative": { "poaCode": "083", - "registrationNumber": "67890", + "registrationNumber": "999999999999", "type": "ATTORNEY", "address": { "addressLine1": "123", @@ -11193,7 +11193,7 @@ { "title": "Resource not found", "status": "404", - "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", + "detail": "Could not find an Accredited Representative with registration number: 999999999999 and poa code: 083", "source": { "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } @@ -11563,7 +11563,7 @@ }, "serviceOrganization": { "poaCode": "083", - "registrationNumber": "67890" + "registrationNumber": "999999999999" } } } @@ -11631,11 +11631,11 @@ "application/json": { "example": { "data": { - "id": "09a36719-ad88-46b9-97d1-80a746ef9e81", + "id": "af367b07-5484-4eb7-8a2b-3d4bf1ba447c", "type": "claimsApiPowerOfAttorneys", "attributes": { "status": "submitted", - "dateRequestAccepted": "2024-04-23", + "dateRequestAccepted": "2024-04-24", "representative": { "serviceOrganization": { "poaCode": "074" diff --git a/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json b/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json index 83308517114..98196980051 100644 --- a/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json +++ b/modules/claims_api/app/swagger/claims_api/v2/production/swagger.json @@ -5789,7 +5789,7 @@ "application/json": { "example": { "data": { - "id": "cfe5b467-a176-4987-80a9-4350ba73f350", + "id": "05d0b0a5-f2c6-40fb-a88a-7f8fb6888649", "type": "forms/526", "attributes": { "veteran": { @@ -7873,8 +7873,8 @@ "id": "1", "type": "intent_to_file", "attributes": { - "creationDate": "2024-04-23", - "expirationDate": "2025-04-23", + "creationDate": "2024-04-24", + "expirationDate": "2025-04-24", "type": "compensation", "status": "active" } @@ -8692,7 +8692,7 @@ "application/json": { "example": { "data": { - "id": "74658dd8-0176-4bd4-ac22-beedcef627df", + "id": "6f744006-a5d4-4df8-8869-735a7a011c2b", "type": "individual", "attributes": { "code": "083", @@ -8892,7 +8892,7 @@ { "title": "Resource not found", "status": "404", - "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", + "detail": "Could not find an Accredited Representative with registration number: 999999999999 and poa code: 083", "source": { "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } @@ -9320,7 +9320,7 @@ }, "representative": { "poaCode": "083", - "registrationNumber": "67890", + "registrationNumber": "999999999999", "type": "ATTORNEY", "address": { "addressLine1": "123", @@ -9388,7 +9388,7 @@ "application/json": { "example": { "data": { - "id": "f8eefcaa-020f-473e-9382-11dbd36f32ff", + "id": "3a617b31-b98c-408a-844c-9bf3eef46b10", "type": "organization", "attributes": { "code": "083", @@ -9596,7 +9596,7 @@ { "title": "Resource not found", "status": "404", - "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", + "detail": "Could not find an Accredited Representative with registration number: 999999999999 and poa code: 083", "source": { "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } @@ -9966,7 +9966,7 @@ }, "serviceOrganization": { "poaCode": "083", - "registrationNumber": "67890" + "registrationNumber": "999999999999" } } } @@ -10215,7 +10215,7 @@ { "title": "Resource not found", "status": "404", - "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", + "detail": "Could not find an Accredited Representative with registration number: 999999999999 and poa code: 083", "source": { "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } @@ -10643,7 +10643,7 @@ }, "representative": { "poaCode": "083", - "registrationNumber": "67890", + "registrationNumber": "999999999999", "type": "ATTORNEY", "address": { "addressLine1": "123", @@ -10910,7 +10910,7 @@ { "title": "Resource not found", "status": "404", - "detail": "Could not find an Accredited Representative with registration number: 67890 and poa code: 083", + "detail": "Could not find an Accredited Representative with registration number: 999999999999 and poa code: 083", "source": { "pointer": "/modules/claims_api/app/controllers/claims_api/v2/veterans/power_of_attorney/base_controller.rb:70:in `validate_registration_number!'" } @@ -11280,7 +11280,7 @@ }, "serviceOrganization": { "poaCode": "083", - "registrationNumber": "67890" + "registrationNumber": "999999999999" } } } @@ -11348,11 +11348,11 @@ "application/json": { "example": { "data": { - "id": "c08567c4-6f1d-49bb-8416-01b91642b301", + "id": "475c01f3-1705-4639-a793-7a80074884ea", "type": "claimsApiPowerOfAttorneys", "attributes": { "status": "submitted", - "dateRequestAccepted": "2024-04-23", + "dateRequestAccepted": "2024-04-24", "representative": { "serviceOrganization": { "poaCode": "074" diff --git a/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122/invalid_poa.json b/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122/invalid_poa.json index c8e51c69b95..57ef9056d29 100644 --- a/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122/invalid_poa.json +++ b/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122/invalid_poa.json @@ -12,7 +12,7 @@ }, "serviceOrganization": { "poaCode": "aaa", - "registrationNumber": "67890" + "registrationNumber": "999999999999" } } } diff --git a/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122/valid.json b/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122/valid.json index 82a23c3051b..fe439564f1a 100644 --- a/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122/valid.json +++ b/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122/valid.json @@ -12,7 +12,7 @@ }, "serviceOrganization": { "poaCode": "083", - "registrationNumber": "67890" + "registrationNumber": "999999999999" } } } diff --git a/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122a/invalid_poa.json b/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122a/invalid_poa.json index a93b72d9101..fd18c06f7f4 100644 --- a/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122a/invalid_poa.json +++ b/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122a/invalid_poa.json @@ -12,7 +12,7 @@ }, "representative": { "poaCode": "aaa", - "registrationNumber": "67890", + "registrationNumber": "999999999999", "type": "ATTORNEY", "address": { "addressLine1": "123", diff --git a/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122a/valid.json b/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122a/valid.json index ce086b08903..ed6315f06bc 100644 --- a/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122a/valid.json +++ b/modules/claims_api/spec/fixtures/v2/veterans/power_of_attorney/2122a/valid.json @@ -14,7 +14,7 @@ }, "representative": { "poaCode": "083", - "registrationNumber": "67890", + "registrationNumber": "999999999999", "type": "ATTORNEY", "address": { "addressLine1": "123", diff --git a/modules/claims_api/spec/requests/v2/veterans/power_of_attorney_ind_request_spec.rb b/modules/claims_api/spec/requests/v2/veterans/power_of_attorney_ind_request_spec.rb index dee3b666e60..92689e629e2 100644 --- a/modules/claims_api/spec/requests/v2/veterans/power_of_attorney_ind_request_spec.rb +++ b/modules/claims_api/spec/requests/v2/veterans/power_of_attorney_ind_request_spec.rb @@ -19,7 +19,7 @@ before do Veteran::Service::Representative.create!(representative_id: '12345', poa_codes: [individual_poa_code], first_name: 'Abraham', last_name: 'Lincoln') - Veteran::Service::Representative.create!(representative_id: '67890', poa_codes: [organization_poa_code], + Veteran::Service::Representative.create!(representative_id: '999999999999', poa_codes: [organization_poa_code], first_name: 'George', last_name: 'Washington') end @@ -346,7 +346,7 @@ it 'returns a meaningful 404' do mock_ccg(%w[claim.write claim.read]) do |auth_header| - detail = 'Could not find an Accredited Representative with registration number: 67890 ' \ + detail = 'Could not find an Accredited Representative with registration number: 999999999999 ' \ 'and poa code: aaa' post validate2122a_path, params: request_body, headers: auth_header diff --git a/modules/claims_api/spec/requests/v2/veterans/power_of_attorney_org_request_spec.rb b/modules/claims_api/spec/requests/v2/veterans/power_of_attorney_org_request_spec.rb index e9016bdde23..1e31d3f757c 100644 --- a/modules/claims_api/spec/requests/v2/veterans/power_of_attorney_org_request_spec.rb +++ b/modules/claims_api/spec/requests/v2/veterans/power_of_attorney_org_request_spec.rb @@ -17,7 +17,8 @@ describe 'PowerOfAttorney' do before do - Veteran::Service::Representative.create!(representative_id: '67890', poa_codes: [organization_poa_code], + Veteran::Service::Representative.create!(representative_id: '999999999999', + poa_codes: [organization_poa_code], first_name: 'George', last_name: 'Washington') Veteran::Service::Organization.create!(poa: organization_poa_code, name: "#{organization_poa_code} - DISABLED AMERICAN VETERANS") @@ -39,7 +40,7 @@ }, serviceOrganization: { poaCode: organization_poa_code.to_s, - registrationNumber: '67890' + registrationNumber: '999999999999' } } } @@ -103,7 +104,8 @@ context 'multiple reps with same poa code and registration number' do let(:rep_id) do - Veteran::Service::Representative.create!(representative_id: '67890', poa_codes: [organization_poa_code], + Veteran::Service::Representative.create!(representative_id: '999999999999', + poa_codes: [organization_poa_code], first_name: 'George', last_name: 'Washington-test').id end @@ -181,7 +183,7 @@ it 'returns a meaningful 404' do mock_ccg(%w[claim.write claim.read]) do |auth_header| - detail = 'Could not find an Accredited Representative with registration number: 67890 ' \ + detail = 'Could not find an Accredited Representative with registration number: 999999999999 ' \ 'and poa code: aaa' post validate2122_path, params: request_body, headers: auth_header diff --git a/modules/claims_api/spec/requests/v2/veterans/rswag_power_of_attorney_spec.rb b/modules/claims_api/spec/requests/v2/veterans/rswag_power_of_attorney_spec.rb index 9c17a58ad68..7158c3a3e56 100644 --- a/modules/claims_api/spec/requests/v2/veterans/rswag_power_of_attorney_spec.rb +++ b/modules/claims_api/spec/requests/v2/veterans/rswag_power_of_attorney_spec.rb @@ -184,7 +184,7 @@ expect_any_instance_of(local_bgs).to receive(:find_poa_by_participant_id).and_return(bgs_poa) allow_any_instance_of(local_bgs).to receive(:find_poa_history_by_ptcpnt_id) .and_return({ person_poa_history: nil }) - Veteran::Service::Representative.new(representative_id: '67890', + Veteran::Service::Representative.new(representative_id: '999999999999', poa_codes: [poa_code], first_name: 'Firstname', last_name: 'Lastname', @@ -352,7 +352,8 @@ Veteran::Service::Organization.create!(poa: organization_poa_code, name: "#{organization_poa_code} - DISABLED AMERICAN VETERANS", phone: '555-555-5555') - Veteran::Service::Representative.create!(representative_id: '67890', poa_codes: [organization_poa_code], + Veteran::Service::Representative.create!(representative_id: '999999999999', + poa_codes: [organization_poa_code], first_name: 'Firstname', last_name: 'Lastname', phone: '555-555-5555') @@ -510,7 +511,7 @@ end before do |example| - Veteran::Service::Representative.new(representative_id: '67890', + Veteran::Service::Representative.new(representative_id: '999999999999', poa_codes: [poa_code], first_name: 'Firstname', last_name: 'Lastname', @@ -679,7 +680,7 @@ before do |example| Veteran::Service::Organization.create!(poa: poa_code) - Veteran::Service::Representative.create!(representative_id: '67890', poa_codes: [poa_code], + Veteran::Service::Representative.create!(representative_id: '999999999999', poa_codes: [poa_code], first_name: 'Firstname', last_name: 'Lastname', phone: '555-555-5555') From 4135951a5b9aebde4c9a445755abcc99dbc5c103 Mon Sep 17 00:00:00 2001 From: Andrew Herzberg Date: Wed, 24 Apr 2024 12:48:27 -0700 Subject: [PATCH 20/25] add upstream service failures to mutli status response (#16465) --- .../mobile/v0/appointments_controller.rb | 13 +++---- .../mobile/v2/appointments/provider_names.rb | 13 +++++-- .../services/mobile/v2/appointments/proxy.rb | 38 ++++++++++++++++--- .../appointments_vaos_v2_list_request_spec.rb | 29 ++++++++++++++ .../v2/appointments/provider_names_spec.rb | 22 +++++++---- .../support/schemas/VAOS_v2_appointments.json | 2 +- 6 files changed, 93 insertions(+), 24 deletions(-) diff --git a/modules/mobile/app/controllers/mobile/v0/appointments_controller.rb b/modules/mobile/app/controllers/mobile/v0/appointments_controller.rb index 6525148a734..adff7bb4ea5 100644 --- a/modules/mobile/app/controllers/mobile/v0/appointments_controller.rb +++ b/modules/mobile/app/controllers/mobile/v0/appointments_controller.rb @@ -87,7 +87,7 @@ def fetch_appointments # The mobile app does not distinguish between VA and CC errors so we are only indicating that there are errors # If we ever want to distinguish be VA and CC errors, it will require coordination with the front-end team def partial_errors(failures) - if failures.present? + if appointment_errors?(failures) { errors: [{ source: 'VA Service' }] } @@ -95,12 +95,11 @@ def partial_errors(failures) end def get_response_status(failures) - case failures&.size - when 0, nil - :ok - else - :multi_status - end + appointment_errors?(failures) ? :multi_status : :ok + end + + def appointment_errors?(failures) + failures.any? { |failure| failure[:appointment_errors].present? } end def filter_by_date_range(appointments) diff --git a/modules/mobile/app/services/mobile/v2/appointments/provider_names.rb b/modules/mobile/app/services/mobile/v2/appointments/provider_names.rb index 1f7473ecc86..4ec4528201d 100644 --- a/modules/mobile/app/services/mobile/v2/appointments/provider_names.rb +++ b/modules/mobile/app/services/mobile/v2/appointments/provider_names.rb @@ -20,10 +20,17 @@ def form_names_from_appointment_practitioners_list(practitioners_list) return nil if practitioners_list.blank? provider_names = [] + missing_providers = [] practitioners_list.each do |practitioner| - provider_names << find_provider_name(practitioner) + name, id = find_provider_name(practitioner) + if name + provider_names << name + else + missing_providers << id + end end - provider_names.compact.join(', ').presence + provider_names = provider_names.compact.join(', ').presence + [provider_names, missing_providers] end private @@ -41,7 +48,7 @@ def find_provider_name(practitioner) name = provider_data&.name&.strip&.presence # cache even if it's nil to avoid duplicate requests @providers_cache[id] = name - name + [name, id] end def find_practitioner_name_in_list(practitioner) diff --git a/modules/mobile/app/services/mobile/v2/appointments/proxy.rb b/modules/mobile/app/services/mobile/v2/appointments/proxy.rb index 40348c892be..4fa4ed8ee02 100644 --- a/modules/mobile/app/services/mobile/v2/appointments/proxy.rb +++ b/modules/mobile/app/services/mobile/v2/appointments/proxy.rb @@ -24,13 +24,21 @@ def get_appointments(start_date:, end_date:, include_pending:, pagination_params filterer = PresentationFilter.new(include_pending:) appointments = appointments.keep_if { |appt| filterer.user_facing?(appt) } - appointments = merge_clinic_facility_address(appointments) - appointments = merge_auxiliary_clinic_info(appointments) - appointments = merge_provider_names(appointments) + appointments, missing_facilities = merge_clinic_facility_address(appointments) + appointments, missing_clinics = merge_auxiliary_clinic_info(appointments) + appointments, missing_providers = merge_provider_names(appointments) appointments = vaos_v2_to_v0_appointment_adapter.parse(appointments) - - [appointments.sort_by(&:start_date_utc), response[:meta][:failures]] + failures = [ + { appointment_errors: Array.wrap(response[:meta][:failures]) }, + { missing_facilities: }, + { missing_clinics: }, + { missing_providers: } + ] + failures.reject! { |failure| failure.values.first&.empty? } + Rails.logger.info('Mobile Appointment Partial Error', errors: failures) if failures.any? + + [appointments.sort_by(&:start_date_utc), failures] end private @@ -43,12 +51,18 @@ def merge_clinic_facility_address(appointments) cached_facilities[facility_id] = appointments_helper.get_facility(facility_id) end + missing_facilities = [] + appointments.each do |appt| facility_id = appt[:location_id] next unless facility_id appt[:location] = cached_facilities[facility_id] + + missing_facilities << facility_id unless cached_facilities[facility_id] end + + [appointments, missing_facilities] end def merge_auxiliary_clinic_info(appointments) @@ -59,6 +73,8 @@ def merge_auxiliary_clinic_info(appointments) cached_clinics[clinic_id] = appointments_helper.get_clinic(location_id, clinic_id) end + missing_clinics = [] + appointments.each do |appt| clinic_id = appt[:clinic] next unless clinic_id @@ -68,16 +84,26 @@ def merge_auxiliary_clinic_info(appointments) physical_location = cached_clinics.dig(clinic_id, :physical_location) appt[:physical_location] = physical_location + + missing_clinics << clinic_id unless cached_clinics[clinic_id] end + [appointments, missing_clinics] end def merge_provider_names(appointments) provider_names_proxy = ProviderNames.new(@user) + missing_providers = [] appointments.each do |appt| practitioners_list = appt[:practitioners] - names = provider_names_proxy.form_names_from_appointment_practitioners_list(practitioners_list) + next unless practitioners_list + + names, appointment_missing_providers = + provider_names_proxy.form_names_from_appointment_practitioners_list(practitioners_list) appt[:healthcare_provider] = names + missing_providers.concat(appointment_missing_providers) unless names end + + [appointments, missing_providers] end def appointments_helper diff --git a/modules/mobile/spec/request/appointments_vaos_v2_list_request_spec.rb b/modules/mobile/spec/request/appointments_vaos_v2_list_request_spec.rb index 60f14b0c007..42149d33ca9 100644 --- a/modules/mobile/spec/request/appointments_vaos_v2_list_request_spec.rb +++ b/modules/mobile/spec/request/appointments_vaos_v2_list_request_spec.rb @@ -13,6 +13,7 @@ before do Flipper.enable('va_online_scheduling') allow_any_instance_of(VAOS::UserService).to receive(:session).and_return('stubbed_token') + allow(Rails.logger).to receive(:info) Timecop.freeze(Time.zone.parse('2022-01-01T19:25:00Z')) end @@ -66,6 +67,7 @@ end end end + expect(response).to have_http_status(:ok) location = response.parsed_body.dig('data', 0, 'attributes', 'location') physical_location = response.parsed_body.dig('data', 0, 'attributes', 'physicalLocation') expect(response.body).to match_json_schema('VAOS_v2_appointments') @@ -84,6 +86,14 @@ 'url' => nil, 'code' => nil }) expect(physical_location).to eq('MTZ OPC, LAB') + expect(response.parsed_body['meta']).to eq({ + 'pagination' => { 'currentPage' => 1, + 'perPage' => 10, + 'totalPages' => 1, + 'totalEntries' => 1 }, + 'upcomingAppointmentsCount' => 0, + 'upcomingDaysLimit' => 7 + }) end end @@ -97,6 +107,9 @@ end end end + expect(response).to have_http_status(:ok) + expect(Rails.logger).to have_received(:info).with('Mobile Appointment Partial Error', + errors: [{ missing_facilities: ['983'] }]) expect(response.body).to match_json_schema('VAOS_v2_appointments') location = response.parsed_body.dig('data', 0, 'attributes', 'location') expect(location).to eq({ 'id' => nil, @@ -155,6 +168,10 @@ end end end + expect(response).to have_http_status(:ok) + expect(Rails.logger).to have_received(:info).with('Mobile Appointment Partial Error', + errors: [{ missing_facilities: ['999AA'] }, + { missing_clinics: ['999'] }]) expect(response.body).to match_json_schema('VAOS_v2_appointments') expect(response.parsed_body.dig('data', 0, 'attributes', 'healthcareService')).to be_nil end @@ -187,6 +204,14 @@ end expect(response).to have_http_status(:multi_status) + appointment_error = { errors: [{ appointment_errors: [{ system: 'the system', + id: 'id-string', + status: 'status-string', + code: 0, + trace_id: 'traceId-string', + message: 'msg-string', + detail: 'detail-string' }] }] } + expect(Rails.logger).to have_received(:info).with('Mobile Appointment Partial Error', appointment_error) expect(response.parsed_body['data'].count).to eq(1) expect(response.parsed_body['meta']).to include( { @@ -287,6 +312,8 @@ def fetch_appointments end expect(response).to have_http_status(:ok) expect(appointment['attributes']['healthcareProvider']).to be_nil + expect(Rails.logger).to have_received(:info).with('Mobile Appointment Partial Error', + errors: [{ missing_providers: ['1407938061'] }]) end it 'falls back to nil when provider service returns 500' do @@ -304,6 +331,8 @@ def fetch_appointments end expect(response).to have_http_status(:ok) expect(appointment['attributes']['healthcareProvider']).to be_nil + expect(Rails.logger).to have_received(:info).with('Mobile Appointment Partial Error', + errors: [{ missing_providers: ['1407938061'] }]) end end diff --git a/modules/mobile/spec/services/v2/appointments/provider_names_spec.rb b/modules/mobile/spec/services/v2/appointments/provider_names_spec.rb index 526a040733f..6f4b080541b 100644 --- a/modules/mobile/spec/services/v2/appointments/provider_names_spec.rb +++ b/modules/mobile/spec/services/v2/appointments/provider_names_spec.rb @@ -69,27 +69,31 @@ end it 'returns names as first_name last_name' do - name = subject.form_names_from_appointment_practitioners_list(single_practitioner_with_name) + name, missing_providers = subject.form_names_from_appointment_practitioners_list(single_practitioner_with_name) expect(name).to eq('CAROLYN KNIEFEL') + expect(missing_providers).to eq([]) end it 'handles partial names predictably' do partial_name_data = single_practitioner_with_name.first partial_name_data[:name].delete(:given) - name = subject.form_names_from_appointment_practitioners_list([partial_name_data]) + name, missing_providers = subject.form_names_from_appointment_practitioners_list([partial_name_data]) expect(name).to eq('KNIEFEL') + expect(missing_providers).to eq([]) end it 'aggregates multiple names as a comma separated list' do - name = subject.form_names_from_appointment_practitioners_list(multiple_practioners_with_names) + name, missing_providers = subject.form_names_from_appointment_practitioners_list(multiple_practioners_with_names) expect(name).to eq('CAROLYN KNIEFEL, MARCY NADEAU') + expect(missing_providers).to eq([]) end it 'forms names from upstream when an identifier is found without a name' do allow_any_instance_of(VAOS::V2::MobilePPMSService).to\ receive(:get_provider).with('1407938061').and_return(provider_response) - name = subject.form_names_from_appointment_practitioners_list(practitioner_without_name) + name, missing_providers = subject.form_names_from_appointment_practitioners_list(practitioner_without_name) expect(name).to eq('DEHGHAN, AMIR') + expect(missing_providers).to eq([]) end it 'can request multiple upstream providers' do @@ -107,8 +111,10 @@ receive(:get_provider).with('1407938061').and_return(provider_response) allow_any_instance_of(VAOS::V2::MobilePPMSService).to\ receive(:get_provider).with('1407938062').and_return(second_provider_response) - name = subject.form_names_from_appointment_practitioners_list(multiple_practitioners_without_names) + name, missing_providers = + subject.form_names_from_appointment_practitioners_list(multiple_practitioners_without_names) expect(name).to eq('DEHGHAN, AMIR, J. Jones') + expect(missing_providers).to eq([]) end it 'only requests an upstream provider once' do @@ -121,8 +127,9 @@ it 'returns nil when the ppms service raises an error' do allow_any_instance_of(VAOS::V2::MobilePPMSService).to\ receive(:get_provider).and_raise(Common::Exceptions::BackendServiceException) - name = subject.form_names_from_appointment_practitioners_list(practitioner_without_name) + name, missing_providers = subject.form_names_from_appointment_practitioners_list(practitioner_without_name) expect(name).to be_nil + expect(missing_providers).to eq(['1407938061']) end it 'returns nil if the returned provider does not match the expected structure' do @@ -130,8 +137,9 @@ allow_any_instance_of(VAOS::V2::MobilePPMSService).to\ receive(:get_provider).with('1407938061').and_return(nameless_provider) - name = subject.form_names_from_appointment_practitioners_list(practitioner_without_name) + name, missing_providers = subject.form_names_from_appointment_practitioners_list(practitioner_without_name) expect(name).to be_nil + expect(missing_providers).to eq(['1407938061']) end end end diff --git a/modules/mobile/spec/support/schemas/VAOS_v2_appointments.json b/modules/mobile/spec/support/schemas/VAOS_v2_appointments.json index 1a3f2ce3bc3..3d419e31c69 100644 --- a/modules/mobile/spec/support/schemas/VAOS_v2_appointments.json +++ b/modules/mobile/spec/support/schemas/VAOS_v2_appointments.json @@ -235,7 +235,7 @@ ], "properties": { "errors": { - "type": "null" + "type": ["array","null"] }, "pagination": { "type": "object", From 1e50563b8ba4a4d4653ca7a7382a1941f7498dc7 Mon Sep 17 00:00:00 2001 From: Tom Harrison Date: Wed, 24 Apr 2024 15:57:29 -0400 Subject: [PATCH 21/25] Add temporary logging for direct deposit control information (#16453) --- .../v0/profile/direct_deposits_controller.rb | 30 +++++-- .../direct_deposit/control_information.rb | 80 +++++++++++++------ .../direct_deposits_controller_spec.rb | 44 +++++++++- .../control_information_spec.rb | 61 ++++++++++---- 4 files changed, 168 insertions(+), 47 deletions(-) diff --git a/app/controllers/v0/profile/direct_deposits_controller.rb b/app/controllers/v0/profile/direct_deposits_controller.rb index 942a666f594..ff08ee72400 100644 --- a/app/controllers/v0/profile/direct_deposits_controller.rb +++ b/app/controllers/v0/profile/direct_deposits_controller.rb @@ -11,8 +11,7 @@ module Profile class DirectDepositsController < ApplicationController service_tag 'direct-deposit' before_action { authorize :lighthouse, :direct_deposit_access? } - before_action :payment_account, only: :update - before_action :control_information, only: :update + after_action :log_sso_info, only: :update rescue_from(*Lighthouse::ServiceException::ERROR_MAP.values) do |exception| @@ -28,12 +27,19 @@ class DirectDepositsController < ApplicationController def show response = client.get_payment_info + set_control_information(response.body[:control_information]) + log_control_info(@control_information, 'Show') + render status: response.status, json: response.body, serializer: DisabilityCompensationsSerializer end def update + set_control_information(control_info_params) + set_payment_account(payment_account_params) + + log_control_info(@control_information, 'Update') response = client.update_payment_info(@payment_account) send_confirmation_email @@ -44,6 +50,15 @@ def update private + def log_control_info(control_info, action) + ::Rails.logger.info("Direct Deposit Control Info: #{action}", + { benefit_type: control_info.benefit_type, + updatable: control_info.account_updatable?, + valid: control_info.valid?, + restrictions: control_info.restrictions.join(', '), + errors: control_info.errors.join(', ') }) + end + def single_form_enabled? Flipper.enabled?(:profile_show_direct_deposit_single_form, @current_user) end @@ -56,12 +71,13 @@ def client @client ||= DirectDeposit::Client.new(@current_user.icn) end - def payment_account - @payment_account ||= Lighthouse::DirectDeposit::PaymentAccount.new(payment_account_params) + def set_payment_account(params) + @payment_account ||= Lighthouse::DirectDeposit::PaymentAccount.new(params) end - def control_information - @control_information ||= Lighthouse::DirectDeposit::ControlInformation.new(control_info_params) + def set_control_information(params) + @control_information ||= Lighthouse::DirectDeposit::ControlInformation.new + @control_information.assign_attributes(params) end def payment_account_params @@ -84,7 +100,7 @@ def control_info_params :has_no_fiduciary_assigned, :is_not_deceased, :has_payment_address, - :has_indentity) + :has_identity) end def send_confirmation_email diff --git a/lib/lighthouse/direct_deposit/control_information.rb b/lib/lighthouse/direct_deposit/control_information.rb index 4ed67551aeb..a41dc0c42c9 100644 --- a/lib/lighthouse/direct_deposit/control_information.rb +++ b/lib/lighthouse/direct_deposit/control_information.rb @@ -3,58 +3,88 @@ module Lighthouse module DirectDeposit class ControlInformation - include ActiveModel::Model - - ACTIONS = [:can_update_direct_deposit].freeze - USAGES = %i[is_corp_available is_edu_claim_available].freeze - RESTRICTIONS = %i[ - is_corp_rec_found - has_no_bdn_payments - has_identity - has_index - is_competent - has_mailing_address - has_no_fiduciary_assigned - is_not_deceased - has_payment_address - ].freeze - - attr_accessor(*(ACTIONS + USAGES + RESTRICTIONS)) + include ActiveModel::Attributes + include ActiveModel::AttributeAssignment + + # Actions + attribute :can_update_direct_deposit, :boolean + + # Usage + attribute :is_corp_available, :boolean + attribute :is_edu_claim_available, :boolean + + # Restrictions + attribute :is_corp_rec_found, :boolean + attribute :has_no_bdn_payments, :boolean + attribute :has_identity, :boolean + attribute :has_index, :boolean + attribute :is_competent, :boolean + attribute :has_mailing_address, :boolean + attribute :has_no_fiduciary_assigned, :boolean + attribute :is_not_deceased, :boolean + attribute :has_payment_address, :boolean + attr_reader :errors alias :comp_and_pen? is_corp_available alias :edu_benefits? is_edu_claim_available def account_updatable? - @can_update_direct_deposit && restrictions.size.zero? + can_update_direct_deposit.present? && restrictions.size.zero? end def benefit_type? comp_and_pen? || edu_benefits? end + def benefit_type + return 'both' if comp_and_pen? && edu_benefits? + return 'cnp' if comp_and_pen? + return 'edu' if edu_benefits? + + 'none' + end + def restrictions - RESTRICTIONS.reject { |name| send(name) } + restrictions = [] + restrictions << 'is_corp_rec_found' unless is_corp_rec_found + restrictions << 'has_no_bdn_payments' unless has_no_bdn_payments + restrictions << 'has_identity' unless has_identity + restrictions << 'has_index' unless has_index + restrictions << 'is_competent' unless is_competent + restrictions << 'has_mailing_address' unless has_mailing_address + restrictions << 'has_no_fiduciary_assigned' unless has_no_fiduciary_assigned + restrictions << 'is_not_deceased' unless is_not_deceased + restrictions << 'has_payment_address' unless has_payment_address + restrictions end def clear_restrictions - @can_update_direct_deposit = true - RESTRICTIONS.each { |name| send("#{name}=", true) } + assign_attributes can_update_direct_deposit: true + assign_attributes is_corp_rec_found: true + assign_attributes has_no_bdn_payments: true + assign_attributes has_identity: true + assign_attributes has_index: true + assign_attributes is_competent: true + assign_attributes has_mailing_address: true + assign_attributes has_no_fiduciary_assigned: true + assign_attributes is_not_deceased: true + assign_attributes has_payment_address: true end def valid? @errors = [] error = 'Has restrictions. Account should not be updatable.' - errors << error if @can_update_direct_deposit && restrictions.any? + @errors << error if can_update_direct_deposit && restrictions.any? error = 'Has no restrictions. Account should be updatable.' - errors << error if !@can_update_direct_deposit && restrictions.empty? + @errors << error if !can_update_direct_deposit && restrictions.empty? error = 'Missing benefit type. Must be either CnP or EDU benefits.' - errors << error unless benefit_type? + @errors << error unless benefit_type? - errors.size.zero? + @errors.size.zero? end end end diff --git a/spec/controllers/v0/profile/direct_deposits_controller_spec.rb b/spec/controllers/v0/profile/direct_deposits_controller_spec.rb index 3dd8abc3e91..709a25e4e35 100644 --- a/spec/controllers/v0/profile/direct_deposits_controller_spec.rb +++ b/spec/controllers/v0/profile/direct_deposits_controller_spec.rb @@ -9,11 +9,28 @@ sign_in_as(user) token = 'abcdefghijklmnop' allow_any_instance_of(DirectDeposit::Configuration).to receive(:access_token).and_return(token) + allow(Rails.logger).to receive(:info) Flipper.disable(:profile_show_direct_deposit_single_form) end describe '#show' do context 'when successful' do + it 'logs the control info' do + VCR.use_cassette('lighthouse/direct_deposit/show/200_valid') do + get(:show) + end + + expect(response).to have_http_status(:ok) + expect(Rails.logger) + .to have_received(:info) + .with('Direct Deposit Control Info: Show', + { benefit_type: 'both', + updatable: true, + valid: true, + restrictions: '', + errors: '' }) + end + it 'returns a status of 200' do VCR.use_cassette('lighthouse/direct_deposit/show/200_valid') do get(:show) @@ -154,11 +171,36 @@ control_information: { can_update_direct_deposit: true, is_corp_available: true, - is_edu_claim_available: true + is_edu_claim_available: true, + is_corp_rec_found: true, + has_no_bdn_payments: true, + has_index: true, + is_competent: true, + has_mailing_address: true, + has_no_fiduciary_assigned: true, + is_not_deceased: true, + has_payment_address: true, + has_identity: true } } end + it 'logs the control info' do + VCR.use_cassette('lighthouse/direct_deposit/update/200_valid') do + put(:update, params:) + end + + expect(response).to have_http_status(:ok) + expect(Rails.logger) + .to have_received(:info) + .with('Direct Deposit Control Info: Update', + { benefit_type: 'both', + updatable: true, + valid: true, + restrictions: '', + errors: '' }) + end + it 'returns a status of 200' do VCR.use_cassette('lighthouse/direct_deposit/update/200_valid') do put(:update, params:) diff --git a/spec/lib/lighthouse/direct_deposit/control_information_spec.rb b/spec/lib/lighthouse/direct_deposit/control_information_spec.rb index ab3cdb5db61..252bf2c7296 100644 --- a/spec/lib/lighthouse/direct_deposit/control_information_spec.rb +++ b/spec/lib/lighthouse/direct_deposit/control_information_spec.rb @@ -10,16 +10,32 @@ info.clear_restrictions end + context 'when clear_restrictions is called' do + it 'is updatable' do + expect(info.account_updatable?).to be(true) + end + end + context 'when no restrictions' do it 'is updateable' do expect(info.account_updatable?).to be(true) expect(info.restrictions).to be_empty end + + context 'and can_update_direct_deposit is false' do + it 'is invalid' do + info.is_edu_claim_available = true + info.can_update_direct_deposit = false + + expect(info.valid?).to be(false) + expect(info.errors).to eq(['Has no restrictions. Account should be updatable.']) + end + end end context 'when there is a restriction' do it 'is not updateable' do - Lighthouse::DirectDeposit::ControlInformation::RESTRICTIONS.each do |name| + info.restrictions.each do |name| info.clear_restrictions info.send("#{name}=", false) @@ -27,6 +43,17 @@ expect(info.restrictions).not_to be_empty end end + + context 'and can_update_direct_deposit is true' do + it 'is invalid' do + info.is_corp_available = true + info.has_index = false + info.can_update_direct_deposit = true + + expect(info.valid?).to be(false) + expect(info.errors).to eq(['Has restrictions. Account should not be updatable.']) + end + end end context 'when is_corp_available is true' do @@ -43,30 +70,36 @@ end end - context 'has no benefit type' do + context 'when no benefit type' do it 'is invalid' do expect(info.valid?).to be(false) expect(info.errors).to eq(['Missing benefit type. Must be either CnP or EDU benefits.']) end end - context 'has restrictions' do - it 'account should not be updatable' do - info.is_edu_claim_available = true - info.has_identity = false + context 'benefit type' do + it 'returns a benefit type of cnp' do + info.is_corp_available = true + info.is_edu_claim_available = false + expect(info.benefit_type).to eq('cnp') + end - expect(info.valid?).to be(false) - expect(info.errors).to eq(['Has restrictions. Account should not be updatable.']) + it 'returns a benefit type of edu' do + info.is_corp_available = false + info.is_edu_claim_available = true + expect(info.benefit_type).to eq('edu') end - end - context 'has no restrictions' do - it 'account should be updatable' do + it 'returns a benefit type of both' do info.is_corp_available = true - info.can_update_direct_deposit = false + info.is_edu_claim_available = true + expect(info.benefit_type).to eq('both') + end - expect(info.valid?).to be(false) - expect(info.errors).to eq(['Has no restrictions. Account should be updatable.']) + it 'returns a benefit type of none' do + info.is_corp_available = false + info.is_edu_claim_available = false + expect(info.benefit_type).to eq('none') end end end From 8aebcd6d13ab77bd3e665802cedf95e5323da818 Mon Sep 17 00:00:00 2001 From: Rockwell Windsor Rice <129893414+rockwellwindsor-va@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:59:45 -0500 Subject: [PATCH 22/25] Api 34938 poa v2 create veteran rep (#16212) * WPI:Adds start of service * WIP * WIP * WIP:Updates structure to be more in line with manage rep structure to maintain uniformity * WIP:Updates params * Updates to take in options as the params for create_veteran_representative * Revert Gemfile.lock change because of conflict * Removes comment * Adds tests for valid request and incorrect ptcpnt_id being used * Removes uneeded value from test file * Revert Gemfile.lock change * Fixes typo in cassette --- .../veteran_representative_service.rb | 5 +- .../create_veteran_representative_request.rb | 21 ++ .../read_all_veteran_representatives.rb | 2 +- ...ate_veteran_representative_request_spec.rb | 147 +++++++++ .../veteran_representative_service_spec.rb | 36 +++ ...mpi_ptcpnt_id_instead_of_vnp_ptcpnt_id.yml | 233 +++++++++++++++ .../valid_params.yml | 280 ++++++++++++++++++ 7 files changed, 721 insertions(+), 3 deletions(-) create mode 100644 modules/claims_api/lib/bgs_service/veteran_representative_service/create_veteran_representative_request.rb create mode 100644 modules/claims_api/spec/lib/claims_api/bgs/veteran_representative_service/create_veteran_representative_request_spec.rb create mode 100644 modules/claims_api/spec/lib/claims_api/bgs/veteran_representative_service/veteran_representative_service_spec.rb create mode 100644 spec/support/vcr_cassettes/claims_api/bgs/veteran_representative_service/create_veteran_representative/mpi_ptcpnt_id_instead_of_vnp_ptcpnt_id.yml create mode 100644 spec/support/vcr_cassettes/claims_api/bgs/veteran_representative_service/create_veteran_representative/valid_params.yml diff --git a/modules/claims_api/lib/bgs_service/veteran_representative_service.rb b/modules/claims_api/lib/bgs_service/veteran_representative_service.rb index 7b798d89e24..2ef438d9482 100644 --- a/modules/claims_api/lib/bgs_service/veteran_representative_service.rb +++ b/modules/claims_api/lib/bgs_service/veteran_representative_service.rb @@ -1,15 +1,16 @@ # frozen_string_literal: true +require_relative 'veteran_representative_service/create_veteran_representative_request' require_relative 'veteran_representative_service/read_all_veteran_representatives' module ClaimsApi class VeteranRepresentativeService < ClaimsApi::LocalBGS private - def make_request(**args) + def make_request(namespace:, **args) super( endpoint: 'VDC/VeteranRepresentativeService', - namespaces: { 'ns0' => '/data' }, + namespaces: { namespace => '/data' }, transform_response: false, **args ) diff --git a/modules/claims_api/lib/bgs_service/veteran_representative_service/create_veteran_representative_request.rb b/modules/claims_api/lib/bgs_service/veteran_representative_service/create_veteran_representative_request.rb new file mode 100644 index 00000000000..69823f7f0c7 --- /dev/null +++ b/modules/claims_api/lib/bgs_service/veteran_representative_service/create_veteran_representative_request.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module ClaimsApi + class VeteranRepresentativeService < ClaimsApi::LocalBGS + def create_veteran_representative(options) + injected = convert_nil_values(options) + body = Nokogiri::XML::DocumentFragment.parse <<~EOXML + + #{injected} + + EOXML + + make_request( + namespace: 'data', + action: 'createVeteranRepresentative', + body: body.to_s, + key: 'VeteranRepresentativeReturn' + ) + end + end +end diff --git a/modules/claims_api/lib/bgs_service/veteran_representative_service/read_all_veteran_representatives.rb b/modules/claims_api/lib/bgs_service/veteran_representative_service/read_all_veteran_representatives.rb index b9de1f6f373..9dfeb0e3c69 100644 --- a/modules/claims_api/lib/bgs_service/veteran_representative_service/read_all_veteran_representatives.rb +++ b/modules/claims_api/lib/bgs_service/veteran_representative_service/read_all_veteran_representatives.rb @@ -13,7 +13,7 @@ def read_all_veteran_representatives(type_code:, ptcpnt_id:) #{type_code} EOXML - ret = make_request(action: 'readAllVeteranRepresentatives', body:) + ret = make_request(namespace: 'ns0', action: 'readAllVeteranRepresentatives', body:) &.dig('VeteranRepresentativeReturnList') || [] [ret].flatten end diff --git a/modules/claims_api/spec/lib/claims_api/bgs/veteran_representative_service/create_veteran_representative_request_spec.rb b/modules/claims_api/spec/lib/claims_api/bgs/veteran_representative_service/create_veteran_representative_request_spec.rb new file mode 100644 index 00000000000..ebcf7905201 --- /dev/null +++ b/modules/claims_api/spec/lib/claims_api/bgs/veteran_representative_service/create_veteran_representative_request_spec.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'bgs_service/veteran_representative_service' +require Rails.root.join('modules', 'claims_api', 'spec', 'support', 'bgs_client_helpers.rb') + +metadata = { + bgs: { + service: 'veteran_representative_service', + operation: 'create_veteran_representative' + } +} + +describe ClaimsApi::VeteranRepresentativeService, metadata do + describe '#create_veteran_representative' do + subject do + service = described_class.new(**header_params) + service.create_veteran_representative(**params) + end + + let(:header_params) do + { + external_uid: 'keyHere', + external_key: 'keyHere' + } + end + + describe 'with valid request params' do + let(:params) do + { + form_type_code: '21-22', + proc_id: '3854909', + veteran_ptcpnt_id: '182359', + poa_code: '074', + section_7332_auth: false, + limitation_drug_abuse: false, + limitation_alcohol: false, + limitation_hiv: false, + limitation_s_c_a: false, + limitation_h_i_v: false, + change_address_auth: true, + vdc_status: 'Submitted', + representative_type: 'Recognized Veterans Service Organization', + claimant_ptcpnt_id: '182358', + # rubocop:disable Naming/VariableNumber + address_line_1: '76 Crowther Ave', + # rubocop:enable Naming/VariableNumber + city: 'Bridgeport', + postal_code: '06605', + state: 'CT', + submitted_date: '2024-04-22T19:27:37Z' + } + end + + let(:expected_response) do + { + 'addressLine1' => '76 Crowther Ave', + 'addressLine2' => nil, + 'addressLine3' => nil, + 'changeAddressAuth' => 'true', + 'city' => 'Bridgeport', + 'claimantPtcpntId' => '182358', + 'claimantRelationship' => nil, + 'formTypeCode' => '21-22', + 'insuranceNumbers' => nil, + 'limitationAlcohol' => 'false', + 'limitationDrugAbuse' => 'false', + 'limitationHIV' => 'false', + 'limitationSCA' => 'false', + 'organizationName' => nil, + 'otherServiceBranch' => nil, + 'phoneNumber' => nil, + 'poaCode' => '074', + 'postalCode' => '06605', + 'procId' => '3854909', + 'representativeFirstName' => nil, + 'representativeLastName' => nil, + 'representativeLawFirmOrAgencyName' => nil, + 'representativeTitle' => nil, + 'representativeType' => 'Recognized Veterans Service Organization', + 'section7332Auth' => 'false', + 'serviceBranch' => nil, + 'serviceNumber' => nil, + 'state' => 'CT', + 'vdcStatus' => 'Submitted', + 'veteranPtcpntId' => '182359', + 'acceptedBy' => nil, + 'claimantFirstName' => 'VERNON', + 'claimantLastName' => 'WAGNER', + 'claimantMiddleName' => nil, + 'declinedBy' => nil, + 'declinedReason' => nil, + 'secondaryStatus' => nil, + 'veteranFirstName' => 'VERNON', + 'veteranLastName' => 'WAGNER', + 'veteranMiddleName' => nil, + 'veteranSSN' => nil, + 'veteranVAFileNumber' => nil + } + end + + it 'returns a response with expected body' do + use_bgs_cassette('valid_params') do + expect(subject).to eq(expected_response) + end + end + end + + describe 'with invalid params' do + describe 'with the MPI participant ID being used instead of the VNP participant ID' do + let(:params) do + { + form_type_code: '21-22', + proc_id: '3854909', + veteran_ptcpnt_id: '600043284', + poa_code: '074', + section_7332_auth: false, + limitation_drug_abuse: false, + limitation_alcohol: false, + limitation_hiv: false, + limitation_s_c_a: false, + limitation_h_i_v: false, + change_address_auth: true, + vdc_status: 'Submitted', + representative_type: 'Recognized Veterans Service Organization', + claimant_ptcpnt_id: '182358', + # rubocop:disable Naming/VariableNumber + address_line_1: '76 Crowther Ave', + # rubocop:enable Naming/VariableNumber + city: 'Bridgeport', + postal_code: '06605', + state: 'CT', + submitted_date: '2024-04-22T19:27:37Z' + } + end + + it 'raises Common::Exceptions::ServiceError' do + use_bgs_cassette('mpi_ptcpnt_id_instead_of_vnp_ptcpnt_id') do + expect { subject }.to raise_error( + Common::Exceptions::ServiceError + ) + end + end + end + end + end +end diff --git a/modules/claims_api/spec/lib/claims_api/bgs/veteran_representative_service/veteran_representative_service_spec.rb b/modules/claims_api/spec/lib/claims_api/bgs/veteran_representative_service/veteran_representative_service_spec.rb new file mode 100644 index 00000000000..c2db3c02fd1 --- /dev/null +++ b/modules/claims_api/spec/lib/claims_api/bgs/veteran_representative_service/veteran_representative_service_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'bgs_service/veteran_representative_service' +require Rails.root.join('modules', 'claims_api', 'spec', 'support', 'bgs_client_helpers.rb') + +describe ClaimsApi::VeteranRepresentativeService do + let(:header_params) do + { + external_uid: 'xUid', + external_key: 'xKey' + } + end + + describe 'with a namespace param' do + it 'does not raise ArgumentError' do + service = described_class.new(**header_params) + expect do + service.send(:make_request, namespace: 'testspace', action: 'testAction', body: 'this is the body', + key: 'ThisIsTheKey') + end.not_to raise_error(ArgumentError) + end + end + + describe 'without the namespace param' do + let(:params) { { ptcpnt_id: '123456' } } + + it 'raises ArgumentError' do + service = described_class.new(**header_params) + expect do + service.send(:make_request, action: 'testAction', body: 'this is the body', + key: 'ThisIsTheKey') + end.to raise_error(ArgumentError) + end + end +end diff --git a/spec/support/vcr_cassettes/claims_api/bgs/veteran_representative_service/create_veteran_representative/mpi_ptcpnt_id_instead_of_vnp_ptcpnt_id.yml b/spec/support/vcr_cassettes/claims_api/bgs/veteran_representative_service/create_veteran_representative/mpi_ptcpnt_id_instead_of_vnp_ptcpnt_id.yml new file mode 100644 index 00000000000..9314758c514 --- /dev/null +++ b/spec/support/vcr_cassettes/claims_api/bgs/veteran_representative_service/create_veteran_representative/mpi_ptcpnt_id_instead_of_vnp_ptcpnt_id.yml @@ -0,0 +1,233 @@ +--- +http_interactions: +- request: + method: get + uri: "/VDC/VeteranRepresentativeService?WSDL" + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.9.0 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 23 Apr 2024 19:25:26 GMT + Server: + - Apache + X-Frame-Options: + - SAMEORIGIN + Transfer-Encoding: + - chunked + Content-Type: + - text/xml;charset=utf-8 + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: |- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + recorded_at: Mon, 22 Apr 2024 19:27:00 GMT +- request: + method: post + uri: "/VDC/VeteranRepresentativeService" + body: + encoding: UTF-8 + string: | + + + + + + VAgovAPI + + + 127.0.0.1 + 281 + VAgovAPI + keyHere + keyHere + + + + + + + 21-223854909600043284074falsefalsefalsefalsefalsefalsetrueSubmittedRecognized Veterans Service Organization18235876 Crowther AveBridgeport06605CT2024-04-22T19:27:37Z + + + + + headers: + User-Agent: + - Faraday v2.9.0 + Content-Type: + - text/xml;charset=UTF-8 + Host: + - ".vba.va.gov" + Soapaction: + - '"createVeteranRepresentative"' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 500 + message: Internal Server Error + headers: + Date: + - Tue, 23 Apr 2024 19:25:27 GMT + Server: + - Apache + X-Frame-Options: + - SAMEORIGIN + Transfer-Encoding: + - chunked + Content-Type: + - text/xml; charset=utf-8 + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: 'ns0:Servergov.va.vba.benefits.exceptions.MessageFault + + 3 + : + ORA-02291: integrity constraint (CORPPROD.FK1_VNP_PTCPNT_RLNSHP) violated - parent key + not found - Input: Proc ID: 3854909, poa code = 074, formTypeCode = 21-22, + submittedDate: 2024-04-22T14:27:37-05:00 + + + 3 + : + ORA-02291: integrity constraint (CORPPROD.FK1_VNP_PTCPNT_RLNSHP) violated - parent key + not found - Input: Proc ID: 3854909, poa code = 074, formTypeCode = 21-22, + submittedDate: 2024-04-22T14:27:37-05:00 + + + + + + ' + recorded_at: Mon, 22 Apr 2024 19:27:00 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/support/vcr_cassettes/claims_api/bgs/veteran_representative_service/create_veteran_representative/valid_params.yml b/spec/support/vcr_cassettes/claims_api/bgs/veteran_representative_service/create_veteran_representative/valid_params.yml new file mode 100644 index 00000000000..767a27d1269 --- /dev/null +++ b/spec/support/vcr_cassettes/claims_api/bgs/veteran_representative_service/create_veteran_representative/valid_params.yml @@ -0,0 +1,280 @@ +--- +http_interactions: +- request: + method: get + uri: "/VDC/VeteranRepresentativeService?WSDL" + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.9.0 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 23 Apr 2024 19:07:13 GMT + Server: + - Apache + X-Frame-Options: + - SAMEORIGIN + Transfer-Encoding: + - chunked + Content-Type: + - text/xml;charset=utf-8 + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: |- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + recorded_at: Mon, 22 Apr 2024 19:27:37 GMT +- request: + method: post + uri: "/VDC/VeteranRepresentativeService" + body: + encoding: UTF-8 + string: | + + + + + + VAgovAPI + + + 127.0.0.1 + 281 + VAgovAPI + keyHere + keyHere + + + + + + + + 21-22 + 3854909 + 182359 + 074 + false + false + false + false + false + false + true + Submitted + Recognized Veterans Service Organization + 182358 + 76 Crowther Ave + Bridgeport + 06605 + CT + 2024-04-22T19:27:37Z + + + + + headers: + User-Agent: + - Faraday v2.9.0 + Content-Type: + - text/xml;charset=UTF-8 + Host: + - ".vba.va.gov" + Soapaction: + - '"createVeteranRepresentative"' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 23 Apr 2024 19:07:14 GMT + Server: + - Apache + X-Frame-Options: + - SAMEORIGIN + Transfer-Encoding: + - chunked + Content-Type: + - text/xml; charset=utf-8 + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: + + 76 Crowther Ave + + + true + Bridgeport + 182358 + + 21-22 + + false + false + false + false + + + + 074 + 06605 + 3854909 + + + + + Recognized Veterans Service Organization + false + + + CT + Submitted + 182359 + + VERNON + WAGNER + + + + + VERNON + WAGNER + + + + + + + + recorded_at: Mon, 22 Apr 2024 19:27:37 GMT +recorded_with: VCR 6.2.0 From 225805b190a44e3bf8646552996a700cf41ebf26 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen <134089461+Khoa-V-Nguyen@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:07:16 -0600 Subject: [PATCH 23/25] BE | Ask Va Api: `Inquiries` retriever error handling (#16489) * update inquiries retriever error handling * remove authenticate for InquiriesController#show action --------- Co-authored-by: khoa-v-nguyen --- .../ask_va_api/v0/inquiries_controller.rb | 4 ++- .../app/lib/ask_va_api/inquiries/retriever.rb | 7 ++++- .../ask_va_api/inquiries/retriever_spec.rb | 20 ++++++++----- .../spec/requests/v0/inquiries_spec.rb | 30 +++++++++---------- 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/modules/ask_va_api/app/controllers/ask_va_api/v0/inquiries_controller.rb b/modules/ask_va_api/app/controllers/ask_va_api/v0/inquiries_controller.rb index 9cc82b5a60e..12f91508ed1 100644 --- a/modules/ask_va_api/app/controllers/ask_va_api/v0/inquiries_controller.rb +++ b/modules/ask_va_api/app/controllers/ask_va_api/v0/inquiries_controller.rb @@ -6,7 +6,7 @@ class InquiriesController < ApplicationController around_action :handle_exceptions before_action :get_inquiries_by_icn, only: [:index] before_action :get_inquiry_by_id, only: [:show] - skip_before_action :authenticate, only: %i[unauth_create upload_attachment test_create] + skip_before_action :authenticate, only: %i[unauth_create upload_attachment test_create show] skip_before_action :verify_authenticity_token, only: %i[unauth_create upload_attachment test_create] def index @@ -63,6 +63,8 @@ def create_reply private def get_inquiry_by_id + entity_class = AskVAApi::Inquiries::Entity + retriever = Inquiries::Retriever.new(user_mock_data: params[:mock], entity_class:) inq = retriever.fetch_by_id(id: params[:id]) @inquiry = Result.new(payload: Inquiries::Serializer.new(inq).serializable_hash, status: :ok) end diff --git a/modules/ask_va_api/app/lib/ask_va_api/inquiries/retriever.rb b/modules/ask_va_api/app/lib/ask_va_api/inquiries/retriever.rb index 0951d724eb8..073c35f8832 100644 --- a/modules/ask_va_api/app/lib/ask_va_api/inquiries/retriever.rb +++ b/modules/ask_va_api/app/lib/ask_va_api/inquiries/retriever.rb @@ -57,7 +57,12 @@ def filter_data(data, id = nil) end def handle_response_data(response) - response[:Data].presence || raise(InquiriesRetrieverError, response[:Message]) + if response[:Data].nil? + error = JSON.parse(response[:body], symbolize_names: true) + raise InquiriesRetrieverError, error[:Message] + else + response[:Data] + end end end end diff --git a/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/retriever_spec.rb b/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/retriever_spec.rb index b848c81cb93..ee1f4e45987 100644 --- a/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/retriever_spec.rb +++ b/modules/ask_va_api/spec/app/lib/ask_va_api/inquiries/retriever_spec.rb @@ -20,17 +20,23 @@ describe '#call' do context 'when Crm raise an error' do let(:icn) { '123' } - let(:response) do - { Data: nil, - Message: 'Data Validation: No Contact found by ICN', - ExceptionOccurred: true, - ExceptionMessage: 'Data Validation: No Contact found by ICN', - MessageId: '2733ca25-7e64-4fbc-af2c-366f4bd2e3dc' } + let(:body) do + '{"Data":null,"Message":"Data Validation: No Inquiries found by ID A-20240423-30709"' \ + ',"ExceptionOccurred":true,"ExceptionMessage":"Data Validation: No Inquiries found by ' \ + 'ID A-20240423-30709","MessageId":"ca5b990a-63fe-407d-a364-46caffce12c1"}' + end + let(:failure) do + { + status: 400, + body:, + response_headers: nil, + url: nil + } end before do allow_any_instance_of(Crm::CrmToken).to receive(:call).and_return('Token') - allow(service).to receive(:call).and_return(response) + allow(service).to receive(:call).and_return(failure) end it 'raise CorrespondenceRetrieverrError' do diff --git a/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb b/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb index 25ff307fb6f..03eec8510ca 100644 --- a/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb +++ b/modules/ask_va_api/spec/requests/v0/inquiries_spec.rb @@ -207,19 +207,25 @@ end context 'when the id is invalid' do - let(:crm_response) do - { Data: nil, - Message: 'Data Validation: No Inquiries found by ID A-20230305-30617', - ExceptionOccurred: true, - ExceptionMessage: 'Data Validation: No Inquiries found by ID A-20230305-30617', - MessageId: 'e6024ccb-e19b-4bc6-990c-667e7ebab4ec' } + let(:body) do + '{"Data":null,"Message":"Data Validation: No Inquiries found by ID A-20240423-30709"' \ + ',"ExceptionOccurred":true,"ExceptionMessage":"Data Validation: No Inquiries found by ' \ + 'ID A-20240423-30709","MessageId":"ca5b990a-63fe-407d-a364-46caffce12c1"}' + end + let(:failure) do + { + status: 400, + body:, + response_headers: nil, + url: nil + } end let(:service) { instance_double(Crm::Service) } before do allow(Crm::Service).to receive(:new).and_return(service) allow_any_instance_of(Crm::CrmToken).to receive(:call).and_return('Token') - allow(service).to receive(:call).and_return(crm_response) + allow(service).to receive(:call).and_return(failure) sign_in(authorized_user) get "#{inquiry_path}/#{invalid_id}" end @@ -228,17 +234,9 @@ it_behaves_like 'common error handling', :unprocessable_entity, 'service_error', 'AskVAApi::Inquiries::InquiriesRetrieverError: ' \ - 'Data Validation: No Inquiries found by ID A-20230305-30617' + 'Data Validation: No Inquiries found by ID A-20240423-30709' end end - - context 'when user is not signed in' do - before do - get "#{inquiry_path}/#{valid_id}" - end - - it { expect(response).to have_http_status(:unauthorized) } - end end describe 'GET #download_attachment' do From 4f082e5f97b280b50a890b555ea0e9e2c924d340 Mon Sep 17 00:00:00 2001 From: Seth Darr <92405130+sethdarragile6@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:26:20 -0700 Subject: [PATCH 24/25] Toxic Exposure: Add basic toxicExposure node to pre-submission JSON (#16450) * add toxicExposure to pre-submission JSON * remove aborted test attempt * fixed malformed JSON in with_everything * rubocop'd it * add TE flipper flag * remove breakpoints * rubocop * fix the with_everything.json * change toxicExposureConditions to conditions --- .../data_translation_all_claim.rb | 9 +++ .../data_translation_all_claim_spec.rb | 30 +++++++++ ...sability_compensation_form_request_spec.rb | 2 + .../all_claims_fe_submission.json | 1 + .../submissions/with_everything.json | 64 ++++++++++++++++++- 5 files changed, 105 insertions(+), 1 deletion(-) diff --git a/lib/evss/disability_compensation_form/data_translation_all_claim.rb b/lib/evss/disability_compensation_form/data_translation_all_claim.rb index 8eda0195f33..dd7b695d1a0 100644 --- a/lib/evss/disability_compensation_form/data_translation_all_claim.rb +++ b/lib/evss/disability_compensation_form/data_translation_all_claim.rb @@ -62,6 +62,7 @@ def translate output_form.update(translate_veteran) output_form.update(translate_treatments) output_form.update(translate_disabilities) + output_form.update(add_toxic_exposure) if Flipper.enabled?(:disability_526_toxic_exposure, @current_user) @translated_form end @@ -629,6 +630,14 @@ def map_secondary(input_disability, disabilities) end end + ### + # Toxic Exposure + ### + + def add_toxic_exposure + { 'toxicExposure' => input_form['toxicExposure'] } + end + def application_expiration_date 1.year.from_now.iso8601 end diff --git a/spec/lib/evss/disability_compensation_form/data_translation_all_claim_spec.rb b/spec/lib/evss/disability_compensation_form/data_translation_all_claim_spec.rb index 0d000d350b5..88ac3800b51 100644 --- a/spec/lib/evss/disability_compensation_form/data_translation_all_claim_spec.rb +++ b/spec/lib/evss/disability_compensation_form/data_translation_all_claim_spec.rb @@ -1451,6 +1451,36 @@ end end + describe '#add_toxic_exposure' do + let(:form_content) do + { + 'form526' => { + 'toxicExposure' => { + 'gulfWar1990' => { + 'iraq' => true, + 'kuwait' => true, + 'qatar' => true + } + } + } + } + end + + it 'returns toxic exposure' do + expect(subject.send(:add_toxic_exposure)).to eq( + { + 'toxicExposure' => { + 'gulfWar1990' => { + 'iraq' => true, + 'kuwait' => true, + 'qatar' => true + } + } + } + ) + end + end + describe '#application_expiration_date' do it 'returns the application creation date + 365 days' do expect(subject.send(:application_expiration_date)).to eq '2021-11-05T18:19:50Z' diff --git a/spec/requests/disability_compensation_form_request_spec.rb b/spec/requests/disability_compensation_form_request_spec.rb index eb08c9a4385..6825d965218 100644 --- a/spec/requests/disability_compensation_form_request_spec.rb +++ b/spec/requests/disability_compensation_form_request_spec.rb @@ -242,6 +242,8 @@ def test_error(cassette_path, status, headers) post('/v0/disability_compensation_form/submit_all_claim', params: all_claims_form, headers:) expect(response).to have_http_status(:ok) expect(response).to match_response_schema('submit_disability_form') + form = Form526Submission.last.form + expect(form.dig('form526', 'form526', 'toxicExposure')).not_to eq(nil) end it 'matches the rated disabilites schema with camel-inflection' do diff --git a/spec/support/disability_compensation_form/all_claims_fe_submission.json b/spec/support/disability_compensation_form/all_claims_fe_submission.json index 648eff4fd18..200e53e75c2 100644 --- a/spec/support/disability_compensation_form/all_claims_fe_submission.json +++ b/spec/support/disability_compensation_form/all_claims_fe_submission.json @@ -144,6 +144,7 @@ ] } ], + "toxicExposure": {}, "waiveRetirementPay": false, "waiveTrainingPay": true, "hasTrainingPay": true diff --git a/spec/support/disability_compensation_form/submissions/with_everything.json b/spec/support/disability_compensation_form/submissions/with_everything.json index 1fb50701faa..d93f8ff4aa9 100644 --- a/spec/support/disability_compensation_form/submissions/with_everything.json +++ b/spec/support/disability_compensation_form/submissions/with_everything.json @@ -191,7 +191,69 @@ } ] } - ] + ], + "toxicExposure": { + "gulfWar1990": { + "iraq": true, + "kuwait": true, + "qatar": true + }, + "gulfWar1990Details": { + "iraq": { + "startDate": "1991-03-01", + "endDate": "1992-01-01" + }, + "qatar": { + "startDate": "1991-02-12", + "endDate": "1991-06-01" + }, + "kuwait": { + "startDate": "1991-03-15" + } + }, + "herbicide": { + "cambodia": true, + "guam": true, + "laos": true + }, + "herbicideDetails": { + "cambodia": { + "startDate": "1991-03-01", + "endDate": "1992-01-01" + }, + "guam": { + "startDate": "1991-02-12", + "endDate": "1991-06-01" + }, + "laos": { + "startDate": "1991-03-15" + } + }, + "otherHerbicideLocations": "freeform text field.", + "otherExposures": { + "asbestos": true, + "radiation": true, + "mustardgas": false + }, + "otherExposureDetails": { + "asbestos": { + "startDate": "1991-03-01", + "endDate": "1992-01-01" + }, + "radiation": { + "startDate": "1991-03-01", + "endDate": "1992-01-01" + } + }, + "specifyOtherExposures": { + "description": "Lead, burn pits", + "startDate": "1991-03-01", + "endDate": "1992-01-01" + }, + "conditions": { + "deviatedseptum": true + } + } } }, "form526_uploads": [ From 9f01854a9f55ac5d7089fb57dde1a6d4408669ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 07:31:19 -0500 Subject: [PATCH 25/25] Bump super_diff from 0.11.0 to 0.12.0 (#16495) Bumps [super_diff](https://github.com/mcmire/super_diff) from 0.11.0 to 0.12.0. - [Release notes](https://github.com/mcmire/super_diff/releases) - [Changelog](https://github.com/mcmire/super_diff/blob/main/CHANGELOG.md) - [Commits](https://github.com/mcmire/super_diff/compare/v0.11.0...v0.12.0) --- updated-dependencies: - dependency-name: super_diff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c97180f9bf7..d347bccd1bc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -998,7 +998,7 @@ GEM stringio (3.1.0) strong_migrations (1.8.0) activerecord (>= 5.2) - super_diff (0.11.0) + super_diff (0.12.0) attr_extras (>= 6.2.4) diff-lcs patience_diff