onc_certification_g10_test_kit 3.8.1 → 4.0.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/lib/inferno/terminology/expected_manifest.yml +58 -53
- data/lib/inferno/terminology/fhir_package_manager.rb +2 -1
- data/lib/inferno/terminology/loader.rb +7 -3
- data/lib/inferno/terminology/tasks/check_built_terminology.rb +17 -1
- data/lib/inferno/terminology/tasks/download_fhir_terminology.rb +2 -1
- data/lib/inferno/terminology/tasks/download_umls.rb +2 -1
- data/lib/inferno/terminology/tasks/expand_value_set_to_file.rb +1 -1
- data/lib/inferno/terminology/tasks/run_umls_jar.rb +2 -1
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +185 -0
- data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +4 -0
- data/lib/onc_certification_g10_test_kit/g10_options.rb +8 -0
- data/lib/onc_certification_g10_test_kit/igs/CodeSystem-observation-category.json +83 -0
- data/lib/onc_certification_g10_test_kit/igs/StructureDefinition-condition-assertedDate.json +280 -0
- data/lib/onc_certification_g10_test_kit/igs/ValueSet-observation-category.json +48 -0
- data/lib/onc_certification_g10_test_kit/igs/ValueSet-servicerequest-category.json +69 -0
- data/lib/onc_certification_g10_test_kit/limited_scope_grant_test.rb +5 -0
- data/lib/onc_certification_g10_test_kit/multi_patient_api_stu1.rb +10 -9
- data/lib/onc_certification_g10_test_kit/multi_patient_api_stu2.rb +10 -9
- data/lib/onc_certification_g10_test_kit/profile_selector.rb +72 -46
- data/lib/onc_certification_g10_test_kit/restricted_resource_type_access_group.rb +118 -21
- data/lib/onc_certification_g10_test_kit/short_id_manager.rb +2 -0
- data/lib/onc_certification_g10_test_kit/short_id_map.yml +579 -0
- data/lib/onc_certification_g10_test_kit/single_patient_api_group.rb +2 -1
- data/lib/onc_certification_g10_test_kit/single_patient_us_core_4_api_group.rb +33 -18
- data/lib/onc_certification_g10_test_kit/single_patient_us_core_5_api_group.rb +46 -24
- data/lib/onc_certification_g10_test_kit/single_patient_us_core_6_api_group.rb +203 -0
- data/lib/onc_certification_g10_test_kit/smart_scopes_test.rb +14 -4
- data/lib/onc_certification_g10_test_kit/unrestricted_resource_type_access_group.rb +106 -31
- data/lib/onc_certification_g10_test_kit/version.rb +1 -1
- data/lib/onc_certification_g10_test_kit/well_known_capabilities_test.rb +1 -1
- data/lib/onc_certification_g10_test_kit.rb +14 -1
- metadata +13 -8
@@ -4,23 +4,23 @@ module ONCCertificationG10TestKit
|
|
4
4
|
module ProfileSelector
|
5
5
|
include G10Options
|
6
6
|
|
7
|
-
def extract_profile(
|
8
|
-
case
|
7
|
+
def extract_profile(resource_type)
|
8
|
+
case resource_type
|
9
9
|
when 'Medication'
|
10
10
|
return versioned_us_core_module.const_get('USCoreTestSuite').metadata.find do |meta|
|
11
|
-
meta.resource ==
|
11
|
+
meta.resource == resource_type
|
12
12
|
end.profile_url
|
13
13
|
when 'Location'
|
14
14
|
return 'http://hl7.org/fhir/StructureDefinition/Location'
|
15
15
|
end
|
16
|
-
versioned_us_core_module.const_get("#{
|
16
|
+
versioned_us_core_module.const_get("#{resource_type}Group").metadata.profile_url
|
17
17
|
end
|
18
18
|
|
19
|
-
def observation_contains_code(observation_resource, code)
|
19
|
+
def observation_contains_code?(observation_resource, code)
|
20
20
|
observation_resource&.code&.coding&.any? { |coding| coding&.code == code }
|
21
21
|
end
|
22
22
|
|
23
|
-
def resource_contains_category(resource, category_code, category_system = nil) # rubocop:disable Metrics/CyclomaticComplexity
|
23
|
+
def resource_contains_category?(resource, category_code, category_system = nil) # rubocop:disable Metrics/CyclomaticComplexity
|
24
24
|
resource&.category&.any? do |category|
|
25
25
|
category.coding&.any? do |coding|
|
26
26
|
coding.code == category_code &&
|
@@ -35,35 +35,35 @@ module ONCCertificationG10TestKit
|
|
35
35
|
case resource.resourceType
|
36
36
|
when 'Condition'
|
37
37
|
case us_core_version
|
38
|
-
when US_CORE_5
|
39
|
-
if resource_contains_category(resource, 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category')
|
38
|
+
when US_CORE_5, US_CORE_6
|
39
|
+
if resource_contains_category?(resource, 'encounter-diagnosis', 'http://terminology.hl7.org/CodeSystem/condition-category')
|
40
40
|
profiles << extract_profile('ConditionEncounterDiagnosis')
|
41
|
-
elsif resource_contains_category(resource, 'problem-list-item',
|
42
|
-
|
43
|
-
resource_contains_category(resource, 'health-concern', 'http://hl7.org/fhir/us/core/CodeSystem/condition-category')
|
41
|
+
elsif resource_contains_category?(resource, 'problem-list-item',
|
42
|
+
'http://terminology.hl7.org/CodeSystem/condition-category') ||
|
43
|
+
resource_contains_category?(resource, 'health-concern', 'http://hl7.org/fhir/us/core/CodeSystem/condition-category')
|
44
44
|
profiles << extract_profile('ConditionProblemsHealthConcerns')
|
45
45
|
end
|
46
46
|
else
|
47
47
|
profiles << extract_profile(resource.resourceType)
|
48
48
|
end
|
49
49
|
when 'DiagnosticReport'
|
50
|
-
profiles << if resource_contains_category(resource, 'LAB', 'http://terminology.hl7.org/CodeSystem/v2-0074')
|
50
|
+
profiles << if resource_contains_category?(resource, 'LAB', 'http://terminology.hl7.org/CodeSystem/v2-0074')
|
51
51
|
extract_profile('DiagnosticReportLab')
|
52
52
|
else
|
53
53
|
extract_profile('DiagnosticReportNote')
|
54
54
|
end
|
55
55
|
when 'Observation'
|
56
|
-
profiles << extract_profile('Smokingstatus') if observation_contains_code(resource, '72166-2')
|
56
|
+
profiles << extract_profile('Smokingstatus') if observation_contains_code?(resource, '72166-2')
|
57
57
|
|
58
|
-
profiles << extract_profile('ObservationLab') if resource_contains_category(resource, 'laboratory', 'http://terminology.hl7.org/CodeSystem/observation-category')
|
58
|
+
profiles << extract_profile('ObservationLab') if resource_contains_category?(resource, 'laboratory', 'http://terminology.hl7.org/CodeSystem/observation-category')
|
59
59
|
|
60
|
-
profiles << extract_profile('PediatricBmiForAge') if observation_contains_code(resource, '59576-9')
|
60
|
+
profiles << extract_profile('PediatricBmiForAge') if observation_contains_code?(resource, '59576-9')
|
61
61
|
|
62
|
-
profiles << extract_profile('PediatricWeightForHeight') if observation_contains_code(resource, '77606-2')
|
62
|
+
profiles << extract_profile('PediatricWeightForHeight') if observation_contains_code?(resource, '77606-2')
|
63
63
|
|
64
|
-
profiles << extract_profile('PulseOximetry') if observation_contains_code(resource, '59408-5')
|
64
|
+
profiles << extract_profile('PulseOximetry') if observation_contains_code?(resource, '59408-5')
|
65
65
|
|
66
|
-
if observation_contains_code(resource, '8289-1')
|
66
|
+
if observation_contains_code?(resource, '8289-1')
|
67
67
|
profiles << case us_core_version
|
68
68
|
when US_CORE_3
|
69
69
|
extract_profile('HeadCircumference')
|
@@ -72,7 +72,7 @@ module ONCCertificationG10TestKit
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
if observation_contains_code(resource, '9843-4') && !using_us_core_3?
|
75
|
+
if observation_contains_code?(resource, '9843-4') && !using_us_core_3?
|
76
76
|
profiles << extract_profile('HeadCircumference')
|
77
77
|
end
|
78
78
|
|
@@ -81,9 +81,9 @@ module ONCCertificationG10TestKit
|
|
81
81
|
# Body Mass Index is replaced by :pediatric_bmi_age Profile
|
82
82
|
# Systolic Blood Pressure, Diastolic Blood Pressure are covered by :blood_pressure Profile
|
83
83
|
# Head Circumference is replaced by US Core Head Occipital-frontal Circumference Percentile Profile
|
84
|
-
profiles << extract_profile('Bmi') if observation_contains_code(resource, '39156-5') && !using_us_core_3?
|
84
|
+
profiles << extract_profile('Bmi') if observation_contains_code?(resource, '39156-5') && !using_us_core_3?
|
85
85
|
|
86
|
-
if observation_contains_code(resource, '85354-9')
|
86
|
+
if observation_contains_code?(resource, '85354-9')
|
87
87
|
profiles << case us_core_version
|
88
88
|
when US_CORE_3
|
89
89
|
extract_profile('Bp')
|
@@ -92,7 +92,7 @@ module ONCCertificationG10TestKit
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
if observation_contains_code(resource, '8302-2')
|
95
|
+
if observation_contains_code?(resource, '8302-2')
|
96
96
|
profiles << case us_core_version
|
97
97
|
when US_CORE_3
|
98
98
|
extract_profile('Bodyheight')
|
@@ -101,7 +101,7 @@ module ONCCertificationG10TestKit
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
-
if observation_contains_code(resource, '8310-5')
|
104
|
+
if observation_contains_code?(resource, '8310-5')
|
105
105
|
profiles << case us_core_version
|
106
106
|
when US_CORE_3
|
107
107
|
extract_profile('Bodytemp')
|
@@ -110,7 +110,7 @@ module ONCCertificationG10TestKit
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
-
if observation_contains_code(resource, '29463-7')
|
113
|
+
if observation_contains_code?(resource, '29463-7')
|
114
114
|
profiles << case us_core_version
|
115
115
|
when US_CORE_3
|
116
116
|
extract_profile('Bodyweight')
|
@@ -119,7 +119,7 @@ module ONCCertificationG10TestKit
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
-
if observation_contains_code(resource, '8867-4')
|
122
|
+
if observation_contains_code?(resource, '8867-4')
|
123
123
|
profiles << case us_core_version
|
124
124
|
when US_CORE_3
|
125
125
|
extract_profile('Heartrate')
|
@@ -128,7 +128,7 @@ module ONCCertificationG10TestKit
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
-
if observation_contains_code(resource, '9279-1')
|
131
|
+
if observation_contains_code?(resource, '9279-1')
|
132
132
|
profiles << case us_core_version
|
133
133
|
when US_CORE_3
|
134
134
|
extract_profile('Resprate')
|
@@ -138,44 +138,70 @@ module ONCCertificationG10TestKit
|
|
138
138
|
end
|
139
139
|
|
140
140
|
if using_us_core_5? &&
|
141
|
-
resource_contains_category(
|
141
|
+
resource_contains_category?(
|
142
142
|
resource, 'clinical-test', 'http://hl7.org/fhir/us/core/CodeSystem/us-core-observation-category'
|
143
143
|
)
|
144
144
|
profiles << extract_profile('ObservationClinicalTest')
|
145
145
|
end
|
146
146
|
|
147
|
-
if using_us_core_5? && observation_contains_code(resource, '76690-7')
|
147
|
+
if (using_us_core_5? || using_us_core_6?) && observation_contains_code?(resource, '76690-7')
|
148
148
|
profiles << extract_profile('ObservationSexualOrientation')
|
149
149
|
end
|
150
150
|
|
151
151
|
if using_us_core_5? &&
|
152
|
-
resource_contains_category(resource, 'social-history',
|
153
|
-
|
152
|
+
resource_contains_category?(resource, 'social-history',
|
153
|
+
'http://terminology.hl7.org/CodeSystem/observation-category')
|
154
154
|
profiles << extract_profile('ObservationSocialHistory')
|
155
155
|
end
|
156
156
|
|
157
157
|
if using_us_core_5? &&
|
158
|
-
resource_contains_category(resource, 'imaging',
|
159
|
-
|
158
|
+
resource_contains_category?(resource, 'imaging',
|
159
|
+
'http://terminology.hl7.org/CodeSystem/observation-category')
|
160
160
|
profiles << extract_profile('ObservationImaging')
|
161
161
|
end
|
162
162
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
163
|
+
if resource_contains_category?(resource, 'survey',
|
164
|
+
'http://terminology.hl7.org/CodeSystem/observation-category')
|
165
|
+
if using_us_core_5?
|
166
|
+
# We will simply match all Observations of category "survey" to SDOH,
|
167
|
+
# and do not look at the category "sdoh". US Core spec team says that
|
168
|
+
# support for the "sdoh" category is limited, and the validation rules
|
169
|
+
# allow for very generic surveys to validate against this profile.
|
170
|
+
# And will not validate against the ObservationSurvey profile itself.
|
171
|
+
# This may not be exactly precise but it works out the same
|
172
|
+
|
173
|
+
# if we wanted to be more specific here, we would add:
|
174
|
+
# `resource_contains_category?(resource, 'sdoh',
|
175
|
+
# 'http://terminology.hl7.org/CodeSystem/observation-category') &&`
|
176
|
+
# along with a specific extract_profile('ObservationSurvey') to catch non-sdoh.
|
177
|
+
profiles << extract_profile('ObservationSdohAssessment')
|
178
|
+
elsif using_us_core_6?
|
179
|
+
profiles << extract_profile('ObservationScreeningAssessment')
|
180
|
+
end
|
181
|
+
end
|
169
182
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
if
|
175
|
-
|
176
|
-
|
183
|
+
if using_us_core_6? && observation_contains_code?(resource, '11341-5')
|
184
|
+
profiles << extract_profile('ObservationOccupation')
|
185
|
+
end
|
186
|
+
|
187
|
+
if using_us_core_6? && observation_contains_code?(resource, '86645-9')
|
188
|
+
profiles << extract_profile('ObservationPregnancyintent')
|
189
|
+
end
|
190
|
+
|
191
|
+
if using_us_core_6? && observation_contains_code?(resource, '82810-3')
|
192
|
+
profiles << extract_profile('ObservationPregnancystatus')
|
193
|
+
end
|
194
|
+
|
195
|
+
clinical_result_categories = [
|
196
|
+
'laboratory', 'exam', 'therpay', 'imaging', 'procedure', 'vital-signs', 'activity'
|
197
|
+
]
|
177
198
|
|
178
|
-
|
199
|
+
if using_us_core_6? && clinical_result_categories.any? do |category|
|
200
|
+
resource_contains_category?(
|
201
|
+
resource, category, 'http://terminology.hl7.org/CodeSystem/observation-category'
|
202
|
+
)
|
203
|
+
end
|
204
|
+
profiles << extract_profile('ObservationClinicalResult')
|
179
205
|
end
|
180
206
|
|
181
207
|
nil
|
@@ -14,20 +14,25 @@ module ONCCertificationG10TestKit
|
|
14
14
|
|
15
15
|
Resources that can be mapped to USCDI are checked in this test, including:
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
17
|
+
* AllergyIntolerance
|
18
|
+
* CarePlan
|
19
|
+
* CareTeam
|
20
|
+
* Condition
|
21
|
+
* Device
|
22
|
+
* DiagnosticReport
|
23
|
+
* DocumentReference
|
24
|
+
* Goal
|
25
|
+
* Immunization
|
26
|
+
* MedicationRequest
|
27
|
+
* Observation
|
28
|
+
* Patient
|
29
|
+
* Procedure
|
30
|
+
|
31
|
+
If testing against USCDI v2, Encounter and ServiceRequest are also
|
32
|
+
checked.
|
33
|
+
|
34
|
+
If testing against USCDI v3, Encounter, ServiceRequest, Coverage,
|
35
|
+
and MedicationDispense are also checked.
|
31
36
|
|
32
37
|
For each of the resources that can be mapped to USCDI data class or
|
33
38
|
elements, this set of tests performs a minimum number of requests to
|
@@ -42,16 +47,28 @@ module ONCCertificationG10TestKit
|
|
42
47
|
This set of tests does not attempt to access resources that do not
|
43
48
|
directly map to USCDI. For USCDI v1 this includes:
|
44
49
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
50
|
+
* Encounter
|
51
|
+
* Location
|
52
|
+
* Organization
|
53
|
+
* Practitioner
|
49
54
|
|
50
55
|
For USCDI v2 this includes:
|
51
56
|
|
52
|
-
|
53
|
-
|
54
|
-
|
57
|
+
* Location
|
58
|
+
* Organization
|
59
|
+
* Practitioner
|
60
|
+
|
61
|
+
For USCDI v3 this includes:
|
62
|
+
|
63
|
+
* Location
|
64
|
+
* Organization
|
65
|
+
* Practitioner
|
66
|
+
* RelatedPerson
|
67
|
+
* Specimen
|
68
|
+
|
69
|
+
It also does not test Provenance, as this resource type is accessed by
|
70
|
+
queries through other resource types. These resources types are accessed
|
71
|
+
in the more comprehensive Single Patient Query tests.
|
55
72
|
|
56
73
|
If the tester chooses to not grant access to a resource, the queries
|
57
74
|
associated with that resource must result in either a 401 (Unauthorized)
|
@@ -349,5 +366,85 @@ module ONCCertificationG10TestKit
|
|
349
366
|
USCoreTestKit::USCoreV501::ServiceRequestGroup
|
350
367
|
end
|
351
368
|
end
|
369
|
+
|
370
|
+
test from: :g10_restricted_access_test do
|
371
|
+
title 'Access to Encounter resources are restricted properly based on patient-selected scope'
|
372
|
+
description %(
|
373
|
+
This test ensures that access to the Encounter is granted or
|
374
|
+
denied based on the selection by the tester prior to the execution of
|
375
|
+
the test. If the tester indicated that access will be granted to this
|
376
|
+
resource, this test verifies that a search by patient in this resource
|
377
|
+
does not result in an access denied result. If the tester indicated that
|
378
|
+
access will be denied for this resource, this verifies that search by
|
379
|
+
patient in the resource results in an access denied result.
|
380
|
+
)
|
381
|
+
id :g10_us_core_6_encounter_restricted_access
|
382
|
+
|
383
|
+
required_suite_options G10Options::US_CORE_6_REQUIREMENT
|
384
|
+
|
385
|
+
def resource_group
|
386
|
+
USCoreTestKit::USCoreV610::EncounterGroup
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
test from: :g10_restricted_access_test do
|
391
|
+
title 'Access to ServiceRequest resources are restricted properly based on patient-selected scope'
|
392
|
+
description %(
|
393
|
+
This test ensures that access to the ServiceRequest is granted or
|
394
|
+
denied based on the selection by the tester prior to the execution of
|
395
|
+
the test. If the tester indicated that access will be granted to this
|
396
|
+
resource, this test verifies that a search by patient in this resource
|
397
|
+
does not result in an access denied result. If the tester indicated that
|
398
|
+
access will be denied for this resource, this verifies that search by
|
399
|
+
patient in the resource results in an access denied result.
|
400
|
+
)
|
401
|
+
id :g10_us_core_6_service_request_restricted_access
|
402
|
+
|
403
|
+
required_suite_options G10Options::US_CORE_6_REQUIREMENT
|
404
|
+
|
405
|
+
def resource_group
|
406
|
+
USCoreTestKit::USCoreV610::ServiceRequestGroup
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
test from: :g10_restricted_access_test do
|
411
|
+
title 'Access to Coverage resources are restricted properly based on patient-selected scope'
|
412
|
+
description %(
|
413
|
+
This test ensures that access to the Coverage is granted or
|
414
|
+
denied based on the selection by the tester prior to the execution of
|
415
|
+
the test. If the tester indicated that access will be granted to this
|
416
|
+
resource, this test verifies that a search by patient in this resource
|
417
|
+
does not result in an access denied result. If the tester indicated that
|
418
|
+
access will be denied for this resource, this verifies that search by
|
419
|
+
patient in the resource results in an access denied result.
|
420
|
+
)
|
421
|
+
id :g10_us_core_6_coverage_restricted_access
|
422
|
+
|
423
|
+
required_suite_options G10Options::US_CORE_6_REQUIREMENT
|
424
|
+
|
425
|
+
def resource_group
|
426
|
+
USCoreTestKit::USCoreV610::CoverageGroup
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
test from: :g10_restricted_access_test do
|
431
|
+
title 'Access to MedicationDispense resources are restricted properly based on patient-selected scope'
|
432
|
+
description %(
|
433
|
+
This test ensures that access to the MedicationDispense is granted or
|
434
|
+
denied based on the selection by the tester prior to the execution of
|
435
|
+
the test. If the tester indicated that access will be granted to this
|
436
|
+
resource, this test verifies that a search by patient in this resource
|
437
|
+
does not result in an access denied result. If the tester indicated that
|
438
|
+
access will be denied for this resource, this verifies that search by
|
439
|
+
patient in the resource results in an access denied result.
|
440
|
+
)
|
441
|
+
id :g10_us_core_6_medication_dispense_restricted_access
|
442
|
+
|
443
|
+
required_suite_options G10Options::US_CORE_6_REQUIREMENT
|
444
|
+
|
445
|
+
def resource_group
|
446
|
+
USCoreTestKit::USCoreV610::MedicationDispenseGroup
|
447
|
+
end
|
448
|
+
end
|
352
449
|
end
|
353
450
|
end
|
@@ -26,6 +26,8 @@ module ONCCertificationG10TestKit
|
|
26
26
|
rescue KeyError
|
27
27
|
Inferno::Application['logger'].warn("No short id defined for #{runnable.id}")
|
28
28
|
end
|
29
|
+
rescue Errno::ENOENT
|
30
|
+
Inferno::Application['logger'].warn('No short id map found')
|
29
31
|
end
|
30
32
|
|
31
33
|
### The methods below are only for creating an initial list of short ids
|