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 fbc5a31a77f..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 @@ -89,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 c8db6b456e4..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