Skip to content

Commit

Permalink
[Automated] Merged master into target preview_envs_k8s
Browse files Browse the repository at this point in the history
  • Loading branch information
va-vsp-bot authored Apr 5, 2024
2 parents 786b040 + 85af796 commit dafe6e1
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 4 deletions.
64 changes: 61 additions & 3 deletions modules/vaos/app/controllers/vaos/v2/appointments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,7 @@ def merge_clinics(appointments)
def merge_facilities(appointments)
appointments.each do |appt|
appt[:location] = get_facility_memoized(appt[:location_id]) unless appt[:location_id].nil?
if cerner?(appt) && appt[:location].is_a?(Hash) && appt[:location]&.values&.any? do |v|
v.include?('COL OR 1')
end
if cerner?(appt) && contains_substring(extract_all_values(appt[:location]), 'COL OR 1')
log_appt_id_location_name(appt)
end
end
Expand Down Expand Up @@ -310,6 +308,66 @@ def get_facility_memoized(location_id)
end
memoize :get_facility_memoized

# This method extracts all values from a given object, which can be either an `OpenStruct`, `Hash`, or `Array`.
# It recursively traverses the object and collects all values into an array.
# In case of an `Array`, it looks inside each element of the array for values.
# If the object is neither an OpenStruct, Hash, nor an Array, it returns the unmodified object in an array.
#
# @param object [OpenStruct, Hash, Array] The object from which to extract values.
# This could either be an OpenStruct, Hash or Array.
#
# @return [Array] An array of all values found in the object.
# If the object is not an OpenStruct, Hash, nor an Array, then the unmodified object is returned.
#
# @example
# extract_all_values({a: 1, b: 2, c: {d: 3, e: 4}}) # => [1, 2, 3, 4]
# extract_all_values(OpenStruct.new(a: 1, b: 2, c: OpenStruct.new(d: 3, e: 4))) # => [1, 2, 3, 4]
# extract_all_values([{a: 1}, {b: 2}]) # => [1, 2]
# extract_all_values({a: 1, b: [{c: 2}, {d: "hello"}]}) # => [1, 2, "hello"]
# extract_all_values("not a hash, openstruct, or array") # => ["not a hash, openstruct, or array"]
#
def extract_all_values(object)
return [object] unless object.is_a?(OpenStruct) || object.is_a?(Hash) || object.is_a?(Array)

values = []
object = object.to_h if object.is_a?(OpenStruct)

if object.is_a?(Array)
object.each do |o|
values += extract_all_values(o)
end
else
object.each_pair do |_, value|
case value
when OpenStruct, Hash, Array then values += extract_all_values(value)
else values << value
end
end
end

values
end

# This method checks if any string element in the given array contains the specified substring.
#
# @param arr [Array] The array to be searched.
# @param substring [String] The substring to look for.
#
# @return [Boolean] Returns true if any string element in the array contains the substring, false otherwise.
# If the input parameters are not of the correct type the method will return false.
#
# @example
# contains_substring(['Hello', 'World'], 'ell') # => true
# contains_substring(['Hello', 'World'], 'xyz') # => false
# contains_substring('Hello', 'ell') # => false
# contains_substring(['Hello', 'World'], 123) # => false
#
def contains_substring(arr, substring)
return false unless arr.is_a?(Array) && substring.is_a?(String)

arr.any? { |element| element.is_a?(String) && element.include?(substring) }
end

def scrape_appt_comments_and_log_details(appt, appt_method, comment_key)
if appt&.[](:reason)&.include? comment_key
log_appt_comment_data(appt, appt_method, appt&.[](:reason), comment_key, REASON)
Expand Down
139 changes: 138 additions & 1 deletion modules/vaos/spec/request/v2/appointments_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,54 @@
}
}

mock_appt_location_openstruct = OpenStruct.new(
{
'id': '983',
'vistaSite': '983',
'vastParent': '983',
'type': 'va_facilities',
'name': 'COL OR 1',
'classification': 'VA Medical Center (VAMC)',
'lat': 39.744507,
'long': -104.830956,
'website': 'https://www.denver.va.gov/locations/directions.asp',
'phone': {
'main': '307-778-7550',
'fax': '307-778-7381',
'pharmacy': '866-420-6337',
'afterHours': '307-778-7550',
'patientAdvocate': '307-778-7550 x7517',
'mentalHealthClinic': '307-778-7349',
'enrollmentCoordinator': '307-778-7550 x7579'
},
'physicalAddress': {
'type': 'physical',
'line': ['2360 East Pershing Boulevard'],
'city': 'Cheyenne',
'state': 'WY',
'postalCode': '82001-5356'
},
'mobile': false,
'healthService': %w[Audiology Cardiology DentalServices EmergencyCare Gastroenterology
Gynecology MentalHealthCare Nutrition Ophthalmology Optometry Orthopedics
Podiatry PrimaryCare SpecialtyCare UrgentCare Urology WomensHealth],
'operatingStatus': {
'code': 'NORMAL'
}
}
)

mock_appt_location_extracted_values = ['983', '983', '983', 'va_facilities', 'COL OR 1', 'VA Medical Center (VAMC)',
39.744507, -104.830956, 'https://www.denver.va.gov/locations/directions.asp',
'307-778-7550', '307-778-7381', '866-420-6337', '307-778-7550',
'307-778-7550 x7517', '307-778-7349', '307-778-7550 x7579',
'physical', '2360 East Pershing Boulevard', 'Cheyenne', 'WY',
'82001-5356', false, 'Audiology', 'Cardiology', 'DentalServices',
'EmergencyCare', 'Gastroenterology', 'Gynecology', 'MentalHealthCare',
'Nutrition', 'Ophthalmology', 'Optometry', 'Orthopedics',
'Podiatry', 'PrimaryCare', 'SpecialtyCare',
'UrgentCare', 'Urology', 'WomensHealth', 'NORMAL']

before do
Flipper.enable('va_online_scheduling')
sign_in_as(current_user)
Expand Down Expand Up @@ -194,12 +242,17 @@
VCR.use_cassette('vaos/v2/appointments/get_appointments_200_booked_cerner_with_color1_location',
match_requests_on: %i[method path query], allow_playback_repeats: true) do
allow(Rails.logger).to receive(:info).at_least(:once)
allow_any_instance_of(VAOS::V2::AppointmentsController).to receive(
:get_facility_memoized
).and_return(mock_appt_location_openstruct)
get '/vaos/v2/appointments?_include=facilities,clinics', params:, headers: inflection_header
data = JSON.parse(response.body)['data']
expect(response).to have_http_status(:ok)
expect(response.body).to be_a(String)
expect(data.size).to eq(2)
expect(data[0]['attributes']['location']).to eq(mock_facility)
expect(data[0]['attributes']['location']['attributes'].to_json).to eq(
mock_appt_location_openstruct.table.to_json
)
expect(Rails.logger).to have_received(:info).with("Details for Cerner 'COL OR 1' Appointment",
any_args).at_least(:once)
expect(response).to match_camelized_response_schema('vaos/v2/appointments', { strict: false })
Expand Down Expand Up @@ -598,5 +651,89 @@
end
end
end

describe 'extract_all_values' do
context 'when processing an array, hash, or openstruct' do
let(:array1) { ['a', 'b', 'c', %w[100 200 300]] }

let(:hash1) { { a: '100', b: '200', c: '300' } }

let(:os1) do
OpenStruct.new({ 'a' => '100', 'b' => '200', 'c' => '300', 'd' => 400 })
end

it 'returns an array of values from an array' do
expect(subject.send(:extract_all_values, array1)).to eq(%w[a b c 100 200 300])
end

it 'returns an array of values from a hash' do
expect(subject.send(:extract_all_values, hash1)).to eq(%w[100 200 300])
end

it 'returns an array of values from a simple openstruct' do
expect(subject.send(:extract_all_values, os1)).to eq(['100', '200', '300', 400])
end

it 'returns an array of values from a nested openstruct' do
expect(subject.send(:extract_all_values,
mock_appt_location_openstruct)).to eq(mock_appt_location_extracted_values)
end
end

context 'when processing input that is not an array, hash, or openstruct' do
it 'returns input object in an array' do
expect(subject.send(:extract_all_values, 'Simple String Input')).to eq(['Simple String Input'])
end

it 'returns input object in an array (nil)' do
expect(subject.send(:extract_all_values, nil)).to eq([nil])
end
end
end

describe 'contains_substring' do
context 'when checking an input array that contains a given substring' do
it 'returns true' do
expect(subject.send(:contains_substring, ['given string', 'another string', 100], 'given string')).to be(true)
end
end

context 'when checking an input array that does not contain a given substring' do
it 'returns false' do
expect(subject.send(:contains_substring, ['given string', 'another string', 100],
'different string')).to be(false)
end
end

context 'when checking a non-array and a string' do
it 'returns false' do
expect(subject.send(:contains_substring, 'given string', 'given string')).to be(false)
end
end

context 'when checking nil and a string' do
it 'returns false' do
expect(subject.send(:contains_substring, nil, 'some string')).to be(false)
end
end

context 'when checking an array and a non-string' do
it 'returns false' do
expect(subject.send(:contains_substring, ['given string', 'another string', 100], 100)).to be(false)
end
end

context 'when the input array contains nil' do
it 'returns false' do
expect(subject.send(:contains_substring, [nil], 'some string')).to be(false)
end
end

context 'when the input array is empty' do
it 'returns false' do
expect(subject.send(:contains_substring, [], 'some string')).to be(false)
end
end
end
end
end

0 comments on commit dafe6e1

Please sign in to comment.