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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/pdex_payer_client_postman_preset.json +12 -0
  3. data/config/presets/pdex_payer_server_fhir_foundry_ri_preset.json +96 -0
  4. data/config/presets/pdex_payer_server_inferno_ri_preset.json +96 -0
  5. data/lib/davinci_pdex_test_kit/docs/davinci_pdex_test_kit_description_v200.md +33 -0
  6. data/lib/davinci_pdex_test_kit/docs/payer_client_suite_description_v200.md +107 -17
  7. data/lib/davinci_pdex_test_kit/fhir_resource_navigation.rb +5 -1
  8. data/lib/davinci_pdex_test_kit/group_metadata.rb +5 -1
  9. data/lib/davinci_pdex_test_kit/igs/davinci-pdex-2.0.0.tgz +0 -0
  10. data/lib/davinci_pdex_test_kit/igs/us-core-3.1.1.tgz +0 -0
  11. data/lib/davinci_pdex_test_kit/metadata.rb +16 -0
  12. data/lib/davinci_pdex_test_kit/must_support_test.rb +3 -0
  13. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_validation_test.rb +20 -18
  14. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_validation_test.rb +96 -43
  15. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_workflow_interaction_test.rb +49 -0
  16. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/allergyintolerance_clinical_data_request_test.rb +18 -16
  17. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careplan_clinical_data_request_test.rb +18 -16
  18. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careteam_clinical_data_request_test.rb +18 -16
  19. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/clinical_data_request_check_test.rb +24 -0
  20. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/condition_clinical_data_request_test.rb +18 -16
  21. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/device_clinical_data_request_test.rb +19 -17
  22. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/diagnosticreport_clinical_data_request_test.rb +18 -16
  23. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/documentreference_clinical_data_request_test.rb +18 -16
  24. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/encounter_clinical_data_request_test.rb +18 -16
  25. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/explanationofbenefit_clinical_data_request_test.rb +18 -16
  26. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/goal_clinical_data_request_test.rb +18 -16
  27. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/immunization_clinical_data_request_test.rb +18 -16
  28. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/location_clinical_data_request_test.rb +18 -16
  29. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationdispense_clinical_data_request_test.rb +18 -16
  30. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationrequest_clinical_data_request_test.rb +18 -16
  31. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/observation_clinical_data_request_test.rb +18 -16
  32. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/organization_clinical_data_request_test.rb +18 -16
  33. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/patient_clinical_data_request_test.rb +18 -16
  34. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/patient_id_search_request_check_test.rb +21 -0
  35. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitioner_clinical_data_request_test.rb +18 -16
  36. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitionerrole_clinical_data_request_test.rb +18 -16
  37. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/procedure_clinical_data_request_test.rb +18 -16
  38. data/lib/davinci_pdex_test_kit/pdex_payer_client/collection.rb +46 -44
  39. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/binary_endpoint.rb +26 -0
  40. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/export_endpoint.rb +29 -0
  41. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/export_status_endpoint.rb +38 -0
  42. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/member_match_endpoint.rb +51 -0
  43. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/next_page_endpoint.rb +23 -0
  44. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/patient_endpoint.rb +25 -0
  45. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/patient_everything_endpoint.rb +34 -0
  46. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/proxy_endpoint.rb +178 -0
  47. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/resource_read_endpoint.rb +21 -0
  48. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/resource_search_endpoint.rb +22 -0
  49. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/token_endpoint.rb +27 -0
  50. data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server.rb +53 -0
  51. data/lib/davinci_pdex_test_kit/pdex_payer_client/tags.rb +15 -0
  52. data/lib/davinci_pdex_test_kit/pdex_payer_client/urls.rb +51 -0
  53. data/lib/davinci_pdex_test_kit/pdex_payer_client_suite.rb +101 -144
  54. data/lib/davinci_pdex_test_kit/pdex_payer_server/coverage_to_link_minimal_data_validation.rb +1 -1
  55. data/lib/davinci_pdex_test_kit/pdex_payer_server/coverage_to_link_must_support_validation.rb +1 -1
  56. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_id_search_test.rb +5 -4
  57. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_identifier_search_test.rb +5 -4
  58. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_must_support_test.rb +3 -2
  59. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_last_updated_search_test.rb +7 -6
  60. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_service_date_search_test.rb +7 -6
  61. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_type_search_test.rb +7 -6
  62. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_use_search_test.rb +6 -5
  63. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_provenance_revinclude_search_test.rb +10 -7
  64. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_read_test.rb +1 -1
  65. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_reference_resolution_test.rb +3 -2
  66. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_validation_test.rb +1 -1
  67. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/metadata.yml +12 -12
  68. data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit_group.rb +12 -14
  69. data/lib/davinci_pdex_test_kit/pdex_payer_server/export_patient_group.rb +3 -4
  70. data/lib/davinci_pdex_test_kit/pdex_payer_server/export_validation_group.rb +2 -6
  71. data/lib/davinci_pdex_test_kit/pdex_payer_server/member_match_request_local_references_validation.rb +1 -1
  72. data/lib/davinci_pdex_test_kit/pdex_payer_server/member_match_request_profile_validation.rb +1 -3
  73. data/lib/davinci_pdex_test_kit/pdex_payer_server/multiple_member_matches_group.rb +7 -8
  74. data/lib/davinci_pdex_test_kit/pdex_payer_server/no_member_matches_group.rb +7 -8
  75. data/lib/davinci_pdex_test_kit/pdex_payer_server/patient_operation_in_capability_statement_validation.rb +1 -3
  76. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_clinical_data_group.rb +3 -5
  77. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_everything_group.rb +2 -4
  78. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_export_group.rb +2 -4
  79. data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_member_match_group.rb +12 -13
  80. data/lib/davinci_pdex_test_kit/pdex_payer_server_suite.rb +13 -14
  81. data/lib/davinci_pdex_test_kit/version.rb +2 -3
  82. data/lib/davinci_pdex_test_kit.rb +1 -2
  83. metadata +65 -24
  84. data/lib/davinci_pdex_test_kit/ext/inferno_core/record_response_route.rb +0 -98
  85. data/lib/davinci_pdex_test_kit/ext/inferno_core/request.rb +0 -19
  86. data/lib/davinci_pdex_test_kit/ext/inferno_core/runnable.rb +0 -18
  87. data/lib/davinci_pdex_test_kit/mock_server.rb +0 -281
  88. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_submit_test.rb +0 -24
  89. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/client_member_match_must_support_submit_test.rb +0 -26
  90. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/client_member_match_must_support_validation_test.rb +0 -32
  91. data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/metadata.yml +0 -61
  92. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/initial_scratch_storing.rb +0 -32
  93. data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/initial_wait_test.rb +0 -31
  94. data/lib/davinci_pdex_test_kit/tags.rb +0 -11
  95. data/lib/davinci_pdex_test_kit/urls.rb +0 -77
  96. /data/lib/davinci_pdex_test_kit/{metadata → pdex_payer_client/mock_server/resources}/mock_capability_statement.json +0 -0
  97. /data/lib/davinci_pdex_test_kit/{metadata → pdex_payer_client/mock_server/resources}/mock_operation_outcome_resource.json +0 -0
@@ -1,98 +0,0 @@
1
- require 'hanami/controller'
2
-
3
- module Inferno
4
- module DSL
5
- # A base class for creating routes with custom response logic. Requests and responses are tagged and saved.
6
- # @private
7
- # @see Inferno::DSL::Runnable#resume_test_route
8
- class RecordResponseRoute < Hanami::Action
9
- include Import[
10
- requests_repo: 'inferno.repositories.requests',
11
- results_repo: 'inferno.repositories.results',
12
- test_runs_repo: 'inferno.repositories.test_runs',
13
- tests_repo: 'inferno.repositories.tests'
14
- ]
15
-
16
- def self.call(...)
17
- new.call(...)
18
- end
19
-
20
- # @private
21
- def test_run_identifier_block
22
- self.class.singleton_class.instance_variable_get(:@test_run_identifier_block)
23
- end
24
-
25
- # @private
26
- def build_response_block
27
- self.class.singleton_class.instance_variable_get(:@build_response_block)
28
- end
29
-
30
- # @private
31
- def tags
32
- self.class.singleton_class.instance_variable_get(:@tags)
33
- end
34
-
35
- # @private
36
- def resumes?(test)
37
- instance_exec(test, &self.class.singleton_class.instance_variable_get(:@resumes))
38
- end
39
-
40
- # @private
41
- def find_test_run(test_run_identifier)
42
- test_runs_repo.find_latest_waiting_by_identifier(test_run_identifier)
43
- end
44
-
45
- # @private
46
- def find_waiting_result(test_run)
47
- results_repo.find_waiting_result(test_run_id: test_run.id)
48
- end
49
-
50
- # @private
51
- def update_result(waiting_result)
52
- results_repo.update_result(waiting_result.id, 'pass')
53
- end
54
-
55
- # @private
56
- def persist_request(request, test_run, waiting_result, test)
57
- requests_repo.create(
58
- request.to_hash.merge(
59
- test_session_id: test_run.test_session_id,
60
- result_id: waiting_result.id,
61
- name: test.config.request_name(test.incoming_request_name),
62
- tags:
63
- )
64
- )
65
- end
66
-
67
- # @private
68
- def find_test(waiting_result)
69
- tests_repo.find(waiting_result.test_id)
70
- end
71
-
72
- # @private
73
- def handle(req, res)
74
- request = Inferno::Entities::Request.from_hanami_request(req)
75
-
76
- test_run_identifier = instance_exec(request, &test_run_identifier_block)
77
-
78
- test_run = find_test_run(test_run_identifier)
79
-
80
- halt 500, "Unable to find test run with identifier '#{test_run_identifier}'." if test_run.nil?
81
-
82
- waiting_result = find_waiting_result(test_run)
83
- test = find_test(waiting_result)
84
-
85
- test_runs_repo.mark_as_no_longer_waiting(test_run.id) if resumes? test
86
-
87
- update_result(waiting_result) if resumes? test
88
-
89
- instance_exec(request, test, waiting_result, &build_response_block)
90
-
91
- Inferno::Entities::Request.to_hanami_response(request, res)
92
- persist_request(request, test_run, waiting_result, test)
93
-
94
- Jobs.perform(Jobs::ResumeTestRun, test_run.id) if resumes? test
95
- end
96
- end
97
- end
98
- end
@@ -1,19 +0,0 @@
1
- module Inferno
2
- module Entities
3
- class Request
4
- def self.to_hanami_response(request, response)
5
- response.status = request.status
6
- response.body = request.response_body
7
- request.response_headers.each do |header|
8
- response.headers[header.name] = header.value
9
- end
10
-
11
- response
12
- end
13
-
14
- def response_headers=(headers_hash)
15
- headers.concat(headers_hash.map { |key, value| Header.new(name: key.to_s, value:, type: 'response') })
16
- end
17
- end
18
- end
19
- end
@@ -1,18 +0,0 @@
1
- require_relative 'record_response_route'
2
-
3
- module Inferno
4
- module DSL
5
- module Runnable
6
- def record_response_route(method, path, tags, build_response, resumes: ->(_) { true }, &block)
7
- route_class = Class.new(Inferno::DSL::RecordResponseRoute) do |klass|
8
- klass.singleton_class.instance_variable_set(:@build_response_block, build_response)
9
- klass.singleton_class.instance_variable_set(:@test_run_identifier_block, block)
10
- klass.singleton_class.instance_variable_set(:@tags, Array.wrap(tags))
11
- klass.singleton_class.instance_variable_set(:@resumes, resumes)
12
- end
13
-
14
- route(method, path, route_class)
15
- end
16
- end
17
- end
18
- end
@@ -1,281 +0,0 @@
1
- require_relative 'user_input_response'
2
- require_relative 'urls'
3
- require_relative 'pdex_payer_client/collection'
4
- require_relative 'pdex_payer_client/client_validation_test'
5
- #require_relative 'metadata/mock_capability_statement'
6
-
7
-
8
- module DaVinciPDexTestKit
9
- # Serve responses to PAS requests
10
- #
11
- # Note that there are numerous expected validation issues that can safely be ignored.
12
- # See here for full list: https://hl7.org/fhir/us/davinci-pas/STU2/qa.html#suppressed
13
- module MockServer
14
- include URLs
15
-
16
- def server_proxy
17
- @server_proxy ||= Faraday.new(
18
- url: ENV.fetch('FHIR_REFERENCE_SERVER'),
19
- params: {},
20
- headers: {'Content-Type' => 'application/json', 'Authorization' => 'Bearer SAMPLE_TOKEN', 'Host' => ENV.fetch('HOST_HEADER')},
21
- ) do |proxy|
22
- proxy.use FaradayMiddleware::Gzip
23
- end
24
- end
25
-
26
- def token_response(request, _test = nil, _test_result = nil)
27
- # Placeholder for a more complete mock token endpoint
28
- request.response_body = { access_token: SecureRandom.hex, token_type: 'bearer', expires_in: 300 }.to_json
29
- request.status = 200
30
- end
31
-
32
- def claim_response(request, test = nil, test_result = nil)
33
- endpoint = resource_endpoint(request.url)
34
- params = match_request_to_expectation(endpoint, request.query_parameters)
35
- if params
36
- response = server_proxy.get(endpoint, params)
37
- request.status = response.status
38
- response_resource = replace_bundle_urls(FHIR.from_contents(response.body))
39
- request.response_headers = remove_transfer_encoding_header(response.headers)
40
- request.response_body = response_resource.to_json
41
- request.response_header("content-length").value = request.response_body.length
42
- else
43
- response = server_proxy.get('Patient', {_id: 999})
44
- response_resource = FHIR.from_contents(response.body)
45
- response_resource.entry = [{fullUrl: 'urn:uuid:2866af9c-137d-4458-a8a9-eeeec0ce5583', resource: mock_operation_outcome_resource, search: {mode: 'outcome'}}]
46
- response_resource.link.first.url = request.url #specific case for Operation Outcome handling
47
- request.status = 400
48
- request.response_body = response_resource.to_json
49
- end
50
- end
51
-
52
- def read_next_page(request, test = nil, test_result = nil)
53
- response = server_proxy.get('', request.query_parameters)
54
- request.status = response.status
55
- request.response_headers = remove_transfer_encoding_header(response.headers)
56
- request.response_body = replace_bundle_urls(FHIR.from_contents(response.body)).to_json
57
- end
58
-
59
- def everything_response(request, test = nil, test_result = nil)
60
- response = server_proxy.get('Patient/999/$everything') #TODO: Change from static response
61
- request.status = response.status
62
- request.response_headers = remove_transfer_encoding_header(response.headers)
63
- request.response_body = replace_bundle_urls(FHIR.from_contents(response.body)).to_json
64
- end
65
-
66
- def export_response(request, test = nil, test_result = nil)
67
- headers_as_hash = request.request_headers.map { |header| {"#{header.name}": header.value}}.reduce({}) { |reduced, curr| reduced.merge(curr)}
68
- response = server_proxy.get do |req|
69
- req.url 'Group/pdex-Group/$export' #TODO: change from static response
70
- req.headers = headers_as_hash.merge(server_proxy.headers)
71
- end
72
- request.status = response.status
73
- request.response_headers = response.env.response_headers
74
- request.response_header("content-location").value.gsub!(/(.*)\?/, "#{new_link}/$export-poll-status?")
75
- request.response_body = response.body
76
- end
77
-
78
- def export_status_response(request, test = nil, test_result = nil)
79
- headers_as_hash = request.request_headers.map { |header| {"#{header.name}": header.value}}.reduce({}) { |reduced, curr| reduced.merge(curr)}
80
- response = server_proxy.get do |req|
81
- req.url '$export-poll-status'
82
- req.params = request.query_parameters
83
- req.headers = headers_as_hash.merge(server_proxy.headers)
84
- end
85
- request.status = response.status
86
- request.response_headers = remove_transfer_encoding_header(response.env.response_headers)
87
- request.response_body = response.status.to_i == 200 ? replace_export_urls(JSON.parse(response.body)).to_json : response.body
88
- request.response_header("content-length").value = request.response_body.length
89
- end
90
-
91
- def binary_read_response(request, test = nil, test_result = nil)
92
- binary_id = request.url.split('/').last
93
- response = server_proxy.get('Binary/'+binary_id)
94
- request.status = response.status
95
- request.response_headers = response.headers
96
- request.response_body = response.body
97
- end
98
-
99
- def member_match_response(request, test = nil, test_result = nil)
100
- #remove token from request as well
101
- original_request_as_hash = JSON.parse(request.request_body).to_h
102
- request.request_body = original_request_as_hash.to_json
103
- #TODO: Change from static response
104
- request.response_body = {
105
- resourceType: "Parameters",
106
- parameter: [
107
- {
108
- name: "MemberIdentifier",
109
- valueIdentifier: {
110
- type: {
111
- coding: [
112
- {
113
- system: "http://terminology.hl7.org/CodeSystem/v2-0203",
114
- code: "MB"
115
- }
116
- ]
117
- },
118
- system: "https://github.com/inferno-framework/target-payer/identifiers/member",
119
- value: "99999",
120
- assigner: {
121
- display: "Old Payer"
122
- }
123
- }
124
- }
125
- ]
126
- }.to_json
127
- request.status = 200
128
- end
129
-
130
- def get_metadata
131
- proc { [200, {'Content-Type' => 'application/fhir+json;charset=utf-8'}, [File.read("lib/davinci_pdex_test_kit/metadata/mock_capability_statement.json")]] }
132
- end
133
-
134
- def remove_transfer_encoding_header(headers)
135
- if !headers["transfer-encoding"].nil?
136
- headers.reject!{|key, value| key == "transfer-encoding"}
137
- else
138
- headers
139
- end
140
- end
141
-
142
- def match_request_to_expectation(endpoint, params)
143
- matched_search = SEARCHES_BY_PRIORITY[endpoint.to_sym].find {|expectation| (params.keys.map{|key| key.to_s} & expectation).sort == expectation}
144
- # matched_search_without_patient = SEARCHES_BY_PRIORITY[endpoint.to_sym].find {|expectation| (params.keys.map{|key| key.to_s} << "patient" & expectation) == expectation}
145
-
146
- if matched_search
147
- params.select {|key, value| matched_search.include?(key.to_s) || key == "_revInclude" || key == "_include"}
148
- else
149
- nil
150
- end
151
- # else
152
- # new_params = params.select {|key, value| matched_search_without_patient.include?(key.to_s) || key == "_revInclude" || key == "_include"}
153
- # new_params["patient"] = patient_id_from_match_request
154
- # new_params
155
- # end
156
- end
157
-
158
- def extract_client_id(request)
159
- URI.decode_www_form(request.request_body).to_h['client_id']
160
- end
161
-
162
- # Header expected to be a bearer token of the form "Bearer: <token>"
163
- def extract_bearer_token(request)
164
- request.request_header('Authorization')&.value&.split&.last
165
- end
166
-
167
- def extract_token_from_query_params(request)
168
- request.query_parameters['token']
169
- end
170
-
171
- # Pull resource type from url
172
- # e.g. http://example.org/fhir/Patient/123 -> Patient
173
- # @private
174
- def resource_endpoint(url)
175
- return unless url.start_with?('http://', 'https://')
176
-
177
- /custom\/pdex_payer_client\/fhir\/(.*)\?/.match(url)[1]
178
- end
179
-
180
- # @private
181
- def referenced_entities(resource, entries, root_url)
182
- matches = []
183
- attributes = resource&.source_hash&.keys
184
- attributes.each do |attr|
185
- value = resource.send(attr.to_sym)
186
- if value.is_a?(FHIR::Reference) && value.reference.present?
187
- match = find_matching_entry(value.reference, entries, root_url)
188
- if match.present? && matches.none?(match)
189
- value.reference = match.fullUrl
190
- matches.concat([match], referenced_entities(match.resource, entries, root_url))
191
- end
192
- elsif value.is_a?(Array) && value.all? { |elmt| elmt.is_a?(FHIR::Model) }
193
- value.each { |val| matches.concat(referenced_entities(val, entries, root_url)) }
194
- end
195
- end
196
-
197
- matches
198
- end
199
-
200
- def mock_operation_outcome_resource
201
- FHIR.from_contents(File.read("lib/davinci_pdex_test_kit/metadata/mock_operation_outcome_resource.json"))
202
- end
203
-
204
- def replace_bundle_urls(bundle)
205
- reference_server_base = ENV.fetch('FHIR_REFERENCE_SERVER')
206
- bundle&.link.map! {|link| {relation: link.relation, url: link.url.gsub(reference_server_base, new_link)}}
207
- bundle&.entry&.map! do |bundled_resource|
208
- {fullUrl: bundled_resource.fullUrl.gsub(reference_server_base, new_link),
209
- resource: bundled_resource.resource,
210
- search: bundled_resource.search
211
- }
212
- end
213
- bundle
214
- end
215
-
216
- def replace_export_urls(export_status_output)
217
- reference_server_base = ENV.fetch('FHIR_REFERENCE_SERVER')
218
- export_status_output['output'].map! { |binary| {type: binary["type"], url: binary["url"].gsub(reference_server_base, new_link)} }
219
- export_status_output['request'] = new_link + '/Patient/$export'
220
- export_status_output
221
- end
222
-
223
- def new_link
224
- "#{Inferno::Application['base_url']}\/custom\/pdex_payer_client\/fhir"
225
- end
226
-
227
- # @private
228
- def absolute_reference(ref, entries, root_url)
229
- url = find_matching_entry(ref&.reference, entries, root_url)&.fullUrl
230
- ref.reference = url if url
231
- ref
232
- end
233
-
234
- def fetch_all_bundled_resources(
235
- reply_handler: nil,
236
- max_pages: 0,
237
- additional_resource_types: [],
238
- resource_type: self.resource_type
239
- )
240
- page_count = 1
241
- resources = []
242
- bundle = resource
243
- resources += bundle&.entry&.map { |entry| entry&.resource }
244
-
245
- until bundle.nil? || (page_count == max_pages && max_pages != 0)
246
-
247
- next_bundle_link = bundle&.link&.find { |link| link.relation == 'next' }&.url
248
- reply_handler&.call(response)
249
-
250
- break if next_bundle_link.blank?
251
-
252
- reply = fhir_client.raw_read_url(next_bundle_link)
253
-
254
- store_request('outgoing') { reply }
255
- error_message = cant_resolve_next_bundle_message(next_bundle_link)
256
-
257
- assert_response_status(200)
258
- assert_valid_json(reply.body, error_message)
259
-
260
- bundle = fhir_client.parse_reply(FHIR::Bundle, fhir_client.default_format, reply)
261
- resources += bundle&.entry&.map { |entry| entry&.resource }
262
-
263
- page_count += 1
264
- end
265
- valid_resource_types = [resource_type, 'OperationOutcome'].concat(additional_resource_types)
266
- resources
267
- end
268
-
269
- # @private
270
- def find_matching_entry(ref, entries, root_url = '')
271
- ref = "#{root_url}/#{ref}" if relative_reference?(ref) && root_url&.present?
272
-
273
- entries&.find { |entry| entry&.fullUrl == ref }
274
- end
275
-
276
- # @private
277
- def relative_reference?(ref)
278
- ref&.count('/') == 1
279
- end
280
- end
281
- end
@@ -1,24 +0,0 @@
1
- require_relative '../../urls'
2
-
3
- module DaVinciPDexTestKit
4
- class PDexClientMemberMatchSubmitTest < Inferno::Test
5
- include URLs
6
-
7
- id :initial_member_match_submit_test
8
- title 'Client makes a $member-match request'
9
- description %(
10
- This test will await a $member-match request and proceed once a request is received.
11
- )
12
- input :access_token
13
-
14
- run do
15
- wait(
16
- identifier: access_token,
17
- message: %(
18
- Access Token: #{access_token} \n
19
- Submit a PDex $member-match request to `#{member_match_url}`.
20
- )
21
- )
22
- end
23
- end
24
- end
@@ -1,26 +0,0 @@
1
- require_relative '../../urls'
2
-
3
- module DaVinciPDexTestKit
4
- class PDexClientMemberMatchMustSupportSubmitTest < Inferno::Test
5
- include URLs
6
-
7
- id :initial_member_match_must_support_submit_test
8
- title '$member-match requests span all Must Supports'
9
- description %(
10
- This test will receive $member-match requests until the user specifies they are done. It then checks all received $member-match requests for Must Support coverage.
11
- )
12
- input :access_token
13
- config options: { accepts_multiple_requests: true }
14
-
15
- run do
16
- wait(
17
- identifier: access_token,
18
- message: %(
19
- Access Token: #{access_token} \n
20
- Submit PDex $member-match request(s) to `#{member_match_url}`, and [click here](#{resume_pass_url}?token=#{access_token}) when all Must Support
21
- elements have been covered.
22
- )
23
- )
24
- end
25
- end
26
- end
@@ -1,32 +0,0 @@
1
- require_relative '../client_validation_test.rb'
2
- require_relative '../../group_metadata.rb'
3
-
4
- module DaVinciPDexTestKit
5
- class PDexInitialMemberMatchMustSupportValidationTest < Inferno::Test
6
- include DaVinciPDexTestKit::MustSupportTest
7
- include DaVinciPDexTestKit::ClientValidationTest
8
- include URLs
9
-
10
- id :initial_member_match_must_support_validation_test
11
- title 'All must support elements are provided in the received $member-match requests'
12
- description %(
13
- This test verifies that the client is capable of making $member-match requests
14
- )
15
- input :access_token
16
-
17
- def resource_type
18
- 'Parameters'
19
- end
20
-
21
- def self.metadata
22
- @metadata ||= DaVinciPDexTestKit::GroupMetadata.new(YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true))
23
- end
24
-
25
- run do
26
-
27
- assert all_member_match_requests, "No previous $member-match requests received"
28
-
29
- perform_must_support_test(all_member_match_requests.map {|match_request| FHIR::Parameters.new(JSON.parse(match_request.request_body).to_h)})
30
- end
31
- end
32
- end
@@ -1,61 +0,0 @@
1
- ---
2
- :name: hrex_member_match_request_parameters
3
- :class_name: HRexMemberMatchRequestParameters
4
- :version: 1.0.0
5
- :reformatted_version: v1.0.0
6
- :resource: Parameters
7
- :profile_url: http://hl7.org/fhir/us/davinci-hrex/StructureDefinition/hrex-parameters-member-match-in
8
- :profile_name: HRex Member Match Request Parameters
9
- :profile_version: 1.0.0
10
- :title: Member Match Request Parameters
11
- :short_description: "The Parameters profile for Da Vinci Find Member using Patient and Coverage Resources Request. The resource must contain: \n * MemberPatient - US Core Patient containing member demographics \n * CoverageToMatch - details of prior health plan coverage provided by the member, typically from their health plan coverage card \n * CoverageToLink - details of new or prospective health plan coverage, provided by the health plan based upon the member's enrolment"
12
- :is_delayed: false
13
- :interactions: []
14
- :operations: []
15
- :include_params: []
16
- :revincludes: []
17
- :required_concepts: []
18
- :must_supports:
19
- :extensions: []
20
- :slices:
21
- - :slice_id: Parameters.parameter:MemberPatient
22
- :slice_name: MemberPatient
23
- :path: parameter
24
- :discriminator:
25
- :type: value
26
- :values:
27
- - :path: name
28
- :value: MemberPatient
29
- - :slice_id: Parameters.parameter:CoverageToMatch
30
- :slice_name: CoverageToMatch
31
- :path: parameter
32
- :discriminator:
33
- :type: value
34
- :values:
35
- - :path: name
36
- :value: CoverageToMatch
37
- - :slice_id: Parameters.parameter:CoverageToLink
38
- :slice_name: CoverageToLink
39
- :path: parameter
40
- :discriminator:
41
- :type: value
42
- :values:
43
- - :path: name
44
- :value: CoverageToLink
45
- - :slice_id: Parameters.parameter:Consent
46
- :slice_name: Consent
47
- :path: parameter
48
- :discriminator:
49
- :type: value
50
- :values:
51
- - :path: name
52
- :value: Consent
53
- :elements:
54
- - :path: parameter:MemberPatient.resource
55
- - :path: parameter:CoverageToMatch.resource
56
- - :path: parameter:CoverageToLink.resource
57
- - :path: parameter:Consent.resource
58
- :mandatory_elements:
59
-
60
-
61
-
@@ -1,32 +0,0 @@
1
- require_relative '../client_validation_test.rb'
2
- module DaVinciPDexTestKit
3
- class PDexClientScratchStorage < Inferno::Test
4
- include DaVinciPDexTestKit::ClientValidationTest
5
-
6
- id :initial_scratch_storing
7
- title 'Client makes clinical data requests that capture an entire patient'
8
- description %(
9
- This test organizes the received requests in order to validate all expected specific resources were returned
10
- )
11
- input :access_token
12
-
13
- run do
14
- previous_clinical_data_request_resources.each do |request, resources|
15
- resources.each do |resource|
16
- scratch[resource.resourceType.to_sym] ||= []
17
- scratch[resource.resourceType.to_sym] |= [resource]
18
- end
19
- end
20
- if !export_resources.empty?
21
- info "Attempted an $export request"
22
- export_resources.each do |resource|
23
- scratch[resource.resourceType.to_sym] ||= []
24
- scratch[resource.resourceType.to_sym] |= [resource]
25
- end
26
- end
27
- if everything_request
28
- info "Attempted an $everything request"
29
- end
30
- end
31
- end
32
- end
@@ -1,31 +0,0 @@
1
- require_relative '../../urls'
2
- module DaVinciPDexTestKit
3
- class PDexClientSubmitMustSupportTest < Inferno::Test
4
- include URLs
5
-
6
- id :initial_wait_test
7
- title 'Client makes clinical data requests'
8
- description %(
9
- This test will receive clinical data requests until the user confirms they are done.
10
- )
11
- input :access_token
12
- config options: { accepts_multiple_requests: true }
13
-
14
- run do
15
- wait(
16
- identifier: access_token,
17
- message: %(
18
- Access Token: #{access_token} \n
19
- Submit PDex requests via at least one of the following methods:
20
- * Single Resource API: `#{submit_url}`, with `:endpoint` replaced with the endpoint you want to reach
21
- * $everything method: `#{everything_url}`, with `:patient` replaced with the patient you are matching
22
- * $export method: `#{export_url}`, see workflow process at the [Bulk Data IG](https://hl7.org/fhir/uv/bulkdata/STU2/)
23
- * $export-poll-status: `#{export_status_url}`, then continue to make reads from the binaries if a payload is delivered
24
-
25
- and [click here](#{resume_clinical_data_url}?token=#{access_token}) when done.
26
- ),
27
- timeout: 900
28
- )
29
- end
30
- end
31
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DaVinciPDexTestKit
4
- AUTH_TAG = 'pdex_auth'
5
- SUBMIT_TAG = 'pdex_submit'
6
- BINARY_TAG = 'pdex_binary'
7
- EXPORT_TAG = 'pdex_export'
8
- EXPORT_STATUS_TAG = 'pdex_export_status'
9
- EVERYTHING_TAG = 'pdex_everything'
10
- MEMBER_MATCH_TAG = 'pdex_member_match'
11
- end