Skip to content

Commit

Permalink
Missing Ratings | Add current rating profile endpoint to Caseflow (#1…
Browse files Browse the repository at this point in the history
…5172)

Connects #14839 

### Description
This PR integrates the new current rating endpoint from ruby-bgs into Caseflow, and adds a new model for working with data returned by this endpoint.

### Acceptance Criteria
- [x] Add find_current_rating_profile_by_ptcpnt_id to BGSService
- [x] Add a CurrentRating model which can fetch the (single) current rating for a veteran
  - [x] The same "self" classes in the Rating model aren't needed, but the same instance methods are needed
- [x] Add to BGSService fakes

### Testing Plan
- New spec added: `current_rating_spec.rb`
- Testing locally
  - The fake rating store has a list of available participant IDs: `BGSService.rating_store.all_keys`
  - Use `CurrentRating.fetch_by_participant_id` to fetch an instance and play around with it
  - Check the behavior for a non-existent participant ID
- Testing in unmodified UAT (to confirm everything is safe) and prod (to see representative data)
  - Paste the contents of `current_rating.rb` into Rails console
  - Inside a `class ExternalApi::BGSService`/`end` block:
    - Paste the contents of the `def find_current_rating_profile_by_ptcpnt_id` definition
  - Use `CurrentRating.fetch_by_participant_id` with a bunch of `Veteran.participant_id`s and play around. The new test code can provide some inspiration.
  - Check the behavior for a non-existent participant ID

### Code Documentation Updates
- [x] Add or update code comments at the top of the class, module, and/or component.
  • Loading branch information
nanotone authored Sep 4, 2020
1 parent 962a860 commit e82a0e9
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 1 deletion.
25 changes: 25 additions & 0 deletions app/models/current_rating.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

# CurrentRating provides a Rating implementation based on data returned by the BGS endpoint
# rating_profile.find_current_rating_profile_by_ptcpnt_id. Unlike its siblings RatingAtIssue
# and PromulgatedRating, this fetches a single rating per call. Thus, fetch_in_range and
# ratings_from_bgs_response are left unimplemented, and a few other methods aren't used.

class CurrentRating < Rating
class << self
def fetch_by_participant_id(participant_id)
from_bgs_hash(BGSService.new.find_current_rating_profile_by_ptcpnt_id(participant_id))
rescue BGS::ShareError
nil
end

def from_bgs_hash(data)
new(
participant_id: data[:ptcpnt_vet_id],
profile_date: data[:prfl_dt],
promulgation_date: data[:prmlgn_dt],
rating_profile: data
)
end
end
end
3 changes: 2 additions & 1 deletion app/models/rating.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

# A Rating can be a PromulgatedRating or a RatingAtIssue. Please see the subclasses for more information.
# A Rating can be a PromulgatedRating, RatingAtIssue, or CurrentRating.
# Please see the subclasses for more information.

class Rating
include ActiveModel::Model
Expand Down
9 changes: 9 additions & 0 deletions app/services/external_api/bgs_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,15 @@ def find_contentions_by_claim_id(claim_id)
end
end

def find_current_rating_profile_by_ptcpnt_id(participant_id)
DBService.release_db_connections
MetricsService.record("BGS: find current rating profile for veteran by participant_id #{participant_id}",
service: :bgs,
name: "rating_profile.find_current_rating_profile_by_ptcpnt_id") do
client.rating_profile.find_current_rating_profile_by_ptcpnt_id(participant_id, true)
end
end

def pay_grade_list
DBService.release_db_connections

Expand Down
10 changes: 10 additions & 0 deletions lib/fakes/bgs_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ def find_contentions_by_claim_id(claim_id)
format_contentions(contentions)
end

# :reek:FeatureEnvy
def find_current_rating_profile_by_ptcpnt_id(participant_id)
record = get_rating_record(participant_id)
fail BGS::ShareError, "No Record Found" if record.blank?

# We grab the latest promulgated rating, assuming that under the hood BGS also does.
rating = record[:ratings].max_by { |rt| rt[:prmlgn_dt] }
rating_at_issue_profile_data(rating)
end

def format_contentions(contentions)
{ contentions: contentions.map { |contention| format_contention(contention) } }
end
Expand Down
68 changes: 68 additions & 0 deletions spec/models/current_rating_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

describe CurrentRating do
describe "#fetch_by_participant_id" do
let(:bgs) { double("BGSService") }
let(:pid) { "12345" }
before do
allow(BGSService).to receive(:new) { bgs }
end

subject { CurrentRating.fetch_by_participant_id(pid) }

context "when participant exists" do
let(:bgs_hash) do
{ ptcpnt_vet_id: pid }
end
before do
allow(bgs).to receive(:find_current_rating_profile_by_ptcpnt_id).with(pid).and_return(bgs_hash)
end

it "returns a current rating object" do
expect(subject.participant_id).to eq(pid)
end
end

context "when participant doesn't exist" do
let(:error) { BGS::ShareError.new_from_message("message", 500) }
before do
allow(bgs).to receive(:find_current_rating_profile_by_ptcpnt_id).with(pid).and_raise(error)
end

it { is_expected.to be_nil }
end
end

describe "#from_bgs_hash" do
let(:yesterday) { DateTime.yesterday }
let(:bgs_hash) do
{
ptcpnt_vet_id: "participant ID",
prfl_dt: yesterday,
prmlgn_dt: yesterday,
rating_issues: [
{
rba_issue_id: "rating issue ID",
decn_txt: "issue description text"
}
],
disabilities: [
{
decn_tn: "Service Connected",
dis_sn: "disability ID"
}
],
associated_claims: { clm_id: "EP claim ID", bnft_clm_tc: "600PRI" }
}
end

it "hydrates an object that behaves like a Rating" do
rating = CurrentRating.from_bgs_hash(bgs_hash)
expect(rating.participant_id).to eq("participant ID")
expect(rating.profile_date).to eq(yesterday)
expect(rating.promulgation_date).to eq(yesterday)
expect(rating.issues[0].reference_id).to eq("rating issue ID")
expect(rating.associated_end_products[0].claim_id).to eq("EP claim ID")
end
end
end

0 comments on commit e82a0e9

Please sign in to comment.