Skip to content

Commit

Permalink
Add New CE REST API REST Functionality for Vet Docs (#21812)
Browse files Browse the repository at this point in the history
* Add New CE REST API REST Functionality for Vet Docs

- Add feature toggle to enable/disable new functionality.

- Call REST endpoint for veteran docs when the use_ce_api feature
toggle is enabled.

- Add supporting services and specs.

* Fix Misc. Issues

- Update JsonApiResponseAdapter with latest changes to respnse
parsing found in caseflow-efolder testing.

- Update ruby_claim_evidence_api to bugfix version.

* Update received_at Date Parsing Logic

- Use slashes instead of hyphens to help JS correctly parse the
date.

* Fix Double Quote Issue

* Improve JsonApiResponseAdapter Blank Response Handling

* Pass Rails Logger to VeteranFileFetcher
  • Loading branch information
tradesmanhelix authored and youfoundmanesh committed Oct 8, 2024
1 parent 8acb7f8 commit 07e63d7
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 10 deletions.
18 changes: 9 additions & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,8 @@ GEM
aws-sdk-cognitosync (1.36.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sdk-comprehend (1.62.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-comprehend (1.82.0)
aws-sdk-core (~> 3, >= 3.193.0)
aws-sigv4 (~> 1.1)
aws-sdk-comprehendmedical (1.36.0)
aws-sdk-core (~> 3, >= 3.127.0)
Expand Down Expand Up @@ -408,11 +408,11 @@ GEM
aws-sdk-controltower (1.0.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sdk-core (3.131.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-core (3.196.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1)
aws-sdk-costandusagereportservice (1.41.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
Expand Down Expand Up @@ -1651,7 +1651,7 @@ GEM
immigrant (0.3.6)
activerecord (>= 3.0)
jaro_winkler (1.5.6)
jmespath (1.3.1)
jmespath (1.6.2)
jquery-rails (4.5.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
Expand Down Expand Up @@ -2102,7 +2102,7 @@ GEM
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0, < 4.11)
webmock (3.6.2)
webmock (3.11.3)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
Expand Down
7 changes: 6 additions & 1 deletion app/services/external_api/vbms_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ def self.fetch_documents_for(appeal, _user = nil)
end

def self.fetch_document_series_for(appeal)
ExternalApi::VbmsDocumentSeriesForAppeal.new(file_number: appeal.veteran_file_number).fetch
if FeatureToggle.enabled?(:use_ce_api)
response = VeteranFileFetcher.fetch_veteran_file_list(veteran_file_number: appeal.veteran_file_number)
JsonApiResponseAdapter.new.adapt_fetch_document_series_for(response)
else
ExternalApi::VbmsDocumentSeriesForAppeal.new(file_number: appeal.veteran_file_number).fetch
end
end

def self.update_document_in_vbms(appeal, uploadable_document)
Expand Down
48 changes: 48 additions & 0 deletions app/services/json_api_response_adapter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

# Translates JSON API responses into a format that's compatible with the legacy SOAP responses expected
# by most of Caseflow
class JsonApiResponseAdapter
def adapt_fetch_document_series_for(json_response)
documents = []

return documents unless valid_json_response?(json_response)

json_response.body["files"].each do |file_resp|
documents.push(fetch_document_series_for_response(file_resp))
end

documents
end

private

def valid_json_response?(json_response)
return false if json_response&.body.blank?

json_response.body.key?("files")
end

def fetch_document_series_for_response(file_json)
system_data = file_json["currentVersion"]["systemData"]
provider_data = file_json["currentVersion"]["providerData"]

OpenStruct.new(
document_id: "{#{file_json['currentVersionUuid'].upcase}}",
series_id: "{#{file_json['uuid'].upcase}}",
version: "1",
type_description: provider_data["subject"],
type_id: provider_data["documentTypeId"],
doc_type: provider_data["documentTypeId"],
subject: provider_data["subject"],
# gsub here so that JS will correctly handle this date
# (with dashes the date is 1 day off due to UTC issues)
received_at: provider_data["dateVaReceivedDocument"]&.gsub("-", "/"),
source: provider_data["contentSource"],
mime_type: system_data["mimeType"],
alt_doc_types: nil,
restricted: nil,
upload_date: system_data["uploadedDateTime"]
)
end
end
4 changes: 4 additions & 0 deletions config/initializers/ruby_claim_evidence_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

VeteranFileFetcher = ExternalApi::VeteranFileFetcher
.new(use_canned_api_responses: ApplicationController.dependencies_faked?, logger: Rails.logger)
40 changes: 40 additions & 0 deletions spec/services/external_api/vbms_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

describe ExternalApi::VBMSService do
subject(:described) { described_class }

describe ".fetch_document_series_for" do
let(:mock_json_adapter) { instance_double(JsonApiResponseAdapter) }
let(:mock_vbms_document_series_for_appeal) { instance_double(ExternalApi::VbmsDocumentSeriesForAppeal) }

let!(:appeal) { create(:appeal) }

before do
allow(JsonApiResponseAdapter).to receive(:new).and_return(mock_json_adapter)
allow(ExternalApi::VbmsDocumentSeriesForAppeal).to receive(:new).and_return(mock_vbms_document_series_for_appeal)
end

context "with use_ce_api feature toggle enabled" do
before { FeatureToggle.enable!(:use_ce_api) }
after { FeatureToggle.disable!(:use_ce_api) }

it "calls the CE API" do
expect(VeteranFileFetcher).to receive(:fetch_veteran_file_list)
.with(veteran_file_number: appeal.veteran_file_number)
expect(mock_json_adapter).to receive(:adapt_fetch_document_series_for).and_return([])

described.fetch_document_series_for(appeal)
end
end

context "with no feature toggles enabled" do
it "calls the VbmsDocumentSeriesForAppeal service" do
expect(FeatureToggle).to receive(:enabled?).with(:use_ce_api).and_return(false)
expect(ExternalApi::VbmsDocumentSeriesForAppeal).to receive(:new).with(file_number: appeal.veteran_file_number)
expect(mock_vbms_document_series_for_appeal).to receive(:fetch)

described.fetch_document_series_for(appeal)
end
end
end
end
54 changes: 54 additions & 0 deletions spec/services/json_api_response_adapter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require "json"

describe JsonApiResponseAdapter do
subject(:described) { described_class.new }

let(:api_response) { instance_double(ExternalApi::Response) }

describe "#adapt_fetch_document_series_for" do
context "with invalid responses" do
it "handles blank responses" do
parsed = described.adapt_fetch_document_series_for(nil)

expect(parsed.length).to eq 0
end

it "handles blank response bodies" do
response = instance_double(ExternalApi::Response, body: nil)
parsed = described.adapt_fetch_document_series_for(response)

expect(parsed.length).to eq 0
end

it "handles response bodies with no files" do
response = instance_double(ExternalApi::Response, body: {})
parsed = described.adapt_fetch_document_series_for(response)

expect(parsed.length).to eq 0
end
end

it "correctly parses an API response" do
file = File.open(Rails.root.join("spec/support/api_responses/ce_api_folders_files_search.json"))
data_hash = JSON.parse(File.read(file))
file.close

expect(api_response).to receive(:body)
.exactly(3).times.and_return(data_hash)

parsed = described.adapt_fetch_document_series_for(api_response)

expect(parsed.length).to eq 2

expect(parsed[0].document_id).to eq "{03223945-468B-4E8A-B79B-82FA73C2D2D9}"
expect(parsed[0].received_at).to eq "2018/03/08"
expect(parsed[0].mime_type).to eq "application/pdf"

expect(parsed[1].document_id).to eq "{7D6AFD8C-3BF7-4224-93AE-E1F07AC43C71}"
expect(parsed[1].received_at).to eq "2018/12/08"
expect(parsed[1].mime_type).to eq "application/pdf"
end
end
end
84 changes: 84 additions & 0 deletions spec/support/api_responses/ce_api_folders_files_search.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"page": {
"totalPages": 1,
"requestedResultsPerPage": 20,
"currentPage": 1,
"totalResults": 2
},
"files": [
{
"owner": {
"type": "VETERAN",
"id": "123456789"
},
"uuid": "23e7ae3b-5489-4fa9-b6e3-b1f953287138",
"currentVersionUuid": "03223945-468b-4e8a-b79b-82fa73c2d2d9",
"currentVersion": {
"systemData": {
"uploadedDateTime": "2018-03-08T14:21:40",
"contentName": "20180308091849 - codesheet.pdf",
"mimeType": "application/pdf",
"uploadSource": "RATING"
},
"providerData": {
"subject": "Rating Decision - Codesheet",
"documentTypeId": 338,
"ocrStatus": "Failure to Process",
"newMail": false,
"bookmarks": {
"VBA": {
"isDefaultRealm": true
}
},
"systemSource": "RATING",
"isAnnotated": false,
"modifiedDateTime": "2018-03-08T14:21:40",
"numberOfContentions": 0,
"readByCurrentUser": false,
"dateVaReceivedDocument": "2018-03-08",
"hasContentionAnnotations": false,
"contentSource": "VBMS-R",
"actionable": false,
"lastOpenedDocument": false
}
}
},
{
"owner": {
"type": "VETERAN",
"id": "123456789"
},
"uuid": "a001424d-99f9-4a96-977d-ee06ec4ef3a7",
"currentVersionUuid": "7d6afd8c-3bf7-4224-93ae-e1f07ac43c71",
"currentVersion": {
"systemData": {
"uploadedDateTime": "2018-03-08T14:21:43",
"contentName": "20180308091852 - narrative.pdf",
"mimeType": "application/pdf",
"uploadSource": "RATING"
},
"providerData": {
"subject": "Rating Decision - Narrative",
"documentTypeId": 339,
"ocrStatus": "Failure to Process",
"newMail": false,
"bookmarks": {
"VBA": {
"isDefaultRealm": true
}
},
"systemSource": "RATING",
"isAnnotated": false,
"modifiedDateTime": "2018-03-08T14:21:43",
"numberOfContentions": 0,
"readByCurrentUser": false,
"dateVaReceivedDocument": "2018-12-08",
"hasContentionAnnotations": false,
"contentSource": "VBMS-R",
"actionable": false,
"lastOpenedDocument": false
}
}
}
]
}

0 comments on commit 07e63d7

Please sign in to comment.