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 Jun 20, 2024
1 parent 6dc18ec commit 59de8ea
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 10 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ gem "redis-namespace"
gem "redis-rails", "~> 5.0.2"
gem "request_store"
gem "roo", "~> 2.7"
gem "ruby_claim_evidence_api", git: "https://github.com/department-of-veterans-affairs/ruby_claim_evidence_api.git", branch: "feature/APPEALS-43121"
# Use SCSS for stylesheets
gem "sass-rails", "~> 5.0"
# Error reporting to Sentry
Expand Down
37 changes: 28 additions & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@ GIT
nokogiri (>= 1.11.0.rc4)
savon (~> 2.12)

GIT
remote: https://github.com/department-of-veterans-affairs/ruby_claim_evidence_api.git
revision: 2c1da40c288be1c60caaefa8de496da7345952ca
branch: feature/APPEALS-43121
specs:
ruby_claim_evidence_api (0.1.0)
activesupport
aws-sdk-comprehend (~> 1.77)
base64
faraday
faraday-multipart
httpi
railties
webmock (~> 3.11.0)

GIT
remote: https://github.com/department-of-veterans-affairs/sniffybara.git
revision: 351560b5789ca638ba7c9b093c2bb1a9a6fda4b3
Expand Down Expand Up @@ -368,8 +383,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 @@ -401,11 +416,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 @@ -1440,6 +1455,7 @@ GEM
aws-sigv4 (1.8.0)
aws-eventstream (~> 1, >= 1.0.2)
backport (1.2.0)
base64 (0.2.0)
benchmark-ips (2.7.2)
bootsnap (1.7.5)
msgpack (~> 1.0)
Expand Down Expand Up @@ -1580,6 +1596,8 @@ GEM
multipart-post (>= 1.2, < 3)
faraday-http-cache (2.4.1)
faraday (>= 0.8)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0)
fast_jsonapi (1.5)
Expand Down Expand Up @@ -1636,7 +1654,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 @@ -1987,7 +2005,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 Expand Up @@ -2098,6 +2116,7 @@ DEPENDENCIES
ruby-debug-ide
ruby-oci8 (~> 2.2)
ruby-prof (~> 1.4)
ruby_claim_evidence_api!
sass-rails (~> 5.0)
scss_lint
sentry-raven
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 59de8ea

Please sign in to comment.