diff --git a/config/features.yml b/config/features.yml index 1d75967a58b..068190f7557 100644 --- a/config/features.yml +++ b/config/features.yml @@ -1257,6 +1257,9 @@ features: disability_compensation_lighthouse_brd: actor_type: user description: If enabled uses the lighthouse Benefits Reference Data service + disability_compensation_lighthouse_generate_pdf: + actor_type: user + description: If enabled uses the lighthouse Benefits Claims service to generate a 526 pdf virtual_agent_fetch_jwt_token: actor_type: user description: Enable the fetching of a JWT token to access MAP environment diff --git a/lib/disability_compensation/factories/api_provider_factory.rb b/lib/disability_compensation/factories/api_provider_factory.rb index e9d7b1913b7..a8b7185306e 100644 --- a/lib/disability_compensation/factories/api_provider_factory.rb +++ b/lib/disability_compensation/factories/api_provider_factory.rb @@ -15,6 +15,9 @@ require 'disability_compensation/providers/brd/brd_provider' require 'disability_compensation/providers/brd/evss_brd_provider' require 'disability_compensation/providers/brd/lighthouse_brd_provider' +require 'disability_compensation/providers/generate_pdf/generate_pdf_provider' +require 'disability_compensation/providers/generate_pdf/evss_generate_pdf_provider' +require 'disability_compensation/providers/generate_pdf/lighthouse_generate_pdf_provider' require 'logging/third_party_transaction' class ApiProviderFactory @@ -31,7 +34,8 @@ class UndefinedFactoryTypeError < StandardError; end intent_to_file: :intent_to_file, ppiu: :ppiu, claims: :claims, - brd: :brd + brd: :brd, + generate_pdf: :generate_pdf }.freeze # Splitting the rated disabilities functionality into two use cases: @@ -47,6 +51,7 @@ class UndefinedFactoryTypeError < StandardError; end # PPIU calls out to Direct Deposit APIs in Lighthouse FEATURE_TOGGLE_PPIU_DIRECT_DEPOSIT = 'disability_compensation_lighthouse_ppiu_direct_deposit_provider' FEATURE_TOGGLE_BRD = 'disability_compensation_lighthouse_brd' + FEATURE_TOGGLE_GENERATE_PDF = 'disability_compensation_lighthouse_generate_pdf' attr_reader :type @@ -56,6 +61,7 @@ class UndefinedFactoryTypeError < StandardError; end :ppiu_service_provider, :claims_service_provider, :brd_service_provider, + :generate_pdf_service_provider, additional_class_logs: { action: 'disability compensation factory choosing API Provider' }, @@ -91,6 +97,8 @@ def call claims_service_provider when FACTORIES[:brd] brd_service_provider + when FACTORIES[:generate_pdf] + generate_pdf_service_provider else raise UndefinedFactoryTypeError end @@ -153,6 +161,23 @@ def brd_service_provider end end + def generate_pdf_service_provider + case api_provider + when API_PROVIDER[:evss] + if @options[:auth_headers].nil? || @options[:auth_headers]&.empty? + raise StandardError, 'options[:auth_headers] is required to create a generate an EVSS pdf provider' + end + + # provide options[:breakered] = false if this needs to use the non-breakered configuration + # for instance, in the backup process + EvssGeneratePdfProvider.new(@options[:auth_headers], breakered: @options[:breakered]) + when API_PROVIDER[:lighthouse] + LighthouseGeneratePdfProvider.new({}) + else + raise NotImplementedError, 'No known Generate Pdf Api Provider type provided' + end + end + def api_provider @api_provider ||= if Flipper.enabled?(@feature_toggle, @current_user) API_PROVIDER[:lighthouse] diff --git a/lib/disability_compensation/providers/generate_pdf/evss_generate_pdf_provider.rb b/lib/disability_compensation/providers/generate_pdf/evss_generate_pdf_provider.rb new file mode 100644 index 00000000000..6cd03f26212 --- /dev/null +++ b/lib/disability_compensation/providers/generate_pdf/evss_generate_pdf_provider.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'disability_compensation/providers/generate_pdf/generate_pdf_provider' +require 'evss/disability_compensation_form/service' +require 'evss/disability_compensation_form/non_breakered_service' + +class EvssGeneratePdfProvider + include GeneratePdfProvider + + def initialize(auth_headers, breakered: true) + # both of these services implement `get_form526` + @service = if breakered + EVSS::DisabilityCompensationForm::Service.new(auth_headers) + else + EVSS::DisabilityCompensationForm::NonBreakeredService.new(auth_headers) + end + end + + def generate_526_pdf(form_content) + @service.get_form526(form_content) + end +end diff --git a/lib/disability_compensation/providers/generate_pdf/generate_pdf_provider.rb b/lib/disability_compensation/providers/generate_pdf/generate_pdf_provider.rb new file mode 100644 index 00000000000..f914f6c9772 --- /dev/null +++ b/lib/disability_compensation/providers/generate_pdf/generate_pdf_provider.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module GeneratePdfProvider + def self.generate_526_pdf(_form_content) + raise NotImplementedError, 'Do not use base module methods. Override this method in implementation class.' + end +end diff --git a/lib/disability_compensation/providers/generate_pdf/lighthouse_generate_pdf_provider.rb b/lib/disability_compensation/providers/generate_pdf/lighthouse_generate_pdf_provider.rb new file mode 100644 index 00000000000..0384339de2d --- /dev/null +++ b/lib/disability_compensation/providers/generate_pdf/lighthouse_generate_pdf_provider.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'disability_compensation/providers/generate_pdf/generate_pdf_provider' + +class LighthouseGeneratePdfProvider + include GeneratePdfProvider + + def initialize(_auth_headers) + # TODO: Implement in Ticket# + end + + def generate_526_pdf(_form_content) + # TODO: Implement in Ticket# + end +end diff --git a/lib/sidekiq/form526_backup_submission_process/processor.rb b/lib/sidekiq/form526_backup_submission_process/processor.rb index 0394818197d..1645719f412 100644 --- a/lib/sidekiq/form526_backup_submission_process/processor.rb +++ b/lib/sidekiq/form526_backup_submission_process/processor.rb @@ -13,6 +13,7 @@ require 'pdf_fill/filler' require 'logging/third_party_transaction' require 'simple_forms_api_submission/metadata_validator' +require 'disability_compensation/factories/api_provider_factory' module Sidekiq module Form526BackupSubmissionProcess @@ -341,7 +342,10 @@ def get_form526_pdf end def get_form_from_external_api(headers, form_json) - EVSS::DisabilityCompensationForm::Service.new(headers).get_form526(form_json) + # get the "breakered" version + service = choose_provider(headers, breakered: true) + + service.generate_526_pdf(form_json) end def get_uploads @@ -423,6 +427,18 @@ def convert_doc_to_pdf(doc, klass) Common::FileHelpers.delete_file_if_exists(actual_path_to_file) if ::Rails.env.production? end end + + def choose_provider(headers, breakered: true) + ApiProviderFactory.call( + type: ApiProviderFactory::FACTORIES[:generate_pdf], + # let Flipper - the feature toggle - choose which provider + provider: nil, + # this sends the auth headers and if we want the "breakered" or "non-breakered" version + options: { auth_headers: headers, breakered: }, + current_user: OpenStruct.new({ flipper_id: submission.user_uuid }), + feature_toggle: ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF + ) + end end class NonBreakeredProcessor < Processor @@ -444,7 +460,10 @@ def get_form526_pdf end def get_from_non_breakered_service(headers, form_json) - EVSS::DisabilityCompensationForm::NonBreakeredService.new(headers).get_form526(form_json) + # get the "non-breakered" version + service = choose_provider(headers, breakered: false) + + service.get_form526(form_json) end class NonBreakeredForm526BackgroundLoader diff --git a/spec/lib/disability_compensation/factories/api_provider_factory_spec.rb b/spec/lib/disability_compensation/factories/api_provider_factory_spec.rb index b95ce03cd19..4f5202d5c3d 100644 --- a/spec/lib/disability_compensation/factories/api_provider_factory_spec.rb +++ b/spec/lib/disability_compensation/factories/api_provider_factory_spec.rb @@ -210,4 +210,38 @@ def provider(api_provider = nil) end.to raise_error NotImplementedError end end + + context 'generate_pdf' do + def provider(api_provider = nil) + ApiProviderFactory.call( + type: ApiProviderFactory::FACTORIES[:generate_pdf], + provider: api_provider, + options: { auth_headers: }, + current_user:, + feature_toggle: ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF + ) + end + + it 'provides an EVSS generate_pdf provider' do + expect(provider(:evss).class).to equal(EvssGeneratePdfProvider) + end + + it 'provides a Lighthouse generate_pdf provider' do + expect(provider(:lighthouse).class).to equal(LighthouseGeneratePdfProvider) + end + + it 'provides generate_pdf provider based on Flipper' do + Flipper.enable(ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF) + expect(provider.class).to equal(LighthouseGeneratePdfProvider) + + Flipper.disable(ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF) + expect(provider.class).to equal(EvssGeneratePdfProvider) + end + + it 'throw error if provider unknown' do + expect do + provider(:random) + end.to raise_error NotImplementedError + end + end end diff --git a/spec/lib/disability_compensation/providers/generate_pdf/evss_generate_pdf_provider_spec.rb b/spec/lib/disability_compensation/providers/generate_pdf/evss_generate_pdf_provider_spec.rb new file mode 100644 index 00000000000..030d63de9d8 --- /dev/null +++ b/spec/lib/disability_compensation/providers/generate_pdf/evss_generate_pdf_provider_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'disability_compensation/factories/api_provider_factory' +require 'disability_compensation/providers/generate_pdf/evss_generate_pdf_provider' +require 'support/disability_compensation_form/shared_examples/generate_pdf_service_provider' + +RSpec.describe EvssGeneratePdfProvider do + let(:current_user) do + create(:user) + end + + let(:auth_headers) do + EVSS::AuthHeaders.new(current_user).to_h + end + + before do + Flipper.disable(ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF) + end + + after do + Flipper.disable(ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF) + end + + it_behaves_like 'generate pdf service provider' + + it 'creates a breakered evss service' do + provider = EvssGeneratePdfProvider.new(auth_headers) + expect(provider.instance_variable_get(:@service).class).to equal(EVSS::DisabilityCompensationForm::Service) + + provider = EvssGeneratePdfProvider.new(auth_headers, breakered: true) + expect(provider.instance_variable_get(:@service).class).to equal(EVSS::DisabilityCompensationForm::Service) + end + + it 'creates a non-breakered evss service' do + provider = EvssGeneratePdfProvider.new(auth_headers, breakered: false) + expect(provider.instance_variable_get(:@service).class) + .to equal(EVSS::DisabilityCompensationForm::NonBreakeredService) + end + + it 'retrieves a generated 526 pdf from the EVSS API' do + VCR.use_cassette('form526_backup/200_evss_get_pdf', match_requests_on: %i[uri method]) do + provider = EvssGeneratePdfProvider.new(auth_headers) + response = provider.generate_526_pdf({}.to_json) + expect(response.body['pdf']).to eq('') + end + end +end diff --git a/spec/lib/disability_compensation/providers/generate_pdf/generate_pdf_provider_spec.rb b/spec/lib/disability_compensation/providers/generate_pdf/generate_pdf_provider_spec.rb new file mode 100644 index 00000000000..943f88d3a65 --- /dev/null +++ b/spec/lib/disability_compensation/providers/generate_pdf/generate_pdf_provider_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'disability_compensation/providers/generate_pdf/generate_pdf_provider' + +RSpec.describe GeneratePdfProvider do + it 'always raises an error on the BRDProvider base module' do + expect do + subject.generate_526_pdf({}) + end.to raise_error NotImplementedError + end +end diff --git a/spec/lib/disability_compensation/providers/generate_pdf/lighthouse_generate_pdf_provider_spec.rb b/spec/lib/disability_compensation/providers/generate_pdf/lighthouse_generate_pdf_provider_spec.rb new file mode 100644 index 00000000000..808fb69a552 --- /dev/null +++ b/spec/lib/disability_compensation/providers/generate_pdf/lighthouse_generate_pdf_provider_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'disability_compensation/factories/api_provider_factory' +require 'disability_compensation/providers/generate_pdf/lighthouse_generate_pdf_provider' +require 'support/disability_compensation_form/shared_examples/generate_pdf_service_provider' +require 'lighthouse/service_exception' + +RSpec.describe LighthouseGeneratePdfProvider do + let(:auth_headers) { {} } + + before do + @provider = LighthouseGeneratePdfProvider.new(auth_headers) + Flipper.enable(ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF) + end + + after do + Flipper.disable(ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF) + end + + it_behaves_like 'generate pdf service provider' + + # TODO: Implement in Ticket# + # it 'retrieves a generated 526 pdf from the Lighthouse API' do + # VCR.use_cassette('lighthouse/benefits_claims/generate_pdf/200_response') do + # + # response = @provider.generate_526_pdf + # expect(response).to eq(nil) + # end + # end +end diff --git a/spec/lib/sidekiq/form526_backup_submission_process/submit_spec.rb b/spec/lib/sidekiq/form526_backup_submission_process/submit_spec.rb index 69ff18ad1ff..0ec092ed2f5 100644 --- a/spec/lib/sidekiq/form526_backup_submission_process/submit_spec.rb +++ b/spec/lib/sidekiq/form526_backup_submission_process/submit_spec.rb @@ -4,12 +4,14 @@ require 'evss/disability_compensation_auth_headers' # required to build a Form526Submission require 'sidekiq/form526_backup_submission_process/submit' +require 'disability_compensation/factories/api_provider_factory' RSpec.describe Sidekiq::Form526BackupSubmissionProcess::Submit, type: :job do subject { described_class } before do Sidekiq::Job.clear_all + Flipper.disable(ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF) end let(:user) { FactoryBot.create(:user, :loa3) } diff --git a/spec/lib/sidekiq/form526_job_status_tracker/job_tracker_spec.rb b/spec/lib/sidekiq/form526_job_status_tracker/job_tracker_spec.rb index a8c84527c9b..8ed993a919b 100644 --- a/spec/lib/sidekiq/form526_job_status_tracker/job_tracker_spec.rb +++ b/spec/lib/sidekiq/form526_job_status_tracker/job_tracker_spec.rb @@ -11,6 +11,10 @@ end end + before do + Flipper.disable(ApiProviderFactory::FEATURE_TOGGLE_GENERATE_PDF) + end + context 'with an exhausted callback message' do let!(:form526_submission) { create :form526_submission } let!(:form526_job_status) do diff --git a/spec/support/disability_compensation_form/shared_examples/generate_pdf_service_provider.rb b/spec/support/disability_compensation_form/shared_examples/generate_pdf_service_provider.rb new file mode 100644 index 00000000000..76fdc0fbf20 --- /dev/null +++ b/spec/support/disability_compensation_form/shared_examples/generate_pdf_service_provider.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'rails_helper' + +shared_examples 'generate pdf service provider' do + # this is used to instantiate any Claim Service with a current_user + subject { described_class.new(auth_headers) } + + it { is_expected.to respond_to(:generate_526_pdf) } +end