Skip to content

Commit 6c089e7

Browse files
authored
Champva 94284 pega reporting api connection (#19951)
* First pass at implementing Pega API client * Cleaned up reminder * Restored prefill in settings * Cleaned up tests
1 parent 9257976 commit 6c089e7

File tree

7 files changed

+222
-0
lines changed

7 files changed

+222
-0
lines changed

config/settings.yml

+2
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,8 @@ intent_to_file:
412412

413413
ivc_champva:
414414
prefill: true
415+
pega_api:
416+
api_key: fake_api_key
415417

416418
form_upload_flow:
417419
prefill: true
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# frozen_string_literal: true
2+
3+
require 'common/client/base'
4+
require_relative 'configuration'
5+
6+
module IvcChampva
7+
module PegaApi
8+
class PegaApiError < StandardError; end
9+
10+
class Client < Common::Client::Base
11+
configuration IvcChampva::PegaApi::Configuration
12+
13+
##
14+
# HTTP POST call to the Pega API to retrieve a report
15+
#
16+
# @param date_start [Date, nil] the start date of the report
17+
# @param date_end [Date, nil] the end date of the report
18+
# @return [Array<Hash>] the report rows
19+
def get_report(date_start, date_end)
20+
resp = connection.post(config.base_path) do |req|
21+
req.headers = headers(date_start, date_end)
22+
end
23+
24+
raise "response code: #{resp.status}, response body: #{resp.body}" unless resp.status == 200
25+
26+
# We also need to check the StatusCode in the response body.
27+
# It seems that when this API errors out, it will return responses with HTTP 200 statuses, but
28+
# the StatusCode in the response body will be something other than 200.
29+
response = JSON.parse(resp.body, symbolize_names: false)
30+
unless response['statusCode'] == 200
31+
raise "alternate response code: #{response['statusCode']}, response body: #{response['body']}"
32+
end
33+
34+
# With both status codes checked and passing, we should now have a body that is more JSON embedded in a string.
35+
# This is our report, let's decode it.
36+
JSON.parse(response['body'])
37+
rescue => e
38+
raise PegaApiError, e.message.to_s
39+
end
40+
41+
##
42+
# Assembles headers for the Pega API request
43+
#
44+
# @param date_start [Date, nil] the start date of the report
45+
# @param date_end [Date, nil] the end date of the report
46+
# @return [Hash] the headers
47+
def headers(date_start, date_end)
48+
{
49+
:content_type => 'application/json',
50+
'x-api-key' => Settings.ivc_champva.pega_api.api_key.to_s,
51+
'date_start' => date_start.to_s,
52+
'date_end' => date_end.to_s,
53+
'case_id' => '' # case_id seems to have no effect, but it is required by the API
54+
}
55+
end
56+
end
57+
end
58+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
require 'common/client/configuration/rest'
4+
require 'common/client/middleware/response/raise_custom_error'
5+
6+
module IvcChampva
7+
module PegaApi
8+
class Configuration < Common::Client::Configuration::REST
9+
def base_path
10+
'https://bt41mfpkj5.execute-api.us-gov-west-1.amazonaws.com/prod/'
11+
end
12+
13+
def connection
14+
Faraday.new(base_path, headers: base_request_headers, request: request_options) do |conn|
15+
conn.use :breakers
16+
# conn.use :instrumentation, name: 'dhp.fitbit.request.faraday'
17+
18+
# Uncomment this if you want curlggg command equivalent or response output to log
19+
# conn.request(:curl, ::Logger.new(STDOUT), :warn) unless Rails.env.production?
20+
# conn.response(:logger, ::Logger.new(STDOUT), bodies: true) unless Rails.env.production?
21+
22+
# conn.response :raise_custom_error, error_prefix: service_name
23+
24+
conn.adapter Faraday.default_adapter
25+
end
26+
end
27+
end
28+
end
29+
end

modules/ivc_champva/spec/fixtures/pega_api_json/report_response_200_200.json

+4
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"statusCode": 500,
3+
"body": "'case_id'"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"message": "Forbidden"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
require 'pega_api/client'
5+
6+
RSpec.describe IvcChampva::PegaApi::Client do
7+
subject { described_class.new }
8+
9+
describe 'get_report' do
10+
let(:body200and200) do # pega api response with HTTP status 200 and alternate status 200
11+
fixture_path = Rails.root.join('modules', 'ivc_champva', 'spec', 'fixtures', 'pega_api_json',
12+
'report_response_200_200.json')
13+
fixture_path.read
14+
end
15+
16+
let(:body200and500) do # pega api response with HTTP status 200 and alternate status 500
17+
fixture_path = Rails.root.join('modules', 'ivc_champva', 'spec', 'fixtures', 'pega_api_json',
18+
'report_response_200_500.json')
19+
fixture_path.read
20+
end
21+
22+
let(:body403) do # pega api response with HTTP status 403 forbidden
23+
fixture_path = Rails.root.join('modules', 'ivc_champva', 'spec', 'fixtures', 'pega_api_json',
24+
'report_response_403.json')
25+
fixture_path.read
26+
end
27+
28+
context 'successful response from pega' do
29+
let(:faraday_response) { double('Faraday::Response', status: 200, body: body200and200) }
30+
31+
before do
32+
allow_any_instance_of(Faraday::Connection).to receive(:post).with(anything).and_return(faraday_response)
33+
end
34+
35+
it 'returns the body as an array of hashes' do
36+
result = subject.get_report(Date.new(2024, 11, 1), Date.new(2024, 12, 31))
37+
38+
expect(result[0]['Creation Date']).to eq('2024-11-27T08:42:11.372000')
39+
expect(result[0]['PEGA Case ID']).to eq('D-55824')
40+
expect(result[0]['Status']).to eq('Open')
41+
end
42+
end
43+
44+
context 'unsuccessful pega response with bad HTTP status' do
45+
let(:faraday_response) { double('Faraday::Response', status: 403, body: body403) }
46+
47+
before do
48+
allow_any_instance_of(Faraday::Connection).to receive(:post).with(anything).and_return(faraday_response)
49+
end
50+
51+
it 'raises error when response is 404' do
52+
expect { subject.get_report(nil, nil) }.to raise_error(IvcChampva::PegaApi::PegaApiError)
53+
end
54+
end
55+
56+
context 'unsuccessful pega response with bad alternate status' do
57+
let(:faraday_response) { double('Faraday::Response', status: 200, body: body200and500) }
58+
59+
before do
60+
allow_any_instance_of(Faraday::Connection).to receive(:post).with(anything).and_return(faraday_response)
61+
end
62+
63+
it 'raises error when alternate status is 500' do
64+
expect { subject.get_report(nil, nil) }.to raise_error(IvcChampva::PegaApi::PegaApiError)
65+
end
66+
end
67+
end
68+
69+
describe 'headers' do
70+
it 'returns the right headers' do
71+
result = subject.headers(Date.new(2024, 11, 1), Date.new(2024, 12, 31))
72+
73+
expect(result[:content_type]).to eq('application/json')
74+
expect(result['x-api-key']).to eq('fake_api_key')
75+
expect(result['date_start']).to eq('2024-11-01')
76+
expect(result['date_end']).to eq('2024-12-31')
77+
expect(result['case_id']).to eq('')
78+
end
79+
80+
it 'returns the right headers with nil dates' do
81+
result = subject.headers(nil, nil)
82+
83+
expect(result[:content_type]).to eq('application/json')
84+
expect(result['x-api-key']).to eq('fake_api_key')
85+
expect(result['date_start']).to eq('')
86+
expect(result['date_end']).to eq('')
87+
expect(result['case_id']).to eq('')
88+
end
89+
end
90+
91+
# Temporary, delete me
92+
# This test is used to hit the production endpoint when running locally.
93+
# It can be removed once we have some real code that uses the Pega API client.
94+
describe 'hit the production endpoint', skip: 'this is useful as a way to hit the API during local development' do
95+
let(:forced_headers) do
96+
{
97+
:content_type => 'application/json',
98+
# use the following line when running locally tp pull the key from an environment variable
99+
'x-api-key' => ENV.fetch('PEGA_API_KEY'), # to set: export PEGA_API_KEY=insert1the2api3key4here
100+
'date_start' => '', # '2024-11-01', # '11/01/2024',
101+
'date_end' => '', # '2024-12-31', # '12/07/2024',
102+
'case_id' => ''
103+
}
104+
end
105+
106+
before do
107+
allow_any_instance_of(IvcChampva::PegaApi::Client).to receive(:headers).with(anything, anything)
108+
.and_return(forced_headers)
109+
end
110+
111+
it 'returns report data' do
112+
VCR.configure do |c|
113+
c.allow_http_connections_when_no_cassette = true
114+
end
115+
116+
result = subject.get_report(Date.new(2024, 11, 1), Date.new(2024, 12, 31))
117+
expect(result.count).to be_positive
118+
119+
# byebug # in byebug, type 'p result' to view the response
120+
end
121+
end
122+
end

0 commit comments

Comments
 (0)