Skip to content

Commit

Permalink
96414 add EPS submit appointment method (#19973)
Browse files Browse the repository at this point in the history
  • Loading branch information
randomsync authored Dec 23, 2024
1 parent d41676b commit 01d25d0
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 18 deletions.
46 changes: 46 additions & 0 deletions modules/vaos/app/services/eps/appointment_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,51 @@ def create_draft_appointment(referral_id:)
{ patientId: patient_id, referralId: referral_id }, headers)
OpenStruct.new(response.body)
end

##
# Submit an appointment to EPS for booking
#
# @param appointment_id [String] The ID of the appointment to submit
# @param params [Hash] Hash containing required and optional parameters
# @option params [String] :network_id The network ID for the appointment
# @option params [String] :provider_service_id The provider service ID
# @option params [Array<String>] :slot_ids Array of slot IDs for the appointment
# @option params [String] :referral_number The referral number
# @option params [Hash] :additional_patient_attributes Optional patient details (address, contact info)
# @raise [ArgumentError] If any required parameters are missing
# @return OpenStruct response from EPS submit appointment endpoint
#
def submit_appointment(appointment_id, params = {})
raise ArgumentError, 'appointment_id is required and cannot be blank' if appointment_id.blank?

required_params = %i[network_id provider_service_id slot_ids referral_number]
missing_params = required_params - params.keys

raise ArgumentError, "Missing required parameters: #{missing_params.join(', ')}" if missing_params.any?

payload = build_submit_payload(params)

response = perform(:post, "/#{config.base_path}/appointments/#{appointment_id}/submit", payload, headers)
OpenStruct.new(response.body)
end

private

def build_submit_payload(params)
payload = {
networkId: params[:network_id],
providerServiceId: params[:provider_service_id],
slotIds: params[:slot_ids],
referral: {
referralNumber: params[:referral_number]
}
}

if params[:additional_patient_attributes]
payload[:additionalPatientAttributes] = params[:additional_patient_attributes]
end

payload
end
end
end
147 changes: 129 additions & 18 deletions modules/vaos/spec/services/eps/appointment_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,31 @@
describe Eps::AppointmentService do
subject(:service) { described_class.new(user) }

let(:icn) { '123ICN' }
let(:user) { double('User', account_uuid: '1234', icn:) }
let(:successful_appt_response) do
double('Response', status: 200, body: { 'count' => 1,
'appointments' => [
{
'id' => 'test-id',
'state' => 'booked',
'patientId' => icn
}
] })
end
let(:referral_id) { 'test-referral-id' }
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
let(:config) { instance_double(Eps::Configuration) }
let(:headers) { { 'Authorization' => 'Bearer token123' } }

let(:appointment_id) { 'appointment-123' }
let(:icn) { '123ICN' }

before do
allow(Rails.cache).to receive(:fetch).and_return(memory_store)
Rails.cache.clear
allow(config).to receive(:base_path).and_return('api/v1')
allow_any_instance_of(Eps::BaseService).to receive_messages(config: config, headers: headers)
end

describe 'get_appointments' do
context 'when requesting appointments for a logged in user' do
let(:successful_appt_response) do
double('Response', status: 200, body: { 'count' => 1,
'appointments' => [
{
'id' => appointment_id,
'state' => 'booked',
'patientId' => icn
}
] })
end

before do
allow_any_instance_of(VAOS::SessionService).to receive(:perform).and_return(successful_appt_response)
end
Expand Down Expand Up @@ -59,10 +62,11 @@
end

describe 'create_draft_appointment' do
let(:referral_id) { 'test-referral-id' }
let(:successful_draft_appt_response) do
double('Response', status: 200, body: { 'id' => icn,
double('Response', status: 200, body: { 'id' => appointment_id,
'state' => 'draft',
'patientId' => 'test-patient-id' })
'patientId' => icn })
end

context 'when creating draft appointment for a given referral_id' do
Expand All @@ -77,7 +81,7 @@
end
end

context 'when the endpoint fails to return appointments' do
context 'when the endpoint fails' do
let(:failed_response) do
double('Response', status: 500, body: 'Unknown service exception')
end
Expand All @@ -98,4 +102,111 @@
end
end
end

describe '#submit_appointment' do
let(:valid_params) do
{
network_id: 'network-123',
provider_service_id: 'provider-456',
slot_ids: ['slot-789'],
referral_number: 'REF-001'
}
end

context 'with valid parameters' do
let(:successful_response) do
double('Response', status: 200, body: { 'id' => appointment_id,
'state' => 'draft',
'patientId' => icn })
end

it 'submits the appointment successfully' do
expected_payload = {
networkId: valid_params[:network_id],
providerServiceId: valid_params[:provider_service_id],
slotIds: valid_params[:slot_ids],
referral: {
referralNumber: valid_params[:referral_number]
}
}

expect_any_instance_of(VAOS::SessionService).to receive(:perform)
.with(:post, "/#{config.base_path}/appointments/#{appointment_id}/submit", expected_payload, kind_of(Hash))
.and_return(successful_response)

exp_response = OpenStruct.new(successful_response.body)

expect(service.submit_appointment(appointment_id, valid_params)).to eq(exp_response)
end

it 'includes additional patient attributes when provided' do
patient_attributes = { name: 'John Doe', email: '[email protected]' }
params_with_attributes = valid_params.merge(additional_patient_attributes: patient_attributes)

expected_payload = {
networkId: valid_params[:network_id],
providerServiceId: valid_params[:provider_service_id],
slotIds: valid_params[:slot_ids],
referral: {
referralNumber: valid_params[:referral_number]
},
additionalPatientAttributes: patient_attributes
}

expect_any_instance_of(VAOS::SessionService).to receive(:perform)
.with(:post, "/#{config.base_path}/appointments/#{appointment_id}/submit", expected_payload, kind_of(Hash))
.and_return(successful_response)

service.submit_appointment(appointment_id, params_with_attributes)
end
end

context 'with invalid parameters' do
it 'raises ArgumentError when appointment_id is nil' do
expect { service.submit_appointment(nil, valid_params) }
.to raise_error(ArgumentError, 'appointment_id is required and cannot be blank')
end

it 'raises ArgumentError when appointment_id is empty' do
expect { service.submit_appointment('', valid_params) }
.to raise_error(ArgumentError, 'appointment_id is required and cannot be blank')
end

it 'raises ArgumentError when appointment_id is blank' do
expect { service.submit_appointment(' ', valid_params) }
.to raise_error(ArgumentError, 'appointment_id is required and cannot be blank')
end

it 'raises ArgumentError when required parameters are missing' do
invalid_params = valid_params.except(:network_id)

expect { service.submit_appointment(appointment_id, invalid_params) }
.to raise_error(ArgumentError, /Missing required parameters: network_id/)
end

it 'raises ArgumentError when multiple required parameters are missing' do
invalid_params = valid_params.except(:network_id, :provider_service_id)

expect { service.submit_appointment(appointment_id, invalid_params) }
.to raise_error(ArgumentError, /Missing required parameters: network_id, provider_service_id/)
end
end

context 'when API returns an error' do
let(:response) { double('Response', status: 500, body: 'Unknown service exception') }
let(:exception) do
Common::Exceptions::BackendServiceException.new(nil, {}, response.status, response.body)
end

before do
allow_any_instance_of(VAOS::SessionService).to receive(:perform).and_raise(exception)
end

it 'returns the error response' do
expect do
service.submit_appointment(appointment_id, valid_params)
end.to raise_error(Common::Exceptions::BackendServiceException, /VA900/)
end
end
end
end

0 comments on commit 01d25d0

Please sign in to comment.