Skip to content

Commit

Permalink
add submission remediation data (#18769)
Browse files Browse the repository at this point in the history
  • Loading branch information
pennja authored Oct 8, 2024
1 parent 89b3cfb commit 21f7b56
Show file tree
Hide file tree
Showing 2 changed files with 257 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# frozen_string_literal: true

require 'simple_forms_api/form_remediation/configuration/base'

module SimpleFormsApi
module FormRemediation
class SubmissionRemediationData
attr_reader :file_path, :submission, :attachments, :metadata

def initialize(id:, config: Configuration::Base.new)
@config = config

validate_input(id)
fetch_submission(id)

@attachments = []
@metadata = {}
rescue => e
config.handle_error("#{self.class.name} initialization failed", e)
end

def hydrate!
form_number = fetch_submission_form_number
form = build_form(form_number)
filler = PdfFiller.new(form_number:, form:)

handle_submission_data(filler, form, form_number)
self
rescue => e
config.handle_error('Error hydrating submission', e)
end

private

attr_reader :config

def validate_input(id)
raise ArgumentError, "No #{config.id_type} was provided" unless id
end

def fetch_submission(id)
@submission = config.submission_type.find_by(config.id_type => id)
validate_submission
end

def validate_submission
raise 'Submission was not found or invalid' unless submission&.send(config.id_type)
raise "#{self.class} cannot be built: Only VFF forms are supported" unless vff_form?
end

def fetch_submission_form_number
vff_forms_map.fetch(submission.form_type)
end

def build_form(form_number)
form_class_name = "SimpleFormsApi::#{form_number.titleize.delete(' ')}"
form_class = form_class_name.constantize
form_class.new(form_data_hash)
rescue NameError => e
config.handle_error("Form class not found for #{form_class_name}", e)
end

def handle_submission_data(filler, form, form_number)
@file_path = generate_pdf_file(filler)
@metadata = validate_metadata(form)
@attachments = process_attachments(form, form_number)
end

def generate_pdf_file(filler)
filler.generate(timestamp: submission.created_at)
rescue => e
config.handle_error('Error generating filled submission PDF', e)
end

def validate_metadata(form)
SimpleFormsApiSubmission::MetadataValidator.validate(
form.metadata,
zip_code_is_us_based: form.zip_code_is_us_based
)
rescue => e
config.handle_error('Metadata validation failed', e)
end

def process_attachments(form, form_number)
case form_number
when 'vba_40_0247', 'vba_40_10007'
form.handle_attachments(file_path)
[]
when 'vba_20_10207'
form.get_attachments
else
[]
end
rescue => e
config.handle_error("Attachment handling failed for #{form_number}", e)
end

def form_data_hash
@form_data_hash ||= JSON.parse(submission.form_data)
rescue JSON::ParserError => e
config.handle_error('Error parsing form data', e)
end

def vff_forms_map
SimpleFormsApi::V1::UploadsController::FORM_NUMBER_MAP
end

def vff_form?
vff_forms_map.key?(submission.form_type)
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# frozen_string_literal: true

require 'rails_helper'
require SimpleFormsApi::Engine.root.join('spec', 'spec_helper.rb')

RSpec.describe SimpleFormsApi::FormRemediation::SubmissionRemediationData do
let(:form_type) { '20-10207' }
let(:fixtures_path) { 'modules/simple_forms_api/spec/fixtures' }
let(:form_data) { Rails.root.join(fixtures_path, 'form_json', 'vba_20_10207_with_supporting_documents.json').read }
let(:file_path) { Rails.root.join(fixtures_path, 'pdfs', 'vba_20_10207-completed.pdf').to_s }
let(:submission) { create(:form_submission, :pending, form_type:, form_data:) }
let(:benefits_intake_uuid) { submission.benefits_intake_uuid }
let(:submission_instance) { described_class.new(id: benefits_intake_uuid) }
let(:filler) { instance_double(SimpleFormsApi::PdfFiller) }
let(:attachments) { Array.new(5) { fixture_file_upload('doctors-note.pdf', 'application/pdf').path } }
let(:metadata) do
{
'veteranFirstName' => 'John',
'veteranLastName' => 'Veteran',
'fileNumber' => '321540987',
'zipCode' => '12345',
'source' => 'VA Platform Digital Forms',
'docType' => '20-10207',
'businessLine' => 'CMP'
}
end
let(:vba_20_10207_instance) { instance_double(SimpleFormsApi::VBA2010207, metadata:) }

before do
allow(FormSubmission).to receive(:find_by).with(benefits_intake_uuid:).and_return(submission)
allow(SecureRandom).to receive(:hex).and_return('random-letters-n-numbers')
allow(SimpleFormsApi::PdfFiller).to receive(:new).and_return(filler)
allow(filler).to receive(:generate).with(timestamp: submission.created_at).and_return(file_path)
allow(SimpleFormsApi::VBA2010207).to receive(:new).and_return(vba_20_10207_instance)
allow(vba_20_10207_instance).to receive_messages(get_attachments: attachments, zip_code_is_us_based: true)
end

describe '#initialize' do
subject(:new) { submission_instance }

context 'when benefits_intake_uuid is valid' do
before { new }

it 'fetches the form submission data' do
expect(FormSubmission).to have_received(:find_by).with(benefits_intake_uuid:)
end

it 'sets the form submission data' do
expect(new.submission).to be(submission)
end

it 'sets attachments to empty array' do
expect(new.attachments).to eq([])
end
end

context 'when benefits_intake_uuid is nil' do
let(:benefits_intake_uuid) { nil }

it 'throws an error' do
expect { new }.to raise_exception('No benefits_intake_uuid was provided')
end
end

context 'when benefits_intake_uuid is missing' do
let(:submission_instance) { described_class.new(stuff: 'thangs') }

it 'throws an error' do
expect { new }.to raise_exception(ArgumentError, 'missing keyword: :id')
end
end

context 'when the form submission is not found' do
before { allow(FormSubmission).to receive(:find_by).and_return(nil) }

it 'throws an error' do
expect { new }.to raise_exception('Submission was not found or invalid')
end
end

context 'when benefits_intake_uuid is invalid' do
let(:benefits_intake_uuid) { 'complete-nonsense' }

before { allow(FormSubmission).to receive(:find_by).and_call_original }

it 'raises an error' do
expect { new }.to raise_exception('Submission was not found or invalid')
end
end

context 'when the associated form submission is not VFF in nature' do
let(:submission) { create(:form_submission, :pending, form_type: '12-34567', form_data:) }

it 'raises an error' do
expect { new }.to raise_exception(
'SimpleFormsApi::FormRemediation::SubmissionRemediationData cannot be built: Only VFF forms are supported'
)
end
end
end

describe '#hydrate!' do
subject(:hydrated) { submission_instance.hydrate! }

context 'when benefits_intake_uuid is valid' do
it 'generates a valid file_path' do
expect(hydrated.file_path).to include(file_path)
end

it 'generates a valid submission' do
expect(hydrated.submission).to be(submission)
end

it 'defaults to an empty array for attachments' do
expect(hydrated.attachments).to eq(attachments)
end

it 'generates valid metadata' do
expect(hydrated.metadata).to eq(metadata)
end

context 'when the form is 20-10207' do
it 'generates a valid array of attachments' do
expect(hydrated.attachments).to eq(attachments)
end
end

context 'when the form is not 20-10207' do
let(:form_type) { '21-10210' }
let(:form_data) { Rails.root.join(fixtures_path, 'form_json', 'vba_21_10210.json').read }
let(:vba_21_10210_instance) { instance_double(SimpleFormsApi::VBA2110210, metadata:) }

before do
allow(SimpleFormsApi::VBA2110210).to receive(:new).and_return(vba_20_10207_instance)
allow(vba_21_10210_instance).to receive_messages(zip_code_is_us_based: true)
end

it 'defaults to an empty array for attachments' do
expect(hydrated.attachments).to eq([])
end
end
end
end
end

0 comments on commit 21f7b56

Please sign in to comment.