-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add submission remediation data (#18769)
- Loading branch information
Showing
2 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
113 changes: 113 additions & 0 deletions
113
...e_forms_api/app/services/simple_forms_api/form_remediation/submission_remediation_data.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
144 changes: 144 additions & 0 deletions
144
modules/simple_forms_api/spec/services/form_remediation/submission_remediation_data_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |