davinci_pdex_test_kit 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +201 -0
- data/lib/davinci_pdex_test_kit/docs/payer_client_suite_description_v200.md +91 -0
- data/lib/davinci_pdex_test_kit/docs/payer_server_suite_description_v200.md +119 -0
- data/lib/davinci_pdex_test_kit/ext/inferno_core/record_response_route.rb +98 -0
- data/lib/davinci_pdex_test_kit/ext/inferno_core/request.rb +19 -0
- data/lib/davinci_pdex_test_kit/ext/inferno_core/runnable.rb +18 -0
- data/lib/davinci_pdex_test_kit/fhir_resource_navigation.rb +154 -0
- data/lib/davinci_pdex_test_kit/group_metadata.rb +109 -0
- data/lib/davinci_pdex_test_kit/metadata/mock_capability_statement.json +1052 -0
- data/lib/davinci_pdex_test_kit/metadata/mock_operation_outcome_resource.json +16 -0
- data/lib/davinci_pdex_test_kit/mock_server.rb +247 -0
- data/lib/davinci_pdex_test_kit/must_support_test.rb +252 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_submit_test.rb +24 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_validation_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/client_member_match_must_support_submit_test.rb +26 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_must_support_tests/client_member_match_must_support_validation_test.rb +32 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_validation_test.rb +94 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/allergyintolerance_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careplan_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careteam_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/condition_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/device_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/diagnosticreport_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/documentreference_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/encounter_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/explanationofbenefit_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/goal_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/immunization_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/initial_scratch_storing.rb +34 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/initial_wait_test.rb +28 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/location_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationdispense_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationrequest_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/observation_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/organization_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/patient_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitioner_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitionerrole_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/procedure_clinical_data_request_test.rb +23 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/collection.rb +46 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client_suite.rb +152 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/abstract_member_match_request_conformance_test.rb +33 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/abstract_member_match_request_local_references_test.rb +35 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/coverage_to_link_has_minimal_data_test.rb +52 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/coverage_to_link_must_support_test.rb +28 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_id_search_test.rb +58 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_identifier_search_test.rb +58 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_must_support_test.rb +40 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_last_updated_search_test.rb +63 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_service_date_search_test.rb +63 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_type_search_test.rb +63 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_patient_use_search_test.rb +68 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_provenance_revinclude_search_test.rb +52 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_read_test.rb +26 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_reference_resolution_test.rb +43 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit/explanation_of_benefit_validation_test.rb +40 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/explanation_of_benefit_group.rb +105 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/export_patient_group.rb +103 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/export_validation_group.rb +59 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/multiple_member_matches_group.rb +66 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/no_member_matches_group.rb +69 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_clinical_data.rb +66 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_everything.rb +184 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_export.rb +67 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_member_match.rb +171 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server_suite.rb +158 -0
- data/lib/davinci_pdex_test_kit/pdex_provider_client_suite.rb +36 -0
- data/lib/davinci_pdex_test_kit/tags.rb +9 -0
- data/lib/davinci_pdex_test_kit/urls.rb +67 -0
- data/lib/davinci_pdex_test_kit/user_input_response.rb +32 -0
- data/lib/davinci_pdex_test_kit/version.rb +5 -0
- data/lib/davinci_pdex_test_kit.rb +8 -0
- metadata +218 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
module DaVinciPDexTestKit
|
2
|
+
SET_TO_BE_GATHERED = {AllergyIntolerance: ['pdex-AllergyIntolerance'],
|
3
|
+
CarePlan: ['pdex-CarePlan'],
|
4
|
+
CareTeam: ['pdex-CareTeam'],
|
5
|
+
Condition: ['pdex-Condition'],
|
6
|
+
Device: ['pdex-Device'],
|
7
|
+
DiagnosticReport: ['pdex-DiagnosticReport'],
|
8
|
+
DocumentReference: ['pdex-DocumentReference'],
|
9
|
+
Encounter: ['pdex-Encounter'],
|
10
|
+
ExplanationOfBenefit: ['pdex-ExplanationOfBenefit'],
|
11
|
+
Goal: ['pdex-Goal'],
|
12
|
+
Immunization: ['pdex-Immunization'],
|
13
|
+
Location: ['pdex-Location'],
|
14
|
+
MedicationDispense: ['pdex-MedicationDispense'],
|
15
|
+
MedicationRequest: ['pdex-MedicationRequest'],
|
16
|
+
Observation: ['pdex-Observation'],
|
17
|
+
Organization: ['pdex-Organization'],
|
18
|
+
Patient: ['999'],
|
19
|
+
Practitioner: ['pdex-Practitioner'],
|
20
|
+
PractitionerRole: ['pdex-PractitionerRole'],
|
21
|
+
Procedure: ['pdex-Procedure']
|
22
|
+
#TODO: What about Provenance?
|
23
|
+
}
|
24
|
+
|
25
|
+
SEARCHES_BY_PRIORITY = {AllergyIntolerance: [['patient']],
|
26
|
+
CarePlan: [['category', 'patient']],
|
27
|
+
CareTeam: [['patient', 'status']],
|
28
|
+
Condition: [['category', 'patient'], ['patient']],
|
29
|
+
Device: [['patient', 'type'], ['patient']],
|
30
|
+
DiagnosticReport: [['category', 'date', 'patient'], ['code', 'patient'], ['category', 'patient'], ['patient']],
|
31
|
+
DocumentReference: [['_id'], ['category', 'date', 'patient'], ['patient', 'type'], ['category', 'patient'], ['patient']],
|
32
|
+
Encounter: [['_id'], ['date', 'patient'], ['patient']],
|
33
|
+
ExplanationOfBenefit: [['_id'], ['patient'], ['identifier'], ['_lastUpdated'], ['service-date'], ['type']],
|
34
|
+
Goal: [['patient']],
|
35
|
+
Immunization: [['patient']],
|
36
|
+
Location: [['name'], ['address']],
|
37
|
+
MedicationDispense: [['patient']],
|
38
|
+
MedicationRequest: [['intent', 'patient']],
|
39
|
+
Observation: [['category', 'date', 'patient'], ['code', 'patient'], ['category', 'patient']],
|
40
|
+
Organization: [['name'], ['address']],
|
41
|
+
Patient: [['_id'], ['identifier'], ['birthdate', 'name'], ['gender', 'name'], ['name']],
|
42
|
+
Practitioner: [['identifier'], ['name']],
|
43
|
+
PractitionerRole: [['practitioner'], ['specialty']],
|
44
|
+
Procedure: [['date', 'patient'], ['patient']],
|
45
|
+
}
|
46
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'inferno/dsl/oauth_credentials'
|
2
|
+
require_relative 'ext/inferno_core/record_response_route'
|
3
|
+
require_relative 'ext/inferno_core/runnable'
|
4
|
+
require_relative 'ext/inferno_core/request'
|
5
|
+
require_relative 'urls'
|
6
|
+
require_relative 'mock_server'
|
7
|
+
require_relative 'tags'
|
8
|
+
require_relative 'pdex_payer_client/collection'
|
9
|
+
require_relative 'must_support_test'
|
10
|
+
require_relative 'pdex_payer_client/client_validation_test'
|
11
|
+
|
12
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/initial_wait_test'
|
13
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/initial_scratch_storing'
|
14
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/allergyintolerance_clinical_data_request_test'
|
15
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/careplan_clinical_data_request_test'
|
16
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/careteam_clinical_data_request_test'
|
17
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/condition_clinical_data_request_test'
|
18
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/device_clinical_data_request_test'
|
19
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/diagnosticreport_clinical_data_request_test'
|
20
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/documentreference_clinical_data_request_test'
|
21
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/encounter_clinical_data_request_test'
|
22
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/explanationofbenefit_clinical_data_request_test'
|
23
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/goal_clinical_data_request_test'
|
24
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/immunization_clinical_data_request_test'
|
25
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/location_clinical_data_request_test'
|
26
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/medicationdispense_clinical_data_request_test'
|
27
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/medicationrequest_clinical_data_request_test'
|
28
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/observation_clinical_data_request_test'
|
29
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/organization_clinical_data_request_test'
|
30
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/patient_clinical_data_request_test'
|
31
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/practitioner_clinical_data_request_test'
|
32
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/practitionerrole_clinical_data_request_test'
|
33
|
+
require_relative 'pdex_payer_client/clinical_data_request_tests/procedure_clinical_data_request_test'
|
34
|
+
|
35
|
+
require_relative 'pdex_payer_client/client_member_match_tests/client_member_match_submit_test'
|
36
|
+
require_relative 'pdex_payer_client/client_member_match_tests/client_member_match_validation_test'
|
37
|
+
# require_relative 'pdex_payer_client/client_must_support_tests/client_member_match_must_support_submit_test'
|
38
|
+
# require_relative 'pdex_payer_client/client_must_support_tests/client_member_match_must_support_validation_test'
|
39
|
+
|
40
|
+
|
41
|
+
module DaVinciPDexTestKit
|
42
|
+
class PDexPayerClientSuite < Inferno::TestSuite
|
43
|
+
extend MockServer
|
44
|
+
extend ClientValidationTest
|
45
|
+
|
46
|
+
id :pdex_payer_client
|
47
|
+
title 'Da Vinci PDex Payer Client Test Suite'
|
48
|
+
description File.read(File.join(__dir__, 'docs', 'payer_client_suite_description_v200.md'))
|
49
|
+
|
50
|
+
def self.test_resumes?(test)
|
51
|
+
!test.config.options[:accepts_multiple_requests]
|
52
|
+
end
|
53
|
+
|
54
|
+
# All FHIR validation requests will use this FHIR validator
|
55
|
+
validator do
|
56
|
+
url ENV.fetch('VALIDATOR_URL')
|
57
|
+
end
|
58
|
+
|
59
|
+
record_response_route :post, TOKEN_PATH, AUTH_TAG, method(:token_response) do |request|
|
60
|
+
PDexPayerClientSuite.extract_client_id(request)
|
61
|
+
end
|
62
|
+
|
63
|
+
record_response_route :get, PATIENT_PATH, SUBMIT_TAG, method(:claim_response), # Patient needs a specific definition
|
64
|
+
resumes: method(:test_resumes?) do |request|
|
65
|
+
PDexPayerClientSuite.extract_bearer_token(request)
|
66
|
+
end
|
67
|
+
|
68
|
+
record_response_route :get, SUBMIT_PATH, SUBMIT_TAG, method(:claim_response),
|
69
|
+
resumes: method(:test_resumes?) do |request|
|
70
|
+
PDexPayerClientSuite.extract_bearer_token(request)
|
71
|
+
end
|
72
|
+
|
73
|
+
record_response_route :get, EVERYTHING_PATH, EVERYTHING_TAG, method(:everything_response),
|
74
|
+
resumes: method(:test_resumes?) do |request|
|
75
|
+
PDexPayerClientSuite.extract_bearer_token(request)
|
76
|
+
end
|
77
|
+
|
78
|
+
# record_response_route :get, EXPORT_PATH, EXPORT_TAG, method(:export_response),
|
79
|
+
# resumes: method(:test_resumes?) do |request|
|
80
|
+
# PDexPayerClientSuite.extract_bearer_token(request)
|
81
|
+
# end
|
82
|
+
|
83
|
+
record_response_route :post, MEMBER_MATCH_PATH, MEMBER_MATCH_TAG, method(:member_match_response),
|
84
|
+
resumes: method(:test_resumes?) do |request|
|
85
|
+
PDexPayerClientSuite.extract_bearer_token(request)
|
86
|
+
end
|
87
|
+
|
88
|
+
record_response_route :get, BASE_FHIR_PATH, SUBMIT_TAG, method(:read_next_page),
|
89
|
+
resumes: method(:test_resumes?) do |request|
|
90
|
+
PDexPayerClientSuite.extract_bearer_token(request)
|
91
|
+
end
|
92
|
+
|
93
|
+
resume_test_route :get, RESUME_PASS_PATH do |request|
|
94
|
+
PDexPayerClientSuite.extract_token_from_query_params(request)
|
95
|
+
end
|
96
|
+
|
97
|
+
resume_test_route :get, RESUME_CLINICAL_DATA_PATH do |request|
|
98
|
+
PDexPayerClientSuite.extract_token_from_query_params(request)
|
99
|
+
end
|
100
|
+
|
101
|
+
resume_test_route :get, RESUME_FAIL_PATH, result: 'fail' do |request|
|
102
|
+
PDexPayerClientSuite.extract_token_from_query_params(request)
|
103
|
+
end
|
104
|
+
|
105
|
+
route(:get, METADATA_PATH, get_metadata)
|
106
|
+
|
107
|
+
group do
|
108
|
+
run_as_group
|
109
|
+
title "Workflow Tests"
|
110
|
+
group do
|
111
|
+
title "$member-match validation"
|
112
|
+
test from: :initial_member_match_submit_test
|
113
|
+
test from: :initial_member_match_validation_test
|
114
|
+
end
|
115
|
+
group do
|
116
|
+
title "Clinical data request tests"
|
117
|
+
test from: :initial_wait_test
|
118
|
+
test from: :initial_scratch_storing
|
119
|
+
test from: :allergyintolerance_clinical_data_request_test
|
120
|
+
test from: :careplan_clinical_data_request_test
|
121
|
+
test from: :careteam_clinical_data_request_test
|
122
|
+
test from: :condition_clinical_data_request_test
|
123
|
+
test from: :device_clinical_data_request_test
|
124
|
+
test from: :diagnosticreport_clinical_data_request_test
|
125
|
+
test from: :documentreference_clinical_data_request_test
|
126
|
+
test from: :encounter_clinical_data_request_test
|
127
|
+
test from: :explanationofbenefit_clinical_data_request_test
|
128
|
+
test from: :goal_clinical_data_request_test
|
129
|
+
test from: :immunization_clinical_data_request_test
|
130
|
+
test from: :location_clinical_data_request_test
|
131
|
+
test from: :medicationdispense_clinical_data_request_test
|
132
|
+
test from: :medicationrequest_clinical_data_request_test
|
133
|
+
test from: :observation_clinical_data_request_test
|
134
|
+
test from: :organization_clinical_data_request_test
|
135
|
+
test from: :patient_clinical_data_request_test
|
136
|
+
test from: :practitioner_clinical_data_request_test
|
137
|
+
test from: :practitionerrole_clinical_data_request_test
|
138
|
+
test from: :procedure_clinical_data_request_test
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# group do
|
143
|
+
# title "Must Support validation"
|
144
|
+
# group do
|
145
|
+
# title "$member-match Must Support tests"
|
146
|
+
# test from: :initial_member_match_must_support_submit_test
|
147
|
+
# test from: :initial_member_match_must_support_validation_test
|
148
|
+
# end
|
149
|
+
# end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
data/lib/davinci_pdex_test_kit/pdex_payer_server/abstract_member_match_request_conformance_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module DaVinciPDexTestKit
|
2
|
+
module PDexPayerServer
|
3
|
+
|
4
|
+
# Exists to factorize input validation
|
5
|
+
class AbstractMemberMatchRequestConformanceTest < Inferno::Test
|
6
|
+
id :abstract_member_match_request_conformance
|
7
|
+
input :member_match_request
|
8
|
+
|
9
|
+
def assert_local_patient_references(member_match_request_parameters)
|
10
|
+
# $member-match has references requirements on its Parameters profile not coded as FHIR constraints
|
11
|
+
# see https://hl7.org/fhir/us/davinci-hrex/STU1/OperationDefinition-member-match.html#resolving-parameter-references
|
12
|
+
parameter_patient_id = member_match_request_parameters.parameter.find{|p| p.name== 'MemberPatient'}.resource.id
|
13
|
+
assert member_match_request_parameters.parameter.find{|p| p.name== 'Consent'}&.resource&.patient&.reference == "Patient/#{parameter_patient_id}",
|
14
|
+
"The reference to Patient resource in Consent parameter must be a local reference referring to MemberPatient with matching id"
|
15
|
+
assert member_match_request_parameters.parameter.find{|p| p.name== 'CoverageToMatch'}&.resource.beneficiary.reference == "Patient/#{parameter_patient_id}",
|
16
|
+
"The reference to Patient resource in CoverageToMatch parameter must be a local reference referring to MemberPatient with matching id"
|
17
|
+
end
|
18
|
+
|
19
|
+
def assert_member_match_request(member_match_request_json)
|
20
|
+
# assert_valid_json(member_match_request_json)
|
21
|
+
member_match_request_resource = FHIR.from_contents(member_match_request_json) # TODO: handle case if it fails to parse as FHIR, but is valid JSON
|
22
|
+
assert_valid_resource(resource: member_match_request_resource, profile_url: 'http://hl7.org/fhir/us/davinci-hrex/StructureDefinition/hrex-parameters-member-match-in')
|
23
|
+
assert_local_patient_references(member_match_request_resource)
|
24
|
+
end
|
25
|
+
|
26
|
+
run do
|
27
|
+
skip_if !member_match_request, "No input provided."
|
28
|
+
|
29
|
+
assert_member_match_request(member_match_request)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module DaVinciPDexTestKit
|
2
|
+
module PDexPayerServer
|
3
|
+
|
4
|
+
# Exists to factorize input validation
|
5
|
+
class AbstractMemberMatchRequestLocalReferencesTest < Inferno::Test
|
6
|
+
id :abstract_member_match_request_local_references
|
7
|
+
title '[USER INPUT VALIDATION] Member match request only uses local references'
|
8
|
+
description %{
|
9
|
+
This test confirms that all Patient references inside the Consent and CoverageToMatch parameters are local references to the MemberPatient
|
10
|
+
parameter. See
|
11
|
+
[resolving parameter references](http://hl7.org/fhir/us/davinci-hrex/STU1/OperationDefinition-member-match.html#resolving-parameter-references)
|
12
|
+
from the HRex 1.0.0. Implementation Guide.
|
13
|
+
}
|
14
|
+
|
15
|
+
input :member_match_request # [String]
|
16
|
+
|
17
|
+
# @param member_match_request_parameters [FHIR::Parameters]
|
18
|
+
def assert_local_patient_references(member_match_request_parameters)
|
19
|
+
# $member-match has references requirements on its Parameters profile not coded as FHIR constraints
|
20
|
+
# see https://hl7.org/fhir/us/davinci-hrex/STU1/OperationDefinition-member-match.html#resolving-parameter-references
|
21
|
+
parameter_patient_id = member_match_request_parameters.parameter.find{|p| p.name== 'MemberPatient'}.resource.id
|
22
|
+
assert member_match_request_parameters.parameter.find{|p| p.name== 'Consent'}&.resource&.patient&.reference == "Patient/#{parameter_patient_id}",
|
23
|
+
"The reference to Patient resource in Consent parameter must be a local reference referring to MemberPatient with matching id"
|
24
|
+
assert member_match_request_parameters.parameter.find{|p| p.name== 'CoverageToMatch'}&.resource&.beneficiary&.reference == "Patient/#{parameter_patient_id}",
|
25
|
+
"The reference to Patient resource in CoverageToMatch parameter must be a local reference referring to MemberPatient with matching id"
|
26
|
+
end
|
27
|
+
|
28
|
+
run do
|
29
|
+
skip_if !member_match_request, "No input provided."
|
30
|
+
|
31
|
+
assert_local_patient_references( FHIR.from_contents(member_match_request) )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
module DaVinciPDexTestKit
|
3
|
+
module PDexPayerServer
|
4
|
+
class CoverageToLinkHasMinimalDataTest < Inferno::Test
|
5
|
+
|
6
|
+
id :coverage_to_link_has_minimal_data
|
7
|
+
title '[USER INPUT VALIDATION] CoverageToLink parameter should not include any data elements not marked as mustSupport'
|
8
|
+
optional
|
9
|
+
description %{
|
10
|
+
This test will skip if there is no CoverageToLink parameter in the member match request input for one match.
|
11
|
+
|
12
|
+
If that resource is present, it will check conformance against the
|
13
|
+
[HRex Coverage Profile](https://hl7.org/fhir/us/davinci-hrex/STU1/StructureDefinition-hrex-coverage.html)
|
14
|
+
and check that no elements that are neither MustSupport nor Mandatory are present.
|
15
|
+
|
16
|
+
If certain MustSupport elements are missing this test may still pass.
|
17
|
+
|
18
|
+
See [notes](https://hl7.org/fhir/us/davinci-hrex/STU1/OperationDefinition-member-match.html#notes) in HRex Implementation Guide,
|
19
|
+
as required by PDex Implementation Guide.
|
20
|
+
}
|
21
|
+
|
22
|
+
input :member_match_request
|
23
|
+
|
24
|
+
run do
|
25
|
+
member_match_request_resource = FHIR.from_contents(member_match_request)
|
26
|
+
skip_if !member_match_request_resource.parameter.find{|p| p.name=='CoverageToLink'},
|
27
|
+
"No CoverageToLink parameter provided"
|
28
|
+
|
29
|
+
coverage = member_match_request_resource.parameter.find{|p| p.name=='CoverageToLink'}.resource
|
30
|
+
|
31
|
+
assert_resource_type(:coverage, resource: coverage)
|
32
|
+
assert !coverage.type
|
33
|
+
assert !coverage.policyHolder
|
34
|
+
assert !coverage.subscriber
|
35
|
+
assert !coverage.relationship
|
36
|
+
assert !coverage.period
|
37
|
+
assert !coverage.local_class.any? do |backbone_element|
|
38
|
+
backbone_element.type.coding.any? do |coding|
|
39
|
+
!(coding.code == 'group' &&
|
40
|
+
coding.system == 'http://terminology.hl7.org/CodeSystem/coverage-class')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
assert !coverage.order
|
44
|
+
assert !coverage.network
|
45
|
+
assert coverage.costToBeneficiary.empty?
|
46
|
+
assert coverage.subrogation.nil?
|
47
|
+
assert !coverage.contract
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
module DaVinciPDexTestKit
|
3
|
+
module PDexPayerServer
|
4
|
+
class CoverageToLinkMustSupportTest < Inferno::Test
|
5
|
+
|
6
|
+
id :coverage_to_link_must_support
|
7
|
+
title '[USER INPUT VALIDATION] CoverageToLink parameter is optional for generic FHIR clients, but required for Payer systems.'
|
8
|
+
description 'See [CoverageToLink parameter documentation](https://hl7.org/fhir/us/davinci-hrex/STU1/OperationDefinition-member-match.html).'
|
9
|
+
optional
|
10
|
+
|
11
|
+
input :member_match_request
|
12
|
+
|
13
|
+
# Special test for 'CoverageToLink' test in Member Match Request, which is "MustSupport":
|
14
|
+
# https://hl7.org/fhir/us/davinci-hrex/STU1/OperationDefinition-member-match.html
|
15
|
+
#
|
16
|
+
# > This parameter is optional as this operation may be invoked by non-payer systems. However, it is considered 'mustSupport'.
|
17
|
+
# > If the client invoking the operation is a payer, they SHALL include their coverage information for the member when invoking
|
18
|
+
# > the operation.
|
19
|
+
run do
|
20
|
+
member_match_request_resource = FHIR.from_contents(member_match_request)
|
21
|
+
|
22
|
+
assert member_match_request_resource.parameter.find{|p| p.name=='CoverageToLink'}&.resource, "No CoverageToLink parameter provided."
|
23
|
+
assert_resource_type(:coverage, resource: member_match_request_resource.parameter.find{|p| p.name=='CoverageToLink'}&.resource)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'us_core_test_kit/search_test'
|
2
|
+
require 'us_core_test_kit/search_test_properties'
|
3
|
+
require 'us_core_test_kit/generator/group_metadata'
|
4
|
+
|
5
|
+
module DaVinciPDexTestKit
|
6
|
+
module PDexPayerServer
|
7
|
+
class ExplanationOfBenefitIdSearchTest < Inferno::Test
|
8
|
+
include USCoreTestKit::SearchTest
|
9
|
+
|
10
|
+
title 'Server returns valid results for Patient search by _id'
|
11
|
+
description %(
|
12
|
+
A server SHALL support searching by
|
13
|
+
_id on the ExplanationOfBenefit resource. This test
|
14
|
+
will pass if resources are returned and match the search criteria. If
|
15
|
+
none are returned, the test is skipped.
|
16
|
+
|
17
|
+
Because this is the first search of the sequence, resources in the
|
18
|
+
response will be used for subsequent tests.
|
19
|
+
|
20
|
+
Additionally, this test will check that GET and POST search methods
|
21
|
+
return the same number of results. Search by POST is required by the
|
22
|
+
FHIR R4 specification, and these tests interpret search by GET as a
|
23
|
+
requirement of DaVinci PDex v2.0.0.
|
24
|
+
|
25
|
+
[PDex Server CapabilityStatement](https://hl7.org/fhir/us/davinci-pdex/STU2/CapabilityStatement-pdex-server.html)
|
26
|
+
|
27
|
+
)
|
28
|
+
|
29
|
+
id :pdex_explanation_of_benefit__id_search_test
|
30
|
+
|
31
|
+
input :patient_ids,
|
32
|
+
title: 'Patient IDs',
|
33
|
+
description: 'Comma separated list of patient IDs that in sum contain all MUST SUPPORT elements'
|
34
|
+
|
35
|
+
# TODO: test if this test runs
|
36
|
+
|
37
|
+
def self.properties
|
38
|
+
@properties ||= USCoreTestKit::SearchTestProperties.new(
|
39
|
+
resource_type: 'ExplanationOfBenefit',
|
40
|
+
search_param_names: ['_id']
|
41
|
+
# TODO: any more search test properties?
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.metadata
|
46
|
+
@metadata ||= USCoreTestKit::Generator::GroupMetadata.new(YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true))
|
47
|
+
end
|
48
|
+
|
49
|
+
def scratch_resources
|
50
|
+
scratch[:patient_resources] ||= {}
|
51
|
+
end
|
52
|
+
|
53
|
+
run do
|
54
|
+
run_search_test
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'us_core_test_kit/search_test'
|
2
|
+
require 'us_core_test_kit/search_test_properties'
|
3
|
+
require 'us_core_test_kit/generator/group_metadata'
|
4
|
+
|
5
|
+
module DaVinciPDexTestKit
|
6
|
+
module PDexPayerServer
|
7
|
+
class ExplanationOfBenefitIdentifierSearchTest < Inferno::Test
|
8
|
+
include USCoreTestKit::SearchTest
|
9
|
+
|
10
|
+
title 'Server returns valid results for Patient search by identifier'
|
11
|
+
description %(
|
12
|
+
A server SHALL support searching by
|
13
|
+
identifier on the ExplanationOfBenefit resource. This test
|
14
|
+
will pass if resources are returned and match the search criteria. If
|
15
|
+
none are returned, the test is skipped.
|
16
|
+
|
17
|
+
Because this is the first search of the sequence, resources in the
|
18
|
+
response will be used for subsequent tests.
|
19
|
+
|
20
|
+
Additionally, this test will check that GET and POST search methods
|
21
|
+
return the same number of results. Search by POST is required by the
|
22
|
+
FHIR R4 specification, and these tests interpret search by GET as a
|
23
|
+
requirement of DaVinci PDex v2.0.0.
|
24
|
+
|
25
|
+
[PDex Server CapabilityStatement](https://hl7.org/fhir/us/davinci-pdex/STU2/CapabilityStatement-pdex-server.html)
|
26
|
+
|
27
|
+
)
|
28
|
+
|
29
|
+
id :pdex_explanation_of_benefit_identifier_search_test
|
30
|
+
|
31
|
+
input :patient_ids,
|
32
|
+
title: 'Patient IDs',
|
33
|
+
description: 'Comma separated list of patient IDs that in sum contain all MUST SUPPORT elements'
|
34
|
+
|
35
|
+
# TODO: test if this test runs
|
36
|
+
|
37
|
+
def self.properties
|
38
|
+
@properties ||= USCoreTestKit::SearchTestProperties.new(
|
39
|
+
resource_type: 'ExplanationOfBenefit',
|
40
|
+
search_param_names: ['identifier']
|
41
|
+
# TODO: any more search test properties?
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.metadata
|
46
|
+
@metadata ||= USCoreTestKit::Generator::GroupMetadata.new(YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true))
|
47
|
+
end
|
48
|
+
|
49
|
+
def scratch_resources
|
50
|
+
scratch[:patient_resources] ||= {}
|
51
|
+
end
|
52
|
+
|
53
|
+
run do
|
54
|
+
run_search_test
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'us_core_test_kit/must_support_test'
|
2
|
+
require 'us_core_test_kit/generator/group_metadata'
|
3
|
+
|
4
|
+
module DaVinciPDexTestKit
|
5
|
+
module PDexPayerServer
|
6
|
+
class ExplanationOfBenefitMustSupportTest < Inferno::Test
|
7
|
+
include USCoreTestKit::MustSupportTest
|
8
|
+
|
9
|
+
title 'All must support elements are provided in the ExplanationOfBenefit resources returned'
|
10
|
+
description %(
|
11
|
+
US Core Responders SHALL be capable of populating all data elements as
|
12
|
+
part of the query results as specified by the US Core Server Capability
|
13
|
+
Statement. This test will look through the ExplanationOfBenefit resources
|
14
|
+
found previously for the following must support elements:
|
15
|
+
|
16
|
+
#### TODO: list out MS elements:
|
17
|
+
|
18
|
+
* ...
|
19
|
+
)
|
20
|
+
|
21
|
+
id :pdex_explanation_of_benefit_must_support_test
|
22
|
+
|
23
|
+
def resource_type
|
24
|
+
'ExplanationOfBenefit'
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.metadata
|
28
|
+
@metadata ||= USCoreTestKit::Generator::GroupMetadata.new(YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true))
|
29
|
+
end
|
30
|
+
|
31
|
+
def scratch_resources
|
32
|
+
scratch[:explanation_of_benefit_resources] ||= {}
|
33
|
+
end
|
34
|
+
|
35
|
+
run do
|
36
|
+
perform_must_support_test(all_scratch_resources)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'us_core_test_kit/search_test'
|
2
|
+
require 'us_core_test_kit/search_test_properties'
|
3
|
+
require 'us_core_test_kit/generator/group_metadata'
|
4
|
+
|
5
|
+
module DaVinciPDexTestKit
|
6
|
+
module PDexPayerServer
|
7
|
+
class ExplanationOfBenefitPatientLastUpdatedSearchTest < Inferno::Test
|
8
|
+
include USCoreTestKit::SearchTest
|
9
|
+
|
10
|
+
title 'Server returns valid results for ExplanationOfBenefit search by patient + _lastUpdated'
|
11
|
+
description %(
|
12
|
+
A server SHALL support searching by
|
13
|
+
patient + _lastUpdated on the ExplanationOfBenefit resource. This test
|
14
|
+
will pass if resources are returned and match the search criteria. If
|
15
|
+
none are returned, the test is skipped.
|
16
|
+
|
17
|
+
This test verifies that the server supports searching by reference using
|
18
|
+
the form `patient=[id]` as well as `patient=Patient/[id]`. The two
|
19
|
+
different forms are expected to return the same number of results. US
|
20
|
+
Core requires that both forms are supported by US Core responders, and
|
21
|
+
PDex expands upon US Core.
|
22
|
+
|
23
|
+
Because this is the first search of the sequence, resources in the
|
24
|
+
response will be used for subsequent tests.
|
25
|
+
|
26
|
+
Additionally, this test will check that GET and POST search methods
|
27
|
+
return the same number of results. Search by POST is required by the
|
28
|
+
FHIR R4 specification, and these tests interpret search by GET as a
|
29
|
+
requirement of PDex v2.0.0.
|
30
|
+
|
31
|
+
[PDex Server CapabilityStatement](https://hl7.org/fhir/us/davinci-pdex/STU2/CapabilityStatement-pdex-server.html)
|
32
|
+
|
33
|
+
)
|
34
|
+
|
35
|
+
id :pdex_explanation_of_benefit_patient__last_updated_search_test
|
36
|
+
|
37
|
+
input :patient_ids,
|
38
|
+
title: 'Patient IDs',
|
39
|
+
description: 'Comma separated list of patient IDs that in sum contain all MUST SUPPORT elements'
|
40
|
+
|
41
|
+
def self.properties
|
42
|
+
@properties ||= USCoreTestKit::SearchTestProperties.new(
|
43
|
+
resource_type: 'ExplanationOfBenefit',
|
44
|
+
search_param_names: ['patient', '_lastUpdated'],
|
45
|
+
test_post_search: true
|
46
|
+
# TODO other properties?
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.metadata
|
51
|
+
@metadata ||= USCoreTestKit::Generator::GroupMetadata.new(YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true))
|
52
|
+
end
|
53
|
+
|
54
|
+
def scratch_resources
|
55
|
+
scratch[:explanation_of_benefit_resources] ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
run do
|
59
|
+
run_search_test
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'us_core_test_kit/search_test'
|
2
|
+
require 'us_core_test_kit/search_test_properties'
|
3
|
+
require 'us_core_test_kit/generator/group_metadata'
|
4
|
+
|
5
|
+
module DaVinciPDexTestKit
|
6
|
+
module PDexPayerServer
|
7
|
+
class ExplanationOfBenefitPatientServiceDateSearchTest < Inferno::Test
|
8
|
+
include USCoreTestKit::SearchTest
|
9
|
+
|
10
|
+
title 'Server returns valid results for ExplanationOfBenefit search by patient + service-date'
|
11
|
+
description %(
|
12
|
+
A server SHALL support searching by
|
13
|
+
patient + service-date on the ExplanationOfBenefit resource. This test
|
14
|
+
will pass if resources are returned and match the search criteria. If
|
15
|
+
none are returned, the test is skipped.
|
16
|
+
|
17
|
+
This test verifies that the server supports searching by reference using
|
18
|
+
the form `patient=[id]` as well as `patient=Patient/[id]`. The two
|
19
|
+
different forms are expected to return the same number of results. US
|
20
|
+
Core requires that both forms are supported by US Core responders, and
|
21
|
+
PDex expands upon US Core.
|
22
|
+
|
23
|
+
Because this is the first search of the sequence, resources in the
|
24
|
+
response will be used for subsequent tests.
|
25
|
+
|
26
|
+
Additionally, this test will check that GET and POST search methods
|
27
|
+
return the same number of results. Search by POST is required by the
|
28
|
+
FHIR R4 specification, and these tests interpret search by GET as a
|
29
|
+
requirement of PDex v2.0.0.
|
30
|
+
|
31
|
+
[PDex Server CapabilityStatement](https://hl7.org/fhir/us/davinci-pdex/STU2/CapabilityStatement-pdex-server.html)
|
32
|
+
|
33
|
+
)
|
34
|
+
|
35
|
+
id :pdex_explanation_of_benefit_patient_service_date_search_test
|
36
|
+
|
37
|
+
input :patient_ids,
|
38
|
+
title: 'Patient IDs',
|
39
|
+
description: 'Comma separated list of patient IDs that in sum contain all MUST SUPPORT elements'
|
40
|
+
|
41
|
+
def self.properties
|
42
|
+
@properties ||= USCoreTestKit::SearchTestProperties.new(
|
43
|
+
resource_type: 'ExplanationOfBenefit',
|
44
|
+
search_param_names: ['patient', 'service-date'],
|
45
|
+
test_post_search: true
|
46
|
+
# TODO other properties?
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.metadata
|
51
|
+
@metadata ||= USCoreTestKit::Generator::GroupMetadata.new(YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true))
|
52
|
+
end
|
53
|
+
|
54
|
+
def scratch_resources
|
55
|
+
scratch[:explanation_of_benefit_resources] ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
run do
|
59
|
+
run_search_test
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|