Skip to content

Commit

Permalink
reorganization of spec tests and changes to checking parameter for pr…
Browse files Browse the repository at this point in the history
…imitive
  • Loading branch information
360dgries committed Oct 6, 2023
1 parent ac8a754 commit d77c0bf
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 37 deletions.
17 changes: 8 additions & 9 deletions lib/inferno/dsl/fhir_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,13 @@ def fhir_clients
@fhir_clients ||= {}
end

# Checks if a parameter can be used in a GET request according FHIR specification
# Wrapper for checking if parameter contents are primitive
#
# @param param [FHIR::Parameters::Parameter] Parameter to be checked
# @private
def safe_for_get?(param)
valid = param.valid? && param.part.empty? && param.resource.nil? # Parameter is valid
param_val = param.to_hash.except('name') # should contain only one value if it is a valid parameter
valid && !param_val.empty? && FHIR.primitive?(datatype: param_val.keys[0][5..], value: param_val.values[0])
def primitive_parameter?(param)
param_val = param.to_hash.except('name')
param_val.any? { |datatype, param_value| FHIR.primitive?(datatype: datatype[5..], value: param_value) }
end

# Converts a list of FHIR Parameters into a query string for GET requests
Expand All @@ -76,10 +75,9 @@ def safe_for_get?(param)
# @private
def body_to_path(body)
query_hashes = body.parameter.map do |param|
if safe_for_get?(param)
if primitive_parameter?(param)
{ param.name => param.to_hash.except('name').values[0] }
else
# Handle the case of nonprimitive
Inferno::Application[:logger].error "Cannot use GET request with non-primitive datatype #{param.name}"
raise ArgumentError, "Cannot use GET request with non-primitive datatype #{param.name}"
end
Expand All @@ -91,9 +89,11 @@ def body_to_path(body)
#
# @note This is a placeholder method until the FHIR::Client supports
# general operations. Note that while both POST and GET methods are allowed,
# GET is only allowed when the operation does not affect the servers state.
# GET is only allowed when the operation does not affect the server's state.
# See https://build.fhir.org/operationdefinition-definitions.html#OperationDefinition.affectsState
#
# @note Currently does not allow for repeated parameters if using GET
#
# @param path [String]
# @param body [FHIR::Parameters] Must all be primitive if making GET request
# @param client [Symbol]
Expand All @@ -115,7 +115,6 @@ def fhir_operation(path, body: nil, client: :default, name: nil, headers: {}, op
path = "#{path}?#{body_to_path(body)}" if body.present?
fhir_client(client).send(:get, path, operation_headers)
else
# Handle the case of non-supported operation_method
Inferno::Application[:logger].error "Cannot perform #{operation_method} requests, use GET or POST"
raise ArgumentError, "Cannot perform #{operation_method} requests, use GET or POST"
end
Expand Down
79 changes: 51 additions & 28 deletions spec/inferno/dsl/fhir_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,43 +135,43 @@ def test_session_id
end
end

describe '#safe_for_get?' do
it 'returns true when given a primitive parameter' do
expect(group.safe_for_get?(boolean_parameter)).to be true
end

it 'returns false when given a resource parameter' do
expect(group.safe_for_get?(resource_parameter)).to be false
end

it 'returns false when given a complex parameter' do
expect(group.safe_for_get?(ratio_parameter)).to be false
end
describe '#primitive_parameter?' do
# it 'returns true when given a primitive parameter' do
# expect(group.primitive_parameter?(boolean_parameter)).to be true
# end

# it 'returns false when given a resource parameter' do
# expect(group.primitive_parameter?(resource_parameter)).to be false
# end

# it 'returns false when given a complex parameter' do
# expect(group.primitive_parameter?(ratio_parameter)).to be false
# end
end

describe '#body_to_path' do
it 'converts primitives into a path query' do
expect(group.body_to_path(body_with_two_primitives)).to eq({ PARAM_BOOL: true, PARAM_STRING: 'STRING' }.to_query)
end
# it 'converts primitives into a path query' do
# expect(group.body_to_path(body_with_two_primitives)).to eq({ PARAM_BOOL: true, PARAM_STRING: 'STRING' }.to_query)
# end

it 'handles repeated parameters' do
expected_body = [{ PARAM_BOOL: true }, { PARAM_BOOL: false }].map(&:to_query).join('&')
expect(group.body_to_path(body_with_repeated_parameters)).to eq(expected_body)
end

it 'raises error if non-primitive parameter found' do
body = body_with_nonprimitive
expect do
group.body_to_path(body)
end.to raise_error(ArgumentError, 'Cannot use GET request with non-primitive datatype PARAM_RATIO')
end
# it 'raises error if non-primitive parameter found' do
# body = body_with_nonprimitive
# expect do
# group.body_to_path(body)
# end.to raise_error(ArgumentError, 'Cannot use GET request with non-primitive datatype PARAM_RATIO')
# end

it 'raises error if parameter is resource' do
body = body_with_resource
expect do
group.body_to_path(body)
end.to raise_error(ArgumentError, 'Cannot use GET request with non-primitive datatype PARAM_RESOURCE')
end
# it 'raises error if parameter is resource' do
# body = body_with_resource
# expect do
# group.body_to_path(body)
# end.to raise_error(ArgumentError, 'Cannot use GET request with non-primitive datatype PARAM_RESOURCE')
# end
end

describe '#fhir_operation' do
Expand Down Expand Up @@ -216,7 +216,7 @@ def test_session_id
end

context 'with a body of parameters' do
it 'uses get when all parameters are primitive' do
it 'uses get when all parameters are primitive and GET specified' do
body = body_with_two_primitives
get_with_body_request_stub =
stub_request(:get, "#{base_url}/#{path}")
Expand All @@ -228,12 +228,35 @@ def test_session_id
expect(get_with_body_request_stub).to have_been_made.once
end

# This test left for testing DoD of FI-2223
# https://oncprojectracking.healthit.gov/support/browse/FI-2223
#
# it 'correctly handles repeated parameters' do
# body = body_with_repeated_parameters
# get_with_body_request_stub =
# stub_request(:get, "#{base_url}/#{path}")
# .with(body: URI.encode_www_form({PARAM_BOOL: [true, false]}))
# .to_return(status: 200, body: resource.to_json)
# puts get_with_body_request_stub.to_s

# group.fhir_operation(path, body:, operation_method: :get)

# expect(get_with_body_request_stub).to have_been_made.once
# end

it 'prevents get when parameters are non-primitive' do
body = body_with_nonprimitive
expect do
group.fhir_operation(path, body:, operation_method: :get)
end.to raise_error(ArgumentError, 'Cannot use GET request with non-primitive datatype PARAM_RATIO')
end

it 'prevents get when parameters contain resources' do
body = body_with_resource
expect do
group.fhir_operation(path, body:, operation_method: :get)
end.to raise_error(ArgumentError, 'Cannot use GET request with non-primitive datatype PARAM_RESOURCE')
end
end

context 'with the client parameter' do
Expand Down

0 comments on commit d77c0bf

Please sign in to comment.