diff --git a/Gemfile.lock b/Gemfile.lock index 0ff0f7d6eb8..d0b8c2ae221 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -603,7 +603,7 @@ GEM jruby-openssl (0.15.1-java) json (2.7.5) json (2.7.5-java) - json-schema (5.0.1) + json-schema (5.1.0) addressable (~> 2.8) json_schema (0.21.0) json_schemer (2.3.0) @@ -729,7 +729,7 @@ GEM openssl (3.2.0-java) jruby-openssl (~> 0.14) operating_hours (0.1.0) - optimist (3.1.0) + optimist (3.2.0) os (1.1.4) ostruct (0.6.1) ox (2.14.18) @@ -1041,7 +1041,7 @@ GEM stringio (3.1.2) strong_migrations (2.0.2) activerecord (>= 6.1) - super_diff (0.13.0) + super_diff (0.14.0) attr_extras (>= 6.2.4) diff-lcs patience_diff diff --git a/app/controllers/v0/disability_compensation_forms_controller.rb b/app/controllers/v0/disability_compensation_forms_controller.rb index 09c0814e4e2..ef1ce6556fc 100644 --- a/app/controllers/v0/disability_compensation_forms_controller.rb +++ b/app/controllers/v0/disability_compensation_forms_controller.rb @@ -52,6 +52,9 @@ def suggested_conditions end def submit_all_claim + temp_separation_location_fix if Flipper.enabled?(:disability_compensation_temp_separation_location_code_string, + @current_user) + saved_claim = SavedClaim::DisabilityCompensation::Form526AllClaim.from_hash(form_content) saved_claim.save ? log_success(saved_claim) : log_failure(saved_claim) submission = create_submission(saved_claim) @@ -172,5 +175,21 @@ def missing_disabilities?(submission) end false end + + # TEMPORARY + # Turn separation location into string + # 11/18/2024 BRD EVSS -> Lighthouse migration caused separation location to turn into an integer, + # while SavedClaim (vets-json-schema) is expecting a string + def temp_separation_location_fix + if form_content.is_a?(Hash) && form_content['form526'].is_a?(Hash) + separation_location_code = form_content.dig('form526', 'serviceInformation', 'separationLocation', + 'separationLocationCode') + unless separation_location_code.nil? + form_content['form526']['serviceInformation']['separationLocation']['separationLocationCode'] = + separation_location_code.to_s + end + end + end + # END TEMPORARY end end diff --git a/app/sidekiq/evss/disability_compensation_form/submit_form0781.rb b/app/sidekiq/evss/disability_compensation_form/submit_form0781.rb index 7056b36dd39..c06e9670303 100644 --- a/app/sidekiq/evss/disability_compensation_form/submit_form0781.rb +++ b/app/sidekiq/evss/disability_compensation_form/submit_form0781.rb @@ -149,7 +149,7 @@ def get_docs(submission_id, uuid) if parsed_forms[form_type_key].present? file_type_and_file_objs << { type: actual_form_types, - file: process_0781(uuid, FORM_ID_0781, parsed_forms[form_type_key], + file: process_0781(uuid, actual_form_types, parsed_forms[form_type_key], upload: false) } end diff --git a/config/betamocks/services_config.yml b/config/betamocks/services_config.yml index 2bdf997c445..3e29c582c21 100644 --- a/config/betamocks/services_config.yml +++ b/config/betamocks/services_config.yml @@ -941,6 +941,13 @@ - :name: "GIDS" :base_uri: <%= "#{URI(Settings.gids.url).host}:#{URI(Settings.gids.url).port}" %> :endpoints: + - :method: :get + :path: "/gids/v0/institution_programs" + :file_path: "gids/programs" + # Mock only enabled when filtering by flight programs, see: lib/gi/search_client.rb + :cache_multiple_responses: + :uid_location: query + :uid_locator: type - :method: :get :path: "/gids/v1/lce" :file_path: "gids/lce" diff --git a/config/features.yml b/config/features.yml index fda615484b7..2eac790e6e6 100644 --- a/config/features.yml +++ b/config/features.yml @@ -23,6 +23,10 @@ features: actor_type: user description: Enables the endpoints of the accredited representative portal enable_in_development: true + aedp_vadx: + actor_type: user + description: Enables the VADX experimental features in the AEDP application + enable_in_development: true all_claims_add_disabilities_enhancement: actor_type: user description: Enables enhancement to the 21-526EZ "Add Disabilities" page being implemented by the Conditions Team. @@ -166,9 +170,6 @@ features: champva_unique_temp_file_names: actor_type: user description: Enables unique temp file names for CHAMPVA PDF files - champva_file_recreate: - actor_type: user - description: Enhances file creation reliability by adding retry functionality in the vets-api tmp folder champva_failure_email_job_enabled: actor_type: user description: Enables sending failure notification emails for IVC CHAMPVA form submissions that lack a Pega status @@ -530,6 +531,9 @@ features: actor_type: user description: enables sending flashes to BGS for disability_compensation submissions. enable_in_development: true + disability_compensation_temp_separation_location_code_string: + actor_type: user + description: enables forcing separation location code to be a string in submit_all_claim endpoint. disability_compensation_form4142_supplemental: actor_type: user description: Use Lighthouse API to submit supplemental Form 21-4142 from Form 526EZ submissions @@ -1046,6 +1050,10 @@ features: actor_type: user description: Enables/disables filter feature for medications list enable_in_development: true + mhv_medications_display_grouping: + actor_type: user + description: Enables/disables grouping medications related work + enable_in_development: true mobile_allergy_intolerance_model: actor_type: user description: For mobile app, enalbes use of strict models for parsing allergy intolerance diff --git a/config/settings.yml b/config/settings.yml index f90840cc4c4..d1d68722acd 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -490,6 +490,8 @@ gids: url: https://dev.va.gov/gids open_timeout: 1 read_timeout: 1 + search: + use_mocks: false lce: use_mocks: false @@ -1288,6 +1290,8 @@ vanotify: form21_674_action_needed_email: form21_674_action_needed_email_template_id form21_0966_confirmation_email: form21_0966_confirmation_email_template_id form21_0966_error_email: form21_0966_error_email_template_id + form21_0966_received_email: form21_0966_received_email_template_id + form21_0966_itf_api_received_email: form21_0966_itf_api_received_email_template_id form21_0972_confirmation_email: form21_0972_confirmation_email_template_id form21_0972_error_email: form21_0972_error_email_template_id form21_0972_received_email: form21_0972_received_email_template_id @@ -1845,6 +1849,7 @@ vaos: client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" audience_claim_url: "https://login.wellhive.com/oauth2/default/v1/token" access_token_url: "https://login.wellhive.com/oauth2/default/v1/token" - api_url: "https://api.wellhive.com/care-navigation/v1" + api_url: "https://api.wellhive.com" + base_path: "care-navigation/v1" scopes: "care-nav" diff --git a/config/settings/production.yml b/config/settings/production.yml index 94c004502e0..bf4692f5afa 100644 --- a/config/settings/production.yml +++ b/config/settings/production.yml @@ -1,2 +1,92 @@ +betamocks: + recording: false +central_mail: + upload: + enabled: true +check_in: + authentication: + retry_attempt_expiry: 604800 + chip_api_v2: + mock: false + timeout: 30 + lorota_v2: + mock: false + travel_reimbursement_api: + redis_token_expiry: 3540 +clamav: + mock: false +coverband: + github_organization: department-of-veterans-affairs +decision_review: + mock: false + pdf_validation: + enabled: true +dogstatsd: + enabled: true +evss: + s3: + uploads_enabled: true +expiry_scanner: + slack: + channel_id: C24RH0W11 +flipper: + github_organization: department-of-veterans-affairs + mute_logs: false +form_10_10cg: + poa: + s3: + enabled: true +form526_backup: + submission_method: single +google_analytics_cvu: + type: service_account hca: ca: [] +lighthouse: + benefits_intake: + path: /services/vba_documents + use_mocks: false + version: v1 + veteran_verification: + form526: + use_mocks: false +maintenance: + services: + bgs: P5Q2OCZ +modules_appeals_api: + legacy_appeals_enabled: true + schema_dir: config/schemas +mvi: + pii_logging: false +session_cookie: + secure: true +sidekiq_admin_panel: false +sidekiq: + github_organization: department-of-veterans-affairs +va_profile: + contact_information: + cache_enabled: true + enabled: true + mock: false + timeout: 30 + demographics: + cache_enabled: false + enabled: true + mock: false + timeout: 30 + military_personnel: + cache_enabled: false + enabled: true + mock: false + timeout: 30 + veteran_status: + mock: false +vba_documents: + enable_validate_document_endpoint: true + s3: + enabled: true + slack: + daily_notification_hour: 7 + in_flight_notification_hung_time_in_days: 14 + renotification_in_minutes: 1440 + update_stalled_notification_in_minutes: 180 diff --git a/lib/disability_compensation/responses/intake_sites_response.rb b/lib/disability_compensation/responses/intake_sites_response.rb index 3828d5cddc0..b944cb731c1 100644 --- a/lib/disability_compensation/responses/intake_sites_response.rb +++ b/lib/disability_compensation/responses/intake_sites_response.rb @@ -6,7 +6,7 @@ class SeparationLocation include ActiveModel::Serialization include Virtus.model - attribute :code, Integer + attribute :code, String attribute :description, String end diff --git a/lib/gi/search_client.rb b/lib/gi/search_client.rb index bdb1528c565..0a57a92c4c5 100644 --- a/lib/gi/search_client.rb +++ b/lib/gi/search_client.rb @@ -14,6 +14,10 @@ def get_institution_search_results_v0(params = {}) end def get_institution_program_search_results_v0(params = {}) + # Mock response if querying for flight school programs + # TO-DO: Remove after flight school program data becomes accessible + config.instance_variable_set(:@program_type_flight, true) if params[:type] == 'FLGT' + response = perform(:get, 'v0/institution_programs', params) gids_response(response) end diff --git a/lib/gi/search_configuration.rb b/lib/gi/search_configuration.rb index f2124999100..63f35628ee8 100644 --- a/lib/gi/search_configuration.rb +++ b/lib/gi/search_configuration.rb @@ -4,5 +4,14 @@ module GI class SearchConfiguration < GI::Configuration self.read_timeout = Settings.gids.search&.read_timeout || 4 self.open_timeout = Settings.gids.search&.open_timeout || 4 + + # Mock response if querying for flight school programs + # TO-DO: Remove after flight school program data becomes accessible + def use_mocks? + return false unless instance_variable_defined?(:@program_type_flight) + + querying_by_flight = remove_instance_variable(:@program_type_flight) + (querying_by_flight && Settings.gids.search.use_mocks) || false + end end end diff --git a/lib/medical_records/bb_internal/client.rb b/lib/medical_records/bb_internal/client.rb index 4c690806189..dcf4b76e071 100644 --- a/lib/medical_records/bb_internal/client.rb +++ b/lib/medical_records/bb_internal/client.rb @@ -17,6 +17,35 @@ class Client < Common::Client::Base configuration BBInternal::Configuration client_session BBInternal::ClientSession + ################################################################################ + # User Management APIs + ################################################################################ + + # Retrieves the patient information by user ID. + # @return [Hash] A hash containing the patient's details + # + def get_patient + response = perform(:get, "usermgmt/patient/uid/#{@session.user_id}", nil, token_headers) + patient = response.body + + raise Common::Exceptions::ServiceError.new(detail: 'Patient not found') if patient.blank? + + patient + end + + # Retrieves the BBMI notification setting for the user. + # @return [Hash] containing: + # - flag [Boolean]: Indicates whether the BBMI notification setting is enabled (true) or disabled (false) + # + def get_bbmi_notification_setting + response = perform(:get, 'usermgmt/notification/bbmi', nil, token_headers) + response.body + end + + ################################################################################ + # Blue Button Medical Imaging (BBMI) APIs + ################################################################################ + ## # Get a list of MHV radiology reports from VIA for the current user. These results do not # include CVIX reports. @@ -127,25 +156,73 @@ def get_study_status response.body end - # Retrieves the BBMI notification setting for the user. - # @return [Hash] containing: - # - flag [Boolean]: Indicates whether the BBMI notification setting is enabled (true) or disabled (false) - # - def get_bbmi_notification_setting - response = perform(:get, 'usermgmt/notification/bbmi', nil, token_headers) + ################################################################################ + # Self-Entered Information (SEI) APIs + ################################################################################ + + def get_sei_vital_signs_summary + response = perform(:get, "vitals/summary/#{@session.user_id}", nil, token_headers) response.body end - # Retrieves the patient information by user ID. - # @return [Hash] A hash containing the patient's details - # - def get_patient - response = perform(:get, "usermgmt/patient/uid/#{@session.user_id}", nil, token_headers) - patient = response.body + def get_sei_allergies + response = perform(:get, "healthhistory/allergy/#{@session.user_id}", nil, token_headers) + response.body + end - raise Common::Exceptions::ServiceError.new(detail: 'Patient not found') if patient.blank? + def get_sei_family_health_history + response = perform(:get, "healthhistory/healthHistory/#{@session.user_id}", nil, token_headers) + response.body + end - patient + def get_sei_immunizations + response = perform(:get, "healthhistory/immunization/#{@session.user_id}", nil, token_headers) + response.body + end + + def get_sei_test_entries + response = perform(:get, "healthhistory/testEntry/#{@session.user_id}", nil, token_headers) + response.body + end + + def get_sei_medical_events + response = perform(:get, "healthhistory/medicalEvent/#{@session.user_id}", nil, token_headers) + response.body + end + + def get_sei_military_history + response = perform(:get, "healthhistory/militaryHistory/#{@session.user_id}", nil, token_headers) + response.body + end + + def get_sei_healthcare_providers + response = perform(:get, "getcare/healthCareProvider/#{@session.user_id}", nil, token_headers) + response.body + end + + def get_sei_health_insurance + response = perform(:get, "getcare/healthInsurance/#{@session.user_id}", nil, token_headers) + response.body + end + + def get_sei_treatment_facilities + response = perform(:get, "getcare/treatmentFacility/#{@session.user_id}", nil, token_headers) + response.body + end + + def get_sei_food_journal + response = perform(:get, "journal/journals/#{@session.user_id}", nil, token_headers) + response.body + end + + def get_sei_activity_journal + response = perform(:get, "journal/activityjournals/#{@session.user_id}", nil, token_headers) + response.body + end + + def get_sei_medications + response = perform(:get, "pharmacy/medications/#{@session.user_id}", nil, token_headers) + response.body end # Retrieves the patient demographic information 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 3c80c3e6954..9ceb5e72b75 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 @@ -192,6 +192,7 @@ def full_transform_form :'view:streamlined_waiver', :'view:streamlined_waiver_asset_update', :'view:review_page_navigation_toggle', + :'view:show_updated_expense_pages', questions: %i[ has_repayments has_credit_card_bills has_recreational_vehicle has_vehicle has_real_estate spouse_has_benefits is_married @@ -317,11 +318,12 @@ def full_transform_form ] ], expenses: [ - expense_records: %i[name amount], - credit_card_bills: %i[ - purpose creditor_name original_amount unpaid_balance - amount_due_monthly date_started amount_past_due - ] + :monthly_housing_expenses, + { expense_records: %i[name amount], + credit_card_bills: %i[ + purpose creditor_name original_amount unpaid_balance + amount_due_monthly date_started amount_past_due + ] } ], utility_records: %i[name amount], other_expenses: %i[name amount], diff --git a/modules/ivc_champva/app/controllers/ivc_champva/v1/uploads_controller.rb b/modules/ivc_champva/app/controllers/ivc_champva/v1/uploads_controller.rb index 4b8f4a0291a..e2732a66ce6 100644 --- a/modules/ivc_champva/app/controllers/ivc_champva/v1/uploads_controller.rb +++ b/modules/ivc_champva/app/controllers/ivc_champva/v1/uploads_controller.rb @@ -15,50 +15,25 @@ class UploadsController < ApplicationController '10-7959A' => 'vha_10_7959a' }.freeze - if Flipper.enabled?(:champva_file_recreate, @user) - def submit - Datadog::Tracing.trace('Start IVC File Submission') do - form_id = get_form_id - Datadog::Tracing.active_trace&.set_tag('form_id', form_id) - parsed_form_data = JSON.parse(params.to_json) - statuses, error_message = handle_file_uploads(form_id, parsed_form_data) + def submit + Datadog::Tracing.trace('Start IVC File Submission') do + form_id = get_form_id + Datadog::Tracing.active_trace&.set_tag('form_id', form_id) + parsed_form_data = JSON.parse(params.to_json) + statuses, error_message = handle_file_uploads(form_id, parsed_form_data) - response = build_json(Array(statuses), error_message) + response = build_json(Array(statuses), error_message) - if @current_user && response[:status] == 200 - InProgressForm.form_for_user(params[:form_number], @current_user)&.destroy! - end - - render json: response[:json], status: response[:status] - end - rescue => e - Rails.logger.error "Error: #{e.message}" - Rails.logger.error e.backtrace.join("\n") - render json: { error_message: "Error: #{e.message}" }, status: :internal_server_error - end - else - def submit - Datadog::Tracing.trace('Start IVC File Submission') do - form_id = get_form_id - Datadog::Tracing.active_trace&.set_tag('form_id', form_id) - parsed_form_data = JSON.parse(params.to_json) - file_paths, metadata = get_file_paths_and_metadata(parsed_form_data) - statuses, error_message = FileUploader.new(form_id, metadata, file_paths, true).handle_uploads - response = build_json(Array(statuses), error_message) - - if @current_user && response[:status] == 200 - InProgressForm.form_for_user(params[:form_number], - @current_user)&.destroy! - end - - render json: response[:json], status: response[:status] - rescue => e - Rails.logger.error "Error: #{e.message}" - Rails.logger.error e.backtrace.join("\n") - render json: { error_message: "Error: #{e.message}" }, - status: :internal_server_error + if @current_user && response[:status] == 200 + InProgressForm.form_for_user(params[:form_number], @current_user)&.destroy! end + + render json: response[:json], status: response[:status] end + rescue => e + Rails.logger.error "Error: #{e.message}" + Rails.logger.error e.backtrace.join("\n") + render json: { error_message: "Error: #{e.message}" }, status: :internal_server_error end def submit_supporting_documents @@ -74,22 +49,20 @@ def submit_supporting_documents private - if Flipper.enabled?(:champva_file_recreate, @user) - def handle_file_uploads(form_id, parsed_form_data) + def handle_file_uploads(form_id, parsed_form_data) + file_paths, metadata = get_file_paths_and_metadata(parsed_form_data) + statuses, error_message = FileUploader.new(form_id, metadata, file_paths, true).handle_uploads + statuses = Array(statuses) + + # Retry attempt if specific error message is found + if statuses.any? do |status| + status.is_a?(String) && status.include?('No such file or directory @ rb_sysopen') + end file_paths, metadata = get_file_paths_and_metadata(parsed_form_data) statuses, error_message = FileUploader.new(form_id, metadata, file_paths, true).handle_uploads - statuses = Array(statuses) - - # Retry attempt if specific error message is found - if statuses.any? do |status| - status.is_a?(String) && status.include?('No such file or directory @ rb_sysopen') - end - file_paths, metadata = get_file_paths_and_metadata(parsed_form_data) - statuses, error_message = FileUploader.new(form_id, metadata, file_paths, true).handle_uploads - end - - [statuses, error_message] end + + [statuses, error_message] end def get_attachment_ids_and_form(parsed_form_data) @@ -116,8 +89,22 @@ def get_attachment_ids_and_form(parsed_form_data) end def supporting_document_ids(parsed_form_data) - parsed_form_data['supporting_docs']&.pluck('attachment_id')&.compact.presence || - parsed_form_data['supporting_docs']&.pluck('claim_id')&.compact.presence || [] + cached_uploads = [] + parsed_form_data['supporting_docs']&.each do |d| + # Get the database record that corresponds to this file upload: + record = PersistentAttachments::MilitaryRecords.find_by(guid: d['confirmation_code']) + # Push to our array with some extra information so we can sort by date uploaded: + cached_uploads.push({ attachment_id: d['attachment_id'], + created_at: record.created_at, + file_name: record.file.id }) + end + + # Sort by date created so we have the file's upload order and + # reduce down to just the attachment id strings: + attachment_ids = cached_uploads.sort_by { |h| h[:created_at] }.pluck(:attachment_id)&.compact.presence + + # Return either the attachment IDs or `claim_id`s (in the case of form 10-7959a): + attachment_ids || parsed_form_data['supporting_docs']&.pluck('claim_id')&.compact.presence || [] end # rubocop:disable Metrics/MethodLength diff --git a/modules/ivc_champva/spec/requests/ivc_champva/v1/forms/uploads_spec.rb b/modules/ivc_champva/spec/requests/ivc_champva/v1/forms/uploads_spec.rb index 1d738bb868d..5f7b9cd9c76 100644 --- a/modules/ivc_champva/spec/requests/ivc_champva/v1/forms/uploads_spec.rb +++ b/modules/ivc_champva/spec/requests/ivc_champva/v1/forms/uploads_spec.rb @@ -36,6 +36,8 @@ it 'uploads a PDF file to S3' do mock_form = double(first_name: 'Veteran', last_name: 'Surname', form_uuid: 'some_uuid') + allow(PersistentAttachments::MilitaryRecords).to receive(:find_by) + .and_return(double('Record1', created_at: 1.day.ago, id: 'some_uuid', file: double(id: 'file0'))) allow(IvcChampvaForm).to receive(:first).and_return(mock_form) allow_any_instance_of(Aws::S3::Client).to receive(:put_object).and_return(true) @@ -49,6 +51,17 @@ expect(response).to have_http_status(:ok) end + + it 'returns a 500 error when supporting documents are submitted, but are missing from the database' do + allow_any_instance_of(Aws::S3::Client).to receive(:put_object).and_return(true) + + # Actual supporting_docs should exist as records in the DB. This test + # ensures that if they aren't present we won't have a silent failure + data_with_docs = data.merge({ supporting_docs: [{ confirmation_code: 'NOT_IN_DATABASE' }] }) + post '/ivc_champva/v1/forms', params: data_with_docs + + expect(response).to have_http_status(:internal_server_error) + end end end @@ -123,6 +136,53 @@ result = controller.supporting_document_ids expect(result).to eq([1, 2]) end + + it 'orders supporting document ids by date created' do + clamscan = double(safe?: true) + allow(Common::VirusScan).to receive(:scan).and_return(clamscan) + + # Mocking PersistentAttachments::MilitaryRecords to return controlled data + record1 = double('Record1', created_at: 1.day.ago, id: 'doc0', file: double(id: 'file0')) + record2 = double('Record2', created_at: Time.zone.now, id: 'doc1', file: double(id: 'file1')) + + allow(PersistentAttachments::MilitaryRecords).to receive(:find_by).with(guid: 'code1').and_return(record1) + allow(PersistentAttachments::MilitaryRecords).to receive(:find_by).with(guid: 'code2').and_return(record2) + + parsed_form_data = { + 'form_number' => '10-10D', + 'supporting_docs' => [ + { 'attachment_id' => 'doc1', 'confirmation_code' => 'code2' }, + { 'attachment_id' => 'doc0', 'confirmation_code' => 'code1' } + ] + } + + # Create an instance of the controller + controller = IvcChampva::V1::UploadsController.new + + # Call the private method using `send` + attachment_ids = controller.send(:supporting_document_ids, parsed_form_data) + + # Mock metadata generation to align with the sorted order + metadata = { 'metadata' => {}, 'attachment_ids' => attachment_ids } + + expect(metadata).to eq({ + 'metadata' => {}, + 'attachment_ids' => %w[doc0 doc1] # Ensure this matches the sorted order + }) + end + + it 'throws an error when no matching supporting doc is present in the database' do + controller = IvcChampva::V1::UploadsController.new + parsed_form_data = { + 'form_number' => '10-10D', + 'supporting_docs' => [ + { 'attachment_id' => 'doc0', 'confirmation_code' => 'NOT_IN_DATABASE' } + ] + } + expect do + controller.send(:supporting_document_ids, parsed_form_data) + end.to raise_error(NoMethodError) + end end describe '#get_file_paths_and_metadata' do @@ -186,64 +246,62 @@ end end - if Flipper.enabled?(:champva_file_recreate, @user) - describe '#handle_file_uploads' do - let(:controller) { IvcChampva::V1::UploadsController.new } + describe '#handle_file_uploads' do + let(:controller) { IvcChampva::V1::UploadsController.new } - forms.each do |form_file| - form_id = form_file.gsub('vha_', '').gsub('.json', '').upcase - form_numbers_and_classes[form_id] + forms.each do |form_file| + form_id = form_file.gsub('vha_', '').gsub('.json', '').upcase + form_numbers_and_classes[form_id] - context "with form #{form_id}" do - let(:form_id) { form_id } - let(:parsed_form_data) do - JSON.parse(Rails.root.join('modules', 'ivc_champva', 'spec', 'fixtures', 'form_json', form_file).read) - end - let(:file_paths) { ['/path/to/file1.pdf', '/path/to/file2.pdf'] } - let(:metadata) { { 'attachment_ids' => %w[id1 id2] } } - let(:file_uploader) { instance_double(IvcChampva::FileUploader) } + context "with form #{form_id}" do + let(:form_id) { form_id } + let(:parsed_form_data) do + JSON.parse(Rails.root.join('modules', 'ivc_champva', 'spec', 'fixtures', 'form_json', form_file).read) + end + let(:file_paths) { ['/path/to/file1.pdf', '/path/to/file2.pdf'] } + let(:metadata) { { 'attachment_ids' => %w[id1 id2] } } + let(:file_uploader) { instance_double(IvcChampva::FileUploader) } + before do + allow(controller).to receive(:get_file_paths_and_metadata).and_return([file_paths, metadata]) + allow(IvcChampva::FileUploader).to receive(:new).and_return(file_uploader) + end + + context 'when file uploads succeed' do before do - allow(controller).to receive(:get_file_paths_and_metadata).and_return([file_paths, metadata]) - allow(IvcChampva::FileUploader).to receive(:new).and_return(file_uploader) + allow(file_uploader).to receive(:handle_uploads).and_return([[200], nil]) end - context 'when file uploads succeed' do - before do - allow(file_uploader).to receive(:handle_uploads).and_return([[200], nil]) - end + it 'returns success statuses and no error message' do + statuses, error_message = controller.send(:handle_file_uploads, form_id, parsed_form_data) + expect(statuses).to eq([200]) + expect(error_message).to be_nil + end + end - it 'returns success statuses and no error message' do - statuses, error_message = controller.send(:handle_file_uploads, form_id, parsed_form_data) - expect(statuses).to eq([200]) - expect(error_message).to be_nil - end + context 'when file uploads fail with specific error message' do + before do + allow(file_uploader).to receive(:handle_uploads).and_return([['No such file or directory @ rb_sysopen'], + 'File not found']) end - context 'when file uploads fail with specific error message' do - before do - allow(file_uploader).to receive(:handle_uploads).and_return([['No such file or directory @ rb_sysopen'], - 'File not found']) - end - - it 'retries the file uploads and returns the final statuses and error message' do - allow(file_uploader).to receive(:handle_uploads).and_return([[200], nil]) - statuses, error_message = controller.send(:handle_file_uploads, form_id, parsed_form_data) - expect(statuses).to eq([200]) - expect(error_message).to be_nil - end + it 'retries the file uploads and returns the final statuses and error message' do + allow(file_uploader).to receive(:handle_uploads).and_return([[200], nil]) + statuses, error_message = controller.send(:handle_file_uploads, form_id, parsed_form_data) + expect(statuses).to eq([200]) + expect(error_message).to be_nil end + end - context 'when file uploads fail with other errors' do - before do - allow(file_uploader).to receive(:handle_uploads).and_return([[400], 'Upload failed']) - end + context 'when file uploads fail with other errors' do + before do + allow(file_uploader).to receive(:handle_uploads).and_return([[400], 'Upload failed']) + end - it 'returns the error statuses and error message' do - statuses, error_message = controller.send(:handle_file_uploads, form_id, parsed_form_data) - expect(statuses).to eq([400]) - expect(error_message).to eq('Upload failed') - end + it 'returns the error statuses and error message' do + statuses, error_message = controller.send(:handle_file_uploads, form_id, parsed_form_data) + expect(statuses).to eq([400]) + expect(error_message).to eq('Upload failed') end end end diff --git a/modules/my_health/app/controllers/my_health/v1/medical_records/self_entered_controller.rb b/modules/my_health/app/controllers/my_health/v1/medical_records/self_entered_controller.rb new file mode 100644 index 00000000000..82d7594b8bb --- /dev/null +++ b/modules/my_health/app/controllers/my_health/v1/medical_records/self_entered_controller.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module MyHealth + module V1 + module MedicalRecords + class SelfEnteredController < MrController + def vitals + render json: bb_client.get_sei_vital_signs_summary.to_json + end + + def allergies + render json: bb_client.get_sei_allergies.to_json + end + + def family_history + render json: bb_client.get_sei_family_health_history.to_json + end + + def vaccines + render json: bb_client.get_sei_immunizations.to_json + end + + def test_entries + render json: bb_client.get_sei_test_entries.to_json + end + + def medical_events + render json: bb_client.get_sei_medical_events.to_json + end + + def military_history + render json: bb_client.get_sei_military_history.to_json + end + + def providers + render json: bb_client.get_sei_healthcare_providers.to_json + end + + def health_insurance + render json: bb_client.get_sei_health_insurance.to_json + end + + def treatment_facilities + render json: bb_client.get_sei_treatment_facilities.to_json + end + + def food_journal + render json: bb_client.get_sei_food_journal.to_json + end + + def activity_journal + render json: bb_client.get_sei_activity_journal.to_json + end + + def medications + render json: bb_client.get_sei_medications.to_json + end + end + end + end +end diff --git a/modules/my_health/config/routes.rb b/modules/my_health/config/routes.rb index fe2179251e5..c608421b921 100644 --- a/modules/my_health/config/routes.rb +++ b/modules/my_health/config/routes.rb @@ -27,6 +27,21 @@ get :status, on: :collection end resources :military_service, only: %i[index] + resources :self_entered, only: [], defaults: { format: :json } do + get :vitals, on: :collection + get :allergies, on: :collection + get :family_history, on: :collection + get :vaccines, on: :collection + get :test_entries, on: :collection + get :medical_events, on: :collection + get :military_history, on: :collection + get :providers, on: :collection + get :health_insurance, on: :collection + get :treatment_facilities, on: :collection + get :food_journal, on: :collection + get :activity_journal, on: :collection + get :medications, on: :collection + end resources :patient, only: %i[index] do get :demographic, on: :collection end diff --git a/modules/pensions/app/sidekiq/pensions/pension_benefit_intake_job.rb b/modules/pensions/app/sidekiq/pensions/pension_benefit_intake_job.rb index dce2d813f2c..a12ec8b9ef0 100644 --- a/modules/pensions/app/sidekiq/pensions/pension_benefit_intake_job.rb +++ b/modules/pensions/app/sidekiq/pensions/pension_benefit_intake_job.rb @@ -97,6 +97,8 @@ def init(saved_claim_id, user_account_uuid) @claim = Pensions::SavedClaim.find(saved_claim_id) raise PensionBenefitIntakeError, "Unable to find SavedClaim::Pension #{saved_claim_id}" unless @claim + set_signature_date + @intake_service = BenefitsIntake::Service.new end @@ -221,5 +223,19 @@ def cleanup_file_paths rescue => e @pension_monitor.track_file_cleanup_error(@claim, @intake_service, @user_account_uuid, e) end + + ## + # Sets the signature date to the claim.created_at, + # so that retried claims will be considered signed on the date of submission. + # Signature date will be set to current date if not provided. + # + def set_signature_date + form_data = JSON.parse(@claim.form) + form_data['signatureDate'] = @claim.created_at&.strftime('%Y-%m-%d') + @claim.form = form_data.to_json + @claim.save + rescue => e + @pension_monitor.track_claim_signature_error(@claim, @intake_service, @user_account_uuid, e) + end end end diff --git a/modules/pensions/lib/pdf_fill/va21p527ez.rb b/modules/pensions/lib/pdf_fill/va21p527ez.rb index a1ba497f028..50c34aeb5d0 100644 --- a/modules/pensions/lib/pdf_fill/va21p527ez.rb +++ b/modules/pensions/lib/pdf_fill/va21p527ez.rb @@ -1707,8 +1707,9 @@ def expand_direct_deposit_information # SECTION XII: CLAIM CERTIFICATION AND SIGNATURE def expand_claim_certification_and_signature @form_data['noRapidProcessing'] = to_checkbox_on_off(@form_data['noRapidProcessing']) - # form was signed today - @form_data['signatureDate'] = split_date(Time.zone.now.strftime('%Y-%m-%d')) + # signed on provided date (generally SavedClaim.created_at) or default to today + signature_date = @form_data['signatureDate'] || Time.zone.now.strftime('%Y-%m-%d') + @form_data['signatureDate'] = split_date(signature_date) end # Convert a date to a string diff --git a/modules/pensions/lib/pensions/monitor.rb b/modules/pensions/lib/pensions/monitor.rb index ffccee475e3..eb54e56ba52 100644 --- a/modules/pensions/lib/pensions/monitor.rb +++ b/modules/pensions/lib/pensions/monitor.rb @@ -321,5 +321,29 @@ def track_file_cleanup_error(claim, lighthouse_service, user_account_uuid, e) "#{SUBMISSION_STATS_KEY}.cleanup_failed", call_location: caller_locations.first, **additional_context) end + + ## + # log error occurred when setting signature date to claim.created_at + # Error doesn't prevent successful claim submission (defaults to current date) + # @see PensionBenefitIntakeJob + # + # @param claim [Pension::SavedClaim] + # @param lighthouse_service [BenefitsIntake::Service] + # @param user_account_uuid [UUID] + # @param e [Error] + # + def track_claim_signature_error(claim, lighthouse_service, user_account_uuid, e) + additional_context = { + confirmation_number: claim&.confirmation_number, + user_account_uuid:, + claim_id: claim&.id, + benefits_intake_uuid: lighthouse_service&.uuid, + error: e&.message, + tags: + } + track_request('error', 'Lighthouse::PensionBenefitIntakeJob custom date failed', + "#{SUBMISSION_STATS_KEY}.custom_date_failed", + call_location: caller_locations.first, **additional_context) + end end end diff --git a/modules/pensions/spec/lib/pdf_fill/va21p527ez_spec.rb b/modules/pensions/spec/lib/pdf_fill/va21p527ez_spec.rb index 43f77a7ce73..6679abc087b 100644 --- a/modules/pensions/spec/lib/pdf_fill/va21p527ez_spec.rb +++ b/modules/pensions/spec/lib/pdf_fill/va21p527ez_spec.rb @@ -192,6 +192,28 @@ def basic_class end end + describe '#expand_claim_certification_and_signature' do + it 'defaults to today' do + date = Time.new(2024, 11, 25, 2, 2, 2, 'UTC') + zone = double('zone') + allow(zone).to receive(:now).and_return(date) + allow(Time).to receive(:zone).and_return(zone) + form_data = {} + form = described_class.new(form_data) + form.expand_claim_certification_and_signature + expect(form.instance_variable_get('@form_data')['signatureDate']).to eq({ 'month' => '11', 'day' => '25', + 'year' => '2024' }) + end + + it 'applies date if provided' do + form_data = { 'signatureDate' => '2024-10-31' } + form = described_class.new(form_data) + form.expand_claim_certification_and_signature + expect(form.instance_variable_get('@form_data')['signatureDate']).to eq({ 'month' => '10', 'day' => '31', + 'year' => '2024' }) + end + end + describe '#expand_veteran_service_information' do it 'puts overflow on line one' do long_place_of_separation = 'A very long place name that exceeds thirty-six characters' diff --git a/modules/pensions/spec/sidekiq/pensions/pension_benefit_intake_job_spec.rb b/modules/pensions/spec/sidekiq/pensions/pension_benefit_intake_job_spec.rb index da934283484..d6a9f5f0f1d 100644 --- a/modules/pensions/spec/sidekiq/pensions/pension_benefit_intake_job_spec.rb +++ b/modules/pensions/spec/sidekiq/pensions/pension_benefit_intake_job_spec.rb @@ -160,6 +160,25 @@ end end + describe '#set_signature_date' do + before do + job.instance_variable_set(:@pension_monitor, monitor) + allow(monitor).to receive(:track_claim_signature_error) + end + + it 'errors and logs but does not reraise' do + expect(monitor).to receive(:track_claim_signature_error) + job.send(:set_signature_date) + end + + it 'sets the signature date to claim.created_at' do + job.instance_variable_set(:@claim, claim) + job.send(:set_signature_date) + form_data = JSON.parse(claim.form) + expect(form_data['signatureDate']).to eq(claim.created_at.strftime('%Y-%m-%d')) + end + end + describe '#send_confirmation_email' do let(:monitor_error) { create(:monitor_error) } let(:notification) { double('notification') } diff --git a/modules/simple_forms_api/app/controllers/simple_forms_api/v1/uploads_controller.rb b/modules/simple_forms_api/app/controllers/simple_forms_api/v1/uploads_controller.rb index 3f2b1194f31..953021afff3 100644 --- a/modules/simple_forms_api/app/controllers/simple_forms_api/v1/uploads_controller.rb +++ b/modules/simple_forms_api/app/controllers/simple_forms_api/v1/uploads_controller.rb @@ -91,13 +91,13 @@ def handle_210966_authenticated form.track_user_identity(confirmation_number) if confirmation_number && Flipper.enabled?(:simple_forms_email_confirmations) - send_confirmation_email(parsed_form_data, get_form_id, confirmation_number) + send_intent_received_email(parsed_form_data, confirmation_number, expiration_date) end json_for210966(confirmation_number, expiration_date, existing_intents) - rescue Common::Exceptions::UnprocessableEntity, Net::ReadTimeout => e + rescue Common::Exceptions::UnprocessableEntity, Exceptions::BenefitsClaimsApiDownError => e # Common::Exceptions::UnprocessableEntity: There is an authentication issue with the Intent to File API - # Faraday::TimeoutError: The Intent to File API is down or timed out + # Exceptions::BenefitsClaimsApiDownError: The Intent to File API is down or timed out # In either case, we revert to sending a PDF to Central Mail through the Benefits Intake API prepare_params_for_benefits_intake_and_log_error(e) submit_form_to_benefits_intake @@ -292,6 +292,22 @@ def send_confirmation_email(parsed_form_data, form_id, confirmation_number) ) notification_email.send end + + def send_intent_received_email(parsed_form_data, confirmation_number, expiration_date) + config = { + form_data: parsed_form_data, + form_number: 'vba_21_0966_intent_api', + confirmation_number:, + date_submitted: Time.zone.today.strftime('%B %d, %Y'), + expiration_date: + } + notification_email = SimpleFormsApi::NotificationEmail.new( + config, + notification_type: :received, + user: @current_user + ) + notification_email.send + end end end end diff --git a/modules/simple_forms_api/app/services/simple_forms_api/intent_to_file.rb b/modules/simple_forms_api/app/services/simple_forms_api/intent_to_file.rb index 53cceef8dbe..a835f7446b5 100644 --- a/modules/simple_forms_api/app/services/simple_forms_api/intent_to_file.rb +++ b/modules/simple_forms_api/app/services/simple_forms_api/intent_to_file.rb @@ -26,9 +26,7 @@ def submit type = benefit_type.downcase next if existing_intents[type] - response = benefits_claims_lighthouse_service.create_intent_to_file(type, ssn) - confirmation_number = response.dig('data', 'id') - expiration_date = response.dig('data', 'attributes', 'expirationDate') + confirmation_number, expiration_date = create_intent_to_file(type, ssn) end user_account_uuid = user.user_account_uuid @@ -61,6 +59,21 @@ def benefits_claims_lighthouse_service @benefits_claims_lighthouse_service ||= BenefitsClaims::Service.new(icn) end + def create_intent_to_file(type, ssn) + response = benefits_claims_lighthouse_service.create_intent_to_file(type, ssn) + [response.dig('data', 'id'), response.dig('data', 'attributes', 'expirationDate')] + rescue Common::Exceptions::ResourceNotFound => e + Rails.logger.error( + 'Simple forms api - Benefits Claims API, intent to file endpoint is down', + { + intent_type: type, + form_number: params[:form_number], + error: e + } + ) + raise Exceptions::BenefitsClaimsApiDownError + end + def existing_compensation_intent @existing_compensation_intent ||= benefits_claims_lighthouse_service.get_intent_to_file('compensation')&.dig('data', 'attributes') diff --git a/modules/simple_forms_api/app/services/simple_forms_api/notification_email.rb b/modules/simple_forms_api/app/services/simple_forms_api/notification_email.rb index 10b0784eaf4..58c87eeddd5 100644 --- a/modules/simple_forms_api/app/services/simple_forms_api/notification_email.rb +++ b/modules/simple_forms_api/app/services/simple_forms_api/notification_email.rb @@ -2,8 +2,8 @@ module SimpleFormsApi class NotificationEmail - attr_reader :form_number, :confirmation_number, :date_submitted, :lighthouse_updated_at, :notification_type, :user, - :user_account, :form_data + attr_reader :form_number, :confirmation_number, :date_submitted, :expiration_date, :lighthouse_updated_at, + :notification_type, :user, :user_account, :form_data TEMPLATE_IDS = { 'vba_21_0845' => { @@ -19,7 +19,10 @@ class NotificationEmail 'vba_21_0966' => { confirmation: Settings.vanotify.services.va_gov.template_id.form21_0966_confirmation_email, error: Settings.vanotify.services.va_gov.template_id.form21_0966_error_email, - received: nil + received: Settings.vanotify.services.va_gov.template_id.form21_0966_received_email + }, + 'vba_21_0966_intent_api' => { + received: Settings.vanotify.services.va_gov.template_id.form21_0966_itf_api_received_email }, 'vba_21_0972' => { confirmation: Settings.vanotify.services.va_gov.template_id.form21_0972_confirmation_email, @@ -66,6 +69,7 @@ def initialize(config, notification_type: :confirmation, user: nil, user_account @form_number = config[:form_number] @confirmation_number = config[:confirmation_number] @date_submitted = config[:date_submitted] + @expiration_date = config[:expiration_date] @lighthouse_updated_at = config[:lighthouse_updated_at] @notification_type = notification_type @user = user @@ -90,11 +94,16 @@ def send(at: nil) def check_missing_keys(config) missing_keys = %i[form_data form_number confirmation_number date_submitted].select { |key| config[key].nil? } + if config[:form_number] == 'vba_21_0966_intent_api' && config[:expiration_date].nil? + missing_keys << :expiration_date + end raise ArgumentError, "Missing keys: #{missing_keys.join(', ')}" if missing_keys.any? end def flipper? - Flipper.enabled?(:"form#{form_number.gsub('vba_', '')}_confirmation_email") + number = form_number + number = 'vba_21_0966' if form_number.start_with? 'vba_21_0966' + Flipper.enabled?(:"form#{number.gsub('vba_', '')}_confirmation_email") end def enqueue_email(at, template_id) @@ -172,7 +181,7 @@ def get_email_address_from_form_data form21_0845_contact_info[0] when 'vba_21p_0847', 'vba_21_0972' form_data['preparer_email'] - when 'vba_21_0966' + when 'vba_21_0966', 'vba_21_0966_intent_api' form21_0966_email_address when 'vba_21_4142' form_data.dig('veteran', 'email') @@ -196,7 +205,7 @@ def get_first_name_from_form_data form21_0845_contact_info[1] when 'vba_21p_0847' form_data.dig('preparer_name', 'first') - when 'vba_21_0966' + when 'vba_21_0966', 'vba_21_0966_intent_api' form21_0966_first_name when 'vba_21_0972' form_data.dig('preparer_full_name', 'first') @@ -237,7 +246,7 @@ def get_first_name_from_user end def get_personalization(first_name) - if @form_number == 'vba_21_0966' + if @form_number.start_with? 'vba_21_0966' default_personalization(first_name).merge(form21_0966_personalization) else default_personalization(first_name) @@ -348,18 +357,31 @@ def form21_0966_email_address end def form21_0966_personalization + intent_to_file_benefits, intent_to_file_benefits_links = get_intent_to_file_benefits_variables + { + 'intent_to_file_benefits' => intent_to_file_benefits, + 'intent_to_file_benefits_links' => intent_to_file_benefits_links, + 'itf_api_expiration_date' => expiration_date + } + end + + def get_intent_to_file_benefits_variables benefits = @form_data['benefit_selection'] - intent_to_file_benefits = if benefits['compensation'] && benefits['pension'] - 'Disability Compensation (VA Form 21-526EZ) and Pension (VA Form 21P-527EZ)' - elsif benefits['compensation'] - 'Disability Compensation (VA Form 21-526EZ)' - elsif benefits['pension'] - 'Pension (VA Form 21P-527EZ)' - elsif benefits['survivor'] - 'Survivors Pension and/or Dependency and Indemnity Compensation (DIC)' \ - ' (VA Form 21P-534 or VA Form 21P-534EZ)' - end - { 'intent_to_file_benefits' => intent_to_file_benefits } + if benefits['compensation'] && benefits['pension'] + ['disability compensation and Veterans pension benefits', + '[File for disability compensation (VA Form 21-526EZ)]' \ + '(https://www.va.gov/disability/file-disability-claim-form-21-526ez/introduction) and [Apply for Veterans ' \ + 'Pension benefits (VA Form 21P-527EZ)](https://www.va.gov/find-forms/about-form-21p-527ez/)'] + elsif benefits['compensation'] + ['disability compensation', + '[File for disability compensation (VA Form 21-526EZ)](https://www.va.gov/disability/file-disability-claim-form-21-526ez/introduction)'] + elsif benefits['pension'] + ['Veterans pension benefits', + '[Apply for Veterans Pension benefits (VA Form 21P-527EZ)](https://www.va.gov/find-forms/about-form-21p-527ez/)'] + elsif benefits['survivor'] + ['survivors pension benefits', + '[Apply for DIC, Survivors Pension, and/or Accrued Benefits (VA Form 21P-534EZ)](https://www.va.gov/find-forms/about-form-21p-534ez/)'] + end end def form40_10007_first_name diff --git a/modules/simple_forms_api/lib/simple_forms_api.rb b/modules/simple_forms_api/lib/simple_forms_api.rb index 84c928a7f22..18d6fc212e3 100644 --- a/modules/simple_forms_api/lib/simple_forms_api.rb +++ b/modules/simple_forms_api/lib/simple_forms_api.rb @@ -75,5 +75,7 @@ def aggregate_words(parsed_params) words.uniq.sort_by(&:length).reverse end end + + class BenefitsClaimsApiDownError < RuntimeError; end end end diff --git a/modules/simple_forms_api/spec/requests/simple_forms_api/v1/simple_forms_spec.rb b/modules/simple_forms_api/spec/requests/simple_forms_api/v1/simple_forms_spec.rb index e507b06a50d..076bf2e128e 100644 --- a/modules/simple_forms_api/spec/requests/simple_forms_api/v1/simple_forms_spec.rb +++ b/modules/simple_forms_api/spec/requests/simple_forms_api/v1/simple_forms_spec.rb @@ -852,9 +852,11 @@ end context 'veteran preparer' do - it 'successful submission' do + let(:expiration_date) { Time.zone.now } + + it 'sends the received email' do allow_any_instance_of(SimpleFormsApi::IntentToFile) - .to receive(:submit).and_return([confirmation_number, Time.zone.now]) + .to receive(:submit).and_return([confirmation_number, expiration_date]) allow_any_instance_of(SimpleFormsApi::IntentToFile) .to receive(:existing_intents) .and_return({ 'compensation' => 'false', 'pension' => 'false', 'survivor' => 'false' }) @@ -867,14 +869,16 @@ expect(VANotify::EmailJob).to have_received(:perform_async).with( 'abraham.lincoln@vets.gov', - 'form21_0966_confirmation_email_template_id', + 'form21_0966_itf_api_received_email_template_id', { 'first_name' => 'Veteran', 'date_submitted' => Time.zone.today.strftime('%B %d, %Y'), 'confirmation_number' => confirmation_number, 'lighthouse_updated_at' => nil, - 'intent_to_file_benefits' => 'Survivors Pension and/or Dependency and Indemnity Compensation (DIC)' \ - ' (VA Form 21P-534 or VA Form 21P-534EZ)' + 'intent_to_file_benefits' => 'survivors pension benefits', + 'intent_to_file_benefits_links' => '[Apply for DIC, Survivors Pension, and/or Accrued Benefits ' \ + '(VA Form 21P-534EZ)](https://www.va.gov/find-forms/about-form-21p-534ez/)', + 'itf_api_expiration_date' => expiration_date } ) end @@ -897,8 +901,10 @@ 'date_submitted' => Time.zone.today.strftime('%B %d, %Y'), 'confirmation_number' => confirmation_number, 'lighthouse_updated_at' => nil, - 'intent_to_file_benefits' => 'Survivors Pension and/or Dependency and Indemnity Compensation (DIC)' \ - ' (VA Form 21P-534 or VA Form 21P-534EZ)' + 'intent_to_file_benefits' => 'survivors pension benefits', + 'intent_to_file_benefits_links' => '[Apply for DIC, Survivors Pension, and/or Accrued Benefits ' \ + '(VA Form 21P-534EZ)](https://www.va.gov/find-forms/about-form-21p-534ez/)', + 'itf_api_expiration_date' => nil } ) end diff --git a/modules/simple_forms_api/spec/services/intent_to_file_spec.rb b/modules/simple_forms_api/spec/services/intent_to_file_spec.rb index 64a3d36cc34..afe1ab22b8b 100644 --- a/modules/simple_forms_api/spec/services/intent_to_file_spec.rb +++ b/modules/simple_forms_api/spec/services/intent_to_file_spec.rb @@ -4,22 +4,55 @@ require SimpleFormsApi::Engine.root.join('spec', 'spec_helper.rb') describe SimpleFormsApi::IntentToFile do - describe 'an Intent To File has previously been submitted' do - let(:params) do + let(:ssn) { 'fake-ssn' } + let(:icn) { '123498767V234859' } + let(:params) do + { + 'benefit_selection' => { + 'COMPENSATION' => true + }, + 'preparer_identification' => 'VETERAN', + 'veteran_id' => { + 'ssn' => ssn + } + } + end + + describe '#submit' do + let(:expiration_date) { 'fake-expiration-date' } + let(:id) { 'fake-id' } + let(:compensation_intent) do { - 'benefit_selection' => { - 'COMPENSATION' => true - }, - 'preparer_identification' => 'VETERAN', - 'preparer_id' => { - 'ssn' => 'fake-ssn' + 'data' => { + 'id' => id, + 'attributes' => { + 'expirationDate' => expiration_date + } } } end + context 'lighthouse service is down' do + it 'raises Exceptions::BenefitsClaimsApiDownError' do + intent_to_file_service = SimpleFormsApi::IntentToFile.new(build(:user), params) + allow_any_instance_of(BenefitsClaims::Service).to receive(:get_intent_to_file).with('compensation') + .and_return(nil) + allow_any_instance_of(BenefitsClaims::Service).to receive(:get_intent_to_file).with('pension').and_return(nil) + allow_any_instance_of(BenefitsClaims::Service).to receive(:get_intent_to_file).with('survivor').and_return(nil) + allow_any_instance_of(BenefitsClaims::Service).to receive(:create_intent_to_file).with( + 'compensation', + ssn + ).and_raise(Common::Exceptions::ResourceNotFound) + + expect { intent_to_file_service.submit }.to raise_error(SimpleFormsApi::Exceptions::BenefitsClaimsApiDownError) + end + end + end + + describe 'an Intent To File has previously been submitted' do it 'returns no confirmation number and no expiration date if no new ITF is filed' do user = build(:user) - allow(user).to receive_messages(icn: '123498767V234859', participant_id: 'fake-participant-id') + allow(user).to receive_messages(icn:, participant_id: 'fake-participant-id') intent_to_file_service = SimpleFormsApi::IntentToFile.new(user, params) expiration_date = 'fake-expiration-date' compensation_intent = { @@ -41,22 +74,8 @@ end describe 'no Intent to File has previously been submitted' do - let(:ssn) { 'fake-ssn' } - let(:params) do - { - 'benefit_selection' => { - 'COMPENSATION' => true - }, - 'preparer_identification' => 'VETERAN', - 'veteran_id' => { - 'ssn' => ssn - } - } - end - it 'return the expiration date of a newly-created Intent To File' do - user = build(:user) - intent_to_file_service = SimpleFormsApi::IntentToFile.new(user, params) + intent_to_file_service = SimpleFormsApi::IntentToFile.new(build(:user), params) expiration_date = 'fake-expiration-date' id = 'fake-id' compensation_intent = { diff --git a/modules/simple_forms_api/spec/services/notification_email_spec.rb b/modules/simple_forms_api/spec/services/notification_email_spec.rb index 4c804366f1f..f8aae6aeb10 100644 --- a/modules/simple_forms_api/spec/services/notification_email_spec.rb +++ b/modules/simple_forms_api/spec/services/notification_email_spec.rb @@ -730,7 +730,35 @@ end let(:user) { create(:user, :loa3) } - context 'template_id is provided', unless: notification_type == :received do + it 'sends the email' do + allow(VANotify::EmailJob).to receive(:perform_async) + + subject = described_class.new(config, notification_type:, user:) + + subject.send + + expect(VANotify::EmailJob).to have_received(:perform_async).with( + user.va_profile_email, + "form21_0966_#{notification_type}_email_template_id", + { + 'first_name' => 'Veteran', + 'date_submitted' => date_submitted, + 'confirmation_number' => 'confirmation_number', + 'lighthouse_updated_at' => nil, + 'intent_to_file_benefits' => 'survivors pension benefits', + 'intent_to_file_benefits_links' => '[Apply for DIC, Survivors Pension, and/or Accrued Benefits ' \ + '(VA Form 21P-534EZ)](https://www.va.gov/find-forms/about-form-21p-534ez/)', + 'itf_api_expiration_date' => nil + } + ) + end + + context 'preparer is surviving dependent' do + before do + data['preparer_identification'] = 'SURVIVING_DEPENDENT' + config[:form_data] = data + end + it 'sends the email' do allow(VANotify::EmailJob).to receive(:perform_async) @@ -739,23 +767,39 @@ subject.send expect(VANotify::EmailJob).to have_received(:perform_async).with( - user.va_profile_email, + 'survivor@dependent.com', "form21_0966_#{notification_type}_email_template_id", { - 'first_name' => 'Veteran', + 'first_name' => 'I', 'date_submitted' => date_submitted, 'confirmation_number' => 'confirmation_number', 'lighthouse_updated_at' => nil, - 'intent_to_file_benefits' => 'Survivors Pension and/or Dependency and Indemnity Compensation (DIC)' \ - ' (VA Form 21P-534 or VA Form 21P-534EZ)' + 'intent_to_file_benefits' => 'survivors pension benefits', + 'intent_to_file_benefits_links' => '[Apply for DIC, Survivors Pension, and/or Accrued Benefits ' \ + '(VA Form 21P-534EZ)](https://www.va.gov/find-forms/about-form-21p-534ez/)', + 'itf_api_expiration_date' => nil } ) end + end + end + + describe '21_0966 through Intent to File API', if: notification_type == :received do + let(:date_submitted) { Time.zone.today.strftime('%B %d, %Y') } + let(:expiration_date) { 1.year.from_now.strftime('%B %d, %Y') } + let(:data) do + fixture_path = Rails.root.join( + 'modules', 'simple_forms_api', 'spec', 'fixtures', 'form_json', 'vba_21_0966.json' + ) + JSON.parse(fixture_path.read) + end + let(:user) { create(:user, :loa3) } - context 'preparer is surviving dependent' do - before do - data['preparer_identification'] = 'SURVIVING_DEPENDENT' - config[:form_data] = data + context 'template_id is provided' do + context 'expiration_date is provided' do + let(:config) do + { form_data: data, form_number: 'vba_21_0966_intent_api', + confirmation_number: 'confirmation_number', date_submitted:, expiration_date: } end it 'sends the email' do @@ -766,22 +810,70 @@ subject.send expect(VANotify::EmailJob).to have_received(:perform_async).with( - 'survivor@dependent.com', - "form21_0966_#{notification_type}_email_template_id", + user.va_profile_email, + 'form21_0966_itf_api_received_email_template_id', { - 'first_name' => 'I', + 'first_name' => 'Veteran', 'date_submitted' => date_submitted, 'confirmation_number' => 'confirmation_number', 'lighthouse_updated_at' => nil, - 'intent_to_file_benefits' => 'Survivors Pension and/or Dependency and Indemnity Compensation (DIC)' \ - ' (VA Form 21P-534 or VA Form 21P-534EZ)' + 'intent_to_file_benefits' => 'survivors pension benefits', + 'intent_to_file_benefits_links' => '[Apply for DIC, Survivors Pension, and/or Accrued Benefits ' \ + '(VA Form 21P-534EZ)](https://www.va.gov/find-forms/about-form-21p-534ez/)', + 'itf_api_expiration_date' => expiration_date } ) end + + context 'preparer is surviving dependent' do + before do + data['preparer_identification'] = 'SURVIVING_DEPENDENT' + config[:form_data] = data + end + + it 'sends the email' do + allow(VANotify::EmailJob).to receive(:perform_async) + + subject = described_class.new(config, notification_type:, user:) + + subject.send + + expect(VANotify::EmailJob).to have_received(:perform_async).with( + 'survivor@dependent.com', + 'form21_0966_itf_api_received_email_template_id', + { + 'first_name' => 'I', + 'date_submitted' => date_submitted, + 'confirmation_number' => 'confirmation_number', + 'lighthouse_updated_at' => nil, + 'intent_to_file_benefits' => 'survivors pension benefits', + 'intent_to_file_benefits_links' => '[Apply for DIC, Survivors Pension, and/or Accrued Benefits ' \ + '(VA Form 21P-534EZ)](https://www.va.gov/find-forms/about-form-21p-534ez/)', + 'itf_api_expiration_date' => expiration_date + } + ) + end + end + end + + context 'expiration_date is missing' do + let(:config) do + { form_data: data, form_number: 'vba_21_0966_intent_api', + confirmation_number: 'confirmation_number', date_submitted: } + end + + it 'raises ArgumentError' do + expect { described_class.new(config, notification_type:, user:) }.to raise_error(ArgumentError) + end end end - context 'template_id is missing', if: notification_type == :received do + context 'template_id is missing', unless: notification_type == :received do + let(:config) do + { form_data: data, form_number: 'vba_21_0966_intent_api', + confirmation_number: 'confirmation_number', date_submitted:, expiration_date: } + end + let(:data) do fixture_path = Rails.root.join( 'modules', 'simple_forms_api', 'spec', 'fixtures', 'form_json', 'vba_21_0966.json' diff --git a/modules/vaos/app/controllers/vaos/v2/clinics_controller.rb b/modules/vaos/app/controllers/vaos/v2/clinics_controller.rb index dab8bf1d0ed..b7ffdf0fcb8 100644 --- a/modules/vaos/app/controllers/vaos/v2/clinics_controller.rb +++ b/modules/vaos/app/controllers/vaos/v2/clinics_controller.rb @@ -57,12 +57,14 @@ def recent_clinics # get the clinic details using the station id and clinic id location_id = appt.location_id clinic_ids = appt.clinic - clinic = systems_service.get_facility_clinics(location_id:, clinic_ids:)&.first + clinic = mobile_facility_service.get_clinic_with_cache(station_id: location_id, clinic_id: clinic_ids) # if clinic details are not returned, log 'not found' message clinic.nil? ? log_no_clinic_details_found(location_id, clinic_ids) : sorted_clinics.push(clinic) end end + # remove duplicate clinics + sorted_clinics = sorted_clinics.uniq render json: VAOS::V2::ClinicsSerializer.new(sorted_clinics) end diff --git a/modules/vaos/app/docs/vaos/v2/vaos_v2.yaml b/modules/vaos/app/docs/vaos/v2/vaos_v2.yaml index 0049aa3c27c..f13df6b9b70 100644 --- a/modules/vaos/app/docs/vaos/v2/vaos_v2.yaml +++ b/modules/vaos/app/docs/vaos/v2/vaos_v2.yaml @@ -437,6 +437,42 @@ paths: $ref: "#/components/responses/ServiceUnavailable" "504": $ref: "#/components/responses/GatewayTimeout" + "/v2/locations/recent_clinics": + get: + tags: + - facilities + description: Returns the most recent clinics visited + responses: + "200": + description: Returns the most recent clinics visited + content: + application/json: + schema: + required: + - data + properties: + data: + $ref: "#/components/schemas/Clinic" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "403": + $ref: "#/components/responses/Forbidden" + "404": + $ref: "#/components/responses/NotFound" + "422": + $ref: "#/components/responses/Unprocessable" + "500": + $ref: "#/components/responses/InternalServerError" + "501": + $ref: "#/components/responses/NotImplemented" + "502": + $ref: "#/components/responses/BadGateway" + "503": + $ref: "#/components/responses/ServiceUnavailable" + "504": + $ref: "#/components/responses/GatewayTimeout" "/locations/{location_id}/clinics": get: tags: diff --git a/modules/vaos/app/services/eps/appointment_service.rb b/modules/vaos/app/services/eps/appointment_service.rb new file mode 100644 index 00000000000..542724d98a9 --- /dev/null +++ b/modules/vaos/app/services/eps/appointment_service.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Eps + class AppointmentService < BaseService + ## + # Get appointments data from EPS + # + # @return OpenStruct response from EPS appointments endpoint + # + def get_appointments(patient_id:) + response = perform(:get, "/#{config.base_path}/appointments?patientId=#{patient_id}", + {}, headers) + OpenStruct.new(response.body) + end + end +end diff --git a/modules/vaos/app/services/eps/configuration.rb b/modules/vaos/app/services/eps/configuration.rb index 2a1f4f7d7c9..c5cf16b2574 100644 --- a/modules/vaos/app/services/eps/configuration.rb +++ b/modules/vaos/app/services/eps/configuration.rb @@ -2,7 +2,7 @@ module Eps class Configuration < Common::Client::Configuration::REST - delegate :access_token_url, :api_url, :grant_type, :scopes, :client_assertion_type, to: :settings + delegate :access_token_url, :api_url, :base_path, :grant_type, :scopes, :client_assertion_type, to: :settings def settings Settings.vaos.eps diff --git a/modules/vaos/spec/requests/vaos/v2/locations/clinics_spec.rb b/modules/vaos/spec/requests/vaos/v2/locations/clinics_spec.rb index 30539ad3f88..7c1017d8871 100644 --- a/modules/vaos/spec/requests/vaos/v2/locations/clinics_spec.rb +++ b/modules/vaos/spec/requests/vaos/v2/locations/clinics_spec.rb @@ -234,6 +234,7 @@ context 'using VAOS' do before do + # VPG routes do not exist for the MFS calls made for this scenario Flipper.disable(:va_online_scheduling_use_vpg) end @@ -264,7 +265,7 @@ context 'on unsuccessful query for clinic information' do it 'does not populate the sorted clinics list' do - allow_any_instance_of(VAOS::V2::SystemsService).to receive(:get_facility_clinics).and_return(nil) + allow_any_instance_of(VAOS::V2::MobileFacilityService).to receive(:get_clinic_with_cache).and_return(nil) VCR.use_cassette('vaos/v2/systems/get_recent_clinics_200', match_requests_on: %i[method path query]) do Timecop.travel(Time.zone.local(2023, 8, 31, 13, 0, 0)) do @@ -275,52 +276,6 @@ end end end - - context 'using VPG' do - let(:user) { build(:user, :mhv) } - - before do - Flipper.enable(:va_online_scheduling_use_vpg) - end - - context 'on successful query for recent sorted clinics' do - it 'returns the recent sorted clinics' do - VCR.use_cassette('vaos/v2/systems/get_recent_clinics_vpg_200', - match_requests_on: %i[method path query], allow_playback_repeats: true) do - Timecop.travel(Time.zone.local(2023, 8, 31, 13, 0, 0)) do - get '/vaos/v2/locations/recent_clinics', headers: inflection_header - expect(response).to have_http_status(:ok) - clinic_info = JSON.parse(response.body)['data'] - expect(clinic_info[0]['attributes']['stationId']).to eq('983') - expect(clinic_info[0]['attributes']['id']).to eq('1038') - end - end - end - end - - context 'on unsuccessful query for appointment within look back limit' do - it 'returns a 404 http status' do - expect_any_instance_of(VAOS::V2::AppointmentsService) - .to receive(:get_recent_sorted_clinic_appointments) - .and_return(nil) - get '/vaos/v2/locations/recent_clinics', headers: inflection_header - expect(response).to have_http_status(:not_found) - end - end - - context 'on unsuccessful query for clinic information' do - it 'does not populate the sorted clinics list' do - allow_any_instance_of(VAOS::V2::SystemsService).to receive(:get_facility_clinics).and_return(nil) - VCR.use_cassette('vaos/v2/systems/get_recent_clinics_vpg_200', - match_requests_on: %i[method path query]) do - Timecop.travel(Time.zone.local(2023, 8, 31, 13, 0, 0)) do - get '/vaos/v2/locations/recent_clinics', headers: inflection_header - expect(JSON.parse(response.body)['data']).to eq([]) - end - end - end - end - end end end end diff --git a/modules/vaos/spec/services/eps/appointment_service_spec.rb b/modules/vaos/spec/services/eps/appointment_service_spec.rb new file mode 100644 index 00000000000..dff38d609b8 --- /dev/null +++ b/modules/vaos/spec/services/eps/appointment_service_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Eps::AppointmentService do + subject(:service) { described_class.new(user) } + + let(:user) { double('User', account_uuid: '1234') } + let(:successful_appt_response) do + double('Response', status: 200, body: { 'count' => 1, + 'appointments' => [ + { + 'id' => 'test-id', + 'state' => 'booked', + 'patientId' => patient_id + } + ] }) + end + let(:patient_id) { 'test-patient-id' } + let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) } + + describe 'get_appointments' do + before do + allow(Rails.cache).to receive(:fetch).and_return(memory_store) + Rails.cache.clear + end + + context 'when requesting appointments for a given patient_id' do + before do + allow_any_instance_of(VAOS::SessionService).to receive(:perform).and_return(successful_appt_response) + end + + it 'returns the appointments scheduled' do + exp_response = OpenStruct.new(successful_appt_response.body) + + expect(service.get_appointments(patient_id:)).to eq(exp_response) + end + end + + context 'when the endpoint fails to return appointments' do + let(:failed_appt_response) do + double('Response', status: 500, body: 'Unknown service exception') + end + let(:exception) do + Common::Exceptions::BackendServiceException.new(nil, {}, failed_appt_response.status, + failed_appt_response.body) + end + + before do + allow_any_instance_of(VAOS::SessionService).to receive(:perform).and_raise(exception) + end + + it 'throws exception' do + expect { service.get_appointments(patient_id:) }.to raise_error(Common::Exceptions::BackendServiceException, + /VA900/) + end + end + end +end diff --git a/spec/lib/medical_records/bb_internal/client_spec.rb b/spec/lib/medical_records/bb_internal/client_spec.rb index b9b80dbc8e1..d1f0101238b 100644 --- a/spec/lib/medical_records/bb_internal/client_spec.rb +++ b/spec/lib/medical_records/bb_internal/client_spec.rb @@ -198,6 +198,163 @@ expect(error.errors.first[:detail]).to eq('Patient not found') end end + + describe '#get_sei_vital_signs_summary' do + it 'retrieves the SEI vital signs' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_vital_signs_summary' do + response = client.get_sei_vital_signs_summary + + expect(response).to be_a(Hash) + expect(response).to have_key('bloodPreassureReadings') + expect(response).to have_key('bloodSugarReadings') + expect(response).to have_key('bodyTemperatureReadings') + expect(response).to have_key('bodyWeightReadings') + expect(response).to have_key('cholesterolReadings') + expect(response).to have_key('heartRateReadings') + expect(response).to have_key('inrReadings') + expect(response).to have_key('lipidReadings') + expect(response).to have_key('painReadings') + expect(response).to have_key('pulseOximetryReadings') + end + end + end + + describe '#get_sei_allergies' do + it 'retrieves the SEI allergies' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_allergies' do + response = client.get_sei_allergies + + expect(response).to be_a(Hash) + expect(response).to have_key('pojoObject') + expect(response['pojoObject'][0]).to have_key('allergiesId') + end + end + end + + describe '#get_sei_family_health_history' do + it 'retrieves the SEI family health history' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_family_health_history' do + response = client.get_sei_family_health_history + + expect(response).to be_a(Hash) + expect(response).to have_key('pojoObject') + expect(response['pojoObject'][0]).to have_key('relationship') + end + end + end + + describe '#get_sei_immunizations' do + it 'retrieves the SEI immunizations' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_immunizations' do + response = client.get_sei_immunizations + + expect(response).to be_a(Hash) + expect(response).to have_key('pojoObject') + expect(response['pojoObject'][0]).to have_key('immunizationId') + end + end + end + + describe '#get_sei_test_entries' do + it 'retrieves the SEI test entries' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_test_entries' do + response = client.get_sei_test_entries + + expect(response).to be_a(Hash) + expect(response).to have_key('pojoObject') + end + end + end + + describe '#get_sei_medical_events' do + it 'retrieves the SEI medical events' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_medical_events' do + response = client.get_sei_medical_events + + expect(response).to be_a(Hash) + expect(response).to have_key('pojoObject') + expect(response['pojoObject'][0]).to have_key('medicalEventId') + end + end + end + + describe '#get_sei_military_history' do + it 'retrieves the SEI miltary history' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_military_history' do + response = client.get_sei_military_history + + expect(response).to be_a(Hash) + expect(response).to have_key('pojoObject') + expect(response['pojoObject'][0]).to have_key('serviceBranch') + end + end + end + + describe '#get_sei_healthcare_providers' do + it 'retrieves the SEI healthcare providers' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_healthcare_providers' do + response = client.get_sei_healthcare_providers + + expect(response).to be_an(Array) + expect(response[0]).to have_key('healthCareProviderId') + end + end + end + + describe '#get_sei_health_insurance' do + it 'retrieves the SEI health insurance' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_health_insurance' do + response = client.get_sei_health_insurance + + expect(response).to be_an(Array) + expect(response[0]).to have_key('healthInsuranceId') + end + end + end + + describe '#get_sei_treatment_facilities' do + it 'retrieves the SEI treatment facilities' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_treatment_facilities' do + response = client.get_sei_treatment_facilities + + expect(response).to be_an(Array) + expect(response[0]).to have_key('treatmentFacilityId') + end + end + end + + describe '#get_sei_food_journal' do + it 'retrieves the SEI food journal' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_food_journal' do + response = client.get_sei_food_journal + + expect(response).to be_an(Array) + expect(response[0]).to have_key('foodJournalId') + end + end + end + + describe '#get_sei_activity_journal' do + it 'retrieves the SEI activity journal' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_activity_journal' do + response = client.get_sei_activity_journal + + expect(response).to be_an(Array) + expect(response[0]).to have_key('activityJournalId') + end + end + end + + describe '#get_sei_medications' do + it 'retrieves the SEI activity journal' do + VCR.use_cassette 'mr_client/bb_internal/get_sei_medications' do + response = client.get_sei_medications + + expect(response).to be_an(Array) + expect(response[0]).to have_key('medicationId') + end + end + end end describe '#get_demographic_info' do diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_activity_journal.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_activity_journal.yml new file mode 100644 index 00000000000..268935e4070 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_activity_journal.yml @@ -0,0 +1,56 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/journal/activityjournals/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:31:48 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '[{"activityJournalId":14867873,"oplock":null,"createdDate":null,"comments":"test","journalDate":1518152400000,"modifiedDate":null,"activityDetails":[{"activityDetailId":14867874,"repCount":0,"description":"bench + press","timeOfDay":null,"activityType":"W","measure":"P","distanceDuration":0,"setCount":0,"intensity":null,"activityJournalId":14867873,"activityJournal":null,"dispIntensity":null,"dispMeasure":"pound(s)","dispTimeOfDay":null,"dispDescription":"bench + press","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"02/09/2018","dayNoOfWeek":6,"summary":"Weights, + Comments","abbrWeekDay":"Fri","weekDay":"Friday","activityTypeCount":"1 + Activity","aerobicCardioStr":[],"weightsStr":["null bench press "],"otherStr":[],"aerobicCardiaoType":[],"weightsType":[{"activityDetailId":14867874,"repCount":0,"description":"bench + press","timeOfDay":null,"activityType":"W","measure":"P","distanceDuration":0,"setCount":0,"intensity":null,"activityJournalId":14867873,"activityJournal":null,"dispIntensity":null,"dispMeasure":"pound(s)","dispTimeOfDay":null,"dispDescription":"bench + press","editMode":null}],"otherType":[],"activityDetailId":null,"activityType":null,"distDuration":null,"measure":null,"intensity":null,"timeOfDay":null,"noOfSets":null,"noOfReps":null,"activityDesc":null},{"activityJournalId":14867876,"oplock":null,"createdDate":null,"comments":null,"journalDate":1517806800000,"modifiedDate":null,"activityDetails":[{"activityDetailId":14867877,"repCount":0,"description":"Zumba","timeOfDay":"M","activityType":"A","measure":null,"distanceDuration":0,"setCount":0,"intensity":"M","activityJournalId":14867876,"activityJournal":null,"dispIntensity":"Moderate + impact","dispMeasure":null,"dispTimeOfDay":"Morning","dispDescription":"Zumba","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"02/05/2018","dayNoOfWeek":2,"summary":"Aerobic/Cardio","abbrWeekDay":"Mon","weekDay":"Monday","activityTypeCount":"1 + Activity","aerobicCardioStr":["Zumba "],"weightsStr":[],"otherStr":[],"aerobicCardiaoType":[{"activityDetailId":14867877,"repCount":0,"description":"Zumba","timeOfDay":"M","activityType":"A","measure":null,"distanceDuration":0,"setCount":0,"intensity":"M","activityJournalId":14867876,"activityJournal":null,"dispIntensity":"Moderate + impact","dispMeasure":null,"dispTimeOfDay":"Morning","dispDescription":"Zumba","editMode":null}],"weightsType":[],"otherType":[],"activityDetailId":null,"activityType":null,"distDuration":null,"measure":null,"intensity":null,"timeOfDay":null,"noOfSets":null,"noOfReps":null,"activityDesc":null},{"activityJournalId":14867871,"oplock":null,"createdDate":null,"comments":"test","journalDate":1505880000000,"modifiedDate":null,"activityDetails":[{"activityDetailId":14867872,"repCount":0,"description":"Running","timeOfDay":null,"activityType":"A","measure":"ML","distanceDuration":2,"setCount":0,"intensity":null,"activityJournalId":14867871,"activityJournal":null,"dispIntensity":null,"dispMeasure":"mile(s)","dispTimeOfDay":null,"dispDescription":"Running","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"09/20/2017","dayNoOfWeek":4,"summary":"Aerobic/Cardio, + Comments","abbrWeekDay":"Wed","weekDay":"Wednesday","activityTypeCount":"1 + Activity","aerobicCardioStr":["null Running "],"weightsStr":[],"otherStr":[],"aerobicCardiaoType":[{"activityDetailId":14867872,"repCount":0,"description":"Running","timeOfDay":null,"activityType":"A","measure":"ML","distanceDuration":2,"setCount":0,"intensity":null,"activityJournalId":14867871,"activityJournal":null,"dispIntensity":null,"dispMeasure":"mile(s)","dispTimeOfDay":null,"dispDescription":"Running","editMode":null}],"weightsType":[],"otherType":[],"activityDetailId":null,"activityType":null,"distDuration":null,"measure":null,"intensity":null,"timeOfDay":null,"noOfSets":null,"noOfReps":null,"activityDesc":null},{"activityJournalId":14160042,"oplock":null,"createdDate":null,"comments":"Like + %%%","journalDate":1491192000000,"modifiedDate":null,"activityDetails":[{"activityDetailId":14160043,"repCount":456,"description":"Test + @%&#*","timeOfDay":"M","activityType":"W","measure":"HR","distanceDuration":5,"setCount":45,"intensity":"M","activityJournalId":14160042,"activityJournal":null,"dispIntensity":"Moderate + impact","dispMeasure":"hr(s)","dispTimeOfDay":"Morning","dispDescription":"5 + hr(s); 45 set(s) of 456 reps of Test @%&#*","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"04/03/2017","dayNoOfWeek":2,"summary":"Weights, + Comments","abbrWeekDay":"Mon","weekDay":"Monday","activityTypeCount":"1 + Activity","aerobicCardioStr":[],"weightsStr":["null 45 456 Test @%&#* "],"otherStr":[],"aerobicCardiaoType":[],"weightsType":[{"activityDetailId":14160043,"repCount":456,"description":"Test + @%&#*","timeOfDay":"M","activityType":"W","measure":"HR","distanceDuration":5,"setCount":45,"intensity":"M","activityJournalId":14160042,"activityJournal":null,"dispIntensity":"Moderate + impact","dispMeasure":"hr(s)","dispTimeOfDay":"Morning","dispDescription":"5 + hr(s); 45 set(s) of 456 reps of Test @%&#*","editMode":null}],"otherType":[],"activityDetailId":null,"activityType":null,"distDuration":null,"measure":null,"intensity":null,"timeOfDay":null,"noOfSets":null,"noOfReps":null,"activityDesc":null}]' + recorded_at: Thu, 21 Nov 2024 00:31:48 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_allergies.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_allergies.yml new file mode 100644 index 00000000000..59dbdb5e427 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_allergies.yml @@ -0,0 +1,40 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/healthhistory/allergy/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:08:13 GMT + Content-Type: + - application/json + Content-Length: + - '717' + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '{"success":true,"failure":false,"failureMessage":null,"pojoObject":[{"allergiesId":16660767,"comments":null,"allergy":"assure + VA Regression Test","eventDate":"2020-01-26","reaction":"automation assure + reaction","diagnosed":"Y","severity":"M","userprofileId":11375034,"source":"Self"},{"allergiesId":16660768,"comments":null,"allergy":"assure + VA Regression Test","eventDate":"2020-01-26","reaction":"automation assure + reaction","diagnosed":"Y","severity":"M","userprofileId":11375034,"source":"Self"},{"allergiesId":14142745,"comments":null,"allergy":"hay","eventDate":"2017-03-28","reaction":"Test","diagnosed":"Y","severity":"M","userprofileId":11375034,"source":"Self"}],"validationErrors":null,"infoMessages":null}' + recorded_at: Thu, 21 Nov 2024 00:08:13 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_family_health_history.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_family_health_history.yml new file mode 100644 index 00000000000..24f8b228eb0 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_family_health_history.yml @@ -0,0 +1,36 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/healthhistory/healthHistory/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:14:58 GMT + Content-Type: + - application/json + Content-Length: + - '4955' + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '{"success":true,"failure":false,"pojoObject":[{"id":14168647,"relationship":"UMS","firstName":"lucy","living":true,"comments":"","awAsthma":false,"awBronchitis":false,"awCOPD":false,"awEmphysema":false,"awPneumonia":false,"awSoB":false,"awTuberculosis":false,"awOther":false,"alAllergies":true,"alLupus":false,"alOther":false,"alcSocial":false,"alcOneDrink":false,"alcSixDrinks":false,"alcTwoShots":false,"blAnemia":false,"blBruising":false,"blClotting":false,"blLeukemia":false,"blSickleCell":false,"blOther":false,"baArthritis":false,"baFibromyalgia":false,"baJointPain":false,"baLymeDisease":false,"baOther":true,"caBreast":false,"caBowel":false,"caColon":false,"caLung":false,"caOvarian":false,"caSkin":false,"caStomach":false,"caProstate":false,"caOther":false,"chChickenPox":false,"chDiphtheria":false,"chMeasles":false,"chMumps":false,"chWhoopingCough":false,"chOther":false,"dbType1":false,"dbType2":false,"dbType3":false,"gbDisease":true,"gbStones":false,"gbOther":false,"hntCataracts":false,"hntDizziness":false,"hntDyslexia":false,"hntGlaucoma":false,"hntHearingLoss":false,"hntMigraineHeadaches":false,"hntRetinitisPigmentosa":false,"hntOther":false,"heAngina":false,"heCongestiveFailure":false,"heAttack":false,"heMurmur":false,"heHighCholesterol":false,"heHighPressure":false,"heMitralValveProlapse":false,"heRhythmAbnormality":false,"heStroke":false,"heOther":false,"kiInfections":false,"kiStones":false,"kiRenalFailure":false,"kiOther":false,"liHepatitisA":false,"liHepatitisB":false,"liHepatitisC":false,"liCirrhosis":false,"liOther":false,"mdAnxiety":false,"mdBipolar":false,"mdDepression":true,"mdParanoia":false,"mdPTSD":false,"mdSchizophrenia":false,"mdOther":false,"nvEpilepsy":false,"nvMultipleSclerosis":false,"nvNumbness":false,"nvParalysis":false,"nvSeizures":false,"nvOther":false,"nbOnePerMonth":false,"nbOnePerWeek":false,"nbOnePerDay":false,"pnBack":false,"pnJoint":false,"pnMuscle":false,"pnLeg":false,"pnOther":false,"skEczema":false,"skPsoriasis":true,"skOther":false,"slInsomnia":false,"slApnea":false,"slOther":false,"smCurrent":false,"smOnePackPerDay":false,"smTenYears":false,"smTwentyYears":false,"stdChlamydia":false,"stdGonorrhea":false,"stdHerpes":false,"stdSyphilis":false,"stdOther":false,"stmIBS":false,"stmNausea":false,"stmPain":false,"stmSevereIndigestion":false,"stmUlcers":false,"stmOther":false,"thGoiter":false,"thTumor":false,"thOther":false,"wtOverweight":false,"wtUnderweight":false,"oplock":0,"userprofileId":11375034,"otherHealthIssues":[]},{"id":15125365,"relationship":"BRTH","firstName":"Johnny","living":true,"comments":"","awAsthma":true,"awBronchitis":false,"awCOPD":false,"awEmphysema":false,"awPneumonia":false,"awSoB":false,"awTuberculosis":false,"awOther":false,"alAllergies":true,"alLupus":false,"alOther":false,"alcSocial":false,"alcOneDrink":false,"alcSixDrinks":false,"alcTwoShots":false,"blAnemia":false,"blBruising":false,"blClotting":false,"blLeukemia":false,"blSickleCell":false,"blOther":false,"baArthritis":false,"baFibromyalgia":false,"baJointPain":false,"baLymeDisease":false,"baOther":false,"caBreast":false,"caBowel":false,"caColon":false,"caLung":false,"caOvarian":false,"caSkin":false,"caStomach":false,"caProstate":false,"caOther":false,"chChickenPox":false,"chDiphtheria":false,"chMeasles":false,"chMumps":false,"chWhoopingCough":false,"chOther":false,"dbType1":false,"dbType2":false,"dbType3":false,"gbDisease":false,"gbStones":false,"gbOther":false,"hntCataracts":false,"hntDizziness":false,"hntDyslexia":false,"hntGlaucoma":false,"hntHearingLoss":false,"hntMigraineHeadaches":false,"hntRetinitisPigmentosa":false,"hntOther":false,"heAngina":false,"heCongestiveFailure":false,"heAttack":false,"heMurmur":false,"heHighCholesterol":false,"heHighPressure":false,"heMitralValveProlapse":false,"heRhythmAbnormality":false,"heStroke":false,"heOther":false,"kiInfections":false,"kiStones":false,"kiRenalFailure":false,"kiOther":false,"liHepatitisA":false,"liHepatitisB":false,"liHepatitisC":false,"liCirrhosis":false,"liOther":false,"mdAnxiety":false,"mdBipolar":false,"mdDepression":false,"mdParanoia":false,"mdPTSD":false,"mdSchizophrenia":false,"mdOther":false,"nvEpilepsy":false,"nvMultipleSclerosis":false,"nvNumbness":false,"nvParalysis":false,"nvSeizures":false,"nvOther":false,"nbOnePerMonth":false,"nbOnePerWeek":false,"nbOnePerDay":false,"pnBack":false,"pnJoint":false,"pnMuscle":false,"pnLeg":false,"pnOther":false,"skEczema":false,"skPsoriasis":false,"skOther":false,"slInsomnia":false,"slApnea":false,"slOther":false,"smCurrent":false,"smOnePackPerDay":false,"smTenYears":false,"smTwentyYears":false,"stdChlamydia":false,"stdGonorrhea":false,"stdHerpes":false,"stdSyphilis":false,"stdOther":false,"stmIBS":false,"stmNausea":false,"stmPain":false,"stmSevereIndigestion":false,"stmUlcers":false,"stmOther":false,"thGoiter":false,"thTumor":false,"thOther":false,"wtOverweight":false,"wtUnderweight":false,"oplock":0,"userprofileId":11375034,"otherHealthIssues":[]}]}' + recorded_at: Thu, 21 Nov 2024 00:14:58 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_food_journal.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_food_journal.yml new file mode 100644 index 00000000000..5b559f8f3c7 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_food_journal.yml @@ -0,0 +1,86 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/journal/journals/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:25:44 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '[{"foodJournalId":14944772,"oplock":null,"glassesOfWater":10,"createdDate":1523021422000,"comments":null,"journalDate":1522987200000,"modifiedDate":null,"mealItems":[{"mealItemId":14944773,"createdDate":1523021488000,"item":"oj","modifiedDate":null,"mealType":"D","servingSize":"8","quantity":0,"prepMethod":"Frozen","foodJournalId":14944772,"foodJournal":null,"dispDesc":"8 + oz oj ","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"04/06/2018","summary":"Dinner, + Water","dayNoOfWeek":6,"abbrWeekDay":"Fri","weekDay":"Friday","mealItemCount":"1 + Meal Item","breakFastItems":[],"lunchItems":[],"dinnerItems":["8 oz oj (Frozen)"],"snackItems":[],"breakFastMealItems":[],"lunchMealItems":[],"dinnerMealItems":[{"mealItemId":14944773,"createdDate":1523021488000,"item":"oj","modifiedDate":null,"mealType":"D","servingSize":"8","quantity":0,"prepMethod":"Frozen","foodJournalId":14944772,"foodJournal":null,"dispDesc":"8 + oz oj ","editMode":null}],"snackMealItems":[],"mealItemId":null,"mealType":null,"servingSize":null,"quantity":null,"prepMethod":null,"item":null},{"foodJournalId":14867847,"oplock":null,"glassesOfWater":2,"createdDate":1518188373000,"comments":"Test","journalDate":1518152400000,"modifiedDate":null,"mealItems":[{"mealItemId":14867850,"createdDate":1518188462000,"item":"Salad","modifiedDate":null,"mealType":"L","servingSize":"8","quantity":1,"prepMethod":null,"foodJournalId":14867847,"foodJournal":null,"dispDesc":"1:8 + oz Salad ","editMode":null},{"mealItemId":14867848,"createdDate":1518188412000,"item":"Bagel","modifiedDate":null,"mealType":"B","servingSize":null,"quantity":1,"prepMethod":"Toasted","foodJournalId":14867847,"foodJournal":null,"dispDesc":"1:Bagel + ","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"02/09/2018","summary":"Breakfast, + Lunch, Comments, Water","dayNoOfWeek":6,"abbrWeekDay":"Fri","weekDay":"Friday","mealItemCount":"2 + Meal Items","breakFastItems":["1:Bagel (Toasted)"],"lunchItems":["1:8 oz Salad + "],"dinnerItems":[],"snackItems":[],"breakFastMealItems":[{"mealItemId":14867848,"createdDate":1518188412000,"item":"Bagel","modifiedDate":null,"mealType":"B","servingSize":null,"quantity":1,"prepMethod":"Toasted","foodJournalId":14867847,"foodJournal":null,"dispDesc":"1:Bagel + ","editMode":null}],"lunchMealItems":[{"mealItemId":14867850,"createdDate":1518188462000,"item":"Salad","modifiedDate":null,"mealType":"L","servingSize":"8","quantity":1,"prepMethod":null,"foodJournalId":14867847,"foodJournal":null,"dispDesc":"1:8 + oz Salad ","editMode":null}],"dinnerMealItems":[],"snackMealItems":[],"mealItemId":null,"mealType":null,"servingSize":null,"quantity":null,"prepMethod":null,"item":null},{"foodJournalId":14159999,"oplock":null,"glassesOfWater":5,"createdDate":1491397919000,"comments":null,"journalDate":1491192000000,"modifiedDate":null,"mealItems":[{"mealItemId":14160001,"createdDate":1491397962000,"item":"turkey","modifiedDate":null,"mealType":"L","servingSize":"4","quantity":8,"prepMethod":null,"foodJournalId":14159999,"foodJournal":null,"dispDesc":"8:4 + oz turkey ","editMode":null},{"mealItemId":14160000,"createdDate":1491397946000,"item":"eggs","modifiedDate":null,"mealType":"B","servingSize":"6","quantity":1,"prepMethod":"Fried","foodJournalId":14159999,"foodJournal":null,"dispDesc":"1:6 + oz eggs ","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"04/03/2017","summary":"Breakfast, + Lunch, Water","dayNoOfWeek":2,"abbrWeekDay":"Mon","weekDay":"Monday","mealItemCount":"2 + Meal Items","breakFastItems":["1:6 oz eggs (Fried)"],"lunchItems":["8:4 oz + turkey "],"dinnerItems":[],"snackItems":[],"breakFastMealItems":[{"mealItemId":14160000,"createdDate":1491397946000,"item":"eggs","modifiedDate":null,"mealType":"B","servingSize":"6","quantity":1,"prepMethod":"Fried","foodJournalId":14159999,"foodJournal":null,"dispDesc":"1:6 + oz eggs ","editMode":null}],"lunchMealItems":[{"mealItemId":14160001,"createdDate":1491397962000,"item":"turkey","modifiedDate":null,"mealType":"L","servingSize":"4","quantity":8,"prepMethod":null,"foodJournalId":14159999,"foodJournal":null,"dispDesc":"8:4 + oz turkey ","editMode":null}],"dinnerMealItems":[],"snackMealItems":[],"mealItemId":null,"mealType":null,"servingSize":null,"quantity":null,"prepMethod":null,"item":null},{"foodJournalId":14159994,"oplock":null,"glassesOfWater":5,"createdDate":1491397824000,"comments":null,"journalDate":1491105600000,"modifiedDate":null,"mealItems":[{"mealItemId":14159998,"createdDate":1491397906000,"item":"Chips + and salsa","modifiedDate":null,"mealType":"S","servingSize":"2","quantity":11,"prepMethod":"Boiled","foodJournalId":14159994,"foodJournal":null,"dispDesc":"11:2 + oz Chips and salsa ","editMode":null},{"mealItemId":14159996,"createdDate":1491397885000,"item":"cinnamon + rolls","modifiedDate":null,"mealType":"B","servingSize":"3","quantity":3,"prepMethod":"Baked","foodJournalId":14159994,"foodJournal":null,"dispDesc":"3:3 + oz cinnamon rolls ","editMode":null},{"mealItemId":14159995,"createdDate":1491397863000,"item":"Llalsagna","modifiedDate":null,"mealType":"D","servingSize":"8","quantity":1,"prepMethod":"Baked","foodJournalId":14159994,"foodJournal":null,"dispDesc":"1:8 + oz Llalsagna ","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"04/02/2017","summary":"Breakfast, + Dinner, Snack(s), Water","dayNoOfWeek":1,"abbrWeekDay":"Sun","weekDay":"Sunday","mealItemCount":"3 + Meal Items","breakFastItems":["3:3 oz cinnamon rolls (Baked)"],"lunchItems":[],"dinnerItems":["1:8 + oz Llalsagna (Baked)"],"snackItems":["11:2 oz Chips and salsa (Boiled)"],"breakFastMealItems":[{"mealItemId":14159996,"createdDate":1491397885000,"item":"cinnamon + rolls","modifiedDate":null,"mealType":"B","servingSize":"3","quantity":3,"prepMethod":"Baked","foodJournalId":14159994,"foodJournal":null,"dispDesc":"3:3 + oz cinnamon rolls ","editMode":null}],"lunchMealItems":[],"dinnerMealItems":[{"mealItemId":14159995,"createdDate":1491397863000,"item":"Llalsagna","modifiedDate":null,"mealType":"D","servingSize":"8","quantity":1,"prepMethod":"Baked","foodJournalId":14159994,"foodJournal":null,"dispDesc":"1:8 + oz Llalsagna ","editMode":null}],"snackMealItems":[{"mealItemId":14159998,"createdDate":1491397906000,"item":"Chips + and salsa","modifiedDate":null,"mealType":"S","servingSize":"2","quantity":11,"prepMethod":"Boiled","foodJournalId":14159994,"foodJournal":null,"dispDesc":"11:2 + oz Chips and salsa ","editMode":null}],"mealItemId":null,"mealType":null,"servingSize":null,"quantity":null,"prepMethod":null,"item":null},{"foodJournalId":14160007,"oplock":null,"glassesOfWater":6,"createdDate":1491398078000,"comments":null,"journalDate":1491019200000,"modifiedDate":null,"mealItems":[{"mealItemId":14867841,"createdDate":1518188329000,"item":"Tuna + sandwich","modifiedDate":null,"mealType":"L","servingSize":null,"quantity":0,"prepMethod":"Toasted","foodJournalId":14160007,"foodJournal":null,"dispDesc":"Tuna + sandwich ","editMode":null},{"mealItemId":14160008,"createdDate":1491398105000,"item":"donuts","modifiedDate":null,"mealType":"B","servingSize":"2","quantity":10,"prepMethod":"Fried","foodJournalId":14160007,"foodJournal":null,"dispDesc":"10:2 + oz donuts ","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"04/01/2017","summary":"Breakfast, + Lunch, Water","dayNoOfWeek":7,"abbrWeekDay":"Sat","weekDay":"Saturday","mealItemCount":"2 + Meal Items","breakFastItems":["10:2 oz donuts (Fried)"],"lunchItems":["Tuna + sandwich (Toasted)"],"dinnerItems":[],"snackItems":[],"breakFastMealItems":[{"mealItemId":14160008,"createdDate":1491398105000,"item":"donuts","modifiedDate":null,"mealType":"B","servingSize":"2","quantity":10,"prepMethod":"Fried","foodJournalId":14160007,"foodJournal":null,"dispDesc":"10:2 + oz donuts ","editMode":null}],"lunchMealItems":[{"mealItemId":14867841,"createdDate":1518188329000,"item":"Tuna + sandwich","modifiedDate":null,"mealType":"L","servingSize":null,"quantity":0,"prepMethod":"Toasted","foodJournalId":14160007,"foodJournal":null,"dispDesc":"Tuna + sandwich ","editMode":null}],"dinnerMealItems":[],"snackMealItems":[],"mealItemId":null,"mealType":null,"servingSize":null,"quantity":null,"prepMethod":null,"item":null},{"foodJournalId":14160009,"oplock":null,"glassesOfWater":5,"createdDate":1491398122000,"comments":null,"journalDate":1490932800000,"modifiedDate":null,"mealItems":[{"mealItemId":14160010,"createdDate":1491398146000,"item":"cake","modifiedDate":null,"mealType":"B","servingSize":"2","quantity":10,"prepMethod":"Boiled","foodJournalId":14160009,"foodJournal":null,"dispDesc":"10:2 + oz cake ","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"03/31/2017","summary":"Breakfast, + Water","dayNoOfWeek":6,"abbrWeekDay":"Fri","weekDay":"Friday","mealItemCount":"1 + Meal Item","breakFastItems":["10:2 oz cake (Boiled)"],"lunchItems":[],"dinnerItems":[],"snackItems":[],"breakFastMealItems":[{"mealItemId":14160010,"createdDate":1491398146000,"item":"cake","modifiedDate":null,"mealType":"B","servingSize":"2","quantity":10,"prepMethod":"Boiled","foodJournalId":14160009,"foodJournal":null,"dispDesc":"10:2 + oz cake ","editMode":null}],"lunchMealItems":[],"dinnerMealItems":[],"snackMealItems":[],"mealItemId":null,"mealType":null,"servingSize":null,"quantity":null,"prepMethod":null,"item":null},{"foodJournalId":14160015,"oplock":null,"glassesOfWater":6,"createdDate":1491398462000,"comments":null,"journalDate":1490673600000,"modifiedDate":null,"mealItems":[{"mealItemId":14160016,"createdDate":1491398492000,"item":"garden + salad","modifiedDate":null,"mealType":"L","servingSize":"4","quantity":4,"prepMethod":"Fresh","foodJournalId":14160015,"foodJournal":null,"dispDesc":"4:4 + oz garden salad ","editMode":null}],"userId":11375034,"userProfile":null,"dispJournalDate":"03/28/2017","summary":"Lunch, + Water","dayNoOfWeek":3,"abbrWeekDay":"Tue","weekDay":"Tuesday","mealItemCount":"1 + Meal Item","breakFastItems":[],"lunchItems":["4:4 oz garden salad (Fresh)"],"dinnerItems":[],"snackItems":[],"breakFastMealItems":[],"lunchMealItems":[{"mealItemId":14160016,"createdDate":1491398492000,"item":"garden + salad","modifiedDate":null,"mealType":"L","servingSize":"4","quantity":4,"prepMethod":"Fresh","foodJournalId":14160015,"foodJournal":null,"dispDesc":"4:4 + oz garden salad ","editMode":null}],"dinnerMealItems":[],"snackMealItems":[],"mealItemId":null,"mealType":null,"servingSize":null,"quantity":null,"prepMethod":null,"item":null}]' + recorded_at: Thu, 21 Nov 2024 00:25:44 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_health_insurance.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_health_insurance.yml new file mode 100644 index 00000000000..f0052ed605c --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_health_insurance.yml @@ -0,0 +1,36 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/getcare/healthInsurance/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:23:33 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '[{"healthInsuranceId":14944762,"comments":null,"companyName":"CeraVe","companyPhone":null,"firstNameOfInsured":"Sara","groupNumber":null,"insuranceIdNumber":"987654","lastNameOfInsured":"Chamg","preApprovalPhone":null,"primaryInd":false,"startDate":1522987200000,"stopDate":null,"userProfileId":11375034},{"healthInsuranceId":14073489,"comments":null,"companyName":"Holiday","companyPhone":null,"firstNameOfInsured":"Fred","groupNumber":null,"insuranceIdNumber":"987456","lastNameOfInsured":"Flintstone","preApprovalPhone":null,"primaryInd":false,"startDate":1489122000000,"stopDate":null,"userProfileId":11375034},{"healthInsuranceId":13984545,"comments":null,"companyName":"IHC","companyPhone":null,"firstNameOfInsured":"Brown","groupNumber":null,"insuranceIdNumber":"89457","lastNameOfInsured":"Brown","preApprovalPhone":null,"primaryInd":false,"startDate":1486702800000,"stopDate":null,"userProfileId":11375034}]' + recorded_at: Thu, 21 Nov 2024 00:23:33 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_healthcare_providers.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_healthcare_providers.yml new file mode 100644 index 00000000000..7ed31a8f274 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_healthcare_providers.yml @@ -0,0 +1,36 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/getcare/healthCareProvider/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:21:44 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '[{"healthCareProviderId":14944763,"firstName":"Manni","lastName":"Fanni","providerType":"D","otherClinician":null,"workPhone":"801-456-4130","workPhoneExt":null,"emailAddress":null,"comments":null,"userProfileId":11375034},{"healthCareProviderId":15214404,"firstName":"Kin","lastName":"Patel","providerType":"P","otherClinician":null,"workPhone":"4102202049","workPhoneExt":null,"emailAddress":null,"comments":null,"userProfileId":11375034},{"healthCareProviderId":13984530,"firstName":"Keri","lastName":"HOLYOAK","providerType":"S","otherClinician":null,"workPhone":"801-999-9999","workPhoneExt":"123","emailAddress":"KERI@MSN.COM","comments":"ALJDFL","userProfileId":11375034}]' + recorded_at: Thu, 21 Nov 2024 00:21:44 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_immunizations.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_immunizations.yml new file mode 100644 index 00000000000..52b2e0d8199 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_immunizations.yml @@ -0,0 +1,36 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/healthhistory/immunization/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:15:58 GMT + Content-Type: + - application/json + Content-Length: + - '414' + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '{"success":true,"failure":false,"pojoObject":[{"immunizationId":14168645,"dateReceived":"2017-04-13","vaccinationTypeCode":"MNNGC","userprofileId":11375034,"reactions":[{"immunizationReactionId":14168646,"reactionTypeCode":"NSAVMT"}],"nausea":true},{"immunizationId":15125361,"dateReceived":"2000-08-21","comments":"test","vaccinationMethod":"J","vaccinationTypeCode":"S","userprofileId":11375034,"reactions":[]}]}' + recorded_at: Thu, 21 Nov 2024 00:15:58 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_medical_events.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_medical_events.yml new file mode 100644 index 00000000000..2aaae16b4e1 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_medical_events.yml @@ -0,0 +1,36 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/healthhistory/medicalEvent/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:19:19 GMT + Content-Type: + - application/json + Content-Length: + - '195' + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '{"success":true,"failure":false,"pojoObject":[{"medicalEventId":14142751,"comments":"test","startDate":"2017-03-02T23:59:00","medicalEvent":"Surgery","response":"Test","userprofileId":11375034}]}' + recorded_at: Thu, 21 Nov 2024 00:19:19 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_medications.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_medications.yml new file mode 100644 index 00000000000..1a665203f2a --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_medications.yml @@ -0,0 +1,36 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/pharmacy/medications/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:33:28 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '[{"medicationId":14221543,"comments":null,"reason":"stomach pain","startDate":1494302400000,"strength":null,"pharmacyPhone":null,"dosage":"1","frequency":null,"category":"OTC","prescriptionNumber":null,"endDate":null,"medicationName":"TUMS","pharmacyName":null,"userId":11375034,"userProfile":null,"dispStartDate":"05/09/2017","dispEndDate":"","dispCategory":"Over-the-Counter"}]' + recorded_at: Thu, 21 Nov 2024 00:33:28 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_military_history.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_military_history.yml new file mode 100644 index 00000000000..9fdf6f256b5 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_military_history.yml @@ -0,0 +1,37 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/healthhistory/militaryHistory/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:20:12 GMT + Content-Type: + - application/json + Content-Length: + - '379' + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '{"success":true,"failure":false,"pojoObject":[{"id":15125372,"eventTitle":"Test1","eventDate":"2018-08-21","serviceBranch":"N","serviceLocation":"O","exposures":"test","experience":"tedstastgaya + yady ","oplock":1,"userprofileId":11375034},{"id":14168648,"eventTitle":"lkjlkjh","eventDate":"2017-04-13","exposures":"hklj","experience":"navy","oplock":1,"userprofileId":11375034}]}' + recorded_at: Thu, 21 Nov 2024 00:20:12 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_test_entries.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_test_entries.yml new file mode 100644 index 00000000000..db7b05c47d4 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_test_entries.yml @@ -0,0 +1,42 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/healthhistory/testEntry/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Fri, 22 Nov 2024 21:57:16 GMT + Content-Type: + - application/json + Content-Length: + - '984' + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '{"success":true,"failure":false,"pojoObject":[{"testEntryId":18725331,"comments":"Release + 20.1.9.0","eventDate":"2020-11-16T23:59:00","results":"Pass","testName":"Reg + test","userprofileId":11375034},{"testEntryId":13984648,"eventDate":"2017-02-10T23:59:00","testName":"lamp","userprofileId":11375034},{"testEntryId":13984652,"eventDate":"2017-02-10T23:59:00","testName":"ice + cream","userprofileId":11375034},{"testEntryId":13984631,"eventDate":"2017-02-10T23:59:00","testName":"Urine","userprofileId":11375034},{"testEntryId":13984635,"eventDate":"2017-02-10T23:59:00","testName":"Mug","userprofileId":11375034},{"testEntryId":13984565,"eventDate":"2017-02-10T23:59:00","testName":"Blood + Pressure2","userprofileId":11375034},{"testEntryId":13984630,"provider":"Holyoak","eventDate":"2017-02-10T23:59:00","testName":"Blood + test","userprofileId":11375034},{"testEntryId":13984629,"provider":"Holyoak","eventDate":"2017-02-10T23:59:00","testName":"Blood + test","userprofileId":11375034}]}' + recorded_at: Fri, 22 Nov 2024 21:57:16 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_treatment_facilities.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_treatment_facilities.yml new file mode 100644 index 00000000000..9ac035148a7 --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_treatment_facilities.yml @@ -0,0 +1,40 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/getcare/treatmentFacility/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:24:36 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '[{"userProfileId":11375034,"treatmentFacilityId":14551460,"addressCity":null,"addressCountry":null,"addressPostalCode":null,"addressProvince":null,"addressState":null,"addressStreet1":null,"addressStreet2":null,"comments":null,"contactInfoFax":null,"contactInfoWorkPhone":null,"contactInfoWorkPhoneExt":null,"facilityName":"Aveeno + Medical","facilityType":"V","homeFacility":true},{"userProfileId":11375034,"treatmentFacilityId":14551462,"addressCity":null,"addressCountry":null,"addressPostalCode":null,"addressProvince":null,"addressState":null,"addressStreet1":null,"addressStreet2":null,"comments":null,"contactInfoFax":null,"contactInfoWorkPhone":null,"contactInfoWorkPhoneExt":null,"facilityName":"lilfetime + ","facilityType":"V","homeFacility":false},{"userProfileId":11375034,"treatmentFacilityId":14168615,"addressCity":null,"addressCountry":null,"addressPostalCode":null,"addressProvince":null,"addressState":null,"addressStreet1":null,"addressStreet2":null,"comments":null,"contactInfoFax":null,"contactInfoWorkPhone":"801-956-6523","contactInfoWorkPhoneExt":null,"facilityName":"Lone + Peak Hospital","facilityType":"V","homeFacility":false},{"userProfileId":11375034,"treatmentFacilityId":14221544,"addressCity":null,"addressCountry":null,"addressPostalCode":null,"addressProvince":null,"addressState":null,"addressStreet1":null,"addressStreet2":null,"comments":null,"contactInfoFax":null,"contactInfoWorkPhone":"801-231-4561","contactInfoWorkPhoneExt":null,"facilityName":"New + Haven","facilityType":"V","homeFacility":false}]' + recorded_at: Thu, 21 Nov 2024 00:24:36 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_vital_signs_summary.yml b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_vital_signs_summary.yml new file mode 100644 index 00000000000..d60471d040e --- /dev/null +++ b/spec/support/vcr_cassettes/mr_client/bb_internal/get_sei_vital_signs_summary.yml @@ -0,0 +1,50 @@ +--- +http_interactions: +- request: + method: get + uri: "/mhvapi/v1/vitals/summary/11375034" + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - Vets.gov Agent + Token: "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Date: + - Thu, 21 Nov 2024 00:05:07 GMT + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Strict-Transport-Security: + - max-age=16000000; includeSubDomains; preload; + body: + encoding: UTF-8 + string: '{"userProfileId":11375034,"bloodPreassureReadings":[],"bloodSugarReadings":[{"dateEntered":"05/09/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1494388740000,"dashboardDate":"Tue + 05/09/2017","bloodSugarId":14221549,"comments":null,"testingMethod":"CLT","bloodSugarCount":180,"userprofileId":11375034},{"dateEntered":"04/13/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1492142340000,"dashboardDate":"Thu + 04/13/2017","bloodSugarId":14168638,"comments":null,"testingMethod":"I","bloodSugarCount":12,"userprofileId":11375034},{"dateEntered":"02/10/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1486789140000,"dashboardDate":"Fri + 02/10/2017","bloodSugarId":13984647,"comments":"this is a comment\r\n","testingMethod":"SL","bloodSugarCount":646,"userprofileId":11375034}],"bodyTemperatureReadings":[{"dateEntered":"09/06/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1504756740000,"dashboardDate":"Wed + 09/06/2017","bodyTemperatureId":14569457,"comments":null,"bodyTemperature":120,"userprofileId":11375034,"measure":"C","bodyTemperatureMethod":"M"},{"dateEntered":"04/13/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1492142340000,"dashboardDate":"Thu + 04/13/2017","bodyTemperatureId":14168636,"comments":"test","bodyTemperature":98,"userprofileId":11375034,"measure":"F","bodyTemperatureMethod":"M"}],"bodyWeightReadings":[{"dateEntered":"04/13/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1492142340000,"dashboardDate":"Thu + 04/13/2017","bodyweightID":14168635,"bodyweight":123,"comments":null,"userprofileId":11375034,"bodyweightMeasure":"P"}],"cholesterolReadings":null,"heartRateReadings":[{"dateEntered":"04/06/2018","timeEntered":"23:59","hour":null,"minute":null,"reading":1523073540000,"dashboardDate":"Fri + 04/06/2018","heartRateId":14944770,"comments":null,"heartRate":123,"userprofileId":11375034},{"dateEntered":"04/13/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1492142340000,"dashboardDate":"Thu + 04/13/2017","heartRateId":14168634,"comments":null,"heartRate":123,"userprofileId":11375034}],"inrReadings":[{"dateEntered":"04/13/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1492142340000,"dashboardDate":"Thu + 04/13/2017","inrId":14168642,"inr":0.2,"lowendTargetRange":"NONE","highendTragetRange":"NONE","location":null,"provider":null,"comments":null,"userprofileId":11375034}],"lipidReadings":[{"dateEntered":"04/13/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1492142340000,"dashboardDate":"Thu + 04/13/2017","lipidsId":14168639,"fast":"N","total":655,"hdl":345,"ldl":null,"triglycerides":null,"location":"test","provider":null,"comments":"trest","userprofileId":null}],"painReadings":[{"dateEntered":"11/27/2018","timeEntered":"09:00","hour":null,"minute":null,"reading":1543327200000,"dashboardDate":"Tue + 11/27/2018","painId":15282976,"comments":" Test comment% , test comment^&*()+#!\r\n + Test comment% , test ^&*()+#!()@~[]{ brace}","painLevel":3,"userprofileId":11375034},{"dateEntered":"04/13/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1492142340000,"dashboardDate":"Thu + 04/13/2017","painId":14168637,"comments":"edgdff","painLevel":3,"userprofileId":11375034}],"pulseOximetryReadings":[{"dateEntered":"04/13/2017","timeEntered":"23:59","hour":null,"minute":null,"reading":1492142340000,"dashboardDate":"Thu + 04/13/2017","pulseOximetryId":14168641,"comments":"test","suppOxygenDevice":"FM","oxygenSetting":3,"respiratoryRate":67,"oximeterReading":65,"otherSymptoms":null,"symptoms":"D","userprofileId":11375034}]}' + recorded_at: Thu, 21 Nov 2024 00:05:07 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/support/vcr_cassettes/vaos/v2/systems/get_recent_clinics_200.yml b/spec/support/vcr_cassettes/vaos/v2/systems/get_recent_clinics_200.yml index 7c99246001c..6d45081695a 100644 --- a/spec/support/vcr_cassettes/vaos/v2/systems/get_recent_clinics_200.yml +++ b/spec/support/vcr_cassettes/vaos/v2/systems/get_recent_clinics_200.yml @@ -385,7 +385,7 @@ http_interactions: recorded_at: Thu, 31 Aug 2023 22:51:37 GMT - request: method: get - uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=1038&pageSize=0 + uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=1038 body: encoding: US-ASCII string: '' @@ -438,7 +438,7 @@ http_interactions: recorded_at: Thu, 31 Aug 2023 22:51:37 GMT - request: method: get - uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=1081&pageSize=0 + uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=1081 body: encoding: US-ASCII string: '' @@ -491,7 +491,7 @@ http_interactions: recorded_at: Thu, 31 Aug 2023 22:51:37 GMT - request: method: get - uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=1049&pageSize=0 + uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=1049 body: encoding: US-ASCII string: '' @@ -544,7 +544,7 @@ http_interactions: recorded_at: Thu, 31 Aug 2023 22:51:37 GMT - request: method: get - uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=1020&pageSize=0 + uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=1020 body: encoding: US-ASCII string: '' @@ -597,7 +597,7 @@ http_interactions: recorded_at: Thu, 31 Aug 2023 22:51:37 GMT - request: method: get - uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=4275&pageSize=0 + uri: https://veteran.apps.va.gov/vaos/v1/locations/983/clinics?clinicIds=4275 body: encoding: US-ASCII string: '' @@ -650,7 +650,7 @@ http_interactions: recorded_at: Thu, 31 Aug 2023 22:51:37 GMT - request: method: get - uri: https://veteran.apps.va.gov/vaos/v1/locations/983GC/clinics?clinicIds=1081&pageSize=0 + uri: https://veteran.apps.va.gov/vaos/v1/locations/983GC/clinics?clinicIds=1081 body: encoding: US-ASCII string: '' @@ -703,7 +703,7 @@ http_interactions: recorded_at: Thu, 31 Aug 2023 22:51:37 GMT - request: method: get - uri: https://veteran.apps.va.gov/vaos/v1/locations/984/clinics?clinicIds=4275&pageSize=0 + uri: https://veteran.apps.va.gov/vaos/v1/locations/984/clinics?clinicIds=4275 body: encoding: US-ASCII string: '' @@ -756,7 +756,7 @@ http_interactions: recorded_at: Thu, 31 Aug 2023 22:51:37 GMT - request: method: get - uri: https://veteran.apps.va.gov/vaos/v1/locations/984GA/clinics?clinicIds=4275&pageSize=0 + uri: https://veteran.apps.va.gov/vaos/v1/locations/984GA/clinics?clinicIds=4275 body: encoding: US-ASCII string: ''