Skip to content

Commit

Permalink
add expense client and service + tests (#18728)
Browse files Browse the repository at this point in the history
  • Loading branch information
liztownd authored Oct 4, 2024
1 parent ae6c512 commit 56f3840
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
47 changes: 47 additions & 0 deletions modules/travel_pay/app/services/travel_pay/expenses_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

require 'securerandom'
require_relative './base_client'

module TravelPay
class ExpensesClient < TravelPay::BaseClient
##
# HTTP POST call to the BTSSS 'expenses' endpoint to add a new mileage expense
# API responds with an expenseId
#
# @external API params {
# "claimId": "string", // uuid of the claim to attach the expense to
# "dateIncurred": "2024-10-02T14:36:38.043Z", // This is the appointment date-time
# "description": "string", // ?? Not sure what this is or if it is required
# "tripType": "string" // Enum: [ OneWay, RoundTrip, Unspecified ]
# }
#
# @params {
# 'claim_id' => 'string'
# 'appt_date' => 'string'
# 'trip_type' => 'OneWay' | 'RoundTrip' | 'Unspecified'
# 'description' => 'string'
# }
#
# @return expenseId => string
#
def add_mileage_expense(veis_token, btsss_token, params = {})
btsss_url = Settings.travel_pay.base_url
correlation_id = SecureRandom.uuid
Rails.logger.debug(message: 'Correlation ID', correlation_id:)

connection(server_url: btsss_url).post('api/v1.1/expenses/mileage') do |req|
req.headers['Authorization'] = "Bearer #{veis_token}"
req.headers['BTSSS-Access-Token'] = btsss_token
req.headers['X-Correlation-ID'] = correlation_id
req.headers.merge!(claim_headers)
req.body = {
'claimId' => params['claim_id'],
'dateIncurred' => params['appt_date'],
'tripType' => params['trip_type'] || 'RoundTrip', # default to Round Trip if not specified
'description' => params['description'] || 'mileage' # this is required, default to mileage
}.to_json
end
end
end
end
23 changes: 23 additions & 0 deletions modules/travel_pay/app/services/travel_pay/expenses_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module TravelPay
class ExpensesService
def add_expense(veis_token, btsss_token, params = {})
# check for required params (that don't have a default set in the client)
unless params['claim_id'] && params['appt_date']
raise ArgumentError,
message: 'You must provide a claim ID and appointment date to add an expense.'
end

new_expense_response = client.add_mileage_expense(veis_token, btsss_token, params)

new_expense_response.body
end

private

def client
TravelPay::ExpensesClient.new
end
end
end
53 changes: 53 additions & 0 deletions modules/travel_pay/spec/services/expenses_client_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true

require 'rails_helper'

describe TravelPay::ExpensesClient do
let(:user) { build(:user) }

before do
@stubs = Faraday::Adapter::Test::Stubs.new

conn = Faraday.new do |c|
c.adapter(:test, @stubs)
c.response :json
c.request :json
end

allow_any_instance_of(TravelPay::ExpensesClient).to receive(:connection).and_return(conn)
end

context '/expenses/mileage' do
before do
allow_any_instance_of(TravelPay::TokenService)
.to receive(:get_tokens)
.and_return('veis_token', 'btsss_token')
end

# POST add_expense
it 'returns an expenseId from the /expenses/mileage endpoint' do
expense_id = '3fa85f64-5717-4562-b3fc-2c963f66afa6'
@stubs.post('/api/v1.1/expenses/mileage') do
[
200,
{},
{
'data' =>
{
'expenseId' => expense_id
}
}
]
end

client = TravelPay::ExpensesClient.new
new_expense_response = client.add_mileage_expense('veis_token', 'btsss_token',
{ 'claimId' => 'fake_claim_id',
'dateIncurred' => '2024-10-02T14:36:38.043Z',
'tripType' => 'RoundTrip' }.to_json)
actual_expense_id = new_expense_response.body['data']['expenseId']

expect(actual_expense_id).to eq(expense_id)
end
end
end
77 changes: 77 additions & 0 deletions modules/travel_pay/spec/services/expenses_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# frozen_string_literal: true

require 'rails_helper'
require 'securerandom'

describe TravelPay::ExpensesService do
context 'add_expense' do
let(:user) { build(:user) }
let(:add_expense_data) do
{
'data' =>
{
'expenseId' => '3fa85f64-5717-4562-b3fc-2c963f66afa6'
}
}
end
let(:add_expense_response) do
Faraday::Response.new(
body: add_expense_data
)
end

let(:tokens) { %w[veis_token btsss_token] }

context 'add new expense' do
it 'returns an expense ID when passed a valid claim id and appointment date' do
params = { 'claim_id' => '73611905-71bf-46ed-b1ec-e790593b8565',
'appt_date' => '2024-10-02T14:36:38.043Z',
'trip_type' => 'RoundTrip',
'description' => 'this is my description' }

allow_any_instance_of(TravelPay::ExpensesClient)
.to receive(:add_mileage_expense)
.with(*tokens, params)
.and_return(add_expense_response)

service = TravelPay::ExpensesService.new
actual_new_expense_response = service.add_expense(*tokens, params)

expect(actual_new_expense_response['data']).to equal(add_expense_data['data'])
end

it 'succeeds and returns an expense ID when trip type is not specified' do
params = { 'claim_id' => '73611905-71bf-46ed-b1ec-e790593b8565',
'appt_date' => '2024-10-02T14:36:38.043Z' }

allow_any_instance_of(TravelPay::ExpensesClient)
.to receive(:add_mileage_expense)
.with(*tokens, params)
.and_return(add_expense_response)

service = TravelPay::ExpensesService.new
actual_new_expense_response = service.add_expense(*tokens, params)

expect(actual_new_expense_response['data']).to equal(add_expense_data['data'])
end

it 'throws an ArgumentException if not passed the right params' do
service = TravelPay::ExpensesService.new

expect do
service.add_expense(*tokens, { 'claim_id' => nil,
'appt_date' => '2024-10-02T14:36:38.043Z',
'trip_type' => 'OneWay' })
end
.to raise_error(ArgumentError, /You must provide/i)

expect do
service.add_expense(*tokens, { 'claim_id' => '73611905-71bf-46ed-b1ec-e790593b8565',
'appt_date' => nil,
'trip_type' => 'RoundTrip' })
end
.to raise_error(ArgumentError, /You must provide/i)
end
end
end
end

0 comments on commit 56f3840

Please sign in to comment.