Skip to content

Commit

Permalink
BE | Ask Va Api: Update Correspondences::Retriever and `Inquiries::…
Browse files Browse the repository at this point in the history
…Retriever` (#16510)

* Update `Correspondences::Retriever` and `Inquiries::Retriever`

- `Inquiries::Retriever` is returning `correspondences` as an empty array
  instead of `erroring`
- clean up specs as well

* fix linting

---------

Co-authored-by: khoa-v-nguyen <khoa.nguyen@oddball.io>
  • Loading branch information
Khoa-V-Nguyen and khoa-v-nguyen committed Apr 25, 2024
1 parent 9825dab commit 15552a8
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 76 deletions.
25 changes: 14 additions & 11 deletions modules/ask_va_api/app/lib/ask_va_api/correspondences/retriever.rb
Expand Up @@ -2,20 +2,27 @@

module AskVAApi
module Correspondences
class CorrespondencesRetrieverError < StandardError; end

class Retriever < BaseRetriever
attr_reader :inquiry_id, :entity_class
class Retriever
attr_reader :inquiry_id, :entity_class, :user_mock_data

def initialize(inquiry_id:, user_mock_data:, entity_class:)
super(user_mock_data:, entity_class:)
@user_mock_data = user_mock_data
@entity_class = entity_class
@inquiry_id = inquiry_id
end

def call
case fetch_data
when Array
fetch_data.map { |data| entity_class.new(data) }
else
fetch_data
end
end

private

def fetch_data
validate_input(inquiry_id, 'Invalid Inquiry ID')
if user_mock_data
data = File.read('modules/ask_va_api/config/locales/get_replies_mock_data.json')

Expand All @@ -29,18 +36,14 @@ def fetch_data
end
end

def validate_input(input, error_message)
raise ArgumentError, error_message if input.blank?
end

def filter_data(data)
data.select do |cor|
cor[:InquiryId] == inquiry_id
end
end

def handle_response_data(response)
response[:Data].presence || raise(CorrespondencesRetrieverError, response[:Message])
response[:Data].presence || response
end
end
end
Expand Down
16 changes: 9 additions & 7 deletions modules/ask_va_api/app/lib/ask_va_api/inquiries/retriever.rb
Expand Up @@ -38,11 +38,18 @@ def fetch_data(id = nil)
end

def fetch_correspondences(inquiry_id:)
Correspondences::Retriever.new(
correspondences = Correspondences::Retriever.new(
inquiry_id:,
user_mock_data:,
entity_class: AskVAApi::Correspondences::Entity
).call

case correspondences
when Hash
[]
else
correspondences
end
end

def read_mock_data(file_name)
Expand All @@ -57,12 +64,7 @@ def filter_data(data, id = nil)
end

def handle_response_data(response)
if response[:Data].nil?
error = JSON.parse(response[:body], symbolize_names: true)
raise InquiriesRetrieverError, error[:Message]
else
response[:Data]
end
response[:Data].presence || raise(InquiriesRetrieverError, response)
end
end
end
Expand Down
Expand Up @@ -18,15 +18,6 @@
end

describe '#call' do
context 'when id is blank' do
let(:inquiry_id) { nil }

it 'raises an ArgumentError' do
expect { retriever.call }
.to raise_error(ErrorHandler::ServiceError, 'ArgumentError: Invalid Inquiry ID')
end
end

context 'when Crm raise an error' do
let(:endpoint) { 'inquiries/1/replies' }
let(:response) do
Expand All @@ -42,8 +33,12 @@
allow(service).to receive(:call).and_return(response)
end

it 'raise CorrespondenceRetrieverError' do
expect { retriever.call }.to raise_error(ErrorHandler::ServiceError)
it 'returns the error' do
expect(retriever.call).to eq({ Data: [],
Message: 'Data Validation: No Inquiry Found',
ExceptionOccurred: true,
ExceptionMessage: 'Data Validation: No Inquiry Found',
MessageId: '2d746074-9e5c-4987-a894-e3f834b156b5' })
end
end

Expand Down
Expand Up @@ -164,6 +164,74 @@
end
end
end

context 'with Correspondences' do
let(:id) { '123' }
let(:response) do
{ Data: [{ Id: '154163f2-8fbb-ed11-9ac4-00155da17a6f',
InquiryNumber: 'A-20230305-306178',
InquiryStatus: 'Reopened',
SubmitterQuestion: 'test',
LastUpdate: '4/1/2024 12:00:00 AM',
InquiryHasAttachments: true,
InquiryHasBeenSplit: true,
VeteranRelationship: 'GIBillBeneficiary',
SchoolFacilityCode: '77a51029-6816-e611-9436-0050568d743d',
InquiryTopic: 'Medical Care Concerns at a VA Medical Facility',
InquiryLevelOfAuthentication: 'Unauthenticated',
AttachmentNames: [{ Id: '367e8d31-6c82-1d3c-81b8-dd2cabed7555',
Name: 'Test.txt' }] }] }
end

context 'when Correspondence::Retriever returns an error' do
before do
allow_any_instance_of(Crm::CrmToken).to receive(:call).and_return('Token')
allow(service).to receive(:call).and_return(response)
allow_any_instance_of(AskVAApi::Correspondences::Retriever).to receive(:call)
.and_return({ Data: [],
Message: 'Data Validation: No Inquiry Found',
ExceptionOccurred: true,
ExceptionMessage: 'Data Validation: No Inquiry Found',
MessageId: '2d746074-9e5c-4987-a894-e3f834b156b5' })
end

it 'returns correspondences as an empty array' do
inquiry = retriever.fetch_by_id(id:)

expect(inquiry.correspondences).to eq([])
end
end

context 'when Correspondence::Retriever returns a success' do
let(:cor_info) do
{
Id: 'f4b12ee3-93bb-ed11-9886-001dd806a6a7',
ModifiedOn: '3/5/2023 8:25:49 PM',
StatusReason: 'Sent',
Description: 'Dear aminul, Thank you for submitting your ' \
'Inquiry with the U.S. Department of Veteran Affairs.',
MessageType: 'Notification',
EnableReply: true,
AttachmentNames: nil
}
end

let(:correspondence) { AskVAApi::Correspondences::Entity.new(cor_info) }

before do
allow_any_instance_of(Crm::CrmToken).to receive(:call).and_return('Token')
allow(service).to receive(:call).and_return(response)
allow_any_instance_of(AskVAApi::Correspondences::Retriever).to receive(:call)
.and_return([correspondence])
end

it 'returns correspondences as an empty array' do
inquiry = retriever.fetch_by_id(id:)

expect(inquiry.correspondences).to eq([correspondence])
end
end
end
end
end
end
6 changes: 5 additions & 1 deletion modules/ask_va_api/spec/requests/v0/inquiries_spec.rb
Expand Up @@ -234,7 +234,11 @@

it_behaves_like 'common error handling', :unprocessable_entity, 'service_error',
'AskVAApi::Inquiries::InquiriesRetrieverError: ' \
'Data Validation: No Inquiries found by ID A-20240423-30709'
'{:status=>400, :body=>"{\"Data\":null,\"Message\":\"Data Validation: ' \
'No Inquiries found by ID A-20240423-30709\",\"ExceptionOccurred\":' \
'true,\"ExceptionMessage\":\"Data Validation: No Inquiries found by ID ' \
'A-20240423-30709\",\"MessageId\":\"ca5b990a-63fe-407d-a364-46caffce12c1\"}",' \
' :response_headers=>nil, :url=>nil}'
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion modules/ask_va_api/spec/services/crm/crm_token_spec.rb
Expand Up @@ -30,7 +30,7 @@ def mock_response(status:, body:)
end
end

context 'with invalid JSON' do
context 'when veis auth service returns a 401 error response' do
let(:resp) { mock_response(body: { error: 'invalid_client' }, status: 401) }
let(:exception) { Common::Exceptions::BackendServiceException.new(nil, {}, resp.status, resp.body) }

Expand Down
46 changes: 1 addition & 45 deletions modules/ask_va_api/spec/services/crm/service_spec.rb
Expand Up @@ -5,29 +5,14 @@
RSpec.describe Crm::Service do
let(:service) { described_class.new(icn: '123') }

# Helper method to create a mock response
def mock_response(status:, body:)
instance_double(Faraday::Response, status:, body: body.to_json)
end

# Shared examples for error handling
shared_examples 'error handling' do |status, message|
let(:body) { 'Sample error message' }

it "returns a formatted message for status #{status}" do
response = mock_response(status:, body:)
expected_error_message = "#{message} to #{endpoint}: \"#{body}\""

expect do
Crm::ErrorHandler.handle(endpoint, response)
end.to raise_error(Crm::ErrorHandler::ServiceError, expected_error_message)
end
end

describe '#call' do
let(:endpoint) { 'inquiries' }

context 'server response' do
context 'when server response successful' do
context 'with valid JSON' do
let(:response) do
mock_response(
Expand Down Expand Up @@ -64,35 +49,6 @@ def mock_response(status:, body:)
end
end

describe 'error message formatting' do
context 'when response is nil' do
it 'returns a message indicating no response was received' do
expect do
Crm::ErrorHandler.handle(endpoint,
nil)
end.to raise_error(Crm::ErrorHandler::ServiceError, "Server Error to #{endpoint}: ")
end
end

context 'with specific response status codes' do
include_examples 'error handling', 400, 'Bad request'
include_examples 'error handling', 401, 'Unauthorized'
include_examples 'error handling', 403, 'Forbidden: You do not have permission to access'
include_examples 'error handling', 404, 'Resource not found'
end

context 'with unspecified response status codes' do
let(:body) { 'General error message' }

it 'returns a generic error message' do
response = mock_response(status: 418, body:)
expect do
Crm::ErrorHandler.handle(endpoint, response)
end.to raise_error(Crm::ErrorHandler::ServiceError, "Service Error to #{endpoint}: \"#{body}\"")
end
end
end

context 'when the server returns an error' do
let(:resp) { mock_response(body: { error: 'server error' }, status: 500) }
let(:exception) { Common::Exceptions::BackendServiceException.new(nil, {}, resp.status, resp.body) }
Expand Down

0 comments on commit 15552a8

Please sign in to comment.