davinci_pdex_test_kit 0.10.6 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/presets/pdex_payer_client_postman_preset.json +12 -0
- data/config/presets/pdex_payer_server_fhir_foundry_ri_preset.json +96 -0
- data/config/presets/pdex_payer_server_inferno_ri_preset.json +96 -0
- data/lib/davinci_pdex_test_kit/docs/davinci_pdex_test_kit_description_v200.md +33 -0
- data/lib/davinci_pdex_test_kit/docs/payer_client_suite_description_v200.md +107 -17
- data/lib/davinci_pdex_test_kit/fhir_resource_navigation.rb +5 -1
- data/lib/davinci_pdex_test_kit/group_metadata.rb +5 -1
- data/lib/davinci_pdex_test_kit/igs/davinci-pdex-2.0.0.tgz +0 -0
- data/lib/davinci_pdex_test_kit/igs/us-core-3.1.1.tgz +0 -0
- data/lib/davinci_pdex_test_kit/metadata.rb +16 -0
- data/lib/davinci_pdex_test_kit/must_support_test.rb +3 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_validation_test.rb +20 -18
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_validation_test.rb +96 -43
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_workflow_interaction_test.rb +49 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/allergyintolerance_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careplan_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careteam_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/clinical_data_request_check_test.rb +24 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/condition_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/device_clinical_data_request_test.rb +19 -17
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/diagnosticreport_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/documentreference_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/encounter_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/explanationofbenefit_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/goal_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/immunization_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/location_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationdispense_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationrequest_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/observation_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/organization_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/patient_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/patient_id_search_request_check_test.rb +21 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitioner_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitionerrole_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/procedure_clinical_data_request_test.rb +18 -16
- data/lib/davinci_pdex_test_kit/pdex_payer_client/collection.rb +46 -44
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/binary_endpoint.rb +26 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/export_endpoint.rb +29 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/export_status_endpoint.rb +38 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/member_match_endpoint.rb +51 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/next_page_endpoint.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/patient_endpoint.rb +25 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/patient_everything_endpoint.rb +34 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/proxy_endpoint.rb +178 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/resource_read_endpoint.rb +21 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/resource_search_endpoint.rb +22 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/token_endpoint.rb +27 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server.rb +53 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/tags.rb +15 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/urls.rb +51 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client_suite.rb +101 -144
- data/lib/davinci_pdex_test_kit/pdex_payer_server/coverage_to_link_minimal_data_validation.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_server/coverage_to_link_must_support_validation.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_id_search_test.rb +5 -4
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_identifier_search_test.rb +5 -4
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_must_support_test.rb +3 -2
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_last_updated_search_test.rb +7 -6
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_service_date_search_test.rb +7 -6
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_type_search_test.rb +7 -6
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_use_search_test.rb +6 -5
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_provenance_revinclude_search_test.rb +10 -7
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_read_test.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_reference_resolution_test.rb +3 -2
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_validation_test.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/metadata.yml +12 -12
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit_group.rb +12 -14
- data/lib/davinci_pdex_test_kit/pdex_payer_server/export_patient_group.rb +3 -4
- data/lib/davinci_pdex_test_kit/pdex_payer_server/export_validation_group.rb +2 -6
- data/lib/davinci_pdex_test_kit/pdex_payer_server/member_match_request_local_references_validation.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_server/member_match_request_profile_validation.rb +1 -3
- data/lib/davinci_pdex_test_kit/pdex_payer_server/multiple_member_matches_group.rb +7 -8
- data/lib/davinci_pdex_test_kit/pdex_payer_server/no_member_matches_group.rb +7 -8
- data/lib/davinci_pdex_test_kit/pdex_payer_server/patient_operation_in_capability_statement_validation.rb +1 -3
- data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_clinical_data_group.rb +3 -5
- data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_everything_group.rb +2 -4
- data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_export_group.rb +2 -4
- data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_member_match_group.rb +12 -13
- data/lib/davinci_pdex_test_kit/pdex_payer_server_suite.rb +13 -14
- data/lib/davinci_pdex_test_kit/version.rb +2 -3
- data/lib/davinci_pdex_test_kit.rb +1 -2
- metadata +65 -24
- data/lib/davinci_pdex_test_kit/ext/inferno_core/record_response_route.rb +0 -98
- data/lib/davinci_pdex_test_kit/ext/inferno_core/request.rb +0 -19
- data/lib/davinci_pdex_test_kit/ext/inferno_core/runnable.rb +0 -18
- data/lib/davinci_pdex_test_kit/mock_server.rb +0 -281
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_submit_test.rb +0 -24
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/client_member_match_must_support_submit_test.rb +0 -26
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/client_member_match_must_support_validation_test.rb +0 -32
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/metadata.yml +0 -61
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/initial_scratch_storing.rb +0 -32
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/initial_wait_test.rb +0 -31
- data/lib/davinci_pdex_test_kit/tags.rb +0 -11
- data/lib/davinci_pdex_test_kit/urls.rb +0 -77
- /data/lib/davinci_pdex_test_kit/{metadata → pdex_payer_client/mock_server/resources}/mock_capability_statement.json +0 -0
- /data/lib/davinci_pdex_test_kit/{metadata → pdex_payer_client/mock_server/resources}/mock_operation_outcome_resource.json +0 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative '../tags'
|
2
|
+
require_relative 'proxy_endpoint'
|
3
|
+
|
4
|
+
module DaVinciPDexTestKit
|
5
|
+
module PDexPayerClient
|
6
|
+
module MockServer
|
7
|
+
# Although this enpoint is not actually proxying, inherit from ProxyEndpoint to keep
|
8
|
+
# #test_run_identifier and #update_result
|
9
|
+
class MemberMatchEndpoint < ProxyEndpoint
|
10
|
+
def make_response
|
11
|
+
#remove token from request as well
|
12
|
+
#original_request_as_hash = JSON.parse(request.body.string).to_h
|
13
|
+
#request.body.string = original_request_as_hash.to_json
|
14
|
+
|
15
|
+
#TODO: Change from static response
|
16
|
+
response.body = {
|
17
|
+
resourceType: "Parameters",
|
18
|
+
parameter: [
|
19
|
+
{
|
20
|
+
name: "MemberIdentifier",
|
21
|
+
valueIdentifier: {
|
22
|
+
type: {
|
23
|
+
coding: [
|
24
|
+
{
|
25
|
+
system: "http://terminology.hl7.org/CodeSystem/v2-0203",
|
26
|
+
code: "MB"
|
27
|
+
}
|
28
|
+
]
|
29
|
+
},
|
30
|
+
system: "https://github.com/inferno-framework/target-payer/identifiers/member",
|
31
|
+
value: "99999",
|
32
|
+
assigner: {
|
33
|
+
display: "Old Payer"
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
]
|
38
|
+
}.to_json
|
39
|
+
|
40
|
+
response.status = 200
|
41
|
+
response.format = 'application/fhir+json'
|
42
|
+
end
|
43
|
+
|
44
|
+
def tags
|
45
|
+
[MEMBER_MATCH_TAG]
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative '../tags'
|
2
|
+
require_relative 'proxy_endpoint'
|
3
|
+
|
4
|
+
module DaVinciPDexTestKit
|
5
|
+
module PDexPayerClient
|
6
|
+
module MockServer
|
7
|
+
class NextPageEndpoint < ProxyEndpoint
|
8
|
+
|
9
|
+
def make_response
|
10
|
+
server_response = server_proxy.get('', JSON.parse(request.params.to_json))
|
11
|
+
response.status = server_response.status
|
12
|
+
response.format = 'application/fhir+json'
|
13
|
+
response.body = replace_bundle_urls(FHIR.from_contents(server_response.body)).to_json
|
14
|
+
end
|
15
|
+
|
16
|
+
def tags
|
17
|
+
[RESOURCE_REQUEST_TAG]
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../tags'
|
2
|
+
require_relative '../urls'
|
3
|
+
require_relative 'proxy_endpoint'
|
4
|
+
|
5
|
+
module DaVinciPDexTestKit
|
6
|
+
module PDexPayerClient
|
7
|
+
module MockServer
|
8
|
+
class PatientEndpoint < ProxyEndpoint
|
9
|
+
include ::DaVinciPDexTestKit::PDexPayerClient::URLs
|
10
|
+
|
11
|
+
def make_response
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def tags
|
16
|
+
tags = [RESOURCE_REQUEST_TAG]
|
17
|
+
tags << PATIENT_ID_REQUEST_TAG if request.url.include?('99999')
|
18
|
+
|
19
|
+
tags
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative '../tags'
|
2
|
+
require_relative 'proxy_endpoint'
|
3
|
+
|
4
|
+
module DaVinciPDexTestKit
|
5
|
+
module PDexPayerClient
|
6
|
+
module MockServer
|
7
|
+
class PatientEverythingEndpoint < ProxyEndpoint
|
8
|
+
|
9
|
+
def make_response
|
10
|
+
# server_response = proxy_request(request, strict: false) # disable strict to allow $everything request without parameters
|
11
|
+
# response = proxy_response(server_response)
|
12
|
+
patient_id = request.url.match(/Patient\/([A-Za-z0-9\-\.]{1,64})\/\$everything/)&.to_a&.at(1)
|
13
|
+
|
14
|
+
if patient_id.nil?
|
15
|
+
response.status = 400
|
16
|
+
response.body = "Invalid patient id for Patient $everything request: #{request.url}"
|
17
|
+
response.format = :text
|
18
|
+
else
|
19
|
+
server_response = server_proxy.get("Patient/#{patient_id}/$everything")
|
20
|
+
|
21
|
+
response.status = server_response.status
|
22
|
+
response.body = replace_bundle_urls(FHIR.from_contents(server_response.body)).to_json
|
23
|
+
response.format = 'application/fhir+json'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def tags
|
28
|
+
[EVERYTHING_TAG]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
|
4
|
+
require_relative '../urls'
|
5
|
+
|
6
|
+
module DaVinciPDexTestKit
|
7
|
+
module PDexPayerClient
|
8
|
+
module MockServer
|
9
|
+
# @abstract
|
10
|
+
# This class defines
|
11
|
+
# - a Faraday connection for proxying requests to ENV['FHIR_REFERENCE_SERVER']
|
12
|
+
# - common methods and conventions for PDex Client Testing endpoints
|
13
|
+
class ProxyEndpoint < Inferno::DSL::SuiteEndpoint
|
14
|
+
|
15
|
+
include ::DaVinciPDexTestKit::PDexPayerClient::URLs
|
16
|
+
|
17
|
+
def test_run_identifier
|
18
|
+
request.headers['authorization']&.delete_prefix('Bearer ')
|
19
|
+
end
|
20
|
+
|
21
|
+
def make_response
|
22
|
+
server_response = proxy_request(request)
|
23
|
+
proxy_response(server_response)
|
24
|
+
end
|
25
|
+
|
26
|
+
def update_result
|
27
|
+
results_repo.update(result.id, result: 'pass') unless test.config.options[:accepts_multiple_requests]
|
28
|
+
end
|
29
|
+
|
30
|
+
# REST Client that proxies request to server at `ENV[FHIR_REFERENCE_SERVER]`
|
31
|
+
# @return [Faraday] - A Faraday 1.x REST Client
|
32
|
+
# @example
|
33
|
+
# server_response = server_proxy.get('Patient/1')
|
34
|
+
# server_response.body # => FHIR JSON String
|
35
|
+
def server_proxy
|
36
|
+
@server_proxy ||= Faraday.new(
|
37
|
+
url: fhir_reference_server,
|
38
|
+
params: {},
|
39
|
+
headers: {
|
40
|
+
'Accept' => 'application/fhir+json,application/json',
|
41
|
+
'Accept-Encoding' => 'identity',
|
42
|
+
'Authorization' => 'Bearer SAMPLE_TOKEN',
|
43
|
+
'Host' => ENV.fetch('HOST_HEADER')
|
44
|
+
}
|
45
|
+
) do |proxy|
|
46
|
+
proxy.use Faraday::Response::Logger
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def fhir_reference_server
|
53
|
+
ENV.fetch('FHIR_REFERENCE_SERVER')
|
54
|
+
end
|
55
|
+
|
56
|
+
# Modify and send request to server proxy. Intended for use in {#make_response}.
|
57
|
+
# @param request [Hanami::Action::Request]
|
58
|
+
# @option strict [Boolean] if true will return 400 for any requests not allowed by PDex API.
|
59
|
+
# The implementation of 'strict' is based on {#match_request_to_expectation} and collections.rb
|
60
|
+
# @return [Faraday::Response]
|
61
|
+
def proxy_request(request, strict: true)
|
62
|
+
fhir_endpoint = resource_endpoint(request.url)
|
63
|
+
|
64
|
+
server_params = request.params.to_hash
|
65
|
+
server_params = match_request_to_expectation(fhir_endpoint, server_params) unless request.url.include?('$') # exclude operations as hotfix
|
66
|
+
|
67
|
+
if strict && server_params.empty?
|
68
|
+
Faraday::Response.new(
|
69
|
+
status: 400,
|
70
|
+
response_body: File.read(File.expand_path('resources/mock_operation_outcome_resource.json', __dir__))
|
71
|
+
)
|
72
|
+
else
|
73
|
+
server_proxy.get(fhir_endpoint, server_params)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Pull resource type from url
|
78
|
+
# @return [String | nil]
|
79
|
+
# @example
|
80
|
+
# resource_endpoint('http://localhost:4567/custom/pdex_payer_client/fhir/Patient/1') # => 'Patient'
|
81
|
+
def resource_endpoint(url)
|
82
|
+
return unless url.start_with?('http://', 'https://')
|
83
|
+
|
84
|
+
/custom\/pdex_payer_client\/fhir\/([a-zA-Z_-]+)([\/\?].*)?/.match(url)&.to_a&.at(1)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Filter request parameters to only include those allowed by PDex API (hardcoded in collections.rb)
|
88
|
+
# @return [Hash]
|
89
|
+
def match_request_to_expectation(endpoint, params)
|
90
|
+
matched_search = SEARCHES_BY_PRIORITY[endpoint.to_sym]&.find {|expectation| (params.keys.map{|key| key.to_s} & expectation).sort == expectation}
|
91
|
+
|
92
|
+
if matched_search
|
93
|
+
params.select {|key, value| matched_search.include?(key.to_s) || key == "_revInclude" || key == "_include"}
|
94
|
+
else
|
95
|
+
{}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Modify response to pretend that mock server generated it. Optionally pass a block to make more modifications.
|
100
|
+
# @param server_response [Faraday::Response]
|
101
|
+
# @yield [FHIR::Model] If response is FHIR yield the resource for modifications
|
102
|
+
# @yieldreturn [FHIR::Model]
|
103
|
+
# @return [Hanami::Action::Response] Inferno mock server response
|
104
|
+
# @example
|
105
|
+
# def make_response
|
106
|
+
# response = proxy_response(response, Faraday.get('https://example.com/fhir/Patient/1')) do |patient|
|
107
|
+
# patient.meta.profile << "http://example.com/fhir/my-ig-profile"
|
108
|
+
# end
|
109
|
+
# end
|
110
|
+
def proxy_response(server_response, &block)
|
111
|
+
response.status = server_response.status
|
112
|
+
|
113
|
+
if server_response.headers.present?
|
114
|
+
headers = remove_transfer_encoding_header(server_response.headers)
|
115
|
+
response.headers.merge!(headers)
|
116
|
+
end
|
117
|
+
response.headers.merge!({'Server' => self.class.name.deconstantize})
|
118
|
+
|
119
|
+
if is_fhir?(server_response.body)
|
120
|
+
response.format = 'application/fhir+json'
|
121
|
+
resource = FHIR.from_contents(server_response.body)
|
122
|
+
resource = replace_bundle_urls(resource) if resource.resourceType == 'Bundle'
|
123
|
+
|
124
|
+
resource = yield(resource) if block_given?
|
125
|
+
|
126
|
+
response.body = resource.to_json
|
127
|
+
|
128
|
+
elsif is_json?(server_response.body)
|
129
|
+
response.format = 'application/json'
|
130
|
+
# Uncomment to recklessly replace all proxy urls with our urls:
|
131
|
+
# response.body = server_response.body.gsub(fhir_reference_server, base_fhir_url)
|
132
|
+
response.body = server_response.body
|
133
|
+
|
134
|
+
else
|
135
|
+
# Uncomment to recklessly replace all proxy urls with our urls:
|
136
|
+
# response.body = server_response.body.gsub(fhir_reference_server, base_fhir_url)
|
137
|
+
response.body = server_response.body
|
138
|
+
end
|
139
|
+
|
140
|
+
response
|
141
|
+
end
|
142
|
+
|
143
|
+
def remove_transfer_encoding_header(headers)
|
144
|
+
if !headers["transfer-encoding"].nil?
|
145
|
+
headers.reject!{|key, value| key == "transfer-encoding"}
|
146
|
+
else
|
147
|
+
headers
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def is_fhir?(str)
|
152
|
+
!!FHIR.from_contents(str)
|
153
|
+
rescue StandardError
|
154
|
+
false
|
155
|
+
end
|
156
|
+
|
157
|
+
def replace_bundle_urls(bundle)
|
158
|
+
bundle&.link.map! {|link| {relation: link.relation, url: link.url.gsub(fhir_reference_server, base_fhir_url)}}
|
159
|
+
bundle&.entry&.map! do |bundled_resource|
|
160
|
+
{
|
161
|
+
fullUrl: bundled_resource.fullUrl.gsub(fhir_reference_server, base_fhir_url),
|
162
|
+
resource: bundled_resource.resource,
|
163
|
+
search: bundled_resource.search
|
164
|
+
}
|
165
|
+
end
|
166
|
+
bundle
|
167
|
+
end
|
168
|
+
|
169
|
+
def is_json?(str)
|
170
|
+
!!JSON.parse(str)
|
171
|
+
rescue StandardError
|
172
|
+
false
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../tags'
|
2
|
+
require_relative 'proxy_endpoint'
|
3
|
+
|
4
|
+
module DaVinciPDexTestKit
|
5
|
+
module PDexPayerClient
|
6
|
+
module MockServer
|
7
|
+
class ResourceReadEndpoint < ProxyEndpoint
|
8
|
+
|
9
|
+
def proxy_request(request)
|
10
|
+
target_resource = request.url.split('/')[-2..-1].join('/')
|
11
|
+
server_proxy.get(target_resource)
|
12
|
+
end
|
13
|
+
|
14
|
+
def tags
|
15
|
+
[RESOURCE_REQUEST_TAG]
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative '../tags'
|
2
|
+
require_relative 'proxy_endpoint'
|
3
|
+
|
4
|
+
module DaVinciPDexTestKit
|
5
|
+
module PDexPayerClient
|
6
|
+
module MockServer
|
7
|
+
# FIXME: this class is intercepting $export-poll-status requests for some reason
|
8
|
+
# however the $export workflow still works
|
9
|
+
class ResourceSearchEndpoint < ProxyEndpoint
|
10
|
+
|
11
|
+
def make_response
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def tags
|
16
|
+
[RESOURCE_REQUEST_TAG]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative '../tags'
|
2
|
+
require_relative 'proxy_endpoint'
|
3
|
+
|
4
|
+
module DaVinciPDexTestKit
|
5
|
+
module PDexPayerClient
|
6
|
+
module MockServer
|
7
|
+
# This endpoint is intended to help clients jumpstart the payer-to-payer workflow
|
8
|
+
# but Inferno requires a bearer token to recieve this endpoint anyways so
|
9
|
+
# this doesn't offer much utility.
|
10
|
+
# TODO: open this endpoint, or send auth to another service
|
11
|
+
class TokenEndpoint < ProxyEndpoint
|
12
|
+
|
13
|
+
def make_response
|
14
|
+
response.status = 200
|
15
|
+
# TODO: derive access_token from suite inputs
|
16
|
+
response.body = { access_token: SecureRandom.hex, token_type: 'bearer', expires_in: 300 }.to_json
|
17
|
+
response.format = :json
|
18
|
+
end
|
19
|
+
|
20
|
+
def tags
|
21
|
+
[AUTH_TAG]
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative 'mock_server/token_endpoint'
|
2
|
+
require_relative 'mock_server/resource_search_endpoint'
|
3
|
+
require_relative 'mock_server/resource_read_endpoint'
|
4
|
+
require_relative 'mock_server/patient_endpoint'
|
5
|
+
require_relative 'mock_server/binary_endpoint'
|
6
|
+
require_relative 'mock_server/patient_everything_endpoint'
|
7
|
+
require_relative 'mock_server/export_endpoint'
|
8
|
+
require_relative 'mock_server/export_status_endpoint'
|
9
|
+
require_relative 'mock_server/member_match_endpoint'
|
10
|
+
require_relative 'mock_server/next_page_endpoint'
|
11
|
+
|
12
|
+
require_relative '../user_input_response'
|
13
|
+
require_relative 'urls'
|
14
|
+
require_relative 'collection'
|
15
|
+
require_relative 'client_validation_test'
|
16
|
+
|
17
|
+
module DaVinciPDexTestKit
|
18
|
+
module PDexPayerClient
|
19
|
+
# FHIR Server for Client TestSuite
|
20
|
+
# Requires URLs and Inferno::DSL::Runnable modules to be included in Client TestSuite
|
21
|
+
module MockServer
|
22
|
+
include URLs
|
23
|
+
|
24
|
+
# The `suite_endpoint` function is only available in a Runnable, so
|
25
|
+
# we define a hook where when this module is included into a class it's
|
26
|
+
# executed in the class' namespace.
|
27
|
+
def self.included(klass)
|
28
|
+
klass.class_eval do
|
29
|
+
|
30
|
+
# Add your routes/endpoints here, order matters!
|
31
|
+
route :get, METADATA_PATH, Proc.new {
|
32
|
+
[
|
33
|
+
200,
|
34
|
+
{'Content-Type' => 'application/fhir+json;charset=utf8'},
|
35
|
+
File.readlines(File.expand_path('mock_server/resources/mock_capability_statement.json', __dir__))
|
36
|
+
]
|
37
|
+
}
|
38
|
+
suite_endpoint :post, TOKEN_PATH, TokenEndpoint
|
39
|
+
suite_endpoint :post, MEMBER_MATCH_PATH, MemberMatchEndpoint
|
40
|
+
suite_endpoint :get, EVERYTHING_PATH, PatientEverythingEndpoint
|
41
|
+
suite_endpoint :get, EXPORT_PATH, ExportEndpoint
|
42
|
+
suite_endpoint :get, EXPORT_STATUS_PATH, ExportStatusEndpoint
|
43
|
+
suite_endpoint :get, BINARY_PATH, BinaryEndpoint
|
44
|
+
suite_endpoint :get, PATIENT_PATH, PatientEndpoint # PDex Patient query needs its own endpoint
|
45
|
+
suite_endpoint :get, RESOURCE_PATH, ResourceSearchEndpoint
|
46
|
+
suite_endpoint :get, INSTANCE_PATH, ResourceReadEndpoint
|
47
|
+
suite_endpoint :get, BASE_FHIR_PATH, NextPageEndpoint # TODO: better pagination route?
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DaVinciPDexTestKit
|
4
|
+
module PDexPayerClient
|
5
|
+
AUTH_TAG = 'pdex_auth'
|
6
|
+
RESOURCE_REQUEST_TAG = 'pdex_resource_request'
|
7
|
+
PATIENT_ID_REQUEST_TAG = 'pdex_patient_id_request'
|
8
|
+
BINARY_TAG = 'pdex_binary'
|
9
|
+
EXPORT_TAG = 'pdex_export'
|
10
|
+
EXPORT_STATUS_TAG = 'pdex_export_status'
|
11
|
+
EVERYTHING_TAG = 'pdex_everything'
|
12
|
+
MEMBER_MATCH_TAG = 'pdex_member_match'
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DaVinciPDexTestKit
|
4
|
+
module PDexPayerClient
|
5
|
+
|
6
|
+
module URLs
|
7
|
+
BASE_PATH = "#{Inferno::Application['base_url']}/custom/pdex_payer_client"
|
8
|
+
TOKEN_PATH = '/mock_auth/token'
|
9
|
+
PATIENT_PATH = '/fhir/Patient'
|
10
|
+
RESOURCE_PATH = '/fhir/:endpoint'
|
11
|
+
INSTANCE_PATH = '/fhir/:endpoint/:id'
|
12
|
+
SUBMIT_PATH = '/fhir/:endpoint' # FIXME duplicate
|
13
|
+
BINARY_PATH = '/fhir/Binary/:id'
|
14
|
+
METADATA_PATH = '/fhir/metadata'
|
15
|
+
EVERYTHING_PATH = '/fhir/Patient/:patient/$everything'
|
16
|
+
MEMBER_MATCH_PATH = '/fhir/Patient/$member-match'
|
17
|
+
EXPORT_PATH = '/fhir/Patient/$export'
|
18
|
+
EXPORT_STATUS_PATH = '/fhir/$export-poll-status'
|
19
|
+
BASE_FHIR_PATH = '/fhir'
|
20
|
+
RESUME_PASS_PATH = '/resume_pass'
|
21
|
+
RESUME_CLINICAL_DATA_PATH = '/resume_clinical_data'
|
22
|
+
RESUME_FAIL_PATH = '/resume_fail'
|
23
|
+
|
24
|
+
constants.each do |path_constant|
|
25
|
+
# For each constant X_PATH, define x_path()
|
26
|
+
define_method(path_constant.to_s.downcase.to_sym) do
|
27
|
+
URLs.const_get(path_constant)
|
28
|
+
end
|
29
|
+
|
30
|
+
# For each constant X_PATH, define x_url(), which includes base
|
31
|
+
define_method(path_constant.to_s.downcase.gsub(/_path$/, '_url')) do
|
32
|
+
File.join(BASE_PATH, URLs.const_get(path_constant))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# overwrite base_url which is irregular
|
37
|
+
def base_url
|
38
|
+
BASE_PATH
|
39
|
+
end
|
40
|
+
|
41
|
+
# overwrite base_fhir_url which is irregular
|
42
|
+
def base_fhir_url
|
43
|
+
File.join(BASE_PATH, BASE_FHIR_PATH)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
# Add all constants and dynamically defined methods to PDexPayerClient namespace
|
49
|
+
include URLs
|
50
|
+
end
|
51
|
+
end
|